Skip to content

Commit

Permalink
Merge announcer-pt1 into announcer-combobox
Browse files Browse the repository at this point in the history
  • Loading branch information
jandrade committed Dec 12, 2024
2 parents 7492c69 + 50f263b commit b5fb657
Show file tree
Hide file tree
Showing 211 changed files with 11,394 additions and 5,981 deletions.
6 changes: 6 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,12 @@ module.exports = {
"no-undef": "off",
},
},
{
files: ["**/*.stories.tsx"],
rules: {
"testing-library/no-await-sync-events": "off",
},
},
],
globals: {
// `no-undef` doesn't support `globalThis`, for details see
Expand Down
5 changes: 4 additions & 1 deletion .github/workflows/node-ci-lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ jobs:
os: [ubuntu-latest]
node-version: [20.x]
steps:
- uses: actions/checkout@v4
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
Expand Down
3 changes: 2 additions & 1 deletion .storybook/preview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ const parameters = {
},
};

export const decorators = [
const decorators = [
(Story, context) => {
const theme = context.globals.theme;
const enableRenderStateRootDecorator =
Expand Down Expand Up @@ -133,6 +133,7 @@ export const decorators = [

const preview: Preview = {
parameters,
decorators,
globalTypes: {
// Allow the user to select a theme from the toolbar.
theme: {
Expand Down
31 changes: 17 additions & 14 deletions __docs__/wonder-blocks-button/button.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as React from "react";
import {StyleSheet} from "aphrodite";
import type {Meta, StoryObj} from "@storybook/react";
import {expect, fireEvent, userEvent, within} from "@storybook/test";
import {expect, userEvent, within} from "@storybook/test";

import {MemoryRouter, Route, Switch} from "react-router-dom";

Expand Down Expand Up @@ -103,7 +103,6 @@ export const Tertiary: StoryComponentType = {

// Get HTML elements
const button = canvas.getByRole("button");
const computedStyleButton = getComputedStyle(button);
const innerLabel = canvas.getByTestId("test-button-inner-label");
const computedStyleLabel = getComputedStyle(innerLabel, ":after");

Expand All @@ -116,19 +115,23 @@ export const Tertiary: StoryComponentType = {
await expect(computedStyleLabel.height).toBe("2px");
await expect(computedStyleLabel.color).toBe("rgb(24, 101, 242)");

// TODO(WB-1808, somewhatabstract): This isn't working. I got it passing
// locally by calling `button.focus()` as well, but it was super flaky
// and never passed first time.
// Focus style
await fireEvent.focus(button);
await expect(computedStyleButton.outlineColor).toBe(
"rgb(24, 101, 242)",
);
await expect(computedStyleButton.outlineWidth).toBe("2px");

// Active (mouse down) style
// eslint-disable-next-line testing-library/prefer-user-event
await fireEvent.mouseDown(button);
await expect(innerLabel).toHaveStyle("color: rgb(27, 80, 179)");
await expect(computedStyleLabel.height).toBe("2px");
await expect(computedStyleLabel.color).toBe("rgb(27, 80, 179)");
// const computedStyleButton = getComputedStyle(button);
// await fireEvent.focus(button);
// await expect(computedStyleButton.outlineColor).toBe(
// "rgb(24, 101, 242)",
// );
// await expect(computedStyleButton.outlineWidth).toBe("2px");

// // Active (mouse down) style
// // eslint-disable-next-line testing-library/prefer-user-event
// await fireEvent.mouseDown(button);
// await expect(innerLabel).toHaveStyle("color: rgb(27, 80, 179)");
// await expect(computedStyleLabel.color).toBe("rgb(27, 80, 179)");
// await expect(computedStyleLabel.height).toBe("2px");
},
};

Expand Down
7 changes: 1 addition & 6 deletions __docs__/wonder-blocks-core/exports.use-render-state.mdx
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import {Meta} from "@storybook/blocks";

<Meta
title="Packages / Core / Exports / useRenderState()"
/>
<Meta title="Packages / Core / Exports / useRenderState()" />

# useRenderState()

Expand All @@ -16,6 +14,3 @@ The `useRenderState` hook will return either:
the initial rehydration render on the client.
- `RenderState.Standard` if the component renders on the client after the initial
rehydration.

NOTE: Although the `RenderState` enum has a third state `Root`, this value is never
returned by `useRenderState`.
42 changes: 41 additions & 1 deletion __docs__/wonder-blocks-dropdown/base-select.argtypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,53 @@ const argTypes: ArgTypes = {
},

error: {
description: "Whether this component is in an error state.",
description: `Whether this component is in an error state. Use this for
errors that are triggered by something external to the component
(example: an error after form submission).`,
table: {
category: "States",
defaultValue: {summary: "false"},
},
},

required: {
description: `Whether this field is required to to continue, or the
error message to render if the select is left blank. Pass in a
message instead of "true" if possible.`,
table: {
category: "States",
type: {
summary: "boolean | string",
},
},
control: {
type: undefined,
},
},

validate: {
description: `Provide a validation for the selected value. Return a
string error message or null | void for a valid input.
\n Use this for errors that are shown to the user while they are
filling out a form.`,
table: {
category: "States",
type: {
summary: "(value: string) => ?string",
},
},
},

onValidate: {
description: "Called right after the field is validated.",
table: {
category: "Events",
type: {
summary: "(errorMessage: ?string) => mixed",
},
},
},

isFilterable: {
description: `When this is true, the dropdown body shows a search text
input top. The items will be filtered by the input. Selected items
Expand Down
87 changes: 85 additions & 2 deletions __docs__/wonder-blocks-dropdown/combobox.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@ import {Meta, StoryObj} from "@storybook/react";
import {expect, userEvent, within} from "@storybook/test";
import {StyleSheet} from "aphrodite";
import * as React from "react";
import {LabelLarge} from "@khanacademy/wonder-blocks-typography";
import {color, spacing} from "@khanacademy/wonder-blocks-tokens";
import magnifyingGlassIcon from "@phosphor-icons/core/bold/magnifying-glass-bold.svg";

import {LabelLarge, LabelMedium} from "@khanacademy/wonder-blocks-typography";
import {color, semanticColor, spacing} from "@khanacademy/wonder-blocks-tokens";
import {Checkbox} from "@khanacademy/wonder-blocks-form";
import {Combobox, OptionItem} from "@khanacademy/wonder-blocks-dropdown";
import {PhosphorIcon} from "@khanacademy/wonder-blocks-icon";
import {PropsFor, View} from "@khanacademy/wonder-blocks-core";
import {allProfilesWithPictures} from "./option-item-examples";

Expand Down Expand Up @@ -428,3 +431,83 @@ export const Error: Story = {
error: true,
},
};

/**
* With `startIcon`, you can customize the icon that appears at the beginning of
* the Combobox. This is useful when you want to add a custom icon to the
* component.
*
* **NOTE:** When `startIcon` is set, we set some default values for the icon:
* - `size`: "small"
* - `color`: `semanticColor.icon.default`
*
* You can customize the size and color of the icon by passing the `size` and
* `color` props to the `PhosphorIcon` component.
*/
export const StartIcon: Story = {
render: function Render(args: PropsFor<typeof Combobox>) {
const [_, updateArgs] = useArgs();

return (
<View style={{gap: spacing.medium_16}}>
<LabelMedium>With default size and color:</LabelMedium>
<Combobox
{...args}
startIcon={<PhosphorIcon icon={magnifyingGlassIcon} />}
onChange={(newValue) => {
updateArgs({value: newValue});
action("onChange")(newValue);
}}
/>
<LabelMedium>With custom size:</LabelMedium>
<Combobox
{...args}
startIcon={
<PhosphorIcon
icon={magnifyingGlassIcon}
size="medium"
/>
}
onChange={(newValue) => {
updateArgs({value: newValue});
action("onChange")(newValue);
}}
/>
<LabelMedium>With custom color:</LabelMedium>
<Combobox
{...args}
startIcon={
<PhosphorIcon
icon={magnifyingGlassIcon}
size="small"
color={semanticColor.icon.action}
/>
}
onChange={(newValue) => {
updateArgs({value: newValue});
action("onChange")(newValue);
}}
/>
<LabelMedium>Disabled (overrides color prop):</LabelMedium>
<Combobox
{...args}
startIcon={
<PhosphorIcon
icon={magnifyingGlassIcon}
size="small"
color={semanticColor.icon.action}
/>
}
disabled={true}
onChange={(newValue) => {
updateArgs({value: newValue});
action("onChange")(newValue);
}}
/>
</View>
);
},
args: {
children: items,
},
};
13 changes: 13 additions & 0 deletions __docs__/wonder-blocks-dropdown/multi-select.argtypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const argTypes: ArgTypes = {
table: {
type: {summary: "Array<string>"},
},
control: {type: "object"},
},
labels: {
control: {type: "object"},
Expand All @@ -21,6 +22,18 @@ const argTypes: ArgTypes = {
type: {summary: "Labels"},
},
},
showOpenerLabelAsText: {
control: {type: "boolean"},
description: `When false, the SelectOpener can show a Node as a label. When true, the
SelectOpener will use a string as a label. If using custom OptionItems, a
plain text label can be provided with the \`labelAsText\` prop.
Defaults to true.`,

table: {
type: {summary: "boolean"},
defaultValue: {summary: "true"},
},
},
};

export default argTypes;
Loading

0 comments on commit b5fb657

Please sign in to comment.