diff --git a/src/Dropdown/Dropdown.stories.tsx b/src/Dropdown/Dropdown.stories.tsx index f226064e..1519d043 100644 --- a/src/Dropdown/Dropdown.stories.tsx +++ b/src/Dropdown/Dropdown.stories.tsx @@ -1,10 +1,10 @@ +import { Meta, StoryFn as Story } from '@storybook/react' import React from 'react' -import { StoryFn as Story, Meta } from '@storybook/react' - import Dropdown, { DropdownProps } from '.' +import Badge from '../Badge' +import Button from '../Button' import Card from '../Card/' import Navbar from '../Navbar' -import Button from '../Button' export default { title: 'Actions/Dropdown', @@ -76,6 +76,54 @@ InNavbar.args = { end: true, } +export const ButtonToggle: Story = (args) => { + return ( +
+ + + Click + + + Item 1 + Item 2 + + +
+ ) +} + +export const LabelToggle: Story = (args) => { + return ( +
+ + Click + + Item 1 + Item 2 + + +
+ ) +} + +export const UnstyledCustomToggle: Story = (args) => { + return ( +
+ + + + Any component can be a toggle, even a {``}! + + + + Item 1 + Item 2 + + +
+ ) +} + export const Helper: Story = (args) => { return (
diff --git a/src/Dropdown/Dropdown.test.tsx b/src/Dropdown/Dropdown.test.tsx index bce2631b..e8c71a7d 100644 --- a/src/Dropdown/Dropdown.test.tsx +++ b/src/Dropdown/Dropdown.test.tsx @@ -34,7 +34,7 @@ describe('Dropdown', () => { ) expect(screen.getByRole('listbox')).toHaveClass('custom-dropdown') - expect(screen.getByText('Toggle').parentElement).toHaveClass( + expect(screen.getByText('Toggle').closest('button')).toHaveClass( 'custom-toggle' ) expect(screen.getByRole('menu')).toHaveClass('custom-menu') @@ -75,4 +75,58 @@ describe('Dropdown', () => { expect(screen.getByRole('listbox')).toHaveClass('dropdown-hover') expect(screen.getByRole('listbox')).toHaveClass('dropdown-open') }) + + test('Should render a Button when button=true (default)', () => { + render( + + Toggle + {DropdownItems} + + ) + + const toggle = screen.getByRole('button', { name: 'Toggle' }) + expect(toggle).toBeInTheDocument() + expect(toggle.tagName).toBe('BUTTON') + }) + + test('Should render a Button when button=true (explicit)', () => { + render( + + Toggle + {DropdownItems} + + ) + + const toggle = screen.getByRole('button', { name: 'Toggle' }) + expect(toggle).toBeInTheDocument() + expect(toggle.tagName).toBe('BUTTON') + }) + + test('Should render a Label when button=false', () => { + render( + + Toggle + {DropdownItems} + + ) + + const toggle = screen.getByRole('button', { name: 'Toggle' }) + expect(toggle).toBeInTheDocument() + expect(toggle.tagName).toBe('LABEL') + }) + + test('Should render a div when unstyled=true', () => { + render( + + + Toggle + + {DropdownItems} + + ) + + const toggle = screen.getByRole('button', { name: 'Dropdown toggle' }) + expect(toggle).toBeInTheDocument() + expect(toggle.tagName).toBe('DIV') + }) }) diff --git a/src/Dropdown/DropdownToggle.tsx b/src/Dropdown/DropdownToggle.tsx index abbef514..98981d44 100644 --- a/src/Dropdown/DropdownToggle.tsx +++ b/src/Dropdown/DropdownToggle.tsx @@ -1,49 +1,58 @@ -import React, { forwardRef } from 'react' +import React, { forwardRef, HTMLAttributes } from 'react' +import Button, { ButtonProps } from '../Button' +import Label, { LabelProps } from '../Form/Label' -import { ComponentColor, ComponentSize, IComponentBaseProps } from '../types' +export type ButtonDropdownToggleProps = ButtonProps & { + button?: true + unstyled?: false +} -import Button, { ButtonProps } from '../Button' +export type LabelDropdownToggleProps = Omit & { + button: false + unstyled?: false +} -export type DropdownToggleProps = Omit< - React.LabelHTMLAttributes, +export type UnstyledDropdownToggleProps = Omit< + HTMLAttributes, 'color' -> & - IComponentBaseProps & { - color?: ComponentColor - size?: ComponentSize - button?: boolean - disabled?: boolean - } - -const DropdownToggle = ({ - children, - color, - size, - button = true, - dataTheme, - className, - disabled, - ...props -}: DropdownToggleProps) => { - return ( - - ) +> & { + button?: false + unstyled: true } +export type DropdownToggleProps = + | ButtonDropdownToggleProps + | LabelDropdownToggleProps + | UnstyledDropdownToggleProps + +const DropdownToggle = forwardRef( + (props, ref) => { + const { button = true, unstyled = false, ...rest } = props + + if (unstyled) { + return ( +
} + role="button" + tabIndex={0} + {...(rest as React.HTMLAttributes)} + /> + ) + } else if (button) { + return