@indico-data/design-system 1.0.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 (161) hide show
  1. package/.babelrc +27 -0
  2. package/.eslintignore +6 -0
  3. package/.eslintrc.js +63 -0
  4. package/.husky/pre-commit +4 -0
  5. package/.prettierignore +3 -0
  6. package/.prettierrc +6 -0
  7. package/.stackblitzrc +4 -0
  8. package/.storybook/indico-data-logo.svg +1 -0
  9. package/.storybook/main.ts +36 -0
  10. package/.storybook/preview-head.html +19 -0
  11. package/.storybook/preview.ts +24 -0
  12. package/.storybook/themes.js +24 -0
  13. package/.yarn/releases/yarn-classic.cjs +179386 -0
  14. package/.yarnrc.yml +1 -0
  15. package/README.md +30 -0
  16. package/package.json +79 -0
  17. package/src/components/Accordion/Accordion.stories.tsx +47 -0
  18. package/src/components/Accordion/Accordion.styles.ts +35 -0
  19. package/src/components/Accordion/Accordion.tsx +30 -0
  20. package/src/components/Accordion/index.ts +1 -0
  21. package/src/components/Icon/Icon.stories.tsx +60 -0
  22. package/src/components/Icon/Icon.tsx +75 -0
  23. package/src/components/Icon/faIcons.tsx +168 -0
  24. package/src/components/Icon/index.ts +2 -0
  25. package/src/components/Icon/indicons.tsx +699 -0
  26. package/src/components/Icon/storyHelpers.tsx +87 -0
  27. package/src/components/ListTable/Header/Header.styles.ts +62 -0
  28. package/src/components/ListTable/Header/Header.tsx +67 -0
  29. package/src/components/ListTable/Header/index.ts +1 -0
  30. package/src/components/ListTable/ListTable.stories.tsx +301 -0
  31. package/src/components/ListTable/ListTable.styles.ts +76 -0
  32. package/src/components/ListTable/ListTable.tsx +135 -0
  33. package/src/components/ListTable/index.ts +1 -0
  34. package/src/components/ListTable/mock-data/index.ts +1 -0
  35. package/src/components/ListTable/mock-data/mock-data.ts +291 -0
  36. package/src/components/Pagination/Pagination.stories.tsx +45 -0
  37. package/src/components/Pagination/Pagination.styles.ts +51 -0
  38. package/src/components/Pagination/Pagination.tsx +118 -0
  39. package/src/components/Pagination/index.ts +1 -0
  40. package/src/components/basic-section/Section/Section.stories.tsx +14 -0
  41. package/src/components/basic-section/Section/Section.styles.ts +8 -0
  42. package/src/components/basic-section/Section/Section.tsx +30 -0
  43. package/src/components/basic-section/Section/index.ts +1 -0
  44. package/src/components/basic-section/SectionBlock/SectionBlock.styles.ts +15 -0
  45. package/src/components/basic-section/SectionBlock/SectionBlock.tsx +37 -0
  46. package/src/components/basic-section/SectionBlock/index.ts +1 -0
  47. package/src/components/basic-section/SectionBody/SectionBody.stories.tsx +16 -0
  48. package/src/components/basic-section/SectionBody/SectionBody.styles.ts +18 -0
  49. package/src/components/basic-section/SectionBody/SectionBody.tsx +30 -0
  50. package/src/components/basic-section/SectionBody/index.ts +1 -0
  51. package/src/components/basic-section/SectionHeader/SectionHeader.stories.tsx +17 -0
  52. package/src/components/basic-section/SectionHeader/SectionHeader.styles.ts +5 -0
  53. package/src/components/basic-section/SectionHeader/SectionHeader.tsx +35 -0
  54. package/src/components/basic-section/SectionHeader/index.ts +1 -0
  55. package/src/components/basic-section/SectionTable/SectionTable.styles.ts +237 -0
  56. package/src/components/basic-section/SectionTable/SectionTable.tsx +229 -0
  57. package/src/components/basic-section/SectionTable/index.ts +1 -0
  58. package/src/components/basic-section/index.ts +5 -0
  59. package/src/components/buttons/Button/Button.stories.tsx +80 -0
  60. package/src/components/buttons/Button/Button.styles.ts +99 -0
  61. package/src/components/buttons/Button/Button.tsx +74 -0
  62. package/src/components/buttons/Button/index.ts +1 -0
  63. package/src/components/buttons/IconButton/IconButton.stories.tsx +96 -0
  64. package/src/components/buttons/IconButton/IconButton.styles.ts +78 -0
  65. package/src/components/buttons/IconButton/IconButton.tsx +109 -0
  66. package/src/components/buttons/IconButton/index.ts +1 -0
  67. package/src/components/buttons/commonStyles.ts +108 -0
  68. package/src/components/buttons/index.ts +2 -0
  69. package/src/components/buttons/types.ts +2 -0
  70. package/src/components/dropdowns/BorderSelect/BorderSelect.stories.tsx +22 -0
  71. package/src/components/dropdowns/BorderSelect/BorderSelect.styles.ts +73 -0
  72. package/src/components/dropdowns/BorderSelect/BorderSelect.tsx +85 -0
  73. package/src/components/dropdowns/BorderSelect/index.ts +1 -0
  74. package/src/components/dropdowns/MultiCombobox/MultiCombobox.stories.tsx +146 -0
  75. package/src/components/dropdowns/MultiCombobox/MultiCombobox.styles.ts +89 -0
  76. package/src/components/dropdowns/MultiCombobox/MultiCombobox.tsx +123 -0
  77. package/src/components/dropdowns/MultiCombobox/index.ts +1 -0
  78. package/src/components/dropdowns/Select/Select.stories.tsx +54 -0
  79. package/src/components/dropdowns/Select/Select.styles.ts +73 -0
  80. package/src/components/dropdowns/Select/Select.tsx +69 -0
  81. package/src/components/dropdowns/Select/index.ts +1 -0
  82. package/src/components/dropdowns/SingleCombobox/SingleCombobox.stories.tsx +61 -0
  83. package/src/components/dropdowns/SingleCombobox/SingleCombobox.styles.ts +56 -0
  84. package/src/components/dropdowns/SingleCombobox/SingleCombobox.tsx +103 -0
  85. package/src/components/dropdowns/SingleCombobox/index.ts +1 -0
  86. package/src/components/dropdowns/commonStyles.ts +65 -0
  87. package/src/components/dropdowns/index.ts +4 -0
  88. package/src/components/dropdowns/types.ts +45 -0
  89. package/src/components/dropdowns/useCombobox.ts +32 -0
  90. package/src/components/dropdowns/utils.tsx +25 -0
  91. package/src/components/index.ts +9 -0
  92. package/src/components/inputs/EditableInput/EditableInput.stories.tsx +26 -0
  93. package/src/components/inputs/EditableInput/EditableInput.styles.ts +21 -0
  94. package/src/components/inputs/EditableInput/EditableInput.tsx +103 -0
  95. package/src/components/inputs/EditableInput/index.ts +1 -0
  96. package/src/components/inputs/NumberInput/NumberInput.stories.tsx +72 -0
  97. package/src/components/inputs/NumberInput/NumberInput.styles.ts +66 -0
  98. package/src/components/inputs/NumberInput/NumberInput.tsx +153 -0
  99. package/src/components/inputs/NumberInput/index.ts +1 -0
  100. package/src/components/inputs/SearchInput/SearchInput.stories.tsx +17 -0
  101. package/src/components/inputs/SearchInput/SearchInput.styles.ts +25 -0
  102. package/src/components/inputs/SearchInput/SearchInput.tsx +47 -0
  103. package/src/components/inputs/SearchInput/index.ts +1 -0
  104. package/src/components/inputs/TextInput/TextInput.stories.tsx +104 -0
  105. package/src/components/inputs/TextInput/TextInput.styles.ts +74 -0
  106. package/src/components/inputs/TextInput/TextInput.tsx +116 -0
  107. package/src/components/inputs/TextInput/index.ts +1 -0
  108. package/src/components/inputs/index.ts +4 -0
  109. package/src/components/inputs/inputsCommon.styles.ts +61 -0
  110. package/src/components/loading-indicators/BarSpinner/BarSpinner.stories.tsx +14 -0
  111. package/src/components/loading-indicators/BarSpinner/BarSpinner.styles.ts +53 -0
  112. package/src/components/loading-indicators/BarSpinner/BarSpinner.tsx +21 -0
  113. package/src/components/loading-indicators/BarSpinner/index.ts +1 -0
  114. package/src/components/loading-indicators/CirclePulse/CirclePulse.stories.tsx +22 -0
  115. package/src/components/loading-indicators/CirclePulse/CirclePulse.styles.ts +81 -0
  116. package/src/components/loading-indicators/CirclePulse/CirclePulse.tsx +61 -0
  117. package/src/components/loading-indicators/CirclePulse/index.ts +1 -0
  118. package/src/components/loading-indicators/CircleSpinner/CircleSpinner.stories.tsx +16 -0
  119. package/src/components/loading-indicators/CircleSpinner/CircleSpinner.tsx +37 -0
  120. package/src/components/loading-indicators/CircleSpinner/index.ts +1 -0
  121. package/src/components/loading-indicators/LoadingList/LoadingList.stories.tsx +14 -0
  122. package/src/components/loading-indicators/LoadingList/LoadingList.styles.ts +42 -0
  123. package/src/components/loading-indicators/LoadingList/LoadingList.tsx +9 -0
  124. package/src/components/loading-indicators/LoadingList/index.ts +1 -0
  125. package/src/components/loading-indicators/PercentageRing/PercentageRing.stories.tsx +18 -0
  126. package/src/components/loading-indicators/PercentageRing/PercentageRing.styles.ts +27 -0
  127. package/src/components/loading-indicators/PercentageRing/PercentageRing.tsx +76 -0
  128. package/src/components/loading-indicators/PercentageRing/index.ts +1 -0
  129. package/src/components/loading-indicators/RandomLoadingMessage/RandomLoadingMessage.stories.tsx +16 -0
  130. package/src/components/loading-indicators/RandomLoadingMessage/RandomLoadingMessage.tsx +18 -0
  131. package/src/components/loading-indicators/RandomLoadingMessage/index.ts +1 -0
  132. package/src/components/loading-indicators/RandomLoadingMessage/random-messages.js +67 -0
  133. package/src/components/loading-indicators/index.ts +6 -0
  134. package/src/components/user-feedback/Shrug/Shrug.stories.tsx +38 -0
  135. package/src/components/user-feedback/Shrug/Shrug.styles.ts +23 -0
  136. package/src/components/user-feedback/Shrug/Shrug.tsx +44 -0
  137. package/src/components/user-feedback/Shrug/index.ts +1 -0
  138. package/src/components/user-feedback/index.ts +1 -0
  139. package/src/index.tsx +18 -0
  140. package/src/styles/globals/buttons.ts +154 -0
  141. package/src/styles/globals/forms.ts +103 -0
  142. package/src/styles/globals/index.tsx +25 -0
  143. package/src/styles/globals/layout.ts +25 -0
  144. package/src/styles/globals/lists.ts +23 -0
  145. package/src/styles/globals/margin-padding.ts +33 -0
  146. package/src/styles/globals/media.ts +13 -0
  147. package/src/styles/globals/tables.ts +34 -0
  148. package/src/styles/globals/typography.ts +95 -0
  149. package/src/styles/globals/utility-classes.ts +76 -0
  150. package/src/tokens/animation.ts +6 -0
  151. package/src/tokens/breakpoints.ts +11 -0
  152. package/src/tokens/colors.ts +279 -0
  153. package/src/tokens/index.ts +20 -0
  154. package/src/tokens/margin.ts +5 -0
  155. package/src/tokens/numbers.js +41 -0
  156. package/src/tokens/padding.ts +5 -0
  157. package/src/tokens/spacings.ts +5 -0
  158. package/src/tokens/typography.ts +37 -0
  159. package/src/types.ts +6 -0
  160. package/tsconfig.json +13 -0
  161. package/webpack.config.js +35 -0
@@ -0,0 +1,73 @@
1
+ import styled from 'styled-components';
2
+
3
+ import { COLORS, FONT_SIZE } from '@/tokens';
4
+
5
+ export const StyledSelect = styled.div`
6
+ &.horizontal {
7
+ > * {
8
+ display: inline-block;
9
+ }
10
+
11
+ > label {
12
+ margin-right: 12px;
13
+ }
14
+ }
15
+
16
+ label {
17
+ line-height: 1.2;
18
+ margin-bottom: 14px;
19
+ color: ${COLORS.lightFontColor};
20
+ }
21
+
22
+ .select-container {
23
+ position: relative;
24
+ max-width: 300px;
25
+
26
+ select {
27
+ background: transparent;
28
+ border: 1px solid ${COLORS.baliHai};
29
+ width: 100%;
30
+ max-width: 300px;
31
+ color: ${COLORS.lightFontColor};
32
+ font-size: ${FONT_SIZE.base};
33
+ border-radius: 4px;
34
+ padding: 7px 30px 8px 15px;
35
+ appearance: none;
36
+ position: relative;
37
+ z-index: 2;
38
+
39
+ &:focus {
40
+ outline: 0;
41
+ }
42
+
43
+ &::-ms-expand {
44
+ display: none;
45
+ }
46
+ }
47
+
48
+ option {
49
+ color: ${COLORS.black};
50
+
51
+ &:not(:checked) {
52
+ color: ${COLORS.black};
53
+ }
54
+ }
55
+
56
+ .selectCaret {
57
+ display: inline-block;
58
+ right: 12px;
59
+ position: absolute;
60
+ top: 50%;
61
+ transform: translateY(-50%);
62
+ z-index: 1;
63
+ }
64
+ }
65
+ `;
66
+
67
+ export const StyledValidationError = styled.div`
68
+ margin-top: 13px;
69
+
70
+ p {
71
+ color: ${COLORS.curiousBlue};
72
+ }
73
+ `;
@@ -0,0 +1,85 @@
1
+ // TODO: This component's migration was fast-tracked for Insights. Assess for potential refactor and documentation.
2
+
3
+ import React from 'react';
4
+ import { v4 as uuid } from 'uuid';
5
+ import classNames from 'classnames';
6
+
7
+ import { Icon } from '../../Icon';
8
+ import { PermafrostComponent } from '@/types';
9
+
10
+ import { StyledSelect, StyledValidationError } from './BorderSelect.styles';
11
+
12
+ type Props = PermafrostComponent & {
13
+ defaultValue?: string;
14
+ disabled?: boolean;
15
+ horizontal?: boolean;
16
+ initialText?: string;
17
+ label?: string;
18
+ onChange(e: React.ChangeEvent<HTMLSelectElement>): void;
19
+ options: { name: string; value: string | number }[];
20
+ style?: object;
21
+ value?: string | number;
22
+ validationErrors?: string[];
23
+ };
24
+
25
+ export const BorderSelect = (props: Props) => {
26
+ const {
27
+ className = '',
28
+ disabled,
29
+ horizontal,
30
+ id,
31
+ initialText,
32
+ label,
33
+ onChange,
34
+ options,
35
+ style = {},
36
+ value,
37
+ validationErrors,
38
+ } = props;
39
+
40
+ const selectId = uuid();
41
+
42
+ return (
43
+ <StyledSelect
44
+ className={classNames('Select', { horizontal }, className)}
45
+ data-cy={props['data-cy']}
46
+ id={id}
47
+ style={style}
48
+ >
49
+ {label && <label htmlFor={selectId}>{label}</label>}
50
+
51
+ <div className="select-container">
52
+ <select onChange={onChange} value={value} disabled={disabled} id={selectId}>
53
+ {initialText && (
54
+ <option disabled value="">
55
+ {initialText}
56
+ </option>
57
+ )}
58
+
59
+ {options.map((o) => {
60
+ const key = uuid();
61
+
62
+ return (
63
+ <option key={key} value={o.value}>
64
+ {o.name}
65
+ </option>
66
+ );
67
+ })}
68
+ </select>
69
+
70
+ <Icon name="fa-caret-down" className="selectCaret" />
71
+ </div>
72
+ {validationErrors ? (
73
+ <StyledValidationError>
74
+ {validationErrors.map((err, i) => {
75
+ return (
76
+ <p className={`error-${err}`} key={i}>
77
+ {err}
78
+ </p>
79
+ );
80
+ })}
81
+ </StyledValidationError>
82
+ ) : null}
83
+ </StyledSelect>
84
+ );
85
+ };
@@ -0,0 +1 @@
1
+ export { BorderSelect } from './BorderSelect';
@@ -0,0 +1,146 @@
1
+ // TODO: This component's migration was fast-tracked for Insights. Assess for potential refactor and documentation.
2
+
3
+ import React, { useRef } from 'react';
4
+ import type { Meta, StoryObj } from '@storybook/react';
5
+
6
+ import { Icon, IconButton } from '@/components';
7
+ import { ComboboxOption } from '../types';
8
+ import { MultiCombobox } from './MultiCombobox';
9
+ import { useCombobox } from '../useCombobox';
10
+
11
+ const options = [
12
+ { value: 'angie', label: 'angie - Labeler' },
13
+ { value: 'barry', label: 'barry - Labeler' },
14
+ { value: 'cecily', label: 'cecily - Labeler' },
15
+ { value: 'david', label: 'david - Labeler' },
16
+ { value: 'evelyn', label: 'evelyn - Labeler' },
17
+ { value: 'heather', label: 'heather - Labeler' },
18
+ { value: 'isaac', label: 'isaac - Labeler' },
19
+ ];
20
+
21
+ const complexItems = options.map((option) => {
22
+ const textParts = option.label.split('-');
23
+
24
+ return {
25
+ email: option.value,
26
+ user: textParts[0].trim(),
27
+ role: textParts[1].trim(),
28
+ };
29
+ });
30
+
31
+ function StoryRender(props) {
32
+ const selectEl = useRef(null);
33
+ const { clearValue } = useCombobox(selectEl);
34
+
35
+ return (
36
+ <>
37
+ <MultiCombobox ref={selectEl} {...props} />
38
+ <IconButton
39
+ adjustAlignment={0}
40
+ iconName="trash"
41
+ onPress={() => clearValue()}
42
+ label="clear selections"
43
+ style={{ marginTop: '1em' }}
44
+ />
45
+ </>
46
+ );
47
+ }
48
+
49
+ const meta = {
50
+ component: MultiCombobox,
51
+ title: 'dropdowns/MultiCombobox',
52
+ argTypes: {
53
+ options: { control: { disable: true } },
54
+ defaultValue: { control: { disable: true } },
55
+ },
56
+ args: {
57
+ options,
58
+ placeholder: 'Select Team Member(s)',
59
+ onChange: (selectedOptions: ComboboxOption[]) => console.info(selectedOptions),
60
+ },
61
+ } satisfies Meta<typeof MultiCombobox>;
62
+
63
+ export default meta;
64
+ type Story = StoryObj<typeof MultiCombobox>;
65
+
66
+ export const Normal: Story = {
67
+ render: (args) => {
68
+ return <StoryRender {...args} />;
69
+ },
70
+ };
71
+
72
+ export const Open: Story = {
73
+ args: {
74
+ menuIsOpen: true,
75
+ },
76
+ render: (args) => {
77
+ return <StoryRender {...args} />;
78
+ },
79
+ };
80
+
81
+ export const Loading: Story = {
82
+ args: {
83
+ loading: true,
84
+ },
85
+ render: (args) => {
86
+ return <StoryRender {...args} />;
87
+ },
88
+ };
89
+
90
+ export const Disabled: Story = {
91
+ args: {
92
+ disabled: true,
93
+ },
94
+ render: (args) => {
95
+ return <StoryRender {...args} />;
96
+ },
97
+ };
98
+
99
+ export const WithSelections: Story = {
100
+ args: {
101
+ defaultValue: [options[0], options[1]],
102
+ },
103
+ render: (args) => {
104
+ return <StoryRender {...args} />;
105
+ },
106
+ };
107
+
108
+ function customOption(props: { data: any; isFocused?: boolean; isDisabled?: boolean }) {
109
+ const { user, role } = props.data;
110
+
111
+ return (
112
+ <div style={{ display: 'flex', justifyContent: 'space-between' }}>
113
+ <div>{user}</div>
114
+ <div>
115
+ <Icon style={{ color: '#ffa', marginRight: '0.5em', marginBottom: '-3px' }} name="fa-tag" />{' '}
116
+ {role}
117
+ </div>
118
+ </div>
119
+ );
120
+ }
121
+ export const WithCustomOptionComponent: Story = {
122
+ args: {
123
+ options: complexItems,
124
+ customOption,
125
+ customOptionLabel: (option: any) => `${option.email}`,
126
+ customOptionValue: (option: any) => `${option.email}`,
127
+ },
128
+ render: (args) => {
129
+ return <StoryRender {...args} />;
130
+ },
131
+ };
132
+
133
+ export const WithDataCyAttributes: Story = {
134
+ args: {
135
+ 'data-cy': 'cypressSelector',
136
+ multiValueProps: {
137
+ 'data-cy': 'multiValueSelector',
138
+ },
139
+ optionProps: {
140
+ 'data-cy': 'optionSelector',
141
+ },
142
+ },
143
+ render: (args) => {
144
+ return <StoryRender {...args} />;
145
+ },
146
+ };
@@ -0,0 +1,89 @@
1
+ import styled from 'styled-components';
2
+ import ReactSelect from 'react-select';
3
+
4
+ import { COLORS } from '@/tokens';
5
+ import { basicDefaults } from '../commonStyles';
6
+
7
+ const spacingCommon = '10px';
8
+
9
+ export const StyledMultiCombobox = styled(ReactSelect)`
10
+ ${basicDefaults};
11
+
12
+ background-color: ${COLORS.clay};
13
+
14
+ .combobox__control,
15
+ .combobox__menu {
16
+ background-color: inherit;
17
+ border: 1px solid ${COLORS.comet};
18
+ border-radius: 4px;
19
+ }
20
+
21
+ // overall component container
22
+ .combobox__control {
23
+ :hover {
24
+ border-color: ${COLORS.baliHai};
25
+ }
26
+ }
27
+
28
+ .combobox__control--is-disabled {
29
+ :hover {
30
+ border-color: ${COLORS.comet};
31
+ }
32
+ }
33
+
34
+ // the dropdown list container
35
+ .combobox__menu {
36
+ margin-top: 3px;
37
+ }
38
+
39
+ // text input placeholder text
40
+ .combobox__placeholder {
41
+ margin-left: calc(${spacingCommon} + 2px); // ensures text doesn’t overlap with input cursor
42
+ color: ${COLORS.lightFontColor};
43
+ }
44
+
45
+ // container component for the text input
46
+ .combobox__input-container {
47
+ margin-left: ${spacingCommon};
48
+ }
49
+
50
+ // container for selected items (visually inside input)
51
+ .combobox__value-container {
52
+ padding: 0;
53
+ border-radius: inherit;
54
+ }
55
+
56
+ // each selected item (pill)
57
+ .combobox__multi-value {
58
+ height: 30px;
59
+
60
+ color: ${COLORS.defaultFontColor};
61
+ background-color: ${COLORS.oxfordBlue};
62
+ border-radius: 2px;
63
+
64
+ > * {
65
+ color: inherit;
66
+ margin-top: auto;
67
+ margin-bottom: auto;
68
+ }
69
+
70
+ &__remove {
71
+ padding-right: ${spacingCommon};
72
+
73
+ :hover {
74
+ cursor: pointer;
75
+ color: ${COLORS.white};
76
+ background-color: transparent;
77
+ }
78
+ }
79
+
80
+ &__label {
81
+ padding-left: ${spacingCommon};
82
+ }
83
+ }
84
+
85
+ // caret button to open/close menu
86
+ .combobox__dropdown-indicator {
87
+ border-radius: inherit;
88
+ }
89
+ `;
@@ -0,0 +1,123 @@
1
+ // TODO: This component's migration was fast-tracked for Insights. Assess for potential refactor and documentation.
2
+
3
+ import React from 'react';
4
+ import { components } from 'react-select';
5
+
6
+ import { PermafrostComponent } from '@/types';
7
+ import { Icon } from '../../Icon';
8
+ import { addCustomProps } from '../utils';
9
+ import type { ComboboxProps, ComboboxOption } from '../types';
10
+
11
+ import { StyledMultiCombobox } from './MultiCombobox.styles';
12
+
13
+ type Props = PermafrostComponent &
14
+ ComboboxProps & {
15
+ /**
16
+ * MultiValue is a selected option in the input area
17
+ */
18
+ multiValueProps?: {
19
+ 'data-cy': string;
20
+ };
21
+ optionProps?: {
22
+ 'data-cy': string;
23
+ };
24
+ // validationErrors?: string[];
25
+ values?: ComboboxOption[];
26
+ onChange: (selectedOption: ComboboxOption[]) => void;
27
+ };
28
+
29
+ /**
30
+ * Multiselect combobox component. If selections are not bound to outside state
31
+ * via the `value` prop, you will need to import and use the `useCombobox` hook
32
+ * in order to clear its selected value .
33
+ *
34
+ * @see [useCombobox]{@link import('useCombobox').useCombobox}
35
+ */
36
+ export const MultiCombobox = React.forwardRef((props: Props, ref: any) => {
37
+ const {
38
+ className,
39
+ closeMenuOnSelect,
40
+ customOption,
41
+ customOptionLabel,
42
+ customOptionValue,
43
+ defaultValue,
44
+ disabled,
45
+ id,
46
+ loading,
47
+ menuIsOpen,
48
+ multiValueProps = {},
49
+ noOptionsMessage,
50
+ onChange,
51
+ optionProps = {},
52
+ options,
53
+ placeholder,
54
+ // validationErrors,
55
+ values,
56
+ } = props;
57
+
58
+ const MultiValue = (props: any) => {
59
+ return <components.MultiValue {...props} />;
60
+ };
61
+
62
+ const MultiValueRemove = (props: any) => {
63
+ return (
64
+ <components.MultiValueRemove {...props}>
65
+ <Icon name="x-close" ariaLabel="remove" size={[10]} />
66
+ </components.MultiValueRemove>
67
+ );
68
+ };
69
+
70
+ // handles a custom option component generator, if passed in
71
+ const Option = (props: any) => {
72
+ if (customOption) {
73
+ return (
74
+ <components.Option {...props} {...optionProps}>
75
+ {customOption(props)}
76
+ </components.Option>
77
+ );
78
+ }
79
+
80
+ return <components.Option {...props} {...optionProps} />;
81
+ };
82
+
83
+ const ComboboxComponent = () => (
84
+ <StyledMultiCombobox
85
+ aria-label={props['aria-label']}
86
+ aria-labelledby={props['aria-labelledby']}
87
+ ref={ref}
88
+ className={className}
89
+ classNamePrefix="combobox"
90
+ closeMenuOnSelect={closeMenuOnSelect}
91
+ components={{
92
+ MultiValue: addCustomProps(MultiValue, multiValueProps),
93
+ MultiValueRemove,
94
+ Option: addCustomProps(Option, optionProps),
95
+ }}
96
+ defaultValue={defaultValue}
97
+ getOptionLabel={customOptionLabel}
98
+ getOptionValue={customOptionValue}
99
+ id={id}
100
+ isClearable={false}
101
+ isDisabled={disabled}
102
+ isMulti
103
+ isLoading={loading}
104
+ menuIsOpen={menuIsOpen}
105
+ noOptionsMessage={() => noOptionsMessage}
106
+ onChange={onChange}
107
+ options={options}
108
+ placeholder={placeholder}
109
+ // validationErrors={validationErrors}
110
+ value={values}
111
+ />
112
+ );
113
+
114
+ if (props['data-cy']) {
115
+ return (
116
+ <div data-cy={props['data-cy']}>
117
+ <ComboboxComponent />
118
+ </div>
119
+ );
120
+ }
121
+
122
+ return <ComboboxComponent />;
123
+ });
@@ -0,0 +1 @@
1
+ export { MultiCombobox } from './MultiCombobox';
@@ -0,0 +1,54 @@
1
+ // TODO: This component's migration was fast-tracked for Insights. Assess for potential refactor and documentation.
2
+
3
+ import type { Meta, StoryObj } from '@storybook/react';
4
+
5
+ import { Select } from './Select';
6
+
7
+ const meta = {
8
+ component: Select,
9
+ title: 'dropdowns/Select',
10
+ argTypes: {},
11
+ args: {
12
+ onChange: () => {},
13
+ options: [
14
+ { name: 'Andy', value: 'andy' },
15
+ { name: 'Jackson', value: 'jackson' },
16
+ { name: 'Mike', value: 'mike' },
17
+ ],
18
+ },
19
+ } satisfies Meta<typeof Select>;
20
+
21
+ export default meta;
22
+ type Story = StoryObj<typeof Select>;
23
+
24
+ export const Base: Story = {};
25
+
26
+ export const InitialText: Story = {
27
+ args: {
28
+ initialText: 'Select Name',
29
+ },
30
+ };
31
+
32
+ export const Disabled: Story = {
33
+ args: {
34
+ disabled: true,
35
+ },
36
+ };
37
+
38
+ export const Small: Story = {
39
+ args: {
40
+ size: 'small',
41
+ },
42
+ };
43
+
44
+ export const Light: Story = {
45
+ args: {
46
+ variant: 'light',
47
+ },
48
+ parameters: {
49
+ backgrounds: {
50
+ default: 'light',
51
+ values: [{ name: 'light', value: '#fff' }],
52
+ },
53
+ },
54
+ };
@@ -0,0 +1,73 @@
1
+ import styled from 'styled-components';
2
+
3
+ import { COLORS, FONT_SIZE } from '@/tokens';
4
+
5
+ export const StyledSelect = styled.div`
6
+ display: inline-block;
7
+
8
+ .Select__container {
9
+ position: relative;
10
+ z-index: 0;
11
+
12
+ select {
13
+ color: ${COLORS.defaultFontColor};
14
+ appearance: none;
15
+ background: transparent;
16
+ border: none;
17
+ z-index: 1;
18
+
19
+ &:focus {
20
+ outline: 0;
21
+ }
22
+ }
23
+
24
+ option {
25
+ color: ${COLORS.black};
26
+
27
+ &:not(:checked) {
28
+ color: ${COLORS.black};
29
+ }
30
+ }
31
+
32
+ .chevron {
33
+ position: absolute;
34
+ top: 50%;
35
+ transform: translateY(-50%);
36
+ z-index: -1;
37
+ }
38
+
39
+ &.light {
40
+ select {
41
+ color: ${COLORS.black};
42
+ }
43
+
44
+ .chevron {
45
+ color: ${COLORS.black};
46
+ }
47
+ }
48
+
49
+ &.small {
50
+ select {
51
+ font-size: ${FONT_SIZE.base};
52
+ padding: 0;
53
+ padding-right: 15px;
54
+ }
55
+
56
+ .chevron {
57
+ right: 0px;
58
+ }
59
+ }
60
+
61
+ &.medium {
62
+ font-size: ${FONT_SIZE.subheadSmall};
63
+
64
+ select {
65
+ padding: 7px 35px 8px 15px;
66
+ }
67
+
68
+ .chevron {
69
+ right: 12px;
70
+ }
71
+ }
72
+ }
73
+ `;