Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(@clayui/core): adds new width API for the picker #5813

Merged
merged 8 commits into from
Apr 29, 2024
44 changes: 44 additions & 0 deletions packages/clay-core/docs/picker.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,49 @@ import Layout from '@clayui/layout';
import {useId} from '@clayui/shared';
import React from 'react';

const PickerWidthExample = () => {
const imports = `import {Option, Picker} from '@clayui/core';
import Form from '@clayui/form';
import React from 'react';`;

const code = `const CustomWidth = () => {
return (
<div style={{width: '100px'}}>
<Form.Group>
<label htmlFor="picker" id="picker-label">
Year
</label>
<Picker
width={85}
aria-labelledby="picker-label"
id="picker"
items={[
'2020',
'2021',
'2022',
'2023',
'2024',
'2025',
'2026',
'2027',
'2028',
]}
placeholder="Year"
>
{(item) => <Option key={item}>{item}</Option>}
</Picker>
</Form.Group>
</div>
);
};

render(<CustomWidth />)`;

return (
<Editor code={code} imports={imports} scope={{Form, Option, Picker}} />
);
};

const exampleImports = `import {Option, Picker} from '@clayui/core';
import Form from '@clayui/form';
import React from 'react';`;
Expand Down Expand Up @@ -262,6 +305,7 @@ const PickerGroupExample = () => {
);
};
export {
PickerWidthExample,
PickerExample,
PickerGroupExample,
PickerTriggerExample,
Expand Down
6 changes: 6 additions & 0 deletions packages/clay-core/docs/picker.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ storybookPath: 'design-system-components-picker'
---

import {
PickerWidthExample,
PickerExample,
PickerGroupExample,
PickerTriggerExample,
Expand All @@ -26,6 +27,7 @@ import {
- [Custom Trigger](#custom-trigger)
- [Custom Options](#custom-options)
- [Group](#group)
- [Flexibe width](#flexibe-width)
matuzalemsteles marked this conversation as resolved.
Show resolved Hide resolved
- [Hybrid component](#hybrid-component)

</div>
Expand Down Expand Up @@ -153,6 +155,10 @@ The composition allows you to customize the component or add new features. See s

<PickerGroupExample />

## Flexible width

<PickerWidthExample />

## Hybrid component

Native select for mobile devices offers a better experience compared to Picker in some cases. The Picker offers the possibility to render using the native selector of the browser of the device when it is detected that it is on a mobile device, by default this property is disabled but it can be enabled by setting the `native` property to `true`.
Expand Down
21 changes: 19 additions & 2 deletions packages/clay-core/src/picker/Picker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,11 @@ export type Props<T> = {
*/
selectedKey?: React.Key;

/**
* Sets the fixed width of the panel.
*/
width?: number;

/**
* Sets the className for the React.Portal Menu element.
*/
Expand Down Expand Up @@ -163,6 +168,7 @@ export function Picker<T extends Record<string, any> | string | number>({
onSelectionChange,
placeholder = 'Select an option',
selectedKey: externalSelectedKey,
width,
...otherProps
}: Props<T>) {
const [active, setActive] = useControlledState({
Expand Down Expand Up @@ -521,14 +527,25 @@ export function Picker<T extends Record<string, any> | string | number>({
>
<div
className={classNames(
'dropdown-menu dropdown-menu-indicator-start dropdown-menu-select show',
'dropdown-menu dropdown-menu-indicator-start dropdown-menu-select dropdown-menu-width-shrink show',
{
'dropdown-menu-height-lg dropdown-menu-width-shrink':
'dropdown-menu-height-lg':
UNSAFE_behavior === 'secondary',
}
)}
ref={menuRef}
role="presentation"
style={{
maxWidth: 'none',
width: `${
typeof width === 'number'
? width
: (triggerRef.current?.clientWidth || 0) >
160
? triggerRef.current?.clientWidth
: 160
}px`,
}}
>
{UNSAFE_behavior === 'secondary' &&
(isArrowVisible === 'top' ||
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,9 @@ exports[`Picker basic rendering renders open component by default 1`] = `
</div>
<div>
<div
class="dropdown-menu dropdown-menu-indicator-start dropdown-menu-select show"
class="dropdown-menu dropdown-menu-indicator-start dropdown-menu-select dropdown-menu-width-shrink show"
role="presentation"
style="left: -999px; top: -995px;"
style="max-width: none; width: 160px; left: -999px; top: -995px;"
>
<ul
class="inline-scroller list-unstyled"
Expand Down
81 changes: 81 additions & 0 deletions packages/clay-core/stories/Picker.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -225,3 +225,84 @@ export const CustomGroup = () => {
</div>
);
};

export const Width = () => {
const pickerId = useId();
const labelId = useId();

return (
<>
<div style={{width: '250px'}}>
<Form.Group>
<label htmlFor={pickerId} id={labelId}>
Choose a fruit
</label>
<Picker aria-labelledby={labelId} id={pickerId}>
<Option key="apple">Apple</Option>
<Option disabled key="banana">
Banana
</Option>
<Option key="mangos">Mangos</Option>
<Option key="blueberry">Blueberry</Option>
<Option key="boysenberry">Boysenberry</Option>
<Option key="cherry">Cherry</Option>
<Option key="cranberry">Cranberry</Option>
<Option key="eggplant">Eggplant</Option>
<Option key="fig">Fig</Option>
<Option key="grape">Grape</Option>
<Option key="guava">Guava</Option>
<Option key="huckleberry">Huckleberry</Option>
</Picker>
</Form.Group>
</div>

<div style={{width: '100px'}}>
<Form.Group>
<label htmlFor={pickerId} id={labelId}>
Choose a fruit
</label>
<Picker
aria-labelledby={labelId}
id={pickerId}
placeholder="Fruit"
>
<Option key="apple">Apple</Option>
<Option disabled key="banana">
Banana
</Option>
<Option key="mangos">Mangos</Option>
<Option key="blueberry">Blueberry</Option>
<Option key="boysenberry">Boysenberry</Option>
<Option key="cherry">Cherry</Option>
<Option key="cranberry">Cranberry</Option>
<Option key="eggplant">Eggplant</Option>
<Option key="fig">Fig</Option>
<Option key="grape">Grape</Option>
<Option key="guava">Guava</Option>
<Option key="huckleberry">Huckleberry</Option>
</Picker>
</Form.Group>
</div>

<div style={{width: '100px'}}>
<Form.Group>
<label htmlFor={pickerId} id={labelId}>
Year
</label>
<Picker
aria-labelledby={labelId}
id={pickerId}
placeholder="Year"
width={85}
>
<Option key="2020">2020</Option>
<Option key="2021">2021</Option>
<Option key="2022">2022</Option>
<Option key="2023">2023</Option>
<Option key="2024">2024</Option>
</Picker>
</Form.Group>
</div>
</>
);
};
1 change: 1 addition & 0 deletions packages/clay-date-picker/src/DateNavigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ const ClayDatePickerDateNavigation = ({
)
}
selectedKey={String(currentMonth.getFullYear())}
width={85}
>
{(item) => (
<Option key={item.value}>
Expand Down