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(comp): add defaultSelected and disabledKeys prop to Select #1216

Merged
merged 19 commits into from
Aug 20, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
ffa77ec
chore(jest): Update jest to version 27
sebald Jul 2, 2021
7f85798
Merge branch 'jest-major-update-to-27' into main
ti10le Jul 5, 2021
0ed336b
Merge branch 'main' of https://github.com/marigold-ui/marigold into main
ti10le Jul 5, 2021
3a04338
Merge branch 'main' of https://github.com/marigold-ui/marigold into main
ti10le Jul 5, 2021
a643b95
Merge branch 'main' of https://github.com/marigold-ui/marigold into main
ti10le Jul 8, 2021
6fb96ef
Merge branch 'main' of https://github.com/marigold-ui/marigold into main
ti10le Jul 14, 2021
9170315
Merge branch 'main' of https://github.com/marigold-ui/marigold into main
ti10le Jul 15, 2021
d2d4e30
Merge branch 'main' of https://github.com/marigold-ui/marigold into main
ti10le Jul 19, 2021
27c0cad
Merge branch 'main' of https://github.com/marigold-ui/marigold into main
ti10le Jul 21, 2021
9998892
Merge branch 'main' of https://github.com/marigold-ui/marigold into main
ti10le Jul 26, 2021
80f93ab
Merge branch 'main' of https://github.com/marigold-ui/marigold into main
ti10le Jul 28, 2021
3ff4ab7
wip selectedItem and disabledItem
ti10le Jul 28, 2021
8ee8356
Merge branch 'main' of https://github.com/marigold-ui/marigold into s…
ti10le Aug 16, 2021
5ccdcc4
fix select mdx file
ti10le Aug 16, 2021
42a3eb4
add test to fix coverage
ti10le Aug 16, 2021
9f69534
add cursor not allowed fix
ti10le Aug 19, 2021
aba3db4
make this PR better
ti10le Aug 20, 2021
51bd8c9
Merge branch 'main' of https://github.com/marigold-ui/marigold into s…
ti10le Aug 20, 2021
70390c1
fix prop table
ti10le Aug 20, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 65 additions & 8 deletions docs/content/components/select.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,17 @@ Dropdown for selecting an item among different options.

## Properties

| Property | Type | Default |
| :----------------------- | :-------- | :------ |
| `label` (optional) | `string` | |
| `placeholder` (optional) | `string` | |
| `disabled` (optional) | `boolean` | |
| `required` (optional) | `boolean` | |
| `error` (optional) | `string` | |
| Property | Type | Default |
| :------------------------------ | :------------------------------------------------------------------------------------------------------- | :------ |
| `label` (optional) | `string` | |
| `placeholder` (optional) | `string` | |
| `disabled` (optional) | `boolean` | |
| `selectedKey` (optional) | [Key](https://reactjs.org/docs/lists-and-keys.html) | |
| `defaultSelectedKey` (optional) | [Key](https://reactjs.org/docs/lists-and-keys.html) | |
| `disabledKeys` (optional) | [Iterable](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols)`<Key>` | |
| `required` (optional) | `boolean` | |
| `error` (optional) | `string` | |
| `onSelectionChange` (optional) | `(key: Key) => any` | |

## Import

Expand Down Expand Up @@ -56,14 +60,67 @@ import { Item } from '@marigold/components';
</Select>
```

### Disabeld Select
### Default selected Key (uncontrolled)

```tsx
<Select
label="Choose Color (uncontrolled)"
htmlFor="id"
defaultSelectedKey="Red"
>
<Item key="Red">Red</Item>
<Item key="Orange">Orange</Item>
<Item key="Yellow">Yellow</Item>
<Item key="Green">Green</Item>
<Item key="Blue">Blue</Item>
<Item key="Purple">Purple</Item>
</Select>
```

### Selected Key (controlled)

```tsx
() => {
const [color, setColor] = React.useState('Red');
return (
<Select
label="Choose Color (controlled)"
htmlFor="id"
selectedKey={color}
onSelectionChange={selected => setColor(selected)}
>
<Item key="Red">Red</Item>
<Item key="Orange">Orange</Item>
<Item key="Yellow">Yellow</Item>
<Item key="Green">Green</Item>
<Item key="Blue">Blue</Item>
<Item key="Purple">Purple</Item>
</Select>
);
};
```

### Disabled Select

```tsx
<Select label="Disabled Select:" disabled placeholder="disabled Select">
<Item>disabled Item</Item>
</Select>
```

### Disabled Keys

```tsx
<Select label="Favorite Color" htmlFor="id" disabledKeys={['Orange', 'Yellow']}>
<Item key="Red">Red</Item>
<Item key="Orange">Orange</Item>
<Item key="Yellow">Yellow</Item>
<Item key="Green">Green</Item>
<Item key="Blue">Blue</Item>
<Item key="Purple">Purple</Item>
</Select>
```

### Required label Select

```tsx
Expand Down
19 changes: 17 additions & 2 deletions packages/components/src/Select/Option.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useRef } from 'react';
import React, { useEffect, useRef, useState } from 'react';
import type { ListState } from '@react-stately/list';
import type { Node } from '@react-types/shared';
import { useOption } from '@react-aria/listbox';
Expand All @@ -12,6 +12,7 @@ interface OptionProps {

export const Option = ({ item, state }: OptionProps) => {
const ref = useRef<HTMLLIElement>(null);
const [disabled, setDisabled] = useState(false);
const { optionProps, isSelected } = useOption(
{
key: item.key,
Expand All @@ -20,12 +21,26 @@ export const Option = ({ item, state }: OptionProps) => {
ref
);

useEffect(() => {
for (const key of state.disabledKeys.values()) {
if (key === item.key) {
setDisabled(true);
}
}
}, [state.disabledKeys, item.key]);

return (
<Box
as="li"
{...optionProps}
ref={ref}
variant={isSelected ? 'select.option.selected' : 'select.option'}
variant={
isSelected
? 'select.option.selected'
: disabled
? 'select.option.disabled'
: 'select.option'
}
>
{item.rendered}
</Box>
Expand Down
8 changes: 4 additions & 4 deletions packages/components/src/Select/Select.stories.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -53,16 +53,16 @@ import { Item } from '@marigold/components';
# Select

export const Template = args => (
<Select label="Favorite Color" htmlFor="id" {...args}>
{/* Storybook crashes with imported <Item> component
<Select label="Favorite Color" htmlFor="id" {...args}>
{/* Storybook crashes with imported <Item> component
<Item>Red</Item>
<Item>Orange</Item>
<Item>Yellow</Item> */}
</Select>
</Select>
);

<Canvas>
<Story name="Default">{Template.bind({})}</Story>
</Canvas>

<ArgsTable story="Default" />
<ArgsTable story="Default" />
52 changes: 52 additions & 0 deletions packages/components/src/Select/Select.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -227,3 +227,55 @@ test('allow users to dismiss the popup with hidden dismiss button', () => {
fireEvent.click(dismissButton);
expect(selectButton).toHaveAttribute('aria-expanded', 'false');
});

test('supports default selectedKey prop', () => {
render(
<MarigoldProvider theme={theme}>
<Select label="MyLabel" data-testid="selectId" defaultSelectedKey="Red">
<Item key="Red">Red</Item>
<Item key="Orange">Orange</Item>
</Select>
</MarigoldProvider>
);
const button = screen.getByTestId('selectId');
expect(button).toHaveTextContent('Red');
});

test('supports change default selectedKey', () => {
render(
<MarigoldProvider theme={theme}>
<Select label="MyLabel" data-testid="selectId" defaultSelectedKey="Red">
<Item key="Red">Red</Item>
<Item key="Orange">Orange</Item>
</Select>
</MarigoldProvider>
);
const button = screen.getByTestId('selectId');
expect(button).toHaveTextContent('Red');

fireEvent.click(button);
const items = screen.getAllByText(/Red/);
fireEvent.click(items[1]);

expect(button).toHaveTextContent('Red');
});

test('supports disabled item prop', () => {
render(
<MarigoldProvider theme={theme}>
<Select label="MyLabel" data-testid="selectId" disabledKeys={['Red']}>
<Item key="Red">Red</Item>
<Item key="Orange">Orange</Item>
</Select>
</MarigoldProvider>
);
const button = screen.getByTestId('selectId');
fireEvent.click(button);
const redItem = screen.getAllByText(/Red/);
fireEvent.click(redItem[1]);
expect(button).toHaveTextContent('Select an option');

const orangeItem = screen.getAllByText(/Orange/);
fireEvent.click(orangeItem[1]);
expect(button).toHaveTextContent('Orange');
});
4 changes: 3 additions & 1 deletion packages/components/src/Select/Select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { HiddenSelect, useSelect } from '@react-aria/select';
import type { AriaSelectProps } from '@react-types/select';
import { useOverlayTriggerState } from '@react-stately/overlays';
import { useOverlayTrigger, useOverlayPosition } from '@react-aria/overlays';
import { SingleSelection } from '@react-types/shared';

import { ComponentProps } from '@marigold/types';
import { ArrowDown, ArrowUp, Exclamation, Required } from '@marigold/icons';
Expand All @@ -24,7 +25,8 @@ export type SelectProps = {
required?: boolean;
error?: string;
} & ComponentProps<'select'> &
AriaSelectProps<object>;
AriaSelectProps<object> &
SingleSelection;

export const Select = ({
placeholder = 'Select an option',
Expand Down
5 changes: 5 additions & 0 deletions themes/theme-b2b/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -548,6 +548,11 @@ const theme: BaseTheme = {
color: colors.gray00,
bg: colors.blue60,
},
disabled: {
...selectOption,
cursor: 'not-allowed',
color: colors.gray40,
ti10le marked this conversation as resolved.
Show resolved Hide resolved
},
},
},
validation: {
Expand Down
4 changes: 4 additions & 0 deletions themes/theme-unicorn/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -556,6 +556,10 @@ const theme: BaseTheme = {
color: colors.gray00,
bg: colors.blue60,
},
disabled: {
...selectOption,
color: colors.gray40,
},
},
},
validation: {
Expand Down