@dhis2-ui/button 10.16.1 → 10.16.3-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/package.json +8 -7
  2. package/src/button/__tests__/Button.test.js +126 -0
  3. package/src/button/button.e2e.stories.js +24 -0
  4. package/src/button/button.js +162 -0
  5. package/src/button/button.prod.stories.js +305 -0
  6. package/src/button/button.styles.js +298 -0
  7. package/src/button/features/can_be_blurred/index.js +19 -0
  8. package/src/button/features/can_be_blurred.feature +6 -0
  9. package/src/button/features/can_be_clicked/index.js +18 -0
  10. package/src/button/features/can_be_clicked.feature +6 -0
  11. package/src/button/features/can_be_focused/index.js +18 -0
  12. package/src/button/features/can_be_focused.feature +6 -0
  13. package/src/button/index.js +1 -0
  14. package/src/button-strip/button-strip.e2e.stories.js +13 -0
  15. package/src/button-strip/button-strip.js +58 -0
  16. package/src/button-strip/button-strip.prod.stories.js +88 -0
  17. package/src/button-strip/features/accepts_children/index.js +10 -0
  18. package/src/button-strip/features/accepts_children.feature +5 -0
  19. package/src/button-strip/index.js +1 -0
  20. package/src/dropdown-button/__tests__/dropdown-button.test.js +135 -0
  21. package/src/dropdown-button/dropdown-button.e2e.stories.js +67 -0
  22. package/src/dropdown-button/dropdown-button.js +239 -0
  23. package/src/dropdown-button/dropdown-button.prod.stories.js +129 -0
  24. package/src/dropdown-button/features/accepts_children/index.js +10 -0
  25. package/src/dropdown-button/features/accepts_children.feature +5 -0
  26. package/src/dropdown-button/features/accepts_component/index.js +18 -0
  27. package/src/dropdown-button/features/accepts_component.feature +5 -0
  28. package/src/dropdown-button/features/accepts_icon/index.js +10 -0
  29. package/src/dropdown-button/features/accepts_icon.feature +5 -0
  30. package/src/dropdown-button/features/accepts_initial_focus/index.js +11 -0
  31. package/src/dropdown-button/features/accepts_initial_focus.feature +5 -0
  32. package/src/dropdown-button/features/button_is_clickable/index.js +15 -0
  33. package/src/dropdown-button/features/button_is_clickable.feature +6 -0
  34. package/src/dropdown-button/features/can_be_disabled/index.js +11 -0
  35. package/src/dropdown-button/features/can_be_disabled.feature +6 -0
  36. package/src/dropdown-button/features/common/index.js +5 -0
  37. package/src/dropdown-button/features/opens_a_dropdown/index.js +26 -0
  38. package/src/dropdown-button/features/opens_a_dropdown.feature +11 -0
  39. package/src/dropdown-button/index.js +1 -0
  40. package/src/index.js +4 -0
  41. package/src/locales/en/translations.json +3 -0
  42. package/src/locales/index.js +16 -0
  43. package/src/split-button/features/accepts_children/index.js +12 -0
  44. package/src/split-button/features/accepts_children.feature +5 -0
  45. package/src/split-button/features/accepts_icon/index.js +16 -0
  46. package/src/split-button/features/accepts_icon.feature +5 -0
  47. package/src/split-button/features/accepts_initial_focus/index.js +13 -0
  48. package/src/split-button/features/accepts_initial_focus.feature +5 -0
  49. package/src/split-button/features/arrow_opens_menu/index.js +34 -0
  50. package/src/split-button/features/arrow_opens_menu.feature +15 -0
  51. package/src/split-button/features/button_is_clickable/index.js +13 -0
  52. package/src/split-button/features/button_is_clickable.feature +6 -0
  53. package/src/split-button/features/can_be_disabled/index.js +25 -0
  54. package/src/split-button/features/can_be_disabled.feature +11 -0
  55. package/src/split-button/features/common/index.js +9 -0
  56. package/src/split-button/index.js +1 -0
  57. package/src/split-button/split-button.e2e.stories.js +56 -0
  58. package/src/split-button/split-button.js +273 -0
  59. package/src/split-button/split-button.prod.stories.js +162 -0
  60. package/src/split-button/split-button.test.js +84 -0
@@ -0,0 +1,67 @@
1
+ import React from 'react'
2
+ import { DropdownButton } from './index.js'
3
+
4
+ window.onClick = window.Cypress && window.Cypress.cy.stub()
5
+
6
+ export default { title: 'DropdownButton' }
7
+
8
+ export const Default = () => (
9
+ <DropdownButton
10
+ name="Button"
11
+ value="default"
12
+ component={<div>Content</div>}
13
+ >
14
+ Button
15
+ </DropdownButton>
16
+ )
17
+ export const WithOnClick = () => (
18
+ <DropdownButton
19
+ name="Button"
20
+ value="default"
21
+ onClick={window.onClick}
22
+ component={<div>Content</div>}
23
+ >
24
+ Button
25
+ </DropdownButton>
26
+ )
27
+ export const WithChildren = () => (
28
+ <DropdownButton
29
+ name="Button"
30
+ value="default"
31
+ component={<div>Component</div>}
32
+ >
33
+ I am a child
34
+ </DropdownButton>
35
+ )
36
+ export const WithComponent = () => (
37
+ <DropdownButton
38
+ name="Button"
39
+ value="default"
40
+ component={<div>I am a component</div>}
41
+ />
42
+ )
43
+ export const WithIcon = () => (
44
+ <DropdownButton
45
+ name="Button"
46
+ value="default"
47
+ component={<div>I am a component</div>}
48
+ icon={'Icon'}
49
+ />
50
+ )
51
+ export const WithInitialFocus = () => (
52
+ <DropdownButton
53
+ name="Button"
54
+ value="default"
55
+ component={<div>Content</div>}
56
+ initialFocus
57
+ />
58
+ )
59
+ export const DisabledWithOnClick = () => (
60
+ <DropdownButton
61
+ name="Button"
62
+ value="default"
63
+ component={<div>Content</div>}
64
+ onClick={window.onClick}
65
+ disabled
66
+ />
67
+ )
@@ -0,0 +1,239 @@
1
+ import { requiredIf } from '@dhis2/prop-types'
2
+ import { spacers, sharedPropTypes } from '@dhis2/ui-constants'
3
+ import { Layer } from '@dhis2-ui/layer'
4
+ import { Popper } from '@dhis2-ui/popper'
5
+ import PropTypes from 'prop-types'
6
+ import React, { Component } from 'react'
7
+ import { Button } from '../button/index.js'
8
+
9
+ function ArrowDown({ className }) {
10
+ return (
11
+ <svg
12
+ xmlns="http://www.w3.org/2000/svg"
13
+ viewBox="0 0 12 12"
14
+ className={className}
15
+ >
16
+ <path d="m5.29289 8.7071c.39053.3905 1.02369.3905 1.41422 0l2.99999-2.99999c.3905-.39053.3905-1.02369 0-1.41422-.3905-.39052-1.0237-.39052-1.4142 0l-2.2929 2.2929-2.29289-2.2929c-.39053-.39052-1.02369-.39052-1.41422 0-.39052.39053-.39052 1.02369 0 1.41422z" />
17
+ <style jsx>{`
18
+ svg {
19
+ fill: inherit;
20
+ height: 12px;
21
+ width: 12px;
22
+ vertical-align: middle;
23
+ pointer-events: none;
24
+ }
25
+ `}</style>
26
+ </svg>
27
+ )
28
+ }
29
+ ArrowDown.propTypes = {
30
+ className: PropTypes.string,
31
+ }
32
+
33
+ function ArrowUp({ className }) {
34
+ return (
35
+ <svg
36
+ xmlns="http://www.w3.org/2000/svg"
37
+ viewBox="0 0 12 12"
38
+ className={className}
39
+ >
40
+ <path
41
+ d="m5.29289 8.7071c.39053.3905 1.02369.3905 1.41422 0l2.99999-2.99999c.3905-.39053.3905-1.02369 0-1.41422-.3905-.39052-1.0237-.39052-1.4142 0l-2.2929 2.2929-2.29289-2.2929c-.39053-.39052-1.02369-.39052-1.41422 0-.39052.39053-.39052 1.02369 0 1.41422z"
42
+ transform="matrix(1 0 0 -1 0 12.999974)"
43
+ />
44
+ <style jsx>{`
45
+ svg {
46
+ fill: inherit;
47
+ height: 12px;
48
+ width: 12px;
49
+ vertical-align: middle;
50
+ pointer-events: none;
51
+ }
52
+ `}</style>
53
+ </svg>
54
+ )
55
+ }
56
+ ArrowUp.propTypes = {
57
+ className: PropTypes.string,
58
+ }
59
+
60
+ class DropdownButton extends Component {
61
+ state = {
62
+ open: false,
63
+ }
64
+
65
+ static defaultProps = {
66
+ dataTest: 'dhis2-uicore-dropdownbutton',
67
+ }
68
+
69
+ anchorRef = React.createRef()
70
+
71
+ componentDidMount() {
72
+ document.addEventListener('keydown', this.handleKeyDown)
73
+ }
74
+
75
+ componentWillUnmount() {
76
+ document.removeEventListener('keydown', this.handleKeyDown)
77
+ }
78
+
79
+ handleKeyDown = (event) => {
80
+ if (event.key === 'Escape' && this.state.open) {
81
+ event.preventDefault()
82
+ event.stopPropagation()
83
+ this.setState({ open: false })
84
+ }
85
+ }
86
+
87
+ onClickHandler = ({ name, value }, event) => {
88
+ const handleClick = (open) => {
89
+ if (this.props.onClick) {
90
+ this.props.onClick(
91
+ {
92
+ name,
93
+ value,
94
+ open,
95
+ },
96
+ event
97
+ )
98
+ }
99
+ }
100
+ if (typeof this.props.open === 'boolean') {
101
+ handleClick(!this.props.open)
102
+ } else {
103
+ this.setState({ open: !this.state.open }, () => {
104
+ handleClick(this.state.open)
105
+ })
106
+ }
107
+ }
108
+
109
+ render() {
110
+ const {
111
+ component,
112
+ children,
113
+ className,
114
+ destructive,
115
+ disabled,
116
+ icon,
117
+ large,
118
+ primary,
119
+ secondary,
120
+ small,
121
+ name,
122
+ value,
123
+ tabIndex,
124
+ type,
125
+ initialFocus,
126
+ dataTest = 'dhis2-uicore-dropdownbutton',
127
+ } = this.props
128
+ const open =
129
+ typeof this.props.open === 'boolean'
130
+ ? this.props.open
131
+ : this.state.open
132
+ const ArrowIconComponent = open ? ArrowUp : ArrowDown
133
+
134
+ return (
135
+ <div ref={this.anchorRef} data-test={dataTest}>
136
+ <Button
137
+ className={className}
138
+ destructive={destructive}
139
+ disabled={disabled}
140
+ icon={icon}
141
+ large={large}
142
+ primary={primary}
143
+ secondary={secondary}
144
+ small={small}
145
+ onClick={this.onClickHandler}
146
+ name={name}
147
+ value={value}
148
+ tabIndex={tabIndex}
149
+ type={type}
150
+ initialFocus={initialFocus}
151
+ data-test="dhis2-uicore-dropdownbutton-toggle"
152
+ >
153
+ {children}
154
+ <ArrowIconComponent
155
+ className={`arrow ${small && 'arrow-small'}`}
156
+ />
157
+ </Button>
158
+
159
+ {open && (
160
+ <Layer onBackdropClick={this.onClickHandler} transparent>
161
+ <Popper
162
+ dataTest={`${dataTest}-popper`}
163
+ placement="bottom-start"
164
+ reference={this.anchorRef}
165
+ >
166
+ {component}
167
+ </Popper>
168
+ </Layer>
169
+ )}
170
+
171
+ <style jsx>{`
172
+ .arrow {
173
+ margin-inline-start: ${spacers.dp8};
174
+ }
175
+
176
+ .arrow-small {
177
+ margin-inline-start: ${spacers.dp4};
178
+ }
179
+
180
+ div {
181
+ display: inline-flex;
182
+ position: relative;
183
+ color: inherit;
184
+ white-space: nowrap;
185
+ }
186
+ `}</style>
187
+ </div>
188
+ )
189
+ }
190
+ }
191
+
192
+ DropdownButton.propTypes = {
193
+ /** Children to render inside the buton */
194
+ children: PropTypes.node,
195
+ className: PropTypes.string,
196
+ /** Component to show/hide when button is clicked */
197
+ component: PropTypes.element,
198
+ dataTest: PropTypes.string,
199
+ /**
200
+ * Applies 'destructive' button appearance, implying a dangerous action.
201
+ */
202
+ destructive: PropTypes.bool,
203
+ /** Make the button non-interactive */
204
+ disabled: PropTypes.bool,
205
+ icon: PropTypes.element,
206
+ /** Grants button initial focus on the page */
207
+ initialFocus: PropTypes.bool,
208
+ /** Button size. Mutually exclusive with `small` prop */
209
+ large: sharedPropTypes.sizePropType,
210
+ name: PropTypes.string,
211
+ /** Controls popper visibility. When implementing this prop the component becomes a controlled component */
212
+ open: PropTypes.bool,
213
+ /**
214
+ * Applies 'primary' button appearance, implying the most important action.
215
+ */
216
+ primary: PropTypes.bool,
217
+ /**
218
+ * Applies 'secondary' button appearance.
219
+ */
220
+ secondary: PropTypes.bool,
221
+ /** Button size. Mutually exclusive with `large` prop */
222
+ small: sharedPropTypes.sizePropType,
223
+ tabIndex: PropTypes.string,
224
+ /** Type of button. Can take advantage of different default behavior */
225
+ type: PropTypes.oneOf(['submit', 'reset', 'button']),
226
+ value: PropTypes.string,
227
+ /**
228
+ * Callback triggered on click.
229
+ * Called with signature `({ name: string, value: string, open: bool }, event)`
230
+ * Is required when using the `open` prop to override the internal
231
+ * state.
232
+ */
233
+ onClick: requiredIf(
234
+ (props) => typeof props.open === 'boolean',
235
+ PropTypes.func
236
+ ),
237
+ }
238
+
239
+ export { DropdownButton }
@@ -0,0 +1,129 @@
1
+ import { sharedPropTypes } from '@dhis2/ui-constants'
2
+ import { FlyoutMenu, MenuItem } from '@dhis2-ui/menu'
3
+ import React, { useState } from 'react'
4
+ import { DropdownButton } from './index.js'
5
+
6
+ const description = `
7
+ Presents several actions to a user in a small space. Can replace single, individual buttons. Should only be used for actions that are related to one another. Ensure the button has a useful level that communicates that actions are contained within. Dropdown buttons do not have an explicit action, only expanding the list of contained actions.
8
+
9
+ \`\`\`js
10
+ import { DropdownButton } from '@dhis2/ui'
11
+ \`\`\`
12
+ `
13
+
14
+ const Simple = <span>Simplest thing</span>
15
+
16
+ const { sizeArgType, buttonVariantArgType } = sharedPropTypes
17
+
18
+ export default {
19
+ title: 'Dropdown Button',
20
+ component: DropdownButton,
21
+ parameters: { docs: { description: { component: description } } },
22
+ argTypes: {
23
+ primary: { ...buttonVariantArgType },
24
+ secondary: { ...buttonVariantArgType },
25
+ destructive: { ...buttonVariantArgType },
26
+ small: { ...sizeArgType },
27
+ large: { ...sizeArgType },
28
+ },
29
+ // Default args for all stories (can be overridden)
30
+ args: {
31
+ name: 'buttonName',
32
+ value: 'buttonValue',
33
+ component: Simple,
34
+ children: 'Label me!',
35
+ },
36
+ }
37
+
38
+ const Template = (args) => <DropdownButton {...args} />
39
+
40
+ export const Default = Template.bind({})
41
+
42
+ export const WithClick = Template.bind({})
43
+ WithClick.args = {
44
+ onClick: ({ open }) => console.log('onClick: the dropdown is open: ', open),
45
+ }
46
+
47
+ export const Primary = Template.bind({})
48
+ Primary.args = { primary: true }
49
+
50
+ export const Secondary = Template.bind({})
51
+ Secondary.args = { secondary: true }
52
+
53
+ export const Destructive = Template.bind({})
54
+ Destructive.args = { destructive: true }
55
+
56
+ export const Disabled = Template.bind({})
57
+ Disabled.args = { disabled: true }
58
+
59
+ export const Small = Template.bind({})
60
+ Small.args = { small: true }
61
+
62
+ export const Large = Template.bind({})
63
+ Large.args = { large: true }
64
+
65
+ export const WithMenu = Template.bind({})
66
+ WithMenu.args = {
67
+ component: (
68
+ <FlyoutMenu>
69
+ <MenuItem label="Item 1" />
70
+ <MenuItem label="Item 2" />
71
+ <MenuItem label="Item 3" />
72
+ </FlyoutMenu>
73
+ ),
74
+ }
75
+ // FlyoutMenu needs iframe
76
+ // But docs page down too much with iframe, so disabled
77
+ WithMenu.parameters = { docs: { disable: true } }
78
+
79
+ export const InitialFocus = Template.bind({})
80
+ InitialFocus.args = { initialFocus: true }
81
+ /**
82
+ * 'Initial focus' stories cause the docs page to scroll away each time
83
+ * a control is changed, therefore it is omitted from the docs page (but
84
+ * not the normal 'canvas' story viewer)
85
+ */
86
+ InitialFocus.parameters = { docs: { disable: true } }
87
+
88
+ const OpenTemplate = (args) => {
89
+ return <DropdownButton {...args} />
90
+ }
91
+ export const Open = OpenTemplate.bind({})
92
+ Open.args = {
93
+ open: true,
94
+ component: Simple,
95
+ onClick: () => {},
96
+ }
97
+
98
+ const ManualControlTemplate = (args) => {
99
+ const [isOpen, setIsOpen] = useState(true)
100
+
101
+ const handleOpen = () => setIsOpen(false)
102
+
103
+ const Menu = (
104
+ <ul>
105
+ <li>First option does nothing</li>
106
+ <li onClick={handleOpen}>Close the dropdown</li>
107
+ </ul>
108
+ )
109
+
110
+ return (
111
+ <DropdownButton
112
+ {...args}
113
+ onClick={() => setIsOpen(!isOpen)}
114
+ open={isOpen}
115
+ component={Menu}
116
+ />
117
+ )
118
+ }
119
+ export const ManualControl = ManualControlTemplate.bind({})
120
+ ManualControl.args = {}
121
+
122
+ export const RTL = (args) => (
123
+ <div dir="rtl">
124
+ <DropdownButton {...args} />
125
+ </div>
126
+ )
127
+ RTL.args = {
128
+ children: 'RTL text',
129
+ }
@@ -0,0 +1,10 @@
1
+ import { Given, Then } from '@badeball/cypress-cucumber-preprocessor'
2
+
3
+ Given('a DropdownButton with children is rendered', () => {
4
+ cy.visitStory('DropdownButton', 'With children')
5
+ cy.get('[data-test="dhis2-uicore-dropdownbutton"]').should('be.visible')
6
+ })
7
+
8
+ Then('the children are visible', () => {
9
+ cy.contains('I am a child').should('be.visible')
10
+ })
@@ -0,0 +1,5 @@
1
+ Feature: The DropdownButton renders children
2
+
3
+ Scenario: A DropdownButton with children
4
+ Given a DropdownButton with children is rendered
5
+ Then the children are visible
@@ -0,0 +1,18 @@
1
+ import { Given, Then } from '@badeball/cypress-cucumber-preprocessor'
2
+
3
+ Given(
4
+ 'a DropdownButton with a component prop and opened dropdown is rendered',
5
+ () => {
6
+ cy.visitStory('DropdownButton', 'With component')
7
+
8
+ cy.get('[data-test="dhis2-uicore-dropdownbutton"]').should('be.visible')
9
+ cy.get('[data-test="dhis2-uicore-dropdownbutton"]').click()
10
+ cy.get('[data-test="dhis2-uicore-dropdownbutton-popper"]').should(
11
+ 'exist'
12
+ )
13
+ }
14
+ )
15
+
16
+ Then('the component is visible', () => {
17
+ cy.contains('I am a component').should('be.visible')
18
+ })
@@ -0,0 +1,5 @@
1
+ Feature: The DropdownButton accepts a component prop
2
+
3
+ Scenario: A DropdownButton with a component
4
+ Given a DropdownButton with a component prop and opened dropdown is rendered
5
+ Then the component is visible
@@ -0,0 +1,10 @@
1
+ import { Given, Then } from '@badeball/cypress-cucumber-preprocessor'
2
+
3
+ Given('a DropdownButton with an icon prop is rendered', () => {
4
+ cy.visitStory('DropdownButton', 'With icon')
5
+ cy.get('[data-test="dhis2-uicore-dropdownbutton"]').should('be.visible')
6
+ })
7
+
8
+ Then('the icon is visible', () => {
9
+ cy.contains('Icon').should('be.visible')
10
+ })
@@ -0,0 +1,5 @@
1
+ Feature: The DropdownButton accepts an icon prop
2
+
3
+ Scenario: A DropdownButton with an icon
4
+ Given a DropdownButton with an icon prop is rendered
5
+ Then the icon is visible
@@ -0,0 +1,11 @@
1
+ import { Given, Then } from '@badeball/cypress-cucumber-preprocessor'
2
+
3
+ Given('a DropdownButton with initialFocus is rendered', () => {
4
+ cy.visitStory('DropdownButton', 'With initial focus')
5
+ })
6
+
7
+ Then('the DropdownButton is focused', () => {
8
+ cy.focused()
9
+ .parent('[data-test="dhis2-uicore-dropdownbutton"]')
10
+ .should('exist')
11
+ })
@@ -0,0 +1,5 @@
1
+ Feature: Focusing the DropdownButton on mount
2
+
3
+ Scenario: The DropdownButton renders with focus
4
+ Given a DropdownButton with initialFocus is rendered
5
+ Then the DropdownButton is focused
@@ -0,0 +1,15 @@
1
+ import { Given, Then } from '@badeball/cypress-cucumber-preprocessor'
2
+
3
+ Given('a DropdownButton with onClick handler is rendered', () => {
4
+ cy.visitStory('DropdownButton', 'With on click')
5
+ })
6
+
7
+ Then('the onClick handler is called', () => {
8
+ cy.window().should((win) => {
9
+ expect(win.onClick).to.be.calledWith({
10
+ name: 'Button',
11
+ value: 'default',
12
+ open: true,
13
+ })
14
+ })
15
+ })
@@ -0,0 +1,6 @@
1
+ Feature: The DropdownButton has an onClick api
2
+
3
+ Scenario: The user clicks on the DropdownButton
4
+ Given a DropdownButton with onClick handler is rendered
5
+ When the DropdownButton is clicked
6
+ Then the onClick handler is called
@@ -0,0 +1,11 @@
1
+ import { Given, Then } from '@badeball/cypress-cucumber-preprocessor'
2
+
3
+ Given('a disabled DropdownButton with onClick handler is rendered', () => {
4
+ cy.visitStory('DropdownButton', 'Disabled with on click')
5
+ })
6
+
7
+ Then('the onClick handler is not called', () => {
8
+ cy.window().should((win) => {
9
+ expect(win.onClick).not.to.be.called
10
+ })
11
+ })
@@ -0,0 +1,6 @@
1
+ Feature: The DropdownButton can be disabled
2
+
3
+ Scenario: The user clicks a disabled DropdownButton
4
+ Given a disabled DropdownButton with onClick handler is rendered
5
+ When the DropdownButton is clicked
6
+ Then the onClick handler is not called
@@ -0,0 +1,5 @@
1
+ import { When } from '@badeball/cypress-cucumber-preprocessor'
2
+
3
+ When('the DropdownButton is clicked', () => {
4
+ cy.get('[data-test="dhis2-uicore-dropdownbutton"]').click()
5
+ })
@@ -0,0 +1,26 @@
1
+ import { Given, When, Then } from '@badeball/cypress-cucumber-preprocessor'
2
+
3
+ Given('a default DropdownButton is rendered', () => {
4
+ cy.visitStory('DropdownButton', 'Default')
5
+ })
6
+
7
+ Given('a DropdownButton with opened dropdown is rendered', () => {
8
+ cy.visitStory('DropdownButton', 'Default')
9
+
10
+ cy.get('[data-test="dhis2-uicore-dropdownbutton"]').click()
11
+ cy.get('[data-test="dhis2-uicore-dropdownbutton-popper"]').should('exist')
12
+ })
13
+
14
+ When('the user clicks the backdrop Layer', () => {
15
+ cy.get('[data-test="dhis2-uicore-layer"]').click()
16
+ })
17
+
18
+ Then('the dropdown is not rendered', () => {
19
+ cy.get('[data-test="dhis2-uicore-dropdownbutton-popper"]').should(
20
+ 'not.exist'
21
+ )
22
+ })
23
+
24
+ Then('the dropdown is rendered', () => {
25
+ cy.get('[data-test="dhis2-uicore-dropdownbutton-popper"]').should('exist')
26
+ })
@@ -0,0 +1,11 @@
1
+ Feature: The DropdownButton renders a dropdown
2
+
3
+ Scenario: The user opens the dropdown
4
+ Given a default DropdownButton is rendered
5
+ When the DropdownButton is clicked
6
+ Then the dropdown is rendered
7
+
8
+ Scenario: The user closes the dropdown
9
+ Given a DropdownButton with opened dropdown is rendered
10
+ When the user clicks the backdrop Layer
11
+ Then the dropdown is not rendered
@@ -0,0 +1 @@
1
+ export { DropdownButton } from './dropdown-button.js'
package/src/index.js ADDED
@@ -0,0 +1,4 @@
1
+ export { Button } from './button/index.js'
2
+ export { ButtonStrip } from './button-strip/index.js'
3
+ export { SplitButton } from './split-button/index.js'
4
+ export { DropdownButton } from './dropdown-button/index.js'
@@ -0,0 +1,3 @@
1
+ {
2
+ "Toggle dropdown": "Toggle dropdown"
3
+ }
@@ -0,0 +1,16 @@
1
+ //------------------------------------------------------------------------------
2
+ // <auto-generated>
3
+ // This code was generated by d2-i18n-generate.
4
+ //
5
+ // Changes to this file may cause incorrect behavior and will be lost if
6
+ // the code is regenerated.
7
+ // </auto-generated>
8
+ //------------------------------------------------------------------------------
9
+ import i18n from '@dhis2/d2-i18n'
10
+
11
+ import enTranslations from './en/translations.json'
12
+
13
+ const namespace = 'default'
14
+ i18n.addResources('en', namespace, enTranslations)
15
+
16
+ export default i18n
@@ -0,0 +1,12 @@
1
+ import { Given, Then } from '@badeball/cypress-cucumber-preprocessor'
2
+
3
+ Given('a SplitButton with children is rendered', () => {
4
+ cy.visitStory('SplitButton', 'With children')
5
+ cy.get('[data-test="dhis2-uicore-splitbutton"]').should('be.visible')
6
+ })
7
+
8
+ Then('the children are visible', () => {
9
+ cy.get('[data-test="dhis2-uicore-splitbutton-button"]')
10
+ .contains('I am a child')
11
+ .should('be.visible')
12
+ })
@@ -0,0 +1,5 @@
1
+ Feature: The SplitButton renders children
2
+
3
+ Scenario: A SplitButton with children
4
+ Given a SplitButton with children is rendered
5
+ Then the children are visible
@@ -0,0 +1,16 @@
1
+ import { Given, Then } from '@badeball/cypress-cucumber-preprocessor'
2
+
3
+ Given('a SplitButton with an icon is rendered', () => {
4
+ cy.visitStory('SplitButton', 'With icon')
5
+ cy.get('[data-test="dhis2-uicore-splitbutton"]').should('be.visible')
6
+ })
7
+
8
+ Then('the icon is visible on the left button only', () => {
9
+ cy.get(
10
+ '[data-test="dhis2-uicore-splitbutton-button"] :contains("Icon")'
11
+ ).should('be.visible')
12
+
13
+ cy.get(
14
+ '[data-test="dhis2-uicore-splitbutton-toggle"] :contains("Icon")'
15
+ ).should('not.exist')
16
+ })