mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
* Reactify the confirmation modal Up next: jest tests * Add tests - Relies on https://github.com/elastic/kibana/pull/10821 getting checked in first for commonHtmlProps * Don't include the overlay as part of the confirm modal component * Use the react version of a confirmation modal - Can’t use the modalOverlay or it would be two nested react roots, due to the way it’s embedded in angular. * Add snapshots * Fix tests * fix confirm_modal_promise tests I have no idea why the introduction of react would cause this to fail as it was, but for some reason, grabbing the button reference has to be after the digest loop. * Address code review comments * switch over the remaining React.PropType references (in the modals dir anyway)
This commit is contained in:
parent
02ad0ac16d
commit
7e74b2d19c
40 changed files with 598 additions and 158 deletions
|
@ -161,6 +161,7 @@
|
|||
"node-uuid": "1.4.7",
|
||||
"pegjs": "0.9.0",
|
||||
"postcss-loader": "1.2.1",
|
||||
"prop-types": "15.5.8",
|
||||
"pui-react-overlay-trigger": "7.5.4",
|
||||
"pui-react-tooltip": "7.5.4",
|
||||
"querystring-browser": "1.0.4",
|
||||
|
|
|
@ -47,7 +47,7 @@ describe('ui/modals/confirm_modal', function () {
|
|||
confirmModal(myMessage, { confirmButtonText: 'GREAT!', onConfirm: _.noop });
|
||||
|
||||
$rootScope.$digest();
|
||||
const message = findByDataTestSubj('confirmModalBodyText')[0].innerText;
|
||||
const message = findByDataTestSubj('confirmModalBodyText')[0].innerText.trim();
|
||||
expect(message).to.equal(myMessage);
|
||||
});
|
||||
|
||||
|
@ -62,21 +62,21 @@ describe('ui/modals/confirm_modal', function () {
|
|||
it('for confirm button', () => {
|
||||
confirmModal('What\'s your favorite dinosaur?', confirmModalOptions);
|
||||
$rootScope.$digest();
|
||||
const confirmButtonText = findByDataTestSubj('confirmModalConfirmButton')[0].innerText;
|
||||
const confirmButtonText = findByDataTestSubj('confirmModalConfirmButton')[0].innerText.trim();
|
||||
expect(confirmButtonText).to.equal('Troodon');
|
||||
});
|
||||
|
||||
it('for cancel button', () => {
|
||||
confirmModal('What\'s your favorite dinosaur?', confirmModalOptions);
|
||||
$rootScope.$digest();
|
||||
const cancelButtonText = findByDataTestSubj('confirmModalCancelButton')[0].innerText;
|
||||
const cancelButtonText = findByDataTestSubj('confirmModalCancelButton')[0].innerText.trim();
|
||||
expect(cancelButtonText).to.equal('Dilophosaurus');
|
||||
});
|
||||
|
||||
it('for title text', () => {
|
||||
confirmModal('What\'s your favorite dinosaur?', confirmModalOptions);
|
||||
$rootScope.$digest();
|
||||
const titleText = findByDataTestSubj('confirmModalTitleText')[0].innerText;
|
||||
const titleText = findByDataTestSubj('confirmModalTitleText')[0].innerText.trim();
|
||||
expect(titleText).to.equal('Dinosaurs');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -56,11 +56,10 @@ describe('ui/modals/confirm_modal_promise', function () {
|
|||
const cancelCallback = sinon.spy();
|
||||
|
||||
promise.then(confirmCallback, cancelCallback);
|
||||
$rootScope.$digest();
|
||||
const confirmButton = angular.element(document.body).find('[data-test-subj=confirmModalConfirmButton]');
|
||||
|
||||
$rootScope.$digest();
|
||||
confirmButton.click();
|
||||
|
||||
expect(confirmCallback.called).to.be(true);
|
||||
expect(cancelCallback.called).to.be(false);
|
||||
});
|
||||
|
@ -72,9 +71,8 @@ describe('ui/modals/confirm_modal_promise', function () {
|
|||
const cancelCallback = sinon.spy();
|
||||
promise.then(confirmCallback, cancelCallback);
|
||||
|
||||
const noButton = angular.element(document.body).find('[data-test-subj=confirmModalCancelButton]');
|
||||
|
||||
$rootScope.$digest();
|
||||
const noButton = angular.element(document.body).find('[data-test-subj=confirmModalCancelButton]');
|
||||
noButton.click();
|
||||
|
||||
expect(cancelCallback.called).to.be(true);
|
||||
|
|
|
@ -1,32 +1,9 @@
|
|||
<div class="kuiModal" style="width: 450px" data-test-subj="confirmModal">
|
||||
<div class="kuiModalHeader" ng-if="title">
|
||||
<div class="kuiModalHeader__title" data-test-subj="confirmModalTitleText">
|
||||
{{title}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="kuiModalBody">
|
||||
<div
|
||||
class="kuiModalBodyText"
|
||||
data-test-subj="confirmModalBodyText"
|
||||
>
|
||||
{{message}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="kuiModalFooter">
|
||||
<button
|
||||
class="kuiButton kuiButton--hollow"
|
||||
data-test-subj="confirmModalCancelButton"
|
||||
ng-click="onCancel()"
|
||||
>
|
||||
{{cancelButtonText}}
|
||||
</button>
|
||||
<button
|
||||
class="kuiButton kuiButton--primary"
|
||||
data-test-subj="confirmModalConfirmButton"
|
||||
ng-click="onConfirm()"
|
||||
>
|
||||
{{confirmButtonText}}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<confirm-modal
|
||||
data-test-subj="confirmModal"
|
||||
on-cancel="onCancel"
|
||||
on-confirm="onConfirm"
|
||||
confirm-button-text="confirmButtonText"
|
||||
cancel-button-text="cancelButtonText"
|
||||
message="message"
|
||||
title="title"
|
||||
></confirm-modal>
|
||||
|
|
|
@ -2,10 +2,15 @@ import 'ngreact';
|
|||
|
||||
import {
|
||||
KuiToolBarSearchBox,
|
||||
KuiConfirmModal,
|
||||
} from 'ui_framework/components';
|
||||
|
||||
import { uiModules } from 'ui/modules';
|
||||
|
||||
const app = uiModules.get('app/kibana', ['react']);
|
||||
app.directive('toolBarSearchBox', function (reactDirective) {
|
||||
return reactDirective(KuiToolBarSearchBox);
|
||||
});
|
||||
app.directive('confirmModal', function (reactDirective) {
|
||||
return reactDirective(KuiConfirmModal);
|
||||
});
|
||||
|
|
|
@ -5,8 +5,14 @@ export {
|
|||
KuiLinkButton,
|
||||
KuiSubmitButton,
|
||||
} from './button';
|
||||
|
||||
export {
|
||||
KuiToolBarSearchBox,
|
||||
KuiToolBar,
|
||||
KuiToolBarFooter,
|
||||
} from './tool_bar';
|
||||
|
||||
export {
|
||||
KuiConfirmModal,
|
||||
KuiModalOverlay
|
||||
} from './modal';
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`renders KuiConfirmModal 1`] = `
|
||||
<div
|
||||
aria-label="aria-label"
|
||||
class="kuiModal testClass1 testClass2"
|
||||
data-tests-subj="test subject string"
|
||||
style="width:450px;"
|
||||
>
|
||||
<div
|
||||
class="kuiModalHeader"
|
||||
>
|
||||
<div
|
||||
class="kuiModalHeader__title"
|
||||
data-test-subj="confirmModalTitleText"
|
||||
>
|
||||
A confirmation modal
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="kuiModalBody"
|
||||
>
|
||||
<div
|
||||
class="kuiModalBodyText"
|
||||
data-test-subj="confirmModalBodyText"
|
||||
>
|
||||
This is a confirmation modal example
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="kuiModalFooter"
|
||||
>
|
||||
<button
|
||||
class="kuiButton kuiButton--hollow"
|
||||
data-test-subj="confirmModalCancelButton"
|
||||
>
|
||||
<span
|
||||
class="kuiButton__inner"
|
||||
>
|
||||
<span>
|
||||
Cancel Button Text
|
||||
</span>
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="kuiButton kuiButton--primary"
|
||||
data-test-subj="confirmModalConfirmButton"
|
||||
>
|
||||
<span
|
||||
class="kuiButton__inner"
|
||||
>
|
||||
<span>
|
||||
Confirm Button Text
|
||||
</span>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
|
@ -0,0 +1,11 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`renders KuiModal 1`] = `
|
||||
<div
|
||||
aria-label="aria-label"
|
||||
class="kuiModal testClass1 testClass2"
|
||||
data-test-subj="test subject string"
|
||||
>
|
||||
children
|
||||
</div>
|
||||
`;
|
|
@ -0,0 +1,11 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`renders KuiModalBody 1`] = `
|
||||
<div
|
||||
aria-label="aria-label"
|
||||
class="kuiModalBody testClass1 testClass2"
|
||||
data-test-subj="test subject string"
|
||||
>
|
||||
children
|
||||
</div>
|
||||
`;
|
|
@ -0,0 +1,11 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`renders KuiModalBodyText 1`] = `
|
||||
<div
|
||||
aria-label="aria-label"
|
||||
class="kuiModalBodyText testClass1 testClass2"
|
||||
data-test-subj="test subject string"
|
||||
>
|
||||
children
|
||||
</div>
|
||||
`;
|
|
@ -0,0 +1,11 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`renders KuiModalFooter 1`] = `
|
||||
<div
|
||||
aria-label="aria-label"
|
||||
class="kuiModalFooter testClass1 testClass2"
|
||||
data-test-subj="test subject string"
|
||||
>
|
||||
children
|
||||
</div>
|
||||
`;
|
|
@ -0,0 +1,11 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`renders KuiModalHeader 1`] = `
|
||||
<div
|
||||
aria-label="aria-label"
|
||||
class="kuiModalHeader testClass1 testClass2"
|
||||
data-test-subj="test subject string"
|
||||
>
|
||||
children
|
||||
</div>
|
||||
`;
|
|
@ -0,0 +1,11 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`renders KuiModalHeaderTitle 1`] = `
|
||||
<div
|
||||
aria-label="aria-label"
|
||||
class="kuiModalHeader__title testClass1 testClass2"
|
||||
data-test-subj="test subject string"
|
||||
>
|
||||
children
|
||||
</div>
|
||||
`;
|
|
@ -0,0 +1,11 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`renders KuiModalOverlay 1`] = `
|
||||
<div
|
||||
aria-label="aria-label"
|
||||
class="kuiModalOverlay testClass1 testClass2"
|
||||
data-test-subj="test subject string"
|
||||
>
|
||||
children
|
||||
</div>
|
||||
`;
|
|
@ -2,6 +2,7 @@ $modalPadding: 10px;
|
|||
$modalBorderColor: #6EADC1;
|
||||
$modalBackgroundColor: #FFF;
|
||||
$modalOverlayBackground: rgba(#000000, 0.3);
|
||||
$globalModalDepth: 1000;
|
||||
|
||||
@import "modal_overlay";
|
||||
@import "modal";
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
border: 1px solid $modalBorderColor;
|
||||
border-radius: $globalBorderRadius;
|
||||
box-shadow: 0 5px 22px rgba(#000000, 0.25);
|
||||
z-index: $globalModalDepth + 1;
|
||||
}
|
||||
|
||||
.kuiModalHeader {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
.kuiModalOverlay {
|
||||
position: fixed;
|
||||
z-index: 1000;
|
||||
z-index: $globalModalDepth;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
|
|
75
ui_framework/components/modal/confirm_modal.js
Normal file
75
ui_framework/components/modal/confirm_modal.js
Normal file
|
@ -0,0 +1,75 @@
|
|||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import { KuiModal } from './modal';
|
||||
import { KuiModalFooter } from './modal_footer';
|
||||
import { KuiModalHeader } from './modal_header';
|
||||
import { KuiModalHeaderTitle } from './modal_header_title';
|
||||
import { KuiModalBody } from './modal_body';
|
||||
import { KuiModalBodyText } from './modal_body_text';
|
||||
import { KuiButton } from '../index';
|
||||
|
||||
export function KuiConfirmModal({
|
||||
message,
|
||||
title,
|
||||
onCancel,
|
||||
onConfirm,
|
||||
cancelButtonText,
|
||||
confirmButtonText,
|
||||
className,
|
||||
...rest }) {
|
||||
const ariaLabel = rest['aria-label'];
|
||||
const dataTestSubj = rest['data-test-subj'];
|
||||
return (
|
||||
<KuiModal
|
||||
style={{ 'width': '450px' }}
|
||||
data-tests-subj={ dataTestSubj }
|
||||
aria-label={ ariaLabel }
|
||||
className={ className }
|
||||
>
|
||||
{
|
||||
title ?
|
||||
<KuiModalHeader>
|
||||
<KuiModalHeaderTitle data-test-subj="confirmModalTitleText">
|
||||
{ title }
|
||||
</KuiModalHeaderTitle>
|
||||
</KuiModalHeader>
|
||||
: null
|
||||
}
|
||||
<KuiModalBody>
|
||||
<KuiModalBodyText data-test-subj="confirmModalBodyText">
|
||||
{ message }
|
||||
</KuiModalBodyText>
|
||||
</KuiModalBody>
|
||||
|
||||
<KuiModalFooter>
|
||||
<KuiButton
|
||||
type="hollow"
|
||||
data-test-subj="confirmModalCancelButton"
|
||||
onClick={ onCancel }
|
||||
>
|
||||
{cancelButtonText}
|
||||
</KuiButton>
|
||||
<KuiButton
|
||||
type="primary"
|
||||
data-test-subj="confirmModalConfirmButton"
|
||||
onClick={ onConfirm }
|
||||
>
|
||||
{confirmButtonText}
|
||||
</KuiButton>
|
||||
</KuiModalFooter>
|
||||
</KuiModal>
|
||||
);
|
||||
}
|
||||
|
||||
KuiConfirmModal.propTypes = {
|
||||
message: PropTypes.string,
|
||||
title: PropTypes.string,
|
||||
cancelButtonText: PropTypes.string,
|
||||
confirmButtonText: PropTypes.string,
|
||||
onCancel: PropTypes.func,
|
||||
onConfirm: PropTypes.func,
|
||||
dataTestSubj: PropTypes.string,
|
||||
ariaLabel: PropTypes.string,
|
||||
className: PropTypes.string,
|
||||
};
|
61
ui_framework/components/modal/confirm_modal.test.js
Normal file
61
ui_framework/components/modal/confirm_modal.test.js
Normal file
|
@ -0,0 +1,61 @@
|
|||
import React from 'react';
|
||||
import sinon from 'sinon';
|
||||
import { mount, render } from 'enzyme';
|
||||
|
||||
import { requiredProps } from '../../test/required_props';
|
||||
|
||||
import {
|
||||
KuiConfirmModal,
|
||||
} from './confirm_modal';
|
||||
|
||||
let onConfirm;
|
||||
let onCancel;
|
||||
|
||||
beforeEach(() => {
|
||||
onConfirm = sinon.spy();
|
||||
onCancel = sinon.spy();
|
||||
});
|
||||
|
||||
test('renders KuiConfirmModal', () => {
|
||||
const component = render(<KuiConfirmModal
|
||||
message="This is a confirmation modal example"
|
||||
title="A confirmation modal"
|
||||
onCancel={() => {}}
|
||||
onConfirm={onConfirm}
|
||||
cancelButtonText="Cancel Button Text"
|
||||
confirmButtonText="Confirm Button Text"
|
||||
{ ...requiredProps }
|
||||
/>);
|
||||
expect(component).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('onConfirm', () => {
|
||||
const component = mount(<KuiConfirmModal
|
||||
message="This is a confirmation modal example"
|
||||
title="A confirmation modal"
|
||||
onCancel={onCancel}
|
||||
onConfirm={onConfirm}
|
||||
cancelButtonText="Cancel"
|
||||
confirmButtonText="Confirm"
|
||||
{ ...requiredProps }
|
||||
/>);
|
||||
component.find('[data-test-subj="confirmModalConfirmButton"]').simulate('click');
|
||||
sinon.assert.calledOnce(onConfirm);
|
||||
sinon.assert.notCalled(onCancel);
|
||||
});
|
||||
|
||||
test('onCancel', () => {
|
||||
const component = mount(<KuiConfirmModal
|
||||
message="This is a confirmation modal example"
|
||||
title="A confirmation modal"
|
||||
onCancel={onCancel}
|
||||
onConfirm={onConfirm}
|
||||
cancelButtonText="Cancel"
|
||||
confirmButtonText="Confirm"
|
||||
{ ...requiredProps }
|
||||
/>);
|
||||
component.find('[data-test-subj="confirmModalCancelButton"]').simulate('click');
|
||||
sinon.assert.notCalled(onConfirm);
|
||||
sinon.assert.calledOnce(onCancel);
|
||||
});
|
||||
|
5
ui_framework/components/modal/index.js
Normal file
5
ui_framework/components/modal/index.js
Normal file
|
@ -0,0 +1,5 @@
|
|||
export { KuiConfirmModal } from './confirm_modal';
|
||||
export { KuiModal } from './modal';
|
||||
export { KuiModalFooter } from './modal_footer';
|
||||
export { KuiModalHeader } from './modal_header';
|
||||
export { KuiModalOverlay } from './modal_overlay';
|
17
ui_framework/components/modal/modal.js
Normal file
17
ui_framework/components/modal/modal.js
Normal file
|
@ -0,0 +1,17 @@
|
|||
import React from 'react';
|
||||
import classnames from 'classnames';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
export function KuiModal({ className, children, ...rest }) {
|
||||
const classes = classnames('kuiModal', className);
|
||||
return (
|
||||
<div className={ classes } { ...rest }>
|
||||
{ children }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
KuiModal.propTypes = {
|
||||
className: PropTypes.string,
|
||||
children: PropTypes.node
|
||||
};
|
12
ui_framework/components/modal/modal.test.js
Normal file
12
ui_framework/components/modal/modal.test.js
Normal file
|
@ -0,0 +1,12 @@
|
|||
import React from 'react';
|
||||
import { render } from 'enzyme';
|
||||
import { requiredProps } from '../../test/required_props';
|
||||
|
||||
import {
|
||||
KuiModal,
|
||||
} from './modal';
|
||||
|
||||
test('renders KuiModal', () => {
|
||||
const component = <KuiModal { ...requiredProps }>children</KuiModal>;
|
||||
expect(render(component)).toMatchSnapshot();
|
||||
});
|
17
ui_framework/components/modal/modal_body.js
Normal file
17
ui_framework/components/modal/modal_body.js
Normal file
|
@ -0,0 +1,17 @@
|
|||
import React from 'react';
|
||||
import classnames from 'classnames';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
export function KuiModalBody({ className, children, ...rest }) {
|
||||
const classes = classnames('kuiModalBody', className);
|
||||
return (
|
||||
<div className={ classes } { ...rest }>
|
||||
{ children }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
KuiModalBody.propTypes = {
|
||||
className: PropTypes.string,
|
||||
children: PropTypes.node
|
||||
};
|
12
ui_framework/components/modal/modal_body.test.js
Normal file
12
ui_framework/components/modal/modal_body.test.js
Normal file
|
@ -0,0 +1,12 @@
|
|||
import React from 'react';
|
||||
import { render } from 'enzyme';
|
||||
import { requiredProps } from '../../test/required_props';
|
||||
|
||||
import {
|
||||
KuiModalBody,
|
||||
} from './modal_body';
|
||||
|
||||
test('renders KuiModalBody', () => {
|
||||
const component = <KuiModalBody { ...requiredProps }>children</KuiModalBody>;
|
||||
expect(render(component)).toMatchSnapshot();
|
||||
});
|
17
ui_framework/components/modal/modal_body_text.js
Normal file
17
ui_framework/components/modal/modal_body_text.js
Normal file
|
@ -0,0 +1,17 @@
|
|||
import React from 'react';
|
||||
import classnames from 'classnames';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
export function KuiModalBodyText({ className, children, ...rest }) {
|
||||
const classes = classnames('kuiModalBodyText', className);
|
||||
return (
|
||||
<div className={ classes } { ...rest }>
|
||||
{ children }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
KuiModalBodyText.propTypes = {
|
||||
className: PropTypes.string,
|
||||
children: PropTypes.node
|
||||
};
|
12
ui_framework/components/modal/modal_body_text.test.js
Normal file
12
ui_framework/components/modal/modal_body_text.test.js
Normal file
|
@ -0,0 +1,12 @@
|
|||
import React from 'react';
|
||||
import { render } from 'enzyme';
|
||||
import { requiredProps } from '../../test/required_props';
|
||||
|
||||
import {
|
||||
KuiModalBodyText,
|
||||
} from './modal_body_text';
|
||||
|
||||
test('renders KuiModalBodyText', () => {
|
||||
const component = <KuiModalBodyText { ...requiredProps }>children</KuiModalBodyText>;
|
||||
expect(render(component)).toMatchSnapshot();
|
||||
});
|
17
ui_framework/components/modal/modal_footer.js
Normal file
17
ui_framework/components/modal/modal_footer.js
Normal file
|
@ -0,0 +1,17 @@
|
|||
import React from 'react';
|
||||
import classnames from 'classnames';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
export function KuiModalFooter({ className, children, ...rest }) {
|
||||
const classes = classnames('kuiModalFooter', className);
|
||||
return (
|
||||
<div className={ classes } { ...rest }>
|
||||
{ children }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
KuiModalFooter.propTypes = {
|
||||
className: PropTypes.string,
|
||||
children: PropTypes.node
|
||||
};
|
12
ui_framework/components/modal/modal_footer.test.js
Normal file
12
ui_framework/components/modal/modal_footer.test.js
Normal file
|
@ -0,0 +1,12 @@
|
|||
import React from 'react';
|
||||
import { render } from 'enzyme';
|
||||
import { requiredProps } from '../../test/required_props';
|
||||
|
||||
import {
|
||||
KuiModalFooter,
|
||||
} from './modal_footer';
|
||||
|
||||
test('renders KuiModalFooter', () => {
|
||||
const component = <KuiModalFooter { ...requiredProps }>children</KuiModalFooter>;
|
||||
expect(render(component)).toMatchSnapshot();
|
||||
});
|
17
ui_framework/components/modal/modal_header.js
Normal file
17
ui_framework/components/modal/modal_header.js
Normal file
|
@ -0,0 +1,17 @@
|
|||
import React from 'react';
|
||||
import classnames from 'classnames';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
export function KuiModalHeader({ className, children, ...rest }) {
|
||||
const classes = classnames('kuiModalHeader', className);
|
||||
return (
|
||||
<div className={ classes } { ...rest }>
|
||||
{ children }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
KuiModalHeader.propTypes = {
|
||||
className: PropTypes.string,
|
||||
children: PropTypes.node
|
||||
};
|
12
ui_framework/components/modal/modal_header.test.js
Normal file
12
ui_framework/components/modal/modal_header.test.js
Normal file
|
@ -0,0 +1,12 @@
|
|||
import React from 'react';
|
||||
import { render } from 'enzyme';
|
||||
import { requiredProps } from '../../test/required_props';
|
||||
|
||||
import {
|
||||
KuiModalHeader,
|
||||
} from './modal_header';
|
||||
|
||||
test('renders KuiModalHeader', () => {
|
||||
const component = <KuiModalHeader { ...requiredProps }>children</KuiModalHeader>;
|
||||
expect(render(component)).toMatchSnapshot();
|
||||
});
|
17
ui_framework/components/modal/modal_header_title.js
Normal file
17
ui_framework/components/modal/modal_header_title.js
Normal file
|
@ -0,0 +1,17 @@
|
|||
import React from 'react';
|
||||
import classnames from 'classnames';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
export function KuiModalHeaderTitle({ className, children, ...rest }) {
|
||||
const classes = classnames('kuiModalHeader__title', className);
|
||||
return (
|
||||
<div className={ classes } { ...rest }>
|
||||
{ children }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
KuiModalHeaderTitle.propTypes = {
|
||||
className: PropTypes.string,
|
||||
children: PropTypes.node
|
||||
};
|
12
ui_framework/components/modal/modal_header_title.test.js
Normal file
12
ui_framework/components/modal/modal_header_title.test.js
Normal file
|
@ -0,0 +1,12 @@
|
|||
import React from 'react';
|
||||
import { render } from 'enzyme';
|
||||
import { requiredProps } from '../../test/required_props';
|
||||
|
||||
import {
|
||||
KuiModalHeaderTitle,
|
||||
} from './modal_header_title';
|
||||
|
||||
test('renders KuiModalHeaderTitle', () => {
|
||||
const component = <KuiModalHeaderTitle { ...requiredProps }>children</KuiModalHeaderTitle>;
|
||||
expect(render(component)).toMatchSnapshot();
|
||||
});
|
17
ui_framework/components/modal/modal_overlay.js
Normal file
17
ui_framework/components/modal/modal_overlay.js
Normal file
|
@ -0,0 +1,17 @@
|
|||
import React from 'react';
|
||||
import classnames from 'classnames';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
export function KuiModalOverlay({ className, ...rest }) {
|
||||
const classes = classnames('kuiModalOverlay', className);
|
||||
return (
|
||||
<div
|
||||
className={ classes }
|
||||
{ ...rest}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
KuiModalOverlay.propTypes = {
|
||||
className: PropTypes.string,
|
||||
};
|
12
ui_framework/components/modal/modal_overlay.test.js
Normal file
12
ui_framework/components/modal/modal_overlay.test.js
Normal file
|
@ -0,0 +1,12 @@
|
|||
import React from 'react';
|
||||
import { render } from 'enzyme';
|
||||
import { requiredProps } from '../../test/required_props';
|
||||
|
||||
import {
|
||||
KuiModalOverlay,
|
||||
} from './modal_overlay';
|
||||
|
||||
test('renders KuiModalOverlay', () => {
|
||||
const component = <KuiModalOverlay { ...requiredProps }>children</KuiModalOverlay>;
|
||||
expect(render(component)).toMatchSnapshot();
|
||||
});
|
3
ui_framework/dist/ui_framework.css
vendored
3
ui_framework/dist/ui_framework.css
vendored
|
@ -2118,7 +2118,8 @@ body {
|
|||
background-color: #FFF;
|
||||
border: 1px solid #6EADC1;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 5px 22px rgba(0, 0, 0, 0.25); }
|
||||
box-shadow: 0 5px 22px rgba(0, 0, 0, 0.25);
|
||||
z-index: 1001; }
|
||||
|
||||
.kuiModalHeader {
|
||||
display: -webkit-box;
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
import React from 'react';
|
||||
|
||||
import {
|
||||
KuiConfirmModal,
|
||||
KuiModalOverlay,
|
||||
KuiButton
|
||||
} from '../../../../components/index';
|
||||
|
||||
export class ConfirmModalExample extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
showConfirmModal: false
|
||||
};
|
||||
this.closeModal = this.closeModal.bind(this);
|
||||
this.showModal = this.showModal.bind(this);
|
||||
}
|
||||
|
||||
closeModal() {
|
||||
this.setState({ showConfirmModal: false });
|
||||
}
|
||||
|
||||
showModal() {
|
||||
this.setState({ showConfirmModal: true });
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<KuiButton type="primary" onClick={this.showModal}>
|
||||
Show Modal
|
||||
</KuiButton>
|
||||
{
|
||||
this.state.showConfirmModal ?
|
||||
<KuiModalOverlay>
|
||||
<KuiConfirmModal
|
||||
message="This is a confirmation modal example"
|
||||
title="A confirmation modal"
|
||||
onCancel={this.closeModal}
|
||||
onConfirm={this.closeModal}
|
||||
cancelButtonText="Cancel"
|
||||
confirmButtonText="Confirm"
|
||||
/>
|
||||
</KuiModalOverlay>
|
||||
: null
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
<div class="kuiModal" style="width: 450px">
|
||||
<div class="kuiModalHeader">
|
||||
<div class="kuiModalHeader__title">
|
||||
Delete object
|
||||
</div>
|
||||
|
||||
<div class="kuiModalHeaderCloseButton kuiIcon fa-times"></div>
|
||||
</div>
|
||||
|
||||
<div class="kuiModalBody">
|
||||
<div class="kuiModalBodyText">
|
||||
Are you sure you want to delete this object? You can’t undo this.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="kuiModalFooter">
|
||||
<button class="kuiButton kuiButton--hollow">
|
||||
No, cancel
|
||||
</button>
|
||||
|
||||
<button class="kuiButton kuiButton--primary">
|
||||
Yes, delete this object
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
|
@ -1,5 +1,7 @@
|
|||
import React from 'react';
|
||||
|
||||
import { renderToHtml } from '../../services';
|
||||
|
||||
import {
|
||||
GuideDemo,
|
||||
GuidePage,
|
||||
|
@ -7,38 +9,55 @@ import {
|
|||
GuideSectionTypes,
|
||||
} from '../../components';
|
||||
|
||||
const modalHtml = require('./modal.html');
|
||||
const modalOverlayHtml = require('./modal_overlay.html');
|
||||
const modalOverlayJs = require('raw!./modal_overlay.js');
|
||||
import {
|
||||
KuiConfirmModal,
|
||||
} from '../../../../components';
|
||||
|
||||
import { ConfirmModalExample } from './confirm_modal_example';
|
||||
const showConfirmModalSource = require('!!raw!./confirm_modal_example');
|
||||
const showConfirmModalHtml = renderToHtml(ConfirmModalExample);
|
||||
|
||||
const kuiConfirmModalSource = require('!!raw!../../../../components/modal/confirm_modal');
|
||||
const kuiConfirmModalHtml = renderToHtml(KuiConfirmModal);
|
||||
|
||||
export default props => (
|
||||
<GuidePage title={props.route.name}>
|
||||
|
||||
<GuideSection
|
||||
title="Modal"
|
||||
title="Confirmation Modal"
|
||||
source={[{
|
||||
type: GuideSectionTypes.JS,
|
||||
code: kuiConfirmModalSource,
|
||||
}, {
|
||||
type: GuideSectionTypes.HTML,
|
||||
code: modalHtml,
|
||||
code: kuiConfirmModalHtml,
|
||||
}]}
|
||||
>
|
||||
<GuideDemo
|
||||
html={modalHtml}
|
||||
/>
|
||||
<GuideDemo>
|
||||
<KuiConfirmModal
|
||||
onCancel={() => {}}
|
||||
onConfirm={() => {}}
|
||||
confirmButtonText="Confirm"
|
||||
cancelButtonText="Cancel"
|
||||
message="This is a confirmation modal"
|
||||
title="Confirm Modal Title"
|
||||
/>
|
||||
</GuideDemo>
|
||||
</GuideSection>
|
||||
|
||||
<GuideSection
|
||||
title="ModalOverlay"
|
||||
title="Pop up Confirmation Modal with Overlay"
|
||||
source={[{
|
||||
type: GuideSectionTypes.HTML,
|
||||
code: modalOverlayHtml,
|
||||
}, {
|
||||
type: GuideSectionTypes.JS,
|
||||
code: modalOverlayJs,
|
||||
code: showConfirmModalSource,
|
||||
}, {
|
||||
type: GuideSectionTypes.HTML,
|
||||
code: showConfirmModalHtml,
|
||||
}]}
|
||||
>
|
||||
<GuideDemo
|
||||
html={modalOverlayHtml}
|
||||
js={modalOverlayJs}
|
||||
/>
|
||||
<GuideDemo>
|
||||
<ConfirmModalExample />
|
||||
</GuideDemo>
|
||||
</GuideSection>
|
||||
</GuidePage>
|
||||
);
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
<button data-id="showModalOverlay">Show modal overlay</button>
|
||||
|
||||
<div class="kuiModalOverlay">
|
||||
<div class="kuiModal" style="width: 450px">
|
||||
<div class="kuiModalHeader">
|
||||
<div class="kuiModalHeader__title">
|
||||
Delete object
|
||||
</div>
|
||||
|
||||
<div class="kuiModalHeaderCloseButton kuiIcon fa-times"></div>
|
||||
</div>
|
||||
|
||||
<div class="kuiModalBody">
|
||||
<div class="kuiModalBodyText">
|
||||
Are you sure you want to delete this object? You can’t undo this.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="kuiModalFooter">
|
||||
<button class="kuiButton kuiButton--hollow">
|
||||
No, cancel
|
||||
</button>
|
||||
|
||||
<button class="kuiButton kuiButton--primary">
|
||||
Yes, delete this object
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -1,45 +0,0 @@
|
|||
/* eslint-disable */
|
||||
|
||||
const $showModalOverlayButton = $('[data-id="showModalOverlay"]');
|
||||
const $modalOverlay = $('.kuiModalOverlay');
|
||||
const $modalOverlayCloseButton = $('.kuiModalOverlay .kuiModalHeaderCloseButton');
|
||||
const $modalOverlayCancelButton = $('.kuiModalOverlay .kuiButton--hollow');
|
||||
const $modalOverlayConfirmButton = $('.kuiModalOverlay .kuiButton--primary');
|
||||
|
||||
if (!$showModalOverlayButton.length) {
|
||||
throw new Error('$showModalOverlayButton missing');
|
||||
}
|
||||
|
||||
if (!$modalOverlay.length) {
|
||||
throw new Error('$modalOverlay missing');
|
||||
}
|
||||
|
||||
if (!$modalOverlayCloseButton.length) {
|
||||
throw new Error('$modalOverlayCloseButton missing');
|
||||
}
|
||||
|
||||
if (!$modalOverlayCancelButton.length) {
|
||||
throw new Error('$modalOverlayCancelButton missing');
|
||||
}
|
||||
|
||||
if (!$modalOverlayConfirmButton.length) {
|
||||
throw new Error('$modalOverlayConfirmButton missing');
|
||||
}
|
||||
|
||||
$modalOverlay.hide();
|
||||
|
||||
$showModalOverlayButton.on('click', () => {
|
||||
$modalOverlay.show();
|
||||
});
|
||||
|
||||
$modalOverlayCloseButton.on('click', () => {
|
||||
$modalOverlay.hide();
|
||||
});
|
||||
|
||||
$modalOverlayCancelButton.on('click', () => {
|
||||
$modalOverlay.hide();
|
||||
});
|
||||
|
||||
$modalOverlayConfirmButton.on('click', () => {
|
||||
$modalOverlay.hide();
|
||||
});
|
Loading…
Add table
Add a link
Reference in a new issue