From 4e7d7b26dc8231503b791b04d2a289fde133ff19 Mon Sep 17 00:00:00 2001 From: xrendan Date: Sun, 18 Jan 2026 09:26:25 -0700 Subject: [PATCH 1/6] Add @buildcanada/components to npm publish workflow Add publish-components job to enable CI publishing of the components package alongside the existing charts and colours packages. Co-Authored-By: Claude Opus 4.5 --- .github/workflows/npm-publish.yml | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/.github/workflows/npm-publish.yml b/.github/workflows/npm-publish.yml index d71cb718655..629542d57a0 100644 --- a/.github/workflows/npm-publish.yml +++ b/.github/workflows/npm-publish.yml @@ -11,7 +11,7 @@ on: default: "false" type: boolean package: - description: "Package to publish (charts, colours, or all)" + description: "Package to publish (charts, colours, components, or all)" required: false default: "all" type: choice @@ -19,6 +19,7 @@ on: - all - charts - colours + - components permissions: id-token: write @@ -66,3 +67,21 @@ jobs: - run: bunx npm publish --access public --provenance ${{ env.DRY_RUN }} working-directory: packages/colours + + publish-components: + if: github.event.inputs.package == 'all' || github.event.inputs.package == 'components' || github.event_name == 'release' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-node@v4 + with: + node-version: "24" + registry-url: "https://registry.npmjs.org" + + - uses: oven-sh/setup-bun@v2 + + - run: bun install --frozen-lockfile + + - run: bunx npm publish --access public --provenance ${{ env.DRY_RUN }} + working-directory: packages/components From 1aaddb9da1d3bd5d2794db1aa13cf4b65d2c6968 Mon Sep 17 00:00:00 2001 From: xrendan Date: Sun, 18 Jan 2026 12:20:16 -0700 Subject: [PATCH 2/6] Add Dialog and PopupForm components with Storybook docs - Add non-modal Dialog component with corner positioning - Add PopupForm component composing Dialog with form elements - Add comprehensive Storybook documentation to all component stories - Disable Chromatic on push, only run on PRs Dialog features: - Non-blocking (doesn't prevent UI interaction) - Content-sized (no fixed dimensions) - Corner positioning (top-left, top-right, bottom-left, bottom-right, center) - Configurable offset from screen edges - No rounded corners Co-Authored-By: Claude Opus 4.5 --- .github/workflows/ci.yml | 1 + .storybook/preview.ts | 7 + .../src/components/Button/Button.stories.tsx | 38 +- .../src/components/Checkbox.stories.tsx | 44 +- .../LabeledSwitch/LabeledSwitch.stories.tsx | 44 +- .../LoadingIndicator.stories.tsx | 45 +- .../charts/src/explorer/Explorer.stories.tsx | 37 ++ .../grapher/captionedChart/Logos.stories.tsx | 36 ++ .../src/grapher/core/Grapher.stories.tsx | 34 ++ .../grapher/dataTable/DataTable.stories.tsx | 31 ++ .../src/content/Card/Card.stories.tsx | 44 +- .../src/content/Hero/Hero.stories.tsx | 42 +- .../content/StatBlock/StatBlock.stories.tsx | 48 +- .../src/feedback/Dialog/Dialog.scss | 158 +++++++ .../src/feedback/Dialog/Dialog.stories.tsx | 324 ++++++++++++++ .../components/src/feedback/Dialog/Dialog.tsx | 120 +++++ .../components/src/feedback/Dialog/index.ts | 1 + .../src/feedback/PopupForm/PopupForm.scss | 34 ++ .../feedback/PopupForm/PopupForm.stories.tsx | 411 ++++++++++++++++++ .../src/feedback/PopupForm/PopupForm.tsx | 90 ++++ .../src/feedback/PopupForm/index.ts | 1 + packages/components/src/index.ts | 4 + .../layout/Container/Container.stories.tsx | 40 +- .../src/layout/Divider/Divider.stories.tsx | 39 +- .../src/layout/Grid/Grid.stories.tsx | 47 +- .../src/layout/Section/Section.stories.tsx | 46 +- .../src/layout/Stack/Stack.stories.tsx | 47 +- .../src/navigation/Footer/Footer.stories.tsx | 49 ++- .../src/navigation/Header/Header.stories.tsx | 61 ++- .../src/primitives/Button/Button.stories.tsx | 44 +- .../primitives/Checkbox/Checkbox.stories.tsx | 41 +- .../TextField/TextField.stories.tsx | 46 +- packages/components/src/styles/main.scss | 2 + 33 files changed, 2039 insertions(+), 17 deletions(-) create mode 100644 packages/components/src/feedback/Dialog/Dialog.scss create mode 100644 packages/components/src/feedback/Dialog/Dialog.stories.tsx create mode 100644 packages/components/src/feedback/Dialog/Dialog.tsx create mode 100644 packages/components/src/feedback/Dialog/index.ts create mode 100644 packages/components/src/feedback/PopupForm/PopupForm.scss create mode 100644 packages/components/src/feedback/PopupForm/PopupForm.stories.tsx create mode 100644 packages/components/src/feedback/PopupForm/PopupForm.tsx create mode 100644 packages/components/src/feedback/PopupForm/index.ts diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f091389e364..fa85c55332e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -61,6 +61,7 @@ jobs: retention-days: 7 chromatic: + if: github.event_name == 'pull_request' runs-on: ubuntu-latest needs: build steps: diff --git a/.storybook/preview.ts b/.storybook/preview.ts index 985f1fccd25..f3a0bdfd286 100644 --- a/.storybook/preview.ts +++ b/.storybook/preview.ts @@ -7,6 +7,7 @@ import "../packages/components/src/styles/main.scss" const preview: Preview = { decorators: [ChartsDecorator], + tags: ["autodocs"], parameters: { controls: { matchers: { @@ -24,6 +25,12 @@ const preview: Preview = { { name: "dark", value: "#1a1a1a" }, ], }, + docs: { + source: { + type: "code", + }, + toc: true, + }, }, } diff --git a/packages/charts/src/components/Button/Button.stories.tsx b/packages/charts/src/components/Button/Button.stories.tsx index 602b66af1d0..1ded1f2716a 100644 --- a/packages/charts/src/components/Button/Button.stories.tsx +++ b/packages/charts/src/components/Button/Button.stories.tsx @@ -6,6 +6,37 @@ import { Button } from "./Button" const meta: Meta = { title: "Components/Button", component: Button, + parameters: { + docs: { + description: { + component: ` +A button component for the charts library with multiple theme variants. + +## Usage + +\`\`\`tsx +import { Button } from "@buildcanada/charts" + + + )} + + )} + {description && ( +

+ {description} +

+ )} +
+ {children} +
+ + + ) +} + +export default Dialog diff --git a/packages/components/src/feedback/Dialog/index.ts b/packages/components/src/feedback/Dialog/index.ts new file mode 100644 index 00000000000..b72d7396471 --- /dev/null +++ b/packages/components/src/feedback/Dialog/index.ts @@ -0,0 +1 @@ +export { Dialog, type DialogProps, type DialogPosition } from "./Dialog" diff --git a/packages/components/src/feedback/PopupForm/PopupForm.scss b/packages/components/src/feedback/PopupForm/PopupForm.scss new file mode 100644 index 00000000000..618b8c75cf2 --- /dev/null +++ b/packages/components/src/feedback/PopupForm/PopupForm.scss @@ -0,0 +1,34 @@ +@use "../../styles/tokens" as *; + +/******************************************************************************* + * PopupForm Component + ******************************************************************************/ + +.bc-popup-form { + display: flex; + flex-direction: column; + gap: $space-3; +} + +/******************************************************************************* + * PopupForm Fields + ******************************************************************************/ + +.bc-popup-form__fields { + display: flex; + flex-direction: column; + gap: $space-3; +} + +/******************************************************************************* + * PopupForm Actions + ******************************************************************************/ + +.bc-popup-form__actions { + display: flex; + flex-direction: row; + justify-content: flex-end; + gap: $space-2; + padding-top: $space-2; + border-top: 1px solid $border-muted; +} diff --git a/packages/components/src/feedback/PopupForm/PopupForm.stories.tsx b/packages/components/src/feedback/PopupForm/PopupForm.stories.tsx new file mode 100644 index 00000000000..3a115ff3f2a --- /dev/null +++ b/packages/components/src/feedback/PopupForm/PopupForm.stories.tsx @@ -0,0 +1,411 @@ +import { useState } from "react" +import type { Meta, StoryObj } from "@storybook/react" +import { within, userEvent, expect } from "@storybook/test" + +import { PopupForm } from "./PopupForm" +import { Button } from "../../primitives/Button" +import { TextField } from "../../primitives/TextField" +import { Checkbox } from "../../primitives/Checkbox" + +const meta: Meta = { + title: "Components/Feedback/PopupForm", + component: PopupForm, + parameters: { + layout: "fullscreen", + docs: { + description: { + component: ` +A non-modal form panel that composes Dialog with form elements and action buttons. + +## Usage + +\`\`\`tsx +import { PopupForm, TextField, Checkbox } from "@buildcanada/components" + +function MyComponent() { + const [open, setOpen] = useState(false) + + const handleSubmit = (e: React.FormEvent) => { + console.log("Form submitted") + setOpen(false) + } + + return ( + <> + + + +\`\`\` + +## Spacing Options + +- **none**: 0px +- **xs**: 4px +- **sm**: 8px +- **md**: 16px +- **lg**: 24px +- **xl**: 32px + `, + }, + }, + }, argTypes: { direction: { control: "radio", options: ["vertical", "horizontal"], + description: "Stack direction (column or row)", }, spacing: { control: "select", options: ["none", "xs", "sm", "md", "lg", "xl"], + description: "Gap between items", }, align: { control: "select", options: ["start", "center", "end", "stretch"], + description: "Cross-axis alignment (align-items)", }, justify: { control: "select", options: ["start", "center", "end", "between", "around"], + description: "Main-axis alignment (justify-content)", + }, + wrap: { + description: "Whether items should wrap to next line", }, }, - tags: ["autodocs"], } export default meta diff --git a/packages/components/src/navigation/Footer/Footer.stories.tsx b/packages/components/src/navigation/Footer/Footer.stories.tsx index 6b496f5a21f..958138d7024 100644 --- a/packages/components/src/navigation/Footer/Footer.stories.tsx +++ b/packages/components/src/navigation/Footer/Footer.stories.tsx @@ -8,8 +8,55 @@ const meta: Meta = { component: Footer, parameters: { layout: "fullscreen", + docs: { + description: { + component: ` +A site footer component with logo, navigation links, social links, newsletter signup, and optional quote. + +## Usage + +\`\`\`tsx +import { Footer } from "@buildcanada/components" + +