@dhis2-ui/menu 10.16.2 → 10.16.3

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 (49) hide show
  1. package/package.json +10 -9
  2. package/src/flyout-menu/__tests__/flyout-menu.test.js +48 -0
  3. package/src/flyout-menu/features/accepts_children/index.js +10 -0
  4. package/src/flyout-menu/features/accepts_children.feature +5 -0
  5. package/src/flyout-menu/features/position/index.js +80 -0
  6. package/src/flyout-menu/features/position.feature +19 -0
  7. package/src/flyout-menu/features/toggles_submenus/index.js +26 -0
  8. package/src/flyout-menu/features/toggles_submenus.feature +9 -0
  9. package/src/flyout-menu/flyout-menu.e2e.stories.js +55 -0
  10. package/src/flyout-menu/flyout-menu.js +108 -0
  11. package/src/flyout-menu/flyout-menu.prod.stories.js +229 -0
  12. package/src/flyout-menu/index.js +1 -0
  13. package/src/index.js +6 -0
  14. package/src/menu/__tests__/menu.test.js +213 -0
  15. package/src/menu/features/accepts_children/index.js +10 -0
  16. package/src/menu/features/accepts_children.feature +5 -0
  17. package/src/menu/helpers.js +36 -0
  18. package/src/menu/index.js +1 -0
  19. package/src/menu/menu.e2e.stories.js +5 -0
  20. package/src/menu/menu.js +96 -0
  21. package/src/menu/menu.prod.stories.js +90 -0
  22. package/src/menu/use-menu.js +100 -0
  23. package/src/menu-divider/index.js +1 -0
  24. package/src/menu-divider/menu-divider.js +32 -0
  25. package/src/menu-divider/menu-divider.prod.stories.js +30 -0
  26. package/src/menu-item/__tests__/menu-item.test.js +118 -0
  27. package/src/menu-item/features/accepts_href/index.js +11 -0
  28. package/src/menu-item/features/accepts_href.feature +5 -0
  29. package/src/menu-item/features/accepts_icon/index.js +10 -0
  30. package/src/menu-item/features/accepts_icon.feature +5 -0
  31. package/src/menu-item/features/accepts_label/index.js +10 -0
  32. package/src/menu-item/features/accepts_label.feature +5 -0
  33. package/src/menu-item/features/accepts_suffix/index.js +10 -0
  34. package/src/menu-item/features/accepts_suffix.feature +5 -0
  35. package/src/menu-item/features/accepts_target/index.js +11 -0
  36. package/src/menu-item/features/accepts_target.feature +5 -0
  37. package/src/menu-item/features/is_clickable/index.js +17 -0
  38. package/src/menu-item/features/is_clickable.feature +6 -0
  39. package/src/menu-item/index.js +1 -0
  40. package/src/menu-item/menu-item.e2e.stories.js +29 -0
  41. package/src/menu-item/menu-item.js +204 -0
  42. package/src/menu-item/menu-item.prod.stories.js +197 -0
  43. package/src/menu-item/menu-item.styles.js +133 -0
  44. package/src/menu-section-header/features/accepts_label/index.js +10 -0
  45. package/src/menu-section-header/features/accepts_label.feature +5 -0
  46. package/src/menu-section-header/index.js +1 -0
  47. package/src/menu-section-header/menu-section-header.e2e.stories.js +11 -0
  48. package/src/menu-section-header/menu-section-header.js +52 -0
  49. package/src/menu-section-header/menu-section-header.prod.stories.js +52 -0
@@ -0,0 +1,133 @@
1
+ import { colors, spacers, theme } from '@dhis2/ui-constants'
2
+ import css from 'styled-jsx/css'
3
+
4
+ export default css`
5
+ li {
6
+ display: flex;
7
+ align-items: stretch;
8
+ padding: 0;
9
+ cursor: pointer;
10
+ list-style: none;
11
+ background-color: ${colors.white};
12
+ color: ${colors.grey900};
13
+ fill: ${colors.grey900};
14
+ font-size: 14px;
15
+ line-height: 16px;
16
+ user-select: none;
17
+ }
18
+
19
+ li:hover {
20
+ background-color: ${colors.grey200};
21
+ }
22
+
23
+ li:active,
24
+ li.active {
25
+ background-color: ${colors.grey300};
26
+ }
27
+
28
+ li.destructive {
29
+ color: ${colors.red700};
30
+ fill: ${colors.red600};
31
+ }
32
+
33
+ li.destructive:hover {
34
+ background-color: ${colors.red050};
35
+ }
36
+
37
+ li.destructive:active,
38
+ li.destructive.active {
39
+ background-color: ${colors.red100};
40
+ }
41
+
42
+ li.disabled {
43
+ cursor: not-allowed;
44
+ color: ${colors.grey500};
45
+ fill: ${colors.grey500};
46
+ }
47
+
48
+ li.disabled:hover {
49
+ background-color: ${colors.white};
50
+ }
51
+
52
+ /*focus-visible backwards compatibility for safari: https://css-tricks.com/platform-news-using-focus-visible-bbcs-new-typeface-declarative-shadow-doms-a11y-and-placeholders/*/
53
+ li:focus {
54
+ outline: 3px solid ${theme.focus};
55
+ outline-offset: -3px;
56
+ }
57
+ li:focus:not(:focus-visible) {
58
+ outline: none;
59
+ }
60
+
61
+ a {
62
+ display: inline-flex;
63
+ flex-grow: 1;
64
+ align-items: center;
65
+ padding: 0 ${spacers.dp16};
66
+ min-height: 40px;
67
+ text-decoration: none;
68
+ color: inherit;
69
+ }
70
+
71
+ li.with-chevron a {
72
+ padding-inline-end: ${spacers.dp8};
73
+ }
74
+
75
+ li.dense a {
76
+ padding: 0 ${spacers.dp12};
77
+ min-height: 32px;
78
+ }
79
+
80
+ li.with-chevron.dense a {
81
+ padding-inline-end: ${spacers.dp4};
82
+ }
83
+
84
+ .label {
85
+ flex-grow: 1;
86
+ padding: ${spacers.dp12} 0;
87
+ }
88
+
89
+ li.dense .label {
90
+ padding: ${spacers.dp8} 0;
91
+ }
92
+
93
+ .icon {
94
+ flex-grow: 0;
95
+ margin-inline-end: ${spacers.dp12};
96
+ width: 24px;
97
+ height: 24px;
98
+ }
99
+
100
+ .suffix {
101
+ display: flex;
102
+ align-items: center;
103
+ margin-inline-start: ${spacers.dp8};
104
+ }
105
+
106
+ .chevron {
107
+ display: flex;
108
+ align-items: center;
109
+ flex-grow: 0;
110
+ margin-inline-start: ${spacers.dp24};
111
+ }
112
+
113
+ .chevron:dir(rtl) {
114
+ transform: rotate(180deg);
115
+ }
116
+
117
+ li.dense .icon {
118
+ margin-inline-end: ${spacers.dp8};
119
+ width: 16px;
120
+ height: 16px;
121
+ }
122
+
123
+ li .icon > :global(svg) {
124
+ width: 24px;
125
+ height: 24px;
126
+ }
127
+
128
+ li.dense .icon > :global(svg),
129
+ li .chevron > :global(svg) {
130
+ width: 16px;
131
+ height: 16px;
132
+ }
133
+ `
@@ -0,0 +1,10 @@
1
+ import { Given, Then } from '@badeball/cypress-cucumber-preprocessor'
2
+
3
+ Given('a MenuSectionHeader supplied with a label is rendered', () => {
4
+ cy.visitStory('MenuSectionHeader', 'With Label')
5
+ cy.get('[data-test="dhis2-uicore-menusectionheader"]').should('be.visible')
6
+ })
7
+
8
+ Then('the label is visible', () => {
9
+ cy.get(':contains("label")').should('be.visible')
10
+ })
@@ -0,0 +1,5 @@
1
+ Feature: The MenuSectionHeader accepts a label prop
2
+
3
+ Scenario: MenuSectionHeader renders supplied label
4
+ Given a MenuSectionHeader supplied with a label is rendered
5
+ Then the label is visible
@@ -0,0 +1 @@
1
+ export { MenuSectionHeader } from './menu-section-header.js'
@@ -0,0 +1,11 @@
1
+ import React from 'react'
2
+ import { Menu } from '../index.js'
3
+ import { MenuSectionHeader } from './index.js'
4
+
5
+ export default {
6
+ title: 'MenuSectionHeader',
7
+ component: MenuSectionHeader,
8
+ decorators: [(story) => <Menu>{story()}</Menu>],
9
+ }
10
+
11
+ export const WithLabel = () => <MenuSectionHeader label="label" />
@@ -0,0 +1,52 @@
1
+ import { colors, spacers } from '@dhis2/ui-constants'
2
+ import { Divider } from '@dhis2-ui/divider'
3
+ import cx from 'classnames'
4
+ import PropTypes from 'prop-types'
5
+ import React from 'react'
6
+
7
+ const MenuSectionHeader = ({
8
+ className,
9
+ dataTest = 'dhis2-uicore-menusectionheader',
10
+ dense,
11
+ hideDivider,
12
+ label,
13
+ }) => (
14
+ <li data-test={dataTest} className={cx(className, { dense })}>
15
+ {!hideDivider && <Divider dense={dense} />}
16
+
17
+ <h6>{label}</h6>
18
+
19
+ <style jsx>{`
20
+ li {
21
+ list-style: none;
22
+ background-color: ${colors.white};
23
+ user-select: none;
24
+ padding: 0;
25
+ line-height: 0;
26
+ }
27
+ h6 {
28
+ margin: 0;
29
+ padding: ${spacers.dp8} ${spacers.dp16} ${spacers.dp8}
30
+ ${spacers.dp16};
31
+ font-size: 13px;
32
+ line-height: 16px;
33
+ font-weight: 500;
34
+ color: ${colors.grey700};
35
+ }
36
+ li.dense h6 {
37
+ padding: ${spacers.dp8} ${spacers.dp12} ${spacers.dp4}
38
+ ${spacers.dp12};
39
+ }
40
+ `}</style>
41
+ </li>
42
+ )
43
+
44
+ MenuSectionHeader.propTypes = {
45
+ className: PropTypes.string,
46
+ dataTest: PropTypes.string,
47
+ dense: PropTypes.bool,
48
+ hideDivider: PropTypes.bool,
49
+ label: PropTypes.node,
50
+ }
51
+
52
+ export { MenuSectionHeader }
@@ -0,0 +1,52 @@
1
+ import PropTypes from 'prop-types'
2
+ import React from 'react'
3
+ import { Menu, MenuItem } from '../index.js'
4
+ import { MenuSectionHeader } from './menu-section-header.js'
5
+
6
+ const description = `
7
+ Items in a menu can be split into separate sections by using Dividers. Group relevant menu items together to help the user understand the options quickly. A Divider can be used alone. If using a Menu Section Header, a divider will be automatically included. Try not to group single menu items together. An exception to this is a critical destructive menu item, like 'Delete', which can be separated from other menu items.
8
+
9
+ \`\`\`js
10
+ import { MenuSectionHeader } from '@dhis2/ui'
11
+ \`\`\`
12
+ `
13
+
14
+ export default {
15
+ title: 'Menu Section Header',
16
+ component: MenuSectionHeader,
17
+ args: { label: 'Section header' },
18
+ parameters: { docs: { description: { component: description } } },
19
+ }
20
+
21
+ const Template = ({ menuArgs, ...args }) => (
22
+ <Menu {...menuArgs}>
23
+ <MenuItem label="Menu item above" />
24
+ <MenuSectionHeader {...args} />
25
+ <MenuItem label="Menu item below" />
26
+ </Menu>
27
+ )
28
+ Template.propTypes = { menuArgs: PropTypes.shape() }
29
+
30
+ export const Default = Template.bind({})
31
+
32
+ export const Dense = Template.bind({})
33
+ Dense.args = { menuArgs: { dense: true }, dense: true }
34
+
35
+ export const WithoutDivider = Template.bind({})
36
+ WithoutDivider.args = { hideDivider: true }
37
+
38
+ export const TopOfList = (args) => (
39
+ <Menu>
40
+ <MenuSectionHeader {...args} />
41
+ <MenuItem label="Item 1" />
42
+ <MenuItem label="Item 2" />
43
+ </Menu>
44
+ )
45
+ TopOfList.args = { label: 'Top of list (so <Menu> hides divider)' }
46
+ TopOfList.parameters = {
47
+ docs: {
48
+ description: {
49
+ story: 'When the Section Header is the first child of a `<Menu>`, the Menu parent automatically applies the `hideDivider` prop.',
50
+ },
51
+ },
52
+ }