Skip to content

Commit 81281f1

Browse files
authored
feat(Select): add description support (#695)
1 parent fe6d92c commit 81281f1

File tree

4 files changed

+67
-16
lines changed

4 files changed

+67
-16
lines changed

.changeset/curly-toes-burn.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@cube-dev/ui-kit": minor
3+
---
4+
5+
Remove `ellipsis` flag from `<Select/>`. Text overflow ellipsis is now always used.

.changeset/spicy-mails-whisper.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@cube-dev/ui-kit": patch
3+
---
4+
5+
Add support for description in `Select.Item`.

src/components/fields/Select/Select.stories.tsx

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ export const Primary = Template.bind({});
6565
Primary.args = { type: 'primary', placeholder: 'primary' };
6666

6767
export const Clear = Template.bind({});
68-
Clear.args = { type: 'clear', placeholder: 'clear', width: 'min-content' };
68+
Clear.args = { type: 'clear', placeholder: 'clear', width: 'max-content' };
6969

7070
export const Invalid = Template.bind({});
7171
Invalid.args = { selectedKey: 'yellow', validationState: 'invalid' };
@@ -107,11 +107,33 @@ export const Wide: StoryFn<CubeSelectProps<any>> = (args) => (
107107
))}
108108
</Select>
109109
);
110-
Wide.args = { width: '500px', defaultSelectedKey: options[0] };
110+
Wide.args = { width: 'max-content', defaultSelectedKey: options[0] };
111111

112112
export const WithEllipsis = Template.bind({});
113113
WithEllipsis.args = {
114-
ellipsis: true,
115114
styles: { width: 'max 30x' },
116115
defaultSelectedKey: 'very-long-option-value-with-suffix',
117116
};
117+
118+
export const WithDescription: StoryFn<CubeSelectProps<any>> = (args) => (
119+
<Select
120+
{...args}
121+
placeholder="Select a color"
122+
listBoxStyles={{ width: 'max 30x' }}
123+
>
124+
<Select.Item key="red" description="The color of fire">
125+
Red
126+
</Select.Item>
127+
<Select.Item key="green" description="The color of nature">
128+
Green
129+
</Select.Item>
130+
<Select.Item
131+
key="blue"
132+
description="The color of the sky (very long description)"
133+
>
134+
Blue
135+
</Select.Item>
136+
</Select>
137+
);
138+
WithDescription.args = {};
139+
WithDescription.play = WithDisabledOption.play;

src/components/fields/Select/Select.tsx

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -95,10 +95,7 @@ const SelectWrapperElement = tasty({
9595
textAlign: 'left',
9696
fill: '#clear',
9797
textOverflow: 'ellipsis',
98-
overflow: {
99-
'': 'initial',
100-
ellipsis: 'hidden',
101-
},
98+
overflow: 'hidden',
10299
},
103100

104101
CaretIcon: {
@@ -179,7 +176,7 @@ const ListBoxElement = tasty({
179176
as: 'ul',
180177
styles: {
181178
display: 'flex',
182-
gap: '.5x',
179+
gap: '1bw',
183180
flow: 'column',
184181
margin: '0',
185182
padding: '.5x',
@@ -196,7 +193,9 @@ const ListBoxElement = tasty({
196193
const OptionElement = tasty({
197194
as: 'li',
198195
styles: {
199-
display: 'block',
196+
display: 'flex',
197+
flow: 'column',
198+
gap: '0',
200199
padding: '(1x - 1px) (1.5x - 1px)',
201200
cursor: 'pointer',
202201
radius: true,
@@ -214,6 +213,23 @@ const OptionElement = tasty({
214213
},
215214
preset: 't3',
216215
transition: 'theme',
216+
width: 'max 100%',
217+
218+
Label: {
219+
preset: 't3',
220+
overflow: 'hidden',
221+
textOverflow: 'ellipsis',
222+
width: 'max 100%',
223+
},
224+
225+
Description: {
226+
preset: 't4',
227+
color: '#dark-03',
228+
overflow: 'hidden',
229+
whiteSpace: 'nowrap',
230+
textOverflow: 'ellipsis',
231+
width: 'max 100%',
232+
},
217233
},
218234
});
219235

@@ -265,7 +281,6 @@ export interface CubeSelectProps<T> extends CubeSelectBaseProps<T> {
265281
/** The ref for the list box. */
266282
listBoxRef?: RefObject<HTMLElement>;
267283
size?: 'small' | 'default' | 'large' | string;
268-
ellipsis?: boolean;
269284
placeholder?: string;
270285
}
271286

@@ -321,7 +336,6 @@ function Select<T extends object>(
321336
type = 'outline',
322337
theme = 'default',
323338
labelSuffix,
324-
ellipsis,
325339
suffixPosition = 'before',
326340
...otherProps
327341
} = props;
@@ -383,7 +397,6 @@ function Select<T extends object>(
383397

384398
const modifiers = useMemo(
385399
() => ({
386-
ellipsis,
387400
invalid: isInvalid,
388401
valid: validationState === 'valid',
389402
disabled: isDisabled,
@@ -395,7 +408,6 @@ function Select<T extends object>(
395408
suffix: true,
396409
}),
397410
[
398-
ellipsis,
399411
validationState,
400412
isDisabled,
401413
isLoading,
@@ -575,11 +587,12 @@ function Option({ item, state, styles, shouldUseVirtualFocus }) {
575587
// style to the focused option
576588
let { isFocused, focusProps } = useFocus({ isDisabled });
577589

590+
const description = (item as any)?.props?.description;
591+
578592
return (
579593
<OptionElement
580594
{...mergeProps(optionProps, focusProps)}
581595
ref={ref}
582-
key={item.key}
583596
mods={{
584597
selected: isSelected,
585598
focused: shouldUseVirtualFocus ? isVirtualFocused : isFocused,
@@ -588,7 +601,8 @@ function Option({ item, state, styles, shouldUseVirtualFocus }) {
588601
data-theme={isSelected ? 'special' : undefined}
589602
styles={styles}
590603
>
591-
{item.rendered}
604+
<div data-element="Label">{item.rendered}</div>
605+
{description ? <div data-element="Description">{description}</div> : null}
592606
</OptionElement>
593607
);
594608
}
@@ -601,7 +615,12 @@ const __Select = Object.assign(
601615
_Select as typeof _Select & {
602616
Item: typeof Item;
603617
},
604-
{ Item },
618+
{
619+
Item: Item as unknown as (props: {
620+
description?: ReactNode;
621+
[key: string]: any;
622+
}) => null,
623+
},
605624
);
606625

607626
__Select.displayName = 'Select';

0 commit comments

Comments
 (0)