paris 0.13.6 → 0.14.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.
- package/CHANGELOG.md +19 -0
- package/package.json +1 -1
- package/src/stories/informationaltooltip/InformationalTooltip.module.scss +0 -1
- package/src/stories/informationaltooltip/InformationalTooltip.stories.tsx +6 -42
- package/src/stories/informationaltooltip/InformationalTooltip.tsx +92 -59
- package/src/stories/select/Select.module.scss +1 -2
- package/src/stories/select/Select.stories.ts +26 -4
- package/src/stories/select/Select.tsx +69 -20
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# paris
|
|
2
2
|
|
|
3
|
+
## 0.14.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- ffa4d0c: InformationalTooltip: Removed `headingIcon` prop
|
|
8
|
+
- ffa4d0c: InformationalTooltip: Opens onClick for mobile support, new `disableClick` prop to disable that behavior
|
|
9
|
+
|
|
10
|
+
## 0.14.0
|
|
11
|
+
|
|
12
|
+
### Minor Changes
|
|
13
|
+
|
|
14
|
+
- a805866: Select: added `multiple` prop to convert listbox into a multiselect
|
|
15
|
+
|
|
16
|
+
### Patch Changes
|
|
17
|
+
|
|
18
|
+
- fa49d95: Select: updated hover state for segemented control
|
|
19
|
+
- fa49d95: InformationalTooltip: added `defaultOpen` prop, replacing previous `open` prop
|
|
20
|
+
- fa49d95: InformationalTooltip: added exit animation, and animations use duration theme variables
|
|
21
|
+
|
|
3
22
|
## 0.13.6
|
|
4
23
|
|
|
5
24
|
### Patch Changes
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "paris",
|
|
3
3
|
"author": "Sanil Chawla <sanil@slingshot.fm> (https://sanil.co)",
|
|
4
4
|
"description": "Paris is Slingshot's React design system. It's a collection of reusable components, design tokens, and guidelines that help us build consistent, accessible, and performant user interfaces.",
|
|
5
|
-
"version": "0.
|
|
5
|
+
"version": "0.14.1",
|
|
6
6
|
"homepage": "https://paris.slingshot.fm",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"repository": {
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
2
|
import { createElement } from 'react';
|
|
3
|
-
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
|
4
|
-
import { faPlus } from '@fortawesome/free-solid-svg-icons';
|
|
5
3
|
import { InformationalTooltip } from './InformationalTooltip';
|
|
6
4
|
|
|
7
5
|
const meta: Meta<typeof InformationalTooltip> = {
|
|
@@ -13,17 +11,15 @@ const meta: Meta<typeof InformationalTooltip> = {
|
|
|
13
11
|
export default meta;
|
|
14
12
|
type Story = StoryObj<typeof InformationalTooltip>;
|
|
15
13
|
|
|
16
|
-
const render: Story['render'] = (args) =>
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
...args,
|
|
22
|
-
}));
|
|
14
|
+
const render: Story['render'] = (args) => createElement('div', {
|
|
15
|
+
style: { minHeight: '200px' },
|
|
16
|
+
}, createElement(InformationalTooltip, {
|
|
17
|
+
...args,
|
|
18
|
+
}));
|
|
23
19
|
|
|
24
20
|
export const Default: Story = {
|
|
25
21
|
args: {
|
|
26
|
-
children: 'If you are being
|
|
22
|
+
children: 'If you are being paid on 1099s (through transfer outs) you need to pay taxes quarterly. The amount you pay each quarter is a portion of your estimated tax burden for the year, based on your anticipated income amount. If you over/underpay, you will be refunded/owe the difference at the end of the year. ',
|
|
27
23
|
heading: 'Quarterly taxes',
|
|
28
24
|
},
|
|
29
25
|
render,
|
|
@@ -51,15 +47,6 @@ export const CustomTrigger: Story = {
|
|
|
51
47
|
render,
|
|
52
48
|
};
|
|
53
49
|
|
|
54
|
-
export const Open: Story = {
|
|
55
|
-
args: {
|
|
56
|
-
children: 'Open boolean set to true',
|
|
57
|
-
size: 'medium',
|
|
58
|
-
open: true,
|
|
59
|
-
},
|
|
60
|
-
render,
|
|
61
|
-
};
|
|
62
|
-
|
|
63
50
|
export const CustomAlign: Story = {
|
|
64
51
|
args: {
|
|
65
52
|
children: 'With some text below',
|
|
@@ -74,26 +61,3 @@ export const CustomAlign: Story = {
|
|
|
74
61
|
},
|
|
75
62
|
render,
|
|
76
63
|
};
|
|
77
|
-
|
|
78
|
-
export const HeadingIcon: Story = {
|
|
79
|
-
args: {
|
|
80
|
-
children: 'This is a medium tooltip with a heading',
|
|
81
|
-
size: 'medium',
|
|
82
|
-
headingIcon: (createElement(FontAwesomeIcon, {
|
|
83
|
-
icon: faPlus,
|
|
84
|
-
width: '14px',
|
|
85
|
-
})),
|
|
86
|
-
heading: 'Custom icon',
|
|
87
|
-
},
|
|
88
|
-
render,
|
|
89
|
-
};
|
|
90
|
-
|
|
91
|
-
export const NullIcon: Story = {
|
|
92
|
-
args: {
|
|
93
|
-
children: 'But the headingIcon is null',
|
|
94
|
-
size: 'medium',
|
|
95
|
-
headingIcon: null,
|
|
96
|
-
heading: 'This has a heading',
|
|
97
|
-
},
|
|
98
|
-
render,
|
|
99
|
-
};
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import type { FC, ReactNode } from 'react';
|
|
2
|
+
import { useState } from 'react';
|
|
2
3
|
import clsx from 'clsx';
|
|
3
4
|
import * as RadixTooltip from '@radix-ui/react-tooltip';
|
|
4
|
-
import { motion } from 'framer-motion';
|
|
5
|
+
import { motion, AnimatePresence } from 'framer-motion';
|
|
5
6
|
import styles from './InformationalTooltip.module.scss';
|
|
6
7
|
import { TextWhenString } from '../utility';
|
|
7
8
|
import { Icon, Info } from '../icon';
|
|
8
|
-
import { pvar } from '../theme';
|
|
9
|
+
import { pvar, pget } from '../theme';
|
|
9
10
|
|
|
10
11
|
export type InformationalTooltipProps = {
|
|
11
12
|
/**
|
|
@@ -18,8 +19,6 @@ export type InformationalTooltipProps = {
|
|
|
18
19
|
trigger?: ReactNode;
|
|
19
20
|
/** The heading text in the tooltip. If null, the heading will be hidden. */
|
|
20
21
|
heading?: string | null;
|
|
21
|
-
/** The heading icon in the tooltip. If undefined, will show info icon. If pass in an element, it will display in the heading. If set to null, will hide icon. */
|
|
22
|
-
headingIcon?: ReactNode | null | undefined;
|
|
23
22
|
/** The contents of the tooltip. */
|
|
24
23
|
children?: ReactNode;
|
|
25
24
|
/**
|
|
@@ -41,15 +40,15 @@ export type InformationalTooltipProps = {
|
|
|
41
40
|
*/
|
|
42
41
|
align?: 'start' | 'center' | 'end';
|
|
43
42
|
/**
|
|
44
|
-
*
|
|
43
|
+
* Whether the tooltip should be open by default.
|
|
44
|
+
* @default false
|
|
45
45
|
*/
|
|
46
|
-
|
|
46
|
+
defaultOpen?: boolean;
|
|
47
47
|
/**
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
* @param value {boolean} - The new open state of the tooltip.
|
|
48
|
+
* By default, tooltip opens on hover and on click (for mobile support). If you want to disable the click event, set this to true.
|
|
49
|
+
* @default false
|
|
51
50
|
*/
|
|
52
|
-
|
|
51
|
+
disableClick?: boolean;
|
|
53
52
|
};
|
|
54
53
|
|
|
55
54
|
/**
|
|
@@ -68,58 +67,92 @@ export const InformationalTooltip: FC<InformationalTooltipProps> = ({
|
|
|
68
67
|
size = 'large',
|
|
69
68
|
trigger,
|
|
70
69
|
heading,
|
|
71
|
-
headingIcon,
|
|
72
70
|
children,
|
|
73
71
|
side = 'bottom',
|
|
74
72
|
sideOffset = 6,
|
|
75
73
|
align = 'start',
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
}) =>
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
74
|
+
defaultOpen = false,
|
|
75
|
+
disableClick = false,
|
|
76
|
+
}) => {
|
|
77
|
+
const [isOpen, setOpen] = useState(defaultOpen);
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Converts a CSS time value string to milliseconds
|
|
81
|
+
* @param timeValue - The CSS time value (e.g. '100ms', '0.5s')
|
|
82
|
+
* @returns The time value in milliseconds
|
|
83
|
+
* @throws Error if the time value format is invalid
|
|
84
|
+
*/
|
|
85
|
+
const parseCSSTime = (timeValue: string): number => {
|
|
86
|
+
// Match the value and unit
|
|
87
|
+
const match = timeValue.match(/^([\d.]+)(ms|s)$/);
|
|
88
|
+
|
|
89
|
+
if (!match) {
|
|
90
|
+
console.warn('Invalid CSS time format. Expected formats: "100ms", "0.5s"');
|
|
91
|
+
return 0;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const [, value, unit] = match;
|
|
95
|
+
const numValue = parseFloat(value);
|
|
96
|
+
|
|
97
|
+
// Convert to milliseconds based on the unit
|
|
98
|
+
return unit === 's' ? numValue * 1000 : numValue;
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
return (
|
|
102
|
+
<RadixTooltip.Provider
|
|
103
|
+
delayDuration={parseCSSTime(pget('new.animations.duration.normal'))}
|
|
85
104
|
>
|
|
86
|
-
<RadixTooltip.
|
|
87
|
-
{
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
<RadixTooltip.Content
|
|
97
|
-
side={side}
|
|
98
|
-
sideOffset={sideOffset}
|
|
99
|
-
align={align}
|
|
105
|
+
<RadixTooltip.Root
|
|
106
|
+
open={isOpen}
|
|
107
|
+
onOpenChange={setOpen}
|
|
108
|
+
>
|
|
109
|
+
<RadixTooltip.Trigger
|
|
110
|
+
onClick={() => {
|
|
111
|
+
if (!disableClick) {
|
|
112
|
+
setOpen(!isOpen);
|
|
113
|
+
}
|
|
114
|
+
}}
|
|
100
115
|
>
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
116
|
+
{!trigger ? (
|
|
117
|
+
<Icon icon={Info} size={14} className={styles.icon} style={{ color: pvar('new.colors.contentSecondary') }} />
|
|
118
|
+
) : (
|
|
119
|
+
<>
|
|
120
|
+
{trigger}
|
|
121
|
+
</>
|
|
122
|
+
)}
|
|
123
|
+
</RadixTooltip.Trigger>
|
|
124
|
+
<AnimatePresence>
|
|
125
|
+
{isOpen && (
|
|
126
|
+
<RadixTooltip.Portal forceMount>
|
|
127
|
+
<RadixTooltip.Content
|
|
128
|
+
side={side}
|
|
129
|
+
sideOffset={sideOffset}
|
|
130
|
+
align={align}
|
|
131
|
+
asChild
|
|
132
|
+
>
|
|
133
|
+
<motion.div
|
|
134
|
+
initial={{ opacity: 0, y: 3 }}
|
|
135
|
+
animate={{ opacity: 1, y: 0 }}
|
|
136
|
+
exit={{ opacity: 0, y: 3 }}
|
|
137
|
+
transition={{ duration: parseCSSTime(pget('new.animations.duration.normal')) / 1000 }}
|
|
138
|
+
className={clsx(styles.tooltip, styles[size])}
|
|
139
|
+
>
|
|
140
|
+
{heading && (
|
|
141
|
+
<div className={styles.heading}>
|
|
142
|
+
<TextWhenString as="p" kind="paragraphXSmall" weight="medium">
|
|
143
|
+
{heading}
|
|
144
|
+
</TextWhenString>
|
|
145
|
+
</div>
|
|
146
|
+
)}
|
|
147
|
+
<TextWhenString as="p" kind="paragraphXSmall">
|
|
148
|
+
{children}
|
|
149
|
+
</TextWhenString>
|
|
150
|
+
</motion.div>
|
|
151
|
+
</RadixTooltip.Content>
|
|
152
|
+
</RadixTooltip.Portal>
|
|
153
|
+
)}
|
|
154
|
+
</AnimatePresence>
|
|
155
|
+
</RadixTooltip.Root>
|
|
156
|
+
</RadixTooltip.Provider>
|
|
157
|
+
);
|
|
158
|
+
};
|
|
@@ -15,13 +15,20 @@ type Story = StoryObj<typeof Select>;
|
|
|
15
15
|
const render: Story['render'] = (args) => {
|
|
16
16
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
17
17
|
const [selected, setSelected] = useState<string | null>(null);
|
|
18
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
19
|
+
const [selectedMultiple, setSelectedMultiple] = useState<string[] | null>([]);
|
|
18
20
|
return createElement('div', {
|
|
19
21
|
style: { minHeight: '400px' },
|
|
20
|
-
}, createElement(Select, {
|
|
22
|
+
}, createElement(Select, args.multiple ? {
|
|
21
23
|
...args,
|
|
22
|
-
value:
|
|
23
|
-
onChange: (
|
|
24
|
-
}
|
|
24
|
+
value: selectedMultiple,
|
|
25
|
+
onChange: (value: string[] | null) => setSelectedMultiple(value),
|
|
26
|
+
}
|
|
27
|
+
: {
|
|
28
|
+
...args,
|
|
29
|
+
value: selected,
|
|
30
|
+
onChange: (value: string | null) => setSelected(value),
|
|
31
|
+
}));
|
|
25
32
|
};
|
|
26
33
|
|
|
27
34
|
export const Default: Story = {
|
|
@@ -112,6 +119,21 @@ export const Card: Story = {
|
|
|
112
119
|
render,
|
|
113
120
|
};
|
|
114
121
|
|
|
122
|
+
export const Multiple: Story = {
|
|
123
|
+
args: {
|
|
124
|
+
label: 'Release type',
|
|
125
|
+
description: 'Select the type of release you want to create.',
|
|
126
|
+
options: [
|
|
127
|
+
{ id: '1', node: 'Single' },
|
|
128
|
+
{ id: '2', node: 'EP' },
|
|
129
|
+
{ id: '3', node: 'Album (LP)' },
|
|
130
|
+
],
|
|
131
|
+
multiple: true,
|
|
132
|
+
multipleItemsName: 'releases',
|
|
133
|
+
},
|
|
134
|
+
render,
|
|
135
|
+
};
|
|
136
|
+
|
|
115
137
|
export const Segmented: Story = {
|
|
116
138
|
args: {
|
|
117
139
|
label: 'Donation',
|
|
@@ -29,7 +29,7 @@ export type Option<T = Record<string, any>> = {
|
|
|
29
29
|
disabled?: boolean,
|
|
30
30
|
metadata?: T,
|
|
31
31
|
};
|
|
32
|
-
export type
|
|
32
|
+
export type CommonSelectProps<T = Record<string, any>> = {
|
|
33
33
|
/**
|
|
34
34
|
* The {@link Option}s to render in the select box.
|
|
35
35
|
*
|
|
@@ -38,21 +38,6 @@ export type SelectProps<T = Record<string, any>> = {
|
|
|
38
38
|
* For type safety, you can pass in a type parameter to `SelectProps` component. This will be used as the type for the `metadata` property of each option.
|
|
39
39
|
*/
|
|
40
40
|
options: Option<T>[];
|
|
41
|
-
/**
|
|
42
|
-
* The option ID to render as selected in the select box.
|
|
43
|
-
*
|
|
44
|
-
* This should exactly match one of the option IDs passed in the `options` prop. If `null`, no option will be selected.
|
|
45
|
-
*/
|
|
46
|
-
value?: Option<T>['id'] | null;
|
|
47
|
-
/**
|
|
48
|
-
* The interaction handler for the Select.
|
|
49
|
-
*/
|
|
50
|
-
onChange?: (value: Option<T>['id'] | null) => void | Promise<void>;
|
|
51
|
-
/**
|
|
52
|
-
* The visual variant of the Select. `listbox` will render as a dropdown menu, `radio` will render as a radio group, `card` will render as selectable cards, and `segmented` will render as a segmented control.
|
|
53
|
-
* @default listbox
|
|
54
|
-
*/
|
|
55
|
-
kind?: 'listbox' | 'radio' | 'card' | 'segmented';
|
|
56
41
|
/**
|
|
57
42
|
* The size of the options dropdown, in pixels. Only applicable to kind="listbox".
|
|
58
43
|
*/
|
|
@@ -67,7 +52,6 @@ export type SelectProps<T = Record<string, any>> = {
|
|
|
67
52
|
* @default compact
|
|
68
53
|
*/
|
|
69
54
|
segmentedHeight?: 'compact' | 'tall';
|
|
70
|
-
|
|
71
55
|
/**
|
|
72
56
|
* Prop overrides for other rendered elements. Overrides for the input itself should be passed directly to the component.
|
|
73
57
|
*/
|
|
@@ -83,6 +67,55 @@ export type SelectProps<T = Record<string, any>> = {
|
|
|
83
67
|
}
|
|
84
68
|
} & Omit<InputProps, 'type' | 'overrides'>;
|
|
85
69
|
|
|
70
|
+
export type SingleSelectProps<T = Record<string, any>> = {
|
|
71
|
+
/**
|
|
72
|
+
* The option ID to render as selected in the select box.
|
|
73
|
+
*
|
|
74
|
+
* This should exactly match the option IDs passed in the `options` prop. If `null`, no option will be selected.
|
|
75
|
+
*/
|
|
76
|
+
value?: Option<T>['id'] | null;
|
|
77
|
+
/**
|
|
78
|
+
* The interaction handler for the Select.
|
|
79
|
+
*/
|
|
80
|
+
onChange?: (value: Option<T>['id'] | null) => void | Promise<void>;
|
|
81
|
+
/**
|
|
82
|
+
* The visual variant of the Select. `listbox` will render as a dropdown menu, `radio` will render as a radio group, `card` will render as selectable cards, and `segmented` will render as a segmented control.
|
|
83
|
+
* @default listbox
|
|
84
|
+
*/
|
|
85
|
+
kind?: 'listbox' | 'radio' | 'card' | 'segmented';
|
|
86
|
+
multiple?: false;
|
|
87
|
+
multipleItemsName?: never;
|
|
88
|
+
} & CommonSelectProps;
|
|
89
|
+
|
|
90
|
+
export type MultiSelectProps<T = Record<string, any>> = {
|
|
91
|
+
/**
|
|
92
|
+
* Controls the text of the Multiselect button when multiple items selected, such as "All ___" or "2 ___"
|
|
93
|
+
* @default items
|
|
94
|
+
*/
|
|
95
|
+
multipleItemsName?: string;
|
|
96
|
+
/**
|
|
97
|
+
* The visual variant of the Select. For multiselect, only `listbox` is supported.
|
|
98
|
+
* @default listbox
|
|
99
|
+
*/
|
|
100
|
+
kind?: 'listbox',
|
|
101
|
+
/**
|
|
102
|
+
* Converts the single select into a multiselect.
|
|
103
|
+
*/
|
|
104
|
+
multiple: true;
|
|
105
|
+
/**
|
|
106
|
+
* For multiselect, should be a string[] that matches the option IDs passed in the `options` prop. If `null`, no option will be selected.
|
|
107
|
+
*/
|
|
108
|
+
value?: Option<T>['id'][] | null;
|
|
109
|
+
/**
|
|
110
|
+
* The interaction handler for the Select.
|
|
111
|
+
*/
|
|
112
|
+
onChange?: (value: Option<T>['id'][] | null) => void | Promise<void>;
|
|
113
|
+
} & CommonSelectProps;
|
|
114
|
+
|
|
115
|
+
type SelectProps<T = Record<string, any>> =
|
|
116
|
+
| (SingleSelectProps<T>)
|
|
117
|
+
| (MultiSelectProps<T>);
|
|
118
|
+
|
|
86
119
|
/**
|
|
87
120
|
* A Select component is used to render a `select` box.
|
|
88
121
|
*
|
|
@@ -112,10 +145,25 @@ export const Select = forwardRef(function <T = Record<string, any>>({
|
|
|
112
145
|
kind = 'listbox',
|
|
113
146
|
maxHeight = 320,
|
|
114
147
|
hasOptionBorder = false,
|
|
148
|
+
multiple = false,
|
|
149
|
+
multipleItemsName,
|
|
115
150
|
segmentedHeight = 'compact',
|
|
116
151
|
overrides,
|
|
117
152
|
}: SelectProps<T>, ref: ForwardedRef<any>) {
|
|
118
153
|
const inputID = useId();
|
|
154
|
+
const multiItems = multipleItemsName || 'items';
|
|
155
|
+
const buttonText = () => {
|
|
156
|
+
if (!value || value.length === 0) {
|
|
157
|
+
return placeholder || 'Select an option';
|
|
158
|
+
} if (!multiple) {
|
|
159
|
+
return options?.find((o) => o.id === value)?.node;
|
|
160
|
+
} if (value && value.length === 1) {
|
|
161
|
+
return options?.find((o) => o.id === value[0])?.node;
|
|
162
|
+
} if (value.length === options.length) {
|
|
163
|
+
return `All ${multiItems}`;
|
|
164
|
+
}
|
|
165
|
+
return `${value.length} ${multiItems}`;
|
|
166
|
+
};
|
|
119
167
|
return (
|
|
120
168
|
<Field
|
|
121
169
|
htmlFor={inputID}
|
|
@@ -137,6 +185,7 @@ export const Select = forwardRef(function <T = Record<string, any>>({
|
|
|
137
185
|
ref={ref}
|
|
138
186
|
value={value}
|
|
139
187
|
onChange={onChange}
|
|
188
|
+
multiple={multiple}
|
|
140
189
|
>
|
|
141
190
|
<Listbox.Button
|
|
142
191
|
id={inputID}
|
|
@@ -164,7 +213,7 @@ export const Select = forwardRef(function <T = Record<string, any>>({
|
|
|
164
213
|
)}
|
|
165
214
|
</div>
|
|
166
215
|
)}
|
|
167
|
-
{
|
|
216
|
+
{buttonText()}
|
|
168
217
|
{endEnhancer ? (
|
|
169
218
|
<div
|
|
170
219
|
{...overrides?.endEnhancerContainer}
|
|
@@ -205,7 +254,7 @@ export const Select = forwardRef(function <T = Record<string, any>>({
|
|
|
205
254
|
<Listbox.Option
|
|
206
255
|
key={option.id}
|
|
207
256
|
value={option.id}
|
|
208
|
-
data-selected={option.id === value}
|
|
257
|
+
data-selected={option.id === value || (value && value.includes(option.id))}
|
|
209
258
|
className={clsx(
|
|
210
259
|
overrides?.option,
|
|
211
260
|
styles.option,
|
|
@@ -218,7 +267,7 @@ export const Select = forwardRef(function <T = Record<string, any>>({
|
|
|
218
267
|
{option.node}
|
|
219
268
|
</Text>
|
|
220
269
|
) : option.node}
|
|
221
|
-
{option.id === value && (
|
|
270
|
+
{(option.id === value || (value && value.includes(option.id))) && (
|
|
222
271
|
<Icon icon={Check} size={12} />
|
|
223
272
|
)}
|
|
224
273
|
</Listbox.Option>
|