From 326954dd0dfa6abf69fd6ea8befac39ec3320ab3 Mon Sep 17 00:00:00 2001 From: Juan Andrade Date: Wed, 28 Aug 2024 15:50:55 -0400 Subject: [PATCH] WB-1677.2: Combobox misc fixes (#2308) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary: - Changed the border color from `offBlack16` to `offBlack50` to be consistent with the rest of form fields. - Also applied a few Storybook fixes: - Refactored arg types to use categories - Fixed interactive story to support switching `selectionType` values without breaking the story. Issue: WB-1677 ## Test plan: Navigate to the Combobox docs in Storybook and verify the following: 1. The border color is now `offBlack50`. 2. The arg types are now categorized. 3. The interactive story should now support switching `selectionType` values without breaking the story. This means that the story should try to preserve the `value` when switching between `single` and `multi` selection types. https://github.com/user-attachments/assets/0d8481d8-5fcf-4c0e-b665-0798c22f3e0c Author: jandrade Reviewers: beaesguerra Required Reviewers: Approved By: beaesguerra Checks: ✅ Chromatic - Get results on regular PRs (ubuntu-latest, 20.x), ✅ Check build sizes (ubuntu-latest, 20.x), ✅ Lint (ubuntu-latest, 20.x), ✅ Test (ubuntu-latest, 20.x, 2/2), ✅ Test (ubuntu-latest, 20.x, 1/2), ✅ Chromatic - Build on regular PRs / chromatic (ubuntu-latest, 20.x), ✅ Publish npm snapshot (ubuntu-latest, 20.x), ⏭️ Chromatic - Skip on Release PR (changesets), ✅ Prime node_modules cache for primary configuration (ubuntu-latest, 20.x), ✅ gerald, ✅ Check for .changeset entries for all changed files (ubuntu-latest, 20.x), ⏭️ dependabot Pull Request URL: https://github.com/Khan/wonder-blocks/pull/2308 --- .changeset/thin-gorillas-visit.md | 5 ++ .../combobox.argtypes.ts | 67 +++++++++++++++++++ .../combobox.stories.tsx | 40 +++++++++++ .../src/components/combobox.tsx | 9 +-- 4 files changed, 117 insertions(+), 4 deletions(-) create mode 100644 .changeset/thin-gorillas-visit.md create mode 100644 __docs__/wonder-blocks-dropdown/combobox.argtypes.ts 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,