├── .github ├── ISSUE_TEMPLATE │ ├── 1-component.yml │ ├── 2-enhancement.yml │ ├── 3-bug.yml │ └── config.yml └── workflows │ ├── build_react_component_library_apps.yaml │ ├── publish_design_tokens.yaml │ ├── publish_react_component_library.yaml │ ├── test_design_tokens_build.yaml │ └── test_react_component_library.yaml ├── .gitignore ├── CODE_OF_CONDUCT.md ├── COMPLIANCE.yaml ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── assets ├── Design-System-v6.xd └── badge │ ├── component-draft-blue.png │ ├── component-draft-blue.svg │ ├── component-published-green.png │ └── component-published-green.svg ├── components ├── abbreviations │ ├── README.md │ ├── index.html │ ├── sample.html │ └── style.css ├── about │ ├── about.md │ ├── accessibility.md │ ├── browser_support_guidance.md │ ├── component_workflow.md │ ├── propose_a_component.md │ └── prototyping_tools.md ├── alert_banners │ ├── README.md │ ├── index.html │ ├── sample.html │ └── style.css ├── assets │ ├── images │ │ ├── BCID_H_rgb_rev.svg │ │ ├── BC_Logo_Horizontal.svg │ │ ├── logo-banner.png │ │ ├── logo-banner.svg │ │ └── logo.svg │ └── unsupported-browsers │ │ ├── chrome-icon.png │ │ ├── edge-icon.png │ │ ├── firefox-icon.png │ │ ├── ie-error-graphic.png │ │ └── safari-icon.png ├── beta │ ├── README.md │ ├── images │ │ └── beta-status-bc.png │ ├── index.html │ ├── sample.html │ └── style.css ├── callout │ ├── callout.md │ ├── index.html │ ├── sample.html │ └── style.css ├── checkbox │ ├── README.md │ ├── images │ │ └── checkbox.png │ ├── index.html │ ├── sample.html │ └── style.css ├── date_input │ ├── README.md │ ├── images │ │ └── date_input.png │ ├── index.html │ ├── sample.html │ └── style.css ├── disabled_button │ ├── README.md │ ├── index.html │ ├── sample.html │ └── style.css ├── dropdown │ ├── README.md │ ├── index.html │ ├── sample.html │ └── style.css ├── footer │ ├── README.md │ ├── images │ │ └── footer.png │ ├── index.html │ ├── sample.html │ └── style.css ├── forms │ ├── Form-structure.png │ ├── README.md │ └── optional-example.png ├── header │ ├── README.md │ ├── images │ │ └── header.png │ ├── index.html │ ├── sample.html │ └── style.css ├── link │ ├── README.md │ ├── images │ │ └── link.png │ ├── index.html │ ├── sample.html │ └── style.css ├── navbar │ ├── README.md │ ├── images │ │ ├── navbar.gif │ │ ├── screenshot 1.png │ │ ├── screenshot 2.png │ │ └── screenshot 3.png │ ├── index.html │ ├── sample.html │ └── style.css ├── primary_button │ ├── README.md │ ├── images │ │ └── primary_button.png │ ├── index-dark.html │ ├── index.html │ ├── sample-dark.html │ ├── sample.html │ ├── style-dark.css │ └── style.css ├── radio │ ├── README.md │ ├── images │ │ └── radio.png │ ├── index.html │ ├── sample.html │ └── style.css ├── secondary_button │ ├── README.md │ ├── index-dark.html │ ├── index.html │ ├── sample-dark.html │ ├── sample.html │ ├── style-dark.css │ └── style.css ├── table │ ├── README.md │ ├── images │ │ └── table.png │ ├── index.html │ ├── sample.html │ └── style.css ├── text_input │ ├── README.md │ ├── images │ │ ├── dummy.md │ │ └── text_input.png │ ├── index.html │ ├── sample.html │ └── style.css └── textarea │ ├── README.md │ ├── images │ ├── dummy │ └── textarea.png │ ├── index.html │ ├── sample.html │ └── style.css ├── packages ├── design-tokens │ ├── .gitignore │ ├── .nvmrc │ ├── CHANGELOG.md │ ├── README.md │ ├── build-output.js │ ├── build-output.test.js │ ├── build │ │ ├── .gitignore │ │ ├── cjs-prefixed │ │ │ ├── index.d.ts │ │ │ └── index.js │ │ ├── cjs │ │ │ ├── index.d.ts │ │ │ └── index.js │ │ ├── css-prefixed │ │ │ └── variables.css │ │ ├── css │ │ │ └── variables.css │ │ ├── js-prefixed │ │ │ ├── index.d.ts │ │ │ └── index.js │ │ └── js │ │ │ ├── index.d.ts │ │ │ └── index.js │ ├── dist │ │ ├── .gitignore │ │ ├── README.md │ │ ├── cjs-prefixed │ │ │ ├── index.d.ts │ │ │ └── index.js │ │ ├── cjs │ │ │ ├── index.d.ts │ │ │ └── index.js │ │ ├── css-prefixed │ │ │ └── variables.css │ │ ├── css │ │ │ └── variables.css │ │ ├── js-prefixed │ │ │ ├── index.d.ts │ │ │ └── index.js │ │ ├── js │ │ │ ├── index.d.ts │ │ │ └── index.js │ │ └── package.json │ ├── input │ │ ├── README.md │ │ └── tokens.json │ ├── package-lock.json │ ├── package.json │ ├── run-build.sh │ ├── run-prepare-npm-package.sh │ ├── run-publish-npm-package.sh │ └── tmp.199.json └── react-components │ ├── .eslintrc.cjs │ ├── .gitignore │ ├── .nvmrc │ ├── .storybook │ ├── bcdsTheme.js │ ├── global.css │ ├── main.ts │ ├── manager.js │ ├── preview.ts │ └── test-runner.ts │ ├── CHANGELOG.md │ ├── Dockerfile.storybook │ ├── Dockerfile.vite │ ├── README.md │ ├── index.html │ ├── jest.config.ts │ ├── nginx.storybook.conf │ ├── nginx.vite.conf │ ├── package-lock.json │ ├── package.json │ ├── public │ └── vite.svg │ ├── rollup.config.js │ ├── src │ ├── App.css │ ├── App.tsx │ ├── Changelog.mdx │ ├── assets │ │ ├── BCID_H_rgb_pos.svg │ │ ├── close.svg │ │ ├── icon-exclamation.svg │ │ ├── icon-menu.svg │ │ ├── icon-placeholder.svg │ │ └── tooltip-arrow-up.svg │ ├── components │ │ ├── Accordion │ │ │ ├── Accordion.css │ │ │ ├── Accordion.tsx │ │ │ └── index.ts │ │ ├── AccordionGroup │ │ │ ├── AccordionGroup.css │ │ │ ├── AccordionGroup.tsx │ │ │ └── index.ts │ │ ├── AlertBanner │ │ │ ├── AlertBanner.css │ │ │ ├── AlertBanner.tsx │ │ │ └── index.ts │ │ ├── AlertDialog │ │ │ ├── AlertDialog.css │ │ │ ├── AlertDialog.test.tsx │ │ │ ├── AlertDialog.tsx │ │ │ └── index.ts │ │ ├── Button │ │ │ ├── Button.css │ │ │ ├── Button.test.tsx │ │ │ ├── Button.tsx │ │ │ └── index.ts │ │ ├── ButtonGroup │ │ │ ├── ButtonGroup.css │ │ │ ├── ButtonGroup.test.tsx │ │ │ ├── ButtonGroup.tsx │ │ │ └── index.ts │ │ ├── Callout │ │ │ ├── Callout.css │ │ │ ├── Callout.tsx │ │ │ └── index.ts │ │ ├── Checkbox │ │ │ ├── Checkbox.css │ │ │ ├── Checkbox.test.tsx │ │ │ ├── Checkbox.tsx │ │ │ └── index.ts │ │ ├── CheckboxGroup │ │ │ ├── CheckboxGroup.css │ │ │ ├── CheckboxGroup.test.tsx │ │ │ ├── CheckboxGroup.tsx │ │ │ └── index.ts │ │ ├── Dialog │ │ │ ├── Dialog.css │ │ │ ├── Dialog.test.tsx │ │ │ ├── Dialog.tsx │ │ │ └── index.ts │ │ ├── Footer │ │ │ ├── Footer.css │ │ │ ├── Footer.test.tsx │ │ │ ├── Footer.tsx │ │ │ └── index.ts │ │ ├── Form │ │ │ ├── Form.test.tsx │ │ │ ├── Form.tsx │ │ │ └── index.ts │ │ ├── Header │ │ │ ├── Header.css │ │ │ ├── Header.test.tsx │ │ │ ├── Header.tsx │ │ │ └── index.ts │ │ ├── Heading │ │ │ ├── Heading.css │ │ │ ├── Heading.tsx │ │ │ └── index.ts │ │ ├── Icons │ │ │ ├── SvgBcLogo │ │ │ │ ├── SvgBcLogo.tsx │ │ │ │ └── index.ts │ │ │ ├── SvgBcOutlineIcon │ │ │ │ ├── SvgBcOutlineIcon.tsx │ │ │ │ └── index.ts │ │ │ ├── SvgBetaIcon │ │ │ │ ├── SvgBetaIcon.tsx │ │ │ │ └── index.ts │ │ │ ├── SvgCheckCircleIcon │ │ │ │ ├── SvgCheckCircleIcon.tsx │ │ │ │ └── index.ts │ │ │ ├── SvgCheckIcon │ │ │ │ ├── SvgCheckIcon.tsx │ │ │ │ └── index.ts │ │ │ ├── SvgChevronDownIcon │ │ │ │ ├── SvgChevronDownIcon.tsx │ │ │ │ └── index.ts │ │ │ ├── SvgChevronUpIcon │ │ │ │ ├── SvgChevronUpIcon.tsx │ │ │ │ └── index.ts │ │ │ ├── SvgCloseIcon │ │ │ │ ├── SvgCloseIcon.tsx │ │ │ │ └── index.ts │ │ │ ├── SvgDashIcon │ │ │ │ ├── SvgDashIcon.tsx │ │ │ │ └── index.ts │ │ │ ├── SvgExclamationCircleIcon │ │ │ │ ├── SvgExclamationCircleIcon.tsx │ │ │ │ └── index.ts │ │ │ ├── SvgExclamationIcon │ │ │ │ ├── SvgExclamationIcon.tsx │ │ │ │ └── index.ts │ │ │ ├── SvgInfoIcon │ │ │ │ ├── SvgInfoIcon.tsx │ │ │ │ └── index.ts │ │ │ └── SvgTooltipArrowUp │ │ │ │ ├── SvgTooltipArrowUp.tsx │ │ │ │ └── index.ts │ │ ├── InlineAlert │ │ │ ├── InlineAlert.css │ │ │ ├── InlineAlert.test.tsx │ │ │ ├── InlineAlert.tsx │ │ │ └── index.ts │ │ ├── Link │ │ │ ├── Link.css │ │ │ ├── Link.tsx │ │ │ └── index.ts │ │ ├── Modal │ │ │ ├── Modal.css │ │ │ ├── Modal.test.tsx │ │ │ ├── Modal.tsx │ │ │ └── index.ts │ │ ├── Radio │ │ │ ├── Radio.css │ │ │ ├── Radio.test.tsx │ │ │ ├── Radio.tsx │ │ │ └── index.ts │ │ ├── RadioGroup │ │ │ ├── RadioGroup.css │ │ │ ├── RadioGroup.test.tsx │ │ │ ├── RadioGroup.tsx │ │ │ └── index.ts │ │ ├── Select │ │ │ ├── Select.css │ │ │ ├── Select.tsx │ │ │ └── index.ts │ │ ├── Switch │ │ │ ├── Switch.css │ │ │ ├── Switch.test.tsx │ │ │ ├── Switch.tsx │ │ │ └── index.ts │ │ ├── Tag │ │ │ ├── Tag.css │ │ │ ├── Tag.tsx │ │ │ └── index.ts │ │ ├── TagGroup │ │ │ ├── TagGroup.css │ │ │ ├── TagGroup.tsx │ │ │ └── index.ts │ │ ├── TagList │ │ │ ├── TagList.css │ │ │ ├── TagList.tsx │ │ │ └── index.ts │ │ ├── Text │ │ │ ├── Text.css │ │ │ ├── Text.tsx │ │ │ └── index.ts │ │ ├── TextArea │ │ │ ├── TextArea.css │ │ │ ├── TextArea.tsx │ │ │ └── index.ts │ │ ├── TextField │ │ │ ├── TextField.css │ │ │ ├── TextField.tsx │ │ │ └── index.ts │ │ ├── Tooltip │ │ │ ├── Tooltip.css │ │ │ ├── Tooltip.tsx │ │ │ └── index.ts │ │ └── index.ts │ ├── hooks │ │ └── useWindowDimensions.ts │ ├── index.ts │ ├── main.tsx │ ├── pages │ │ ├── AccordionGroup │ │ │ ├── AccordionGroup.tsx │ │ │ └── index.ts │ │ ├── AlertBanner │ │ │ ├── AlertBanner.tsx │ │ │ └── index.ts │ │ ├── Button │ │ │ ├── Button.tsx │ │ │ ├── ButtonDanger.tsx │ │ │ ├── ButtonLink.tsx │ │ │ ├── ButtonPrimary.tsx │ │ │ ├── ButtonSecondary.tsx │ │ │ ├── ButtonTertiary.tsx │ │ │ └── index.ts │ │ ├── ButtonGroup │ │ │ ├── ButtonGroup.tsx │ │ │ └── index.ts │ │ ├── Callout │ │ │ ├── Callout.tsx │ │ │ └── index.ts │ │ ├── CheckboxGroup │ │ │ ├── CheckboxGroup.tsx │ │ │ └── index.ts │ │ ├── InlineAlert │ │ │ ├── InlineAlert.tsx │ │ │ └── index.ts │ │ ├── ModalDialog │ │ │ ├── ModalDialog.tsx │ │ │ └── index.ts │ │ ├── RadioGroup │ │ │ ├── RadioGroup.tsx │ │ │ └── index.ts │ │ ├── Select │ │ │ ├── Select.tsx │ │ │ ├── UseStateExample.tsx │ │ │ └── index.ts │ │ ├── Switch │ │ │ ├── Switch.tsx │ │ │ └── index.ts │ │ ├── TagGroup │ │ │ ├── Disabled.tsx │ │ │ ├── Horizontal.tsx │ │ │ ├── NonRemovable.tsx │ │ │ ├── TagGroup.tsx │ │ │ ├── Vertical.tsx │ │ │ ├── data.json │ │ │ └── index.ts │ │ ├── TextArea │ │ │ ├── TextArea.tsx │ │ │ └── index.ts │ │ ├── TextField │ │ │ ├── TextField.tsx │ │ │ └── index.ts │ │ ├── TextPage │ │ │ ├── TextPage.tsx │ │ │ └── index.ts │ │ ├── Tooltip │ │ │ ├── Tooltip.tsx │ │ │ └── index.ts │ │ └── index.ts │ ├── stories │ │ ├── Accordion.stories.tsx │ │ ├── AccordionGroup.mdx │ │ ├── AccordionGroup.stories.tsx │ │ ├── AlertBanner.mdx │ │ ├── AlertBanner.stories.tsx │ │ ├── AlertDialog.mdx │ │ ├── AlertDialog.stories.tsx │ │ ├── Button.mdx │ │ ├── Button.stories.tsx │ │ ├── ButtonGroup.mdx │ │ ├── ButtonGroup.stories.tsx │ │ ├── Callout.mdx │ │ ├── Callout.stories.tsx │ │ ├── Checkbox.stories.tsx │ │ ├── CheckboxGroup.mdx │ │ ├── CheckboxGroup.stories.tsx │ │ ├── Dialog.stories.tsx │ │ ├── Dialogs.mdx │ │ ├── Footer.mdx │ │ ├── Footer.stories.tsx │ │ ├── Form.css │ │ ├── Form.mdx │ │ ├── Form.stories.tsx │ │ ├── Header.mdx │ │ ├── Header.stories.tsx │ │ ├── Heading.mdx │ │ ├── Heading.stories.tsx │ │ ├── InlineAlert.mdx │ │ ├── InlineAlert.stories.tsx │ │ ├── Introduction.mdx │ │ ├── Link.mdx │ │ ├── Link.stories.tsx │ │ ├── Modal.stories.tsx │ │ ├── RadioGroup.mdx │ │ ├── RadioGroup.stories.tsx │ │ ├── Select.mdx │ │ ├── Select.stories.tsx │ │ ├── Switch.mdx │ │ ├── Switch.stories.tsx │ │ ├── Tag.stories.tsx │ │ ├── TagGroup.mdx │ │ ├── TagGroup.stories.tsx │ │ ├── TagList.stories.tsx │ │ ├── Text.mdx │ │ ├── Text.stories.tsx │ │ ├── TextArea.mdx │ │ ├── TextArea.stories.tsx │ │ ├── TextField.mdx │ │ ├── TextField.stories.tsx │ │ ├── Tooltip.mdx │ │ └── Tooltip.stories.tsx │ └── vite-env.d.ts │ ├── storybook-public │ └── BCID_H_rgb_pos.svg │ ├── tsconfig.json │ ├── tsconfig.vite.json │ └── vite.config.ts └── styles ├── Icons ├── icon-contrast.png ├── icon-label.png ├── icon-pngs │ ├── bars-solid.png │ ├── chevron-down-solid.png │ ├── chevron-left-solid.png │ ├── chevron-right-solid.png │ ├── chevron-up-solid.png │ ├── envelope-solid.png │ ├── external-link-alt-solid.png │ ├── phone-solid.png │ ├── search.png │ └── upload-solid.png ├── icon-svgs │ ├── bars-solid.svg │ ├── chevron-down-solid.svg │ ├── chevron-left-solid.svg │ ├── chevron-right-solid.svg │ ├── chevron-up-solid.svg │ ├── envelope-solid.svg │ ├── external-link-alt-solid.svg │ ├── phone-solid.svg │ ├── search.svg │ └── upload-solid.svg ├── icons.md └── target-area.png ├── colours ├── colourpalette.md └── images │ ├── 002663.png │ ├── 003366.png │ ├── 1a5a96.png │ ├── 38598a.png │ ├── 481124.png │ ├── 486446.png │ ├── 494949.png │ ├── 5091cd.png │ ├── 5475a7.png │ ├── 616265.png │ ├── 8a9198.png │ ├── 96c0e6.png │ ├── a12622.png │ ├── afafaf.png │ ├── bcbec5.png │ ├── d0d0d1.png │ ├── d8292f.png │ ├── f2f2f2.png │ ├── f3bd48.png │ ├── f3cd65.png │ ├── fade81.png │ ├── fcba19.png │ └── ffffff.png └── typography ├── fonts ├── BCSans-Bold.css ├── BCSans-Bold.eot ├── BCSans-Bold.otf ├── BCSans-Bold.ttf ├── BCSans-Bold.woff ├── BCSans-Bold.woff2 ├── BCSans-BoldItalic.css ├── BCSans-BoldItalic.eot ├── BCSans-BoldItalic.otf ├── BCSans-BoldItalic.ttf ├── BCSans-BoldItalic.woff ├── BCSans-BoldItalic.woff2 ├── BCSans-Italic.css ├── BCSans-Italic.eot ├── BCSans-Italic.otf ├── BCSans-Italic.ttf ├── BCSans-Italic.woff ├── BCSans-Italic.woff2 ├── BCSans-Regular.css ├── BCSans-Regular.eot ├── BCSans-Regular.otf ├── BCSans-Regular.ttf ├── BCSans-Regular.woff ├── BCSans-Regular.woff2 ├── FONTLOG_README.txt └── LICENSE_OFL.txt ├── header-sample.html ├── paragraph-sample.html └── typography.md /.github/ISSUE_TEMPLATE/1-component.yml: -------------------------------------------------------------------------------- 1 | name: New component 2 | description: Propose a new component to be added to the design system 3 | labels: ["component"] 4 | projects: ["bcgov/121"] 5 | assignees: 6 | - mkernohanbc 7 | body: 8 | - type: markdown 9 | attributes: 10 | value: | 11 | We evaluate prospective new components based on: 12 | * Demonstrable impact in terms of functionality or usability of government digital service 13 | * Evidence that the functional need can't be met using existing components 14 | * Demand from the user community 15 | - type: input 16 | id: name 17 | attributes: 18 | label: Component name 19 | description: A short, descriptive name for this component 20 | validations: 21 | required: true 22 | - type: textarea 23 | id: description 24 | attributes: 25 | label: Description 26 | description: Summary of what the component does, and its expected behaviour 27 | validations: 28 | required: true 29 | - type: textarea 30 | id: rationale 31 | attributes: 32 | label: Rationale 33 | description: Brief explanation of why this component is required, and how it will enhance application or service functionality and usability 34 | validations: 35 | required: true 36 | - type: textarea 37 | id: additional 38 | attributes: 39 | label: Additional information 40 | description: Links to any examples, research or code to support your proposal, if available 41 | validations: 42 | required: true 43 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/2-enhancement.yml: -------------------------------------------------------------------------------- 1 | name: Enhancement 2 | description: Suggest a change to how an existing component looks or behaves 3 | labels: ["enhancement"] 4 | projects: ["bcgov/121"] 5 | assignees: 6 | - mkernohanbc 7 | body: 8 | - type: markdown 9 | attributes: 10 | value: | 11 | We evaluate prospective enhancements based on: 12 | * Demonstrable impact in terms of functionality or usability of government digital service 13 | * Technical complexity and impact on existing services 14 | * Demand from the user community 15 | - type: input 16 | id: name 17 | attributes: 18 | label: Related component 19 | description: Which component does this proposed enhancement affect? 20 | validations: 21 | required: true 22 | - type: textarea 23 | id: description 24 | attributes: 25 | label: Description 26 | description: Describe the proposed change 27 | validations: 28 | required: true 29 | - type: textarea 30 | id: rationale 31 | attributes: 32 | label: Rationale 33 | description: Explain why you are proposing this change, and the expected benefit to the user 34 | validations: 35 | required: true 36 | - type: textarea 37 | id: additional 38 | attributes: 39 | label: Additional information 40 | description: Links to any examples, research or code to support your proposal, if available 41 | validations: 42 | required: true 43 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/3-bug.yml: -------------------------------------------------------------------------------- 1 | name: Bug 2 | description: Report an error or unexpected behaviour in a component 3 | labels: ["bug"] 4 | projects: ["bcgov/121"] 5 | assignees: 6 | - mkernohanbc 7 | body: 8 | - type: markdown 9 | attributes: 10 | value: | 11 | Thanks for taking the time to fill out this bug report! Please provide as much information as possible, including screenshots if possible. 12 | - type: input 13 | id: component 14 | attributes: 15 | label: Component 16 | description: Which component does this bug affect? 17 | validations: 18 | required: true 19 | - type: textarea 20 | id: description 21 | attributes: 22 | label: Description 23 | description: Describe the error or unexpected behaviour you observed, and provide screenshots if possible 24 | placeholder: Tell us what's going wrong 25 | validations: 26 | required: true 27 | - type: textarea 28 | id: reproduction 29 | attributes: 30 | label: Steps to reproduce 31 | description: Describe the circumstances under which the bug occurs 32 | placeholder: What were you doing when the bug occurred? 33 | validations: 34 | required: true 35 | - type: textarea 36 | id: technical 37 | attributes: 38 | label: Technical information 39 | description: What browsers or platforms does the bug affect? 40 | placeholder: Desktop or mobile? All browsers, or only one? 41 | validations: 42 | required: true 43 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: true 2 | -------------------------------------------------------------------------------- /.github/workflows/test_design_tokens_build.yaml: -------------------------------------------------------------------------------- 1 | name: Test design tokens build script 2 | 3 | on: 4 | pull_request: 5 | paths: 6 | - packages/design-tokens/** 7 | workflow_dispatch: 8 | 9 | # Cancel any currently running builds to save GitHub Actions hours. 10 | concurrency: 11 | group: ${{ github.workflow }}-${{ github.ref }} 12 | cancel-in-progress: true 13 | 14 | jobs: 15 | run-tests: 16 | name: Run tests 17 | runs-on: ubuntu-latest 18 | 19 | steps: 20 | - name: Checkout code 21 | uses: actions/checkout@v4 22 | 23 | - name: Read .nvmrc 24 | run: echo "GITHUB_NVMRC_VERSION=$(cat .nvmrc)" >> $GITHUB_ENV 25 | working-directory: ./packages/design-tokens 26 | 27 | - name: Set up Node.js 28 | uses: actions/setup-node@v4 29 | with: 30 | node-version: ${{ env.GITHUB_NVMRC_VERSION }} 31 | 32 | - name: Install dependencies 33 | run: npm install 34 | working-directory: ./packages/design-tokens 35 | 36 | - name: Run test suite with npm script 37 | run: npm run test 38 | working-directory: ./packages/design-tokens 39 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | -------------------------------------------------------------------------------- /COMPLIANCE.yaml: -------------------------------------------------------------------------------- 1 | name: compliance 2 | description: | 3 | This document is used to track a project's PIA and STRA 4 | compliance. 5 | spec: 6 | - name: PIA 7 | status: TBD 8 | last-updated: '2020-10-02T00:00:00.000Z' 9 | - name: STRA 10 | status: TBD 11 | last-updated: '2020-10-02T00:00:00.000Z' 12 | -------------------------------------------------------------------------------- /assets/Design-System-v6.xd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcgov/design-system/096e495488948dd1c0a984d4d0b4b6c0ca694e4c/assets/Design-System-v6.xd -------------------------------------------------------------------------------- /assets/badge/component-draft-blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcgov/design-system/096e495488948dd1c0a984d4d0b4b6c0ca694e4c/assets/badge/component-draft-blue.png -------------------------------------------------------------------------------- /assets/badge/component-draft-blue.svg: -------------------------------------------------------------------------------- 1 | componentcomponentdraftdraft -------------------------------------------------------------------------------- /assets/badge/component-published-green.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcgov/design-system/096e495488948dd1c0a984d4d0b4b6c0ca694e4c/assets/badge/component-published-green.png -------------------------------------------------------------------------------- /assets/badge/component-published-green.svg: -------------------------------------------------------------------------------- 1 | componentcomponentpublishedpublished -------------------------------------------------------------------------------- /components/abbreviations/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Abbreviations 8 | 9 | 10 | 11 |

On September 1, 2018, the Affordable Child Care Benefit (ACCB) replaced the Child Care Subsidy. Parents who need financial help with childcare should apply for the new ACCB

12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /components/abbreviations/sample.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Abbreviations 8 | 9 | 17 | 18 | 19 |

On September 1, 2018, the Affordable Child Care Benefit (ACCB) replaced the Child Care Subsidy. Parents who need financial help with childcare should apply for the new ACCB

20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /components/abbreviations/style.css: -------------------------------------------------------------------------------- 1 | p { 2 | font-family: ‘Noto Sans’, Verdana, Arial, sans-serif; 3 | font-size: 18px; 4 | line-height: 1.6; 5 | color: #313132; 6 | } 7 | -------------------------------------------------------------------------------- /components/about/accessibility.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: Accessibility considerations in the design system 3 | title: Accessibility 4 | author: orinevares 5 | --- 6 | 7 | ## Accessibility 8 | 9 | The [Web Content Accessibility Guidelines (WCAG)](https://www.w3.org/TR/WCAG20/) are the internationally recognized guidelines for web accessibility. The Province is committed to meeting WCAG 2.0 and 2.1 Level AA. All design system components meet or exceed these standards. 10 | 11 | Visit the [Accessibility and Inclusion Toolkit](https://www2.gov.bc.ca/gov/content?id=5D5C4759BC7E494AB9E8EDB7AD3D3D78) 12 | for information on how to create accessible content. 13 | -------------------------------------------------------------------------------- /components/about/prototyping_tools.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: How to use the design system prototyping libraries 3 | title: Prototype with the Design System 4 | author: orinevares 5 | --- 6 | 7 | # Prototype with the Design System 8 | 9 | ## Adobe XD 10 | ![Status](https://img.shields.io/badge/Community%20Contribution-v1.0-blue) 11 | 12 | The design system components have been created in Adobe XD by a community member to use for mockups and prototyping. 13 | [Download XD File](https://github.com/bcgov/design-system/raw/main/assets/Design-System-v6.xd) 14 | 15 | A Figma template is also being started [here](https://github.com/bcgov/figma). 16 | -------------------------------------------------------------------------------- /components/alert_banners/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Alert Banners 9 | 10 | 11 | 12 | 15 | 16 | 19 | 20 | 23 | 24 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /components/alert_banners/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: 'BC Sans', 'Noto Sans', Arial, 'sans serif'; 3 | color: #313132; 4 | font-size: 16px; 5 | line-height: 1.5em; 6 | } 7 | 8 | a { 9 | text-decoration: underline; 10 | } 11 | 12 | .bc-gov-alertbanner { 13 | border: 1px solid transparent; 14 | border-radius: 4px; 15 | font-weight: 700; 16 | margin-bottom: 20px; 17 | padding: 15px; 18 | } 19 | 20 | .bc-gov-alertbanner:before { 21 | float: left; 22 | font-family: 'Font Awesome 5 Free'; 23 | font-size: larger; 24 | font-style: normal; 25 | line-height: 1; 26 | margin-right: 10px; 27 | position: relative; 28 | top: 3px; 29 | -moz-osx-font-smoothing: grayscale; 30 | -webkit-font-smoothing: antialiased; 31 | } 32 | 33 | .bc-gov-alertbanner p { 34 | font-size: 18px; 35 | margin: 0; 36 | padding-left: 35px; 37 | } 38 | 39 | .bc-gov-alertbanner-error { 40 | background-color: #f2dede; 41 | border-color: #ebccd1; 42 | color: #a12622; 43 | } 44 | 45 | .bc-gov-alertbanner-error:before { 46 | content: "\f06a"; 47 | } 48 | 49 | .bc-gov-alertbanner-error a { 50 | color: #843534; 51 | } 52 | 53 | .bc-gov-alertbanner-warning { 54 | background-color: #f9f1c6; 55 | border-color: #faebcc; 56 | color: #6c4a00; 57 | } 58 | 59 | .bc-gov-alertbanner-warning:before { 60 | content: "\f071"; 61 | } 62 | 63 | .bc-gov-alertbanner-warning a { 64 | color: #66512c; 65 | } 66 | 67 | .bc-gov-alertbanner-info { 68 | background-color: #d9eaf7; 69 | } 70 | 71 | .bc-gov-alertbanner-info:before { 72 | content: "\f05a"; 73 | } 74 | 75 | .bc-gov-alertbanner-info a { 76 | color: #1a5a96; 77 | } 78 | 79 | .bc-gov-alertbanner-success { 80 | background-color: #dff0d8; 81 | border-color: #d6e9c6; 82 | color: #2d4821; 83 | } 84 | 85 | .bc-gov-alertbanner-success:before { 86 | content: "\f058"; 87 | } 88 | 89 | .bc-gov-alertbanner-success a { 90 | color: #2b542c; 91 | } 92 | -------------------------------------------------------------------------------- /components/assets/images/logo-banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcgov/design-system/096e495488948dd1c0a984d4d0b4b6c0ca694e4c/components/assets/images/logo-banner.png -------------------------------------------------------------------------------- /components/assets/unsupported-browsers/chrome-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcgov/design-system/096e495488948dd1c0a984d4d0b4b6c0ca694e4c/components/assets/unsupported-browsers/chrome-icon.png -------------------------------------------------------------------------------- /components/assets/unsupported-browsers/edge-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcgov/design-system/096e495488948dd1c0a984d4d0b4b6c0ca694e4c/components/assets/unsupported-browsers/edge-icon.png -------------------------------------------------------------------------------- /components/assets/unsupported-browsers/firefox-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcgov/design-system/096e495488948dd1c0a984d4d0b4b6c0ca694e4c/components/assets/unsupported-browsers/firefox-icon.png -------------------------------------------------------------------------------- /components/assets/unsupported-browsers/ie-error-graphic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcgov/design-system/096e495488948dd1c0a984d4d0b4b6c0ca694e4c/components/assets/unsupported-browsers/ie-error-graphic.png -------------------------------------------------------------------------------- /components/assets/unsupported-browsers/safari-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcgov/design-system/096e495488948dd1c0a984d4d0b4b6c0ca694e4c/components/assets/unsupported-browsers/safari-icon.png -------------------------------------------------------------------------------- /components/beta/images/beta-status-bc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcgov/design-system/096e495488948dd1c0a984d4d0b4b6c0ca694e4c/components/beta/images/beta-status-bc.png -------------------------------------------------------------------------------- /components/beta/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Beta Indicator 8 | 9 | 10 | 13 | 14 | 15 |
16 | 25 |
26 | 30 |   31 |
32 | 33 |
34 | 35 | 36 | -------------------------------------------------------------------------------- /components/beta/style.css: -------------------------------------------------------------------------------- 1 | header { 2 | background-color: #036; 3 | border-bottom: 2px solid #fcba19; 4 | padding: 0 65px 0 65px; 5 | color: #fff; 6 | display: flex; 7 | height: 65px; 8 | top: 0px; 9 | position: fixed; 10 | width: 100%; 11 | } 12 | 13 | header h1 { 14 | font-family: ‘Noto Sans’, Verdana, Arial, sans-serif; 15 | font-weight: normal; /* 400 */ 16 | margin: 5px 5px 0 18px; 17 | visibility: hidden; 18 | } 19 | 20 | header .banner { 21 | display: flex; 22 | justify-content: flex-start; 23 | align-items: center; 24 | margin: 0 10px 0 0; 25 | /* border-style: dotted; 26 | border-width: 1px; 27 | border-color: lightgrey; */ 28 | } 29 | 30 | header .other { 31 | display: flex; 32 | flex-grow: 1; 33 | /* border-style: dotted; 34 | border-width: 1px; 35 | border-color: lightgrey; */ 36 | } 37 | 38 | .Beta-PhaseBanner { 39 | color: #fcba19; 40 | margin-top: -1em; 41 | text-transform: uppercase; 42 | font-weight: 600; 43 | font-size: 16px; 44 | } 45 | 46 | :focus { 47 | outline: 4px solid #3B99FC; 48 | outline-offset: 1px; 49 | } 50 | 51 | /* 52 | These are sample media queries only. Media queries are quite subjective 53 | but, in general, should be made for the three different classes of screen 54 | size: phone, tablet, full. 55 | */ 56 | 57 | @media screen and (min-width: 600px) and (max-width: 899px) { 58 | header h1 { 59 | font-size: calc(7px + 2.2vw); 60 | visibility: visible; 61 | } 62 | } 63 | 64 | @media screen and (min-width: 900px) { 65 | header h1 { 66 | font-size: 2.0em; 67 | visibility: visible; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /components/callout/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Sample Callout 6 | 7 | 8 |
9 |

By March 1, 2018, eligible residents of B.C. are expected to renew enrolment in the Medical Services Plan (MSP) and get a BC Services Card.

10 |
11 | 12 | 13 | -------------------------------------------------------------------------------- /components/callout/sample.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Sample Callout 6 | 7 | 24 | 25 |
26 |

By March 1, 2018, eligible residents of B.C. are expected to renew enrolment in the Medical Services Plan (MSP) and get a BC Services Card.

27 |
28 | 29 | 30 | -------------------------------------------------------------------------------- /components/callout/style.css: -------------------------------------------------------------------------------- 1 | .bcgov-callout { 2 | font-family: ‘Noto Sans’, Verdana, Arial, sans-serif; 3 | font-weight: 400; 4 | line-height: 1.6; 5 | font-size: 18px; 6 | color: #313132; 7 | padding: 25px; 8 | border-left: 10px solid #38598a; 9 | margin: 16px 0; 10 | background-color: #f2f2f2; 11 | } 12 | 13 | .bcgov-callout, h1, h2, h3, h4 { 14 | margin: 0; 15 | } 16 | -------------------------------------------------------------------------------- /components/checkbox/images/checkbox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcgov/design-system/096e495488948dd1c0a984d4d0b4b6c0ca694e4c/components/checkbox/images/checkbox.png -------------------------------------------------------------------------------- /components/checkbox/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Sample Checkbox 8 | 9 | 10 | 11 | 15 | 16 | 20 | 21 | 25 | 26 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /components/checkbox/style.css: -------------------------------------------------------------------------------- 1 | /* Customize the label (the container) */ 2 | .checkbox { 3 | display: block; 4 | position: relative; 5 | padding-left: 25px; 6 | margin-bottom: 12px; 7 | cursor: pointer; 8 | Font-family: ‘Noto Sans’, Verdana, Arial, sans-serif; 9 | font-size: 18px; 10 | -webkit-user-select: none; 11 | -moz-user-select: none; 12 | -ms-user-select: none; 13 | user-select: none; 14 | } 15 | 16 | /* Hide the browser's default checkbox */ 17 | .checkbox input { 18 | position: absolute; 19 | opacity: 0; 20 | cursor: pointer; 21 | height: 0; 22 | width: 0; 23 | } 24 | 25 | /* Create a custom checkbox */ 26 | .checkmark { 27 | position: absolute; 28 | top: 3px; 29 | left: 0; 30 | height: 18px; 31 | width: 18px; 32 | outline: 2px solid #606060; 33 | } 34 | 35 | /* When the checkbox is checked, add a blue background */ 36 | .checkbox input:checked ~ .checkmark { 37 | background-color: #606060; 38 | } 39 | 40 | /* Custom checkbox has blue outline when in focus */ 41 | .checkbox input:focus ~ .checkmark { 42 | outline: 4px solid #3B99FC; 43 | } 44 | 45 | /* Create the checkmark/indicator (hidden when not checked) */ 46 | .checkmark:after { 47 | content: "\2713"; 48 | color: white; 49 | position: absolute; 50 | left: 50%; 51 | top: 50%; 52 | transform: translate(-50%, -50%); 53 | display: none; 54 | } 55 | 56 | /* Show the checkmark when checked */ 57 | .checkbox input:checked ~ .checkmark:after { 58 | display: block; 59 | } 60 | 61 | -------------------------------------------------------------------------------- /components/date_input/images/date_input.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcgov/design-system/096e495488948dd1c0a984d4d0b4b6c0ca694e4c/components/date_input/images/date_input.png -------------------------------------------------------------------------------- /components/date_input/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Sample Text Input 8 | 9 | 10 | 11 |
12 |
13 |
14 | 15 |
16 |
17 |
18 | 19 |
20 |
21 | 22 |
23 | 24 |
25 | 26 |
27 |
28 | 29 |
30 | 31 |
32 | 33 |
34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /components/date_input/style.css: -------------------------------------------------------------------------------- 1 | form { 2 | font-family: ‘Noto Sans’, Verdana, Arial, sans-serif; 3 | font-size: 16px; 4 | display: flex; 5 | } 6 | 7 | .date_input_day, .date_input_month { 8 | height: 25px; 9 | border: 2px solid #606060; 10 | margin-top: 5px; 11 | margin-bottom: 15px; 12 | border-radius: 4px; 13 | padding: 5px; 14 | font-family: ‘Noto Sans’, Verdana, Arial, sans-serif; 15 | font-size: 16px; 16 | width: 32px; 17 | } 18 | 19 | .date_input_year { 20 | height: 25px; 21 | border: 2px solid #606060; 22 | margin-top: 5px; 23 | margin-bottom: 15px; 24 | border-radius: 4px; 25 | padding: 5px; 26 | font-family: ‘Noto Sans’, Verdana, Arial, sans-serif; 27 | font-size: 16px; 28 | width: 64px; 29 | } 30 | 31 | .date_input_day[type="text"]:focus { 32 | outline: 4px solid #3B99FC; 33 | outline-offset: 1px; 34 | } 35 | 36 | .date_input_month[type="text"]:focus { 37 | outline: 4px solid #3B99FC; 38 | outline-offset: 1px; 39 | } 40 | 41 | .date_input_year[type="text"]:focus { 42 | outline: 4px solid #3B99FC; 43 | outline-offset: 1px; 44 | } 45 | 46 | .text_label { 47 | display: flex; 48 | } 49 | 50 | .date_field { 51 | margin-right: 20px; 52 | } 53 | -------------------------------------------------------------------------------- /components/disabled_button/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Primary Button 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /components/disabled_button/sample.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Primary Button 8 | 9 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /components/disabled_button/style.css: -------------------------------------------------------------------------------- 1 | .BC-Gov-PrimaryButton-disabled { 2 | background-color: #003366; 3 | opacity: 0.3; 4 | border: none; 5 | border-radius: 4px; 6 | color: white; 7 | padding: 12px 32px; 8 | text-align: center; 9 | text-decoration: none; 10 | display: block; 11 | font-size: 18px; 12 | font-family: ‘Noto Sans’, Verdana, Arial, sans-serif; 13 | font-weight: 700; 14 | letter-spacing: 1px; 15 | cursor: not-allowed; 16 | } 17 | 18 | .BC-Gov-SecondaryButton-disabled { 19 | background-color: white; 20 | opacity: 0.3; 21 | border: 2px solid #003366; 22 | border-radius: 4px; 23 | color: #003366; 24 | padding: 10px 30px; 25 | text-align: center; 26 | text-decoration: none; 27 | display: block; 28 | font-size: 18px; 29 | font-family: ‘Noto Sans’, Verdana, Arial, sans-serif; 30 | font-weight: 700; 31 | letter-spacing: 1px; 32 | cursor: not-allowed; 33 | } 34 | -------------------------------------------------------------------------------- /components/dropdown/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Dropdown 9 | 10 | 11 |
12 | 13 |
14 | 15 | 21 |
22 |
23 | 24 | 25 | -------------------------------------------------------------------------------- /components/dropdown/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: "Noto Sans", Verdana, Arial, sans-serif; 3 | font-size: 18px; 4 | } 5 | 6 | .bc-gov-form { 7 | display: flex; 8 | flex-direction: column; 9 | align-items: flex-start; 10 | } 11 | 12 | .bc-gov-dropdown-label { 13 | margin-bottom: 10px; 14 | } 15 | 16 | .bc-gov-dropdown { 17 | font-family: "Noto Sans", Verdana, Arial, sans-serif; 18 | font-size: 18px; 19 | color: #313132; 20 | background: white; 21 | box-shadow: none; 22 | border: 2px solid #606060; 23 | min-width: 200px; 24 | padding: 8px 45px 8px 15px; 25 | -webkit-appearance:none; 26 | -moz-appearance:none; 27 | appearance:none; 28 | } 29 | 30 | .fa-chevron-down { 31 | pointer-events: none; 32 | position: absolute; 33 | top: calc(1em - 4px); 34 | right: 1em; 35 | } 36 | 37 | .bc-gov-dropdown-wrapper { 38 | position: relative; 39 | display: inline; 40 | } 41 | 42 | :focus { 43 | outline: 4px solid #3B99FC; 44 | outline-offset: 1px; 45 | } 46 | -------------------------------------------------------------------------------- /components/footer/images/footer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcgov/design-system/096e495488948dd1c0a984d4d0b4b6c0ca694e4c/components/footer/images/footer.png -------------------------------------------------------------------------------- /components/footer/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Sample Footer 8 | 9 | 10 | 11 |
12 |

Sample Footer

13 |
14 | 15 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /components/footer/style.css: -------------------------------------------------------------------------------- 1 | footer { 2 | background-color: #036; 3 | border-top: 2px solid #fcba19; 4 | color: #fff; 5 | font-family: ‘Noto Sans’, Verdana, Arial, sans-serif; 6 | } 7 | 8 | footer .container { 9 | display: flex; 10 | justify-content: center; 11 | flex-direction: column; 12 | text-align: center; 13 | height: 46px; 14 | } 15 | 16 | footer ul { 17 | display: flex; 18 | flex-direction: row; 19 | flex-wrap: wrap; 20 | margin: 0; 21 | color: #fff; 22 | list-style: none; 23 | align-items: center; 24 | height: 100%; 25 | } 26 | 27 | footer ul li a { 28 | font-size: 0.813em; 29 | font-weight: normal; /* 400 */ 30 | color: #fff; 31 | border-right: 1px solid #4b5e7e; 32 | padding-left: 5px; 33 | padding-right: 5px; 34 | } 35 | 36 | a:hover { 37 | color: #fff; 38 | text-decoration: underline; 39 | } 40 | 41 | :focus { 42 | outline: 4px solid #3B99FC; 43 | outline-offset: 1px; 44 | } 45 | -------------------------------------------------------------------------------- /components/forms/Form-structure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcgov/design-system/096e495488948dd1c0a984d4d0b4b6c0ca694e4c/components/forms/Form-structure.png -------------------------------------------------------------------------------- /components/forms/optional-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcgov/design-system/096e495488948dd1c0a984d4d0b4b6c0ca694e4c/components/forms/optional-example.png -------------------------------------------------------------------------------- /components/header/images/header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcgov/design-system/096e495488948dd1c0a984d4d0b4b6c0ca694e4c/components/header/images/header.png -------------------------------------------------------------------------------- /components/header/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Sample Header 8 | 9 | 10 | 13 | 14 | 15 |
16 | 22 |
23 | 27 |   28 |
29 |
30 | 31 | 32 | -------------------------------------------------------------------------------- /components/header/style.css: -------------------------------------------------------------------------------- 1 | header { 2 | background-color: #036; 3 | border-bottom: 2px solid #fcba19; 4 | padding: 0 65px 0 65px; 5 | color: #fff; 6 | display: flex; 7 | height: 65px; 8 | top: 0px; 9 | position: fixed; 10 | width: 100%; 11 | } 12 | 13 | header h1 { 14 | font-family: ‘Noto Sans’, Verdana, Arial, sans-serif; 15 | font-weight: normal; /* 400 */ 16 | margin: 5px 5px 0 18px; 17 | visibility: hidden; 18 | } 19 | 20 | header .banner { 21 | display: flex; 22 | justify-content: flex-start; 23 | align-items: center; 24 | margin: 0 10px 0 0; 25 | /* border-style: dotted; 26 | border-width: 1px; 27 | border-color: lightgrey; */ 28 | } 29 | 30 | header .other { 31 | display: flex; 32 | flex-grow: 1; 33 | /* border-style: dotted; 34 | border-width: 1px; 35 | border-color: lightgrey; */ 36 | } 37 | 38 | :focus { 39 | outline: 4px solid #3B99FC; 40 | outline-offset: 1px; 41 | } 42 | 43 | /* 44 | These are sample media queries only. Media queries are quite subjective 45 | but, in general, should be made for the three different classes of screen 46 | size: phone, tablet, full. 47 | */ 48 | 49 | @media screen and (min-width: 600px) and (max-width: 899px) { 50 | header h1 { 51 | font-size: calc(7px + 2.2vw); 52 | visibility: visible; 53 | } 54 | } 55 | 56 | @media screen and (min-width: 900px) { 57 | header h1 { 58 | font-size: 2.0em; 59 | visibility: visible; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /components/link/images/link.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcgov/design-system/096e495488948dd1c0a984d4d0b4b6c0ca694e4c/components/link/images/link.png -------------------------------------------------------------------------------- /components/link/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Sample Link 9 | 10 | 11 | 12 |

This is an internal example of a link to access your application.

13 |

Here is another example of an internal link to apply.

14 |

This is an example of an External Link

15 |

Here is an example of a telephone link: 250-555-0123

16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /components/link/sample.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Sample Link 9 | 33 | 34 | 35 | 36 |

This is an internal example of a link to access your application.

37 |

Here is another example of an internal link to apply.

38 |

This is an example of an External Link

39 |

Here is an example of a telephone link: 250-555-0123

40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /components/link/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: 'Noto Sans', Verdana, Arial, sans-serif; 3 | font-size: 18px; 4 | } 5 | 6 | a { 7 | color: #1a5a96; 8 | } 9 | 10 | a:hover { 11 | text-decoration: none; 12 | color: blue; 13 | } 14 | 15 | i.fa-external-link-alt { 16 | color: #1a5a96; 17 | } 18 | 19 | :focus { 20 | outline: 4px solid #3B99FC; 21 | outline-offset: 1px; 22 | } 23 | -------------------------------------------------------------------------------- /components/navbar/images/navbar.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcgov/design-system/096e495488948dd1c0a984d4d0b4b6c0ca694e4c/components/navbar/images/navbar.gif -------------------------------------------------------------------------------- /components/navbar/images/screenshot 1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcgov/design-system/096e495488948dd1c0a984d4d0b4b6c0ca694e4c/components/navbar/images/screenshot 1.png -------------------------------------------------------------------------------- /components/navbar/images/screenshot 2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcgov/design-system/096e495488948dd1c0a984d4d0b4b6c0ca694e4c/components/navbar/images/screenshot 2.png -------------------------------------------------------------------------------- /components/navbar/images/screenshot 3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcgov/design-system/096e495488948dd1c0a984d4d0b4b6c0ca694e4c/components/navbar/images/screenshot 3.png -------------------------------------------------------------------------------- /components/primary_button/images/primary_button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcgov/design-system/096e495488948dd1c0a984d4d0b4b6c0ca694e4c/components/primary_button/images/primary_button.png -------------------------------------------------------------------------------- /components/primary_button/index-dark.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Primary Button Dark 8 | 9 | 10 |
11 | 12 |
13 | 14 | 15 | -------------------------------------------------------------------------------- /components/primary_button/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Primary Button 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /components/primary_button/sample-dark.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Primary Button Dark 8 | 9 | 49 | 50 |
51 | 52 |
53 | 54 | 55 | -------------------------------------------------------------------------------- /components/primary_button/sample.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Primary Button 8 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /components/primary_button/style-dark.css: -------------------------------------------------------------------------------- 1 | .BC-Gov-PrimaryButton-Dark { 2 | background-color: #fff; 3 | border: none; 4 | border-radius: 4px; 5 | color: #313132; 6 | padding: 12px 32px; 7 | text-align: center; 8 | text-decoration: none; 9 | display: inline-block; 10 | font-size: 18px; 11 | font-family: ‘Noto Sans’, Verdana, Arial, sans-serif; 12 | font-weight: 700; 13 | letter-spacing: 1px; 14 | cursor: pointer; 15 | } 16 | 17 | .BC-Gov-PrimaryButton-Dark:hover { 18 | text-decoration: underline; 19 | background-color: #f2f2f2 20 | } 21 | 22 | :focus { 23 | outline: 4px solid #3B99FC; 24 | outline-offset: 1px; 25 | } 26 | 27 | .BC-Gov-PrimaryButton-Dark:active { 28 | background-color: #fff; 29 | } 30 | 31 | .background-colour { 32 | background-color: #003366; 33 | height: 100px; 34 | width: 300px; 35 | display: flex; 36 | align-items: center; 37 | justify-content: center; 38 | } 39 | -------------------------------------------------------------------------------- /components/primary_button/style.css: -------------------------------------------------------------------------------- 1 | .BC-Gov-PrimaryButton { 2 | background-color: #003366; 3 | border: none; 4 | border-radius: 4px; 5 | color: white; 6 | padding: 12px 32px; 7 | text-align: center; 8 | text-decoration: none; 9 | display: inline-block; 10 | font-size: 18px; 11 | font-family: ‘Noto Sans’, Verdana, Arial, sans-serif; 12 | font-weight: 700; 13 | letter-spacing: 1px; 14 | cursor: pointer; 15 | } 16 | 17 | .BC-Gov-PrimaryButton:hover { 18 | text-decoration: underline; 19 | background-color: #336699; 20 | } 21 | 22 | :focus { 23 | outline: 4px solid #3B99FC; 24 | outline-offset: 1px; 25 | } 26 | 27 | .BC-Gov-PrimaryButton:active { 28 | opacity: 1; 29 | } 30 | -------------------------------------------------------------------------------- /components/radio/images/radio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcgov/design-system/096e495488948dd1c0a984d4d0b4b6c0ca694e4c/components/radio/images/radio.png -------------------------------------------------------------------------------- /components/radio/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Sample Radio Button 8 | 9 | 10 | 11 | 15 | 16 | 20 | 21 | 25 | 26 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /components/radio/style.css: -------------------------------------------------------------------------------- 1 | /* Customize the label (the container) */ 2 | .radio { 3 | display: block; 4 | position: relative; 5 | padding-left: 30px; 6 | margin-bottom: 12px; 7 | cursor: pointer; 8 | font-size: 18px; 9 | font-family: ‘Noto Sans’, Verdana, Arial, sans-serif; 10 | -webkit-user-select: none; 11 | -moz-user-select: none; 12 | -ms-user-select: none; 13 | user-select: none; 14 | } 15 | 16 | /* Hide the browser's default radio button */ 17 | .radio input { 18 | position: absolute; 19 | opacity: 0; 20 | cursor: pointer; 21 | height: 0; 22 | width: 0; 23 | } 24 | 25 | /* Create a custom radio button */ 26 | .dot { 27 | position: absolute; 28 | top: 1px; 29 | left: 0; 30 | height: 18px; 31 | width: 18px; 32 | border-radius: 50%; 33 | border: 2px solid #606060; 34 | } 35 | 36 | /* When the radio button is checked, add a blue background */ 37 | .radio input:checked ~ .dot { 38 | background-color: #ffffff; 39 | } 40 | 41 | /* Custom checkbox has blue outline when in focus */ 42 | .radio input:focus ~ .dot { 43 | outline: 4px solid #3B99FC; 44 | outline-offset: 1px; 45 | } 46 | 47 | /* Create the indicator (the dot/circle - hidden when not checked) */ 48 | .dot:after { 49 | content: ""; 50 | position: absolute; 51 | display: none; 52 | top: 50%; 53 | left: 50%; 54 | width: 12px; 55 | height: 12px; 56 | border-radius: 50%; 57 | background: #606060; 58 | transform: translate(-50%, -50%); 59 | } 60 | 61 | /* Show the indicator (dot/circle) when checked */ 62 | .radio input:checked ~ .dot:after { 63 | display: block; 64 | } 65 | -------------------------------------------------------------------------------- /components/secondary_button/index-dark.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Secondary Button Dark 8 | 9 | 10 |
11 | 12 |
13 | 14 | 15 | -------------------------------------------------------------------------------- /components/secondary_button/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Secondary Button 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /components/secondary_button/sample-dark.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Secondary Button Dark 8 | 9 | 51 | 52 |
53 | 54 |
55 | 56 | 57 | -------------------------------------------------------------------------------- /components/secondary_button/sample.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Secondary Button 8 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /components/secondary_button/style-dark.css: -------------------------------------------------------------------------------- 1 | .BC-Gov-SecondaryButton-Dark { 2 | background: none; 3 | border-radius: 4px; 4 | border: 2px solid #fff; 5 | padding: 10px 30px; 6 | text-align: center; 7 | text-decoration: none; 8 | display: block; 9 | font-size: 18px; 10 | Font-family: ‘Noto Sans’, Verdana, Arial, sans-serif; 11 | font-weight: 700; 12 | letter-spacing: 1px; 13 | cursor: pointer; 14 | color: #fff; 15 | } 16 | 17 | .BC-Gov-SecondaryButton-Dark:hover { 18 | text-decoration: underline; 19 | background-color: #fff; 20 | color: #313132; 21 | } 22 | 23 | :focus { 24 | outline-offset: 1px; 25 | outline: 4px solid #3B99FC; 26 | } 27 | 28 | .BC-Gov-SecondaryButton-Dark:active { 29 | background-color: #f2f2f2; 30 | color: #313132; 31 | } 32 | 33 | .background-colour { 34 | background-color: #003366; 35 | height: 100px; 36 | width: 300px; 37 | display: flex; 38 | align-items: center; 39 | justify-content: center; 40 | } 41 | -------------------------------------------------------------------------------- /components/secondary_button/style.css: -------------------------------------------------------------------------------- 1 | .BC-Gov-SecondaryButton { 2 | background: none; 3 | border-radius: 4px; 4 | border: 2px solid #003366; 5 | padding: 10px 30px; 6 | text-align: center; 7 | text-decoration: none; 8 | display: block; 9 | font-size: 18px; 10 | Font-family: ‘Noto Sans’, Verdana, Arial, sans-serif; 11 | font-weight: 700; 12 | letter-spacing: 1px; 13 | cursor: pointer; 14 | color: #003366; 15 | } 16 | .BC-Gov-SecondaryButton:hover { 17 | opacity: 0.80; 18 | text-decoration: underline; 19 | background-color: #003366; 20 | color: #FFFFFF; 21 | } 22 | :focus { 23 | outline-offset: 1px; 24 | outline: 4px solid #3B99FC; 25 | } 26 | .BC-Gov-SecondaryButton:active { 27 | opacity: 1; 28 | } 29 | -------------------------------------------------------------------------------- /components/table/images/table.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcgov/design-system/096e495488948dd1c0a984d4d0b4b6c0ca694e4c/components/table/images/table.png -------------------------------------------------------------------------------- /components/table/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Sample Table 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 |
Roll Call
FirstnameLastnameAge
JillSmith50
EveJackson94
28 | 29 | 30 | -------------------------------------------------------------------------------- /components/table/sample.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Sample Table 8 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 |
Roll Call
FirstnameLastnameAge
JillSmith50
EveJackson94
52 | 53 | 54 | -------------------------------------------------------------------------------- /components/table/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-size: 16px; 3 | font-family: ‘Noto Sans’, Verdana, Arial, sans-serif; 4 | } 5 | 6 | table, th, td { 7 | border: 1px solid black; 8 | border-collapse: collapse; 9 | } 10 | 11 | th, td { 12 | padding: 15px; 13 | } 14 | 15 | th { 16 | text-align: left; 17 | background-color: #d0d0d1; 18 | } 19 | 20 | caption { 21 | padding: 15px; 22 | } 23 | -------------------------------------------------------------------------------- /components/text_input/images/dummy.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /components/text_input/images/text_input.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcgov/design-system/096e495488948dd1c0a984d4d0b4b6c0ca694e4c/components/text_input/images/text_input.png -------------------------------------------------------------------------------- /components/text_input/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Sample Text Input 8 | 9 | 10 | 11 |
12 |
13 | 14 |
15 |
16 |
17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /components/text_input/sample.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Sample Text Input 8 | 37 | 38 | 39 | 40 |
41 |
42 | 43 |
44 |
45 |
46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /components/text_input/style.css: -------------------------------------------------------------------------------- 1 | form { 2 | font-family: ‘Noto Sans’, Verdana, Arial, sans-serif; 3 | font-size: 18px; 4 | } 5 | 6 | .text_input { 7 | font-family: ‘Noto Sans’, Verdana, Arial, sans-serif; 8 | font-size: 18px; 9 | } 10 | 11 | .text_input { 12 | height: 34px; 13 | border: 2px solid #606060; 14 | margin-top: 5px; 15 | margin-bottom: 15px; 16 | border-radius: 4px; 17 | padding: 5px 5px 5px 7px; 18 | } 19 | 20 | .text_input[type="text"]:focus { 21 | outline: 4px solid #3B99FC; 22 | outline-offset: 1px; 23 | } 24 | 25 | .text_label { 26 | display: flex; 27 | } 28 | -------------------------------------------------------------------------------- /components/textarea/images/dummy: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /components/textarea/images/textarea.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcgov/design-system/096e495488948dd1c0a984d4d0b4b6c0ca694e4c/components/textarea/images/textarea.png -------------------------------------------------------------------------------- /components/textarea/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Textarea 8 | 9 | 10 | 11 |
12 |
13 | 14 |
15 | 16 |
17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /components/textarea/sample.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Textarea 8 | 34 | 35 | 36 | 37 |
38 |
39 | 40 |
41 | 42 |
43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /components/textarea/style.css: -------------------------------------------------------------------------------- 1 | form { 2 | font-family: ‘Noto Sans’, Verdana, Arial, sans-serif; 3 | font-size: 18px; 4 | } 5 | 6 | .text_input { 7 | font-family: ‘Noto Sans’, Verdana, Arial, sans-serif; 8 | font-size: 18px; 9 | border: 2px solid #606060; 10 | margin-top: 5px; 11 | margin-bottom: 15px; 12 | border-radius: 4px; 13 | padding: 5px; 14 | resize: none; 15 | } 16 | 17 | .text_input:focus { 18 | outline: 4px solid #3B99FC; 19 | outline-offset: 1px; 20 | } 21 | 22 | .text_label { 23 | display: flex; 24 | } 25 | -------------------------------------------------------------------------------- /packages/design-tokens/.gitignore: -------------------------------------------------------------------------------- 1 | # Include build and dist folders 2 | !build/* 3 | !dist/* 4 | 5 | .DS_Store 6 | node_modules 7 | -------------------------------------------------------------------------------- /packages/design-tokens/.nvmrc: -------------------------------------------------------------------------------- 1 | 20 2 | -------------------------------------------------------------------------------- /packages/design-tokens/build/.gitignore: -------------------------------------------------------------------------------- 1 | # Include this folder in the repo even if it's empty 2 | -------------------------------------------------------------------------------- /packages/design-tokens/dist/.gitignore: -------------------------------------------------------------------------------- 1 | # Include this folder in the repo even if it's empty 2 | -------------------------------------------------------------------------------- /packages/design-tokens/dist/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@bcgov/design-tokens", 3 | "version": "3.1.1", 4 | "description": "Design tokens for B.C. Design System", 5 | "repository": { 6 | "type": "git", 7 | "url": "git+https://github.com/bcgov/design-system.git" 8 | }, 9 | "keywords": [ 10 | "design system", 11 | "design tokens", 12 | "figma", 13 | "tokens studio", 14 | "style-dictionary" 15 | ], 16 | "author": "Tyler Krys ", 17 | "license": "Apache-2.0", 18 | "bugs": { 19 | "url": "https://github.com/bcgov/design-system/issues" 20 | }, 21 | "homepage": "https://github.com/bcgov/design-system#readme", 22 | "private": false 23 | } 24 | -------------------------------------------------------------------------------- /packages/design-tokens/input/README.md: -------------------------------------------------------------------------------- 1 | This folder holds design token JSON data from Tokens Studio for Figma. 2 | -------------------------------------------------------------------------------- /packages/design-tokens/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "design-tokens", 3 | "version": "3.2.0", 4 | "description": "Transformation pipeline for design tokens for B.C. Design System", 5 | "scripts": { 6 | "build": "./run-build.sh", 7 | "prepare-npm-package": "./run-prepare-npm-package.sh", 8 | "publish-npm-package": "./run-publish-npm-package.sh", 9 | "test": "node --test build-output.test.js" 10 | }, 11 | "type": "module", 12 | "repository": { 13 | "type": "git", 14 | "url": "git+https://github.com/bcgov/design-system.git" 15 | }, 16 | "keywords": [ 17 | "design system", 18 | "design tokens", 19 | "figma", 20 | "tokens studio", 21 | "style-dictionary" 22 | ], 23 | "author": "Tyler Krys ", 24 | "license": "Apache-2.0", 25 | "bugs": { 26 | "url": "https://github.com/bcgov/design-system/issues" 27 | }, 28 | "homepage": "https://github.com/bcgov/design-system#readme", 29 | "dependencies": { 30 | "@tokens-studio/sd-transforms": "1.2.3", 31 | "style-dictionary": "4.0.1" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /packages/design-tokens/run-build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Remove existing build target directories 4 | rm -rf build/cjs* 5 | rm -rf build/css* 6 | rm -rf build/js* 7 | 8 | # Run the tokens transformation script 9 | node build-output.js 10 | -------------------------------------------------------------------------------- /packages/design-tokens/run-prepare-npm-package.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Remove existing dist target directories 4 | rm -rf dist/cjs* 5 | rm -rf dist/css* 6 | rm -rf dist/js* 7 | 8 | # Copy the contents of build into dist 9 | cp -R build/* dist 10 | 11 | # Update the version in dist/package.json to match the root package.json version 12 | ROOT_VERSION=$(jq -r '.version' package.json) 13 | jq --arg version "$ROOT_VERSION" '.version = $version' dist/package.json > tmp.$$.json && mv tmp.$$.json dist/package.json 14 | -------------------------------------------------------------------------------- /packages/design-tokens/run-publish-npm-package.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # The dist directory is used as the root for the published design tokens package 4 | cd dist 5 | 6 | # Publish to npm using any extra command line arguments passed to this script 7 | npm publish "$@" 8 | -------------------------------------------------------------------------------- /packages/design-tokens/tmp.199.json: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bcgov/design-system/096e495488948dd1c0a984d4d0b4b6c0ca694e4c/packages/design-tokens/tmp.199.json -------------------------------------------------------------------------------- /packages/react-components/.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { browser: true, es2020: true }, 4 | extends: [ 5 | "eslint:recommended", 6 | "plugin:@typescript-eslint/recommended", 7 | "plugin:react-hooks/recommended", 8 | "plugin:storybook/recommended", 9 | ], 10 | ignorePatterns: ["dist", ".eslintrc.cjs"], 11 | parser: "@typescript-eslint/parser", 12 | plugins: ["react-refresh"], 13 | rules: { 14 | "react-refresh/only-export-components": [ 15 | "warn", 16 | { allowConstantExport: true }, 17 | ], 18 | }, 19 | }; 20 | -------------------------------------------------------------------------------- /packages/react-components/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | storybook-static 14 | vite-dist 15 | *.local 16 | 17 | # Editor directories and files 18 | .vscode/* 19 | !.vscode/extensions.json 20 | .idea 21 | .DS_Store 22 | *.suo 23 | *.ntvs* 24 | *.njsproj 25 | *.sln 26 | *.sw? 27 | -------------------------------------------------------------------------------- /packages/react-components/.nvmrc: -------------------------------------------------------------------------------- 1 | 20 2 | -------------------------------------------------------------------------------- /packages/react-components/.storybook/bcdsTheme.js: -------------------------------------------------------------------------------- 1 | import { create } from "@storybook/theming/create"; 2 | import "@bcgov/bc-sans/css/BC_Sans.css"; 3 | import * as tokens from "@bcgov/design-tokens/js"; 4 | 5 | export default create({ 6 | // Typography 7 | fontBase: '"BC Sans", sans-serif', 8 | fontCode: "monospace", 9 | 10 | // Colour 11 | colorPrimary: tokens.themePrimaryGold, 12 | colorSecondary: tokens.themePrimaryBlue, 13 | 14 | // UI 15 | appBg: tokens.surfaceColorBackgroundLightBlue, 16 | appContentBg: tokens.surfaceColorBackgroundWhite, 17 | appPreviewBg: tokens.surfaceColorBackgroundWhite, 18 | appBorderColor: tokens.surfaceColorBorderDefault, 19 | appBorderRadius: tokens.layoutBorderRadiusMedium, 20 | 21 | // Text colors 22 | textColor: tokens.typographyColorPrimary, 23 | textInverseColor: tokens.typographyColorPrimaryInvert, 24 | textMutedColor: tokens.typographyColorSecondary, 25 | 26 | // Toolbar default and active colors 27 | barTextColor: tokens.typographyColorSecondary, 28 | barSelectedColor: tokens.surfaceColorBorderActive, 29 | barHoverColor: tokens.surfaceColorBorderActive, 30 | barBg: tokens.surfaceColorBackgroundLightGray, 31 | 32 | // Form colors 33 | inputBg: tokens.surfaceColorFormsDefault, 34 | inputBorder: tokens.surfaceColorBorderDefault, 35 | inputTextColor: tokens.typographyColorSecondary, 36 | inputBorderRadius: tokens.layoutBorderRadiusMedium, 37 | 38 | base: "light", 39 | brandTitle: "B.C. Design System", 40 | brandImage: "BCID_H_rgb_pos.svg", // This lives in storybook-public 41 | }); 42 | -------------------------------------------------------------------------------- /packages/react-components/.storybook/global.css: -------------------------------------------------------------------------------- 1 | #storybook-root { 2 | overflow-x: hidden; 3 | } 4 | -------------------------------------------------------------------------------- /packages/react-components/.storybook/main.ts: -------------------------------------------------------------------------------- 1 | import type { StorybookConfig } from "@storybook/react-vite"; 2 | import * as tokens from "@bcgov/design-tokens/cjs"; 3 | 4 | const config: StorybookConfig = { 5 | stories: ["../src/**/*.mdx", "../src/**/*.stories.@(js|jsx|mjs|ts|tsx)"], 6 | addons: [ 7 | "@storybook/addon-links", 8 | "@storybook/addon-essentials", 9 | "@storybook/addon-interactions", 10 | "@storybook/addon-a11y", 11 | ], 12 | framework: { 13 | name: "@storybook/react-vite", 14 | options: { 15 | builder: { 16 | viteConfigPath: "vite.config.ts", 17 | }, 18 | strictMode: false, 19 | }, 20 | }, 21 | staticDirs: ["../storybook-public"], 22 | 23 | // extra CSS for Storybook docs and UI, injected into 24 | previewHead: (head) => ` 25 | ${head} 26 | 32 | `, 33 | }; 34 | export default config; 35 | -------------------------------------------------------------------------------- /packages/react-components/.storybook/manager.js: -------------------------------------------------------------------------------- 1 | import { addons } from "@storybook/manager-api"; 2 | import bcdsTheme from "./bcdsTheme"; 3 | 4 | addons.setConfig({ 5 | theme: bcdsTheme, 6 | panelPosition: 'bottom', 7 | }); 8 | -------------------------------------------------------------------------------- /packages/react-components/.storybook/preview.ts: -------------------------------------------------------------------------------- 1 | import type { Preview } from "@storybook/react"; 2 | import bcdsTheme from "./bcdsTheme"; 3 | 4 | import "@bcgov/bc-sans/css/BC_Sans.css"; 5 | 6 | import "./global.css"; 7 | 8 | const preview: Preview = { 9 | parameters: { 10 | actions: { argTypesRegex: "^on[A-Z].*" }, 11 | docs: { 12 | theme: bcdsTheme, 13 | canvas: { 14 | withToolbar: true, 15 | }, 16 | }, 17 | controls: { 18 | matchers: { 19 | color: /(background|color)$/i, 20 | date: /Date$/i, 21 | }, 22 | }, 23 | options: { 24 | storySort: { 25 | order: ["Introduction", "Changelog"], 26 | }, 27 | }, 28 | }, 29 | }; 30 | 31 | export default preview; 32 | -------------------------------------------------------------------------------- /packages/react-components/.storybook/test-runner.ts: -------------------------------------------------------------------------------- 1 | // .storybook/test-runner.ts 2 | // From: https://storybook.js.org/docs/writing-tests/accessibility-testing#setup 3 | 4 | import type { TestRunnerConfig } from "@storybook/test-runner"; 5 | import { injectAxe, checkA11y } from "axe-playwright"; 6 | 7 | /* 8 | * See https://storybook.js.org/docs/writing-tests/test-runner#test-hook-api 9 | * to learn more about the test-runner hooks API. 10 | */ 11 | const config: TestRunnerConfig = { 12 | async preVisit(page) { 13 | await injectAxe(page); 14 | }, 15 | async postVisit(page) { 16 | await checkA11y(page, "#storybook-root"); 17 | }, 18 | }; 19 | 20 | export default config; 21 | -------------------------------------------------------------------------------- /packages/react-components/Dockerfile.storybook: -------------------------------------------------------------------------------- 1 | # Dockerfile.storybook 2 | 3 | # ----------- 4 | # Build stage 5 | # ----------- 6 | FROM node:lts-alpine AS build-stage 7 | ARG GITHUB_SHA 8 | ENV GITHUB_SHA=$GITHUB_SHA 9 | 10 | # Copy package.json and package-lock.json 11 | WORKDIR /app 12 | COPY package.json . 13 | COPY vite.config.ts . 14 | 15 | # Print npm config 16 | RUN npm config list 17 | 18 | # Install dependencies 19 | RUN npm install 20 | 21 | # Copy required files 22 | COPY CHANGELOG.md ./CHANGELOG.md 23 | COPY src ./src 24 | COPY .storybook ./.storybook 25 | COPY storybook-public ./storybook-public 26 | 27 | # Run Storybook build script, which places built files in /app/storybook-static 28 | RUN STORYBOOK_GITHUB_SHA=$GITHUB_SHA npm run storybook-build 29 | 30 | # ----------- 31 | # Serve stage 32 | # ----------- 33 | FROM nginxinc/nginx-unprivileged:alpine AS serve-stage 34 | 35 | # Copy nginx configuration 36 | COPY ./nginx.storybook.conf /etc/nginx/nginx.conf 37 | 38 | # Copy built Storybook files to nginx public web root folder 39 | COPY --from=build-stage /app/storybook-static /usr/share/nginx/html 40 | 41 | EXPOSE 8080 42 | CMD ["nginx", "-g", "daemon off;"] 43 | -------------------------------------------------------------------------------- /packages/react-components/Dockerfile.vite: -------------------------------------------------------------------------------- 1 | # Dockerfile.vite 2 | 3 | # ----------- 4 | # Build stage 5 | # ----------- 6 | FROM node:lts-alpine AS build-stage 7 | 8 | # Copy package.json and package-lock.json 9 | WORKDIR /app 10 | COPY package.json . 11 | 12 | # Print npm config 13 | RUN npm config list 14 | 15 | # Install dependencies 16 | RUN npm install 17 | 18 | # Copy required files 19 | COPY index.html ./ 20 | COPY tsconfig.json ./ 21 | COPY tsconfig.vite.json ./ 22 | COPY vite.config.ts ./ 23 | COPY src ./src 24 | 25 | # Run Vite build script, which places built files in /app/vite-dist 26 | RUN npm run vite-build 27 | 28 | # ----------- 29 | # Serve stage 30 | # ----------- 31 | FROM nginxinc/nginx-unprivileged:alpine AS serve-stage 32 | 33 | # Copy nginx configuration 34 | COPY ./nginx.vite.conf /etc/nginx/nginx.conf 35 | 36 | # Copy built Vite files to nginx public web root folder 37 | COPY --from=build-stage /app/vite-dist /usr/share/nginx/html 38 | 39 | EXPOSE 5555 40 | CMD ["nginx", "-g", "daemon off;"] 41 | -------------------------------------------------------------------------------- /packages/react-components/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | BC Design System React Components Vite Kitchen Sink 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /packages/react-components/jest.config.ts: -------------------------------------------------------------------------------- 1 | import type { Config } from "jest"; 2 | 3 | const config: Config = { 4 | // Limit search for tests to the `components` directory 5 | roots: ["./src/components"], 6 | 7 | // Start with the presets from the `ts-jest` package 8 | preset: "ts-jest", 9 | 10 | // Use `jsdom` as the test environment because we are testing React components 11 | testEnvironment: "jsdom", 12 | 13 | // Mocks for static file imports 14 | moduleNameMapper: { 15 | // Necessary because of our CSS file imports like `import "./Button.css"` 16 | "\\.(css)$": "identity-obj-proxy", 17 | }, 18 | 19 | // Log each test result instead of a summary 20 | verbose: true, 21 | }; 22 | 23 | export default config; 24 | -------------------------------------------------------------------------------- /packages/react-components/nginx.storybook.conf: -------------------------------------------------------------------------------- 1 | # nginx.storybook.conf 2 | # Adapted from https://cloud.redhat.com/blog/deploy-vuejs-applications-on-openshift 3 | worker_processes auto; 4 | 5 | pid /tmp/nginx.pid; 6 | 7 | events { 8 | worker_connections 1024; 9 | } 10 | 11 | http { 12 | include /etc/nginx/mime.types; 13 | client_body_temp_path /tmp/client_temp; 14 | proxy_temp_path /tmp/proxy_temp_path; 15 | fastcgi_temp_path /tmp/fastcgi_temp; 16 | uwsgi_temp_path /tmp/uwsgi_temp; 17 | scgi_temp_path /tmp/scgi_temp; 18 | 19 | server { 20 | listen 8080; 21 | server_name _; 22 | gzip on; 23 | gzip_types *; 24 | 25 | index index.html; 26 | error_log /tmp/error.log; 27 | access_log /tmp/access.log; 28 | 29 | # Redirect requests for root to gov.bc.ca B.C. Design System landing page 30 | # Perma-link: https://www2.gov.bc.ca/gov/content?id=67906B3698E44F4592AD4C6DC375B8F1 31 | location = / { 32 | return 301 https://gov.bc.ca/designsystem; 33 | } 34 | 35 | # Requests within /react-components/ path get served the Storybook app 36 | location /react-components/ { 37 | alias /usr/share/nginx/html/; 38 | try_files $uri $uri/ /index.html; 39 | } 40 | 41 | # Redirect /react-components to /react-components/ 42 | location = /react-components { 43 | return 301 /react-components/; 44 | } 45 | 46 | # Redirect 404 errors to the Design System landing page 47 | error_page 404 =301 https://gov.bc.ca/designsystem; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /packages/react-components/nginx.vite.conf: -------------------------------------------------------------------------------- 1 | # nginx.vite.conf 2 | # Adapted from https://cloud.redhat.com/blog/deploy-vuejs-applications-on-openshift 3 | worker_processes auto; 4 | 5 | pid /tmp/nginx.pid; 6 | 7 | events { 8 | worker_connections 1024; 9 | } 10 | 11 | http { 12 | include /etc/nginx/mime.types; 13 | client_body_temp_path /tmp/client_temp; 14 | proxy_temp_path /tmp/proxy_temp_path; 15 | fastcgi_temp_path /tmp/fastcgi_temp; 16 | uwsgi_temp_path /tmp/uwsgi_temp; 17 | scgi_temp_path /tmp/scgi_temp; 18 | 19 | server { 20 | listen 5555; 21 | server_name _; 22 | gzip on; 23 | gzip_types *; 24 | 25 | index index.html; 26 | error_log /tmp/error.log; 27 | access_log /tmp/access.log; 28 | 29 | location / { 30 | root /usr/share/nginx/html; 31 | try_files $uri /index.html; 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /packages/react-components/public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/react-components/rollup.config.js: -------------------------------------------------------------------------------- 1 | import resolve from "@rollup/plugin-node-resolve"; 2 | import commonjs from "@rollup/plugin-commonjs"; 3 | import typescript from "@rollup/plugin-typescript"; 4 | import { dts } from "rollup-plugin-dts"; 5 | import postcss from "rollup-plugin-postcss"; 6 | import peerDepsExternal from "rollup-plugin-peer-deps-external"; 7 | 8 | // eslint-disable-next-line @typescript-eslint/no-var-requires, no-undef 9 | const packageJson = require("./package.json"); 10 | 11 | export default [ 12 | { 13 | input: "src/index.ts", 14 | output: [ 15 | { 16 | file: packageJson.main, 17 | format: "cjs", 18 | sourcemap: true, 19 | }, 20 | { 21 | file: packageJson.module, 22 | format: "esm", 23 | sourcemap: true, 24 | }, 25 | ], 26 | plugins: [ 27 | peerDepsExternal(), 28 | resolve(), 29 | commonjs(), 30 | typescript({ 31 | tsconfig: "./tsconfig.json", 32 | include: ["src/index.ts", "src/components/**/*"], 33 | }), 34 | postcss(), 35 | ], 36 | }, 37 | { 38 | input: "dist/esm/types/index.d.ts", 39 | output: [{ file: "dist/index.d.ts", format: "esm" }], 40 | plugins: [dts()], 41 | external: [/\.css$/], 42 | }, 43 | ]; 44 | -------------------------------------------------------------------------------- /packages/react-components/src/App.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | } 4 | 5 | h1, 6 | h2, 7 | h3, 8 | h4, 9 | h5, 10 | h6 { 11 | font-family: var(--typography-font-families-bc-sans); 12 | } 13 | 14 | main { 15 | margin: 0 auto; 16 | padding: 2rem; 17 | max-width: 1100px; 18 | } 19 | -------------------------------------------------------------------------------- /packages/react-components/src/Changelog.mdx: -------------------------------------------------------------------------------- 1 | import { Markdown } from "@storybook/blocks"; 2 | import Changelog from '../CHANGELOG.md?raw'; 3 | 4 | { Changelog } 5 | -------------------------------------------------------------------------------- /packages/react-components/src/assets/close.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /packages/react-components/src/assets/icon-exclamation.svg: -------------------------------------------------------------------------------- 1 | 7 | 8 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /packages/react-components/src/assets/icon-menu.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /packages/react-components/src/assets/icon-placeholder.svg: -------------------------------------------------------------------------------- 1 | 8 | 9 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /packages/react-components/src/assets/tooltip-arrow-up.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /packages/react-components/src/components/Accordion/Accordion.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | Disclosure, 3 | DisclosurePanel, 4 | DisclosureProps as DisclosureProps, 5 | } from "react-aria-components"; 6 | 7 | import "./Accordion.css"; 8 | import Button from "../Button"; 9 | import SvgChevronUpIcon from "../Icons/SvgChevronUpIcon"; 10 | import SvgChevronDownIcon from "../Icons/SvgChevronDownIcon"; 11 | 12 | export interface AccordionProps extends DisclosureProps { 13 | /* Button label text */ 14 | label?: string; 15 | } 16 | 17 | export default function Accordion({ 18 | label, 19 | children, 20 | ...props 21 | }: AccordionProps) { 22 | return ( 23 | 24 | {({ isExpanded }) => ( 25 | <> 26 | 35 | 36 | <>{children} 37 | 38 | 39 | )} 40 | 41 | ); 42 | } 43 | -------------------------------------------------------------------------------- /packages/react-components/src/components/Accordion/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from "./Accordion"; 2 | export type { AccordionProps } from "./Accordion"; 3 | -------------------------------------------------------------------------------- /packages/react-components/src/components/AccordionGroup/AccordionGroup.tsx: -------------------------------------------------------------------------------- 1 | import { DisclosureGroup, DisclosureGroupProps } from "react-aria-components"; 2 | 3 | import "./AccordionGroup.css"; 4 | 5 | export interface AccordionGroupProps extends DisclosureGroupProps { 6 | /* Sets label displayed above accordion group */ 7 | title?: string; 8 | /* Sets element type for accordion group title. If not set, defaults to */ 9 | titleElement?: "h1" | "h2" | "h3" | "h4" | "h5" | "h6"; 10 | } 11 | 12 | export default function AccordionGroup({ 13 | title, 14 | titleElement, 15 | children, 16 | ...props 17 | }: AccordionGroupProps) { 18 | function getTitle() { 19 | switch (titleElement) { 20 | case "h1": 21 | return

{title}

; 22 | case "h2": 23 | return

{title}

; 24 | case "h3": 25 | return

{title}

; 26 | case "h4": 27 | return

{title}

; 28 | case "h5": 29 | return
{title}
; 30 | case "h6": 31 | return
{title}
; 32 | default: 33 | return {title}; 34 | } 35 | } 36 | return ( 37 | <> 38 | {title && ( 39 |
40 | {getTitle()} 41 |
42 | )} 43 | 44 | {children} 45 | 46 | 47 | ); 48 | } 49 | -------------------------------------------------------------------------------- /packages/react-components/src/components/AccordionGroup/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from "./AccordionGroup"; 2 | export type { AccordionGroupProps } from "./AccordionGroup"; 3 | -------------------------------------------------------------------------------- /packages/react-components/src/components/AlertBanner/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from "./AlertBanner"; 2 | export type { AlertBannerProps } from "./AlertBanner"; 3 | -------------------------------------------------------------------------------- /packages/react-components/src/components/AlertDialog/index.ts: -------------------------------------------------------------------------------- 1 | export { default, DialogTrigger } from "./AlertDialog"; 2 | export type { AlertDialogProps } from "./AlertDialog"; 3 | -------------------------------------------------------------------------------- /packages/react-components/src/components/Button/Button.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | Button as ReactAriaButton, 3 | ButtonProps as ReactAriaButtonProps, 4 | } from "react-aria-components"; 5 | 6 | import "./Button.css"; 7 | 8 | export interface ButtonProps extends ReactAriaButtonProps { 9 | /** 10 | * Defaults to `medium`. `small` is shorter vertically. 11 | */ 12 | size?: "small" | "medium"; 13 | /** 14 | * Defaults to `primary`. 15 | */ 16 | variant?: "primary" | "secondary" | "tertiary" | "link"; 17 | /** 18 | * For destructive/deletion actions. 19 | */ 20 | danger?: boolean; 21 | /** 22 | * If true, renders a square button intended for a single icon. 23 | */ 24 | isIconButton?: boolean; 25 | } 26 | 27 | export default function Button({ 28 | size = "medium", 29 | variant = "primary", 30 | danger = false, 31 | isIconButton = false, 32 | ...props 33 | }: ButtonProps) { 34 | return ( 35 | 41 | ); 42 | } 43 | -------------------------------------------------------------------------------- /packages/react-components/src/components/Button/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from "./Button"; 2 | export type { ButtonProps } from "./Button"; 3 | -------------------------------------------------------------------------------- /packages/react-components/src/components/ButtonGroup/ButtonGroup.css: -------------------------------------------------------------------------------- 1 | .bcds-ButtonGroup { 2 | display: flex; 3 | gap: var(--layout-margin-small); 4 | flex-grow: 1; 5 | } 6 | 7 | .bcds-ButtonGroup.horizontal { 8 | flex-direction: row; 9 | } 10 | 11 | .bcds-ButtonGroup.vertical { 12 | flex-direction: column; 13 | } 14 | 15 | .bcds-ButtonGroup.start { 16 | justify-content: flex-start; 17 | } 18 | 19 | .bcds-ButtonGroup.center { 20 | justify-content: center; 21 | } 22 | 23 | .bcds-ButtonGroup.end { 24 | justify-content: flex-end; 25 | } 26 | -------------------------------------------------------------------------------- /packages/react-components/src/components/ButtonGroup/ButtonGroup.test.tsx: -------------------------------------------------------------------------------- 1 | import "@testing-library/jest-dom"; 2 | import { render, screen } from "@testing-library/react"; 3 | 4 | import ButtonGroup from "./ButtonGroup"; 5 | 6 | describe("ButtonGroup", () => { 7 | render(); 8 | render( 9 | 10 | ); 11 | render(); 12 | render(); 13 | const defaultButtonGroup = screen.getByTestId("button-group"); 14 | const verticalButtonGroup = screen.getByTestId("orientation-vertical"); 15 | const endButtonGroup = screen.getByTestId("alignment-end"); 16 | const centerButtonGroup = screen.getByTestId("alignment-center"); 17 | 18 | it("has default classes", () => { 19 | expect(defaultButtonGroup).toHaveClass("bcds-ButtonGroup horizontal start"); 20 | }); 21 | it("has the role='group' attribute", () => { 22 | expect(defaultButtonGroup).toHaveAttribute("role", "group"); 23 | }); 24 | it("passing orientation adds the correct class", () => { 25 | expect(verticalButtonGroup).toHaveClass("bcds-ButtonGroup vertical start"); 26 | }); 27 | it("passing 'end' alignment adds the correct class", () => { 28 | expect(endButtonGroup).toHaveClass("bcds-ButtonGroup horizontal end"); 29 | }); 30 | it("passing 'center' alignment adds the correct class", () => { 31 | expect(centerButtonGroup).toHaveClass("bcds-ButtonGroup horizontal center"); 32 | }); 33 | }); 34 | -------------------------------------------------------------------------------- /packages/react-components/src/components/ButtonGroup/ButtonGroup.tsx: -------------------------------------------------------------------------------- 1 | import "./ButtonGroup.css"; 2 | 3 | export interface ButtonGroupProps extends React.PropsWithChildren { 4 | /* Sets layout of button group */ 5 | orientation?: "horizontal" | "vertical"; 6 | /* Sets alignment of button group */ 7 | alignment?: "start" | "center" | "end"; 8 | /* Semantic label for button group */ 9 | ariaLabel?: string | undefined; 10 | } 11 | 12 | export default function ButtonGroup({ 13 | orientation = "horizontal", 14 | alignment = "start", 15 | ariaLabel, 16 | children, 17 | ...props 18 | }: ButtonGroupProps) { 19 | return ( 20 |
26 | {children} 27 |
28 | ); 29 | } 30 | -------------------------------------------------------------------------------- /packages/react-components/src/components/ButtonGroup/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from "./ButtonGroup"; 2 | export type { ButtonGroupProps } from "./ButtonGroup"; 3 | -------------------------------------------------------------------------------- /packages/react-components/src/components/Callout/Callout.tsx: -------------------------------------------------------------------------------- 1 | import ButtonGroup from "../ButtonGroup"; 2 | 3 | import "./Callout.css"; 4 | 5 | export interface CalloutProps extends React.PropsWithChildren { 6 | /* Callout theme */ 7 | variant?: "lightGrey" | "lightBlue" | "lightGold" | "Blue" | "Grey" | "Black"; 8 | /* Title */ 9 | title?: string; 10 | /* Description */ 11 | description?: string; 12 | /* Button group */ 13 | buttons?: React.ReactNode; 14 | /* ARIA role */ 15 | role?: React.AriaRole | undefined; 16 | /* */ 17 | isLeftBorderDisabled?: boolean; 18 | } 19 | 20 | export default function Callout({ 21 | variant = "lightGrey", 22 | title, 23 | description, 24 | buttons, 25 | role = "note", 26 | isLeftBorderDisabled = false, 27 | children, 28 | ...props 29 | }: CalloutProps) { 30 | return ( 31 |
38 | {children ? ( 39 | children 40 | ) : ( 41 | <> 42 |
47 | {title && ( 48 | 49 | {title} 50 | 51 | )} 52 | {description && ( 53 | {description} 54 | )} 55 | {buttons && ( 56 | 57 | {buttons} 58 | 59 | )} 60 |
61 | 62 | )} 63 |
64 | ); 65 | } 66 | -------------------------------------------------------------------------------- /packages/react-components/src/components/Callout/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from "./Callout"; 2 | export type { CalloutProps } from "./Callout"; 3 | -------------------------------------------------------------------------------- /packages/react-components/src/components/Checkbox/Checkbox.test.tsx: -------------------------------------------------------------------------------- 1 | import { render, screen, fireEvent } from "@testing-library/react"; 2 | import "@testing-library/jest-dom"; // for matchers like toBeChecked 3 | 4 | import Checkbox from "./Checkbox"; 5 | 6 | describe("Checkbox component", () => { 7 | test("Checkbox renders unchecked, user clicks it, checkbox is checked", () => { 8 | render(I agree); 9 | const checkbox = screen.getByLabelText(/i agree/i); 10 | expect(checkbox).not.toBeChecked(); 11 | fireEvent.click(checkbox); 12 | expect(checkbox).toBeChecked(); 13 | }); 14 | 15 | test("Checkbox renders checked, user clicks it, checkbox is unchecked", () => { 16 | render(Email me my results); 17 | const checkbox = screen.getByLabelText(/email me my results/i); 18 | expect(checkbox).toBeChecked(); 19 | fireEvent.click(checkbox); 20 | expect(checkbox).not.toBeChecked(); 21 | }); 22 | }); 23 | -------------------------------------------------------------------------------- /packages/react-components/src/components/Checkbox/Checkbox.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | Checkbox as ReactAriaCheckbox, 3 | CheckboxProps, 4 | CheckboxRenderProps, 5 | } from "react-aria-components"; 6 | 7 | import SvgCheckIcon from "../Icons/SvgCheckIcon"; 8 | import SvgDashIcon from "../Icons/SvgDashIcon"; 9 | 10 | import "./Checkbox.css"; 11 | 12 | export default function Checkbox({ value, children, ...props }: CheckboxProps) { 13 | return ( 14 | 19 | {({ isRequired, isSelected, isIndeterminate }: CheckboxRenderProps) => ( 20 | <> 21 |
22 | {isSelected && !isIndeterminate && } 23 | {isIndeterminate && } 24 |
25 | 26 | <>{children} {isRequired && "(required)"} 27 | 28 | 29 | )} 30 |
31 | ); 32 | } 33 | -------------------------------------------------------------------------------- /packages/react-components/src/components/Checkbox/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from "./Checkbox"; 2 | export type { CheckboxProps } from "react-aria-components"; 3 | -------------------------------------------------------------------------------- /packages/react-components/src/components/CheckboxGroup/CheckboxGroup.css: -------------------------------------------------------------------------------- 1 | .bcds-react-aria-CheckboxGroup { 2 | display: flex; 3 | flex-direction: column; 4 | gap: var(--layout-margin-small); 5 | } 6 | 7 | /* Orientation */ 8 | .bcds-react-aria-CheckboxGroup--options { 9 | display: flex; 10 | } 11 | 12 | .bcds-react-aria-CheckboxGroup--options.vertical { 13 | flex-direction: column; 14 | gap: var(--layout-margin-small); 15 | } 16 | 17 | .bcds-react-aria-CheckboxGroup--options.horizontal { 18 | flex-direction: row; 19 | gap: var(--layout-margin-medium); 20 | } 21 | .bcds-react-aria-CheckboxGroup--options.horizontal.flex-wrap-nowrap { 22 | flex-wrap: nowrap; 23 | } 24 | .bcds-react-aria-CheckboxGroup--options.horizontal.flex-wrap-wrap { 25 | flex-wrap: wrap; 26 | } 27 | .bcds-react-aria-CheckboxGroup--options.horizontal.flex-wrap-wrap-reverse { 28 | flex-wrap: wrap-reverse; 29 | } 30 | 31 | /* Parts */ 32 | .bcds-react-aria-CheckboxGroup--label { 33 | font: var(--typography-regular-small-body); 34 | color: var(--typography-color-primary); 35 | } 36 | 37 | .bcds-react-aria-CheckboxGroup--description { 38 | font: var(--typography-regular-small-body); 39 | color: var(--typography-color-secondary); 40 | } 41 | 42 | .bcds-react-aria-CheckboxGroup--error { 43 | display: inline-flex; 44 | flex-direction: row; 45 | gap: var(--layout-margin-xsmall); 46 | font: var(--typography-regular-small-body); 47 | color: var(--typography-color-danger); 48 | } 49 | -------------------------------------------------------------------------------- /packages/react-components/src/components/CheckboxGroup/CheckboxGroup.test.tsx: -------------------------------------------------------------------------------- 1 | import { render, screen, fireEvent } from "@testing-library/react"; 2 | import "@testing-library/jest-dom"; // for matchers like toBeChecked 3 | 4 | import CheckboxGroup from "./CheckboxGroup"; 5 | import Checkbox from "../Checkbox/Checkbox"; 6 | 7 | describe("CheckboxGroup component", () => { 8 | beforeEach(() => { 9 | render( 10 | 11 | Apple 12 | Orange 13 | Banana 14 | 15 | ); 16 | }); 17 | 18 | test("renders 3 checkboxes with middle one checked", () => { 19 | const checkboxes = screen.getAllByRole("checkbox"); 20 | expect(checkboxes).toHaveLength(3); 21 | expect(checkboxes[0]).not.toBeChecked(); 22 | expect(checkboxes[1]).toBeChecked(); 23 | expect(checkboxes[2]).not.toBeChecked(); 24 | }); 25 | 26 | test("user clicks 'orange' option, it is no longer checked", () => { 27 | const checkboxOrange = screen.getByLabelText(/orange/i); 28 | expect(checkboxOrange).toBeChecked(); 29 | fireEvent.click(checkboxOrange); 30 | expect(checkboxOrange).not.toBeChecked(); 31 | }); 32 | }); 33 | -------------------------------------------------------------------------------- /packages/react-components/src/components/CheckboxGroup/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from "./CheckboxGroup"; 2 | export type { CheckboxGroupProps } from "./CheckboxGroup"; 3 | -------------------------------------------------------------------------------- /packages/react-components/src/components/Dialog/Dialog.css: -------------------------------------------------------------------------------- 1 | .bcds-react-aria-Dialog { 2 | display: flex; 3 | flex-direction: column; 4 | min-height: var(--layout-margin-xxxlarge); 5 | } 6 | 7 | .bcds-react-aria-Dialog--Container { 8 | position: relative; 9 | } 10 | 11 | /* Close icon */ 12 | .bcds-react-aria-Dialog--closeIcon { 13 | color: var(--icons-color-primary); 14 | position: absolute; 15 | top: 0; 16 | right: 0; 17 | padding: var(--layout-padding-small); 18 | } 19 | .bcds-react-aria-Dialog--closeIcon > svg { 20 | min-width: var(--icons-size-medium); 21 | height: var(--icons-size-medium); 22 | } 23 | -------------------------------------------------------------------------------- /packages/react-components/src/components/Dialog/Dialog.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | Dialog as ReactAriaDialog, 3 | DialogTrigger, 4 | DialogProps as ReactAriaDialogProps, 5 | } from "react-aria-components"; 6 | 7 | import Button from "../Button"; 8 | import SvgCloseIcon from "../Icons/SvgCloseIcon"; 9 | 10 | import "./Dialog.css"; 11 | 12 | export interface DialogProps extends ReactAriaDialogProps { 13 | /* Show or hide close button */ 14 | isCloseable?: boolean; 15 | } 16 | 17 | // This is not currently exported by RAC but we need it to type `close`. 18 | export interface DialogRenderProps { 19 | /** Handler function to close the Dialog */ 20 | close: () => void; 21 | } 22 | 23 | export default function Dialog({ 24 | isCloseable = true, 25 | role = "dialog", 26 | children, 27 | ...props 28 | }: DialogProps) { 29 | return ( 30 | 31 | {({ close }: DialogRenderProps) => ( 32 | <> 33 |
34 | {isCloseable && ( 35 | 36 | 46 | 47 | )} 48 | <>{children} 49 |
50 | 51 | )} 52 |
53 | ); 54 | } 55 | 56 | export { DialogTrigger }; 57 | -------------------------------------------------------------------------------- /packages/react-components/src/components/Dialog/index.ts: -------------------------------------------------------------------------------- 1 | export { default, DialogTrigger } from "./Dialog"; 2 | export type { DialogProps } from "./Dialog"; 3 | -------------------------------------------------------------------------------- /packages/react-components/src/components/Footer/Footer.test.tsx: -------------------------------------------------------------------------------- 1 | import "@testing-library/jest-dom"; 2 | import { render, screen } from "@testing-library/react"; 3 | 4 | import Footer from "./Footer"; 5 | 6 | describe("Footer", () => { 7 | render(