Skip to content

Commit

Permalink
feat(Select): add handling for long text in select field
Browse files Browse the repository at this point in the history
  • Loading branch information
booc0mtaco committed Feb 20, 2024
1 parent 32a3fe9 commit 7c79a6e
Show file tree
Hide file tree
Showing 4 changed files with 135 additions and 17 deletions.
7 changes: 7 additions & 0 deletions src/components/Select/Select.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@
* The caret icon to decorate the select trigger button, animated to rotate.
*/
.select-button__icon {
flex-shrink: 0;
transform: rotate(0);

transition: transform var(--eds-anim-move-medium) ease-out;
Expand All @@ -114,6 +115,12 @@
}
}

.select-button__text--truncated {
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}

.select-button__icon--reversed {
transform: rotate(180deg);
}
35 changes: 35 additions & 0 deletions src/components/Select/Select.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,41 @@ export const Multiple: StoryObj = {
},
};

/**
* The component provides some basic styles to handle long text in the provided field. Use
* `shouldTruncate` on `.ButtonWrapper` to truncate the text with an ellipsis.
*/
export const MultipleWithTruncation: StoryObj = {
args: {
...Default.args,
label: 'Favorite Animal(s)',
multiple: true,
'data-testid': 'dropdown',
defaultValue: [exampleOptions[0]],
className: 'w-60',
name: 'standard-button',
children: (
<>
<Select.Button>
{({ value, open, disabled }) => (
<Select.ButtonWrapper isOpen={open} shouldTruncate>
{value.length > 0 ? value.length : 'none'} long selected
description
</Select.ButtonWrapper>
)}
</Select.Button>
<Select.Options>
{exampleOptions.map((option) => (
<Select.Option key={option.key} value={option}>
{option.label}
</Select.Option>
))}
</Select.Options>
</>
),
},
};

/**
* The field trigger width can be set with utility classes. By default, dropdown popover will exppand to match the width.
*/
Expand Down
11 changes: 10 additions & 1 deletion src/components/Select/Select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,10 @@ type SelectButtonWrapperProps = {
* custom click handler for the built-in or wrapper button
*/
onClick?: MouseEventHandler;
/**
* Whether we should truncate the text displayed in the select field
*/
shouldTruncate?: boolean;
};

type SelectContextType = PopoverContext & {
Expand Down Expand Up @@ -399,6 +403,7 @@ export const SelectButtonWrapper = React.forwardRef<
className,
icon = 'expand-more',
isOpen,
shouldTruncate = false,
onClick: theirOnClick,
...other
},
Expand All @@ -409,6 +414,10 @@ export const SelectButtonWrapper = React.forwardRef<
styles['select-button__icon'],
isOpen && styles['select-button__icon--reversed'],
);
const textClassName = clsx(
shouldTruncate && styles['select-button__text--truncated'],
);

return (
<button
className={componentClassName}
Expand All @@ -421,7 +430,7 @@ export const SelectButtonWrapper = React.forwardRef<
>
{/* Wrapping span ensures that `children` and icon will be correctly pushed to
either side of the button even if `children` contains more than one element. */}
<span>{children}</span>
<span className={textClassName}>{children}</span>
<Icon
className={iconClassName}
name={icon}
Expand Down
99 changes: 83 additions & 16 deletions src/components/Select/__snapshots__/Select.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,24 @@ exports[`<Select /> Generated Snapshots AdjustedWidth story renders snapshot 1`]
<label
class="select__label"
data-headlessui-state="open"
id="headlessui-listbox-label-:r18:"
id="headlessui-listbox-label-:r1e:"
>
Favorite Animal
</label>
</div>
<button
aria-controls="headlessui-listbox-options-:r1a:"
aria-controls="headlessui-listbox-options-:r1g:"
aria-expanded="true"
aria-haspopup="listbox"
aria-labelledby="headlessui-listbox-label-:r18: headlessui-listbox-button-:r19:"
aria-labelledby="headlessui-listbox-label-:r1e: headlessui-listbox-button-:r1f:"
class="select-button"
data-headlessui-state="open"
id="headlessui-listbox-button-:r19:"
id="headlessui-listbox-button-:r1f:"
type="button"
>
<span>
<span
class=""
>
Dogs
</span>
<svg
Expand Down Expand Up @@ -75,7 +77,9 @@ exports[`<Select /> Generated Snapshots Default story renders snapshot 1`] = `
id="headlessui-listbox-button-:r1:"
type="button"
>
<span>
<span
class=""
>
Dogs
</span>
<svg
Expand Down Expand Up @@ -123,7 +127,9 @@ exports[`<Select /> Generated Snapshots Multiple story renders snapshot 1`] = `
id="headlessui-listbox-button-:r13:"
type="button"
>
<span>
<span
class=""
>
1
selected
</span>
Expand All @@ -145,22 +151,75 @@ exports[`<Select /> Generated Snapshots Multiple story renders snapshot 1`] = `
</div>
`;

exports[`<Select /> Generated Snapshots MultipleWithTruncation story renders snapshot 1`] = `
<div
class="select w-60"
data-headlessui-state="open"
data-testid="dropdown"
>
<div
class="select__overline"
>
<label
class="select__label"
data-headlessui-state="open"
id="headlessui-listbox-label-:r18:"
>
Favorite Animal(s)
</label>
</div>
<button
aria-controls="headlessui-listbox-options-:r1a:"
aria-expanded="true"
aria-haspopup="listbox"
aria-labelledby="headlessui-listbox-label-:r18: headlessui-listbox-button-:r19:"
class="select-button"
data-headlessui-state="open"
id="headlessui-listbox-button-:r19:"
type="button"
>
<span
class="select-button__text--truncated"
>
1
long selected description
</span>
<svg
aria-hidden="true"
class="icon select-button__icon select-button__icon--reversed"
fill="currentColor"
height="1.25rem"
style="--icon-size: 1.25rem;"
viewBox="0 0 24 24"
width="1.25rem"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M15.88 9.29L12 13.17 8.12 9.29c-.39-.39-1.02-.39-1.41 0-.39.39-.39 1.02 0 1.41l4.59 4.59c.39.39 1.02.39 1.41 0l4.59-4.59c.39-.39.39-1.02 0-1.41-.39-.38-1.03-.39-1.42 0z"
/>
</svg>
</button>
</div>
`;

exports[`<Select /> Generated Snapshots NoVisibleLabel story renders snapshot 1`] = `
<div
class="select"
data-headlessui-state="open"
data-testid="dropdown"
>
<button
aria-controls="headlessui-listbox-options-:r1f:"
aria-controls="headlessui-listbox-options-:r1l:"
aria-expanded="true"
aria-haspopup="listbox"
class="select-button"
data-headlessui-state="open"
id="headlessui-listbox-button-:r1e:"
id="headlessui-listbox-button-:r1k:"
type="button"
>
<span>
<span
class=""
>
Dogs
</span>
<svg
Expand Down Expand Up @@ -196,7 +255,9 @@ exports[`<Select /> Generated Snapshots StyledUncontrolled story renders snapsho
id="headlessui-listbox-button-:rt:"
type="button"
>
<span>
<span
class=""
>
Dogs
</span>
<svg
Expand Down Expand Up @@ -245,12 +306,12 @@ exports[`<Select /> Generated Snapshots UsingFunctionProps story renders snapsho
data-testid="dropdown"
>
<button
aria-controls="headlessui-listbox-options-:r1k:"
aria-controls="headlessui-listbox-options-:r1q:"
aria-expanded="true"
aria-haspopup="listbox"
class="fpo"
data-headlessui-state="open"
id="headlessui-listbox-button-:r1j:"
id="headlessui-listbox-button-:r1p:"
type="button"
>
Select
Expand Down Expand Up @@ -296,7 +357,9 @@ exports[`<Select /> Generated Snapshots WithFieldName story renders snapshot 1`]
id="headlessui-listbox-button-:rj:"
type="button"
>
<span>
<span
class=""
>
Dogs
</span>
<svg
Expand Down Expand Up @@ -344,7 +407,9 @@ exports[`<Select /> Generated Snapshots WithSelectedOption story renders snapsho
id="headlessui-listbox-button-:rd:"
type="button"
>
<span>
<span
class=""
>
Cats
</span>
<svg
Expand Down Expand Up @@ -392,7 +457,9 @@ exports[`<Select /> Generated Snapshots WithStandardButton story renders snapsho
id="headlessui-listbox-button-:r7:"
type="button"
>
<span>
<span
class=""
>
- Select Option -
</span>
<svg
Expand Down

0 comments on commit 7c79a6e

Please sign in to comment.