From 372fd39e2529cce28f74d9b5e5ece7f2bf728501 Mon Sep 17 00:00:00 2001 From: maledr5 Date: Mon, 22 Jul 2024 17:04:45 +0200 Subject: [PATCH 01/12] docs(pie-docs): DSW-2211 adding overview of web components (#1589) * docs(pie-docs): DSW-2211 add tag shortcode to pie docs This shortcode copy the web component variants. Can be removed once we are able to use our web components in pie docs. * docs(pie-docs): DSW-2211 adding overview of web components Refactors some copy and adds a guide to choose waht component library to use. * docs(pie-docs): DSW-2211 removes new lines and adds changeset file * docs(pie-docs): DSW-2211 fix formatting in headings * docs(pie-docs): DSW-2211 add missing route for testing * docs(pie-docs): DSW-2211 updates README with config for running tests locally * docs(pie-docs): DSW-2211 address PR comments * docs(pie-docs): DSW-2211 address PR comments Co-authored-by: Ashley Watson-Nolan Co-authored-by: Xander Marjoram * docs(pie-docs): DSW-2211 address PR comments * docs(pie-docs): DSW-2211 pr comments - intro section and Next 13 copy * Apply suggestions from code review docs(pie-docs): DSW-2211 address PR comments Co-authored-by: Xander Marjoram --------- Co-authored-by: Ashley Watson-Nolan Co-authored-by: Xander Marjoram --- .changeset/neat-lies-relax.md | 5 + apps/pie-docs/README.md | 15 ++- apps/pie-docs/src/_11ty/shortcodes/index.js | 4 +- apps/pie-docs/src/_11ty/shortcodes/tag.js | 13 +++ .../src/assets/styles/_dependencies.scss | 1 + .../src/assets/styles/components/_tag.scss | 85 +++++++++++++++++ .../src/engineers/getting-started/overview.md | 15 ++- .../engineers/getting-started/structure.md | 92 ++++++++++++++++++- .../src/engineers/web-components/overview.md | 49 ++++++++++ .../web-components/web-components.json | 5 + .../web-components/web-components.md | 9 ++ .../snapshots/expected-routes.snapshot.json | 1 + 12 files changed, 280 insertions(+), 14 deletions(-) create mode 100644 .changeset/neat-lies-relax.md create mode 100644 apps/pie-docs/src/_11ty/shortcodes/tag.js create mode 100644 apps/pie-docs/src/assets/styles/components/_tag.scss create mode 100644 apps/pie-docs/src/engineers/web-components/overview.md create mode 100644 apps/pie-docs/src/engineers/web-components/web-components.json create mode 100644 apps/pie-docs/src/engineers/web-components/web-components.md diff --git a/.changeset/neat-lies-relax.md b/.changeset/neat-lies-relax.md new file mode 100644 index 0000000000..86c5c54db3 --- /dev/null +++ b/.changeset/neat-lies-relax.md @@ -0,0 +1,5 @@ +--- +"pie-docs": minor +--- + +[Changed] - Updates Engineering copy and adds new Web Components index guide to current documentation in Github Wiki. diff --git a/apps/pie-docs/README.md b/apps/pie-docs/README.md index 334b5402ec..cf947baac4 100644 --- a/apps/pie-docs/README.md +++ b/apps/pie-docs/README.md @@ -59,16 +59,23 @@ Our primary concerns are: 4. Our shortcodes return the expected HTML ### Page testing + We have route navigation tests that ensure all existing pages can be correctly navigated to. When you add new pages, these tests will fail as there are new unexpected pages (this is by design). -In order to fix the tests, you will need to register the routes to your newly added pages by running from the root of the monorepo: `yarn test:generate-routes`. This will update the JSON file named `expected-routes.snapshot.json` with the URLs to your new page. +Route tests need a production build so that they do not fail with `draft` page routes. For this, we recommend to: +1. Stop any local instance of the doc site +2. Delete your `dist` folder +3. Create a production build with `yarn build --filter=pie-docs` +Once this is done, you can run the route tests with `yarn test --filter=pie-docs`. From here, we run navigation, accessibility and visual tests against each route. -#### Running the route tests -Route tests are ran as part of `yarn test`. +#### Adding new routes + +In order to fix the tests, you will need to register the routes to your newly added pages by running the following command from the root of the monorepo: `yarn test:generate-routes`. This will update the JSON file named `expected-routes.snapshot.json` with the paths to your new pages. + +### Testing navigation responses -#### Testing navigation responses Running `yarn test:browsers` will ensure that navigating to the routes stored in `expected-routes.snapshot.json` result in Status Code `200` responses. In order to run this command you will need the site to be served to localhost by running `yarn dev --filter=pie-docs` in another terminal. diff --git a/apps/pie-docs/src/_11ty/shortcodes/index.js b/apps/pie-docs/src/_11ty/shortcodes/index.js index 5f68ddbfbd..63f19b8a47 100644 --- a/apps/pie-docs/src/_11ty/shortcodes/index.js +++ b/apps/pie-docs/src/_11ty/shortcodes/index.js @@ -11,6 +11,7 @@ const mediaElement = require('./mediaElementList'); const notification = require('./notification'); const resourceTable = require('./resourceTable'); const simpleTable = require('./simpleTable'); +const tag = require('./tag'); const termsAndDescriptions = require('./termsAndDescriptions'); const tokensTable = require('./tokensTable'); const usage = require('./usage'); @@ -36,8 +37,9 @@ const addAllShortCodes = (eleventyConfig) => { eleventyConfig.addShortcode('notification', (shortcodeArgs) => deindentHTML(notification(shortcodeArgs))); eleventyConfig.addShortcode('resourceTable', (shortcodeArgs) => deindentHTML(resourceTable(shortcodeArgs))); eleventyConfig.addShortcode('simpleTable', (shortcodeArgs) => deindentHTML(simpleTable(shortcodeArgs))); - eleventyConfig.addShortcode('tokensTable', (shortcodeArgs) => deindentHTML(tokensTable(shortcodeArgs))); + eleventyConfig.addShortcode('tag', (shortcodeArgs) => deindentHTML(tag(shortcodeArgs))); eleventyConfig.addShortcode('termsAndDescriptions', (shortcodeArgs) => deindentHTML(termsAndDescriptions(shortcodeArgs))); + eleventyConfig.addShortcode('tokensTable', (shortcodeArgs) => deindentHTML(tokensTable(shortcodeArgs))); eleventyConfig.addShortcode('usage', (shortcodeArgs) => deindentHTML(usage(shortcodeArgs))); }; diff --git a/apps/pie-docs/src/_11ty/shortcodes/tag.js b/apps/pie-docs/src/_11ty/shortcodes/tag.js new file mode 100644 index 0000000000..52f11c96a0 --- /dev/null +++ b/apps/pie-docs/src/_11ty/shortcodes/tag.js @@ -0,0 +1,13 @@ +// @TODO DSW-2258: be replaced once web components are integrated +/** + * Generate an HTML tag component. It duplicates pie tag variants. + * Can be replaced by pie tag when we include pie web components + * @param {string} label - string that renders within the tag + * @param {string} variant - variant name: neutral, blue, green, + * yellow, red, brand, neutral-alternative, outline, ghost + * @returns {string} + */ +module.exports = ({ + label, + variant, +}) => `${label}`; diff --git a/apps/pie-docs/src/assets/styles/_dependencies.scss b/apps/pie-docs/src/assets/styles/_dependencies.scss index 2552387813..248642e5ad 100644 --- a/apps/pie-docs/src/assets/styles/_dependencies.scss +++ b/apps/pie-docs/src/assets/styles/_dependencies.scss @@ -59,6 +59,7 @@ @use 'components/simpleTable'; @use 'components/table'; @use 'components/tabs'; +@use 'components/tag'; @use 'components/termsAndDescriptions'; @use 'components/toggle'; @use 'components/tokensTable'; diff --git a/apps/pie-docs/src/assets/styles/components/_tag.scss b/apps/pie-docs/src/assets/styles/components/_tag.scss new file mode 100644 index 0000000000..2ddebad3a0 --- /dev/null +++ b/apps/pie-docs/src/assets/styles/components/_tag.scss @@ -0,0 +1,85 @@ +@use '@justeattakeaway/pie-css/scss/settings' as *; +@use '@justeattakeaway/pie-css/scss' as p; + +.c-tag { + --tag-bg-color: var(--dt-color-container-strong); + --tag-color: var(--dt-color-content-default); + --tag-border-radius: var(--dt-radius-rounded-b); + --tag-padding-block: 2px; + --tag-padding-inline: var(--dt-spacing-b); + --tag-font-family: var(--dt-font-body-s-family); + --tag-font-weight: var(--dt-font-body-s-weight); + --tag-font-size: #{p.font-size(--dt-font-body-s-size)}; + --tag-line-height: #{p.line-height(--dt-font-body-s-line-height)}; + + // transparent to variable to function properly in component tests + --tag-transparent-bg-color: transparent; + + // Pie Webc Icon var that is used to ensure the correctly sized icon passed in a slot + --icon-display-override: block; + --icon-size-override: 16px; + + display: inline-flex; + vertical-align: middle; + align-items: center; + justify-content: center; + gap: var(--dt-spacing-a); + padding: var(--tag-padding-block) var(--tag-padding-inline); + border-radius: var(--tag-border-radius); + background-color: var(--tag-bg-color); + color: var(--tag-color); + font-family: var(--tag-font-family); + font-weight: var(--tag-font-weight); + font-size: var(--tag-font-size); + line-height: var(--tag-line-height); + + + &[variant='neutral'] { + // same as default styles + } + + &[variant='blue'] { + --tag-bg-color: var(--dt-color-support-info-02); + --tag-color: var(--dt-color-content-default); + } + + &[variant='green'] { + --tag-bg-color: var(--dt-color-support-positive-02); + --tag-color: var(--dt-color-content-default); + } + + &[variant='yellow'] { + --tag-bg-color: var(--dt-color-support-warning-02); + --tag-color: var(--dt-color-content-default); + } + + &[variant='red'] { + --tag-bg-color: var(--dt-color-support-error-02); + --tag-color: var(--dt-color-content-default); + } + + &[variant='brand'] { + --tag-bg-color: var(--dt-color-support-brand-02); + --tag-color: var(--dt-color-content-default); + } + + &[variant='neutral-alternative'] { + --tag-bg-color: var(--dt-color-container-default); + --tag-color: var(--dt-color-content-default); + } + + &[variant='outline'] { + --tag-bg-color: var(--tag-transparent-bg-color); + --tag-color: var(--dt-color-content-default); + + // the outline in design specs is part of the total component + // height calculation, thus, we use box-shadow to mimic borders + // and avoid the extra 2px from "border: 1px solid" as shadows are applied "internally" + box-shadow: 0 0 0 1px var(--dt-color-border-strong); + } + + &[variant='ghost'] { + --tag-bg-color: var(--tag-transparent-bg-color); + --tag-color: var(--dt-color-content-default); + } +} diff --git a/apps/pie-docs/src/engineers/getting-started/overview.md b/apps/pie-docs/src/engineers/getting-started/overview.md index bfa0e88664..77c18c007f 100644 --- a/apps/pie-docs/src/engineers/getting-started/overview.md +++ b/apps/pie-docs/src/engineers/getting-started/overview.md @@ -10,17 +10,11 @@ permalink: engineers/getting-started/ One of the core aims of the **PIE Design System** is to provide engineers with a consistent set of components and best practices for creating and maintaining UIs across JET. -If you're just starting out with PIE, here's a list of recommended resources to get you started. - ---- - -## Code and Project Structure - -All of our PIE components, tools and documentation (including this site) are maintained on the open-source [PIE Monorepo on Github](https://github.com/justeattakeaway/pie). +We develop and maintain several component libraries that implement the PIE design language. Please follow [this guide](/engineers/getting-started/structure/#which-library-should-i-use) to find out which library to use based on your tech stack. For a more detailed look at the **component systems** the PIE team maintain, the PIE monorepo and how it’s structured, see the [structure section of our engineering docs](/engineers/getting-started/structure). -We also help to maintain a number of other projects that incorporate the PIE Design Language (such as [Fozzie](https://github.com/justeattakeaway/fozzie-components) for **VueJS components**, or [Snacks](https://snacks.takeaway.com/) and [Skip PIE](https://github.com/justeat/pie-project) for **React components**). +For a list of which components are supported in each of our libraries, please refer to the [Component Status page](/components/component-status/). --- @@ -30,6 +24,11 @@ If you'd like to contribute to PIE, check out our [contributing guide](/engineer We also maintain **guides** for global front-end best practices across JET. These can be found in the [engineering guidelines section of our docs](/engineers/guidelines/). +### Code and Project Structure + +PIE Web Components, tools and documentation (including this site) are maintained on the open-source [PIE Monorepo on Github](https://github.com/justeattakeaway/pie). + +We support and maintain a number of other projects that incorporate the PIE Design Language (such as [Fozzie](https://github.com/justeattakeaway/fozzie-components) for **VueJS components**, or [Snacks](https://snacks.takeaway.com/) and [Skip PIE](https://github.com/justeat/pie-project) for **React components**). - - - React App - - - -
- - - diff --git a/apps/examples/wc-react17/src/styles.css b/apps/examples/wc-react17/src/App.css similarity index 100% rename from apps/examples/wc-react17/src/styles.css rename to apps/examples/wc-react17/src/App.css diff --git a/apps/examples/wc-react17/src/App.js b/apps/examples/wc-react17/src/App.jsx similarity index 79% rename from apps/examples/wc-react17/src/App.js rename to apps/examples/wc-react17/src/App.jsx index 7a8c897866..d5fe3bcd68 100644 --- a/apps/examples/wc-react17/src/App.js +++ b/apps/examples/wc-react17/src/App.jsx @@ -1,7 +1,7 @@ -import { PieButton } from '@justeattakeaway/pie-button/dist/react'; +import { PieButton } from '@justeattakeaway/pie-webc/react/button.js'; import '@justeattakeaway/pie-css'; -import './styles.css'; +import './App.css'; function App () { return ( diff --git a/apps/examples/wc-react17/src/index.js b/apps/examples/wc-react17/src/index.js deleted file mode 100644 index 8e6b727804..0000000000 --- a/apps/examples/wc-react17/src/index.js +++ /dev/null @@ -1,10 +0,0 @@ -import React from 'react'; -import { render } from 'react-dom'; -import App from './App'; - -render( - - - , - document.getElementById('root'), -); diff --git a/apps/examples/wc-react17/src/main.jsx b/apps/examples/wc-react17/src/main.jsx new file mode 100644 index 0000000000..26a751e915 --- /dev/null +++ b/apps/examples/wc-react17/src/main.jsx @@ -0,0 +1,10 @@ +import React from "react"; +import ReactDOM from "react-dom"; +import App from "./App.jsx"; + +ReactDOM.render( + + + , + document.getElementById("root") +); diff --git a/apps/examples/wc-react17/vite.config.js b/apps/examples/wc-react17/vite.config.js new file mode 100644 index 0000000000..5a33944a9b --- /dev/null +++ b/apps/examples/wc-react17/vite.config.js @@ -0,0 +1,7 @@ +import { defineConfig } from 'vite' +import react from '@vitejs/plugin-react' + +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [react()], +}) diff --git a/yarn.lock b/yarn.lock index 8b9514d50a..5173fbacd3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11358,6 +11358,15 @@ __metadata: languageName: node linkType: hard +"@types/react-dom@npm:^17.0.2": + version: 17.0.25 + resolution: "@types/react-dom@npm:17.0.25" + dependencies: + "@types/react": ^17 + checksum: d1e582682478e0848c8d54ea3e89d02047bac6d916266b85ce63731b06987575919653ea7159d98fda47ade3362b8c4d5796831549564b83088e7aa9ce8b60ed + languageName: node + linkType: hard + "@types/react@npm:*, @types/react@npm:18.3.3, @types/react@npm:>=16": version: 18.3.3 resolution: "@types/react@npm:18.3.3" @@ -11368,6 +11377,17 @@ __metadata: languageName: node linkType: hard +"@types/react@npm:^17, @types/react@npm:^17.0.2": + version: 17.0.80 + resolution: "@types/react@npm:17.0.80" + dependencies: + "@types/prop-types": "*" + "@types/scheduler": ^0.16 + csstype: ^3.0.2 + checksum: 1c27bfc42305d77ef0da55f8f6d4c4a3471aa02b294fcf29ea0f2cfb0bf02892e5a0a3bc7559fa4a5ba50697b2e31076cb5aa5987f69cfc2e880f6426edb8bdf + languageName: node + linkType: hard + "@types/resolve@npm:1.17.1": version: 1.17.1 resolution: "@types/resolve@npm:1.17.1" @@ -11400,6 +11420,13 @@ __metadata: languageName: node linkType: hard +"@types/scheduler@npm:^0.16": + version: 0.16.8 + resolution: "@types/scheduler@npm:0.16.8" + checksum: 6c091b096daa490093bf30dd7947cd28e5b2cd612ec93448432b33f724b162587fed9309a0acc104d97b69b1d49a0f3fc755a62282054d62975d53d7fd13472d + languageName: node + linkType: hard + "@types/semver@npm:^7.3.12, @types/semver@npm:^7.3.4, @types/semver@npm:^7.5.0": version: 7.5.8 resolution: "@types/semver@npm:7.5.8" @@ -19184,12 +19211,12 @@ __metadata: linkType: hard "enhanced-resolve@npm:^5.10.0, enhanced-resolve@npm:^5.12.0, enhanced-resolve@npm:^5.14.1, enhanced-resolve@npm:^5.17.0": - version: 5.17.0 - resolution: "enhanced-resolve@npm:5.17.0" + version: 5.17.1 + resolution: "enhanced-resolve@npm:5.17.1" dependencies: graceful-fs: ^4.2.4 tapable: ^2.2.0 - checksum: 1066000454da6a7aeabdbe1f433d912d1e39e6892142a78a37b6577aab27e0436091fa1399d857ad87085b1c3b73a0f811c8874da3dbdc40fbd5ebe89a5568e6 + checksum: 4bc38cf1cea96456f97503db7280394177d1bc46f8f87c267297d04f795ac5efa81e48115a2f5b6273c781027b5b6bfc5f62b54df629e4d25fa7001a86624f59 languageName: node linkType: hard @@ -31759,9 +31786,9 @@ __metadata: linkType: hard "postcss-resolve-nested-selector@npm:^0.1.1": - version: 0.1.1 - resolution: "postcss-resolve-nested-selector@npm:0.1.1" - checksum: b08fb76ab092a09ee01328bad620a01dcb445ac5eb02dd0ed9ed75217c2f779ecb3bf99a361c46e695689309c08c09f1a1ad7354c8d58c2c2c40d364657fcb08 + version: 0.1.4 + resolution: "postcss-resolve-nested-selector@npm:0.1.4" + checksum: 8de7abd1ae129233480ac123be243e2a722a4bb73fa54fb09cbbe6f10074fac960b9caadad8bc658982b96934080bd7b7f01b622ca7d5d78a25dc9c0532b17cb languageName: node linkType: hard @@ -36584,8 +36611,8 @@ __metadata: linkType: hard "terser-webpack-plugin@npm:^1.4.3": - version: 1.4.5 - resolution: "terser-webpack-plugin@npm:1.4.5" + version: 1.4.6 + resolution: "terser-webpack-plugin@npm:1.4.6" dependencies: cacache: ^12.0.2 find-cache-dir: ^2.1.0 @@ -36598,7 +36625,7 @@ __metadata: worker-farm: ^1.7.0 peerDependencies: webpack: ^4.0.0 - checksum: 02aada80927d3c8105d69cb00384d307b73aed67d180db5d20023a8d649149f3803ad50f9cd2ef9eb2622005de87e677198ecc5088f51422bfac5d4d57472d0e + checksum: 8b6c84df929383032edb25c949781dc55dc31ff85dda9ede25af49357077f615f0065101fcc567cd9c801c8cb1f158ce441fb193c18c6127d04a809a1e7d0d2b languageName: node linkType: hard @@ -39237,12 +39264,19 @@ __metadata: version: 0.0.0-use.local resolution: "wc-react17@workspace:apps/examples/wc-react17" dependencies: - "@justeattakeaway/pie-button": 0.47.8 "@justeattakeaway/pie-css": 0.12.1 - "@lit/react": 1.0.2 + "@justeattakeaway/pie-webc": 0.5.13 + "@lit/react": 1.0.5 + "@types/react": ^17.0.2 + "@types/react-dom": ^17.0.2 + "@vitejs/plugin-react": 4.3.1 + eslint: 8.57.0 + eslint-plugin-react: 7.34.3 + eslint-plugin-react-hooks: 4.6.2 + eslint-plugin-react-refresh: 0.4.7 react: 17.0.2 react-dom: 17.0.2 - react-scripts: 5.0.1 + vite: 5.3.4 languageName: unknown linkType: soft From d3d974c76a5ee1e800c30b59e81002d089b5a26d Mon Sep 17 00:00:00 2001 From: Ashley Watson-Nolan Date: Wed, 24 Jul 2024 15:49:14 +0100 Subject: [PATCH 09/12] feat(pie-button): DSW-000 Changing styles to use classmap (#1587) * refactor(pie-button): DSW-000 updated styles to use classmap * format(pie-button): DSW-000 formatting updates for PR comments * fix(pie-button): DSW-000 change loading attribute to class --- .changeset/modern-melons-draw.md | 6 + .../components/pie-button/src/button.scss | 120 +++++++++++------- packages/components/pie-button/src/index.ts | 22 ++-- .../test/component/pie-button.spec.ts | 10 +- .../scss/mixins/_buttonInteractiveStates.scss | 2 +- .../mixins/buttonInteractiveStates.spec.ts | 6 +- 6 files changed, 103 insertions(+), 63 deletions(-) create mode 100644 .changeset/modern-melons-draw.md diff --git a/.changeset/modern-melons-draw.md b/.changeset/modern-melons-draw.md new file mode 100644 index 0000000000..8c7dfa0c17 --- /dev/null +++ b/.changeset/modern-melons-draw.md @@ -0,0 +1,6 @@ +--- +"@justeattakeaway/pie-button": minor +--- + +[Changed] - Styles now use classmap +[Fixed] - Fixed background colour when button is in `xsmall` or `small` size and responsive mode is true, where the bg-color wasn't updating to orange as required diff --git a/packages/components/pie-button/src/button.scss b/packages/components/pie-button/src/button.scss index 632e407ac4..ed949dd725 100644 --- a/packages/components/pie-button/src/button.scss +++ b/packages/components/pie-button/src/button.scss @@ -1,14 +1,13 @@ @use '@justeattakeaway/pie-css/scss' as p; - -$breakpoint-wide: 768px; +@use '@justeattakeaway/pie-css/scss/settings' as *; /** * Mixin for adding the responsive behaviour. * Takes in the the particular settings for the wide breakpoint. */ @mixin responsive-wide { - &[isResponsive] { - @media (min-width: $breakpoint-wide) { + &.o-btn--responsive { + @include media('>md') { @content; } } @@ -94,12 +93,14 @@ $breakpoint-wide: 768px; // used to specify whether the button should be full width or not inline-size: var(--btn-inline-size); - // Variant - &[variant='primary'] { + // ************************ + // Button Variant Modifiers + // ************************ + &.o-btn--primary { @include p.button-interactive-states('--dt-color-interactive-brand'); - &[size='xsmall'], - &[size='small-productive'] { + &.o-btn--xsmall, + &.o-btn--small-productive { /** * Where the font-size is smaller, * update the button backgrounds so that the text is accessible @@ -108,16 +109,27 @@ $breakpoint-wide: 768px; @include p.button-interactive-states('--dt-color-interactive-primary', 'inverse'); } + + // This is to handle the background colour change getting overridden above, but then being put in responsive mode + // can't use :not for this unfortunately, as then the smaller narrow state would lose its background colour too + &.o-btn--xsmall.o-btn--expressive, + &.o-btn--small-productive { + @include responsive-wide { + --btn-bg-color: var(--dt-color-interactive-brand); + + @include p.button-interactive-states('--dt-color-interactive-brand'); + } + } } - &[variant='secondary'] { + &.o-btn--secondary { --btn-bg-color: var(--dt-color-interactive-secondary); --btn-text-color: var(--dt-color-content-interactive-secondary); @include p.button-interactive-states('--dt-color-interactive-secondary'); } - &[variant='outline'] { + &.o-btn--outline { --btn-bg-color: transparent; --btn-text-color: var(--dt-color-content-interactive-secondary); @@ -128,7 +140,7 @@ $breakpoint-wide: 768px; @include p.button-interactive-states('--dt-color-black', 'transparent'); } - &[variant='ghost'] { + &.o-btn--ghost { --btn-bg-color: transparent; --btn-text-color: var(--dt-color-content-link); @@ -137,15 +149,15 @@ $breakpoint-wide: 768px; @include p.button-interactive-states('--dt-color-black', 'transparent'); } - &[variant='inverse'] { + &.o-btn--inverse { --btn-bg-color: var(--dt-color-interactive-inverse); --btn-text-color: var(--dt-color-content-interactive-secondary); @include p.button-interactive-states('--dt-color-interactive-inverse'); } - &[variant='ghost-inverse'], - &[variant='outline-inverse'] { + &.o-btn--ghost-inverse, + &.o-btn--outline-inverse { --btn-bg-color: transparent; --btn-text-color: var(--dt-color-content-interactive-primary); @@ -154,17 +166,17 @@ $breakpoint-wide: 768px; @include p.button-interactive-states('--dt-color-container-default', 'transparent'); } - &[variant='outline-inverse']:not([disabled]) { + &.o-btn--outline-inverse:not([disabled]) { border: 1px solid var(--dt-color-border-strong); } - &[variant='destructive'] { + &.o-btn--destructive { --btn-bg-color: var(--dt-color-support-error); @include p.button-interactive-states('--dt-color-support-error'); } - &[variant='destructive-ghost'] { + &.o-btn--destructive-ghost { --btn-bg-color: transparent; --btn-text-color: var(--dt-color-content-interactive-error); @@ -173,65 +185,80 @@ $breakpoint-wide: 768px; @include p.button-interactive-states('--dt-color-black', 'transparent'); } - // Additional modifiers - &[isFullWidth] { - --btn-inline-size: 100%; - } - - &[disabled] { - --btn-text-color: var(--dt-color-content-disabled) !important; - - cursor: not-allowed; - - // For every variant (except ghost variants) set the disabled background color - &:not([variant='ghost'], [variant='ghost-inverse'], [variant='destructive-ghost']) { - --btn-bg-color: var(--dt-color-disabled-01) !important; - } - - // For outline variants, set the border to the disabled color - &[variant='outline'] { - border-color: var(--dt-color-disabled-01) !important; - } - } - - &[size='xsmall'] { + // ********************* + // Button Size Modifiers + // ********************* + &.o-btn--xsmall { @include button-size(xsmall); + @include responsive-wide { // productive is the default size when responsive is enabled @include button-size(small-productive); - &[responsiveSize='expressive'] { + &.o-btn--expressive { @include button-size(small-expressive); } } } - &[size='small-expressive'] { + &.o-btn--small-expressive { @include button-size(small-expressive); + @include responsive-wide { @include button-size(medium); } } - &[size='small-productive'] { + &.o-btn--small-productive { @include button-size(small-productive); + @include responsive-wide { @include button-size(medium); } } - &[size='medium'] { + &.o-btn--medium { @include button-size(medium); + @include responsive-wide { @include button-size(large); } } - &[size='large'] { + &.o-btn--large { @include button-size(large); } - &[isLoading] { + // ****************************** + // Additional component modifiers + // ****************************** + &.o-btn--fullWidth { + --btn-inline-size: 100%; + } + + // ************** + // Disabled state + // ************** + &[disabled] { + --btn-text-color: var(--dt-color-content-disabled) !important; + + cursor: not-allowed; + + // For every variant (except ghost variants) set the disabled background color + &:not(.o-btn--ghost, .o-btn--ghost-inverse, .o-btn--destructive-ghost) { + --btn-bg-color: var(--dt-color-disabled-01) !important; + } + + // For outline variants, set the border to the disabled color + &.o-btn--outline { + border-color: var(--dt-color-disabled-01) !important; + } + } + + // ************* + // Loading state + // ************* + &.is-loading { & > *:not(pie-spinner) { visibility: hidden; } @@ -241,6 +268,9 @@ $breakpoint-wide: 768px; } } + // ************ + // Focus styles + // ************ &:focus-visible { @include p.focus; } diff --git a/packages/components/pie-button/src/index.ts b/packages/components/pie-button/src/index.ts index a0806de40e..fa7079dbf0 100644 --- a/packages/components/pie-button/src/index.ts +++ b/packages/components/pie-button/src/index.ts @@ -1,8 +1,8 @@ import { LitElement, html, unsafeCSS, nothing, PropertyValues, TemplateResult, } from 'lit'; +import { classMap } from 'lit/directives/class-map.js'; import { property } from 'lit/decorators.js'; -import { ifDefined } from 'lit/directives/if-defined.js'; import { validPropertyValues, defineCustomElement, FormControlMixin } from '@justeattakeaway/pie-webc-core'; import { ButtonProps, sizes, types, variants, iconPlacements, defaultProps, @@ -226,18 +226,22 @@ export class PieButton extends FormControlMixin(LitElement) implements ButtonPro responsiveSize, } = this; + const classes = { + 'o-btn': true, + 'o-btn--fullWidth': isFullWidth, + 'o-btn--responsive': isResponsive, + [`o-btn--${responsiveSize}`]: Boolean(isResponsive && responsiveSize), + [`o-btn--${variant}`]: true, + [`o-btn--${size}`]: true, + 'is-loading': isLoading, + }; + return html`