/test/setup.js"
53 | ],
54 | "testPathIgnorePatterns": [
55 | "/node_modules/",
56 | "lib/",
57 | "docs/"
58 | ]
59 | },
60 | "devDependencies": {
61 | "@storybook/addon-info": "^3.2.11",
62 | "@storybook/react": "^3.2.11",
63 | "autoprefixer": "^7.1.4",
64 | "babel-cli": "^6.26.0",
65 | "babel-core": "^6.26.0",
66 | "babel-eslint": "^8.0.1",
67 | "babel-jest": "^21.2.0",
68 | "babel-plugin-inline-import": "^2.0.4",
69 | "babel-plugin-react-transform": "^3.0.0",
70 | "babel-plugin-transform-react-constant-elements": "^6.23.0",
71 | "babel-plugin-transform-react-inline-elements": "^6.22.0",
72 | "babel-polyfill": "^6.26.0",
73 | "babel-preset-es2015": "^6.24.1",
74 | "babel-preset-react": "^6.24.1",
75 | "babel-preset-stage-0": "^6.24.1",
76 | "babel-register": "^6.26.0",
77 | "coveralls": "^3.0.0",
78 | "css-loader": "^0.28.7",
79 | "eslint": "^3.19.0",
80 | "eslint-config-airbnb": "^14.1.0",
81 | "eslint-plugin-import": "^2.2.0",
82 | "eslint-plugin-jsx-a11y": "^5.0.1",
83 | "eslint-plugin-react": "^6.10.2",
84 | "file-loader": "^1.1.4",
85 | "jest-cli": "^21.2.1",
86 | "json-loader": "^0.5.7",
87 | "less": "^2.7.2",
88 | "less-loader": "^4.0.5",
89 | "postcss-loader": "^1.3.3",
90 | "prop-types": "^15.5.10",
91 | "raw-loader": "^0.5.1",
92 | "react": "^16.0.0",
93 | "react-dom": "^16.0.0",
94 | "react-test-renderer": "^16.0.0",
95 | "release-relief": "^1.0.1",
96 | "style-loader": "^0.18.2",
97 | "uikit": "^3.0.0-beta.30",
98 | "url-loader": "^0.5.9"
99 | },
100 | "dependencies": {
101 | "classnames": "^2.2.5",
102 | "computed-style": "^0.3.0",
103 | "object-assign": "^4.1.1",
104 | "react-portal": "^3.1.0"
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/src/stories/Modal.js:
--------------------------------------------------------------------------------
1 | import { storiesOf, action } from '@storybook/react'
2 | import React, { Component } from 'react'
3 | import { Button, Modal } from '..'
4 |
5 | Modal.displayName = 'Modal'
6 |
7 | /* eslint-disable */
8 | class OpenButton extends Component {
9 | handleClick = (event) => {
10 | action('handleOpen')()
11 | this.props.onClick(event)
12 | }
13 | render() {
14 | const { handleClick } = this
15 | return
16 | }
17 | }
18 |
19 | class CancelButton extends Component {
20 | handleClick = () => {
21 | action('handleCancel')()
22 | this.props.handleClose()
23 | }
24 | render() {
25 | const { handleClick } = this
26 | return
27 | }
28 | }
29 |
30 | class SaveButton extends Component {
31 | handleClick = () => {
32 | action('handleSave')()
33 | this.props.handleClose()
34 | }
35 | render() {
36 | const { handleClick } = this
37 | return
38 | }
39 | }
40 | /* eslint-enable */
41 |
42 | const LoremIpsum = `Lorem ipsum dolor sit amet, consectetur adipisicing elit,
43 | sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
44 | Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
45 | commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum
46 | dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
47 | culpa qui officia deserunt mollit anim id est laborum.`
48 |
49 | storiesOf('Modal', module)
50 | .addWithInfo('Basic Usage', '', () => (
51 |
52 |
53 |
}>
54 |
Headline
55 |
{LoremIpsum}
56 |
57 |
58 | ), { header: false, inline: true, propTables: [Modal] })
59 | .addWithInfo('Header and Footer', '', () => (
60 |
61 |
}
65 | >
66 |
{LoremIpsum}
67 |
68 |
69 | ), { header: false, inline: true })
70 | .addWithInfo('Caption', '', () => (
71 |
72 |
}>
73 |
Headline
74 |
{LoremIpsum}
75 |
76 |
77 | ), { header: false, inline: true })
78 | .addWithInfo('Alert', '', () => (
79 |
80 | Alert}
83 | type="alert"
84 | onConfirm={action('onConfirm')}
85 | >
86 | Attention!
87 |
88 |
89 | ), { header: false, inline: true })
90 | .addWithInfo('Confirm', '', () => (
91 |
92 | Confirm}
98 | type="confirm"
99 | onCancel={action('onCancel')}
100 | onConfirm={action('onConfirm')}
101 | >
102 | Are you sure?
103 |
104 |
105 | ), { header: false, inline: true })
106 |
--------------------------------------------------------------------------------
/src/__tests__/__snapshots__/Input-test.js.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`Input renders correctly 1`] = `
4 |
7 | `;
8 |
9 | exports[`Input renders correctly 2`] = `
10 |
14 | `;
15 |
16 | exports[`Input renders correctly 3`] = `
17 |
20 | `;
21 |
22 | exports[`Input renders correctly 4`] = `
23 |
26 | `;
27 |
28 | exports[`Input renders correctly 5`] = `
29 |
32 | `;
33 |
34 | exports[`Input renders correctly 6`] = `
35 |
38 | `;
39 |
40 | exports[`Input renders correctly 7`] = `
41 |
44 | `;
45 |
46 | exports[`Input renders correctly 8`] = `
47 |
50 | `;
51 |
52 | exports[`Input renders correctly 9`] = `
53 |
56 | `;
57 |
58 | exports[`Input renders correctly 10`] = `
59 |
62 | `;
63 |
64 | exports[`Input renders correctly 11`] = `
65 |
68 | `;
69 |
70 | exports[`Input renders correctly 12`] = `
71 |
74 |
77 |
90 |
93 |
94 | `;
95 |
96 | exports[`Input renders correctly 13`] = `
97 |
100 |
103 |
116 |
119 |
120 | `;
121 |
122 | exports[`Input renders correctly 14`] = `
123 |
126 |
129 |
142 |
145 |
146 | `;
147 |
--------------------------------------------------------------------------------
/src/stories/Notification.js:
--------------------------------------------------------------------------------
1 | import { storiesOf, action } from '@storybook/react'
2 | import React, { PureComponent } from 'react'
3 | import PropTypes from 'prop-types'
4 | import { Notification, Button } from '..'
5 |
6 | class NotificationsContainer extends PureComponent {
7 | static propTypes = {
8 | position: PropTypes.string.isRequired,
9 | type: PropTypes.string.isRequired,
10 | icon: PropTypes.string, // eslint-disable-line react/require-default-props
11 | isSticky: PropTypes.bool, // eslint-disable-line react/require-default-props
12 | timeout: PropTypes.number, // eslint-disable-line react/require-default-props
13 | onClick: PropTypes.func, // eslint-disable-line react/require-default-props
14 | }
15 |
16 | static defaultProps = {
17 | isSticky: false,
18 | position: 'top-center',
19 | type: 'info',
20 | }
21 |
22 | state = {
23 | notifications: [],
24 | count: 1,
25 | }
26 |
27 | handleClick = (event) => {
28 | event.preventDefault()
29 | this.setState({
30 | notifications: [
31 | {
32 | id: this.state.count,
33 | type: this.props.type,
34 | icon: this.props.icon,
35 | message: `Notification #${this.state.count}`,
36 | isSticky: this.props.isSticky,
37 | timeout: this.props.timeout,
38 | onClick: this.props.onClick ? this.props.onClick : () => {},
39 | },
40 | ...this.state.notifications],
41 | count: this.state.count + 1,
42 | })
43 | }
44 |
45 | render() {
46 | const { notifications } = this.state
47 | const { position, type } = this.props
48 | return (
49 |
59 |
63 |
)
64 | }
65 | }
66 |
67 | Notification.displayName = 'Notification'
68 |
69 | storiesOf('Notification', module)
70 | .addWithInfo('Basic Usage', '', () => (
71 |
72 |
73 |
74 | ), { header: false, inline: true, propTables: [Notification] })
75 | .addWithInfo('Position', '', () => (
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 | ), { header: false, inline: true, propTables: [Notification] })
85 | .addWithInfo('Style', '', () => (
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 | ), { header: false, inline: true, propTables: [Notification] })
94 | .addWithInfo('Component options', '', () => (
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 | ), { header: false, inline: true, propTables: [Notification] })
103 |
--------------------------------------------------------------------------------
/src/stories/Dropdown.js:
--------------------------------------------------------------------------------
1 | import { storiesOf } from '@storybook/react'
2 | import cx from 'classnames'
3 | import React, { Component } from 'react'
4 | import PropTypes from 'prop-types'
5 |
6 | import { Button, Dropdown } from '..'
7 |
8 | // This is to work around: https://github.com/kadirahq/react-storybook-addon-info/issues/26#issuecomment-229029177
9 | Dropdown.displayName = 'Dropdown'
10 |
11 | const Nav = () => (
12 |
21 | )
22 |
23 | const Menu = () =>
24 | Menu.displayName = 'Menu'
25 |
26 | const LoremIpsum = `Lorem ipsum dolor sit amet, consectetur adipisicing elit,
27 | sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.`
28 |
29 | class MyDropdown extends Component {
30 | static propTypes = {
31 | className: PropTypes.string,
32 | onMouseEnter: PropTypes.func,
33 | onMouseLeave: PropTypes.func,
34 | }
35 |
36 | handleMouseLeave = () => {
37 | this.props.onMouseLeave()
38 | }
39 |
40 | handleMouseEnter = () => {
41 | this.props.onMouseEnter()
42 | }
43 |
44 | render() {
45 | const { ...props } = this.props
46 | const { handleMouseEnter, handleMouseLeave } = this
47 | return (
48 |
54 | {LoremIpsum}
55 |
56 | )
57 | }
58 | }
59 |
60 | storiesOf('Dropdown', module)
61 | .addWithInfo('Basic Usage', '', () => (
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 | ), { header: false, inline: true, propTables: [Dropdown] })
74 |
75 | .addWithInfo('Nav in dropdown', '', () => (
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 | ), { header: false, inline: true, propTables: [Dropdown] })
85 |
86 | .addWithInfo('Advanced', '', () => (
87 |
123 | ), { header: false, inline: true })
124 |
--------------------------------------------------------------------------------
/src/Dropdown.js:
--------------------------------------------------------------------------------
1 | import cx from 'classnames'
2 | import React, { Component, cloneElement } from 'react'
3 | import PropTypes from 'prop-types'
4 |
5 | const links = {}
6 |
7 | const subscribe = (namespace, listener) => {
8 | if (!links[namespace]) {
9 | links[namespace] = []
10 | }
11 |
12 | let isSubscribed = true
13 |
14 | links[namespace].push(listener)
15 |
16 | return function unsubscribe() {
17 | if (!isSubscribed) {
18 | return
19 | }
20 |
21 | isSubscribed = false
22 |
23 | const index = links[namespace].indexOf(listener)
24 | links[namespace].splice(index, 1)
25 | }
26 | }
27 | const dispatch = (namespace) => {
28 | const listeners = links[namespace]
29 | for (let i = 0; i < listeners.length; i++) { // eslint-disable-line no-plusplus
30 | const listener = listeners[i]
31 | listener()
32 | }
33 | }
34 |
35 | export default class Dropdown extends Component {
36 | static propTypes = {
37 | children: PropTypes.oneOfType([
38 | PropTypes.func,
39 | PropTypes.arrayOf(PropTypes.element),
40 | ]).isRequired,
41 | delay: PropTypes.number.isRequired,
42 | mode: PropTypes.oneOf(['hover', 'click']).isRequired,
43 | remainTime: PropTypes.number.isRequired,
44 | className: PropTypes.string,
45 | component: PropTypes.node,
46 | link: PropTypes.string,
47 | }
48 |
49 | static defaultProps = {
50 | mode: 'hover',
51 | remainTime: 800,
52 | delay: 0,
53 | component: 'div',
54 | link: '',
55 | className: 'uk-inline',
56 | }
57 |
58 | state = {
59 | isOpen: false,
60 | }
61 |
62 | componentDidMount() {
63 | if (this.props.link) {
64 | // listen to linked components
65 | this.unsubscribe = subscribe(this.props.link, () => {
66 | if (this.state.isOpen) {
67 | this.setState({ isOpen: false })
68 | }
69 | })
70 | }
71 | }
72 |
73 | componentWillUnmount() {
74 | if (this.leaveTimeout) {
75 | clearTimeout(this.leaveTimeout)
76 | }
77 |
78 | if (this.unsubscribe) {
79 | this.unsubscribe()
80 | this.unsubscribe = false
81 | }
82 | }
83 |
84 | handleMouseEnter = () => {
85 | if (this.leaveTimeout) {
86 | clearTimeout(this.leaveTimeout)
87 | }
88 | if (this.props.delay) {
89 | setTimeout(() => {
90 | this.setState({ isOpen: true })
91 | }, this.props.delay)
92 | } else {
93 | if (this.props.link) {
94 | dispatch(this.props.link)
95 | }
96 | this.setState({ isOpen: true })
97 | }
98 |
99 | if (this.props.mode === 'hover') {
100 | this.setState({ isOpen: true })
101 | }
102 | }
103 |
104 | handleMouseLeave = () => {
105 | if (this.props.remainTime) {
106 | this.leaveTimeout = setTimeout(() => {
107 | this.setState({ isOpen: false })
108 | }, this.props.remainTime)
109 | } else {
110 | this.setState({ isOpen: false })
111 | }
112 | }
113 |
114 | handleClick = () => {
115 | if (this.props.mode === 'click') {
116 | this.setState({ isOpen: !this.state.isOpen })
117 | }
118 |
119 | if (this.props.mode === 'hover') {
120 | this.setState({ isOpen: false })
121 | }
122 | }
123 |
124 | render() {
125 | const { handleMouseEnter, handleMouseLeave, handleClick } = this
126 | const { mode, component, children, className } = this.props
127 | const { isOpen } = this.state
128 |
129 | const eventHandlers = {
130 | onClick: handleClick,
131 | }
132 | if (mode === 'hover') {
133 | eventHandlers.onMouseEnter = handleMouseEnter
134 | eventHandlers.onMouseLeave = handleMouseLeave
135 | }
136 |
137 | if (typeof children === 'function') {
138 | return children({ isOpen, ...eventHandlers })
139 | }
140 |
141 | if (!Array.isArray(children) || children.length !== 2) {
142 | throw new Error('Children must be passed as array and must have two components.')
143 | }
144 | const [target, body] = children
145 |
146 | // construct target Element
147 | const targetElement = cloneElement(target, {
148 | ...target.props,
149 | ...eventHandlers,
150 | className: cx(target.props.className, {
151 | 'uk-open': isOpen,
152 | }),
153 | })
154 |
155 | // construct body Element
156 | const bodyElement = cloneElement(body, {
157 | ...body.props,
158 | ...eventHandlers,
159 | className: cx(body.props.className, {
160 | 'uk-open': isOpen,
161 | }),
162 | })
163 |
164 | const WrapperComponent = component
165 |
166 | return (
167 |
168 | {targetElement}
169 | {bodyElement}
170 |
171 | )
172 | }
173 | }
174 |
--------------------------------------------------------------------------------
/src/Modal/index.js:
--------------------------------------------------------------------------------
1 | import classNames from 'classnames'
2 | import React, { Component } from 'react'
3 | import PropTypes from 'prop-types'
4 | import Portal from 'react-portal'
5 |
6 | import Button from '../Button'
7 | import Dialog from './Dialog'
8 | import Prompt from './Prompt'
9 |
10 | export default class Modal extends Component {
11 |
12 | static propTypes = {
13 | children: PropTypes.node.isRequired,
14 | target: PropTypes.element.isRequired,
15 | cancelButtonClass: PropTypes.string,
16 | cancelLabel: PropTypes.string,
17 | confirmButtonClass: PropTypes.string,
18 | confirmLabel: PropTypes.string,
19 | isOpen: PropTypes.bool,
20 | type: PropTypes.string,
21 | onCancel: PropTypes.func, // eslint-disable-line react/require-default-props
22 | onConfirm: PropTypes.func, // eslint-disable-line react/require-default-props
23 | }
24 |
25 | static defaultProps = {
26 | cancelButtonClass: '',
27 | cancelLabel: 'Cancel',
28 | closeTimeoutMS: 0,
29 | confirmButtonClass: '',
30 | confirmLabel: 'Ok',
31 | isOpen: false,
32 | lightbox: false,
33 | shouldCloseOnOverlayClick: true,
34 | target: 'button',
35 | type: 'default',
36 | }
37 |
38 | state = { shouldDisplay: false, isOpen: false }
39 |
40 | setModal = (node) => {
41 | if (node) {
42 | this.modal = node
43 | }
44 | }
45 |
46 | handleClick = () => {
47 | this.setState({ shouldDisplay: !this.state.shouldDisplay })
48 | }
49 |
50 | handleOpen = () => {
51 | setTimeout(() => this.setState({ isOpen: true }), 0)
52 | }
53 |
54 | handleClose = (callback) => {
55 | this.setState(
56 | { isOpen: false },
57 | () => setTimeout(
58 | () => {
59 | this.modal.closePortal()
60 | if (typeof callback === 'function') {
61 | callback()
62 | }
63 | },
64 | 300
65 | )
66 | )
67 | }
68 |
69 | handleBeforeClose = (DOMNode, removeFromDOM) => {
70 | this.setState(
71 | { isOpen: false },
72 | () => setTimeout(removeFromDOM, 300)
73 | )
74 | }
75 |
76 | handleAfterClose = () => {
77 | this.setState({ shouldDisplay: false })
78 | }
79 |
80 | handleConfirm = () => {
81 | this.props.onConfirm()
82 | this.handleClose()
83 | }
84 |
85 | handleCancel = () => {
86 | this.props.onCancel()
87 | this.handleClose()
88 | }
89 |
90 | render() {
91 | const {
92 | handleClose,
93 | handleOpen,
94 | handleConfirm,
95 | handleCancel,
96 | handleAfterClose,
97 | handleBeforeClose,
98 | setModal,
99 | } = this
100 | const {
101 | isOpen,
102 | type,
103 | confirmLabel,
104 | cancelLabel,
105 | target,
106 | } = this.props
107 |
108 | const className = classNames('uk-modal', {
109 | 'uk-open': this.state.isOpen,
110 | })
111 | const style = {
112 | display: 'block',
113 | }
114 |
115 | let footer = []
116 | if (type === 'alert') {
117 | footer = [
118 | () => (
119 |
125 | ),
126 | ]
127 | }
128 |
129 | if (type === 'confirm' || type === 'prompt') {
130 | footer = [
131 | () => (
132 |
135 | ),
136 | () => ,
137 | () => (
138 |
145 | ),
146 | ]
147 | }
148 | const { children, ...dialogProps } = this.props
149 |
150 | let dialogChildren
151 | if (type === 'prompt') {
152 | dialogChildren = {children}
153 | } else {
154 | dialogChildren = children
155 | }
156 |
157 | return (
158 |
167 |
173 |
181 |
182 |
183 | )
184 | }
185 | }
186 |
--------------------------------------------------------------------------------
/docs/logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
34 |
--------------------------------------------------------------------------------
/docs/logo-inverse.svg:
--------------------------------------------------------------------------------
1 |
2 |
34 |
--------------------------------------------------------------------------------
/.storybook/static/logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
34 |
--------------------------------------------------------------------------------
/.storybook/static/logo-inverse.svg:
--------------------------------------------------------------------------------
1 |
2 |
34 |
--------------------------------------------------------------------------------
/src/Modal/__tests__/index-test.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import renderer from 'react-test-renderer'
3 | import Modal from '../index'
4 |
5 | jest.mock('react-portal', () => 'Portal')
6 | jest.useFakeTimers()
7 |
8 | function createNodeMock(element) {
9 | if (element.type === 'modal') {
10 | return {
11 | focus() {},
12 | }
13 | }
14 | return null
15 | }
16 |
17 | describe('Modal', () => {
18 | it('renders correctly', () => {
19 | const options = { createNodeMock }
20 | const component = renderer.create(
21 | Open}>Lorem ipsum, options
22 | )
23 | expect(component.toJSON()).toMatchSnapshot()
24 | })
25 |
26 | it('renders a Header and Footer', () => {
27 | const component = renderer.create(
28 | ,
32 | ]}
33 | header="Headline"
34 | target={}
35 | >
36 | Lorem ipsum
37 |
38 | )
39 | expect(component.toJSON()).toMatchSnapshot()
40 | })
41 |
42 | it('renders a Caption', () => {
43 | const component = renderer.create(
44 | Open}
47 | >
48 | Lorem ipsum
49 |
50 | )
51 | expect(component.toJSON()).toMatchSnapshot()
52 | })
53 |
54 | it('renders a Lightbox', () => {
55 | const component = renderer.create(
56 | Open}
59 | >
60 |
61 |
62 | )
63 | expect(component.toJSON()).toMatchSnapshot()
64 | })
65 |
66 | it('renders a Blank Modal', () => {
67 | const component = renderer.create(
68 | Open}
71 | >
72 |
86 |
87 | )
88 | expect(component.toJSON()).toMatchSnapshot()
89 | })
90 |
91 | it('renders a Spinner', () => {
92 | const component = renderer.create(
93 | Open}
96 | >
97 |
98 |
99 | )
100 | expect(component.toJSON()).toMatchSnapshot()
101 | })
102 |
103 | it('renders an alert modal', () => {
104 | const component = renderer.create(
105 | Open}
107 | type="alert"
108 | >
109 | Something bad happened!
110 |
111 | )
112 | expect(component.toJSON()).toMatchSnapshot()
113 | })
114 |
115 | it('renders an confirm modal', () => {
116 | const component = renderer.create(
117 | Open}
119 | type="confirm"
120 | >
121 | Are you absolutely sure about this?
122 |
123 | )
124 | expect(component.toJSON()).toMatchSnapshot()
125 | })
126 |
127 | it('renders an prompt modal', () => {
128 | const component = renderer.create(
129 | Open}
131 | type="prompt"
132 | >
133 | Please enter the name of the repo you"re deleting:
134 |
135 | )
136 | expect(component.toJSON()).toMatchSnapshot()
137 | })
138 |
139 | let component = renderer.create(
140 | Open}
142 | >
143 | Lorem ipsum
144 |
145 | )
146 |
147 | it('should handle handleClick', () => {
148 | const instance = component.getInstance()
149 | instance.handleClick()
150 | expect(instance.state.shouldDisplay).toBeTruthy()
151 | })
152 |
153 | it('should handle handleOpen', () => {
154 | const instance = component.getInstance()
155 | instance.handleOpen()
156 | jest.runAllTimers()
157 | expect(instance.state.isOpen).toBeTruthy()
158 | })
159 |
160 | it('should handle handleClose', () => {
161 | const instance = component.getInstance()
162 | instance.closePortal = jest.fn()
163 | instance.handleClose()
164 | expect(instance.state.isOpen).toBeFalsy()
165 | })
166 |
167 | it('should handle callback function if handleClose has it', () => {
168 | const instance = component.getInstance()
169 | const callback = jest.fn()
170 | instance.closePortal = jest.fn()
171 | instance.handleClose(callback)
172 | expect(instance.state.isOpen).toBeFalsy()
173 | })
174 |
175 | it('should set modal ref to Portal', () => {
176 | const instance = component.getInstance()
177 | const node = { closePortal: jest.fn() }
178 | instance.setModal(node)
179 | instance.handleClose()
180 | jest.runAllTimers()
181 | expect(node.closePortal).toHaveBeenCalled()
182 | })
183 |
184 | it('should handle handleAfterClose', () => {
185 | const instance = component.getInstance()
186 | instance.handleAfterClose()
187 | expect(instance.state.shouldDisplay).toBeFalsy()
188 | })
189 |
190 | it('should handle handleBeforeClose', () => {
191 | const instance = component.getInstance()
192 | instance.handleBeforeClose({ removeFromDOM: jest.fn() })
193 | expect(instance.state.isOpen).toBeFalsy()
194 | })
195 |
196 | component = renderer.create(
197 | Confirm}
200 | type="confirm"
201 | onCancel={jest.fn()}
202 | onConfirm={jest.fn()}
203 | >
204 | Are you sure?
205 |
206 | )
207 |
208 | it('should handle handleCancel', () => {
209 | const instance = component.getInstance()
210 | instance.handleCancel()
211 | expect(instance.props.onCancel).toHaveBeenCalled()
212 | })
213 |
214 | it('should handle handleConfirm', () => {
215 | const instance = component.getInstance()
216 | instance.handleConfirm()
217 | expect(instance.props.onConfirm).toHaveBeenCalled()
218 | })
219 | })
220 |
--------------------------------------------------------------------------------
/src/__tests__/Dropdown-test.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import renderer from 'react-test-renderer'
3 | import cx from 'classnames'
4 | import Dropdown from '../Dropdown'
5 | import Button from '../Button'
6 |
7 | jest.useFakeTimers()
8 | const LoremIpsum = 'Lorem ipsum dolor sit amet, consectetur adipisicing elit'
9 |
10 | it('renders correctly', () => {
11 | expect(renderer.create(
12 |
13 |
14 |
15 | {LoremIpsum}
16 |
17 |
18 | ).toJSON()).toMatchSnapshot()
19 |
20 | expect(renderer.create(
21 |
22 |
23 |
24 |
25 | - Active
26 | - Item
27 |
28 |
29 |
30 | ).toJSON()).toMatchSnapshot()
31 | })
32 |
33 | it('changes the class when hovered', () => {
34 | let component = renderer.create(
35 |
36 |
37 |
38 | {LoremIpsum}
39 |
40 |
41 | )
42 | let tree = component.toJSON()
43 | expect(tree).toMatchSnapshot()
44 |
45 | let instance = component.getInstance()
46 |
47 | // manually trigger the callback
48 | instance.handleMouseEnter()
49 | expect(component.toJSON()).toMatchSnapshot()
50 |
51 | // manually trigger the callback
52 | instance = component.getInstance()
53 | instance.handleMouseLeave()
54 | expect(component.toJSON()).toMatchSnapshot()
55 |
56 | // Fast forward timers, class should now be gone
57 | jest.runAllTimers()
58 | expect(component.toJSON()).toMatchSnapshot()
59 |
60 | instance = component.getInstance()
61 | instance.handleMouseEnter()
62 | expect(instance.state.isOpen).toBeTruthy()
63 |
64 | component = renderer.create(
65 |
66 |
67 |
68 | {LoremIpsum}
69 |
70 |
71 | )
72 | instance = component.getInstance()
73 | instance.handleMouseEnter()
74 | expect(instance.state.isOpen).toBeTruthy()
75 |
76 | jest.runAllTimers()
77 | tree = component.toJSON()
78 | expect(tree).toMatchSnapshot()
79 |
80 | instance.handleMouseLeave()
81 | jest.runAllTimers()
82 | expect(tree).toMatchSnapshot()
83 | expect(instance.state.isOpen).toBe(false)
84 | })
85 |
86 | it('changes the class when clicked', () => {
87 | const component = renderer.create(
88 |
89 |
90 |
91 | {LoremIpsum}
92 |
93 |
94 | )
95 | let tree = component.toJSON()
96 | expect(tree).toMatchSnapshot()
97 |
98 | // manually trigger the callback
99 | tree.children[0].props.onClick()
100 |
101 | // re-rendering
102 | tree = component.toJSON()
103 | expect(tree).toMatchSnapshot()
104 |
105 | // manually trigger the callback
106 | tree.children[0].props.onClick()
107 |
108 | // re-rendering
109 | tree = component.toJSON()
110 | expect(tree).toMatchSnapshot()
111 | })
112 |
113 | it('closes sibling Dropdown on open', () => {
114 | const firstComponent = renderer.create(
115 |
116 |
117 |
118 | {LoremIpsum}
119 |
120 |
121 | )
122 | let first = firstComponent.toJSON()
123 | expect(first).toMatchSnapshot()
124 |
125 | const firstInstance = firstComponent.getInstance()
126 |
127 | // manually trigger the callback
128 | firstInstance.handleMouseEnter()
129 |
130 | first = firstComponent.toJSON()
131 | expect(first).toMatchSnapshot()
132 | expect(firstInstance.state.isOpen).toBe(true)
133 |
134 | const secondComponent = renderer.create(
135 |
136 |
137 |
138 | {LoremIpsum}
139 |
140 |
141 | )
142 | let second = secondComponent.toJSON()
143 | expect(second).toMatchSnapshot()
144 |
145 | const secondInstance = secondComponent.getInstance()
146 |
147 | // manually trigger the callback
148 | secondInstance.handleMouseEnter()
149 |
150 | // Verify that it is open
151 | second = secondComponent.toJSON()
152 | expect(second).toMatchSnapshot('should be open')
153 | expect(secondInstance.state.isOpen).toBe(true)
154 |
155 | // Verify that the first component is closed
156 | first = firstComponent.toJSON()
157 | expect(first).toMatchSnapshot('should be closed')
158 | expect(firstInstance.state.isOpen).toBe(false)
159 |
160 | // Verify there is a subscription
161 | expect({}.hasOwnProperty.call(secondInstance, 'unsubscribe')).toBe(true)
162 | const unsubscribe = secondInstance.unsubscribe
163 |
164 | // Start leave timeout before unmount
165 | secondInstance.handleMouseLeave()
166 |
167 | // Trigger unmount
168 | secondComponent.update()
169 | // Should be no error from calling this again
170 | unsubscribe()
171 | })
172 |
173 | it('closes when clicked when in hover mode', () => {
174 | const component = renderer.create(
175 |
176 |
177 |
178 | {LoremIpsum}
179 |
180 |
181 | )
182 | let tree = component.toJSON()
183 | const treeInstance = component.getInstance()
184 |
185 | // clicking the dropdown should not open it
186 | treeInstance.handleClick()
187 | tree = component.toJSON()
188 | expect(treeInstance.state.isOpen).toBe(false)
189 |
190 | // open the dropdown
191 | treeInstance.handleMouseEnter()
192 | tree = component.toJSON()
193 | expect(tree).toMatchSnapshot()
194 | expect(treeInstance.state.isOpen).toBe(true)
195 |
196 | // close the dropdown by click
197 | treeInstance.handleClick()
198 | tree = component.toJSON()
199 | expect(tree).toMatchSnapshot()
200 | expect(treeInstance.state.isOpen).toBe(false)
201 |
202 | // clicking the dropdown again shouldn't open it
203 | treeInstance.handleClick()
204 | tree = component.toJSON()
205 | expect(tree).toMatchSnapshot()
206 | expect(treeInstance.state.isOpen).toBe(false)
207 | })
208 |
209 | it('it should throw Invalid proptytype error on invalid children', () => {
210 | expect(() => {
211 | const component = renderer.create(
212 |
213 |
214 |
215 | )
216 | component.toJSON()
217 | }).toThrowErrorMatchingSnapshot()
218 |
219 | expect(() => {
220 | const component = renderer.create(
221 |
222 |
223 |
224 |
225 |
226 | )
227 | component.toJSON()
228 | }).toThrowError('Children must be passed as array and must have two components.')
229 | })
230 |
231 | it('it should render correctly when children are passed as function', () => {
232 | const component = renderer.create(
233 |
234 | {({ open, onClick }) => (
235 |
236 |
237 |
238 | Dropdown content here
239 |
240 |
241 | )}
242 |
243 | )
244 | const tree = component.toJSON()
245 | expect(tree).toMatchSnapshot()
246 | })
247 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 | All notable changes to this project will be documented in this file.
3 |
4 | The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
5 | and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
6 |
7 | ## [Unreleased]
8 | ### Changed
9 | * Migrated to UIkit v3
10 |
11 | ## [2.3.2] - 2017-05-13
12 | ### Bugfixes
13 | * Accidentally published v3 beta on `latest` tag.
14 |
15 | ## [2.3.1] - 2017-03-17
16 | ### Changed
17 | * Fixed broken logo in readme.
18 |
19 | ## [2.3.0] - 2017-03-09
20 | ### Bugfixes
21 | * Clicking inside a `Dropdown` when in hover mode closes it.
22 |
23 | ## [2.2.0] - 2017-03-02
24 | ### Bugfixes
25 | * `Dropdown` component was not clearing its hover timeout when unmounting.
26 |
27 | ### Features
28 | * `Dropdown` component got a link prop to prevent sibling dropdowns from overlapping.
29 |
30 | ## [2.1.1] - 2017-02-06
31 | ### Bugfixes
32 | * `Notify` component was not passing `icon` props in the storybook.
33 | * Added space between NotifyMesssage and `icon` if `icon` is added.
34 |
35 | ## [2.1.0] - 2017-01-04
36 | * Added two props, `confirmButtonClass` and `cancelButtonClass` to footer buttons that allows to pass CSS classes.
37 | * `handleClose` allows callbacks.
38 | * `Notify` component allows to pass `onClick` props that can be used trigger `onClick` event on `NotifyMesssage`
39 |
40 | ## [2.0.0] - 2016-11-22
41 | ### Bugfixes
42 | * `Notify` component was not passing all the props.
43 |
44 | ### Breaking Changes
45 | * `Modal` component needs to pass `target` as Element instead of Node. `target` is required.
46 |
47 | ### Coverage
48 | * uikit-react has 100% test coverage now.
49 |
50 | ### Features
51 | * `Modal` component is rendered using [react-portal](https://github.com/tajo/react-portal) for better positioning and styling
52 |
53 | ## [1.0.0] - 2016-11-10
54 | ### Added
55 | * Added new component [Notify](http://uikit-react.io/?selectedKind=Notify&selectedStory=Basic%20Usage&full=0&down=1&left=1&panelRight=0&downPanel=kadirahq%2Fstorybook-addon-actions%2Factions-panel).
56 |
57 | ## [0.6.2] - 2016-08-24
58 | ### Documentation
59 | * add reference to [redux-form-uikit](https://github.com/stipsan/redux-form-uikit). (#173)
60 |
61 | ## [0.6.1] - 2016-08-23
62 | ### Features
63 | * Improved icon support in [Input](http://uikit-react.io/?selectedKind=Input&selectedStory=Form%20and%20icons&full=0&down=0&left=1&panelRight=0) component. You can `flip` the icon position, and `icon="spinner"` and `icon="refresh"` will have a spinning animation applied. (#171)
64 |
65 | ### Documentation
66 | * The Select component is removed from readme and storybook until it's stable. It's still available but it's not recommended to use it in production as its API is likely to change. (#172)
67 |
68 | ## [0.6.0] - 2016-08-23
69 | ### Features
70 | * New [Input](http://uikit-react.io/?selectedKind=Input&selectedStory=Basic%20Usage&full=0&down=0&left=1&panelRight=0) component added (#169)
71 |
72 | ### Documentation
73 | * Readme updated with links to each component.
74 | * npm homepage link points to [uikit-react.io](https://uikit-react.io/) instead of the GitHub project page.
75 |
76 | ## [0.5.0] - 2016-08-19
77 | ### Breaking Changes
78 | * SCSS source of Select component removed, all in on LESS now.
79 |
80 | ### Documentation
81 | * [uikit-react.io](https://uikit-react.io/) is now using the gradient theme.
82 |
83 | ## [0.4.1] - 2016-08-19
84 | ### Documentation
85 | * Typos in README.md (#157)
86 | * Added GA tracking to [uikit-react.io](https://uikit-react.io/) (#159).
87 |
88 | ## [0.4.0] - 2016-08-18
89 | ### Features
90 | * New [Modal](http://uikit-react.io/?selectedKind=Modal&selectedStory=Basic%20Usage&full=0&down=0&left=1&panelRight=0) component added.
91 |
92 | ## [0.3.0] - 2016-08-13
93 | ### Breaking Changes
94 | * `` no longer toggles `.uk-active` on clicks and is no longer a stateful Component (#142)
95 |
96 | ## [0.2.0] - 2016-08-11
97 | ### Features
98 | * [Dropdown](https://uikit-react.io/?selectedKind=Dropdown&selectedStory=Basic%20Usage&full=0&down=1&left=1&panelRight=0) got a `component` prop that controls the rendering of the dropdown wrapper.
99 |
100 | ### Storybook
101 | * Check out the new [Advanced](https://uikit-react.io/?selectedKind=Dropdown&selectedStory=Advanced&full=0&down=1&left=1&panelRight=0) Dropdown story to see how this new prop lets you use `` inside a navbar.
102 |
103 | ## [0.1.2] - 2016-08-09
104 | ### Bugfixes
105 | * `scss` folder was in the wrong location
106 |
107 | ## [0.1.1] - 2016-08-09
108 | ### Features
109 | * `scss` folder now included on npm
110 |
111 | ### Example
112 |
113 | Here's how you can import the styling for the [Select](http://uikit-react.io/?selectedKind=Select&selectedStory=Basic%20Usage&full=0&down=1&left=1&panelRight=0) component assuming you're using webpack and sass-loader:
114 | ```scss
115 | @import "~uikit-react/scss/Select.scss";
116 | ```
117 |
118 | A complete example if you only need the styling required to render the `uikit-react` components, assuming you already have `uikit` as a dependency in your `package.json`:
119 |
120 | ```scss
121 | $icon-font-path: "~uikit/dist/fonts";
122 |
123 | @import "~uikit/dist/scss/uikit-mixins.scss";
124 | @import "~uikit/dist/scss/uikit-variables.scss";
125 | @import "~uikit/dist/scss/uikit.scss";
126 | @import "~uikit/dist/scss/components/autocomplete.scss";
127 | @import "~uikit/dist/scss/components/form-advanced.scss";
128 |
129 | @import "~uikit-react/scss/Select.scss";
130 | ```
131 |
132 | ## [0.1.0] - 2016-08-08
133 | ### Features
134 | * [Select](http://uikit-react.io/?selectedKind=Select&selectedStory=Basic%20Usage&full=0&down=0&left=1&panelRight=0) component added, a fork of react-select adapted to reuse as much UIkit markup as possible.
135 |
136 | ### Documentation
137 | * [uikit-react.io](https://uikit-react.io) storybook site updated with a navbar with logo.
138 |
139 | ### Bugfixes
140 | * Storybook on [uikit-react.io](https://uikit-react.io) no longer minifies the component name.
141 |
142 | ## [0.1.0-alpha.2] - 2016-08-01
143 | ### Features
144 | * added simple [Button](http://uikit-react.io/?selectedKind=Button&full=0&down=0&left=1&panelRight=0) component.
145 | * added simple [Dropdown](http://uikit-react.io/?selectedKind=Dropdown&selectedStory=Basic%20Usage&full=0&down=0&left=1&panelRight=0) component.
146 |
147 | ### Docs
148 | In the initial alphas we had a docs site up on firebase: https://uikit-react.firebaseapp.com/#/
149 | But instead of a conventional OSS project site we decided to host the React Storybook of the project here: [uikit-react.io](https://uikit-react.io) which will serve as documentation and usage examples of the UIkit React components included in `uikit-react`
150 |
151 | Proved stable enough for a stable semver major version 💃
152 |
153 | [Unreleased]: https://github.com/stipsan/uikit-react/compare/v2.3.2...HEAD
154 | [2.3.2]: https://github.com/stipsan/uikit-react/compare/v2.3.1...v2.3.2
155 | [2.3.1]: https://github.com/stipsan/uikit-react/compare/v2.3.0...v2.3.1
156 | [2.3.0]: https://github.com/stipsan/uikit-react/compare/v2.2.0...v2.3.0
157 | [2.2.0]: https://github.com/stipsan/uikit-react/compare/v2.1.1...v2.2.0
158 | [2.1.1]: https://github.com/stipsan/uikit-react/compare/v2.1.0...v2.1.1
159 | [2.1.0]: https://github.com/stipsan/uikit-react/compare/v2.0.0...v2.1.0
160 | [2.0.0]: https://github.com/stipsan/uikit-react/compare/v1.0.0...v2.0.0
161 | [1.0.0]: https://github.com/stipsan/uikit-react/compare/v0.6.2...v1.0.0
162 | [0.6.2]: https://github.com/stipsan/uikit-react/compare/v0.6.1...v0.6.2
163 | [0.6.1]: https://github.com/stipsan/uikit-react/compare/v0.6.0...v0.6.1
164 | [0.6.0]: https://github.com/stipsan/uikit-react/compare/v0.5.0...v0.6.0
165 | [0.5.0]: https://github.com/stipsan/uikit-react/compare/v0.4.1...v0.5.0
166 | [0.4.1]: https://github.com/stipsan/uikit-react/compare/v0.4.0...v0.4.1
167 | [0.4.0]: https://github.com/stipsan/uikit-react/compare/v0.3.0...v0.4.0
168 | [0.3.0]: https://github.com/stipsan/uikit-react/compare/v0.2.0...v0.3.0
169 | [0.2.0]: https://github.com/stipsan/uikit-react/compare/v0.1.2...v0.2.0
170 | [0.1.2]: https://github.com/stipsan/uikit-react/compare/v0.1.1...v0.1.2
171 | [0.1.1]: https://github.com/stipsan/uikit-react/compare/v0.1.0...v0.1.1
172 | [0.1.0]: https://github.com/stipsan/uikit-react/compare/v0.1.0-alpha.2...v0.1.0
173 |
--------------------------------------------------------------------------------
/src/__tests__/__snapshots__/Dropdown-test.js.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`changes the class when clicked 1`] = `
4 |
7 |
14 |
18 | Lorem ipsum dolor sit amet, consectetur adipisicing elit
19 |
20 |
21 | `;
22 |
23 | exports[`changes the class when clicked 2`] = `
24 |
27 |
34 |
38 | Lorem ipsum dolor sit amet, consectetur adipisicing elit
39 |
40 |
41 | `;
42 |
43 | exports[`changes the class when clicked 3`] = `
44 |
47 |
54 |
58 | Lorem ipsum dolor sit amet, consectetur adipisicing elit
59 |
60 |
61 | `;
62 |
63 | exports[`changes the class when hovered 1`] = `
64 |
67 |
76 |
82 | Lorem ipsum dolor sit amet, consectetur adipisicing elit
83 |
84 |
85 | `;
86 |
87 | exports[`changes the class when hovered 2`] = `
88 |
91 |
100 |
106 | Lorem ipsum dolor sit amet, consectetur adipisicing elit
107 |
108 |
109 | `;
110 |
111 | exports[`changes the class when hovered 3`] = `
112 |
115 |
124 |
130 | Lorem ipsum dolor sit amet, consectetur adipisicing elit
131 |
132 |
133 | `;
134 |
135 | exports[`changes the class when hovered 4`] = `
136 |
139 |
148 |
154 | Lorem ipsum dolor sit amet, consectetur adipisicing elit
155 |
156 |
157 | `;
158 |
159 | exports[`changes the class when hovered 5`] = `
160 |
163 |
172 |
178 | Lorem ipsum dolor sit amet, consectetur adipisicing elit
179 |
180 |
181 | `;
182 |
183 | exports[`changes the class when hovered 6`] = `
184 |
187 |
196 |
202 | Lorem ipsum dolor sit amet, consectetur adipisicing elit
203 |
204 |
205 | `;
206 |
207 | exports[`closes sibling Dropdown on open 1`] = `
208 |
211 |
220 |
226 | Lorem ipsum dolor sit amet, consectetur adipisicing elit
227 |
228 |
229 | `;
230 |
231 | exports[`closes sibling Dropdown on open 2`] = `
232 |
235 |
244 |
250 | Lorem ipsum dolor sit amet, consectetur adipisicing elit
251 |
252 |
253 | `;
254 |
255 | exports[`closes sibling Dropdown on open 3`] = `
256 |
259 |
268 |
274 | Lorem ipsum dolor sit amet, consectetur adipisicing elit
275 |
276 |
277 | `;
278 |
279 | exports[`closes when clicked when in hover mode 1`] = `
280 |
283 |
292 |
298 | Lorem ipsum dolor sit amet, consectetur adipisicing elit
299 |
300 |
301 | `;
302 |
303 | exports[`closes when clicked when in hover mode 2`] = `
304 |
307 |
316 |
322 | Lorem ipsum dolor sit amet, consectetur adipisicing elit
323 |
324 |
325 | `;
326 |
327 | exports[`closes when clicked when in hover mode 3`] = `
328 |
331 |
340 |
346 | Lorem ipsum dolor sit amet, consectetur adipisicing elit
347 |
348 |
349 | `;
350 |
351 | exports[`it should render correctly when children are passed as function 1`] = `
352 |
355 |
360 |
363 | Dropdown content here
364 |
365 |
366 | `;
367 |
368 | exports[`it should throw Invalid proptytype error on invalid children 1`] = `
369 | "Warning: Failed prop type: Invalid prop \`children\` supplied to \`Dropdown\`.
370 | in Dropdown"
371 | `;
372 |
373 | exports[`renders correctly 1`] = `
374 |
377 |
386 |
392 | Lorem ipsum dolor sit amet, consectetur adipisicing elit
393 |
394 |
395 | `;
396 |
397 | exports[`renders correctly 2`] = `
398 |
401 |
410 |
416 |
419 | -
422 | Active
423 |
424 | -
425 | Item
426 |
427 |
428 |
429 |
430 | `;
431 |
432 | exports[`should be closed 1`] = `
433 |
436 |
445 |
451 | Lorem ipsum dolor sit amet, consectetur adipisicing elit
452 |
453 |
454 | `;
455 |
456 | exports[`should be open 1`] = `
457 |
460 |
469 |
475 | Lorem ipsum dolor sit amet, consectetur adipisicing elit
476 |
477 |
478 | `;
479 |
--------------------------------------------------------------------------------
/src/Modal/__tests__/__snapshots__/index-test.js.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`Modal renders a Blank Modal 1`] = `
4 |
12 | Open
13 |
14 | }
15 | >
16 |
26 |
30 |
52 |
53 |
54 |
57 |
60 |
68 |
71 |
72 | Headline
73 |
74 |
77 |
78 | Lorem ipsum
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 | `;
88 |
89 | exports[`Modal renders a Caption 1`] = `
90 |
98 | Open
99 |
100 | }
101 | >
102 |
112 |
116 |
138 |
139 |
142 | Caption
143 |
144 |
147 | Lorem ipsum
148 |
149 |
150 |
151 |
152 | `;
153 |
154 | exports[`Modal renders a Header and Footer 1`] = `
155 |
163 | Open
164 |
165 | }
166 | >
167 |
177 |
181 |
203 |
206 |
207 | Headline
208 |
209 |
210 |
211 |
214 | Lorem ipsum
215 |
216 |
219 |
224 |
225 |
226 |
227 |
228 | `;
229 |
230 | exports[`Modal renders a Lightbox 1`] = `
231 |
239 | Open
240 |
241 | }
242 | >
243 |
253 |
257 |
279 |
280 |
281 |
284 |

289 |
290 |
291 |
292 |
293 | `;
294 |
295 | exports[`Modal renders a Spinner 1`] = `
296 |
304 | Open
305 |
306 | }
307 | >
308 |
333 |
334 | `;
335 |
336 | exports[`Modal renders an alert modal 1`] = `
337 |
345 | Open
346 |
347 | }
348 | >
349 |
359 |
363 |
364 |
365 |
368 | Something bad happened!
369 |
370 |
373 |
380 |
381 |
382 |
383 |
384 | `;
385 |
386 | exports[`Modal renders an confirm modal 1`] = `
387 |
395 | Open
396 |
397 | }
398 | >
399 |
409 |
413 |
414 |
415 |
418 | Are you absolutely sure about this?
419 |
420 |
423 |
430 |
431 |
432 |
433 |
440 |
441 |
442 |
443 |
444 | `;
445 |
446 | exports[`Modal renders an prompt modal 1`] = `
447 |
455 | Open
456 |
457 | }
458 | >
459 |
469 |
473 |
474 |
475 |
489 |
492 |
499 |
500 |
501 |
502 |
509 |
510 |
511 |
512 |
513 | `;
514 |
515 | exports[`Modal renders correctly 1`] = `
516 |
524 | Open
525 |
526 | }
527 | >
528 |
538 |
542 |
564 |
565 |
566 |
569 | Lorem ipsum
570 |
571 |
572 |
573 |
574 | `;
575 |
--------------------------------------------------------------------------------