Skip to content

Commit

Permalink
Feat(web-react): Use the new Placement dictionary in Dropdown #DS-923
Browse files Browse the repository at this point in the history
  • Loading branch information
adamkudrna committed Oct 19, 2023
1 parent 07fe0df commit ec31151
Show file tree
Hide file tree
Showing 6 changed files with 40 additions and 48 deletions.
4 changes: 2 additions & 2 deletions packages/web-react/src/components/Dropdown/Dropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ import React, { createElement, useRef, LegacyRef } from 'react';
import classNames from 'classnames';
import DropdownWrapper from './DropdownWrapper';
import { useStyleProps } from '../../hooks';
import { DropdownPlacements, SpiritDropdownProps } from '../../types';
import { SpiritDropdownProps } from '../../types';
import { useDropdown } from './useDropdown';
import { useDropdownStyleProps } from './useDropdownStyleProps';
import { useDropdownAriaProps } from './useDropdownAriaProps';

const defaultProps = {
placement: DropdownPlacements.BOTTOM_LEFT,
enableAutoClose: true,
placement: 'bottom-left',
};

const Dropdown = (props: SpiritDropdownProps) => {
Expand Down
4 changes: 2 additions & 2 deletions packages/web-react/src/components/Dropdown/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import { Dropdown } from '@lmc-eu/spirit-web-react/components';
| `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` | [`DropdownPlacement`][dropdownplacement] | `bottom-left` || Alignment of the component |
| `placement` | [Placement dictionary][dictionary-placement] | `bottom-left` || Alignment of the component |
| `renderTrigger` | `(render: DropdownRenderProps) => ReactNode` ||| Properties for trigger render |
| `UNSAFE_className` | `string` ||| Wrapper custom classname |
| `UNSAFE_style` | `CSSProperties` ||| Wrapper custom style |
Expand All @@ -40,6 +40,6 @@ import { Dropdown } from '@lmc-eu/spirit-web-react/components';
| `trigger.ref` | `LegacyRef<HTMLButtonElement & HTMLAnchorElement>` | Trigger reference |

[dropdown]: https://github.com/lmc-eu/spirit-design-system/tree/main/packages/web/src/scss/components/Dropdown
[dropdownplacement]: https://github.com/lmc-eu/spirit-design-system/blob/main/packages/web-react/src/types/dropdown.ts#L4
[dropdownbreakpoint]: https://github.com/lmc-eu/spirit-design-system/blob/main/packages/web-react/src/types/dropdown.ts#L11
[dropdownfullwidthmode]: https://github.com/lmc-eu/spirit-design-system/blob/main/packages/web-react/src/types/dropdown.ts#L19
[dictionary-placement]: https://github.com/lmc-eu/spirit-design-system/tree/main/docs/DICTIONARIES.md#placement
Original file line number Diff line number Diff line change
@@ -1,35 +1,42 @@
import { renderHook } from '@testing-library/react-hooks';
import { DropdownPlacements } from '../../../types';
import { PlacementDictionaryType } from '../../../types/shared/dictionaries';
import { useDropdownStyleProps, UseDropdownStyleProps } from '../useDropdownStyleProps';

describe('useDropdownStyleProps', () => {
it('should return defaults', () => {
const props = { isOpen: true, placement: 'bottom-left' } as UseDropdownStyleProps;
const { result } = renderHook(() => useDropdownStyleProps(props));
const { result } = renderHook(() => useDropdownStyleProps());

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

it('should render as open', () => {
const props = {
isOpen: true,
} as UseDropdownStyleProps;
const { result } = renderHook(() => useDropdownStyleProps(props));

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

it('should transfer additional props', () => {
it('should change placement', () => {
const props = {
isOpen: false,
placement: DropdownPlacements.BOTTOM_LEFT,
transferProp: 'test',
};
placement: 'top-right' as PlacementDictionaryType,
} as UseDropdownStyleProps;
const { result } = renderHook(() => useDropdownStyleProps(props));

expect(result.current.props).toEqual({ transferProp: 'test' });
expect(result.current.classProps.contentClassName).toBe('Dropdown Dropdown--topRight');
});

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

expect(result.current.classProps.contentClassName).toBe('Dropdown Dropdown--top Dropdown--right');
expect(result.current.classProps.contentClassName).toBe('Dropdown Dropdown--bottomLeft');
expect(result.current.props).toEqual({ transferProp: 'test' });
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ import React, { Ref } from 'react';
import { Markdown } from '@storybook/blocks';
import type { Meta, StoryObj } from '@storybook/react';

import { DropdownFullWidthModes, DropdownPlacements } from '../../../types';
import { Placements } from '../../../constants';

import { DropdownFullWidthModes } from '../../../types';
import { Button, Icon, Text } from '../..';
import ReadMe from '../README.md';
import { Dropdown } from '..';
Expand Down Expand Up @@ -38,9 +40,9 @@ const meta: Meta<typeof Dropdown> = {
},
placement: {
control: 'select',
options: [...Object.values(DropdownPlacements), undefined],
options: Object.values(Placements),
table: {
defaultValue: { summary: DropdownPlacements.BOTTOM_LEFT },
defaultValue: { summary: Placements.BOTTOM_LEFT },
},
},
},
Expand All @@ -66,6 +68,7 @@ const meta: Meta<typeof Dropdown> = {
</>
),
id: 'DropdownExample',
placement: Placements.BOTTOM_LEFT,
},
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import classNames from 'classnames';
import { SpiritDropdownProps, DropdownProps, DropdownPlacements } from '../../types';
import { SpiritDropdownProps, DropdownProps } from '../../types';
import { useClassNamePrefix } from '../../hooks';
import { kebabCaseToCamelCase } from '../../utils';

export interface UseDropdownStyleProps extends SpiritDropdownProps {
/** open state */
Expand All @@ -19,24 +20,15 @@ export interface UseDropdownStylePropsReturn {
export const useDropdownStyleProps = (
props: UseDropdownStyleProps = { isOpen: false },
): UseDropdownStylePropsReturn => {
const { isOpen, placement = DropdownPlacements.BOTTOM_LEFT, ...modifiedProps } = props;
const { isOpen, placement = 'bottom-left', ...modifiedProps } = props;

const dropdownClass = useClassNamePrefix('Dropdown');
const dropdownWrapperClass = `${dropdownClass}Wrapper`;
const dropdownBottomClass = `${dropdownClass}--bottom`;
const dropdownTopClass = `${dropdownClass}--top`;
const dropdownLeftClass = `${dropdownClass}--left`;
const dropdownRightClass = `${dropdownClass}--right`;
const dropdownPlacementClass = `${dropdownClass}--${kebabCaseToCamelCase(placement)}`;
const expandedClass = isOpen ? 'is-expanded' : '';
const openClass = isOpen ? 'is-open' : '';
const dropdownPlacementClassNames = {
'bottom-left': classNames(dropdownBottomClass, dropdownLeftClass),
'bottom-right': classNames(dropdownBottomClass, dropdownRightClass),
'top-left': classNames(dropdownTopClass, dropdownLeftClass),
'top-right': classNames(dropdownTopClass, dropdownRightClass),
};
const dropdownClassName = classNames(dropdownClass, openClass, {
[dropdownPlacementClassNames[placement]]: placement,
});

const dropdownClassName = classNames(dropdownClass, dropdownPlacementClass, openClass);
const triggerClassName = classNames(expandedClass);

return {
Expand Down
14 changes: 2 additions & 12 deletions packages/web-react/src/types/dropdown.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,12 @@
import { LegacyRef, ReactNode } from 'react';
import { Booleanish, ChildrenProps, ClickEvent, StyleProps } from './shared';

export const DropdownPlacements = {
BOTTOM_LEFT: 'bottom-left',
BOTTOM_RIGHT: 'bottom-right',
TOP_LEFT: 'top-left',
TOP_RIGHT: 'top-right',
} as const;
import { Booleanish, ChildrenProps, ClickEvent, PlacementDictionaryType, StyleProps } from './shared';

export const DropdownFullWidthModes = {
OFF: 'off',
MOBILE_ONLY: 'mobile-only',
ALL: 'all',
} as const;

export type DropdownPlacementKeys = keyof typeof DropdownPlacements;
export type DropdownPlacement = (typeof DropdownPlacements)[DropdownPlacementKeys];

export type DropdownFullWidthModeKeys = keyof typeof DropdownFullWidthModes;
export type DropdownFullWidthMode = (typeof DropdownFullWidthModes)[DropdownFullWidthModeKeys];

Expand All @@ -40,7 +30,7 @@ export interface DropdownProps extends ChildrenProps, StyleProps {

export interface SpiritDropdownProps extends DropdownProps {
enableAutoClose?: boolean;
placement?: DropdownPlacement;
placement?: PlacementDictionaryType;
fullWidthMode?: DropdownFullWidthMode;
onAutoClose?: (event: Event) => void;
}

0 comments on commit ec31151

Please sign in to comment.