Skip to content

Commit

Permalink
Feat(web-react): Deprecate non-flow-relative placements in Dropdown
Browse files Browse the repository at this point in the history
… #DS-1132

Use flow-relative placement values instead, e.g. `top-left` is now `top-start`.
  • Loading branch information
crishpeen authored and adamkudrna committed Feb 20, 2024
1 parent e954642 commit f4aa004
Show file tree
Hide file tree
Showing 14 changed files with 130 additions and 97 deletions.
9 changes: 5 additions & 4 deletions packages/web-react/src/components/Dropdown/Dropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,18 @@ import { useDropdownStyleProps } from './useDropdownStyleProps';

const defaultProps = {
enableAutoClose: true,
placement: Placements.BOTTOM_LEFT,
placement: Placements.BOTTOM_START,
};

export const Dropdown = (props: SpiritDropdownProps) => {
const {
id = Math.random().toString(36).slice(2, 7),
children,
renderTrigger,
enableAutoClose,
fullWidthMode,
id = Math.random().toString(36).slice(2, 7),
onAutoClose,
placement = defaultProps.placement,
renderTrigger,
...rest
} = props;

Expand All @@ -32,7 +33,7 @@ export const Dropdown = (props: SpiritDropdownProps) => {

const { isOpen, toggleHandler } = useDropdown({ dropdownRef, triggerRef, enableAutoClose, onAutoClose });
const { classProps, props: modifiedProps } = useDropdownStyleProps({ isOpen, ...rest });
const { triggerProps, contentProps } = useDropdownAriaProps({ id, isOpen, toggleHandler, fullWidthMode });
const { triggerProps, contentProps } = useDropdownAriaProps({ id, isOpen, fullWidthMode, placement, toggleHandler });

const { styleProps: contentStyleProps, props: contentOtherProps } = useStyleProps({ ...modifiedProps });
const { styleProps: triggerStyleProps } = useStyleProps({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const defaultContext: DropdownContextType = {
id: '',
isOpen: false,
onToggle: () => {},
placement: Placements.BOTTOM_LEFT,
placement: Placements.BOTTOM_START,
triggerRef: { current: undefined },
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ interface DropdownPopoverProps extends ChildrenProps, StyleProps {}
export const DropdownPopover = (props: DropdownPopoverProps) => {
const { children, ...rest } = props;
const { id, isOpen, onToggle, fullWidthMode, placement } = useDropdownContext();
const { classProps, props: modifiedProps } = useDropdownStyleProps({ isOpen, placement, ...rest });
const { classProps, props: modifiedProps } = useDropdownStyleProps({ isOpen, ...rest });
const { styleProps: contentStyleProps, props: contentOtherProps } = useStyleProps({ ...modifiedProps });
const { contentProps } = useDropdownAriaProps({ id, isOpen, toggleHandler: onToggle, fullWidthMode });
const { contentProps } = useDropdownAriaProps({ id, isOpen, toggleHandler: onToggle, placement, fullWidthMode });

return (
<div
Expand Down
57 changes: 33 additions & 24 deletions packages/web-react/src/components/Dropdown/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,14 @@ import { Dropdown, Button, Item } from '@lmc-eu/spirit-web-react/components';

## API

| Name | Type | Default | Required | Description |
| ----------------- | ------------------------------------------------ | ------------- | -------- | ---------------------------------------------- |
| `enableAutoClose` | `bool` | `true` || Enables close on click outside of Dropdown |
| `fullWidthMode` | [`DropdownFullwidthMode`][dropdownfullwidthmode] | `off` || Full-width mode |
| `id` | `string` | `<random>` || Component id |
| `onAutoClose` . | `(event: Event) => void` ||| Callback on close on click outside of Dropdown |
| `placement` | [Placement dictionary][dictionary-placement] | `bottom-left` || Alignment of the component |
| `renderTrigger` | `(render: DropdownRenderProps) => ReactNode` ||| Properties for trigger render |
| Name | Type | Default | Required | Description |
| ----------------- | ------------------------------------------------ | -------------- | -------- | ---------------------------------------------- |
| `enableAutoClose` | `bool` | `true` || Enables close on click outside of Dropdown |
| `fullWidthMode` | [`DropdownFullwidthMode`][dropdownfullwidthmode] | `off` || Full-width mode |
| `id` | `string` | `<random>` || Component id |
| `onAutoClose` . | `(event: Event) => void` | || Callback on close on click outside of Dropdown |
| `placement` | [Placement dictionary][dictionary-placement] | `bottom-start` || Alignment of the component |
| `renderTrigger` | `(render: DropdownRenderProps) => ReactNode` | || Properties for trigger render |

On top of the API options, the components accept [additional attributes][readme-additional-attributes].
If you need more control over the styling of a component, you can use [style props][readme-style-props]
Expand Down Expand Up @@ -77,6 +77,14 @@ const onToggle = () => setIsOpen(!isOpen);
</DropdownModern>;
```

### ⚠️ DEPRECATION NOTICE

Both cross-axis placements have been renamed from `top-left`, `top-right`, `right-top`, `right-bottom`,
etc. to `top-start`, `top-end`, `right-start`, `right-end`, etc. The old names are deprecated and will be
removed in the next major release.

[What are deprecations?][readme-deprecations]

### Dropdown with Item

Enhance your DropdownPopover by incorporating the versatile [Item][item] component.
Expand Down Expand Up @@ -111,15 +119,15 @@ import { UncontrolledDropdown, DropdownTrigger, DropdownPopover } from '@lmc-eu/

### DropdownModern

| Name | Type | Default | Required | Description |
| ----------------- | ------------------------------------------------ | ------------- | -------- | ---------------------------------------------- |
| `enableAutoClose` | `bool` | `true` || Enables close on click outside of Dropdown |
| `fullWidthMode` | [`DropdownFullwidthMode`][dropdownfullwidthmode] | `off` || Full-width mode |
| `id` | `string` | - || Component id |
| `isOpen` | `bool` | `false` || Open state |
| `onAutoClose` | `(event: Event) => void` ||| Callback on close on click outside of Dropdown |
| `onToggle` | `() => void` ||| Function for toggle open state of dropdown |
| `placement` | [Placement dictionary][dictionary-placement] | `bottom-left` || Alignment of the component |
| Name | Type | Default | Required | Description |
| ----------------- | ------------------------------------------------ | -------------- | -------- | ---------------------------------------------- |
| `enableAutoClose` | `bool` | `true` || Enables close on click outside of Dropdown |
| `fullWidthMode` | [`DropdownFullwidthMode`][dropdownfullwidthmode] | `off` || Full-width mode |
| `id` | `string` | - || Component id |
| `isOpen` | `bool` | `false` || Open state |
| `onAutoClose` | `(event: Event) => void` | || Callback on close on click outside of Dropdown |
| `onToggle` | `() => void` | || Function for toggle open state of dropdown |
| `placement` | [Placement dictionary][dictionary-placement] | `bottom-start` || Alignment of the component |

On top of the API options, the components accept [additional attributes][readme-additional-attributes].
If you need more control over the styling of a component, you can use [style props][readme-style-props]
Expand Down Expand Up @@ -148,13 +156,13 @@ and [escape hatches][readme-escape-hatches].

### UncontrolledDropdown

| Name | Type | Default | Required | Description |
| ----------------- | ------------------------------------------------ | ------------- | -------- | ---------------------------------------------- |
| `enableAutoClose` | `bool` | `true` || Enables close on click outside of Dropdown |
| `fullWidthMode` | [`DropdownFullwidthMode`][dropdownfullwidthmode] | `off` || Full-width mode |
| `id` | `string` | `<random>` || Component id |
| `onAutoClose` | `(event: Event) => void` ||| Callback on close on click outside of Dropdown |
| `placement` | [Placement dictionary][dictionary-placement] | `bottom-left` || Alignment of the component |
| Name | Type | Default | Required | Description |
| ----------------- | ------------------------------------------------ | -------------- | -------- | ---------------------------------------------- |
| `enableAutoClose` | `bool` | `true` || Enables close on click outside of Dropdown |
| `fullWidthMode` | [`DropdownFullwidthMode`][dropdownfullwidthmode] | `off` || Full-width mode |
| `id` | `string` | `<random>` || Component id |
| `onAutoClose` | `(event: Event) => void` | || Callback on close on click outside of Dropdown |
| `placement` | [Placement dictionary][dictionary-placement] | `bottom-start` || Alignment of the component |

On top of the API options, the components accept [additional attributes][readme-additional-attributes].
If you need more control over the styling of a component, you can use [style props][readme-style-props]
Expand All @@ -167,5 +175,6 @@ and [escape hatches][readme-escape-hatches].
[dropdownfullwidthmode]: https://github.com/lmc-eu/spirit-design-system/blob/main/packages/web-react/src/types/dropdown.ts#L19
[item]: https://github.com/lmc-eu/spirit-design-system/blob/main/packages/web-react/src/components/Item/README.md
[readme-additional-attributes]: https://github.com/lmc-eu/spirit-design-system/blob/main/packages/web-react/README.md#additional-attributes
[readme-deprecations]: https://github.com/lmc-eu/spirit-design-system/tree/main/packages/web-react/README.md#deprecations
[readme-escape-hatches]: https://github.com/lmc-eu/spirit-design-system/blob/main/packages/web-react/README.md#escape-hatches
[readme-style-props]: https://github.com/lmc-eu/spirit-design-system/blob/main/packages/web-react/README.md#style-props
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { renderHook } from '@testing-library/react-hooks';
import { PlacementDictionaryType } from '../../../types';
import { useDropdownAriaProps } from '../useDropdownAriaProps';

describe('useDropdownAriaProps', () => {
Expand All @@ -7,6 +8,7 @@ describe('useDropdownAriaProps', () => {
fullWidthMode: undefined,
id: 'test-dropdown-id',
isOpen: true,
placement: 'bottom-start' as PlacementDictionaryType,
toggleHandler: () => null,
};
const { result } = renderHook(() => useDropdownAriaProps(props));
Expand All @@ -15,5 +17,8 @@ describe('useDropdownAriaProps', () => {
expect(result.current.triggerProps['aria-expanded']).toBeDefined();
expect(result.current.triggerProps['aria-controls']).toBeDefined();
expect(result.current.triggerProps.onClick).toBeDefined();
expect(result.current.contentProps).toBeDefined();
expect(result.current.contentProps['data-spirit-placement']).toBeDefined();
expect(result.current.contentProps['data-spirit-placement']).toBe('bottom-start');
});
});
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import { renderHook } from '@testing-library/react-hooks';
import { PlacementDictionaryType } from '../../../types';
import { useDropdownStyleProps, UseDropdownStyleProps } from '../useDropdownStyleProps';

describe('useDropdownStyleProps', () => {
it('should return defaults', () => {
const { result } = renderHook(() => useDropdownStyleProps());

expect(result.current.classProps.contentClassName).toBe('Dropdown Dropdown--bottomLeft');
expect(result.current.classProps.contentClassName).toBe('Dropdown');
expect(result.current.classProps.wrapperClassName).toBe('DropdownWrapper');
});

Expand All @@ -16,27 +15,18 @@ describe('useDropdownStyleProps', () => {
} as UseDropdownStyleProps;
const { result } = renderHook(() => useDropdownStyleProps(props));

expect(result.current.classProps.contentClassName).toBe('Dropdown Dropdown--bottomLeft is-open');
expect(result.current.classProps.contentClassName).toBe('Dropdown is-open');
expect(result.current.classProps.triggerClassName).toBe('is-expanded');
});

it('should change placement', () => {
const props = {
placement: 'top-right' as PlacementDictionaryType,
} as UseDropdownStyleProps;
const { result } = renderHook(() => useDropdownStyleProps(props));

expect(result.current.classProps.contentClassName).toBe('Dropdown Dropdown--topRight');
});

it('should transfer additional props', () => {
const props = {
isOpen: false,
transferProp: 'test',
} as UseDropdownStyleProps;
const { result } = renderHook(() => useDropdownStyleProps(props));

expect(result.current.classProps.contentClassName).toBe('Dropdown Dropdown--bottomLeft');
expect(result.current.classProps.contentClassName).toBe('Dropdown');
expect(result.current.props).toEqual({ transferProp: 'test' });
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const DropdownEnhancedShadow = () => {

return (
<div className="spirit-feature-dropdown-enable-enhanced-shadow">
<Dropdown renderTrigger={dropdownTrigger} placement="top-left">
<Dropdown renderTrigger={dropdownTrigger} placement="top-start">
<DropdownContentFactory content={dropdownContent} />
</Dropdown>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const DropdownFullwidthAll = () => {
);

return (
<Dropdown renderTrigger={dropdownTrigger} fullWidthMode="all" placement="top-left">
<Dropdown renderTrigger={dropdownTrigger} fullWidthMode="all" placement="top-start">
<DropdownContentFactory content={dropdownContent} />
</Dropdown>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const DropdownFullwidthMobileOnly = () => {
);

return (
<Dropdown renderTrigger={dropdownTrigger} fullWidthMode="mobile-only" placement="top-left">
<Dropdown renderTrigger={dropdownTrigger} fullWidthMode="mobile-only" placement="top-start">
<DropdownContentFactory content={dropdownContent} />
</Dropdown>
);
Expand Down
Loading

0 comments on commit f4aa004

Please sign in to comment.