diff --git a/CHANGELOG.md b/CHANGELOG.md index e111bfcb37..163da63a0e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm - Add multiple selection flavor for `Dropdown` component @Bugaa92 ([#845](https://github.com/stardust-ui/react/pull/845)) - Add `black` and `white` options for the `color` prop of the `Label` component @mnajdova ([#855](https://github.com/stardust-ui/react/pull/855)) - Add `Flex` component @kuzhelov ([#802](https://github.com/stardust-ui/react/pull/802)) +- Add `inline` prop for `Dropdown` component @Bugaa92 ([#863](https://github.com/stardust-ui/react/pull/863)) ### Fixes - Focus the last focused element which triggered `Popup` on ESC @sophieH29 ([#861](https://github.com/stardust-ui/react/pull/861)) diff --git a/docs/src/examples/components/Dropdown/Types/DropdownExampleInline.shorthand.tsx b/docs/src/examples/components/Dropdown/Types/DropdownExampleInline.shorthand.tsx new file mode 100644 index 0000000000..523dfd0511 --- /dev/null +++ b/docs/src/examples/components/Dropdown/Types/DropdownExampleInline.shorthand.tsx @@ -0,0 +1,38 @@ +import * as React from 'react' +import { Dropdown, Header } from '@stardust-ui/react' + +const inputItems = [ + 'Bruce Wayne', + 'Natasha Romanoff', + 'Steven Strange', + 'Alfred Pennyworth', + `Scarlett O'Hara`, + 'Imperator Furiosa', + 'Bruce Banner', + 'Peter Parker', + 'Selina Kyle', +] + +const DropdownExampleInline = () => ( + <> +
Inline:
+
+ Some text inline with the{' '} + and more text. +
+
Inline Search:
+ + Some other text inline with the{' '} + {' '} + and more text. + + +) + +export default DropdownExampleInline diff --git a/docs/src/examples/components/Dropdown/Types/index.tsx b/docs/src/examples/components/Dropdown/Types/index.tsx index a730a3bd47..aa2d168534 100644 --- a/docs/src/examples/components/Dropdown/Types/index.tsx +++ b/docs/src/examples/components/Dropdown/Types/index.tsx @@ -19,6 +19,11 @@ const Types = () => ( description="A dropdown can be searchable." examplePath="components/Dropdown/Types/DropdownExampleSearch" /> + ) diff --git a/packages/react/src/components/Dropdown/Dropdown.tsx b/packages/react/src/components/Dropdown/Dropdown.tsx index 3482d89b44..d7e82d5c05 100644 --- a/packages/react/src/components/Dropdown/Dropdown.tsx +++ b/packages/react/src/components/Dropdown/Dropdown.tsx @@ -76,6 +76,9 @@ export interface DropdownProps extends UIComponentProps) => string + /** A dropdown can be formatted to appear inline in the content of other components. */ + inline?: boolean + /** Array of props for generating list options (Dropdown.Item[]) and selected item labels(Dropdown.SelectedItem[]), if it's a multiple selection. */ items?: ShorthandValue[] @@ -190,6 +193,7 @@ class Dropdown extends AutoControlledComponent, Dropdo fluid: PropTypes.bool, getA11ySelectionMessage: PropTypes.object, getA11yStatusMessage: PropTypes.func, + inline: PropTypes.bool, items: customPropTypes.collectionShorthand, itemToString: PropTypes.func, loading: PropTypes.bool, @@ -333,11 +337,12 @@ class Dropdown extends AutoControlledComponent, Dropdo styles: ComponentSlotStylesInput, getToggleButtonProps: (options?: GetToggleButtonPropsOptions) => any, ): JSX.Element { + const { triggerButton } = this.props const content = this.getSelectedItemAsString(this.state.value) return ( - {Button.create(this.props.triggerButton, { + {Button.create(triggerButton, { defaultProps: { className: Dropdown.slotClassNames.triggerButton, content, @@ -369,7 +374,7 @@ class Dropdown extends AutoControlledComponent, Dropdo ) => void, variables, ): JSX.Element { - const { searchInput, multiple, placeholder } = this.props + const { inline, searchInput, multiple, placeholder } = this.props const { searchQuery, value } = this.state const noPlaceholder = @@ -378,6 +383,7 @@ class Dropdown extends AutoControlledComponent, Dropdo return DropdownSearchInput.create(searchInput || {}, { defaultProps: { placeholder: noPlaceholder ? '' : placeholder, + inline, variables, inputRef: this.inputRef, }, diff --git a/packages/react/src/components/Dropdown/DropdownSearchInput.tsx b/packages/react/src/components/Dropdown/DropdownSearchInput.tsx index 7c8cbcc1e7..1e2b6658fc 100644 --- a/packages/react/src/components/Dropdown/DropdownSearchInput.tsx +++ b/packages/react/src/components/Dropdown/DropdownSearchInput.tsx @@ -14,6 +14,9 @@ import { UIComponentProps } from '../../lib/commonPropInterfaces' import Input from '../Input/Input' export interface DropdownSearchInputProps extends UIComponentProps { + /** A dropdown search input can be formatted to appear inline in the context of a Dropdown. */ + inline?: boolean + /** Ref for input DOM node. */ inputRef?: React.Ref @@ -70,7 +73,7 @@ class DropdownSearchInput extends UIComponent = { - root: ({ variables: v, props: { active } }): ICSSInJSStyle => ({ - [`&.${ListItem.className}`]: { backgroundColor: v.listItemBackgroundColor }, - - ...(active && { - [`&.${ListItem.className}`]: { - backgroundColor: v.listItemBackgroundColorActive, - color: v.listItemColorActive, - }, + root: ({ props: p, variables: v }): ICSSInJSStyle => ({ + whiteSpace: 'nowrap', + backgroundColor: v.listItemBackgroundColor, + ...(p.active && { + color: v.listItemColorActive, + backgroundColor: v.listItemBackgroundColorActive, }), }), } diff --git a/packages/react/src/themes/teams/components/Dropdown/dropdownSearchInputStyles.ts b/packages/react/src/themes/teams/components/Dropdown/dropdownSearchInputStyles.ts index cb0f8652e5..7452a15b6b 100644 --- a/packages/react/src/themes/teams/components/Dropdown/dropdownSearchInputStyles.ts +++ b/packages/react/src/themes/teams/components/Dropdown/dropdownSearchInputStyles.ts @@ -11,10 +11,14 @@ const dropdownSearchInputStyles: ComponentSlotStylesInput< flexGrow: 1, }), - input: ({ variables: v }): ICSSInJSStyle => ({ + input: ({ props: p }): ICSSInJSStyle => ({ width: '100%', - backgroundColor: v.backgroundColor, + backgroundColor: 'transparent', borderWidth: 0, + ...(p.inline && { + paddingLeft: 0, + paddingRight: 0, + }), }), } diff --git a/packages/react/src/themes/teams/components/Dropdown/dropdownStyles.ts b/packages/react/src/themes/teams/components/Dropdown/dropdownStyles.ts index 9e2cceb70f..38c06c13ac 100644 --- a/packages/react/src/themes/teams/components/Dropdown/dropdownStyles.ts +++ b/packages/react/src/themes/teams/components/Dropdown/dropdownStyles.ts @@ -3,23 +3,58 @@ import { DropdownProps, DropdownState } from '../../../../components/Dropdown/Dr import { DropdownVariables } from './dropdownVariables' import { pxToRem } from '../../../../lib' -const dropdownStyles: ComponentSlotStylesInput = { - root: (): ICSSInJSStyle => ({}), +type DropdownPropsAndState = DropdownProps & DropdownState + +const transparentColorStyle: ICSSInJSStyle = { + backgroundColor: 'transparent', + borderColor: 'transparent', + borderBottomColor: 'transparent', +} + +const transparentColorStyleObj: ICSSInJSStyle = { + ...transparentColorStyle, + ':hover': transparentColorStyle, + ':active': transparentColorStyle, + ':focus': { + ...transparentColorStyle, + ':active': transparentColorStyle, + }, +} + +const getWidth = (p: DropdownPropsAndState, v: DropdownVariables): string => { + if (p.fluid) { + return '100%' + } + + if (p.inline) { + return 'initial' + } + + return v.width +} + +const dropdownStyles: ComponentSlotStylesInput = { + root: ({ props: p }): ICSSInJSStyle => ({ + ...(p.inline && { + display: 'inline-flex', + }), + }), container: ({ props: p, variables: v }): ICSSInJSStyle => ({ display: 'flex', flexWrap: 'wrap', - outline: 0, - backgroundColor: v.backgroundColor, + position: 'relative', boxSizing: 'border-box', borderStyle: 'solid', borderColor: 'transparent', + outline: 0, + width: getWidth(p, v), borderWidth: v.borderWidth, borderRadius: v.borderRadius, color: v.color, - width: p.fluid ? '100%' : v.width, - position: 'relative', + backgroundColor: v.backgroundColor, ...(p.focused && { borderBottomColor: v.borderColorFocus }), + ...(p.inline && transparentColorStyleObj), }), selectedItems: ({ props: p, variables: v }): ICSSInJSStyle => ({ @@ -32,19 +67,14 @@ const dropdownStyles: ComponentSlotStylesInput { - const transparentColorStyle = { - backgroundColor: 'transparent', - borderColor: 'transparent', - } return { boxShadow: 'none', margin: '0', justifyContent: 'left', padding: v.comboboxPaddingButton, height: pxToRem(30), - ...transparentColorStyle, ...(p.multiple && { minWidth: 0, flex: 1 }), - ':hover': transparentColorStyle, + ...transparentColorStyleObj, ':focus': { ...transparentColorStyle, ':after': { @@ -54,7 +84,11 @@ const dropdownStyles: ComponentSlotStylesInput