diff --git a/.changeset/thin-gorillas-visit.md b/.changeset/thin-gorillas-visit.md new file mode 100644 index 000000000..ca2c85054 --- /dev/null +++ b/.changeset/thin-gorillas-visit.md @@ -0,0 +1,5 @@ +--- +"@khanacademy/wonder-blocks-dropdown": patch +--- + +Update borderColor to be more a11y friendly diff --git a/__docs__/wonder-blocks-dropdown/combobox.argtypes.ts b/__docs__/wonder-blocks-dropdown/combobox.argtypes.ts new file mode 100644 index 000000000..e2a35a58c --- /dev/null +++ b/__docs__/wonder-blocks-dropdown/combobox.argtypes.ts @@ -0,0 +1,67 @@ +import {ArgTypes} from "@storybook/react"; + +const argTypes: ArgTypes = { + autoComplete: { + options: ["none", "list"], + control: {type: "select"}, + }, + + /** + * States + */ + disabled: { + table: { + category: "States", + }, + }, + loading: { + table: { + category: "States", + }, + }, + opened: { + table: { + category: "States", + }, + }, + + /** + * Visual Style + */ + style: { + table: { + category: "Visual style", + }, + }, + light: { + table: { + category: "Visual style", + }, + }, + + /** + * Events + */ + onToggle: { + table: { + category: "Events", + }, + }, + + onChange: { + table: { + category: "Events", + }, + }, + + labels: { + table: { + type: { + summary: "ComboboxLabels", + detail: "See wonder-blocks-dropdown/src/util/types.ts", + }, + }, + }, +}; + +export default argTypes; diff --git a/__docs__/wonder-blocks-dropdown/combobox.stories.tsx b/__docs__/wonder-blocks-dropdown/combobox.stories.tsx index e1a00aef9..a2df85185 100644 --- a/__docs__/wonder-blocks-dropdown/combobox.stories.tsx +++ b/__docs__/wonder-blocks-dropdown/combobox.stories.tsx @@ -1,4 +1,5 @@ import {action} from "@storybook/addon-actions"; +import {useArgs} from "@storybook/preview-api"; import {Meta, StoryObj} from "@storybook/react"; import {StyleSheet} from "aphrodite"; import * as React from "react"; @@ -9,6 +10,8 @@ import {LabelLarge} from "@khanacademy/wonder-blocks-typography"; import {color, spacing} from "@khanacademy/wonder-blocks-tokens"; import {allProfilesWithPictures} from "./option-item-examples"; +import argTypes from "./combobox.argtypes"; + import packageConfig from "../../packages/wonder-blocks-dropdown/package.json"; import ComponentInfo from "../../.storybook/components/component-info"; @@ -56,12 +59,16 @@ const defaultArgs = { disabled: false, placeholder: "Select an item", testId: "", + autoComplete: "none", + light: false, + loading: false, }; export default { title: "Packages / Dropdown / Combobox", component: Combobox, args: defaultArgs, + argTypes, decorators: [ (Story): React.ReactElement> => ( @@ -85,8 +92,41 @@ type Story = StoryObj; * The default Combobox with a list of items. */ export const Default: Story = { + render: function Render(args: PropsFor) { + const [{selectionType, value}, updateArgs] = useArgs(); + const prevSelectionTypeRef = React.useRef(args.selectionType); + + // Allows switching between single and multiple selection types without + // losing the selected value. + React.useEffect(() => { + // Try to keep the value in sync with the selection type + if (selectionType !== prevSelectionTypeRef.current) { + if (selectionType === "single") { + updateArgs({ + value: Array.isArray(value) ? value[0] : value, + }); + } else if (selectionType === "multiple") { + updateArgs({value: Array.isArray(value) ? value : [value]}); + } + } + prevSelectionTypeRef.current = selectionType; + }, [updateArgs, selectionType, value]); + + return ( + { + updateArgs({value: newValue}); + action("onChange")(newValue); + }} + /> + ); + }, args: { children: items, + selectionType: "single", }, }; diff --git a/packages/wonder-blocks-dropdown/src/components/combobox.tsx b/packages/wonder-blocks-dropdown/src/components/combobox.tsx index bde2a96fa..86d1a1f48 100644 --- a/packages/wonder-blocks-dropdown/src/components/combobox.tsx +++ b/packages/wonder-blocks-dropdown/src/components/combobox.tsx @@ -69,6 +69,8 @@ type Props = { /** * The object containing the custom labels used inside this component. + * + * This is useful for internationalization. Defaults to English. */ labels?: ComboboxLabels; @@ -120,9 +122,8 @@ type Props = { * * It’s internally mapped to aria-autocomplete set in the input field * (combobox). - * - * TODO(WB-1740): Add support to `inline` and `both` values. */ + // TODO(WB-1740): Add support to `inline` and `both` values. autoComplete?: "none" | "list" | undefined; }; @@ -606,7 +607,7 @@ const styles = StyleSheet.create({ // The following styles are to emulate the input styles background: color.white, borderRadius: border.radius.medium_4, - border: `solid 1px ${color.offBlack16}`, + border: `solid 1px ${color.offBlack50}`, paddingInline: spacing.xSmall_8, }, focused: { @@ -638,7 +639,7 @@ const styles = StyleSheet.create({ }, }, /** - * Listbo custom styles + * Listbox custom styles */ listbox: { backgroundColor: color.white,