From 1eb54995f92b6cf6f05fab5d11b9bd110fb5a155 Mon Sep 17 00:00:00 2001 From: Nathan Young <1447339+nathanyoung@users.noreply.github.com> Date: Wed, 17 Jul 2024 13:46:14 -0700 Subject: [PATCH] BREAKING CHANGE: Dark mode support (#902) BREAKING CHANGE: Dark mode support * wip * font colors * BREAKING CHANGE: background, border, font specific colors BREAKING CHANGE: background, border, font specific colors BREAKING CHANGE: Spinner variant prop changed to color * BREAKING CHANGE: ThemeProvider * feat(RadioGroup): dark mode support * feat(Accordion): dark mode support * feat(Tabs): dark mode support * feat(TabsSlider): dark mode support * dark mode tokens * Update FileUpload.tsx * Update Heading.Playground.stories.tsx * Update MediaModal.tsx * feat(Card): dark mode support * feat(Alert): dark mode support * feat(TabsSlider): dark mode support * feat(CategoryFilter): dark mode support * wip * checkboxinput * OptionTile * update pdt package with new tokens * fix build * fix lint * Update Box.tsx * checkboxinput * Update MediaModal.tsx * Update SelectInputNative.module.scss * Update Checkbox.module.scss * Update pull-request.yml * light mode button background tokens * light mode button font color tokens * light mode button border color tokens * pdt 1.3.0 * SelectInput dark mode fixes * Badge dark mode * spec body font * wip * remove internal form color tokens * remove form theming docs * wip * Toast dark mode * Toggle dark mode * Table dark mode * remove component design token documentation * more cleanup * datepicker dark mode * pdt 1.4 * Update Theming.stories.mdx * feat: Modal dark mode (#894) * feat: Modal dark mode * Update Modal.module.scss * Update Modal.module.scss * fix: bump pdt (#895) * fix: bump pdt * fix build * fix(Popover): arrowColor background color type * fix: transparent border color * fix(Table): dark mode loading state (#896) * fix(Table): dark mode loading state * Update Table.module.scss * fix: update color documentation * Merge branch 'main' into beta * clean up * Update Popover.VisualTests.stories.tsx * feat: document brand colors, semantic colors, and dark values * Dark mode (#899) * BREAKING CHANGE: Dark mode support (#893) * wip * font colors * BREAKING CHANGE: background, border, font specific colors BREAKING CHANGE: background, border, font specific colors BREAKING CHANGE: Spinner variant prop changed to color * BREAKING CHANGE: ThemeProvider * feat(RadioGroup): dark mode support * feat(Accordion): dark mode support * feat(Tabs): dark mode support * feat(TabsSlider): dark mode support * dark mode tokens * Update FileUpload.tsx * Update Heading.Playground.stories.tsx * Update MediaModal.tsx * feat(Card): dark mode support * feat(Alert): dark mode support * feat(TabsSlider): dark mode support * feat(CategoryFilter): dark mode support * wip * checkboxinput * OptionTile * update pdt package with new tokens * fix build * fix lint * Update Box.tsx * checkboxinput * Update MediaModal.tsx * Update SelectInputNative.module.scss * Update Checkbox.module.scss * Update pull-request.yml * light mode button background tokens * light mode button font color tokens * light mode button border color tokens * pdt 1.3.0 * SelectInput dark mode fixes * Badge dark mode * spec body font * wip * remove internal form color tokens * remove form theming docs * wip * Toast dark mode * Toggle dark mode * Table dark mode * remove component design token documentation * more cleanup * datepicker dark mode * pdt 1.4 * Update Theming.stories.mdx * feat: Modal dark mode (#894) * feat: Modal dark mode * Update Modal.module.scss * Update Modal.module.scss * fix: bump pdt (#895) * fix: bump pdt * fix build * fix(Popover): arrowColor background color type * fix: transparent border color * fix(Table): dark mode loading state (#896) * fix(Table): dark mode loading state * Update Table.module.scss * build(deps): bump ws from 6.2.2 to 6.2.3 (#897) Bumps [ws](https://github.com/websockets/ws) from 6.2.2 to 6.2.3. - [Release notes](https://github.com/websockets/ws/releases) - [Commits](https://github.com/websockets/ws/compare/6.2.2...6.2.3) --- updated-dependencies: - dependency-name: ws dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * fix: update color documentation * Merge branch 'main' into beta * clean up * Update Popover.VisualTests.stories.tsx * feat: document brand colors, semantic colors, and dark values * Update GetStarted.stories.mdx * fix: Alert close button color * feat: CategoryFilter dark mode tokens * docs: apply darkmode background to story canvas --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * fix: more cleanup (#900) * BREAKING CHANGE: Dark mode support (#893) * wip * font colors * BREAKING CHANGE: background, border, font specific colors BREAKING CHANGE: background, border, font specific colors BREAKING CHANGE: Spinner variant prop changed to color * BREAKING CHANGE: ThemeProvider * feat(RadioGroup): dark mode support * feat(Accordion): dark mode support * feat(Tabs): dark mode support * feat(TabsSlider): dark mode support * dark mode tokens * Update FileUpload.tsx * Update Heading.Playground.stories.tsx * Update MediaModal.tsx * feat(Card): dark mode support * feat(Alert): dark mode support * feat(TabsSlider): dark mode support * feat(CategoryFilter): dark mode support * wip * checkboxinput * OptionTile * update pdt package with new tokens * fix build * fix lint * Update Box.tsx * checkboxinput * Update MediaModal.tsx * Update SelectInputNative.module.scss * Update Checkbox.module.scss * Update pull-request.yml * light mode button background tokens * light mode button font color tokens * light mode button border color tokens * pdt 1.3.0 * SelectInput dark mode fixes * Badge dark mode * spec body font * wip * remove internal form color tokens * remove form theming docs * wip * Toast dark mode * Toggle dark mode * Table dark mode * remove component design token documentation * more cleanup * datepicker dark mode * pdt 1.4 * Update Theming.stories.mdx * feat: Modal dark mode (#894) * feat: Modal dark mode * Update Modal.module.scss * Update Modal.module.scss * fix: bump pdt (#895) * fix: bump pdt * fix build * fix(Popover): arrowColor background color type * fix: transparent border color * fix(Table): dark mode loading state (#896) * fix(Table): dark mode loading state * Update Table.module.scss * build(deps): bump ws from 6.2.2 to 6.2.3 (#897) Bumps [ws](https://github.com/websockets/ws) from 6.2.2 to 6.2.3. - [Release notes](https://github.com/websockets/ws/releases) - [Commits](https://github.com/websockets/ws/compare/6.2.2...6.2.3) --- updated-dependencies: - dependency-name: ws dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * fix: update color documentation * Merge branch 'main' into beta * clean up * Update Popover.VisualTests.stories.tsx * feat: document brand colors, semantic colors, and dark values * Update GetStarted.stories.mdx * fix: Alert close button color * feat: CategoryFilter dark mode tokens * docs: apply darkmode background to story canvas * fix(TextInputInset): prefix and suffix dark mode colors * fix: cleanup stories * feat(Toggle): use toggle specific background color tokens * refactor(OptionTile): hover border colors * build(deps): bump palmetto-design-tokens from 1.7.1 to 1.7.2 * fix(OptionTile): selected error text color * fix: remove fullstory --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * fix(Card): subdued card darkmode * docs(OptionTileGroup): fix example border * fix rename * Update Intro.stories.mdx --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .eslintrc | 1 + .github/workflows/pull-request.yml | 2 +- .storybook/main.js | 1 - .storybook/preview-body.html | 3 +- .storybook/preview.js | 9 +- .storybook/register.js | 11 - package.json | 3 +- .../Accordion/Accordion.Overview.stories.mdx | 92 ++- src/components/Accordion/AccordionPanel.tsx | 2 +- .../Accordion/AccordionPanelSummary.tsx | 4 +- .../Alert/Alert.Overview.stories.mdx | 99 --- src/components/Alert/Alert.module.scss | 48 +- src/components/Alert/Alert.tsx | 4 +- .../Badge/Badge.Overview.stories.mdx | 66 -- src/components/Badge/Badge.module.scss | 113 +-- src/components/Badge/Badge.tsx | 11 - src/components/Box/Box.Overview.stories.mdx | 709 +++++++++-------- src/components/Box/Box.Playground.stories.tsx | 18 +- .../Box/Box.VisualTests.stories.tsx | 394 +++------- src/components/Box/Box.tsx | 565 +++++++------- .../Button/Button.Overview.stories.mdx | 158 ---- src/components/Button/Button.module.scss | 175 ++--- src/components/Button/Button.test.jsx | 12 +- src/components/Button/Button.tsx | 6 +- .../Card/Card.Codesandbox.stories.mdx | 2 +- src/components/Card/Card.Overview.stories.mdx | 83 +- src/components/Card/Card.module.scss | 18 +- src/components/Card/Card.tsx | 7 +- .../Card/components/CardFooter/CardFooter.tsx | 7 +- .../CategoryFilter.Overview.stories.mdx | 42 - .../CategoryFilter/CategoryFilter.module.scss | 41 +- .../CheckboxInput.Overview.stories.mdx | 79 +- .../components/Checkbox.module.scss | 115 ++- .../DateInput/DateInput.Overview.stories.mdx | 4 - .../DatePicker.Overview.stories.mdx | 171 +---- .../DatePicker/DatePicker.module.scss | 103 ++- src/components/Details/Details.module.scss | 5 +- .../Drawer/Drawer.Overview.stories.mdx | 97 --- src/components/Drawer/Drawer.module.scss | 27 +- src/components/Drawer/Drawer.tsx | 4 +- src/components/FileUpload/FileUpload.tsx | 2 +- .../FormLabel/FormLabel.Overview.stories.mdx | 4 - .../FormLabel/FormLabel.module.scss | 15 +- .../Heading/Heading.Overview.stories.mdx | 31 - .../Heading/Heading.Playground.stories.tsx | 2 +- src/components/Heading/Heading.module.scss | 6 +- src/components/HelpText/HelpText.module.scss | 10 +- src/components/Icon/Icon.tsx | 10 +- .../InputValidationMessage.module.scss | 2 +- .../MediaModal.Overview.stories.mdx | 36 +- src/components/MediaModal/MediaModal.tsx | 2 +- .../Modal/Modal.Overview.stories.mdx | 40 +- .../Modal/Modal.VisualTests.stories.jsx | 10 +- src/components/Modal/Modal.module.scss | 40 +- src/components/Modal/Modal.test.tsx | 4 +- .../components/ModalFooter/ModalFooter.tsx | 2 +- .../components/ModalHeader/ModalHeader.tsx | 4 +- .../OptionTile.Overview.stories.mdx | 139 +--- .../OptionTile/OptionTile.module.scss | 60 +- .../OptionTileGroup.Overview.stories.mdx | 14 +- .../OptionTileGroup/OptionTileGroup.tsx | 2 +- .../Popover/Popover.Codesandbox.stories.mdx | 8 +- .../Popover/Popover.Overview.stories.mdx | 114 +-- .../Popover/Popover.VisualTests.stories.tsx | 18 +- src/components/Popover/Popover.test.tsx | 2 +- src/components/Popover/Popover.tsx | 7 +- .../RadioGroup.Overview.stories.mdx | 5 - .../RadioGroup/RadioGroup.module.scss | 23 +- .../RadioGroup/RadioInput/RadioInput.tsx | 2 +- .../RadioGroup/RadioInput/RadioInputIcon.tsx | 6 +- .../SelectInput.Overview.stories.mdx | 35 +- .../SelectInput/SelectInput.module.scss | 62 +- .../SelectInputInset.Overview.stories.mdx | 4 - .../SelectInputInset.module.scss | 57 +- .../SelectInputNative.Overview.stories.mdx | 4 - .../SelectInputNative.module.scss | 37 +- .../SelectInputNative/SelectInputNative.tsx | 15 +- .../Spinner/Spinner.Codesandbox.stories.mdx | 48 +- .../Spinner/Spinner.Playground.stories.tsx | 8 +- .../Spinner/Spinner.VisualTests.stories.tsx | 11 +- src/components/Spinner/Spinner.module.scss | 14 - src/components/Spinner/Spinner.stories.mdx | 52 +- src/components/Spinner/Spinner.tsx | 24 +- .../Table/Table.Overview.stories.mdx | 288 +++---- src/components/Table/Table.module.scss | 5 +- .../Table/TableBody/TableBody.module.scss | 4 +- .../TableBodyCell/TableBodyCell.module.scss | 23 +- .../TableBody/TableBodyCell/TableBodyCell.tsx | 8 +- .../TableHeaderCell.module.scss | 27 +- .../TableHeaderCell/TableHeaderCell.tsx | 1 - .../common/TableRow/TableRow.module.scss | 2 +- src/components/Tabs/TabItem.tsx | 2 +- src/components/Tabs/Tabs.Overview.stories.mdx | 32 - src/components/Tabs/Tabs.module.scss | 25 +- src/components/Tabs/Tabs.tsx | 2 +- .../TabsSlider.Overview.stories.mdx | 29 - .../TabsSlider/TabsSlider.module.scss | 16 +- src/components/TabsSlider/TabsSlider.tsx | 6 +- .../TextInput/TextInput.Overview.stories.mdx | 4 - .../TextInput/TextInput.module.scss | 291 +++++-- .../TextInputInset.Overview.stories.mdx | 4 - .../TextInputInset/TextInputInset.module.scss | 69 +- .../TextLink/TextLink.Overview.stories.mdx | 51 +- src/components/TextLink/TextLink.module.scss | 16 +- .../TextareaInput.Overview.stories.mdx | 4 - .../TextareaInput/TextareaInput.module.scss | 120 ++- .../TextareaInputInset.Overview.stories.mdx | 4 - .../TextareaInputInset.module.scss | 47 +- .../ThemeProvider.Codesandbox.stories.mdx | 196 ----- .../ThemeProvider.Overview.stories.mdx | 190 +---- .../ThemeProvider/ThemeProvider.test.tsx | 24 +- .../ThemeProvider/ThemeProvider.tsx | 100 ++- .../TimePicker.Overview.stories.mdx | 10 +- .../TimePickerNative.Overview.stories.mdx | 10 +- .../Toast/Toast.Overview.stories.mdx | 33 - src/components/Toast/Toast.test.tsx | 282 +++++-- .../Toast/ToastNotification.module.scss | 12 +- src/components/Toast/ToastNotification.tsx | 47 +- .../Toggle/Toggle.Overview.stories.mdx | 30 - src/components/Toggle/Toggle.module.scss | 21 +- src/declarations.d.ts | 3 + src/docs/Content.GoalsPrinciples.stories.mdx | 44 +- src/docs/FormTheming.stories.mdx | 280 ------- src/docs/Foundation.DesignTokens.stories.mdx | 320 +++++--- src/docs/GetStarted.stories.mdx | 25 +- src/docs/Intro.stories.mdx | 5 +- src/docs/Theming.stories.mdx | 716 +++++++++++------- .../createComponent.Overview.stories.mdx | 177 ++--- src/lib/tokens.ts | 21 +- src/styles/flex.scss | 673 ++++++++++++---- src/styles/variables/forms.scss | 32 +- src/styles/variables/index.scss | 1 - src/styles/variables/table.scss | 20 - src/styles/variables/tokens.scss | 1 + src/types/index.ts | 3 +- yarn.lock | 20 +- 136 files changed, 3784 insertions(+), 4894 deletions(-) delete mode 100644 .storybook/register.js delete mode 100644 src/components/ThemeProvider/ThemeProvider.Codesandbox.stories.mdx delete mode 100644 src/docs/FormTheming.stories.mdx delete mode 100644 src/styles/variables/table.scss diff --git a/.eslintrc b/.eslintrc index b3a748a53..1469739d9 100644 --- a/.eslintrc +++ b/.eslintrc @@ -19,6 +19,7 @@ "browser": true }, "rules": { + "react/require-default-props": ["error", { "ignoreFunctionalComponents": true }], "arrow-parens": [ "error", "as-needed" diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 531b21600..e9f965e1b 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -121,7 +121,7 @@ jobs: fetch-depth: 0 # Required to retrieve git history - uses: actions/setup-node@v2 with: - node-version: '16' + node-version: 16 - uses: actions/cache@v1 with: path: ~/.cache/yarn diff --git a/.storybook/main.js b/.storybook/main.js index 8baff240d..e4af93cbc 100644 --- a/.storybook/main.js +++ b/.storybook/main.js @@ -37,7 +37,6 @@ module.exports = { 'storybook-addon-designs', 'storybook-addon-mdx-embed', '@storybook/addon-postcss', - './register', ], webpackFinal: config => { const mdxRule = config.module.rules.find((rule) => diff --git a/.storybook/preview-body.html b/.storybook/preview-body.html index fadf906d7..2e9f54c2c 100644 --- a/.storybook/preview-body.html +++ b/.storybook/preview-body.html @@ -1,6 +1,7 @@ diff --git a/.storybook/preview.js b/.storybook/preview.js index 4194d2dda..97614b249 100644 --- a/.storybook/preview.js +++ b/.storybook/preview.js @@ -27,9 +27,14 @@ export const parameters = { 'Foundation', ['Design Principles', 'Design Tokens'], 'Content', - ['Goals and Principles', 'Voice and Tone', 'Grammar and Mechanics', 'Word List'], + [ + 'Goals and Principles', + 'Voice and Tone', + 'Grammar and Mechanics', + 'Word List', + ], 'Theming', - ['Overview', 'Form Controls'], + ['Overview'], 'Components', 'Patterns', ], diff --git a/.storybook/register.js b/.storybook/register.js deleted file mode 100644 index 44f8941d9..000000000 --- a/.storybook/register.js +++ /dev/null @@ -1,11 +0,0 @@ -// register.js -import { addons } from '@storybook/addons'; - -import * as FullStory from '@fullstory/browser'; - -addons.register('storybook/fullstory', () => { - FullStory.init({ - orgId: 'P6XKD', - devMode: window.location.hostname !== 'ux.palmetto.com', - }); -}); \ No newline at end of file diff --git a/package.json b/package.json index c1978d3db..d7177a1d8 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ }, "dependencies": { "@palmetto/dialog": "^0.16.4", - "@palmetto/palmetto-design-tokens": "0.79.2", + "@palmetto/palmetto-design-tokens": "1.7.2", "@popperjs/core": "^2.5.3", "classnames": "^2.2.6", "cleave.js": "^1.6.0", @@ -85,7 +85,6 @@ "@babel/plugin-transform-spread": "^7.13.0", "@babel/polyfill": "^7.10.4", "@babel/preset-react": "^7.10.4", - "@fullstory/browser": "^1.4.9", "@mdx-js/loader": "^1.6.22", "@semantic-release/changelog": "5", "@semantic-release/commit-analyzer": "^8.0.1", diff --git a/src/components/Accordion/Accordion.Overview.stories.mdx b/src/components/Accordion/Accordion.Overview.stories.mdx index ae3f7238d..6bf696134 100644 --- a/src/components/Accordion/Accordion.Overview.stories.mdx +++ b/src/components/Accordion/Accordion.Overview.stories.mdx @@ -52,16 +52,18 @@ Accordions are useful when you want to toggle between hiding and showing additio

- Solar panels, also called photovoltaic or PV panels, consist of solar cells that are - designed to capture the radiant light and heat contained in sunlight and convert it - into usable clean energy for your home. + Solar panels, also called photovoltaic or PV panels, consist of + solar cells that are designed to capture the radiant light and + heat contained in sunlight and convert it into usable clean + energy for your home.

- When sunlight hits your solar panel, the photons of energy are converted into DC - (direct current) electricity, which is then converted into AC (alternating current) - electricity for use in your home. Solar panels are often grouped together to form a - solar grid or solar array, allowing you to capture and harness the right amount of - energy for your needs. + When sunlight hits your solar panel, the photons of energy are + converted into DC (direct current) electricity, which is then + converted into AC (alternating current) electricity for use in + your home. Solar panels are often grouped together to form a + solar grid or solar array, allowing you to capture and harness + the right amount of energy for your needs.

@@ -74,14 +76,16 @@ Accordions are useful when you want to toggle between hiding and showing additio

- There are several factors we can look at to determine if solar might be a good - solution for your needs, including roof space, home energy usage, credit health, and - eligibility for incentives. At Palmetto, we start by calculating a quick savings - estimate based on your home, location, and current utility costs. Then, we’ll - schedule a meeting to clarify your goals, address any questions, identify purchase - options, and outline the solar process. All of this happens before you pay, allowing - you to decide if a solar power system is right for you based on a complete - understanding of the potential costs and savings. + There are several factors we can look at to determine if solar + might be a good solution for your needs, including roof space, + home energy usage, credit health, and eligibility for + incentives. At Palmetto, we start by calculating a quick savings + estimate based on your home, location, and current utility + costs. Then, we’ll schedule a meeting to clarify your goals, + address any questions, identify purchase options, and outline + the solar process. All of this happens before you pay, allowing + you to decide if a solar power system is right for you based on + a complete understanding of the potential costs and savings.

@@ -94,13 +98,15 @@ Accordions are useful when you want to toggle between hiding and showing additio

- The right solar power system for your home will depend on a variety of factors, - including your current energy usage, the size and layout of your roof, and your - preferred level of energy independence. To hone in on the right solution for your - home, we always begin with a personal consultation and a survey, both of which serve - to clarify your goals and outline available options. Should you choose to invest, - we’ll design a custom solution to meet your goals and maximize your savings—no - haggling, no upselling, just right. + The right solar power system for your home will depend on a + variety of factors, including your current energy usage, the + size and layout of your roof, and your preferred level of energy + independence. To hone in on the right solution for your home, we + always begin with a personal consultation and a survey, both of + which serve to clarify your goals and outline available options. + Should you choose to invest, we’ll design a custom solution to + meet your goals and maximize your savings—no haggling, no + upselling, just right.

@@ -153,9 +159,10 @@ By default the caret is on the right. You can render the caret on the left side

- Together, we’ll clarify your goals, address any questions, identify purchase options - and incentives, and outline the solar process—placing you in the driver’s seat for - everything moving forward. + Together, we’ll clarify your goals, address any questions, + identify purchase options and incentives, and outline the solar + process—placing you in the driver’s seat for everything moving + forward.

@@ -169,9 +176,9 @@ By default the caret is on the right. You can render the caret on the left side

- Our solar specialists will take a survey of your property and define specific - requirements in your area. Then, we’ll design a solar energy system to maximize your - savings. + Our solar specialists will take a survey of your property and + define specific requirements in your area. Then, we’ll design a + solar energy system to maximize your savings.

@@ -185,9 +192,10 @@ By default the caret is on the right. You can render the caret on the left side

- We work on your behalf to navigate state and municipal requirements, homeowners - associations, and utility paperwork—moving your project from design to install with - the ultimate efficiency. + We work on your behalf to navigate state and municipal + requirements, homeowners associations, and utility + paperwork—moving your project from design to install with the + ultimate efficiency.

@@ -236,9 +244,10 @@ You can also choose to hide the caret altogether. Moreover, the accordion is a v

- Together, we’ll clarify your goals, address any questions, identify purchase options - and incentives, and outline the solar process—placing you in the driver’s seat for - everything moving forward. + Together, we’ll clarify your goals, address any questions, + identify purchase options and incentives, and outline the solar + process—placing you in the driver’s seat for everything moving + forward.

@@ -252,9 +261,9 @@ You can also choose to hide the caret altogether. Moreover, the accordion is a v

- Our solar specialists will take a survey of your property and define specific - requirements in your area. Then, we’ll design a solar energy system to maximize your - savings. + Our solar specialists will take a survey of your property and + define specific requirements in your area. Then, we’ll design a + solar energy system to maximize your savings.

@@ -268,9 +277,10 @@ You can also choose to hide the caret altogether. Moreover, the accordion is a v

- We work on your behalf to navigate state and municipal requirements, homeowners - associations, and utility paperwork—moving your project from design to install with - the ultimate efficiency. + We work on your behalf to navigate state and municipal + requirements, homeowners associations, and utility + paperwork—moving your project from design to install with the + ultimate efficiency.

diff --git a/src/components/Accordion/AccordionPanel.tsx b/src/components/Accordion/AccordionPanel.tsx index b531808de..10be4628f 100644 --- a/src/components/Accordion/AccordionPanel.tsx +++ b/src/components/Accordion/AccordionPanel.tsx @@ -6,7 +6,7 @@ export type AccordionPanelProps = DetailsProps; export const AccordionPanel: React.FC = ({ children, borderWidth = '0 0 xs 0', - borderColor = 'grey-100', + borderColor = 'separator', ...restProps }) => (
diff --git a/src/components/Accordion/AccordionPanelSummary.tsx b/src/components/Accordion/AccordionPanelSummary.tsx index d6ce3de65..c36b300d3 100644 --- a/src/components/Accordion/AccordionPanelSummary.tsx +++ b/src/components/Accordion/AccordionPanelSummary.tsx @@ -30,7 +30,7 @@ export const AccordionPanelSummary: React.FC = ({ )} @@ -39,7 +39,7 @@ export const AccordionPanelSummary: React.FC = ({ )} diff --git a/src/components/Alert/Alert.Overview.stories.mdx b/src/components/Alert/Alert.Overview.stories.mdx index f6603f3ad..f4b4a5144 100644 --- a/src/components/Alert/Alert.Overview.stories.mdx +++ b/src/components/Alert/Alert.Overview.stories.mdx @@ -186,102 +186,3 @@ Renders a version of the banner with less padding. ; - -## Custom Theme - -The Alert component can be themed by base tokens, or component specific tokens. - - - - <> -
- -
-
- - -
- -
-
- -## Component Design Tokens - - - - - - - - - - {(() => { - const tokens = { - '--alert-default-background-color': '--color-brand-grey-100', - '--alert-default-font-color': '--color-brand-grey-600', - '--alert-default-icon-color': '--color-brand-grey-600', - '--alert-default-border-color': '--color-brand-grey-200', - '--alert-info-background-color': '--color-brand-info-50', - '--alert-info-font-color': '--color-brand-grey-600', - '--alert-info-icon-color': '--color-brand-info-500', - '--alert-info-border-color': '--color-brand-info-200', - '--alert-success-background-color': '--color-brand-success-50', - '--alert-success-font-color': '--color-brand-grey-600', - '--alert-success-icon-color': '--color-brand-success-500', - '--alert-success-border-color': '--color-brand-success-200', - '--alert-warning-background-color': '--color-brand-warning-50', - '--alert-warning-font-color': '--color-brand-grey-600', - '--alert-warning-icon-color': '--color-brand-warning-500', - '--alert-warning-border-color': '--color-brand-warning-200', - '--alert-danger-background-color': '--color-brand-danger-50', - '--alert-danger-font-color': '--color-brand-grey-600', - '--alert-danger-icon-color': '--color-brand-danger-500', - '--alert-danger-border-color': '--color-brand-danger-200', - '--alert-border-width': '--size-border-xs', - '--alert-border-color': 'transparent', - '--alert-box-shadow': '--size-box-shadow-0', - }; - return Object.entries(tokens).map(([name, entry], i) => ( - - - - - )); - })()} - -
token namedefault value
- {name} - - {entry} -
diff --git a/src/components/Alert/Alert.module.scss b/src/components/Alert/Alert.module.scss index f532b02e2..c8d39a272 100644 --- a/src/components/Alert/Alert.module.scss +++ b/src/components/Alert/Alert.module.scss @@ -1,7 +1,7 @@ .alert { - border-width: var(--alert-border-width, var(--size-border-xs)); + border-width: var(--size-border-xs); border-style: solid; - box-shadow: var(--alert-box-shadow, var(--size-box-shadow-0)); + box-shadow: var(--size-box-shadow-0); .close-icon { > button { @@ -11,46 +11,42 @@ padding: 0; color: inherit; font: inherit; - - &:hover { - color: var(--color-brand-grey-600); - } } } } .alert__default { - color: var(--alert-default-font-color, var(--color-brand-grey-600)); - background: var(--alert-default-background-color, var(--color-brand-grey-100)); - border-color: var(--alert-default-border-color, var(--color-brand-grey-200)); + color: var(--color-text-body-primary); + background: var(--color-background-default); + border-color: var(--color-border-default); } .alert__info { - color: var(--alert-info-font-color, var(--color-brand-grey-600)); - background: var(--alert-info-background-color, var(--color-brand-info-50)); - border-color: var(--alert-info-border-color, var(--color-brand-info-200)); + color: var(--color-text-body-primary); + background: var(--color-background-info); + border-color: var(--color-border-info); } .alert__success { - color: var(--alert-success-font-color, var(--color-brand-grey-600)); - background: var(--alert-success-background-color, var(--color-brand-success-50)); - border-color: var(--alert-success-border-color, var(--color-brand-success-200)); + color: var(--color-text-body-primary); + background: var(--color-background-success); + border-color: var(--color-border-success); } .alert__warning { - color: var(--alert-warning-font-color, var(--color-brand-grey-600)); - background: var(--alert-warning-background-color, var(--color-brand-warning-50)); - border-color: var(--alert-warning-border-color, var(--color-brand-warning-200)); + color: var(--color-text-body-primary); + background: var(--color-background-warning); + border-color: var(--color-border-warning); } .alert__danger { - color: var(--alert-danger-font-color, var(--color-brand-grey-600)); - background: var(--alert-danger-background-color, var(--color-brand-danger-50)); - border-color: var(--alert-danger-border-color, var(--color-brand-danger-200)); + color: var(--color-text-body-primary); + background: var(--color-background-danger); + border-color: var(--color-border-danger); } -.alert__icon__default { color: var(--alert-default-icon-color, var(--color-brand-grey-600)); } -.alert__icon__info { color: var(--alert-info-icon-color, var(--color-brand-info-500)); } -.alert__icon__success { color: var(--alert-success-icon-color, var(--color-brand-success-500)); } -.alert__icon__warning { color: var(--alert-warning-icon-color, var(--color-brand-warning-500)); } -.alert__icon__danger { color: var(--alert-danger-icon-color, var(--color-brand-danger-500)); } +.alert__icon__default { color: var(--color-text-alert-icon-default); } +.alert__icon__info { color: var(--color-text-alert-icon-info); } +.alert__icon__success { color: var(--color-text-alert-icon-success); } +.alert__icon__warning { color: var(--color-text-alert-icon-warning); } +.alert__icon__danger { color: var(--color-text-alert-icon-danger); } diff --git a/src/components/Alert/Alert.tsx b/src/components/Alert/Alert.tsx index f72cb68d5..b63750f3f 100644 --- a/src/components/Alert/Alert.tsx +++ b/src/components/Alert/Alert.tsx @@ -93,9 +93,9 @@ export const Alert: FC = ({ }; return ( - + ); diff --git a/src/components/Badge/Badge.Overview.stories.mdx b/src/components/Badge/Badge.Overview.stories.mdx index 682e86edf..df8b5b001 100644 --- a/src/components/Badge/Badge.Overview.stories.mdx +++ b/src/components/Badge/Badge.Overview.stories.mdx @@ -85,69 +85,3 @@ so the badge can be a different size per breakpoint. }} - -## Component Design Tokens - - - - - - - - - - {(() => { - const tokens = { - '--badge-border-radius': '--size-border-radius-sm', - '--badge-border-width': '--size-border-xs', - '--badge-font-weight': '--size-font-weight-bold', - '--badge-size-sm-font-size': '--size-font-2xs', - '--badge-size-sm-padding-vertical': '--size-spacing-2xs', - '--badge-size-sm-padding-horizontal': '--size-spacing-2xs', - '--badge-size-md-font-size': '--size-font-xs', - '--badge-size-md-padding-vertical': '--size-spacing-2xs', - '--badge-size-md-padding-horizontal': '--size-spacing-xs', - '--badge-size-lg-font-size': '--size-font-sm', - '--badge-size-lg-padding-vertical': '--size-spacing-2xs', - '--badge-size-lg-padding-horizontal': '--size-spacing-xs', - '--badge-size-xl-font-size': '--size-font-md', - '--badge-size-xl-padding-vertical': '--size-spacing-xs', - '--badge-size-xl-padding-horizontal': '--size-spacing-sm', - '--badge-primary-background-color': '--color-brand-primary-100', - '--badge-primary-border-color': '--color-brand-grey-200', - '--badge-primary-font-color': '--color-brand-grey-700', - '--badge-secondary-background-color': '--color-brand-secondary-100', - '--badge-secondary-border-color': '--color-brand-grey-200', - '--badge-secondary-font-color': '--color-brand-grey-700', - '--badge-tertiary-background-color': '--color-brand-tertiary-100', - '--badge-tertiary-border-color': '--color-brand-tertiary-200', - '--badge-tertiary-font-color': '--color-brand-grey-700', - '--badge-success-background-color': '--color-brand-success-100', - '--badge-success-border-color': '--color-brand-success-200', - '--badge-success-font-color': '--color-brand-grey-700', - '--badge-danger-background-color': '--color-brand-danger-100', - '--badge-danger-border-color': '--color-brand-danger-200', - '--badge-danger-font-color': '--color-brand-grey-700', - '--badge-info-background-color': '--color-brand-info-100', - '--badge-info-border-color': '--color-brand-border-200', - '--badge-info-font-color': '--color-brand-grey-700', - '--badge-warning-background-color': '--color-brand-warning-100', - '--badge-warning-border-color': '--color-brand-warning-200', - '--badge-warning-font-color': '--color-brand-grey-700', - '--badge-default-background-color': '--color-brand-grey-100', - '--badge-default-border-color': '--color-brand-grey-200', - '--badge-default-font-color': '--color-brand-grey-700', - }; - return Object.entries(tokens).map(([name, entry], i) => ( - - - - - )); - })()} - -
token namedefault value
- {name} - - {entry} -
diff --git a/src/components/Badge/Badge.module.scss b/src/components/Badge/Badge.module.scss index b5fb6253c..56268efb9 100644 --- a/src/components/Badge/Badge.module.scss +++ b/src/components/Badge/Badge.module.scss @@ -1,96 +1,113 @@ @import '~@palmetto/palmetto-design-tokens/build/scss/variables-size'; @mixin size-sm { - font-size: var(--badge-size-sm-font-size, var(--size-font-2xs)); - padding: var(--badge-size-sm-padding-vertical, var(--size-spacing-2xs)) - var(--badge-size-sm-padding-horizontal, var(--size-spacing-2xs)); + font-size: var(--size-font-2xs); + padding: var(--size-spacing-2xs) var(--size-spacing-2xs); } -%size-sm { @include size-sm; } -.size-sm { @extend %size-sm; } +%size-sm { + @include size-sm; +} + +.size-sm { + @extend %size-sm; +} @mixin size-md { - font-size: var(--badge-size-md-font-size, var(--size-font-xs)); - padding: var(--badge-size-md-padding-vertical, var(--size-spacing-2xs)) - var(--badge-size-md-padding-horizontal, var(--size-spacing-xs)); + font-size: var(--size-font-xs); + padding: var(--size-spacing-2xs) var(--size-spacing-xs); } -%size-md { @include size-md; } -.size-md { @extend %size-md; } +%size-md { + @include size-md; +} + +.size-md { + @extend %size-md; +} @mixin size-lg { - font-size: var(--badge-size-lg-font-size, var(--size-font-sm)); - padding: var(--badge-size-lg-padding-vertical, var(--size-spacing-2xs)) - var(--badge-size-lg-padding-horizontal, var(--size-spacing-xs)); + font-size: var(--size-font-sm); + padding: var(--size-spacing-2xs) var(--size-spacing-xs); +} + +%size-lg { + @include size-lg; } -%size-lg { @include size-lg; } -.size-lg { @extend %size-lg; } +.size-lg { + @extend %size-lg; +} @mixin size-xl { - font-size: var(--badge-size-xl-font-size, var(--size-font-md)); - padding: var(--badge-size-xl-padding-vertical, var(--size-spacing-xs)) - var(--badge-size-xl-padding-horizontal, var(--size-spacing-sm)); + font-size: var(--size-font-md); + padding: var(--size-spacing-xs) var(--size-spacing-sm); } -%size-xl { @include size-xl; } -.size-xl { @extend %size-xl; } +%size-xl { + @include size-xl; +} + +.size-xl { + @extend %size-xl; +} .badge { - border-radius: var(--badge-border-radius, var(--size-border-radius-sm)); + border-radius: var(--size-border-radius-sm); border-style: solid; - border-width: var(--badge-border-width, var(--size-border-xs)); - text-transform: uppercase; + border-width: var(--size-border-xs); + font-family: var(--asset-fonts-body); + font-weight: var(--size-font-weight-bold); letter-spacing: 0.8px; - font-weight: var(--badge-font-weight, var(--size-font-weight-bold)); line-height: var(--size-line-height-base); + text-transform: uppercase; &.primary { - background-color: var(--badge-primary-background-color, var(--color-brand-primary-100)); - border-color: var(--badge-primary-border-color, var(--color-brand-primary-200)); - color: var(--badge-primary-font-color, var(--color-brand-grey-700)); + background-color: var(--color-background-badge-primary); + border-color: var(--color-border-badge-primary); + color: var(--color-text-badge-primary); } &.secondary { - background-color: var(--badge-secondary-background-color, var(--color-brand-secondary-100)); - border-color: var(--badge-secondary-border-color, var(--color-brand-secondary-200)); - color: var(--badge-secondary-font-color, var(--color-brand-grey-700)); + background-color: var(--color-background-badge-secondary); + border-color: var(--color-border-badge-secondary); + color: var(--color-text-badge-secondary); } &.tertiary { - background-color: var(--badge-tertiary-background-color, var(--color-brand-tertiary-100)); - border-color: var(--badge-tertiary-border-color, var(--color-brand-tertiary-200)); - color: var(--badge-tertiary-font-color, var(--color-brand-grey-700)); + background-color: var(--color-background-badge-tertiary); + border-color: var(--color-border-badge-tertiary); + color: var(--color-text-badge-tertiary); } &.success { - background-color: var(--badge-success-background-color, var(--color-brand-success-100)); - border-color: var(--badge-success-border-color, var(--color-brand-success-200)); - color: var(--badge-success-font-color, var(--color-brand-grey-700)); + background-color: var(--color-background-badge-success); + border-color: var(--color-border-badge-success); + color: var(--color-text-badge-success); } &.danger { - background-color: var(--badge-danger-background-color, var(--color-brand-danger-100)); - border-color: var(--badge-danger-border-color, var(--color-brand-danger-200)); - color: var(--badge-danger-font-color, var(--color-brand-grey-700)); + background-color: var(--color-background-badge-danger); + border-color: var(--color-border-badge-danger); + color: var(--color-text-badge-danger); } &.info { - background-color: var(--badge-info-background-color, var(--color-brand-info-100)); - border-color: var(--badge-info-border-color, var(--color-brand-info-200)); - color: var(--badge-info-font-color, var(--color-brand-grey-700)); + background-color: var(--color-background-badge-info); + border-color: var(--color-border-badge-info); + color: var(--color-text-badge-info); } &.warning { - background-color: var(--badge-warning-background-color, var(--color-brand-warning-100)); - border-color: var(--badge-warning-border-color, var(--color-brand-warning-200)); - color: var(--badge-warning-font-color, var(--color-brand-grey-700)); + background-color: var(--color-background-badge-warning); + border-color: var(--color-border-badge-warning); + color: var(--color-text-badge-warning); } &.default { - background-color: var(--badge-default-background-color, var(--color-brand-grey-100)); - border-color: var(--badge-default-border-color, var(--color-brand-grey-200)); - color: var(--badge-default-font-color, var(--color-brand-grey-700)); + background-color: var(--color-background-badge-default); + border-color: var(--color-border-badge-default); + color: var(--color-text-badge-default); } &.size-sm { diff --git a/src/components/Badge/Badge.tsx b/src/components/Badge/Badge.tsx index 25f312151..4b1cbdd3f 100644 --- a/src/components/Badge/Badge.tsx +++ b/src/components/Badge/Badge.tsx @@ -45,17 +45,6 @@ export interface BadgeProps { [x: string]: any; // eslint-disable-line } -export const BADGE_COLOR_MAP: { [key in BadgeVariant]: BadgeColorAttributes } = { - info: { font: 'dark-500', background: 'info-100' }, - primary: { font: 'dark-500', background: 'primary-100' }, - success: { font: 'dark-500', background: 'success-100' }, - secondary: { font: 'dark-500', background: 'secondary-100' }, - warning: { font: 'dark-500', background: 'warning-100' }, - tertiary: { font: 'dark-500', background: 'tertiary-100' }, - danger: { font: 'dark-500', background: 'danger-100' }, - default: { font: 'dark-500', background: 'grey-100' }, -}; - export const Badge: FC = ({ className = '', message = '', diff --git a/src/components/Box/Box.Overview.stories.mdx b/src/components/Box/Box.Overview.stories.mdx index ca28cb977..89bce3c60 100644 --- a/src/components/Box/Box.Overview.stories.mdx +++ b/src/components/Box/Box.Overview.stories.mdx @@ -7,7 +7,6 @@ import { FONT_FAMILY_OPTIONS, FONT_FAMILY_VALUES, FONT_COLOR_OPTIONS, - BRAND_COLOR_NAMES, SPACING_OPTIONS, } from '../../lib/tokens'; @@ -26,7 +25,7 @@ A `` is a layout component to build UIs with consistent padding and spacing - - secondary-lighter - - - danger-lightest - - - primary + + + primary + + + secondary + + + tertiary + + + inverse + + + default + + + info + + + success + + + warning + + + danger + @@ -73,33 +92,41 @@ Use the `borderColor` prop to set the color of the border and the borderWidth to - - grey-lighter, xs md + + separator + + + success, 0 sm md xs + + + default, md + + + info, md - - danger, 0 sm md xs + + warning, md - - primary-darker, md + + danger, md - ## Gap Use `gap` to set the spacing between children of a Box (for display grid and flex). - + - - - - - - + + + + + + @@ -108,39 +135,39 @@ Use `gap` to set the spacing between children of a Box (for display grid and fle Use `rowGap` and `columnGap` to set the spacing between children of a Box (for display grid and flex) in the row and column directions independently. You can also use shorthand `gap` to set both at once (e.g. `gap="row col"`). - + - - - - - - + + + + + + - + - - - - - - + + + + + + - - - + + + - - - + + + @@ -153,16 +180,15 @@ For block layouts, you can use `childGap` to set the spacing between children of - - - - - + + + + + - ## Flex Properties ### Flex @@ -180,7 +206,7 @@ passing using a standard `style` object with the `flex` shorthand you need. - + 1 - + 2 - + 3 - + 4 - + 5 @@ -258,19 +284,19 @@ Set direction of child elements in a flex container. Column - + 1 - + 2 - + 3 - + 4 - + 5 @@ -278,19 +304,19 @@ Set direction of child elements in a flex container. Row Reverse - + 1 - + 2 - + 3 - + 4 - + 5 @@ -298,19 +324,19 @@ Set direction of child elements in a flex container. Column Reverse - + 1 - + 2 - + 3 - + 4 - + 5 @@ -318,39 +344,19 @@ Set direction of child elements in a flex container. Row Reverse - + 1 - + 2 - + 3 - + 4 - + 5 @@ -358,39 +364,19 @@ Set direction of child elements in a flex container. Column Reverse - + 1 - + 2 - + 3 - + 4 - + 5 @@ -403,7 +389,7 @@ Set direction of child elements in a flex container. start - - - + + + center - - - + + + end - - - + + + between - - - + + + around - - - + + + evenly - - - + + + @@ -558,14 +544,14 @@ Set content alignment along the cross axis. - - - + + + @@ -573,14 +559,14 @@ Set content alignment along the cross axis. - - - + + + @@ -588,14 +574,14 @@ Set content alignment along the cross axis. - - - + + + @@ -603,14 +589,14 @@ Set content alignment along the cross axis. - - - + + + @@ -618,14 +604,14 @@ Set content alignment along the cross axis. - - - + + + @@ -650,14 +636,14 @@ This property has no effect when there is only one line of flex items. height="200px" wrap gap="md" - background="primary-lighter" + background="primary-100" direction="row" > - - - - - + + + + + @@ -670,14 +656,14 @@ This property has no effect when there is only one line of flex items. height="200px" wrap gap="md" - background="primary-lighter" + background="primary-100" direction="row" > - - - - - + + + + + @@ -690,14 +676,14 @@ This property has no effect when there is only one line of flex items. height="200px" wrap gap="md" - background="primary-lighter" + background="primary-100" direction="row" > - - - - - + + + + + @@ -710,17 +696,17 @@ This property has no effect when there is only one line of flex items. height="200px" wrap gap="md" - background="primary-lighter" + background="primary-100" direction="row" > - - - - - + + + + + - + between @@ -730,14 +716,14 @@ This property has no effect when there is only one line of flex items. height="200px" wrap gap="md" - background="primary-lighter" + background="primary-100" direction="row" > - - - - - + + + + + @@ -750,14 +736,14 @@ This property has no effect when there is only one line of flex items. height="200px" wrap gap="md" - background="primary-lighter" + background="primary-100" direction="row" > - - - - - + + + + + @@ -770,9 +756,18 @@ Use the `color` prop to set the color of the text - Danger 500 - Info 500 - Default Color + + body-primary + body-secondary + body-tertiary + contrast + inverse-primary + inverse-secondary + primary + success + info + disabled + @@ -802,7 +797,12 @@ Set the `fontSize` prop with a [font size](?path=/story/design-tokens-design-tok Brand Font {FONT_FAMILY_VALUES['brand'].value} - + Monospace Font {FONT_FAMILY_VALUES['monospace'].value} @@ -851,19 +851,19 @@ The `margin` prop accepts a single [spacing](?path=/story/design-tokens-design-t - + lg margin - + lg vertical and md horizontal - + 0 vertical and 2xl horizontal - + sm top, md horizontal, 2xl bottom - + sm top, lg right, 2xl bottom, 0 left @@ -875,19 +875,19 @@ The `padding` prop accepts a single [spacing](?path=/story/design-tokens-design- - + lg padding - + lg vertical and md horizontal - + 0 vertical and 2xl horizontal - + sm top, md horizontal, 2xl bottom - + sm top, lg right, 2xl bottom, 0 left @@ -900,34 +900,34 @@ Set the `radius` prop with a [radius token](?path=/story/design-tokens-design-to - + xs - + sm - + md - + lg - + circle - + sm lg - + sm md lg - + xs sm md lg - + 0 0 md md - + md md 0 0 @@ -950,7 +950,7 @@ Set the `shadow` prop with a [shadow token](?path=/story/design-tokens-design-to shadow="0" alignItems="center" justifyContent="center" - background="white" + background="primary" radius="md" padding="sm" height="lg" @@ -961,7 +961,7 @@ Set the `shadow` prop with a [shadow token](?path=/story/design-tokens-design-to shadow="2xs" alignItems="center" justifyContent="center" - background="white" + background="primary" radius="md" padding="sm" height="lg" @@ -972,7 +972,7 @@ Set the `shadow` prop with a [shadow token](?path=/story/design-tokens-design-to shadow="xs" alignItems="center" justifyContent="center" - background="white" + background="primary" radius="md" padding="sm" height="lg" @@ -983,7 +983,7 @@ Set the `shadow` prop with a [shadow token](?path=/story/design-tokens-design-to shadow="sm" alignItems="center" justifyContent="center" - background="white" + background="primary" radius="md" padding="sm" height="lg" @@ -994,7 +994,7 @@ Set the `shadow` prop with a [shadow token](?path=/story/design-tokens-design-to shadow="md" alignItems="center" justifyContent="center" - background="white" + background="primary" radius="md" padding="sm" height="lg" @@ -1005,7 +1005,7 @@ Set the `shadow` prop with a [shadow token](?path=/story/design-tokens-design-to shadow="lg" alignItems="center" justifyContent="center" - background="white" + background="primary" radius="md" padding="sm" height="lg" @@ -1016,7 +1016,7 @@ Set the `shadow` prop with a [shadow token](?path=/story/design-tokens-design-to shadow="xl" alignItems="center" justifyContent="center" - background="white" + background="primary" radius="md" padding="sm" height="lg" @@ -1027,7 +1027,7 @@ Set the `shadow` prop with a [shadow token](?path=/story/design-tokens-design-to shadow="2xl" alignItems="center" justifyContent="center" - background="white" + background="primary" radius="md" padding="sm" height="lg" @@ -1044,14 +1044,14 @@ Width can be set to any CSS unit value (px, rem, em, %). - - + + 227px - + 10rem - + 50% @@ -1062,29 +1062,29 @@ Width can be set to any CSS unit value (px, rem, em, %). - - + + sm - + md - + lg - + xl - + 2xl - + 3xl - + 4xl - + 5xl @@ -1095,50 +1095,50 @@ Set the width to a common percentage of the Box's parent. - - + + 10% - + 15% - + 20% - + 25% - + 30% - + 33% - + 34% - + 40% - + 50% - + 60% - + 70% - + 75% - + 80% - + 90% - + 100% @@ -1151,14 +1151,14 @@ Set the maximum width of the Box by setting `maxWidth` to a [width token](?path= - - + + 2xl - + 145px - + 50% @@ -1171,14 +1171,14 @@ Set the minimum width of the Box by setting `minWidth` to a [width token](?path= - - + + 2xl - + 145px - + 50% @@ -1191,9 +1191,9 @@ Height can be set to any CSS unit value (px, rem, em, %). - + - + - + 10% @@ -1329,7 +1319,7 @@ Set the height to a common percentage of the Box's parent. flex="auto" justifyContent="center" alignItems="center" - background="primary-light" + background="primary-300" height="15" > 15% @@ -1338,7 +1328,7 @@ Set the height to a common percentage of the Box's parent. flex="auto" justifyContent="center" alignItems="center" - background="primary-light" + background="primary-300" height="20" > 20% @@ -1347,7 +1337,7 @@ Set the height to a common percentage of the Box's parent. flex="auto" justifyContent="center" alignItems="center" - background="primary-light" + background="primary-300" height="25" > 25% @@ -1356,7 +1346,7 @@ Set the height to a common percentage of the Box's parent. flex="auto" justifyContent="center" alignItems="center" - background="primary-light" + background="primary-300" height="30" > 30% @@ -1365,7 +1355,7 @@ Set the height to a common percentage of the Box's parent. flex="auto" justifyContent="center" alignItems="center" - background="primary-light" + background="primary-300" height="33" > 33% @@ -1374,7 +1364,7 @@ Set the height to a common percentage of the Box's parent. flex="auto" justifyContent="center" alignItems="center" - background="primary-light" + background="primary-300" height="34" > 34% @@ -1383,7 +1373,7 @@ Set the height to a common percentage of the Box's parent. flex="auto" justifyContent="center" alignItems="center" - background="primary-light" + background="primary-300" height="40" > 40% @@ -1392,7 +1382,7 @@ Set the height to a common percentage of the Box's parent. flex="auto" justifyContent="center" alignItems="center" - background="primary-light" + background="primary-300" height="50" > 50% @@ -1401,7 +1391,7 @@ Set the height to a common percentage of the Box's parent. flex="auto" justifyContent="center" alignItems="center" - background="primary-light" + background="primary-300" height="60" > 60% @@ -1410,7 +1400,7 @@ Set the height to a common percentage of the Box's parent. flex="auto" justifyContent="center" alignItems="center" - background="primary-light" + background="primary-300" height="70" > 70% @@ -1419,7 +1409,7 @@ Set the height to a common percentage of the Box's parent. flex="auto" justifyContent="center" alignItems="center" - background="primary-light" + background="primary-300" height="75" > 75% @@ -1428,7 +1418,7 @@ Set the height to a common percentage of the Box's parent. flex="auto" justifyContent="center" alignItems="center" - background="primary-light" + background="primary-300" height="80" > 80% @@ -1437,7 +1427,7 @@ Set the height to a common percentage of the Box's parent. flex="auto" justifyContent="center" alignItems="center" - background="primary-light" + background="primary-300" height="90" > 90% @@ -1446,7 +1436,7 @@ Set the height to a common percentage of the Box's parent. flex="auto" justifyContent="center" alignItems="center" - background="primary-light" + background="primary-300" height="100" > 100% @@ -1461,18 +1451,13 @@ Set the maximum width of the Box by setting `maxHeight` to a [height token](?pat - + lg @@ -1481,7 +1466,7 @@ Set the maximum width of the Box by setting `maxHeight` to a [height token](?pat flex="auto" justifyContent="center" alignItems="center" - background="primary-light" + background="primary-300" > 50px @@ -1490,7 +1475,7 @@ Set the maximum width of the Box by setting `maxHeight` to a [height token](?pat flex="auto" justifyContent="center" alignItems="center" - background="primary-light" + background="primary-300" > 50% @@ -1506,7 +1491,7 @@ Set the minimum width of the Box by setting `minHeight` to a [height token](?pat 3xl @@ -1525,7 +1510,7 @@ Set the minimum width of the Box by setting `minHeight` to a [height token](?pat minHeight="50px" justifyContent="center" alignItems="center" - background="primary-light" + background="primary-300" > 50px @@ -1534,7 +1519,7 @@ Set the minimum width of the Box by setting `minHeight` to a [height token](?pat minHeight="50%" justifyContent="center" alignItems="center" - background="primary-light" + background="primary-300" > 50% @@ -1553,7 +1538,7 @@ Set the overflow behavior of the Box with `overflow` padding="md" gap="md" flex="auto" - background="primary-lighter" + background="primary-100" borderColor="grey" height="100px" > @@ -1591,25 +1576,25 @@ Set the cursor for value for the element in question. Use any valid [CSS cursor padding="md" gap="md" flex="auto" - background="primary-lighter" + background="primary-100" overflow="auto" > - + pointer - + move - + not-allowed - + grab - + zoom-in - + zoom-out @@ -1627,14 +1612,14 @@ responsive object prop with said values. Example with `fixed` position not inclu padding="md" childGap="md" display="block" - background="primary-lighter" + background="primary-100" overflow="scroll" height="300px" > @@ -1653,7 +1638,7 @@ responsive object prop with said values. Example with `fixed` position not inclu static @@ -1687,15 +1672,15 @@ Currently our library supports hover states for: - `shadow` - + @@ -1703,16 +1688,16 @@ Currently our library supports hover states for: - + - +

This box will have no padding until the viewport reaches the desktop breakpoint.{' '} diff --git a/src/components/Box/Box.Playground.stories.tsx b/src/components/Box/Box.Playground.stories.tsx index 000ef4aa4..672ed4bbe 100644 --- a/src/components/Box/Box.Playground.stories.tsx +++ b/src/components/Box/Box.Playground.stories.tsx @@ -2,6 +2,7 @@ import React from 'react'; import { Meta, Story } from '@storybook/react/types-6-0'; import { Box, BoxProps } from './Box'; import { + BACKGROUND_COLOR_OPTIONS, BORDER_SIZE_OPTIONS, BORDER_RADIUS_OPTIONS, BOX_SHADOW_OPTIONS, @@ -85,7 +86,14 @@ export default { alignItems: { control: { type: 'select', - options: [null, 'flex-start', 'flex-end', 'center', 'baseline', 'stretch'], + options: [ + null, + 'flex-start', + 'flex-end', + 'center', + 'baseline', + 'stretch', + ], }, }, justifyContent: { @@ -287,7 +295,7 @@ export default { background: { control: { type: 'select', - options: [null, ...BRAND_COLOR_OPTIONS], + options: [null, ...BACKGROUND_COLOR_OPTIONS], }, }, radius: { @@ -360,7 +368,7 @@ export default { childBackground: { control: { type: 'select', - options: [null, ...BRAND_COLOR_OPTIONS], + options: [null, ...BACKGROUND_COLOR_OPTIONS], }, }, className: { @@ -447,12 +455,12 @@ const Template: Story = ({ export const Playground = Template.bind({}); Playground.args = { - background: 'info-300', + background: 'inverse', direction: 'row', childWidth: 'lg', childHeight: 'lg', gap: 'sm', padding: 'lg', width: '100', - childBackground: 'white', + childBackground: 'primary', }; diff --git a/src/components/Box/Box.VisualTests.stories.tsx b/src/components/Box/Box.VisualTests.stories.tsx index 3a9017ea0..a9b3f9f9f 100644 --- a/src/components/Box/Box.VisualTests.stories.tsx +++ b/src/components/Box/Box.VisualTests.stories.tsx @@ -2,16 +2,18 @@ /* eslint-disable no-else-return */ import React from 'react'; import { Meta, Story } from '@storybook/react/types-6-0'; + import { Box, BoxProps } from './Box'; import { + BORDER_COLOR_OPTIONS, FONT_SIZE_OPTIONS, FONT_COLOR_OPTIONS, - BRAND_COLOR_NAMES, SPACING_OPTIONS, FONT_FAMILY_OPTIONS, FONT_WEIGHT_OPTIONS, + BACKGROUND_COLOR_OPTIONS, } from '../../lib/tokens'; -import { BrandColor } from '../../types'; +import { BackgroundColor, BorderColor } from '../../types'; import { RESPONSIVE_STORY } from '../../docs/constants'; import { ResponsiveProvider } from '../ResponsiveProvider/ResponsiveProvider'; import { useBreakpoint } from '../../hooks/useBreakpoint/useBreakpoint'; @@ -22,214 +24,22 @@ export default { } as Meta; export const AllBackgroundColors: React.FunctionComponent = () => ( - - {BRAND_COLOR_NAMES.map((color, index) => { - if (color.includes('inherit')) return null; - else if ( - color === 'dark' - || color === 'light' - || color === 'black' - || color === 'white' - || color === 'transparent' - ) { - return ( - - {`${color}`} - - ); - } else { - return ( - - - {`${color}-50`} - - - {`${color}-100`} - - - {`${color}-200`} - - - {`${color}-300`} - - - {`${color}-400`} - - - {`${color}-500`} - - - {`${color}-600`} - - - {`${color}-700`} - - - {`${color}-800`} - - - {`${color}-900`} - - - ); - } - })} + + {BACKGROUND_COLOR_OPTIONS.map((color: BackgroundColor, index: number) => ( + + {color} + + ))} ); export const AllBorderColors: React.FunctionComponent = () => ( - - {BRAND_COLOR_NAMES.map((color, index) => { - if (color.includes('inherit')) return null; - else if ( - color === 'dark' - || color === 'light' - || color === 'black' - || color === 'white' - || color === 'transparent' - ) { - return ( - - {`${color}`} - - ); - } else { - return ( - - - {`${color}-50`} - - - {`${color}-100`} - - - {`${color}-200`} - - - {`${color}-300`} - - - {`${color}-400`} - - - {`${color}-500`} - - - {`${color}-600`} - - - {`${color}-700`} - - - {`${color}-800`} - - - {`${color}-900`} - - - ); - } - })} + + {BORDER_COLOR_OPTIONS.map((color: BorderColor, index: number) => ( + + {color} + + ))} ); @@ -237,19 +47,19 @@ export const AllGap: React.FunctionComponent = () => ( {[...SPACING_OPTIONS].map((spacing, i) => ( - + {spacing} - + {spacing} - + {spacing} - + {spacing} - + {spacing} @@ -261,19 +71,19 @@ export const AllRowGap: React.FunctionComponent = () => ( {[...SPACING_OPTIONS].map((spacing, i) => ( - + {spacing} - + {spacing} - + {spacing} - + {spacing} - + {spacing} @@ -285,19 +95,19 @@ export const AllColumnGap: React.FunctionComponent = () => ( {[...SPACING_OPTIONS].map((spacing, i) => ( - + {spacing} - + {spacing} - + {spacing} - + {spacing} - + {spacing} @@ -309,19 +119,19 @@ export const AllRowChildGap: React.FunctionComponent = () => ( {[...SPACING_OPTIONS].map((spacing, i) => ( - + {spacing} - + {spacing} - + {spacing} - + {spacing} - + {spacing} @@ -333,19 +143,19 @@ export const AllColumnChildGap: React.FunctionComponent = () => ( {[...SPACING_OPTIONS].map((spacing, i) => ( - + {spacing} - + {spacing} - + {spacing} - + {spacing} - + {spacing} @@ -389,7 +199,7 @@ export const AllFontSizesWeightsFamily: React.FunctionComponent = () = export const AllMargin: React.FunctionComponent = () => ( <> {[...SPACING_OPTIONS].map((spacing, i) => ( - + {`${spacing} margin`} ))} @@ -399,7 +209,7 @@ export const AllMargin: React.FunctionComponent = () => ( export const AllHorizontalMargin: React.FunctionComponent = () => ( <> {[...SPACING_OPTIONS].map((spacing, i) => ( - + {`${spacing} horizontal margin`} ))} @@ -409,7 +219,7 @@ export const AllHorizontalMargin: React.FunctionComponent = () => ( export const AllVerticalMargin: React.FunctionComponent = () => ( <> {[...SPACING_OPTIONS].map((spacing, i) => ( - + {`${spacing} vertical margin`} ))} @@ -419,7 +229,7 @@ export const AllVerticalMargin: React.FunctionComponent = () => ( export const AllPadding: React.FunctionComponent = () => ( <> {[...SPACING_OPTIONS].map((spacing, i) => ( - + {`${spacing} padding`} ))} @@ -431,7 +241,7 @@ export const AllHorizontalPadding: React.FunctionComponent = () => ( {[...SPACING_OPTIONS].map((spacing, i) => ( @@ -446,7 +256,7 @@ export const AllVerticalPadding: React.FunctionComponent = () => ( {[...SPACING_OPTIONS].map((spacing, i) => ( @@ -464,9 +274,7 @@ const BoxTemplate: Story = ({ propertyName, ...args }) => {

{`Breakpoint: ${activeBreakpoint.name}`}

- {`${propertyName}: ${ - args[propertyName][activeBreakpoint.name] - }`} + {`${propertyName}: ${args[propertyName][activeBreakpoint.name]}`}

@@ -685,9 +493,7 @@ const BoxChildrenTemplate: Story = ({ propertyName, ...args }) => { >

{`Breakpoint: ${activeBreakpoint.name}`}

- {`${propertyName}: ${ - args[propertyName][activeBreakpoint.name] - }`} + {`${propertyName}: ${args[propertyName][activeBreakpoint.name]}`}

= ({ propertyName, ...args }) => { >

{`Breakpoint: ${activeBreakpoint.name}`}

- {`${propertyName}: ${ - args[propertyName][activeBreakpoint.name] - }`} + {`${propertyName}: ${args[propertyName][activeBreakpoint.name]}`}

= ({ propertyName, ...args }) => { >

{`Breakpoint: ${activeBreakpoint.name}`}

- {`${propertyName}: ${ - args[propertyName][activeBreakpoint.name] - }`} + {`${propertyName}: ${args[propertyName][activeBreakpoint.name]}`}

@@ -797,115 +599,115 @@ export const AllCursorOptions: React.FunctionComponent = () => ( padding="md" childGap="md" flex="auto" - background="primary-lighter" + background="primary-50" overflow="auto" > - + auto - + default - + none - + context-menu - + help - + pointer - + progress - + wait - + cell - + crosshair - + text - + vertical-text - + alias - + copy - + move - + no-drop - + not-allowed - + grab - + grabbing - + all-scroll - + col-resize - + row-resize - + n-resize - + e-resize - + s-resize - + w-resize - + ne-resize - + nw-resize - + se-resize - + sw-resize - + ew-resize - + ns-resize - + nesw-resize - + nwse-resize - + zoom-in - + zoom-out @@ -916,34 +718,34 @@ export const AllPositionOptions: React.FunctionComponent = () => ( padding="md" childGap="md" flex="auto" - background="primary-lighter" + background="primary-50" overflow="auto" > - + absolute - + relative - + sticky - + fixed - + static - + unset - + initial - + inherit - + revert diff --git a/src/components/Box/Box.tsx b/src/components/Box/Box.tsx index 948c1188a..5299704c8 100644 --- a/src/components/Box/Box.tsx +++ b/src/components/Box/Box.tsx @@ -11,11 +11,12 @@ import { import * as CSS from 'csstype'; import classNames from 'classnames'; import { + BackgroundColor, BaseSpacing, + BorderColor, BorderRadiusSize, BorderSize, BoxShadowSize, - BrandColor, BreakpointSizeWithBase, CssAlignContentValue, CssAlignItemsValue, @@ -41,7 +42,11 @@ import { getElementType } from '../../lib/getElementType'; import { generateResponsiveClasses } from '../../lib/generateResponsiveClasses'; import styles from './Box.module.scss'; -export type HoverableBoxProperties = 'color' | 'borderColor' | 'shadow' | 'background'; +export type HoverableBoxProperties = + | 'color' + | 'borderColor' + | 'shadow' + | 'background'; export interface BoxProps { /** * The element type to be rendered. @@ -62,14 +67,13 @@ export interface BoxProps { */ alignSelf?: CssAlignItemsValue | ResponsiveProp; /** - * Any valid [brand color token](/?path=/story/design-tokens-design-tokens--page#color), or a `url()` for an image + * Any valid background color, or a `url()` for an image */ - background?: BrandColor; + background?: BackgroundColor; /** - * Any valid [brand color token](/?path=/story/design-tokens-design-tokens--page#color) for the border color - * Or a responsive prop with BrandColor for each breakpoint. + * Any valid border color */ - borderColor?: BrandColor; + borderColor?: BorderColor; /** * Width of the Box's border * Can be a single [border width token](/?path=/story/design-tokens-design-tokens--page#border-width). @@ -175,7 +179,9 @@ export interface BoxProps { /** * How space between and around content items is distributed along the main-axis a flex Box */ - justifyContent?: CssJustifyContentValue | ResponsiveProp; + justifyContent?: + | CssJustifyContentValue + | ResponsiveProp; /** * Amount of space around the element. * Can be a single [spacing value](/?path=/story/design-tokens-design-tokens--page#spacing). @@ -265,269 +271,316 @@ export interface BoxProps { * A `` is a layout component to build UIs with consistent padding and spacing between * elements. */ -export const Box: FC = forwardRef(( - { - as = 'div', - alignItems = undefined, - alignContent = undefined, - alignSelf = undefined, - background = undefined, - borderColor = undefined, - borderWidth = undefined, - children = undefined, - childGap = undefined, - className = '', - color = undefined, - columnGap = undefined, - cursor = undefined, - display = 'flex', - direction = 'column', - flex = undefined, - fontFamily = undefined, - fontSize = 'inherit', - focus = undefined, - fontWeight = undefined, - gap = undefined, - height = undefined, - hover = undefined, - justifyContent = undefined, - margin = undefined, - maxHeight = undefined, - minHeight = undefined, - maxWidth = undefined, - minWidth = undefined, - overflow = undefined, - padding = undefined, - position = undefined, - radius = undefined, - rowGap = undefined, - shadow = undefined, - style = {}, - textAlign = undefined, - wrap = undefined, - width = undefined, - zIndex = undefined, - ...restProps - }, - ref, -) => { - const heightCss = getDimensionCss('h', height); - const widthCss = getDimensionCss('w', width); - const maxHeightCss = getDimensionCss('mh', maxHeight); - const maxWidthCss = getDimensionCss('mw', maxWidth); - const minHeightCss = getDimensionCss('minh', minHeight); - const minWidthCss = getDimensionCss('minw', minWidth); - - const isFlexBox = typeof display === 'string' && display.includes('flex'); - const flexDirectionClasses = isFlexBox ? generateResponsiveClasses('flex-direction', direction) : null; - - const cssPropertyMap: { - [key: string]: { - classPrefix: string; - transformer: typeof generateResponsiveClasses | typeof cssShorthandToClasses; - }; - } = { - color: { classPrefix: 'font-color', transformer: generateResponsiveClasses }, - background: { classPrefix: 'background-color', transformer: generateResponsiveClasses }, - borderColor: { classPrefix: 'border-color', transformer: generateResponsiveClasses }, - borderWidth: { classPrefix: 'border-width', transformer: cssShorthandToClasses }, - shadow: { classPrefix: 'shadow', transformer: generateResponsiveClasses }, - fontSize: { classPrefix: 'font-size', transformer: generateResponsiveClasses }, - }; - - const getStatefulClasses = (stateKey: 'hover' | 'focus', values: BoxProps['hover' | 'hover']) => values // eslint-disable-line - ? Object.entries(values).map(([key, value]) => ( - cssPropertyMap[key].transformer(`${stateKey}:${cssPropertyMap[key as keyof BoxProps['focus' | 'hover']].classPrefix}`, value) // eslint-disable-line max-len - )) - : undefined; - - const hoverClasses = getStatefulClasses('hover', hover); - const focusClasses = getStatefulClasses('focus', focus); - - const boxClasses = classNames( - className, - cssShorthandToClasses('m', margin), - cssShorthandToClasses('p', padding), - cssShorthandToClasses('br', radius), - cssShorthandToClasses('g', gap), - cssShorthandToClasses('cg', columnGap), - cssShorthandToClasses('rg', rowGap), - heightCss.classes, - maxHeightCss.classes, - minHeightCss.classes, - maxWidthCss.classes, - minWidthCss.classes, - widthCss.classes, - flexDirectionClasses, - generateResponsiveClasses('display', display), - generateResponsiveClasses('justify-content', justifyContent), - generateResponsiveClasses('align-items', alignItems), - generateResponsiveClasses('align-content', alignContent), - generateResponsiveClasses('align-self', alignSelf), - generateResponsiveClasses('font-family', fontFamily), - generateResponsiveClasses('font-size', fontSize), - generateResponsiveClasses('overflow', overflow), - generateResponsiveClasses('shadow', shadow), - generateResponsiveClasses('flex', flex), - cssShorthandToClasses('border-width', borderWidth), - generateResponsiveClasses('font-weight', fontWeight), - generateResponsiveClasses('text-align', textAlign), - generateResponsiveClasses('position', position), - generateResponsiveClasses('z-index', zIndex), - ...(hoverClasses ?? []), - ...(focusClasses ?? []), +export const Box: FC = forwardRef( + ( { - 'flex-wrap': isFlexBox && wrap, - 'flex-nowrap': isFlexBox && wrap === false, - [`background-color-${background}`]: background, - [`font-color-${color}`]: color, - [`border-color-${borderColor}`]: borderColor, - [`cursor-${cursor}`]: cursor, - [styles['box-transition']]: hover || focus, + as = 'div', + alignItems = undefined, + alignContent = undefined, + alignSelf = undefined, + background = undefined, + borderColor = undefined, + borderWidth = undefined, + children = undefined, + childGap = undefined, + className = '', + color = undefined, + columnGap = undefined, + cursor = undefined, + display = 'flex', + direction = 'column', + flex = undefined, + fontFamily = undefined, + fontSize = 'inherit', + focus = undefined, + fontWeight = undefined, + gap = undefined, + height = undefined, + hover = undefined, + justifyContent = undefined, + margin = undefined, + maxHeight = undefined, + minHeight = undefined, + maxWidth = undefined, + minWidth = undefined, + overflow = undefined, + padding = undefined, + position = undefined, + radius = undefined, + rowGap = undefined, + shadow = undefined, + style = {}, + textAlign = undefined, + wrap = undefined, + width = undefined, + zIndex = undefined, + ...restProps }, - ); - - const boxStyles = { - ...style, - ...heightCss.styles, - ...maxHeightCss.styles, - ...maxWidthCss.styles, - ...widthCss.styles, - ...minHeightCss.styles, - ...minWidthCss.styles, - }; - - /** - * Creates an object that maps the flex direction to either `right` or `bottom` - * so a margin can be applied to that side. - */ - const generateChildGapDirection = (): ResponsiveProp => { - let childGapDirection = {}; - - const getChildGapMarginDirection = (d: CssFlexDirectionValue) => { - let marginDirection = ''; - if (d?.includes('row')) marginDirection = 'right'; - else if (d?.includes('column')) marginDirection = 'bottom'; - - return marginDirection; + ref, + ) => { + const heightCss = getDimensionCss('h', height); + const widthCss = getDimensionCss('w', width); + const maxHeightCss = getDimensionCss('mh', maxHeight); + const maxWidthCss = getDimensionCss('mw', maxWidth); + const minHeightCss = getDimensionCss('minh', minHeight); + const minWidthCss = getDimensionCss('minw', minWidth); + + const isFlexBox = typeof display === 'string' && display.includes('flex'); + const flexDirectionClasses = isFlexBox + ? generateResponsiveClasses('flex-direction', direction) + : null; + + const cssPropertyMap: { + [key: string]: { + classPrefix: string; + transformer: + | typeof generateResponsiveClasses + | typeof cssShorthandToClasses; + }; + } = { + color: { + classPrefix: 'font-color', + transformer: generateResponsiveClasses, + }, + background: { + classPrefix: 'background-color', + transformer: generateResponsiveClasses, + }, + borderColor: { + classPrefix: 'border-color', + transformer: generateResponsiveClasses, + }, + borderWidth: { + classPrefix: 'border-width', + transformer: cssShorthandToClasses, + }, + shadow: { classPrefix: 'shadow', transformer: generateResponsiveClasses }, + fontSize: { + classPrefix: 'font-size', + transformer: generateResponsiveClasses, + }, }; - if (typeof direction === 'string') { - childGapDirection = { base: getChildGapMarginDirection(direction) }; - } else if (typeof direction === 'object' && direction !== null) { - childGapDirection = Object.keys(direction).reduce( - (acc, curr) => ({ - ...acc, - [curr]: getChildGapMarginDirection(direction[curr as BreakpointSizeWithBase]), - }), - {}, - ); - } + const getStatefulClasses = ( + stateKey: 'hover' | 'focus', + values: BoxProps['hover' | 'hover'], + ) => + (values // eslint-disable-line + ? Object.entries(values).map(([key, value]) => cssPropertyMap[key].transformer( + `${stateKey}:${ + cssPropertyMap[key as keyof BoxProps['focus' | 'hover']] + .classPrefix + }`, + value, + )) + : undefined); + + const hoverClasses = getStatefulClasses('hover', hover); + const focusClasses = getStatefulClasses('focus', focus); + + const boxClasses = classNames( + className, + cssShorthandToClasses('m', margin), + cssShorthandToClasses('p', padding), + cssShorthandToClasses('br', radius), + cssShorthandToClasses('g', gap), + cssShorthandToClasses('cg', columnGap), + cssShorthandToClasses('rg', rowGap), + heightCss.classes, + maxHeightCss.classes, + minHeightCss.classes, + maxWidthCss.classes, + minWidthCss.classes, + widthCss.classes, + flexDirectionClasses, + generateResponsiveClasses('display', display), + generateResponsiveClasses('justify-content', justifyContent), + generateResponsiveClasses('align-items', alignItems), + generateResponsiveClasses('align-content', alignContent), + generateResponsiveClasses('align-self', alignSelf), + generateResponsiveClasses('font-family', fontFamily), + generateResponsiveClasses('font-size', fontSize), + generateResponsiveClasses('overflow', overflow), + generateResponsiveClasses('shadow', shadow), + generateResponsiveClasses('flex', flex), + cssShorthandToClasses('border-width', borderWidth), + generateResponsiveClasses('font-weight', fontWeight), + generateResponsiveClasses('text-align', textAlign), + generateResponsiveClasses('position', position), + generateResponsiveClasses('z-index', zIndex), + ...(hoverClasses ?? []), + ...(focusClasses ?? []), + { + 'flex-wrap': isFlexBox && wrap, + 'flex-nowrap': isFlexBox && wrap === false, + [`background-color-${background}`]: background, + [`font-color-${color}`]: color, + [`border-color-${borderColor}`]: borderColor, + [`cursor-${cursor}`]: cursor, + [styles['box-transition']]: hover || focus, + }, + ); + + const boxStyles = { + ...style, + ...heightCss.styles, + ...maxHeightCss.styles, + ...maxWidthCss.styles, + ...widthCss.styles, + ...minHeightCss.styles, + ...minWidthCss.styles, + }; - return childGapDirection; - }; + /** + * Creates an object that maps the flex direction to either `right` or `bottom` + * so a margin can be applied to that side. + */ + const generateChildGapDirection = (): ResponsiveProp => { + let childGapDirection = {}; + + const getChildGapMarginDirection = (d: CssFlexDirectionValue) => { + let marginDirection = ''; + if (d?.includes('row')) marginDirection = 'right'; + else if (d?.includes('column')) marginDirection = 'bottom'; + + return marginDirection; + }; + + if (typeof direction === 'string') { + childGapDirection = { base: getChildGapMarginDirection(direction) }; + } else if (typeof direction === 'object' && direction !== null) { + childGapDirection = Object.keys(direction).reduce( + (acc, curr) => ({ + ...acc, + [curr]: getChildGapMarginDirection( + direction[curr as BreakpointSizeWithBase], + ), + }), + {}, + ); + } + + return childGapDirection; + }; - /** - * Shapes the childGap prop into a ResponsiveSpacing object - * so that we can cross-reference values between direction and childGap values to generate - * responsive classes. - */ - const generateChildGap = (): ResponsiveProp => { - let childGapObj = {}; + /** + * Shapes the childGap prop into a ResponsiveSpacing object + * so that we can cross-reference values between direction and childGap values to generate + * responsive classes. + */ + const generateChildGap = (): ResponsiveProp => { + let childGapObj = {}; + + if (typeof childGap === 'string') { + childGapObj = { base: childGap }; + } else if (typeof childGap === 'object' && childGap !== null) { + childGapObj = { ...childGap }; + } + + return childGapObj; + }; - if (typeof childGap === 'string') { - childGapObj = { base: childGap }; - } else if (typeof childGap === 'object' && childGap !== null) { - childGapObj = { ...childGap }; + const childGapClasses: string[] = []; + + if (childGap && direction) { + const childGapDirection = generateChildGapDirection(); + const childGapValues = generateChildGap(); + const breakpoints: BreakpointSizeWithBase[] = [ + 'hd', + 'desktop', + 'tablet', + 'base', + ]; + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const findMatchingBreakpoint = ( + responsiveObj: ResponsiveProp, + key: BreakpointSizeWithBase, + ): string => { + const index = breakpoints.findIndex(breakpoint => breakpoint === key); + let value = ''; + + value = responsiveObj[key]; + + if (!value) return findMatchingBreakpoint(responsiveObj, breakpoints[index + 1]); + + return value; + }; + + breakpoints.forEach(breakpoint => { + const foundDirection = findMatchingBreakpoint( + childGapDirection, + breakpoint as BreakpointSizeWithBase, + ); + const foundChildGap = findMatchingBreakpoint( + childGapValues, + breakpoint as BreakpointSizeWithBase, + ); + + const classSuffix = breakpoint === 'base' ? '' : `-${breakpoint}`; + const oppositeDirection = foundDirection === 'bottom' ? 'right' : 'bottom'; + + childGapClasses.push( + `m-${foundDirection}-${foundChildGap}${classSuffix}`, + ); + childGapClasses.push(`m-${oppositeDirection}-0${classSuffix}`); + }); } - return childGapObj; - }; - - const childGapClasses: string[] = []; - - if (childGap && direction) { - const childGapDirection = generateChildGapDirection(); - const childGapValues = generateChildGap(); - const breakpoints: BreakpointSizeWithBase[] = ['hd', 'desktop', 'tablet', 'base']; - + /** + * Shallow merges existing classes of child node with a className based on the childGap value. + */ // eslint-disable-next-line @typescript-eslint/no-explicit-any - const findMatchingBreakpoint = (responsiveObj: ResponsiveProp, - key: BreakpointSizeWithBase): string => { - const index = breakpoints.findIndex(breakpoint => breakpoint === key); - let value = ''; - - value = responsiveObj[key]; - - if (!value) return findMatchingBreakpoint(responsiveObj, breakpoints[index + 1]); - - return value; + const decorateChildren = ( + child: string | number | ReactElement, + i: number, + array: ReactElement[], + ) => { + if ( + i === array.length - 1 + || !child + || typeof child === 'string' + || typeof child === 'number' + ) { + return child; // Not gap if child is last element or if the children are strings or numbers. + } + + const childClasses = classNames(child.props.className, [ + ...Array.from(new Set(childGapClasses)), + ]); + + return cloneElement(child, { + className: childClasses, + key: child.key ?? i, + }); }; - breakpoints.forEach(breakpoint => { - const foundDirection = findMatchingBreakpoint( - childGapDirection, - breakpoint as BreakpointSizeWithBase, - ); - const foundChildGap = findMatchingBreakpoint( - childGapValues, - breakpoint as BreakpointSizeWithBase, - ); - - const classSuffix = breakpoint === 'base' ? '' : `-${breakpoint}`; - const oppositeDirection = foundDirection === 'bottom' ? 'right' : 'bottom'; - - childGapClasses.push(`m-${foundDirection}-${foundChildGap}${classSuffix}`); - childGapClasses.push(`m-${oppositeDirection}-0${classSuffix}`); - }); - } - - /** - * Shallow merges existing classes of child node with a className based on the childGap value. - */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const decorateChildren = (child: string | number | ReactElement, i: number, array: ReactElement[]) => { - if ( - i === array.length - 1 - || !child - || typeof child === 'string' - || typeof child === 'number' - ) { - return child; // Not gap if child is last element or if the children are strings or numbers. - } - - const childClasses = classNames(child.props.className, [...new Set(childGapClasses)]); + let decoratedChildren = Children.toArray(children).filter( + child => child !== null, + ); - return cloneElement(child, { - className: childClasses, - key: child.key ?? i, - }); - }; - - let decoratedChildren = Children.toArray(children).filter(child => child !== null); - - if (childGapClasses && decoratedChildren.length > 1) { - decoratedChildren = decoratedChildren - .map((value, index, array) => decorateChildren( - value as string | number | ReactElement, // eslint-disable-line @typescript-eslint/no-explicit-any - index, - array as ReactElement[], // eslint-disable-line @typescript-eslint/no-explicit-any + if (childGapClasses && decoratedChildren.length > 1) { + decoratedChildren = decoratedChildren.map((value, index, array) => decorateChildren( + value as string | number | ReactElement, // eslint-disable-line @typescript-eslint/no-explicit-any + index, + array as ReactElement[], // eslint-disable-line @typescript-eslint/no-explicit-any )); - } - - const element = getElementType(Box, { as }); + } - return createElement( - element, - { - className: boxClasses, - style: boxStyles, - ref, - ...restProps, - }, - (children !== null && children !== undefined) ? decoratedChildren : null, - ); -}); + const element = getElementType(Box, { as }); + + return createElement( + element, + { + className: boxClasses, + style: boxStyles, + ref, + ...restProps, + }, + children !== null && children !== undefined ? decoratedChildren : null, + ); + }, +); export const boxPropsKeys: (keyof Pick>)[] = [ 'as', diff --git a/src/components/Button/Button.Overview.stories.mdx b/src/components/Button/Button.Overview.stories.mdx index 1c1edfd49..0628b66dc 100644 --- a/src/components/Button/Button.Overview.stories.mdx +++ b/src/components/Button/Button.Overview.stories.mdx @@ -266,161 +266,3 @@ can render buttons as one of `button`, `a`, and `input`.
- -## Custom Theme - -The Button component can be themed by base tokens, or component specific tokens. This example shows how we style our `Button` with our brand font and squared corners for use on our public marketing site. - - - - - - - - - - - - -## Component Design Tokens - - - - - - - - - - {(() => { - const tokens = { - '--button-font-family': '--asset-fonts-body', - '--button-font-weight': '--size-font-weight-bold', - '--button-size-xs-border-radius': - '--form-control-size-sm-border-radius', - '--button-size-xs-font-size': '--form-control-size-xs-font-size', - '--button-size-xs-padding-vertical': '--size-spacing-2xs', - '--button-size-xs-padding-horizontal': '--size-spacing-xs', - '--button-size-sm-border-radius': - '--form-control-size-sm-border-radius', - '--button-size-sm-font-size': '--form-control-size-sm-font-size', - '--button-size-sm-padding-vertical': '--form-control-size-sm-padding', - '--button-size-sm-padding-horizontal': '--size-spacing-sm', - '--button-size-md-border-radius': - '--form-control-size-md-border-radius', - '--button-size-md-font-size': '--form-control-size-md-font-size', - '--button-size-md-padding-vertical': '--form-control-size-md-padding', - '--button-size-md-padding-horizontal': '--size-spacing-md', - '--button-size-lg-border-radius': - '--form-control-size-lg-border-radius', - '--button-size-lg-font-size': '--form-control-size-lg-font-size', - '--button-size-lg-padding-vertical': '--form-control-size-lg-padding', - '--button-size-lg-padding-horizontal': '--size-spacing-lg', - '--button-primary-background-color': '--color-brand-primary-500;', - '--button-primary-background-color-hover': '--color-brand-primary-600', - '--button-primary-background-color-active': '--color-brand-primary-700', - '--button-primary-font-color': '--color-brand-white-base', - '--button-primary-font-color-hover': '--color-brand-white-base', - '--button-secondary-background-color': '--color-brand-white-base', - '--button-secondary-background-color-hover': '--color-brand-primary-50', - '--button-secondary-background-color-active': - '--color-brand-primary-100', - '--button-secondary-border-color': '--color-brand-grey-200', - '--button-secondary-border-color-hover': '--color-brand-primary-100', - '--button-secondary-font-color': '--color-brand-primary-500', - '--button-secondary-font-color-hover': '--color-brand-primary-500', - '--button-tertiary-background-color': 'transparent', - '--button-tertiary-background-color-hover': '--color-brand-primary-50', - '--button-tertiary-background-color-active': - '--color-brand-primary-100', - '--button-tertiary-font-color': '--color-brand-primary-500', - '--button-tertiary-font-color-hover': '--color-brand-primary-500', - '--button-primary-neutral-background-color': '--color-brand-grey-100', - '--button-primary-neutral-background-color-hover': - '--color-brand-grey-200', - '--button-primary-neutral-background-color-active': - '--color-brand-grey-300', - '--button-primary-neutral-font-color': '--color-brand-grey-700', - '--button-primary-neutral-font-color-hover': '--color-brand-grey-700', - '--button-secondary-neutral-background-color': - '--color-brand-white-base', - '--button-secondary-neutral-background-color-hover': - '--color-brand-grey-100', - '--button-secondary-neutral-background-color-active': - '--color-brand-grey-200', - '--button-secondary-neutral-border-color': '--color-brand-grey-200', - '--button-secondary-neutral-border-color-hover': - '--color-brand-grey-100', - '--button-secondary-neutral-font-color': '--color-brand-grey-700', - '--button-secondary-neutral-font-color-hover': '--color-brand-grey-700', - '--button-tertiary-neutral-background-color': 'transparent', - '--button-tertiary-neutral-background-color-hover': - '--color-brand-grey-100', - '--button-tertiary-neutral-background-color-active': - '--color-brand-grey-200', - '--button-tertiary-neutral-font-color': '--color-brand-grey-700', - '--button-tertiary-neutral-font-color-hover': '--color-brand-grey-700', - '--button-primary-danger-background-color': '--color-brand-danger-500', - '--button-primary-danger-background-color-hover': - '--color-brand-danger-600', - '--button-primary-danger-background-color-active': - '--color-brand-danger-700', - '--button-primary-danger-font-color': '--color-brand-white-base', - '--button-primary-danger-font-color-hover': '--color-brand-white-base', - '--button-secondary-danger-background-color': - '--color-brand-white-base', - '--button-secondary-danger-background-color-hover': - '--color-brand-danger-50', - '--button-secondary-danger-background-color-active': - '--color-brand-danger-100', - '--button-secondary-danger-border-color': '--color-brand-grey-200', - '--button-secondary-danger-border-color-hover': - '--color-brand-danger-100', - '--button-secondary-danger-font-color': '--color-brand-danger-500', - '--button-secondary-danger-font-color-hover': - '--color-brand-danger-500', - '--button-tertiary-danger-background-color': 'transparent', - '--button-tertiary-danger-background-color-hover': - '--color-brand-danger-50', - '--button-tertiary-danger-background-color-active': - '--color-brand-danger-100', - '--button-tertiary-danger-font-color': '--color-brand-danger-500', - '--button-tertiary-danger-font-color-hover': '--color-brand-danger-500', - '--button-box-shadow-focus': '0 0 0 4px --color-brand-primary-200', - '--button-neutral-box-shadow-focus': '0 0 0 4px --color-brand-grey-200', - '--button-danger-box-shadow-focus': - '0 0 0 4px --color-brand-danger-200', - }; - return Object.entries(tokens).map(([name, entry], i) => ( - - - - - )); - })()} - -
token namedefault value
- {name} - - {entry} -
diff --git a/src/components/Button/Button.module.scss b/src/components/Button/Button.module.scss index 59bf345a9..e63d2821d 100644 --- a/src/components/Button/Button.module.scss +++ b/src/components/Button/Button.module.scss @@ -1,69 +1,6 @@ @import '~@palmetto/palmetto-design-tokens/build/scss/variables-size'; :root { - --button-primary-background-color: var(--color-brand-primary-500); - --button-primary-background-color-hover: var(--color-brand-primary-600); - --button-primary-background-color-active: var(--color-brand-primary-700); - --button-primary-font-color: var(--color-brand-white-base); - --button-primary-font-color-hover: var(--color-brand-white-base); - --button-secondary-background-color: var(--color-brand-white-base); - --button-secondary-background-color-hover: var(--color-brand-primary-50); - --button-secondary-background-color-active: var(--color-brand-primary-100); - --button-secondary-border-color: var(--color-brand-grey-200); - --button-secondary-border-color-hover: var(--color-brand-primary-100); - --button-secondary-font-color: var(--color-brand-primary-500); - --button-secondary-font-color-hover: var(--color-brand-primary-500); - --button-tertiary-background-color: transparent; - --button-tertiary-background-color-hover: var(--color-brand-primary-50); - --button-tertiary-background-color-active: var(--color-brand-primary-100); - --button-tertiary-font-color: var(--color-brand-primary-500); - --button-tertiary-font-color-hover: var(--color-brand-primary-500); - --button-primary-neutral-background-color: var(--color-brand-grey-100); - --button-primary-neutral-background-color-hover: var(--color-brand-grey-200); - --button-primary-neutral-background-color-active: var(--color-brand-grey-300); - --button-primary-neutral-font-color: var(--color-brand-grey-700); - --button-primary-neutral-font-color-hover: var(--color-brand-grey-700); - --button-secondary-neutral-background-color: var(--color-brand-white-base); - --button-secondary-neutral-background-color-hover: var(--color-brand-grey-50); - --button-secondary-neutral-background-color-active: var( - --color-brand-grey-200 - ); - --button-secondary-neutral-border-color: var(--color-brand-grey-200); - --button-secondary-neutral-border-color-hover: var(--color-brand-grey-200); - --button-secondary-neutral-font-color: var(--color-brand-grey-700); - --button-secondary-neutral-font-color-hover: var(--color-brand-grey-700); - --button-tertiary-neutral-background-color: transparent; - --button-tertiary-neutral-background-color-hover: var(--color-brand-grey-100); - --button-tertiary-neutral-background-color-active: var( - --color-brand-grey-200 - ); - --button-tertiary-neutral-font-color: var(--color-brand-grey-700); - --button-tertiary-neutral-font-color-hover: var(--color-brand-grey-700); - --button-primary-danger-background-color: var(--color-brand-danger-500); - --button-primary-danger-background-color-hover: var(--color-brand-danger-600); - --button-primary-danger-background-color-active: var( - --color-brand-danger-700 - ); - --button-primary-danger-font-color: var(--color-brand-white-base); - --button-primary-danger-font-color-hover: var(--color-brand-white-base); - --button-secondary-danger-background-color: var(--color-brand-white-base); - --button-secondary-danger-background-color-hover: var( - --color-brand-danger-50 - ); - --button-secondary-danger-background-color-active: var( - --color-brand-danger-100 - ); - --button-secondary-danger-border-color: var(--color-brand-grey-200); - --button-secondary-danger-border-color-hover: var(--color-brand-danger-100); - --button-secondary-danger-font-color: var(--color-brand-danger-500); - --button-secondary-danger-font-color-hover: var(--color-brand-danger-500); - --button-tertiary-danger-background-color: transparent; - --button-tertiary-danger-background-color-hover: var(--color-brand-danger-50); - --button-tertiary-danger-background-color-active: var( - --color-brand-danger-100 - ); - --button-tertiary-danger-font-color: var(--color-brand-danger-500); - --button-tertiary-danger-font-color-hover: var(--color-brand-danger-500); --button-box-shadow-focus: 0 0 0 4px var(--color-brand-primary-200); --button-neutral-box-shadow-focus: 0 0 0 4px var(--color-brand-grey-200); --button-danger-box-shadow-focus: 0 0 0 4px var(--color-brand-danger-200); @@ -215,7 +152,7 @@ padding: 0; color: inherit; line-height: var(--size-line-height-input); - font-family: var(--button-font-family, var(--asset-fonts-body)); + font-family: var(--asset-fonts-body); display: inline-flex; align-items: center; justify-content: center; @@ -237,8 +174,8 @@ } &.primary { - background-color: var(--button-primary-background-color); - color: var(--button-primary-font-color); + background-color: var(--color-background-button-primary); + color: var(--color-text-button-primary); &:focus { outline: 0; @@ -259,17 +196,17 @@ } &:not(:disabled):hover { - background-color: var(--button-primary-background-color-hover); - color: var(--button-primary-font-color-hover); + background-color: var(--color-background-button-primary-hover); + color: var(--color-text-button-primary-hover); } &:not(:disabled):active { - background-color: var(--button-primary-background-color-active); + background-color: var(--color-background-button-primary-active); } &.neutral { - background-color: var(--button-primary-neutral-background-color); - color: var(--button-primary-neutral-font-color); + background-color: var(--color-background-button-primary-neutral); + color: var(--color-text-button-primary-neutral); &:focus { outline: 0; @@ -287,18 +224,18 @@ } &:not(:disabled):hover { - background-color: var(--button-primary-neutral-background-color-hover); - color: var(--button-primary-neutral-font-color-hover); + background-color: var(--color-background-button-primary-neutral-hover); + color: var(--color-text-button-primary-neutral-hover); } &:not(:disabled):active { - background-color: var(--button-primary-neutral-background-color-active); + background-color: var(--color-background-button-primary-neutral-active); } } &.danger { - background-color: var(--button-primary-danger-background-color); - color: var(--button-primary-danger-font-color); + background-color: var(--color-background-button-primary-danger); + color: var(--color-text-button-primary-danger); &:focus { outline: 0; @@ -316,21 +253,21 @@ } &:not(:disabled):hover { - background-color: var(--button-primary-danger-background-color-hover); - color: var(--button-primary-danger-font-color-hover); + background-color: var(--color-background-button-primary-danger-hover); + color: var(--color-text-button-primary-danger-hover); } &:not(:disabled):active { - background-color: var(--button-primary-danger-background-color-active); + background-color: var(--color-background-button-primary-danger-active); } } } &.secondary { border: 1px solid; - border-color: var(--button-secondary-border-color); - background-color: var(--button-secondary-background-color); - color: var(--button-secondary-font-color); + border-color: var(--color-border-button-secondary); + background-color: var(--color-background-button-secondary); + color: var(--color-text-button-secondary); &:focus { outline: 0; @@ -349,20 +286,20 @@ } &:not(:disabled):hover { - border-color: var(--button-secondary-border-color-hover); - background-color: var(--button-secondary-background-color-hover); - color: var(--button-secondary-font-color-hover); + border-color: var(--color-border-button-secondary-hover); + background-color: var(--color-background-button-secondary-hover); + color: var(--color-text-button-secondary-hover); } &:not(:disabled):active { - background-color: var(--button-secondary-background-color-active); + background-color: var(--color-background-button-secondary-active); } &.neutral { - background-color: var(--button-secondary-neutral-background-color); + background-color: var(--color-background-button-secondary-neutral); border: 1px solid; - border-color: var(--button-secondary-neutral-border-color); - color: var(--button-secondary-neutral-font-color); + border-color: var(--color-border-button-secondary-neutral); + color: var(--color-text-button-secondary-neutral); &:focus { outline: 0; @@ -381,25 +318,25 @@ } &:not(:disabled):hover { - border-color: var(--button-secondary-neutral-border-color-hover); + border-color: var(--color-border-button-secondary-neutral-hover); background-color: var( - --button-secondary-neutral-background-color-hover + --color-background-button-secondary-neutral-hover ); - color: var(--button-secondary-neutral-font-color-hover); + color: var(--color-text-button-secondary-neutral-hover); } &:not(:disabled):active { background-color: var( - --button-secondary-neutral-background-color-active + --color-background-button-secondary-neutral-active ); } } &.danger { - background-color: var(--button-secondary-danger-background-color); + background-color: var(--color-background-button-secondary-danger); border: 1px solid; - border-color: var(--button-secondary-danger-border-color); - color: var(--button-secondary-danger-font-color); + border-color: var(--color-border-button-secondary-danger); + color: var(--color-text-button-secondary-danger); &:focus { outline: 0; @@ -417,22 +354,22 @@ } &:not(:disabled):hover { - border-color: var(--button-secondary-danger-border-color-hover); - background-color: var(--button-secondary-danger-background-color-hover); - color: var(--button-secondary-danger-font-color-hover); + border-color: var(--color-border-button-secondary-danger-hover); + background-color: var(--color-background-button-secondary-danger-hover); + color: var(--color-text-button-secondary-danger-hover); } &:not(:disabled):active { background-color: var( - --button-secondary-danger-background-color-active + --color-background-button-secondary-danger-active ); } } } &.tertiary { - background-color: var(--button-tertiary-background-color); - color: var(--button-tertiary-font-color); + background-color: var(--color-background-button-tertiary); + color: var(--color-text-button-tertiary); &:focus { outline: 0; @@ -451,19 +388,19 @@ } &:not(:disabled):hover { - background-color: var(--button-tertiary-background-color-hover); - border-color: var(--button-tertiary-background-color-hover); - color: var(--button-tertiary-font-color-hover); + background-color: var(--color-background-button-tertiary-hover); + border-color: var(--color-background-button-tertiary-hover); + color: var(--color-text-button-tertiary-hover); } &:not(:disabled):active { - background-color: var(--button-tertiary-background-color-active); - border-color: var(--button-tertiary-background-color-active); + background-color: var(--color-background-button-tertiary-active); + border-color: var(--color-background-button-tertiary-active); } &.neutral { - background-color: var(--button-tertiary-neutral-background-color); - color: var(--button-tertiary-neutral-font-color); + background-color: var(--color-background-button-tertiary-neutral); + color: var(--color-text-button-tertiary-neutral); &:focus { outline: 0; @@ -482,21 +419,21 @@ } &:not(:disabled):hover { - background-color: var(--button-tertiary-neutral-background-color-hover); - border-color: var(--button-tertiary-neutral-background-color-hover); - color: var(--button-tertiary-neutral-font-color-hover); + background-color: var(--color-background-button-tertiary-neutral-hover); + border-color: var(--color-background-button-tertiary-neutral-hover); + color: var(--color-text-button-tertiary-neutral-hover); } &:not(:disabled):active { background-color: var( - --button-tertiary-neutral-background-color-active + --color-background-button-tertiary-neutral-active ); } } &.danger { - background-color: var(--button-tertiary-danger-background-color); - color: var(--button-tertiary-danger-font-color); + background-color: var(--color-background-button-tertiary-danger); + color: var(--color-text-button-tertiary-danger); &:focus { outline: 0; @@ -514,13 +451,13 @@ } &:not(:disabled):hover { - background-color: var(--button-tertiary-danger-background-color-hover); - border-color: var(--button-tertiary-danger-background-color-hover); - color: var(--button-tertiary-danger-font-color-hover); + background-color: var(--color-background-button-tertiary-danger-hover); + border-color: var(--color-background-button-tertiary-danger-hover); + color: var(--color-text-button-tertiary-danger-hover); } &:not(:disabled):active { - background-color: var(--button-tertiary-danger-background-color-active); + background-color: var(--color-background-button-tertiary-danger-active); } } } diff --git a/src/components/Button/Button.test.jsx b/src/components/Button/Button.test.jsx index 3a957a527..26dc9280d 100644 --- a/src/components/Button/Button.test.jsx +++ b/src/components/Button/Button.test.jsx @@ -284,7 +284,7 @@ describe('Button', () => { ); const spinnerElement = document.getElementsByClassName('spinner')[0]; expect(spinnerElement).toBeInTheDocument(); - expect(spinnerElement).toHaveClass('font-color-dark'); + expect(spinnerElement).toHaveClass('font-color-body-primary'); }); test('it renders the primary spinning loading indicator with prefix icon', () => { @@ -306,10 +306,10 @@ describe('Button', () => { ); const spinnerElement = document.getElementsByClassName('spinner')[0]; expect(spinnerElement).toBeInTheDocument(); - expect(spinnerElement).toHaveClass('font-color-dark'); + expect(spinnerElement).toHaveClass('font-color-body-primary'); }); - test('it renders the grey spinning indicator if button variant is secondary with neutral tone', () => { + test('it renders the body-primary color indicator if button variant is secondary with neutral tone', () => { render( - - - This is a "night" themed drawer. - - -
- ); - }} -
-
- -## Component Design Tokens - - - - - - - - - - {(() => { - const tokens = { - '--drawer-background-color': '--color-brand-white-500', - '--drawer-box-shadow': '--size-box-shadow-xl', - '--drawer-font-color': '--color-brand-grey-100', - '--drawer-header-border-color': '--color-brand-grey-100', - '--drawer-width': '--size-width-4xl', - '--drawer-close-button-color': '--color-brand-grey-500', - '--drawer-close-button-color-hover': '--color-brand-grey-600', - '--drawer-close-button-box-shadow-focus': '--color-brand-grey-200', - }; - return Object.entries(tokens).map(([name, entry], i) => ( - - - - - )); - })()} - - -
token namedefault value
- {name} - - {entry} -
diff --git a/src/components/Drawer/Drawer.module.scss b/src/components/Drawer/Drawer.module.scss index 238d5c3d8..65b21ce79 100644 --- a/src/components/Drawer/Drawer.module.scss +++ b/src/components/Drawer/Drawer.module.scss @@ -38,18 +38,18 @@ .drawer { [data-reach-dialog-content] { - background-color: var(--drawer-background-color, var(--color-brand-white-500)); - color: var(--drawer-font-color, inherit); + background-color: var(--color-background-primary); + color: var(--color-text-body-primary); display: flex; flex-direction: column; - padding: var(--drawer-content-padding, var(--size-spacing-0)); + padding: 0; position: absolute; - box-shadow: var(--drawer-box-shadow, var(--size-box-shadow-xl)); + box-shadow: var(--size-box-shadow-xl); z-index: var(--size-z-index-drawer); &.left { left: 0; - width: var(--w, var(--drawer-width, 80vw)); + width: var(--w, 80vw); height: 100%; :global { @@ -59,7 +59,7 @@ &.right { right: 0; - width: var(--w, var(--drawer-width, 80vw)); + width: var(--w, 80vw); height: 100%; :global { @@ -87,17 +87,17 @@ } } - @media(min-width: $size-breakpoint-tablet) { + @media (min-width: $size-breakpoint-tablet) { &.right, &.left { - width: var(--w, var(--drawer-width, var(--size-width-4xl))); + width: var(--w, var(--size-width-4xl)); } } } } .drawer-header { - border-color: var(--drawer-header-border-color, var(--color-brand-grey-100)); + border-color: var(--color-border-separator); } .drawer-close-button { @@ -105,18 +105,21 @@ background: transparent; cursor: pointer; padding: var(--size-spacing-xs); - color: var(--drawer-close-button-color, var(--color-brand-grey-500)); + color: var(--color-text-body-secondary); line-height: var(--size-line-height-base); border-radius: var(--size-border-radius-sm); &:hover { - color: var(--drawer-close-button-color-hover, var(--color-brand-grey-600)); + color: var(--color-text-body-primary); } //Show focus styles on keyboard focus. &:focus-visible { outline: 0; - box-shadow: var(--drawer-close-button-box-shadow-focus, 0 0 0 4px var(--color-brand-grey-200)); + box-shadow: var( + --drawer-close-button-box-shadow-focus, + 0 0 0 4px var(--color-brand-grey-200) + ); } //Hide focus styles if they are not needed, for example, diff --git a/src/components/Drawer/Drawer.tsx b/src/components/Drawer/Drawer.tsx index 20e43464a..7d3c718c6 100644 --- a/src/components/Drawer/Drawer.tsx +++ b/src/components/Drawer/Drawer.tsx @@ -154,7 +154,7 @@ export const Drawer = forwardRef( className={styles['drawer-close-button']} onClick={onDismiss} > - +
); @@ -179,7 +179,7 @@ export const Drawer = forwardRef( className={styles['drawer-close-button']} onClick={onDismiss} > - + )}
diff --git a/src/components/FileUpload/FileUpload.tsx b/src/components/FileUpload/FileUpload.tsx index dac43bd97..a0a46a100 100644 --- a/src/components/FileUpload/FileUpload.tsx +++ b/src/components/FileUpload/FileUpload.tsx @@ -201,7 +201,7 @@ export const FileUpload: FC = React.forwardRef< > {fileNameMaxLength ? truncateFileName(file.name, fileNameMaxLength) diff --git a/src/components/FormLabel/FormLabel.Overview.stories.mdx b/src/components/FormLabel/FormLabel.Overview.stories.mdx index e2ddd1965..88bf6deb7 100644 --- a/src/components/FormLabel/FormLabel.Overview.stories.mdx +++ b/src/components/FormLabel/FormLabel.Overview.stories.mdx @@ -79,7 +79,3 @@ FormLabels support the ability to for its text to be interactive or link to anot
- -## Component Design Tokens - -This component shares component design tokens with all form controls. For a complete list of tokens, see the [Theming Form Controls documentation](/docs/theming-form-controls--custom-theme-form). diff --git a/src/components/FormLabel/FormLabel.module.scss b/src/components/FormLabel/FormLabel.module.scss index ddddecfab..3eb469a5e 100644 --- a/src/components/FormLabel/FormLabel.module.scss +++ b/src/components/FormLabel/FormLabel.module.scss @@ -1,14 +1,17 @@ .label { - font-family: var(--form-control-font-family, var(--INTERNAL_form-control-font-family)); - color: var(--form-control-label-font-color, var(--INTERNAL_form-control-label-font-color)); - font-size: var(--form-control-size-md-label-size, var(--INTERNAL_form-control-size-md-label-size)); - font-weight: var(--form-control-label-font-weight, var(--INTERNAL_form-control-label-font-weight)); + font-family: var(--asset-fonts-body); + color: var(--color-text-body-primary); + font-size: var( + --form-control-size-md-label-size, + var(--INTERNAL_form-control-size-md-label-size) + ); + font-weight: var(--size-font-weight-medium); &.radio-input-label { - font-weight: 400; + font-weight: var(--size-font-weight-regular); } &.disabled { - color: var(--color-brand-grey-300); + color: var(--color-text-disabled); } } diff --git a/src/components/Heading/Heading.Overview.stories.mdx b/src/components/Heading/Heading.Overview.stories.mdx index fe0ea70b0..e4768c971 100644 --- a/src/components/Heading/Heading.Overview.stories.mdx +++ b/src/components/Heading/Heading.Overview.stories.mdx @@ -90,34 +90,3 @@ The variant of the heading is inherited from its parent, but can be set to brand
- -## Component Design Tokens - - - - - - - - - - {(() => { - const tokens = { - '--heading-font-family': '--asset-fonts-brand', - '--heading-font-weight': '--size-font-weight-black', - '--heading-line-height': '--size-line-height-heading', - }; - return Object.entries(tokens).map(([name, entry], i) => ( - - - - - )); - })()} - - -
token namedefault value
- {name} - - {entry} -
diff --git a/src/components/Heading/Heading.Playground.stories.tsx b/src/components/Heading/Heading.Playground.stories.tsx index 4d14f4812..291fb5b3a 100644 --- a/src/components/Heading/Heading.Playground.stories.tsx +++ b/src/components/Heading/Heading.Playground.stories.tsx @@ -41,6 +41,6 @@ export const Playground = Template.bind({}); Playground.args = { as: 'h4', children: 'Lead the world towards a clean energy future', - variant: 'grey-darker', + variant: 'body-primary', size: 'base', }; diff --git a/src/components/Heading/Heading.module.scss b/src/components/Heading/Heading.module.scss index a1b1aee41..42fc411d7 100644 --- a/src/components/Heading/Heading.module.scss +++ b/src/components/Heading/Heading.module.scss @@ -1,5 +1,5 @@ .heading { - line-height: var(--heading-line-height, var(--size-line-height-heading)); - font-family: var(--heading-font-family, var(--asset-fonts-brand)); - font-weight: var(--heading-font-weight, var(--size-font-weight-bold)); + line-height: var(--size-line-height-heading); + font-family: var(--asset-fonts-brand); + font-weight: var(--size-font-weight-bold); } diff --git a/src/components/HelpText/HelpText.module.scss b/src/components/HelpText/HelpText.module.scss index 359d3f2e0..301359405 100644 --- a/src/components/HelpText/HelpText.module.scss +++ b/src/components/HelpText/HelpText.module.scss @@ -1,12 +1,6 @@ .help-text { - color: var( - --form-control-help-text-font-color, - var(--INTERNAL_form-control-help-text-font-color) - ); - font-family: var( - --form-control-font-family, - var(--INTERNAL_form-control-font-family) - ); + color: var(--color-text-body-tertiary); + font-family: var(--asset-fonts-body); font-size: var( --form-control-help-text-font-size, var(--INTERNAL_form-control-help-text-font-size) diff --git a/src/components/Icon/Icon.tsx b/src/components/Icon/Icon.tsx index 67890ec33..572dbaf29 100644 --- a/src/components/Icon/Icon.tsx +++ b/src/components/Icon/Icon.tsx @@ -2,9 +2,7 @@ import React, { FC, forwardRef } from 'react'; import icons from '@palmetto/palmetto-design-tokens/build/icons/react'; import classNames from 'classnames'; import { generateResponsiveClasses } from '../../lib/generateResponsiveClasses'; -import { - FontColor, FontSize, IconName, ResponsiveProp, -} from '../../types'; +import { FontColor, FontSize, IconName, ResponsiveProp } from '../../types'; import { Box } from '../Box/Box'; export interface IconProps { @@ -28,9 +26,7 @@ export interface IconProps { } export const Icon: FC = forwardRef( - ({ - className = undefined, name, color, size, ...restProps - }, ref) => { + ({ className = undefined, name, color, size, ...restProps }, ref) => { const IconComponent = icons[name]; if (!IconComponent) console.error(`Icon '${name}' not found`); // eslint-disable-line no-console @@ -51,7 +47,7 @@ export const Icon: FC = forwardRef( ) : ( - + @@ -304,32 +309,3 @@ If `headerContent` is defined, then the `title` and `description` will not be re }}
- -## Component Design Tokens - - - - - - - - - - {(() => { - const tokens = { - '--media-modal-font-color': '--color-brand-grey-100', - }; - return Object.entries(tokens).map(([name, entry], i) => ( - - - - - )); - })()} - - -
token namedefault value
- {name} - - {entry} -
diff --git a/src/components/MediaModal/MediaModal.tsx b/src/components/MediaModal/MediaModal.tsx index 19720c5fc..3fd39236e 100644 --- a/src/components/MediaModal/MediaModal.tsx +++ b/src/components/MediaModal/MediaModal.tsx @@ -114,7 +114,7 @@ export const MediaModal: React.FC = forwardRef< className={styles['media-modal-close']} onClick={onDismiss} cursor="pointer" - color="grey-100" + color="grey-300" background="transparent" borderWidth="0" padding="xs" diff --git a/src/components/Modal/Modal.Overview.stories.mdx b/src/components/Modal/Modal.Overview.stories.mdx index 59071bf6b..b69fec650 100644 --- a/src/components/Modal/Modal.Overview.stories.mdx +++ b/src/components/Modal/Modal.Overview.stories.mdx @@ -58,7 +58,7 @@ In order to hide or show the Modal, set the Modal's `isOpen` prop to `true` or ` /> Modal content - @@ -192,7 +192,7 @@ Omit `` to render a minimal modal without a header. > Modal content - @@ -239,7 +239,7 @@ Use `fullScreenMobile` to enable fullscreen at mobile viewport widths. /> Modal content - @@ -294,37 +294,3 @@ maxWidth, use existing tokens only. }}
- -## Component Design Tokens - - - - - - - - - - {(() => { - const tokens = { - '--modal-background-color': '--color-brand-white-500', - '--modal-border-radius': '--size-border-radius-md', - '--modal-box-shadow': '--size-box-shadow-md', - '--modal-close-button-color': '--color-brand-grey-500', - '--modal-close-button-color-hover': '--color-brand-grey-600', - '--modal-close-button-box-shadow-focus': '--color-brand-grey-200', - '--modal-border-separator-color': '--color-brand-grey-100', - }; - return Object.entries(tokens).map(([name, entry], i) => ( - - - - - )); - })()} - -
token namedefault value
- {name} - - {entry} -
diff --git a/src/components/Modal/Modal.VisualTests.stories.jsx b/src/components/Modal/Modal.VisualTests.stories.jsx index df2cdb219..0725be624 100644 --- a/src/components/Modal/Modal.VisualTests.stories.jsx +++ b/src/components/Modal/Modal.VisualTests.stories.jsx @@ -31,7 +31,7 @@ export const BasicExample = () => ( null} /> Modal content - @@ -58,7 +58,7 @@ export const WithoutHeader = () => ( null}> Modal content - @@ -75,7 +75,7 @@ export const FullScreenOnMobile = () => ( /> Modal content - @@ -92,7 +92,7 @@ export const WithMaxWidth = () => ( /> Modal content - @@ -114,7 +114,7 @@ export const WithResponsiveMaxWidth = () => ( /> Modal content - diff --git a/src/components/Modal/Modal.module.scss b/src/components/Modal/Modal.module.scss index 430951e9f..421852d6a 100644 --- a/src/components/Modal/Modal.module.scss +++ b/src/components/Modal/Modal.module.scss @@ -1,25 +1,27 @@ @import '~@palmetto/palmetto-design-tokens/build/scss/variables-size'; // This line prevents @reach/dialog from throwing a warning due to not importing their CSS. -:root { --reach-dialog: 1; } +:root { + --reach-dialog: 1; +} .modal-close { border: none; background: transparent; cursor: pointer; padding: var(--size-spacing-xs); - color: var(--modal-close-button-color, var(--color-brand-grey-500)); + color: var(--color-text-body-primary); line-height: var(--size-line-height-base); border-radius: var(--size-border-radius-sm); &:hover { - color: var(--modal-close-button-color-hover, var(--color-brand-grey-600)); + color: var(--color-text-contrast); } // Show focus styles on keyboard focus. &:focus-visible { outline: 0; - box-shadow: var(--modal-close-button-box-shadow-focus, 0 0 0 4px var(--color-brand-grey-200)); + box-shadow: 0 0 0 4px var(--color-brand-grey-200); } // Hide focus styles if they are not needed, for example, @@ -28,9 +30,9 @@ outline: 0; box-shadow: none; } - } + [data-reach-dialog-overlay].modal { display: flex; position: fixed; @@ -40,8 +42,7 @@ left: 0; align-items: flex-end; z-index: var(--size-z-index-overlay); - background: hsl(0deg 0% 0% / 33%); - background-color: rgb(77 82 79 / 50%); + background-color: rgba(0 0 0 / 60%); overflow: hidden; :global { @@ -60,8 +61,13 @@ @media (min-width: $size-breakpoint-tablet) { display: grid; - grid-template-rows: minmax(var(--size-spacing-2xl), 1fr) auto minmax(var(--size-spacing-2xl), 1fr); - grid-template-columns: var(--size-spacing-2xl) auto var(--size-spacing-2xl); + grid-template-rows: minmax(var(--size-spacing-2xl), 1fr) auto minmax( + var(--size-spacing-2xl), + 1fr + ); + grid-template-columns: var(--size-spacing-2xl) auto var( + --size-spacing-2xl + ); align-content: center; align-items: center; overflow: hidden; @@ -69,6 +75,8 @@ } [data-reach-dialog-content] { + color: var(--color-text-body-primary); + font-family: var(--asset-fonts-body); display: flex; position: absolute; bottom: 0; @@ -77,10 +85,11 @@ grid-column: 1; z-index: var(--size-z-index-modal); margin: 0; - background-color: var(--modal-background-color, var(--color-brand-white-500)); + background-color: var(--color-background-primary); padding: 0; width: 100%; - border-radius: var(--modal-border-radius, var(--size-border-radius-md)) var(--modal-border-radius, var(--size-border-radius-md)) 0 0; + border-radius: var(--modal-border-radius, var(--size-border-radius-md)) + var(--modal-border-radius, var(--size-border-radius-md)) 0 0; :global { animation: slideInUp 0.3s; @@ -103,7 +112,7 @@ } } - @media(min-width: $size-breakpoint-desktop) { + @media (min-width: $size-breakpoint-desktop) { width: 50vw; } } @@ -121,7 +130,10 @@ @media (min-width: $size-breakpoint-tablet) { display: grid; - grid-template-rows: minmax(var(--size-spacing-2xl), 1fr) auto minmax(var(--size-spacing-2xl), 1fr); + grid-template-rows: minmax(var(--size-spacing-2xl), 1fr) auto minmax( + var(--size-spacing-2xl), + 1fr + ); grid-template-columns: var(--size-spacing-2xl) auto var(--size-spacing-2xl); align-items: center; overflow: hidden; @@ -143,7 +155,7 @@ animation: fadeInUp 0.2s ease-out; } - @media(min-width: $size-breakpoint-desktop) { + @media (min-width: $size-breakpoint-desktop) { width: 50vw; } } diff --git a/src/components/Modal/Modal.test.tsx b/src/components/Modal/Modal.test.tsx index d5b8ae19c..17b583b6f 100644 --- a/src/components/Modal/Modal.test.tsx +++ b/src/components/Modal/Modal.test.tsx @@ -47,7 +47,7 @@ describe('Modal', () => { test('onDismiss', async () => { const mockOnDismiss = jest.fn(); - const { getByTestId } = render( + const { getByLabelText } = render( Modal body content @@ -55,7 +55,7 @@ describe('Modal', () => { , ); - const closeButton = getByTestId('icon-testid--remove').closest('button'); + const closeButton = getByLabelText('close'); expect(closeButton).toBeInTheDocument(); if (closeButton) { diff --git a/src/components/Modal/components/ModalFooter/ModalFooter.tsx b/src/components/Modal/components/ModalFooter/ModalFooter.tsx index 7c6802702..c4b15ebdf 100644 --- a/src/components/Modal/components/ModalFooter/ModalFooter.tsx +++ b/src/components/Modal/components/ModalFooter/ModalFooter.tsx @@ -21,11 +21,11 @@ export const ModalFooter: FC = ({ direction={direction} alignItems={alignItems} justifyContent={justifyContent} + borderColor="separator" borderWidth="xs 0 0 0" gap={gap} style={{ flexShrink: 0, - borderColor: 'var(--modal-border-separator-color, var(--color-brand-grey-100))', ...style, }} {...restProps} diff --git a/src/components/Modal/components/ModalHeader/ModalHeader.tsx b/src/components/Modal/components/ModalHeader/ModalHeader.tsx index d00b0093a..31be0b445 100644 --- a/src/components/Modal/components/ModalHeader/ModalHeader.tsx +++ b/src/components/Modal/components/ModalHeader/ModalHeader.tsx @@ -27,10 +27,10 @@ export const ModalHeader: FC = ({ id, onDismiss, title = undef direction="row" alignItems="center" justifyContent={justifyContentValue} + borderColor="separator" borderWidth="0 0 xs 0" style={{ flexShrink: 0, - borderColor: 'var(--modal-border-separator-color, var(--color-brand-grey-100))', }} height="lg" > @@ -46,7 +46,7 @@ export const ModalHeader: FC = ({ id, onDismiss, title = undef className={styles['modal-close']} onClick={onDismiss} > - + )}
diff --git a/src/components/OptionTile/OptionTile.Overview.stories.mdx b/src/components/OptionTile/OptionTile.Overview.stories.mdx index ed95905d8..f66879bb7 100644 --- a/src/components/OptionTile/OptionTile.Overview.stories.mdx +++ b/src/components/OptionTile/OptionTile.Overview.stories.mdx @@ -132,9 +132,9 @@ Also note that these icons are only there for visual feedback, as the true input name="hoverOptionTile" value="hoverOptionTile" hover={{ - borderColor: 'danger', + borderColor: 'primary', shadow: 'lg', - background: 'danger-lightest', + background: 'primary', }} > Hello world! @@ -195,9 +195,7 @@ Also note that these icons are only there for visual feedback, as the true input name={option.name} value={option.value} background={ - option.value === selectedOption - ? 'secondary-lightest' - : undefined + option.value === selectedOption ? 'secondary-50' : undefined } borderColor={ option.value === selectedOption ? 'secondary' : undefined @@ -216,134 +214,3 @@ Also note that these icons are only there for visual feedback, as the true input }}
- -## Component Design Tokens - -This component shares component design tokens with all form controls. For a complete list of tokens, see the [Theming Form Controls documentation](/docs/theming-form-controls--custom-theme-form). - -If you require theming for this component separately of other form controls, it also includes the following component specific tokens: - - - - - - - - - - - {(() => { - const tokens = { - '--option-tile-background-color': { - global: '--form-control-background-color', - default: '--color-brand-white-base', - }, - '--option-tile-border-color': { - global: '--form-control-border-color', - default: '--color-brand-grey-100', - }, - '--option-tile-border-radius': { - global: '--form-control-size-md-border-radius', - default: '--size-border-radius-md', - }, - '--option-tile-font-family': { - global: '--form-control-font-family', - default: '--asset-fonts-body', - }, - '--option-tile-line-height': { - global: '--form-control-line-height', - default: '--size-line-height-input', - }, - '--option-tile-border-color-hover': { - global: '--form-control-border-color-hover', - default: '--color-brand-grey-300', - }, - '--option-tile-background-color-disabled': { - global: '--form-control-background-color-disabled', - default: '--color-brand-grey-50', - }, - '--option-tile-font-color-disabled': { - global: '--form-control-font-color-disabled', - default: '--color-brand-grey-300', - }, - '--option-tile-border-color-disabled': { - global: '--form-control-border-color', - default: '--color-brand-grey-100', - }, - '--option-tile-font-color-error': { - global: '--form-control-font-color-error', - default: '--color-brand-danger-500', - }, - '--option-tile-border-color-error-hover': { - global: '--form-control-border-color-hover', - default: '--color-brand-grey-300', - }, - '--option-tile-font-color-error-disabled': { - global: '--form-control-font-color-error-disabled', - default: '--color-brand-danger-200', - }, - '--option-tile-border-color-error-disabled-hover': { - global: '--form-control-border-color', - default: '--color-brand-grey-100', - }, - '--option-tile-background-color-selected': { - global: '--form-control-background-color-selected', - default: '--color-brand-primary-50', - }, - '--option-tile-border-color-selected': { - global: '--form-control-border-color-selected', - default: '--color-brand-primary-500', - }, - '--option-tile-background-color-disabled-selected': { - global: '--form-control-background-color-disabled', - default: '--color-brand-grey-50', - }, - '--option-tile-border-color-disabled-selected': { - global: '--form-control-border-color', - default: '--color-brand-grey-100', - }, - '--option-tile-border-color-disabled-selected-hover': { - global: '--form-control-border-color', - default: '--color-brand-grey-100', - }, - '--option-tile-background-color-selected-error': { - global: '--form-control-background-color-error', - default: '--color-brand-danger-50', - }, - '--option-tile-border-color-selected-error': { - global: '--form-control-border-color-selected-error', - default: '--color-brand-danger-500', - }, - '--option-tile-font-color-selected-error': { - global: 'form-control-font-color-error', - default: '--color-brand-danger-500', - }, - '--option-tile-font-color-disabled-selected-error': { - global: '--form-control-font-color-error-disabled', - default: 'color-brand-danger-200', - }, - '--option-tile-border-color-selected-error-hover': { - global: '--form-control-border-color-selected-error', - default: 'color-brand-danger-500', - }, - '--option-tile-border-color-selected-hover': { - global: '--form-control-border-color-selected-hover', - default: '--color-brand-primary-500', - }, - }; - return Object.entries(tokens).map(([name, entry], i) => ( - - - - - - )); - })()} - -
token nameglobal form control tokendefault
- {name} - - {entry.global} - - {entry.default} -
diff --git a/src/components/OptionTile/OptionTile.module.scss b/src/components/OptionTile/OptionTile.module.scss index 8ccd7324f..ceee76fa4 100644 --- a/src/components/OptionTile/OptionTile.module.scss +++ b/src/components/OptionTile/OptionTile.module.scss @@ -1,79 +1,81 @@ .option-tile { - background-color: var(--option-tile-background-color, var(--form-control-background-color, var(--INTERNAL_form-control-background-color))); - border: 1px solid var(--option-tile-border-color, var(--form-control-border-color, var(--INTERNAL_form-control-border-color))); - border-radius: var(--option-tile-border-radius, var(--form-control-size-md-border-radius, var(--INTERNAL_form-control-size-md-border-radius))); - font-family: var(--option-tile-font-family, var(--form-control-font-family, var(--INTERNAL_form-control-font-family))); - line-height: var(--option-tile-line-height, var(--form-control-line-height, var(--INTERNAL_form-control-line-height))); + background-color: var(--color-background-form-control); + border: 1px solid var(--color-border-separator); + border-radius: var(--INTERNAL_form-control-size-md-border-radius); + font-family: var(--asset-fonts-body); + line-height: var(--size-line-height-input); &:focus-within { - box-shadow: var(--form-control-box-shadow-focus, var(--INTERNAL_form-control-box-shadow-focus)), - inset 0 0 0 1px var(--form-control-border-color-focus, var(--INTERNAL_form-control-border-color-focus)); + box-shadow: var(--INTERNAL_form-control-box-shadow-focus), + inset 0 0 0 1px var(--INTERNAL_form-control-border-color-focus); } &:hover { - border: 1px solid var(--option-tile-border-color-hover, var(--form-control-border-color-hover, var(--INTERNAL_form-control-border-color-hover))); + border: 1px solid var(--color-border-default); } // https://stackoverflow.com/questions/262158/disabled-input-text-color-on-ios &.disabled { - background-color: var(--option-tile-background-color-disabled, var(--form-control-background-color-disabled, var(--INTERNAL_form-control-background-color-disabled))); - color: var(--option-tile-font-color-disabled, var(--form-control-font-color-disabled, var(--INTERNAL_form-control-font-color-disabled))); - -webkit-text-fill-color: var(--option-tile-font-color-disabled, var(--form-control-font-color-disabled, var(--INTERNAL_form-control-font-color-disabled))); + background-color: var(--color-background-form-control-disabled); + color: var(--color-text-disabled); + -webkit-text-fill-color: var(--color-text-disabled); opacity: 1; &:hover { cursor: not-allowed; - border: 1px solid var(--option-tile-border-color-hover-disabled, var(--option-tile-border-color, var(--form-control-border-color, var(--INTERNAL_form-control-border-color)))); + border: 1px solid var(--color-border-separator); } } &.error { - color: var(--option-tile-font-color-error, var(--form-control-font-color-error, var(--INTERNAL_form-control-font-color-error))); + color: var(--color-text-danger); &:hover { - border: 1px solid var(--option-tile-border-color-error-hover, var(--form-control-border-color-hover, var(--INTERNAL_form-control-border-color-hover))); + border: 1px solid var(--color-border-default); } &.disabled { - color: var(--option-tile-font-color-error-disabled, var(--form-control-font-color-error-disabled, var(--INTERNAL_form-control-font-color-error-disabled))); - -webkit-text-fill-color: var(--option-tile-font-color-error-disabled, var(--form-control-font-color-error-disabled, var(--INTERNAL_form-control-font-color-error-disabled))); + color: var(--color-text-danger-disabled); + -webkit-text-fill-color: var(--color-text-danger-disabled); &:hover { - border: 1px solid var(--option-tile-border-color-error-disabled-hover, var(--form-control-border-color, var(--INTERNAL_form-control-border-color))); + border: 1px solid var(--color-border-separator); } } } &.selected { - background-color: var(--option-tile-background-color-selected, var(--form-control-background-color-selected, var(--INTERNAL_form-control-background-color-selected))); - border: 1px solid var(--option-tile-border-color-selected, var(--form-control-border-color-selected, var(--INTERNAL_form-control-border-color-selected))); + background-color: var(--color-background-form-control-selected); + border: 1px solid var(--INTERNAL_form-control-border-color-selected); + color: var(--color-text-body-primary); &.disabled { - background-color: var(--option-tile-background-color-disabled-selected, var(--form-control-background-color-disabled, var(--INTERNAL_form-control-background-color-disabled))); - border: 1px solid var(--option-tile-border-color-disabled-selected, var(--form-control-border-color, var(--INTERNAL_form-control-border-color))); + background-color: var(--color-background-form-control-disabled); + border: 1px solid var(--color-border-separator); &:hover { - border: 1px solid var(--option-tile-border-color-disabled-selected-hover, var(--form-control-border-color, var(--INTERNAL_form-control-border-color))); + border: 1px solid var(--color-border-separator); } } &.error { - background-color: var(--option-tile-background-color-selected-error, var(--form-control-background-color-error, var(--INTERNAL_form-control-background-color-error))); - border: 1px solid var(--option-tile-border-color-selected-error, var(--form-control-border-color-selected-error, var(--INTERNAL_form-control-border-color-selected-error))); - color: var(--option-tile-font-color-selected-error, var(--form-control-font-color-error, var(--INTERNAL_form-control-font-color-error))); + background-color: var(--color-background-form-control-error); + border: 1px solid var(--INTERNAL_form-control-border-color-selected-error); + color: var(--color-text-danger); &.disabled { - color: var(--option-tile-font-color-disabled-selected-error, var(--form-control-font-color-error-disabled, var(--INTERNAL_form-control-font-color-error-disabled))); - -webkit-text-fill-color: var(--option-tile-font-color-disabled-selected-error, var(--form-control-font-color-error-disabled, var(--INTERNAL_form-control-font-color-error-disabled))); + color: var(--color-text-danger-disabled); + -webkit-text-fill-color: var(--color-text-danger-disabled); } &:hover { - border: 1px solid var(--option-tile-border-color-selected-error-hover, var(--form-control-border-color-selected-error, var(--INTERNAL_form-control-border-color-selected-error))); + border: 1px solid + var(--INTERNAL_form-control-border-color-selected-error); } } &:hover { - border: 1px solid var(--option-tile-border-color-selected-hover, var(--form-control-border-color-selected-hover, var(--INTERNAL_form-control-border-color-selected-hover))); + border: 1px solid var(--INTERNAL_form-control-border-color-selected); } } } diff --git a/src/components/OptionTileGroup/OptionTileGroup.Overview.stories.mdx b/src/components/OptionTileGroup/OptionTileGroup.Overview.stories.mdx index 4bc0ef6f8..3ae4a5fdf 100644 --- a/src/components/OptionTileGroup/OptionTileGroup.Overview.stories.mdx +++ b/src/components/OptionTileGroup/OptionTileGroup.Overview.stories.mdx @@ -418,12 +418,12 @@ Pass an `error` to an individual option to indicate that something about that sp
-## Full Width (or lack thereof) +## Full Width The OptionsTile component has fullWidth (100%) enabled by default but it can be disabled if need be. - + {() => { const [valueHorizontal, setValueHorizontal] = useState([]); const [valueVertical, setValueVertical] = useState([]); @@ -510,7 +510,7 @@ The tiles can render custom content with a `render` function passed in the optio maxWidth="120px" radius="md" borderWidth="md" - borderColor="grey-light" + borderColor="separator" src="https://www.thespruceeats.com/thmb/BYOHKcXhja-ez7Fr9obgBrDHJ1Y=/3064x2042/filters:fill(auto,1)/easy-chocolate-ice-cream-recipe-1945798-hero-01-45d9f26a0aaf4c1dba38d7e0a2ab51e2.jpg" />
@@ -530,7 +530,7 @@ The tiles can render custom content with a `render` function passed in the optio maxWidth="120px" radius="md" borderWidth="md" - borderColor="grey-light" + borderColor="separator" src="https://www.seriouseats.com/thmb/AVrcpDEKKinSsmgcHvMNxBVCdXc=/1500x844/smart/filters:no_upscale()/__opt__aboutcom__coeus__resources__content_migration__serious_eats__seriouseats.com__recipes__images__2015__07__20150706-strawberry-ice-cream-vicky-wasik-4-f3453966ec94404aaf44da724aef978b.jpg" />
@@ -550,7 +550,7 @@ The tiles can render custom content with a `render` function passed in the optio maxWidth="120px" radius="md" borderWidth="md" - borderColor="grey-light" + borderColor="separator" src="data:image/jpeg;base64,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" />
@@ -569,7 +569,3 @@ The tiles can render custom content with a `render` function passed in the optio }}
- -## Component Design Tokens - -This component shares component design tokens with all form controls. For a complete list of tokens, see the [Theming Form Controls documentation](/docs/theming-form-controls--custom-theme-form). diff --git a/src/components/OptionTileGroup/OptionTileGroup.tsx b/src/components/OptionTileGroup/OptionTileGroup.tsx index 61db40eda..967e45b49 100644 --- a/src/components/OptionTileGroup/OptionTileGroup.tsx +++ b/src/components/OptionTileGroup/OptionTileGroup.tsx @@ -125,7 +125,7 @@ export const OptionTileGroup: ForwardRefExoticComponent = as="legend" display="block" margin="0 0 md 0" - color={hasAnyError ? 'danger' : 'dark'} + color={hasAnyError ? 'danger' : 'body-primary'} fontSize="sm" fontWeight="bold" > diff --git a/src/components/Popover/Popover.Codesandbox.stories.mdx b/src/components/Popover/Popover.Codesandbox.stories.mdx index bdf7367aa..048c2fc78 100644 --- a/src/components/Popover/Popover.Codesandbox.stories.mdx +++ b/src/components/Popover/Popover.Codesandbox.stories.mdx @@ -51,7 +51,7 @@ export default () => { as="nav" fontSize="sm" className="main-nav" - background="white" + background="primary" padding={{ base: '3xl 0 0 0', desktop: '0', @@ -66,7 +66,7 @@ export default () => { fontSize="xs" color="white" radius="sm" - background="primary-light" + background="primary-100" padding="2xs" > JC @@ -95,7 +95,7 @@ export default () => { childGap="sm" padding="lg 0 0 0" borderWidth="xs 0 0 0" - borderColor="grey-lighter" + borderColor="separator" style={{ flexShrink: 0 }} > @@ -111,7 +111,7 @@ export default () => { childGap="sm" padding="lg 0 0 0" borderWidth="xs 0 0 0" - borderColor="grey-lighter" + borderColor="separator" style={{ flex: '1 0 auto' }} > diff --git a/src/components/Popover/Popover.Overview.stories.mdx b/src/components/Popover/Popover.Overview.stories.mdx index 87fae2e7a..2d6a0f9c7 100644 --- a/src/components/Popover/Popover.Overview.stories.mdx +++ b/src/components/Popover/Popover.Overview.stories.mdx @@ -113,8 +113,7 @@ You can apply a custom class to your popover with the `className` prop. Here we ## Popover Styling Because the rendered Popover is powered by our `Box` component ([Read More](/?path=/docs/components-box-overview--background)) you -can use all known box props to style it. The below example includes some of the basics, but is not representative of -the entire gamut of styling options. +can use all known box props to style it using the `contentContainerProps` prop. { const { isOpen: isPopoverOpen, handleToggle: togglePopover } = useOpenClose(); - const [popoverBackground, setPopoverBackground] = useState({ - value: 'white', - label: 'White', - }); - const [popoverFontColor, setPopoverFontColor] = useState({ - value: 'dark', - label: 'Dark', - }); - const [popoverRadius, setPopoverRadius] = useState({ - value: 'sm', - label: 'Small', - }); - const backgroundOptions = [ - { value: 'white', label: 'White' }, - { value: 'primary', label: 'Primary' }, - { value: 'secondary', label: 'Secondary' }, - { value: 'tertiary', label: 'Tertiary' }, - { value: 'warning', label: 'Warning' }, - { value: 'grey-light', label: 'Grey Light' }, - { value: 'grey-dark', label: 'Grey Dark' }, - ]; - const fontColorOptions = [ - { value: 'white', label: 'White' }, - { value: 'dark', label: 'Dark' }, - ]; - const borderRadiusOptions = [ - { value: 'sm', label: 'Small' }, - { value: 'md', label: 'Medium' }, - { value: 'lg', label: 'Large' }, - ]; return ( @@ -170,9 +139,9 @@ the entire gamut of styling options. placement={'right'} contentContainerProps={{ padding: 'sm', - background: popoverBackground.value, - color: popoverFontColor.value, - radius: popoverRadius.value, + background: 'info', + color: 'white', + radius: 'md', }} > - - - { - setPopoverBackground(event.target.value); - }} - value={popoverBackground} - label="Background Color" - /> - - - { - setPopoverFontColor(event.target.value); - }} - value={popoverFontColor} - label="Font Color" - /> - - - { - setPopoverRadius(event.target.value); - }} - value={popoverRadius} - label="Border Radius" - /> - - ); }} @@ -284,8 +221,6 @@ prevent the content from getting cut off. placement={position} contentContainerProps={{ padding: 'sm', - background: 'secondary', - color: 'white', }} > + )); }); @@ -317,7 +343,9 @@ describe('Toast', () => { }); expect(screen.getByText('test compact toast')).toBeInTheDocument(); - expect(screen.getByText('test compact toast').parentElement).toHaveClass('p-sm'); + expect(screen.getByText('test compact toast').parentElement).toHaveClass( + 'p-sm', + ); act(() => { toast.dismiss(); @@ -406,74 +434,121 @@ describe('Toast', () => { test('Default duration -- blank toast', async () => { render(); - act(() => { toast('default timeout blank toast'); }); - expect(screen.getByText('default timeout blank toast')).toBeInTheDocument(); + act(() => { + toast('default timeout blank toast'); + }); + expect( + screen.getByText('default timeout blank toast'), + ).toBeInTheDocument(); // After 3000ms nothing should have changed. - act(() => { jest.advanceTimersByTime(3000); }); - expect(screen.getByText('default timeout blank toast')).toBeInTheDocument(); + act(() => { + jest.advanceTimersByTime(3000); + }); + expect( + screen.getByText('default timeout blank toast'), + ).toBeInTheDocument(); // After 4000ms (3000 + 1000) the toast should still be in the DOM, // but not visible. We confirm this with the `not-visible` class. - act(() => { jest.advanceTimersByTime(1000); }); - expect(screen.getByText('default timeout blank toast')?.parentElement) - .toHaveClass('toast-notification--not-visible'); + act(() => { + jest.advanceTimersByTime(1000); + }); + expect( + screen.getByText('default timeout blank toast')?.parentElement, + ).toHaveClass('toast-notification--not-visible'); // After another 1000ms the toast is cleared from the DOM completely (after animation is done). - act(() => { jest.advanceTimersByTime(1000); }); + act(() => { + jest.advanceTimersByTime(1000); + }); expect(screen.queryByText('default timeout blank toast')).toBe(null); }); test('Default duration -- error toast', async () => { render(); - act(() => { toast.error('default timeout error toast'); }); - expect(screen.getByText('default timeout error toast')).toBeInTheDocument(); + act(() => { + toast.error('default timeout error toast'); + }); + expect( + screen.getByText('default timeout error toast'), + ).toBeInTheDocument(); // After 3000ms nothing should have changed. - act(() => { jest.advanceTimersByTime(3000); }); - expect(screen.getByText('default timeout error toast')).toBeInTheDocument(); + act(() => { + jest.advanceTimersByTime(3000); + }); + expect( + screen.getByText('default timeout error toast'), + ).toBeInTheDocument(); // After 4000ms (3000 + 1000) the toast should still be in the DOM, // but not visible. We confirm this with the `not-visible` class. - act(() => { jest.advanceTimersByTime(1000); }); - expect(screen.getByText('default timeout error toast')?.parentElement) - .toHaveClass('toast-notification--not-visible'); + act(() => { + jest.advanceTimersByTime(1000); + }); + expect( + screen.getByText('default timeout error toast')?.parentElement, + ).toHaveClass('toast-notification--not-visible'); // After another 1000ms the toast is cleared from the DOM completely (after animation is done). - act(() => { jest.advanceTimersByTime(1000); }); + act(() => { + jest.advanceTimersByTime(1000); + }); expect(screen.queryByText('default timeout error toast')).toBe(null); }); test('Default duration -- success toast', async () => { render(); - act(() => { toast.success('default timeout success toast'); }); - expect(screen.getByText('default timeout success toast')).toBeInTheDocument(); + act(() => { + toast.success('default timeout success toast'); + }); + expect( + screen.getByText('default timeout success toast'), + ).toBeInTheDocument(); // After 1000ms nothing should have changed. - act(() => { jest.advanceTimersByTime(1000); }); - expect(screen.getByText('default timeout success toast')).toBeInTheDocument(); + act(() => { + jest.advanceTimersByTime(1000); + }); + expect( + screen.getByText('default timeout success toast'), + ).toBeInTheDocument(); // After 2000ms (1000 + 1000) the toast should still be in the DOM, // but not visible. We confirm this with the `not-visible` class. - act(() => { jest.advanceTimersByTime(1000); }); - expect(screen.getByText('default timeout success toast')?.parentElement) - .toHaveClass('toast-notification--not-visible'); + act(() => { + jest.advanceTimersByTime(1000); + }); + expect( + screen.getByText('default timeout success toast')?.parentElement, + ).toHaveClass('toast-notification--not-visible'); // After another 1000ms the toast is cleared from the DOM completely (after animation is done). - act(() => { jest.advanceTimersByTime(1000); }); + act(() => { + jest.advanceTimersByTime(1000); + }); expect(screen.queryByText('default timeout success toast')).toBe(null); }); test('Default duration -- loading toast', async () => { render(); - act(() => { toast.loading('default timeout loading toast'); }); - expect(screen.getByText('default timeout loading toast')).toBeInTheDocument(); + act(() => { + toast.loading('default timeout loading toast'); + }); + expect( + screen.getByText('default timeout loading toast'), + ).toBeInTheDocument(); // After any amount of time nothing should have changed. - act(() => { jest.advanceTimersByTime(999999); }); - expect(screen.getByText('default timeout loading toast')).toBeInTheDocument(); + act(() => { + jest.advanceTimersByTime(999999); + }); + expect( + screen.getByText('default timeout loading toast'), + ).toBeInTheDocument(); // Toast can be dismissed programmatically, however. act(() => { @@ -485,40 +560,70 @@ describe('Toast', () => { test('With a custom duration on the container', async () => { render(); - act(() => { toast('custom timeout on container toast'); }); - expect(screen.getByText('custom timeout on container toast')).toBeInTheDocument(); + act(() => { + toast('custom timeout on container toast'); + }); + expect( + screen.getByText('custom timeout on container toast'), + ).toBeInTheDocument(); // After 8000ms nothing should have changed. - act(() => { jest.advanceTimersByTime(8000); }); - expect(screen.getByText('custom timeout on container toast')).toBeInTheDocument(); + act(() => { + jest.advanceTimersByTime(8000); + }); + expect( + screen.getByText('custom timeout on container toast'), + ).toBeInTheDocument(); // after 10000ms toast should be in DOM but not visible. - act(() => { jest.advanceTimersByTime(2000); }); - expect(screen.getByText('custom timeout on container toast')?.parentElement) - .toHaveClass('toast-notification--not-visible'); + act(() => { + jest.advanceTimersByTime(2000); + }); + expect( + screen.getByText('custom timeout on container toast')?.parentElement, + ).toHaveClass('toast-notification--not-visible'); // after another 1000ms the toast should be removed from the DOM. - act(() => { jest.advanceTimersByTime(1000); }); - expect(screen.queryByText('custom timeout on container toast')).toBe(null); + act(() => { + jest.advanceTimersByTime(1000); + }); + expect(screen.queryByText('custom timeout on container toast')).toBe( + null, + ); }); test('Overriding container duration in single toast', async () => { render(); - act(() => { toast('custom timeout on individual toast', { duration: 10000 }); }); - expect(screen.getByText('custom timeout on individual toast')).toBeInTheDocument(); + act(() => { + toast('custom timeout on individual toast', { duration: 10000 }); + }); + expect( + screen.getByText('custom timeout on individual toast'), + ).toBeInTheDocument(); // After 8000ms nothing should have changed. - act(() => { jest.advanceTimersByTime(8000); }); - expect(screen.getByText('custom timeout on individual toast')).toBeInTheDocument(); + act(() => { + jest.advanceTimersByTime(8000); + }); + expect( + screen.getByText('custom timeout on individual toast'), + ).toBeInTheDocument(); // after 10000ms toast should be in DOM but not visible. - act(() => { jest.advanceTimersByTime(2000); }); - expect(screen.getByText('custom timeout on individual toast')?.parentElement) - .toHaveClass('toast-notification--not-visible'); + act(() => { + jest.advanceTimersByTime(2000); + }); + expect( + screen.getByText('custom timeout on individual toast')?.parentElement, + ).toHaveClass('toast-notification--not-visible'); // after another 1000ms the toast should be removed from the DOM. - act(() => { jest.advanceTimersByTime(1000); }); - expect(screen.queryByText('custom timeout on individual toast')).toBe(null); + act(() => { + jest.advanceTimersByTime(1000); + }); + expect(screen.queryByText('custom timeout on individual toast')).toBe( + null, + ); }); }); @@ -542,31 +647,42 @@ describe('Toast', () => { test('Pause duration on mouseover', async () => { render(); - act(() => { toast('default timeout blank toast'); }); + act(() => { + toast('default timeout blank toast'); + }); expect(screen.getByText('default timeout blank toast')).toBeInTheDocument(); // Mousing over the element should delay the duration until toast is dismissed await fireEvent.mouseOver(screen.getByText('default timeout blank toast')); // Toast should still be present since user has moused over it. - act(() => { jest.advanceTimersByTime(99999); }); + act(() => { + jest.advanceTimersByTime(99999); + }); expect(screen.getByText('default timeout blank toast')).toBeInTheDocument(); // Mouse out should re-start timer. await fireEvent.mouseOut(screen.getByText('default timeout blank toast')); // After 3000ms nothing should have changed. - act(() => { jest.advanceTimersByTime(3000); }); + act(() => { + jest.advanceTimersByTime(3000); + }); expect(screen.getByText('default timeout blank toast')).toBeInTheDocument(); // After 4000ms (3000 + 1000) the toast should still be in the DOM, // but not visible. We confirm this with the `not-visible` class. - act(() => { jest.advanceTimersByTime(1000); }); - expect(screen.getByText('default timeout blank toast')?.parentElement) - .toHaveClass('toast-notification--not-visible'); + act(() => { + jest.advanceTimersByTime(1000); + }); + expect( + screen.getByText('default timeout blank toast')?.parentElement, + ).toHaveClass('toast-notification--not-visible'); // After another 1000ms the toast is cleared from the DOM completely (after animation is done). - act(() => { jest.advanceTimersByTime(1000); }); + act(() => { + jest.advanceTimersByTime(1000); + }); expect(screen.queryByText('default timeout blank toast')).toBe(null); }); @@ -630,7 +746,9 @@ describe('Toast', () => { }); expect(screen.queryByText('update after dismiss')).toBe(null); - expect(screen.getByText('updated after dismiss to success')).toBeInTheDocument(); + expect( + screen.getByText('updated after dismiss to success'), + ).toBeInTheDocument(); act(() => { toast.remove(); diff --git a/src/components/Toast/ToastNotification.module.scss b/src/components/Toast/ToastNotification.module.scss index a56199435..e6a41b7e0 100644 --- a/src/components/Toast/ToastNotification.module.scss +++ b/src/components/Toast/ToastNotification.module.scss @@ -1,15 +1,15 @@ .toast-notification { - background-color: var(--toast-notification-background-color, var(--color-brand-grey-800)); - color: var(--toast-notification-font-color, var(--color-brand-white-500)); - border-radius: var(--toast-notification-border-radius, var(--size-border-radius-sm)); - box-shadow: var(--toast-notification-box-shadow, var(--size-box-shadow-2xs)); + background-color: var(--color-background-inverse); + color: var(--color-text-inverse-primary); + border-radius: var(--size-border-radius-sm); + box-shadow: var(--size-box-shadow-2xs); will-change: transform; pointer-events: auto; } .toast-dismiss { - border-color: var(--toast-notification-dismiss-border-color, var(--color-brand-grey-600)); - color: var(--toast-notification-dismiss-color, var(--color-brand-white-500)); + border-color: var(--color-border-toast-separator); + color: var(--color-background-inverse-primary); } .toast-notification-enter-top { diff --git a/src/components/Toast/ToastNotification.tsx b/src/components/Toast/ToastNotification.tsx index 8e32b32e9..703ffca94 100644 --- a/src/components/Toast/ToastNotification.tsx +++ b/src/components/Toast/ToastNotification.tsx @@ -25,25 +25,33 @@ interface ToastNotificationProps { /** * Render function to create custom toast notification. */ - children?: (components: { - message: React.ReactNode; - }) => React.ReactNode; + children?: (components: { message: React.ReactNode; }) => React.ReactNode; /** * Handler for when the dismiss button is pressed. */ onDismiss?: () => void; } -const getAnimationClass = (position: ToastPosition, visible: boolean): React.CSSProperties => { +const getAnimationClass = ( + position: ToastPosition, + visible: boolean, +): React.CSSProperties => { const verticalPosition = position.includes('top') ? 'top' : 'bottom'; const horizontalPosition = position.includes('left') ? 'left' : 'right'; const isCentered = position.includes('center'); const [enter, exit] = prefersReducedMotion() - ? [styles['toast-notification-fade-in'], styles['toast-notification-fade-out']] + ? [ + styles['toast-notification-fade-in'], + styles['toast-notification-fade-out'], + ] : [ styles[`toast-notification-enter-${verticalPosition}`], - styles[`toast-notification-exit-${isCentered ? verticalPosition : horizontalPosition}`], + styles[ + `toast-notification-exit-${ + isCentered ? verticalPosition : horizontalPosition + }` + ], ]; return visible ? enter : exit; @@ -55,7 +63,7 @@ const renderToastIcon = (toast: Toast) => { if (type === 'blank') return; let iconName: IconName = 'exclamation-mark'; - let iconColor: FontColor = 'dark'; + let iconColor: FontColor = 'grey-600'; if (type === 'success') { iconName = 'c-check'; @@ -67,7 +75,11 @@ const renderToastIcon = (toast: Toast) => { iconColor = 'danger-300'; } - const icon = type !== 'loading' ? : ; + const icon = type !== 'loading' ? ( + + ) : ( + + ); // eslint-disable-next-line consistent-return return ( @@ -79,7 +91,10 @@ const renderToastIcon = (toast: Toast) => { const toastTypesWithIcon: ToastType[] = ['error', 'success', 'loading']; -const renderDismissIcon = (toast: Toast, onDismiss: ToastNotificationProps['onDismiss']) => { +const renderDismissIcon = ( + toast: Toast, + onDismiss: ToastNotificationProps['onDismiss'], +) => { if (!toast.canDismiss) return; // eslint-disable-next-line consistent-return @@ -103,14 +118,14 @@ const renderDismissIcon = (toast: Toast, onDismiss: ToastNotificationProps['onDi // eslint-disable-next-line import/prefer-default-export export const ToastNotification: React.FC = React.memo( - ({ - toast, position = 'top-center', style, children, onDismiss, - }) => { + ({ toast, position = 'top-center', style, children, onDismiss }) => { const message = ( = React.memo( ); - const animationClass = toast?.height ? getAnimationClass(toast.position || position, toast.visible) : undefined; + const animationClass = toast?.height + ? getAnimationClass(toast.position || position, toast.visible) + : undefined; const classes = classNames( toast.className, @@ -141,7 +158,7 @@ export const ToastNotification: React.FC = React.memo( style={{ ...style, ...toast.style, - ...!toast.height && { opacity: 0 }, + ...(!toast.height && { opacity: 0 }), }} > {typeof children === 'function' ? ( diff --git a/src/components/Toggle/Toggle.Overview.stories.mdx b/src/components/Toggle/Toggle.Overview.stories.mdx index f15ce7dcc..d3c472794 100644 --- a/src/components/Toggle/Toggle.Overview.stories.mdx +++ b/src/components/Toggle/Toggle.Overview.stories.mdx @@ -224,33 +224,3 @@ Use the `error` prop to mark the input as invalid. `error` accepts a `boolean`, }} - -## Component Design Tokens - - - - - - - - - - {(() => { - const tokens = { - '--toggle-background-color': '--color-brand-grey-200', - '--toggle-background-color-checked': '--color-brand-primary-500', - '--toggle-background-color-error': '--color-brand-danger-500', - }; - return Object.entries(tokens).map(([name, entry], i) => ( - - - - - )); - })()} - -
token namedefault value
- {name} - - {entry} -
diff --git a/src/components/Toggle/Toggle.module.scss b/src/components/Toggle/Toggle.module.scss index bf64b73e7..394211637 100644 --- a/src/components/Toggle/Toggle.module.scss +++ b/src/components/Toggle/Toggle.module.scss @@ -169,19 +169,19 @@ transition: transform 0.25s ease; border-radius: 50%; box-shadow: 0 0 2px rgb(0 0 0 / 45%); - background-color: var(--color-brand-white-base); + background-color: var(--color-background-white); } .toggle-track { display: block; transition: background-color 0.25s ease; border-radius: 9999em; - background-color: var(--toggle-background-color, var(--color-brand-grey-200)); + background-color: var(--color-background-toggle); cursor: pointer; padding: 2px; &.error { - background-color: var(--toggle-background-color-error, var(--color-brand-danger-500)); + background-color: var(--color-background-toggle-error); } } @@ -198,11 +198,11 @@ white-space: nowrap; &:checked + .toggle-track { - background-color: var(--toggle-background-color-checked, var(--color-brand-primary-500)); + background-color: var(--color-background-toggle-checked); } &:checked + .toggle-track.error { - background-color: var(--toggle-background-color-error, var(--color-brand-danger-500)); + background-color: var(--color-background-toggle-error); } &:checked + .toggle-track .toggle-thumb.thumb-size-sm { @@ -259,16 +259,21 @@ } } - &:focus + .toggle-track { outline: 0; - box-shadow: var(--form-control-box-shadow-focus, var(--INTERNAL_form-control-box-shadow-focus)); + box-shadow: var( + --form-control-box-shadow-focus, + var(--INTERNAL_form-control-box-shadow-focus) + ); } // Show focus styles on keyboard focus. &:focus-visible + .toggle-track { outline: 0; - box-shadow: var(--form-control-box-shadow-focus, var(--INTERNAL_form-control-box-shadow-focus)); + box-shadow: var( + --form-control-box-shadow-focus, + var(--INTERNAL_form-control-box-shadow-focus) + ); } // Hide focus styles if they are not needed, for example, diff --git a/src/declarations.d.ts b/src/declarations.d.ts index 8a80c711f..12294d07b 100644 --- a/src/declarations.d.ts +++ b/src/declarations.d.ts @@ -3,6 +3,9 @@ declare module '*.svg'; declare module '@palmetto/palmetto-design-tokens/build/js/variables-size'; declare module '@palmetto/palmetto-design-tokens/build/js/variables-color'; declare module '@palmetto/palmetto-design-tokens/build/js/variables-asset'; +declare module '@palmetto/palmetto-design-tokens/build/json/values/variables-size.json'; +declare module '@palmetto/palmetto-design-tokens/build/json/values/variables-color.json'; +declare module '@palmetto/palmetto-design-tokens/build/json/variables-asset.json'; declare module '@palmetto/palmetto-design-tokens/build/types/'; declare module '@palmetto/palmetto-design-tokens/build/icons/react'; declare module '@palmetto/palmetto-design-tokens/build/icons'; diff --git a/src/docs/Content.GoalsPrinciples.stories.mdx b/src/docs/Content.GoalsPrinciples.stories.mdx index 5b337d14e..1db5764cd 100644 --- a/src/docs/Content.GoalsPrinciples.stories.mdx +++ b/src/docs/Content.GoalsPrinciples.stories.mdx @@ -1,20 +1,38 @@ - import { Box, Heading } from '../components'; - - These guidelines may be modified, expanded, or updated over time as new needs arise. It’s impossible to predict every possible content need, and there may be exceptions that are required to aid with legibility, branding, etc. If you have any questions about how to use this guide, or you have a content need that goes against one of these guidelines, please post that request in the #Content Slack Channel and it will be reviewed for consideration. + + These guidelines may be modified, expanded, or updated over time as new needs + arise. It’s impossible to predict every possible content need, and there may + be exceptions that are required to aid with legibility, branding, etc. If you + have any questions about how to use this guide, or you have a content need + that goes against one of these guidelines, please post that request in the{' '} + + #Content Slack Channel + {' '} + and it will be reviewed for consideration. - + - - Content Goals - With every piece of content we publish, we aim to: +{' '} + + + Content Goals + + + With every piece of content we publish, we aim to: + @@ -65,13 +83,17 @@ import { Box, Heading } from '../components'; - - - Content Principles - In order to achieve our content goals, we follow these principles: +{' '} + + + Content Principles + + + In order to achieve our content goals, we follow these principles: + diff --git a/src/docs/FormTheming.stories.mdx b/src/docs/FormTheming.stories.mdx deleted file mode 100644 index 0ec7097cc..000000000 --- a/src/docs/FormTheming.stories.mdx +++ /dev/null @@ -1,280 +0,0 @@ -import { Meta, Story, Canvas } from '@storybook/addon-docs'; -import { useState } from 'react'; -import { TextInput } from '../components/TextInput/TextInput'; -import { TextInputInset } from '../components/TextInputInset/TextInputInset'; -import { CheckboxInput } from '../components/CheckboxInput/CheckboxInput'; -import { SelectInput } from '../components/SelectInput/SelectInput'; -import { SelectInputNative } from '../components/SelectInputNative/SelectInputNative'; -import { SelectInputInset } from '../components/SelectInputInset/SelectInputInset'; -import { OptionTileGroup } from '../components/OptionTileGroup/OptionTileGroup'; -import { RadioGroup } from '../components/RadioGroup/RadioGroup'; -import { TextareaInput } from '../components/TextareaInput/TextareaInput'; -import { TextareaInputInset } from '../components/TextareaInputInset/TextareaInputInset'; -import { Toggle } from '../components/Toggle/Toggle'; -import { Button } from '../components/Button/Button'; -import { Box } from '../components/Box/Box'; -import { TimePickerNative } from '../components/TimePickerNative/TimePickerNative'; - - - -# Theming Form Controls - -Form controls share tokens since they are designed to have a consistent appearance (e.g. a TextInput and SelectInput look similar). Instead of redefining individual component specific tokens, the following tokens only need to be set once, and all form controls will take on their new appearance. - - - - {() => { - const options = [ - { - id: 'car', - value: 'car', - label: 'Car', - }, - { - id: 'truck', - value: 'truck', - label: 'Truck', - }, - { - id: 'motorcycle', - value: 'motorcycle', - label: 'Motorcycle', - }, - ]; - const [isThemed, setIsThemed] = useState(true); - const [themeExampleValues, setThemeExampleValues] = useState({ - multiSelectValue: [ - { - id: 'motorcycle', - value: 'motorcycle', - label: 'Motorcycle', - }, - { - id: 'truck', - value: 'truck', - label: 'Truck', - }, - ], - optionTileGroupValue: options[0].value, - radioValue: options[0].value, - selectValue: options[0].value, - textValue: 'hello world', - textareaValue: 'hello world', - emptyValue: '', - }); - const handleChange = (key, value) => { - setThemeExampleValues(prevFields => ({ - ...prevFields, - [key]: value, - })); - }; - const customTheme = { - '--color-brand-primary-50': '#FAF5FF', - '--color-brand-primary-100': '#E9D8FD', - '--color-brand-primary-200': '#D6BCFA', - '--color-brand-primary-300': '#B794F4', - '--color-brand-primary-400': '#9F7AEA', - '--color-brand-primary-500': '#805AD5', - '--color-brand-primary-600': '#6B46C1', - '--color-brand-primary-700': '#553C9A', - '--color-brand-primary-800': '#44337A', - '--color-brand-primary-900': '#322659', - '--form-control-size-md-border-radius': 0, - '--form-control-font-family': 'Consolas,monaco,monospace', - '--form-control-border-color': '#D6BCFA', - '--form-control-border-color-hover': '#805AD5', - }; - return ( - - setIsThemed(e.target.checked)} - /> - handleChange('emptyValue', event.target.value)} - /> - handleChange('textValue', event.target.value)} - /> - handleChange('textValue', event.target.value)} - /> - handleChange('selectValue', event.target.value)} - options={options} - value={themeExampleValues.selectValue} - /> - handleChange('selectValue', event.target.value)} - options={options} - value={themeExampleValues.selectValue} - /> - - handleChange('multiSelectValue', event.target.value) - } - /> - handleChange('textareaValue', e.target.value)} - /> - handleChange('textareaValue', e.target.value)} - /> - - {}} - isChecked - /> - {}} - /> - - handleChange('radioValue', event.target.value)} - value={themeExampleValues.radioValue} - options={options} - direction="row" - /> - - handleChange('optionTileGroupValue', event.target.value) - } - options={options} - direction="row" - /> - - ); - }} - - - -## Form Control Common Tokens - -The following tokens are shared by all form controls to maintain a consistent appearance. - -
- - - - - - - - {(() => { - const tokens = { - 'form-control-box-shadow-focus': '0 0 0 4px --color-brand-primary-200', - 'form-control-label-margin': '--size-spacing-xs', - 'form-control-help-margin': '--size-spacing-2xs', - 'form-control-line-height': '--size-line-height-input', - 'form-control-help-text-font-size': 'var(--size-font-sm)', - 'form-control-help-text-font-weight': 'var(--size-font-weight-regular)', - 'form-control-label-font-weight': 'var(--size-font-weight-medium)', - 'form-control-legend-font-weight': 'var(--size-font-weight-medium)', - 'form-control-box-shadow': '0 3px 0 rgba(0, 0, 0, 0.05)', - 'form-control-font-family': '--asset-fonts-body', - 'form-control-size-xs-border-radius': '--size-border-radius-sm', - 'form-control-size-xs-font-size': '--size-font-xs', - 'form-control-size-xs-padding': '--size-spacing-2xs', - 'form-control-size-sm-border-radius': '--size-border-radius-sm', - 'form-control-size-sm-font-size': '--size-font-sm', - 'form-control-size-sm-padding': '--size-spacing-xs', - 'form-control-size-md-label-size': '--size-font-sm', - 'form-control-size-md-border-radius': '--size-border-radius-md', - 'form-control-size-md-font-size': '--size-font-md', - 'form-control-size-md-padding': '--size-spacing-sm', - 'form-control-size-lg-border-radius': '--size-border-radius-md', - 'form-control-size-lg-font-size': '--size-font-lg', - 'form-control-size-lg-padding': '--size-spacing-md', - 'form-control-background-color': '--color-brand-white-base', - 'form-control-background-color-disabled': '--color-brand-grey-50', - 'form-control-background-color-error': '--color-brand-danger-50', - 'form-control-background-color-selected': '--color-brand-primary-50', - 'form-control-border-color': '--color-brand-grey-100', - 'form-control-border-color-error': '--color-brand-danger-100', - 'form-control-border-color-focus': '--color-brand-grey-600', - 'form-control-border-color-hover': '--color-brand-grey-300', - 'form-control-border-color-selected': '--color-brand-primary-500', - 'form-control-border-color-selected-hover': '--color-brand-primary-500', - 'form-control-font-color': '--color-brand-grey-700', - 'form-control-font-color-disabled': '--color-brand-grey-300', - 'form-control-font-color-error': '--color-brand-danger-base', - 'form-control-font-color-error-disabled': '--color-brand-danger-200', - 'form-control-help-text-font-color': 'var(--color-brand-grey-500)', - 'form-control-label-font-color': 'var(--color-brand-grey-700)', - 'form-control-description-color': '--color-brand-grey-600', - 'form-control-icon-color': '--color-brand-grey-300', - 'form-control-icon-color-hover': '--color-brand-grey', - 'form-control-placeholder-color': '--color-brand-grey-300', - 'form-control-checkbox-color': '--color-brand-grey-500', - 'form-control-checkbox-color-checked': '--color-brand-primary-500', - 'form-control-checkbox-color-disabled': '--color-brand-primary-200', - 'form-control-checkbox-color-checked-disabled': - '--color-brand-primary-200', - 'form-control-radio-group-description-spacing': '--size-spacing-xs', - 'form-control-radio-group-options-spacing': '--size-spacing-md', - 'form-control-select-sm-icon-size': '20px', - 'form-control-select-md-icon-size': '32px', - 'form-control-select-lg-icon-size': '34px', - 'form-control-select-padding': '--size-spacing-2xs', - 'form-control-select-clear-icon-margin': '--size-spacing-xs', - 'form-control-text-clear-icon-margin': '--size-spacing-xs', - 'form-control-text-clear-icon-font-size': '--size-font-md', - }; - return Object.entries(tokens).map(([name, entry], i) => ( - - - - - )); - })()} - -
token namedefault value
- {name} - - {entry} -
-import {TextareaInputInset} from 'src/components/TextareaInputInset/TextareaInputInset'; diff --git a/src/docs/Foundation.DesignTokens.stories.mdx b/src/docs/Foundation.DesignTokens.stories.mdx index 6a889c30e..d845ba866 100644 --- a/src/docs/Foundation.DesignTokens.stories.mdx +++ b/src/docs/Foundation.DesignTokens.stories.mdx @@ -1,5 +1,5 @@ import { ColorPalette, ColorItem, Meta } from '@storybook/addon-docs'; -import { color } from '@palmetto/palmetto-design-tokens/build/json/variables-color.json'; +import { color } from '@palmetto/palmetto-design-tokens/build/js/variables-color'; import { size } from '@palmetto/palmetto-design-tokens/build/js/variables-size'; import { asset } from '@palmetto/palmetto-design-tokens/build/js/variables-asset'; import { Canvas } from '@storybook/addon-docs'; @@ -18,34 +18,6 @@ We use [Style Dictionary](https://amzn.github.io/style-dictionary/) to generate [Palmetto Design Tokens](https://github.com/palmetto/palmetto-design-tokens) are available as an [npm package](https://www.npmjs.com/package/@palmetto/palmetto-design-tokens) so that you can create a Palmetto unified product experience for your platform of choice. -## Types - -### Global Tokens - -Global tokens are the primitive values in our design language, represented by context-agnostic names. Color palette, spacing, typography, and dimension values are all recorded as global tokens. These can be directly used, and are inherited by all other token types. - -```css ---color-brand-grey-500: #2f8459; -``` - -### Alias Tokens or Common Tokens - -Alias tokens relate to a specific context or abstraction. Aliases help communicate the intended purpose of a token, and are effective when a value with a single intent will appear in multiple places. - -```css ---color-brand-primary-base: #008433; /* alias */ ---form-control-background-color: --color-brand-white-base; /* common */ -``` - -### Component Specific Tokens - -Component-specific tokens have the most specific component level context. They often inherit from alias or global tokens, but are named in a way that allows consumers to be as specific as possible in applying tokens in component development. - -```css ---button-background-color: --color-brand-primary-base; /* component */ ---badge-size-xl-font-size: --size-font-md; -``` - ## Border Radius Use these tokens for `border-radius`. They are defined in `rem`, which means they will scale when adjusting the root font size. Pixel values are calculated with a root font size of `16px`. @@ -153,7 +125,7 @@ The following breakpoints are used in utility classes, but you can use them to m ))} - size-breakpoint-base + size-breakpoint-500 0px @@ -162,102 +134,196 @@ The following breakpoints are used in utility classes, but you can use them to m ## Color - +Refer to the [Palmetto Design Tokens Figma](https://www.figma.com/design/abGRptpr7iPaMsXdEPVm6W/Design-Tokens?node-id=0-1&t=oY6gZSqBDdP10U54-1) for colors. + +### Brand Palette - { - acc[item] = Object.keys(color.brand.white).map(g => color.brand.white[g].value)[i]; - return acc; - }, {})} -/> - - { - acc[item] = Object.keys(color.brand.black).map(g => color.brand.black[g].value)[i]; - return acc; - }, {})} -/> - - { - acc[item] = Object.keys(color.brand.light).map(g => color.brand.light[g].value)[i]; - return acc; - }, {})} -/> - - { - acc[item] = Object.keys(color.brand.dark).map(g => color.brand.dark[g].value)[i]; - return acc; - }, {})} -/> - - { - acc[item] = Object.keys(color.brand.grey).map(g => color.brand.grey[g].value)[i]; - return acc; - }, {})} -/> - { - acc[item] = Object.keys(color.brand.primary).map(g => color.brand.primary[g].value)[i]; - return acc; - }, {})} -/> - { - acc[item] = Object.keys(color.brand.secondary).map(g => color.brand.secondary[g].value)[i]; - return acc; - }, {})} -/> - { - acc[item] = Object.keys(color.brand.tertiary).map(g => color.brand.tertiary[g].value)[i]; - return acc; - }, {})} -/> - { - acc[item] = Object.keys(color.brand.info).map(g => color.brand.info[g].value)[i]; - return acc; - }, {})} -/> - { - acc[item] = Object.keys(color.brand.warning).map(g => color.brand.warning[g].value)[i]; - return acc; - }, {})} -/> - { - acc[item] = Object.keys(color.brand.danger).map(g => color.brand.danger[g].value)[i]; - return acc; - }, {})} -/> + + { + acc[item] = Object.keys(color.brand.primary).map( + g => color.brand.primary[g].value, + )[i]; + return acc; + }, {})} + /> + { + acc[item] = Object.keys(color.brand.secondary).map( + g => color.brand.secondary[g].value, + )[i]; + return acc; + }, {})} + /> + { + acc[item] = Object.keys(color.brand.tertiary).map( + g => color.brand.tertiary[g].value, + )[i]; + return acc; + }, {})} + /> + { + acc[item] = Object.keys(color.brand.success).map( + g => color.brand.success[g].value, + )[i]; + return acc; + }, {})} + /> + { + acc[item] = Object.keys(color.brand.info).map( + g => color.brand.info[g].value, + )[i]; + return acc; + }, {})} + /> + { + acc[item] = Object.keys(color.brand.warning).map( + g => color.brand.warning[g].value, + )[i]; + return acc; + }, {})} + /> + { + acc[item] = Object.keys(color.brand.orange).map( + g => color.brand.orange[g].value, + )[i]; + return acc; + }, {})} + /> + { + acc[item] = Object.keys(color.brand.danger).map( + g => color.brand.danger[g].value, + )[i]; + return acc; + }, {})} + /> + { + acc[item] = Object.keys(color.brand.grey).map( + g => color.brand.grey[g].value, + )[i]; + return acc; + }, {})} + /> +### Background Color Tokens + + + + + + + + + + + + + + {Object.entries(color.background).map(([name, entry], i) => ( + + + + + + + + + ))} + +
Token NameProp ValueValueDark Value
+ {`color-background-${name}`} + + {name} + {entry.value}{entry.darkValue}
+ +### Border Color Tokens + + + + + + + + + + + + + + {Object.entries(color.border).map(([name, entry], i) => ( + + + + + + + + + ))} + +
Token NameProp ValueValueDark Value
+ {`color-border-${name}`} + + {name} + {entry.value}{entry.darkValue}
+ +### Font Color Tokens + + + + + + + + + + + + + + {Object.entries(color.text).map(([name, entry], i) => ( + + + + + + + + + ))} + +
Token NameProp ValueValueDark Value
+ {`color-text-${name}`} + + {name} + {entry.value}{entry.darkValue}
+ ## Font Family Use these tokens for `font-family`. @@ -308,7 +374,13 @@ Use these tokens for `font-size`. They are defined in `rem`, which means they wi {name} {entry.value} - {name === 'base' ? '16' : name === 'inherit' ? '' : entry.original.value * 16} + + {name === 'base' + ? '16' + : name === 'inherit' + ? '' + : entry.original.value * 16} + ))} diff --git a/src/docs/GetStarted.stories.mdx b/src/docs/GetStarted.stories.mdx index bc45dfd41..0e8095a2e 100644 --- a/src/docs/GetStarted.stories.mdx +++ b/src/docs/GetStarted.stories.mdx @@ -20,7 +20,7 @@ or @import '@palmetto/palmetto-components/dist/css/index.css'; ``` -### 3. Import Global CSS Reset (Optional) +### 3. Import Global CSS Reset We recommend importing our global reset in order to maintain a consistent look of all components across applications. @@ -29,7 +29,7 @@ look of all components across applications. @import '@palmetto/palmetto-components/dist/css/reset.css' ``` -### 4. Import Nexa Font (Optional) +### 4. Import Nexa Font We recommend importing our brand font, Nexa, for styling headings, etc. @@ -51,13 +51,13 @@ function App() { ReactDOM.render(, document.querySelector('#app')); ``` -### 6. Responsive Hooks & Window size context (Optional) +### 6. Theme and Responsive Hooks size context -`palmetto-components` provides [responsive hooks]() as well as opinionated [breakpoints]() to make custom responsive layouts -easier to craft. +Wrap your application in the `ThemeProvider` and `ResponsiveProvider` components to provide theme and responsive hooks to your application. -In order for these hooks to work, however, they must be provided a context that feeds window size updates via a single listener (for performance reasons). -use the [`ResponsiveProvider`]() to wrap your application and ensure that responsive hooks have access to the necessary context. +Use the [ResponsiveProvider](?path=/docs/providers-responsiveprovider-overview--default-story) to wrap your application and ensure that responsive hooks have access to the necessary context. + +Theming is supported via the [ThemeProvider](?path=/docs/providers-themeprovider-overview--usage) component. This component allows you to set a default theme and a storage key for persisting the theme in local storage. ```jsx import React from 'react'; @@ -69,10 +69,11 @@ function App() { } ReactDOM.render( - - - , - document.querySelector('#app') + + + + + , + document.querySelector('#app'), ); ``` - diff --git a/src/docs/Intro.stories.mdx b/src/docs/Intro.stories.mdx index a0ee198a0..51fbc0647 100644 --- a/src/docs/Intro.stories.mdx +++ b/src/docs/Intro.stories.mdx @@ -6,9 +6,10 @@ import { Meta } from '@storybook/addon-docs'; Welcome to the Palmetto Design System, whose purpose is to help us deliver high quality Palmetto branded applications, faster and better. It consists of the following: -- [Palmetto Components](https://github.com/palmetto/palmetto-components) - an open source, react-based, component library for Palmetto applications and websites. +- [Palmetto Components](https://github.com/palmetto/palmetto-components) - an open source, react, component library for Palmetto applications and websites. - [Palmetto Design Tokens](https://github.com/palmetto/palmetto-design-tokens) - A central location to store shared attributes of the Palmetto Design System. These include things like color, fonts, spacing, and more. -- Brand Assets: _coming soon_ +- [Palmetto Design Tokens Figma](https://www.figma.com/design/abGRptpr7iPaMsXdEPVm6W/Design-Tokens?node-id=0-1&t=lrjGWsHEtCpB42ZZ-1) - The Palmetto Design Tokens package reads this figma file to build the dictionary of design tokens. +- [Palmetto Design System Figma](https://www.figma.com/design/k1kOsplTGXvSSMQQCzhCND/Palmetto-Design-System?node-id=1035-13864&t=8eOhpstn9zXi8xyj-1) - Corresponding Figma components of the Palmetto Components. - [Content Guidelines](?path=/story/content-goals-and-principles--page) - A guide for applying Palmetto's voice and tone in your writing. If you have any questions or concerns, please feel free to reach out to the UX Team on Slack (#ux). One of our missions is build tools to make your job easier and you more successful, so please don't hesitate to reach out. diff --git a/src/docs/Theming.stories.mdx b/src/docs/Theming.stories.mdx index 6497384c3..ceb8a5d85 100644 --- a/src/docs/Theming.stories.mdx +++ b/src/docs/Theming.stories.mdx @@ -4,10 +4,12 @@ import { size } from '@palmetto/palmetto-design-tokens/build/js/variables-size'; import { color } from '@palmetto/palmetto-design-tokens/build/js/variables-color'; import { asset } from '@palmetto/palmetto-design-tokens/build/js/variables-asset'; +import { Accordion } from '../components/Accordion/Accordion'; import { Alert } from '../components/Alert/Alert'; import { Badge } from '../components/Badge/Badge'; import { Box } from '../components/Box/Box'; import { Button } from '../components/Button/Button'; +import { Card } from '../components/Card/Card'; import { CategoryFilter } from '../components/CategoryFilter/CategoryFilter'; import { CheckboxInput } from '../components/CheckboxInput/CheckboxInput'; import { Heading } from '../components/Heading/Heading'; @@ -21,6 +23,11 @@ import { TabsSlider } from '../components/TabsSlider/TabsSlider'; import { Toggle } from '../components/Toggle/Toggle'; import { TextareaInput } from '../components/TextareaInput/TextareaInput'; import { TextInput } from '../components/TextInput/TextInput'; +import { + ThemeProvider, + Theme, + useTheme, +} from '../components/ThemeProvider/ThemeProvider'; @@ -42,7 +49,7 @@ Also referred to as alias tokens, common tokens relate to a specific context or ### Component Tokens -Component tokens are scoped to specific components so altering them will apply to that component only. E.G: `--button-size-md-font-size`. +Component tokens are scoped to specific components so altering them will apply to that component only. E.G: `--color-background-button-primary`. Not every possible property style is available to be customized, as the Palmetto Design System is not intended to be a fully-customizable ui library. Token documentation for components that are theme-able are at the bottom of each components' documentation page. @@ -53,304 +60,445 @@ Here is an example where all three token types are used to create a customized a {() => { - const options = [ - { - id: 'car', - value: 'car', - label: 'Car', - }, - { - id: 'truck', - value: 'truck', - label: 'Truck', - }, - { - id: 'motorcycle', - value: 'motorcycle', - label: 'Motorcycle', - }, - ]; - const [isThemed, setIsThemed] = useState(true); - const [themeExampleValues, setThemeExampleValues] = useState({ - activePage: 1, - multiSelectValue: [ + const App = () => { + const alertVariants = [ + 'default', + 'info', + 'success', + 'warning', + 'danger', + ]; + const message = variant => ` + This is a ${variant} alert. It also has longer text to see what these alerts + can look like when broken into multiple lines. This one will definitely + break into multiple lines in most standard screen resolutions. + `; + const options = [ { - id: 'motorcycle', - value: 'motorcycle', - label: 'Motorcycle', + id: 'car', + value: 'car', + label: 'Car', }, { id: 'truck', value: 'truck', label: 'Truck', }, - ], - optionTileGroupValue: options[0].value, - radioValue: options[0].value, - selectedTab: 0, - selectedTabSlider: 0, - selectValue: options[0].value, - textValue: 'hello world', - textareaValue: 'hello world', - }); - const handleChange = (key, value) => { - setThemeExampleValues(prevFields => ({ - ...prevFields, - [key]: value, - })); - }; - const customTheme = { - // Base tokens - '--asset-fonts-brand': 'Consolas,monaco,monospace', - '--color-brand-primary-50': '#FAF5FF', - '--color-brand-primary-100': '#E9D8FD', - '--color-brand-primary-200': '#D6BCFA', - '--color-brand-primary-300': '#B794F4', - '--color-brand-primary-400': '#9F7AEA', - '--color-brand-primary-500': '#805AD5', - '--color-brand-primary-600': '#6B46C1', - '--color-brand-primary-700': '#553C9A', - '--color-brand-primary-800': '#44337A', - '--color-brand-primary-900': '#322659', - '--color-brand-info-50': '#EBF8FF', - '--color-brand-info-100': '#BEE3F8', - '--color-brand-info-200': '#90CDF4', - '--color-brand-info-300': '#63B3ED', - '--color-brand-info-400': '#4299E1', - '--color-brand-info-500': '#3182CE', - '--color-brand-info-600': '#2B6CB0', - '--color-brand-info-700': '#2C5282', - '--color-brand-info-800': '#2A4365', - '--color-brand-info-900': '#1A365D', - '--color-brand-success-50': '#F0FFF4', - '--color-brand-success-100': '#C6F6D5', - '--color-brand-success-200': '#9AE6B4', - '--color-brand-success-300': '#68D391', - '--color-brand-success-400': '#48BB78', - '--color-brand-success-500': '#38A169', - '--color-brand-success-600': '#2F855A', - '--color-brand-success-700': '#276749', - '--color-brand-success-800': '#22543D', - '--color-brand-success-900': '#1C4532', - '--color-brand-danger-50': '#FFF5F5', - '--color-brand-danger-100': '#FED7D7', - '--color-brand-danger-200': '#FEB2B2', - '--color-brand-danger-300': '#FC8181', - '--color-brand-danger-400': '#F56565', - '--color-brand-danger-500': '#E53E3E', - '--color-brand-danger-600': '#C53030', - '--color-brand-danger-700': '#9B2C2C', - '--color-brand-danger-800': '#822727', - '--color-brand-danger-900': '#63171B', - '--color-brand-grey-50': '#FAFAFA', - '--color-brand-grey-100': '#EDEDED', - '--color-brand-grey-200': '#D4D4D4', - '--color-brand-grey-300': '#BCBCBC', - '--color-brand-grey-400': '#A4A4A4', - '--color-brand-grey-500': '#8B8B8B', - '--color-brand-grey-600': '#727272', - '--color-brand-grey-700': '#5F5F5F', - '--color-brand-grey-800': '#4B4B4B', - '--color-brand-grey-900': '#3B3B3B', - // Common tokens - '--form-control-size-md-border-radius': 0, - '--form-control-font-family': 'Consolas,monaco,monospace', - '--form-control-border-color': '#805AD5', - // Component tokens - '--alert-border-width': '2px', - '--alert-info-border-color': '#3182CE', - '--button-size-md-border-radius': '0', - '--button-size-md-padding-vertical': '.5rem', - '--button-size-md-padding-horizontal': '.5rem', - '--button-primary-box-shadow-focus': - '0 0 0 4px var(--color-brand-primary-200)', - '--button-font-family': 'Consolas,monaco,monospace', - '--button-primary-background-color': 'var(--color-brand-primary-500)', - '--button-primary-background-color-hover': - 'var(--color-brand-primary-600)', - '--button-primary-background-color-active': - 'var(--color-brand-primary-700)', - '--button-secondary-background-color': 'var(--color-brand-white-base)', - '--button-secondary-background-color-hover': - 'var(--color-brand-primary-50)', - '--button-secondary-background-color-active': - 'var(--color-brand-primary-100)', - '--button-secondary-border-color': 'var(--color-brand-grey-200)', - '--button-secondary-border-color-hover': - 'var(--color-brand-primary-100)', - '--button-secondary-font-color': 'var(--color-brand-primary-500)', - '--button-secondary-font-color-hover': 'var(--color-brand-primary-500)', - '--button-tertiary-background-color': 'transparent', - '--button-tertiary-background-color-hover': - 'var(--color-brand-primary-50)', - '--button-tertiary-background-color-active': - 'var(--color-brand-primary-100)', - '--button-tertiary-font-color': 'var(--color-brand-primary-500)', - '--button-tertiary-font-color-hover': 'var(--color-brand-primary-500)', - }; - return ( - - setIsThemed(event.target.checked)} - isChecked={isThemed} - size="lg" - /> - - - Leading the world toward a clean energy future - - - - - - - - - - - - - - Unselected - Selected - - - handleChange('selectedTab', index)} - > - Tab 1 - Tab 2 - Tab 3 - - - handleChange('selectedTabSlider', index) - } - > - Tab 1 - Tab 2 - Tab 3 - Disabled - - - - - - - - - - - - - - - Form Inputs - - handleChange('textValue', event.target.value)} - /> - - handleChange('selectValue', event.target.value) + { + id: 'motorcycle', + value: 'motorcycle', + label: 'Motorcycle', + }, + ]; + const [isThemed, setIsThemed] = useState(false); + const [themeExampleValues, setThemeExampleValues] = useState({ + activePage: 1, + multiSelectValue: [ + { + id: 'motorcycle', + value: 'motorcycle', + label: 'Motorcycle', + }, + { + id: 'truck', + value: 'truck', + label: 'Truck', + }, + ], + optionTileGroupValue: options[0].value, + radioValue: options[0].value, + selectedTab: 0, + selectedTabSlider: 0, + selectValue: options[0].value, + textValue: 'hello world', + textareaValue: 'hello world', + }); + const [openPanels, setOpenPanels] = useState({ + '1': false, + '2': true, + '3': false, + }); + const handleChange = (key, value) => { + setThemeExampleValues(prevFields => ({ + ...prevFields, + [key]: value, + })); + }; + /* This logic ensures only one panel is open at a time */ + const handleTogglePanels = id => { + const updatedPanels = { ...openPanels }; + if (updatedPanels[id]) { + updatedPanels[id] = false; + } else { + Object.keys(updatedPanels).forEach(key => { + if (updatedPanels[key]) { + updatedPanels[key] = false; } - options={options} - value={themeExampleValues.selectValue} + }); + updatedPanels[id] = true; + } + setOpenPanels(updatedPanels); + }; + const customTheme = { + // Base tokens + '--asset-fonts-brand': 'Consolas,monaco,monospace', + '--asset-fonts-body': 'Consolas,monaco,monospace', + '--color-brand-primary-50': '#FAF5FF', + '--color-brand-primary-100': '#E9D8FD', + '--color-brand-primary-200': '#D6BCFA', + '--color-brand-primary-300': '#B794F4', + '--color-brand-primary-400': '#9F7AEA', + '--color-brand-primary-500': '#805AD5', + '--color-brand-primary-600': '#6B46C1', + '--color-brand-primary-700': '#553C9A', + '--color-brand-primary-800': '#44337A', + '--color-brand-primary-900': '#322659', + '--color-brand-info-50': '#EBF8FF', + '--color-brand-info-100': '#BEE3F8', + '--color-brand-info-200': '#90CDF4', + '--color-brand-info-300': '#63B3ED', + '--color-brand-info-400': '#4299E1', + '--color-brand-info-500': '#3182CE', + '--color-brand-info-600': '#2B6CB0', + '--color-brand-info-700': '#2C5282', + '--color-brand-info-800': '#2A4365', + '--color-brand-info-900': '#1A365D', + '--color-brand-success-50': '#F0FFF4', + '--color-brand-success-100': '#C6F6D5', + '--color-brand-success-200': '#9AE6B4', + '--color-brand-success-300': '#68D391', + '--color-brand-success-400': '#48BB78', + '--color-brand-success-500': '#38A169', + '--color-brand-success-600': '#2F855A', + '--color-brand-success-700': '#276749', + '--color-brand-success-800': '#22543D', + '--color-brand-success-900': '#1C4532', + '--color-brand-danger-50': '#FFF5F5', + '--color-brand-danger-100': '#FED7D7', + '--color-brand-danger-200': '#FEB2B2', + '--color-brand-danger-300': '#FC8181', + '--color-brand-danger-400': '#F56565', + '--color-brand-danger-500': '#E53E3E', + '--color-brand-danger-600': '#C53030', + '--color-brand-danger-700': '#9B2C2C', + '--color-brand-danger-800': '#822727', + '--color-brand-danger-900': '#63171B', + '--color-brand-grey-50': '#FAFAFA', + '--color-brand-grey-100': '#EDEDED', + '--color-brand-grey-200': '#D4D4D4', + '--color-brand-grey-300': '#BCBCBC', + '--color-brand-grey-400': '#A4A4A4', + '--color-brand-grey-500': '#8B8B8B', + '--color-brand-grey-600': '#727272', + '--color-brand-grey-700': '#5F5F5F', + '--color-brand-grey-800': '#4B4B4B', + '--color-brand-grey-900': '#3B3B3B', + '--color-text-primary': '#805AD5', + // Common tokens + '--form-control-size-md-border-radius': 0, + '--asset-fonts-body': 'Consolas,monaco,monospace', + // Component tokens + '--color-background-button-primary': 'var(--color-brand-primary-500)', + '--color-background-button-primary-hover': + 'var(--color-brand-primary-600)', + '--color-background-button-primary-active': + 'var(--color-brand-primary-700)', + '--color-background-button-secondary': 'var(--color-background-white)', + '--color-background-button-secondary-hover': + 'var(--color-brand-primary-50)', + '--color-background-button-secondary-active': + 'var(--color-brand-primary-100)', + '--color-border-button-secondary': 'var(--color-brand-grey-200)', + '--color-border-button-secondary-hover': + 'var(--color-brand-primary-100)', + '--color-text-button-secondary': 'var(--color-brand-primary-500)', + '--color-text-button-secondary-hover': + 'var(--color-brand-primary-500)', + '--color-background-button-tertiary': 'transparent', + '--color-background-button-tertiary-hover': + 'var(--color-brand-primary-50)', + '--color-background-button-tertiary-active': + 'var(--color-brand-primary-100)', + '--color-text-button-tertiary': 'var(--color-brand-primary-500)', + '--color-text-button-tertiary-hover': + 'var(--color-brand-primary-500)', + '--color-background-form-control-selected': + 'var(--color-brand-primary-800)', + }; + return ( + + setIsThemed(event.target.checked)} + isChecked={isThemed} + size="lg" /> - - handleChange('multiSelectValue', event.target.value) + + + Leading the world toward a clean energy future + + + + + + + + + + + + + + Unselected + Disabled + Selected + + handleChange('selectedTab', index)} + > + Tab 1 + Tab 2 + Tab 3 + + + handleChange('selectedTabSlider', index) } - /> - handleChange('textareaValue', e.target.value)} - /> - - {}} - isChecked + > + Tab 1 + Tab 2 + Tab 3 + Disabled + + + + + + + + + + + + + + + + + + + Form Inputs + + + handleChange('textValue', event.target.value) + } /> - {}} + + handleChange('selectValue', event.target.value) + } + options={options} + value={themeExampleValues.selectValue} + /> + + handleChange('multiSelectValue', event.target.value) + } + /> + handleChange('textareaValue', e.target.value)} + /> + + {}} + isChecked + /> + {}} + /> + {}} + /> + {}} + /> + + + handleChange('radioValue', event.target.value) + } + value={themeExampleValues.radioValue} + options={options} + direction="row" + /> + + handleChange('optionTileGroupValue', event.target.value) + } + options={options} + direction="row" /> - handleChange('radioValue', event.target.value)} - value={themeExampleValues.radioValue} - options={options} - direction="row" - /> - - handleChange('optionTileGroupValue', event.target.value) - } - options={options} - direction="row" + + + +

Card content

+
+ Footer +
+ + + handleTogglePanels('1')} + isDetailsOpen={openPanels['1']} + > + What is solar energy? How do solar panels work? + + +

+ Solar panels, also called photovoltaic or PV panels, consist + of solar cells that are designed to capture the radiant + light and heat contained in sunlight and convert it into + usable clean energy for your home. +

+

+ When sunlight hits your solar panel, the photons of energy + are converted into DC (direct current) electricity, which is + then converted into AC (alternating current) electricity for + use in your home. Solar panels are often grouped together to + form a solar grid or solar array, allowing you to capture + and harness the right amount of energy for your needs. +

+
+
+ + handleTogglePanels('2')} + isDetailsOpen={openPanels['2']} + > + How do I know if solar is right for me? + + +

+ There are several factors we can look at to determine if + solar might be a good solution for your needs, including + roof space, home energy usage, credit health, and + eligibility for incentives. At Palmetto, we start by + calculating a quick savings estimate based on your home, + location, and current utility costs. Then, we’ll schedule a + meeting to clarify your goals, address any questions, + identify purchase options, and outline the solar process. + All of this happens before you pay, allowing you to decide + if a solar power system is right for you based on a complete + understanding of the potential costs and savings. +

+
+
+ + handleTogglePanels('3')} + isDetailsOpen={openPanels['3']} + > + How many solar panels do I need? + + +

+ The right solar power system for your home will depend on a + variety of factors, including your current energy usage, the + size and layout of your roof, and your preferred level of + energy independence. To hone in on the right solution for + your home, we always begin with a personal consultation and + a survey, both of which serve to clarify your goals and + outline available options. Should you choose to invest, + we’ll design a custom solution to meet your goals and + maximize your savings—no haggling, no upselling, just right. +

+
+
+
+ {alertVariants.map(variant => ( + + ))} + handleChange('activePage', index)} + totalItemsCount={100} + arePagesVisible + numberOfPagesDisplayed={3} />
- handleChange('activePage', index)} - totalItemsCount={100} - arePagesVisible - numberOfPagesDisplayed={3} - /> -
+ ); + }; + return ( + + + ); }}
diff --git a/src/lib/createComponent/createComponent.Overview.stories.mdx b/src/lib/createComponent/createComponent.Overview.stories.mdx index 61003867b..4bded931f 100644 --- a/src/lib/createComponent/createComponent.Overview.stories.mdx +++ b/src/lib/createComponent/createComponent.Overview.stories.mdx @@ -17,7 +17,7 @@ This however can lead to markup that can be hard to read in some cases. Consider shadow="sm" radius="sm" borderWidth="xs" - borderColor="grey-lighter" + borderColor="separator" hover={{ shadow: 'md', }} @@ -26,10 +26,10 @@ This however can lead to markup that can be hard to read in some cases. Consider > ( shadow="sm" radius="sm" borderWidth="xs" - borderColor="grey-lighter" + borderColor="separator" hover={{ shadow: 'md', }} @@ -104,10 +104,10 @@ export const App = () => ( > ( ( ( ( ); ``` -## Improving This Code +## Improving This Code + The first step toward improving this code is obviously to try and remove duplicate elements so it's easier to parse. We can accomplish it like this: ```jsx @@ -178,7 +179,7 @@ export const App = () => { shadow="sm" radius="sm" borderWidth="xs" - borderColor="grey-lighter" + borderColor="separator" hover={{ shadow: 'md', }} @@ -189,10 +190,10 @@ export const App = () => { { +export const MainContainer = props => { const { children, gap = 'md', @@ -224,13 +225,13 @@ export const MainContainer = (props) => { shadow = 'sm', radius = 'sm', border = 'xs', - borderColor = 'grey-lighter', + borderColor = 'separator', hover = { shadow: 'md', }, padding = 'md', justifyContent = 'space-evenly', - ...restProps, + ...restProps } = props; return ( @@ -254,20 +255,20 @@ export const MainContainer = (props) => { // Column.jsx import { Box } from '@palmetto/palmetto-components'; -export const Column = (props) => { +export const Column = props => { const { children, justifyContent = 'center', - background = 'info-lightest', + background = 'info-50', padding = 'md', hover = { - background: 'info-lighter', + background: 'info-100', shadow: 'md', }, radius = 'sm', flex = 'auto', alignItems = 'center', - ...restProps, + ...restProps } = props; return ( @@ -294,15 +295,13 @@ export const App = () => { const columns = ['Column 1', 'Column 2', 'Column 3', 'Column 4']; {columns.map(column => ( - - {column} - + {column} ))} - -} + ; +}; ``` -This is our cleanest example yet, but the process of creating these components is still not ideal as they require re-writing each custom Box and then ensuring +This is our cleanest example yet, but the process of creating these components is still not ideal as they require re-writing each custom Box and then ensuring they always get the exact correct props, as well as ensuring proper spreading of other props. ## Enter the `createComponent` utility @@ -319,7 +318,7 @@ const MainContainer = createComponent(Box)({ shadow: 'sm', radius: 'sm', borderWidth: 'xs', - borderColor: 'grey-lighter', + borderColor: 'separator', hover: { shadow: 'md', }, @@ -329,10 +328,10 @@ const MainContainer = createComponent(Box)({ const Column = createComponent(Box)({ justifyContent: 'center', - background: 'info-lightest', + background: 'info-50', padding: 'md', hover: {{ - background: 'info-lighter', + background: 'info-100', shadow: 'md', }} radius: 'sm', @@ -355,47 +354,45 @@ export const App = () => { And here we have the same result as the original but with a much lighter markup footprint. The components in this example `MainContainer` and `Column` can also take any of the original `Box` props and overwrite its default style. This allows for even more complex customization such as creating custom components from other custom components. Read on for an example. - + - {() => { - const MainContainer = createComponent(Box)({ - gap: 'md', - direction: 'row', - shadow: 'sm', - radius: 'sm', - borderWidth: 'xs', - borderColor: 'grey-lighter', - hover: { - shadow: 'md', - }, - padding: 'md', - justifyContent: 'space-evenly', - }); - const Column = createComponent(Box)({ - justifyContent: 'center', - background: 'info-lightest', - padding: 'md', - hover: { - background: 'info-lighter', - shadow: 'md', - }, - radius: 'sm', - flex: 'auto', - alignItems: 'center', - cursor: 'pointer', - }); - const columns = ['Column 1', 'Column 2', 'Column 3', 'Column 4']; - return ( - - {columns.map(column => ( - - {column} - - ))} - - ); - }} + {() => { + const MainContainer = createComponent(Box)({ + gap: 'md', + direction: 'row', + shadow: 'sm', + radius: 'sm', + borderWidth: 'xs', + borderColor: 'separator', + hover: { + shadow: 'md', + }, + padding: 'md', + justifyContent: 'space-evenly', + }); + const Column = createComponent(Box)({ + justifyContent: 'center', + background: 'info-50', + padding: 'md', + hover: { + background: 'info-100', + shadow: 'md', + }, + radius: 'sm', + flex: 'auto', + alignItems: 'center', + cursor: 'pointer', + }); + const columns = ['Column 1', 'Column 2', 'Column 3', 'Column 4']; + return ( + + {columns.map(column => ( + {column} + ))} + + ); + }} @@ -419,29 +416,21 @@ The below shows how we can create simple variations on a component with this uti hover: { shadow: 'md' }, }); const BlueColumn = createComponent(BaseColumn)({ - background: 'info-lightest', - color: 'info-dark', + background: 'info-50', + color: 'info-600', }); const RedColumn = createComponent(BaseColumn)({ - background: 'danger-lightest', - color: 'danger-dark', + background: 'danger-50', + color: 'danger-600', }); return ( - - blue - - - red - - - blue - - - red - + blue + red + blue + red ); }} -
\ No newline at end of file +
diff --git a/src/lib/tokens.ts b/src/lib/tokens.ts index e4c1e808c..132c12913 100644 --- a/src/lib/tokens.ts +++ b/src/lib/tokens.ts @@ -4,23 +4,24 @@ import assets from '@palmetto/palmetto-design-tokens/build/json/variables-asset. import { ICON_NAMES as iconNames } from '@palmetto/palmetto-design-tokens/build/icons'; import { + BackgroundColor, + BorderColor, BorderRadiusSize, BorderSize, + BoxShadowSize, BrandColor, Breakpoint, BreakpointSizeWithBase, - BoxShadowSize, - ColorName, FontColor, - FontSize, FontFamily, + FontSize, FontWeight, HeightSize, + IconName, LineHeightSize, SpacingSize, WidthSize, ZIndexSize, - IconName, } from '../types'; const { size } = sizes; @@ -43,18 +44,20 @@ export const BREAKPOINTS = [...Object.entries(size.breakpoint), ['base', 0]] minWidth: parseInt(value as string, 10), })) as Breakpoint[]; -export const BRAND_COLOR_OPTIONS = (Object.keys(color.brand) as ColorName[]) +export const BRAND_COLOR_OPTIONS = (Object.keys(color.brand)) .map(colorName => ( Object.keys(color.brand[colorName]) .map(colorGrade => (colorGrade === 'base' ? colorName : `${colorName}-${colorGrade}`)) )).flat() as BrandColor[]; -export const BRAND_COLOR_NAMES = Object.keys(color.brand) as ColorName[]; +export const BRAND_COLOR_NAMES = Object.keys(color.brand); export const BRAND_COLOR_VALUES = Object.values(color.brand); -export const BASE_BRAND_COLORS = Object.entries({ ...color.brand }) - .reduce((acc, [key, value]) => ({ ...acc, [key]: value?.base }), {}) as { [c in ColorName]: string }; -export const FONT_COLOR_OPTIONS = [...BRAND_COLOR_OPTIONS] as FontColor[]; +export const BACKGROUND_COLOR_OPTIONS = [...(Object.keys(color.background)), ...BRAND_COLOR_OPTIONS] as BackgroundColor[]; + +export const BORDER_COLOR_OPTIONS = [...(Object.keys(color.border)), ...BRAND_COLOR_OPTIONS] as BorderColor[]; + +export const FONT_COLOR_OPTIONS = [...(Object.keys(color.text)), ...BRAND_COLOR_OPTIONS] as FontColor[]; export const FONT_COLOR_VALUES = color.brand; export const FONT_SIZE_OPTIONS = Object.keys(size.font) as FontSize[]; diff --git a/src/styles/flex.scss b/src/styles/flex.scss index 0359669b9..d5983ecdb 100644 --- a/src/styles/flex.scss +++ b/src/styles/flex.scss @@ -7,45 +7,138 @@ min-width: 0; min-height: 0; } -.flex-none { flex: none; } -.flex-initial { flex: initial; } -.flex-inherit { flex: inherit; } -.flex-unset { flex: unset; } - -.flex-direction-column { flex-direction: column; } -.flex-direction-row { flex-direction: row; } -.flex-direction-column-reverse { flex-direction: column-reverse; } -.flex-direction-row-reverse { flex-direction: row-reverse; } - -.flex-wrap { flex-wrap: wrap; } -.flex-nowrap { flex-wrap: nowrap; } -.flex-wrap-reverse { flex-wrap: wrap-reverse; } - -.justify-content-flex-start { justify-content: flex-start; } -.justify-content-flex-end { justify-content: flex-end; } -.justify-content-center { justify-content: center; } -.justify-content-space-between { justify-content: space-between; } -.justify-content-space-around { justify-content: space-around; } -.justify-content-space-evenly { justify-content: space-evenly; } - -.align-items-flex-start { align-items: flex-start; } -.align-items-flex-end { align-items: flex-end; } -.align-items-center { align-items: center; } -.align-items-baseline { align-items: baseline; } -.align-items-stretch { align-items: stretch; } - -.align-content-flex-start { align-content: flex-start; } -.align-content-flex-end { align-content: flex-end; } -.align-content-center { align-content: center; } -.align-content-stretch { align-content: stretch; } -.align-content-space-between { align-content: space-between; } -.align-content-space-around { align-content: space-around; } - -.align-self-flex-start { align-self: flex-start; } -.align-self-flex-end { align-self: flex-end; } -.align-self-center { align-self: center; } -.align-self-baseline { align-self: baseline; } -.align-self-stretch { align-self: stretch; } + +.flex-none { + flex: none; +} + +.flex-initial { + flex: initial; +} + +.flex-inherit { + flex: inherit; +} + +.flex-unset { + flex: unset; +} + +.flex-direction-column { + flex-direction: column; +} + +.flex-direction-row { + flex-direction: row; +} + +.flex-direction-column-reverse { + flex-direction: column-reverse; +} + +.flex-direction-row-reverse { + flex-direction: row-reverse; +} + +.flex-wrap { + flex-wrap: wrap; +} + +.flex-nowrap { + flex-wrap: nowrap; +} + +.flex-wrap-reverse { + flex-wrap: wrap-reverse; +} + +.justify-content-flex-start { + justify-content: flex-start; +} + +.justify-content-flex-end { + justify-content: flex-end; +} + +.justify-content-center { + justify-content: center; +} + +.justify-content-space-between { + justify-content: space-between; +} + +.justify-content-space-around { + justify-content: space-around; +} + +.justify-content-space-evenly { + justify-content: space-evenly; +} + +.align-items-flex-start { + align-items: flex-start; +} + +.align-items-flex-end { + align-items: flex-end; +} + +.align-items-center { + align-items: center; +} + +.align-items-500line { + align-items: baseline; +} + +.align-items-stretch { + align-items: stretch; +} + +.align-content-flex-start { + align-content: flex-start; +} + +.align-content-flex-end { + align-content: flex-end; +} + +.align-content-center { + align-content: center; +} + +.align-content-stretch { + align-content: stretch; +} + +.align-content-space-between { + align-content: space-between; +} + +.align-content-space-around { + align-content: space-around; +} + +.align-self-flex-start { + align-self: flex-start; +} + +.align-self-flex-end { + align-self: flex-end; +} + +.align-self-center { + align-self: center; +} + +.align-self-500line { + align-self: baseline; +} + +.align-self-stretch { + align-self: stretch; +} @media (min-width: $size-breakpoint-tablet) { .flex-auto-tablet { @@ -53,47 +146,139 @@ min-width: 0; min-height: 0; } - .flex-none-tablet { flex: none; } - .flex-initial-tablet { flex: initial; } - .flex-inherit-tablet { flex: inherit; } - .flex-unset-tablet { flex: unset; } - .flex-direction-column-tablet { flex-direction: column; } - .flex-direction-row-tablet { flex-direction: row; } - .flex-direction-column-reverse-tablet { flex-direction: column-reverse; } - .flex-direction-row-reverse-tablet { flex-direction: row-reverse; } + .flex-none-tablet { + flex: none; + } - .flex-wrap-tablet { flex-wrap: wrap; } - .flex-nowrap-tablet { flex-wrap: nowrap; } - .flex-wrap-reverse-tablet { flex-wrap: wrap-reverse; } + .flex-initial-tablet { + flex: initial; + } - .justify-content-flex-start-tablet { justify-content: flex-start; } - .justify-content-flex-end-tablet { justify-content: flex-end; } - .justify-content-center-tablet { justify-content: center; } - .justify-content-space-between-tablet { justify-content: space-between; } - .justify-content-space-around-tablet { justify-content: space-around; } - .justify-content-space-evenly-tablet { justify-content: space-evenly; } + .flex-inherit-tablet { + flex: inherit; + } - .align-items-flex-start-tablet { align-items: flex-start; } - .align-items-flex-end-tablet { align-items: flex-end; } - .align-items-center-tablet { align-items: center; } - .align-items-baseline-tablet { align-items: baseline; } - .align-items-stretch-tablet { align-items: stretch; } + .flex-unset-tablet { + flex: unset; + } - .align-content-flex-start-tablet { align-content: flex-start; } - .align-content-flex-end-tablet { align-content: flex-end; } - .align-content-center-tablet { align-content: center; } - .align-content-stretch-tablet { align-content: stretch; } - .align-content-space-between-tablet { align-content: space-between; } - .align-content-space-around-tablet { align-content: space-around; } + .flex-direction-column-tablet { + flex-direction: column; + } - .align-self-flex-start-tablet { align-self: flex-start; } - .align-self-flex-end-tablet { align-self: flex-end; } - .align-self-center-tablet { align-self: center; } - .align-self-baseline-tablet { align-self: baseline; } - .align-self-stretch-tablet { align-self: stretch; } -} + .flex-direction-row-tablet { + flex-direction: row; + } + .flex-direction-column-reverse-tablet { + flex-direction: column-reverse; + } + + .flex-direction-row-reverse-tablet { + flex-direction: row-reverse; + } + + .flex-wrap-tablet { + flex-wrap: wrap; + } + + .flex-nowrap-tablet { + flex-wrap: nowrap; + } + + .flex-wrap-reverse-tablet { + flex-wrap: wrap-reverse; + } + + .justify-content-flex-start-tablet { + justify-content: flex-start; + } + + .justify-content-flex-end-tablet { + justify-content: flex-end; + } + + .justify-content-center-tablet { + justify-content: center; + } + + .justify-content-space-between-tablet { + justify-content: space-between; + } + + .justify-content-space-around-tablet { + justify-content: space-around; + } + + .justify-content-space-evenly-tablet { + justify-content: space-evenly; + } + + .align-items-flex-start-tablet { + align-items: flex-start; + } + + .align-items-flex-end-tablet { + align-items: flex-end; + } + + .align-items-center-tablet { + align-items: center; + } + + .align-items-500line-tablet { + align-items: baseline; + } + + .align-items-stretch-tablet { + align-items: stretch; + } + + .align-content-flex-start-tablet { + align-content: flex-start; + } + + .align-content-flex-end-tablet { + align-content: flex-end; + } + + .align-content-center-tablet { + align-content: center; + } + + .align-content-stretch-tablet { + align-content: stretch; + } + + .align-content-space-between-tablet { + align-content: space-between; + } + + .align-content-space-around-tablet { + align-content: space-around; + } + + .align-self-flex-start-tablet { + align-self: flex-start; + } + + .align-self-flex-end-tablet { + align-self: flex-end; + } + + .align-self-center-tablet { + align-self: center; + } + + .align-self-500line-tablet { + align-self: baseline; + } + + .align-self-stretch-tablet { + align-self: stretch; + } +} @media (min-width: $size-breakpoint-desktop) { .flex-auto-desktop { @@ -101,45 +286,138 @@ min-width: 0; min-height: 0; } - .flex-none-desktop { flex: none; } - .flex-initial-desktop { flex: initial; } - .flex-inherit-desktop { flex: inherit; } - .flex-unset-desktop { flex: unset; } - - .flex-direction-column-desktop { flex-direction: column; } - .flex-direction-row-desktop { flex-direction: row; } - .flex-direction-column-reverse-desktop { flex-direction: column-reverse; } - .flex-direction-row-reverse-desktop { flex-direction: row-reverse; } - - .flex-wrap-desktop { flex-wrap: wrap; } - .flex-nowrap-desktop { flex-wrap: nowrap; } - .flex-wrap-reverse-desktop { flex-wrap: wrap-reverse; } - - .justify-content-flex-start-desktop { justify-content: flex-start; } - .justify-content-flex-end-desktop { justify-content: flex-end; } - .justify-content-center-desktop { justify-content: center; } - .justify-content-space-between-desktop { justify-content: space-between; } - .justify-content-space-around-desktop { justify-content: space-around; } - .justify-content-space-evenly-desktop { justify-content: space-evenly; } - - .align-items-flex-start-desktop { align-items: flex-start; } - .align-items-flex-end-desktop { align-items: flex-end; } - .align-items-center-desktop { align-items: center; } - .align-items-baseline-desktop { align-items: baseline; } - .align-items-stretch-desktop { align-items: stretch; } - - .align-content-flex-start-desktop { align-content: flex-start; } - .align-content-flex-end-desktop { align-content: flex-end; } - .align-content-center-desktop { align-content: center; } - .align-content-stretch-desktop { align-content: stretch; } - .align-content-space-between-desktop { align-content: space-between; } - .align-content-space-around-desktop { align-content: space-around; } - - .align-self-flex-start-desktop { align-self: flex-start; } - .align-self-flex-end-desktop { align-self: flex-end; } - .align-self-center-desktop { align-self: center; } - .align-self-baseline-desktop { align-self: baseline; } - .align-self-stretch-desktop { align-self: stretch; } + + .flex-none-desktop { + flex: none; + } + + .flex-initial-desktop { + flex: initial; + } + + .flex-inherit-desktop { + flex: inherit; + } + + .flex-unset-desktop { + flex: unset; + } + + .flex-direction-column-desktop { + flex-direction: column; + } + + .flex-direction-row-desktop { + flex-direction: row; + } + + .flex-direction-column-reverse-desktop { + flex-direction: column-reverse; + } + + .flex-direction-row-reverse-desktop { + flex-direction: row-reverse; + } + + .flex-wrap-desktop { + flex-wrap: wrap; + } + + .flex-nowrap-desktop { + flex-wrap: nowrap; + } + + .flex-wrap-reverse-desktop { + flex-wrap: wrap-reverse; + } + + .justify-content-flex-start-desktop { + justify-content: flex-start; + } + + .justify-content-flex-end-desktop { + justify-content: flex-end; + } + + .justify-content-center-desktop { + justify-content: center; + } + + .justify-content-space-between-desktop { + justify-content: space-between; + } + + .justify-content-space-around-desktop { + justify-content: space-around; + } + + .justify-content-space-evenly-desktop { + justify-content: space-evenly; + } + + .align-items-flex-start-desktop { + align-items: flex-start; + } + + .align-items-flex-end-desktop { + align-items: flex-end; + } + + .align-items-center-desktop { + align-items: center; + } + + .align-items-500line-desktop { + align-items: baseline; + } + + .align-items-stretch-desktop { + align-items: stretch; + } + + .align-content-flex-start-desktop { + align-content: flex-start; + } + + .align-content-flex-end-desktop { + align-content: flex-end; + } + + .align-content-center-desktop { + align-content: center; + } + + .align-content-stretch-desktop { + align-content: stretch; + } + + .align-content-space-between-desktop { + align-content: space-between; + } + + .align-content-space-around-desktop { + align-content: space-around; + } + + .align-self-flex-start-desktop { + align-self: flex-start; + } + + .align-self-flex-end-desktop { + align-self: flex-end; + } + + .align-self-center-desktop { + align-self: center; + } + + .align-self-500line-desktop { + align-self: baseline; + } + + .align-self-stretch-desktop { + align-self: stretch; + } } @media (min-width: $size-breakpoint-hd) { @@ -148,43 +426,136 @@ min-width: 0; min-height: 0; } - .flex-none-hd { flex: none; } - .flex-initial-hd { flex: initial; } - .flex-inherit-hd { flex: inherit; } - .flex-unset-hd { flex: unset; } - - .flex-direction-column-hd { flex-direction: column; } - .flex-direction-row-hd { flex-direction: row; } - .flex-direction-column-reverse-hd { flex-direction: column-reverse; } - .flex-direction-row-reverse-hd { flex-direction: row-reverse; } - - .flex-wrap-hd { flex-wrap: wrap; } - .flex-nowrap-hd { flex-wrap: nowrap; } - .flex-wrap-reverse-hd { flex-wrap: wrap-reverse; } - - .justify-content-flex-start-hd { justify-content: flex-start; } - .justify-content-flex-end-hd { justify-content: flex-end; } - .justify-content-center-hd { justify-content: center; } - .justify-content-space-between-hd { justify-content: space-between; } - .justify-content-space-around-hd { justify-content: space-around; } - .justify-content-space-evenly-hd { justify-content: space-evenly; } - - .align-items-flex-start-hd { align-items: flex-start; } - .align-items-flex-end-hd { align-items: flex-end; } - .align-items-center-hd { align-items: center; } - .align-items-baseline-hd { align-items: baseline; } - .align-items-stretch-hd { align-items: stretch; } - - .align-content-flex-start-hd { align-content: flex-start; } - .align-content-flex-end-hd { align-content: flex-end; } - .align-content-center-hd { align-content: center; } - .align-content-stretch-hd { align-content: stretch; } - .align-content-space-between-hd { align-content: space-between; } - .align-content-space-around-hd { align-content: space-around; } - - .align-self-flex-start-hd { align-self: flex-start; } - .align-self-flex-end-hd { align-self: flex-end; } - .align-self-center-hd { align-self: center; } - .align-self-baseline-hd { align-self: baseline; } - .align-self-stretch-hd { align-self: stretch; } + + .flex-none-hd { + flex: none; + } + + .flex-initial-hd { + flex: initial; + } + + .flex-inherit-hd { + flex: inherit; + } + + .flex-unset-hd { + flex: unset; + } + + .flex-direction-column-hd { + flex-direction: column; + } + + .flex-direction-row-hd { + flex-direction: row; + } + + .flex-direction-column-reverse-hd { + flex-direction: column-reverse; + } + + .flex-direction-row-reverse-hd { + flex-direction: row-reverse; + } + + .flex-wrap-hd { + flex-wrap: wrap; + } + + .flex-nowrap-hd { + flex-wrap: nowrap; + } + + .flex-wrap-reverse-hd { + flex-wrap: wrap-reverse; + } + + .justify-content-flex-start-hd { + justify-content: flex-start; + } + + .justify-content-flex-end-hd { + justify-content: flex-end; + } + + .justify-content-center-hd { + justify-content: center; + } + + .justify-content-space-between-hd { + justify-content: space-between; + } + + .justify-content-space-around-hd { + justify-content: space-around; + } + + .justify-content-space-evenly-hd { + justify-content: space-evenly; + } + + .align-items-flex-start-hd { + align-items: flex-start; + } + + .align-items-flex-end-hd { + align-items: flex-end; + } + + .align-items-center-hd { + align-items: center; + } + + .align-items-500line-hd { + align-items: baseline; + } + + .align-items-stretch-hd { + align-items: stretch; + } + + .align-content-flex-start-hd { + align-content: flex-start; + } + + .align-content-flex-end-hd { + align-content: flex-end; + } + + .align-content-center-hd { + align-content: center; + } + + .align-content-stretch-hd { + align-content: stretch; + } + + .align-content-space-between-hd { + align-content: space-between; + } + + .align-content-space-around-hd { + align-content: space-around; + } + + .align-self-flex-start-hd { + align-self: flex-start; + } + + .align-self-flex-end-hd { + align-self: flex-end; + } + + .align-self-center-hd { + align-self: center; + } + + .align-self-500line-hd { + align-self: baseline; + } + + .align-self-stretch-hd { + align-self: stretch; + } } diff --git a/src/styles/variables/forms.scss b/src/styles/variables/forms.scss index ae73c6c62..f0c82d358 100644 --- a/src/styles/variables/forms.scss +++ b/src/styles/variables/forms.scss @@ -1,17 +1,13 @@ .palmetto-components__variables__form-control { // ----GLOBALS---- --INTERNAL_form-control-box-shadow-focus: 0 0 0 4px - var(--color-brand-primary-200); + var(--color-border-primary); --INTERNAL_form-control-label-margin: var(--size-spacing-xs); --INTERNAL_form-control-help-margin: var(--size-spacing-2xs); - --INTERNAL_form-control-line-height: var(--size-line-height-input); --INTERNAL_form-control-help-text-font-weight: var( --size-font-weight-regular ); - --INTERNAL_form-control-label-font-weight: var(--size-font-weight-medium); - --INTERNAL_form-control-legend-font-weight: var(--size-font-weight-medium); --INTERNAL_form-control-box-shadow: 0 3px 0 rgb(0 0 0 / 5%); - --INTERNAL_form-control-font-family: var(--asset-fonts-body); --INTERNAL_form-control-help-text-font-size: var(--size-font-sm); // --SIZES-- @@ -38,38 +34,12 @@ --INTERNAL_form-control-size-lg-padding: var(--size-spacing-md); // --COLORS-- - --INTERNAL_form-control-background-color: var(--color-brand-white-base); - --INTERNAL_form-control-background-color-disabled: var(--color-brand-grey-50); - --INTERNAL_form-control-background-color-error: var(--color-brand-danger-50); - --INTERNAL_form-control-background-color-selected: var( - --color-brand-primary-50 - ); - --INTERNAL_form-control-border-color: var(--color-brand-grey-100); - --INTERNAL_form-control-border-color-error: var(--color-brand-danger-100); - --INTERNAL_form-control-border-color-error-disabled: var( - --color-brand-danger-100 - ); --INTERNAL_form-control-border-color-focus: var(--color-brand-grey-600); --INTERNAL_form-control-border-color-hover: var(--color-brand-grey-300); --INTERNAL_form-control-border-color-selected: var(--color-brand-primary-500); --INTERNAL_form-control-border-color-selected-error: var( --color-brand-danger-500 ); - --INTERNAL_form-control-border-color-selected-hover: var( - --color-brand-primary-500 - ); - --INTERNAL_form-control-font-color: var(--color-brand-grey-700); - --INTERNAL_form-control-font-color-disabled: var(--color-brand-grey-300); - --INTERNAL_form-control-font-color-error: var(--color-brand-danger-500); - --INTERNAL_form-control-font-color-error-disabled: var( - --color-brand-danger-200 - ); - --INTERNAL_form-control-help-text-font-color: var(--color-brand-grey-500); - --INTERNAL_form-control-label-font-color: var(--color-brand-grey-700); - --INTERNAL_form-control-description-color: var(--color-brand-grey-600); - --INTERNAL_form-control-icon-color: var(--color-brand-grey-300); - --INTERNAL_form-control-icon-color-hover: var(--color-brand-grey); - --INTERNAL_form-control-placeholder-color: var(--color-brand-grey-300); // ----RADIO GROUP---- --INTERNAL_form-control-radio-group-description-spacing: var( diff --git a/src/styles/variables/index.scss b/src/styles/variables/index.scss index bbf28910f..d943c80d8 100644 --- a/src/styles/variables/index.scss +++ b/src/styles/variables/index.scss @@ -1,3 +1,2 @@ @import './tokens'; @import './forms'; -@import './table'; diff --git a/src/styles/variables/table.scss b/src/styles/variables/table.scss deleted file mode 100644 index 4ef30a3c2..000000000 --- a/src/styles/variables/table.scss +++ /dev/null @@ -1,20 +0,0 @@ -.palmetto-components__variables__table { - --INTERNAL_table-border-color: var(--color-brand-grey-100); - --INTERNAL_table-border-width: var(--size-border-xs); - --INTERNAL_table-background-color: var(--color-brand-white-500); - --INTERNAL_table-font-color: var(--color-brand-grey-600); - --INTERNAL_table-padding-horizontal: var(--size-spacing-lg); - --INTERNAL_table-padding-vertical: var(--size-spacing-md); - --INTERNAL_table-compact-padding-horizontal: var(--size-spacing-xs); - --INTERNAL_table-compact-padding-vertical: var(--size-spacing-xs); - --INTERNAL_table-header-background-color: var(--color-brand-white-500); - --INTERNAL_table-header-font-size: var(--size-font-xs); - --INTERNAL_table-header-font-color: var(--color-brand-grey-600); - --INTERNAL_table-header-font-weight: var(--size-font-weight-bold); - --INTERNAL_table-header-sort-icon-spacing: var(--size-spacing-xs); - --INTERNAL_table-header-padding-vertical: var(--size-spacing-md); - --INTERNAL_table-header-border-width: var(--size-border-xs); - --INTERNAL_table-font-size: var(--size-font-sm); - --INTERNAL_table-row-hover-background: var(--color-brand-grey-50); - --INTERNAL_table-row-striped-background: var(--color-brand-grey-50); -} diff --git a/src/styles/variables/tokens.scss b/src/styles/variables/tokens.scss index 7ff37efd5..90ec6a11d 100644 --- a/src/styles/variables/tokens.scss +++ b/src/styles/variables/tokens.scss @@ -1,3 +1,4 @@ @import '~@palmetto/palmetto-design-tokens/build/css/variables-asset.css'; @import '~@palmetto/palmetto-design-tokens/build/css/variables-color.css'; +@import '~@palmetto/palmetto-design-tokens/build/css/variables-color-dark.css'; @import '~@palmetto/palmetto-design-tokens/build/css/variables-size.css'; diff --git a/src/types/index.ts b/src/types/index.ts index 3d1e4f29a..a19b9e4d9 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -21,8 +21,9 @@ import { export type { BorderSize, BoxShadowSize, + BackgroundColor, + BorderColor, BrandColor, - ColorName, FontColor, FontSize, FontWeight, diff --git a/yarn.lock b/yarn.lock index acb4e04cc..793a7788b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2792,18 +2792,6 @@ "@figspec/components" "^1.0.0" "@lit-labs/react" "^1.0.2" -"@fullstory/browser@^1.4.9": - version "1.7.1" - resolved "https://registry.yarnpkg.com/@fullstory/browser/-/browser-1.7.1.tgz#eb94fcb5e21b13a1b30de58951480ac344e61cdd" - integrity sha512-IBPisG+xRyTHHX8XkZJkQRbP2hVYNMZUYW8R3YiB582dl/VZImkFN+LopIAfPqB97FAZgUTofi7flkrHT4Qmtg== - dependencies: - "@fullstory/snippet" "1.3.1" - -"@fullstory/snippet@1.3.1": - version "1.3.1" - resolved "https://registry.yarnpkg.com/@fullstory/snippet/-/snippet-1.3.1.tgz#6817ea94601e071e630b25262e703ca356a5f537" - integrity sha512-NgrBWGHH5i8zejlRFSyJNhovkNqHAXsWKrcXIWaABrgESwbkdGETjOU7BD7d1ZeT0X+QXL/2yr/1y4xnWfVkwQ== - "@gar/promisify@^1.0.1", "@gar/promisify@^1.1.3": version "1.1.3" resolved "https://registry.yarnpkg.com/@gar/promisify/-/promisify-1.1.3.tgz#555193ab2e3bb3b6adc3d551c9c030d9e860daf6" @@ -3532,10 +3520,10 @@ react-remove-scroll "^2.4.3" tslib "^2.3.0" -"@palmetto/palmetto-design-tokens@0.79.2": - version "0.79.2" - resolved "https://registry.yarnpkg.com/@palmetto/palmetto-design-tokens/-/palmetto-design-tokens-0.79.2.tgz#6236ed70252c05119375754529fb6a3d06d6c65d" - integrity sha512-9K36ykZSpZjCSPIKTEFgoEO8HdtCiSC7CF27gKVc2BEhAJ6XdT+vlp4j7Rr2Wto8CwM/hQZXSe+XqYL6VRrmGg== +"@palmetto/palmetto-design-tokens@1.7.2": + version "1.7.2" + resolved "https://registry.yarnpkg.com/@palmetto/palmetto-design-tokens/-/palmetto-design-tokens-1.7.2.tgz#269903b7cbfa77a95889ad5eeaa453332fdd9f99" + integrity sha512-4Ldyr+U+oUCnDHXkXOBIdmQSiZjG/E6pst/Tl69qLBJ3ZsvLUXvu3jyiGy//O0wYpVaO7BBsyT3q5a6e5ycdyg== "@pmmmwh/react-refresh-webpack-plugin@^0.5.3": version "0.5.10"