diff --git a/.github/project-labeler.yml b/.github/project-labeler.yml index 41f86eefc7..77a36d30df 100644 --- a/.github/project-labeler.yml +++ b/.github/project-labeler.yml @@ -128,4 +128,6 @@ pie-webc-core: - 'packages/components/pie-webc-core/**/*' pie-webc-testing: - - 'packages/components/pie-webc-testing/**/*' \ No newline at end of file + - 'packages/components/pie-webc-testing/**/*' +pie-toast-provider: + - packages/components/pie-toast-provider/**/* diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e214c7a9ba..570208c03c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -51,6 +51,7 @@ env: PERCY_DO_NOT_CAPTURE_RESPONSIVE_ASSETS: true PERCY_PAGE_LOAD_TIMEOUT: ${{ vars.PERCY_PAGE_LOAD_TIMEOUT }} PERCY_NETWORK_IDLE_WAIT_TIMEOUT: ${{ vars.PERCY_NETWORK_IDLE_WAIT_TIMEOUT }} + PERCY_TOKEN_PIE_TOAST_PROVIDER: ${{ secrets.PERCY_TOKEN_PIE_TOAST_PROVIDER }} jobs: check-change-type: diff --git a/apps/pie-storybook/package.json b/apps/pie-storybook/package.json index 0bc81b2206..4e6ff8c71e 100644 --- a/apps/pie-storybook/package.json +++ b/apps/pie-storybook/package.json @@ -39,6 +39,7 @@ "@justeattakeaway/pie-text-input": "0.24.5", "@justeattakeaway/pie-textarea": "0.13.0", "@justeattakeaway/pie-toast": "0.5.0", + "@justeattakeaway/pie-toast-provider": "0.0.0", "dompurify": "3.1.3" }, "devDependencies": { diff --git a/apps/pie-storybook/stories/pie-toast-provider.stories.ts b/apps/pie-storybook/stories/pie-toast-provider.stories.ts new file mode 100644 index 0000000000..f7e026cc80 --- /dev/null +++ b/apps/pie-storybook/stories/pie-toast-provider.stories.ts @@ -0,0 +1,34 @@ +import { html } from 'lit'; +import { type Meta } from '@storybook/web-components'; + +import '@justeattakeaway/pie-toast-provider'; +import { type ToastProviderProps } from '@justeattakeaway/pie-toast-provider'; + +import { createStory } from '../utilities'; + +type ToastProviderStoryMeta = Meta; + +const defaultArgs: ToastProviderProps = {}; + +const toastProviderStoryMeta: ToastProviderStoryMeta = { + title: 'Toast Provider', + component: 'pie-toast-provider', + argTypes: {}, + args: defaultArgs, + parameters: { + design: { + type: 'figma', + url: '', + }, + }, +}; + +export default toastProviderStoryMeta; + +// TODO: remove the eslint-disable rule when props are added +// eslint-disable-next-line no-empty-pattern +const Template = ({}: ToastProviderProps) => html` + +`; + +export const Default = createStory(Template, defaultArgs)(); diff --git a/bundlewatch.config.json b/bundlewatch.config.json index a2055453f9..16d2f0c8dc 100644 --- a/bundlewatch.config.json +++ b/bundlewatch.config.json @@ -183,10 +183,16 @@ { "path": "./packages/components/pie-toast/dist/react.js", "maxSize": "0.45 KB" + }, + { + "path": "./packages/components/pie-toast-provider/dist/*.js", + "maxSize": "3 KB" } ], "defaultCompression": "gzip", "ci": { - "trackBranches": ["main"] + "trackBranches": [ + "main" + ] } -} +} \ No newline at end of file diff --git a/packages/components/pie-toast-provider/.eslintignore b/packages/components/pie-toast-provider/.eslintignore new file mode 100644 index 0000000000..a4c746553e --- /dev/null +++ b/packages/components/pie-toast-provider/.eslintignore @@ -0,0 +1,6 @@ +.turbo +dist +node_modules +lit-browsers-report +lit-visual-report +test-results diff --git a/packages/components/pie-toast-provider/README.md b/packages/components/pie-toast-provider/README.md new file mode 100644 index 0000000000..bdf92fa97f --- /dev/null +++ b/packages/components/pie-toast-provider/README.md @@ -0,0 +1,91 @@ +

+ +

+ +

+ + GitHub Workflow Status + +

+ +# Table of Contents + +1. [Introduction](#pie-toast-provider) +2. [Installation](#installation) +3. [Importing the component](#importing-the-component) +4. [Peer Dependencies](#peer-dependencies) +5. [Props](#props) +6. [Contributing](#contributing) + +## pie-toast-provider + +`pie-toast-provider` is a Web Component built using the Lit library. + +This component can be easily integrated into various frontend frameworks and customized through a set of properties. + + +## Installation + +To install `pie-toast-provider` in your application, run the following on your command line: + +```bash +# npm +$ npm i @justeattakeaway/pie-toast-provider + +# yarn +$ yarn add @justeattakeaway/pie-toast-provider +``` + +For full information on using PIE components as part of an application, check out the [Getting Started Guide](https://github.com/justeattakeaway/pie/wiki/Getting-started-with-PIE-Web-Components). + + +### Importing the component + +#### JavaScript +```js +// Default – for Native JS Applications, Vue, Angular, Svelte, etc. +import { PieToastProvider } from '@justeattakeaway/pie-toast-provider'; + +// If you don't need to reference the imported object, you can simply +// import the module which registers the component as a custom element. +import '@justeattakeaway/pie-toast-provider'; +``` + +#### React +```js +// React +// For React, you will need to import our React-specific component build +// which wraps the web component using ​@lit/react +import { PieToastProvider } from '@justeattakeaway/pie-toast-provider/dist/react'; +``` + +> [!NOTE] +> When using the React version of the component, please make sure to also +> include React as a [peer dependency](#peer-dependencies) in your project. + + +## Peer Dependencies + +> [!IMPORTANT] +> When using `pie-toast-provider`, you will also need to include a couple of dependencies to ensure the component renders as expected. See [the PIE Wiki](https://github.com/justeattakeaway/pie/wiki/Getting-started-with-PIE-Web-Components#expected-dependencies) for more information and how to include these in your application. + + +## Props + +| Property | Type | Default | Description | +|---|---|---|---| +| - | - | - | - | + +In your markup or JSX, you can then use these to set the properties for the `pie-toast-provider` component: + +```html + + + + + +``` + +## Contributing + +Check out our [contributing guide](https://github.com/justeattakeaway/pie/wiki/Contributing-Guide) for more information on [local development](https://github.com/justeattakeaway/pie/wiki/Contributing-Guide#local-development) and how to run specific [component tests](https://github.com/justeattakeaway/pie/wiki/Contributing-Guide#testing). \ No newline at end of file diff --git a/packages/components/pie-toast-provider/custom-elements-manifest.config.mjs b/packages/components/pie-toast-provider/custom-elements-manifest.config.mjs new file mode 100644 index 0000000000..b4be0cb5ed --- /dev/null +++ b/packages/components/pie-toast-provider/custom-elements-manifest.config.mjs @@ -0,0 +1,15 @@ +import { moduleFileExtensionsPlugin } from 'cem-plugin-module-file-extensions'; + +export default { + globs: [ + './src/**/!(*.css).ts', + ], + exclude: [ + '**/*.d.ts', + '**/*.d.js', + '**/react.ts', + '**/test/**', + '**/node_modules/**', + ], + plugins: [moduleFileExtensionsPlugin()], +}; diff --git a/packages/components/pie-toast-provider/declaration.d.ts b/packages/components/pie-toast-provider/declaration.d.ts new file mode 100644 index 0000000000..e198d772d0 --- /dev/null +++ b/packages/components/pie-toast-provider/declaration.d.ts @@ -0,0 +1,9 @@ +declare module '*.scss' { + const content: Record; + export default content; +} + +declare module '*.scss?inline' { + const content: Record; + export default content; +} diff --git a/packages/components/pie-toast-provider/package.json b/packages/components/pie-toast-provider/package.json new file mode 100644 index 0000000000..b19ba8a56b --- /dev/null +++ b/packages/components/pie-toast-provider/package.json @@ -0,0 +1,53 @@ +{ + "name": "@justeattakeaway/pie-toast-provider", + "description": "PIE Design System Toast Provider built using Web Components", + "version": "0.0.0", + "type": "module", + "main": "dist/index.js", + "module": "dist/index.js", + "types": "dist/index.d.ts", + "files": [ + "custom-elements.json", + "src", + "dist", + "**/*.d.ts" + ], + "pieMetadata": { + "componentStatus": "alpha" + }, + "scripts": { + "build": "run -T vite build", + "build:react-wrapper": "npx build-react-wrapper", + "create:manifest": "yarn cem analyze --litelement", + "lint:scripts": "run -T eslint .", + "lint:scripts:fix": "yarn lint:scripts --fix", + "lint:style": "run -T stylelint ./src/**/*.{css,scss}", + "lint:style:fix": "yarn lint:style --fix", + "watch": "run -T vite build --watch", + "test": "echo \"Error: no test specified\" && exit 0", + "test:ci": "yarn test", + "test:browsers": "npx playwright test -c ./playwright-lit.config.ts", + "test:browsers:ci": "yarn test:browsers", + "test:visual": "run -T cross-env-shell PERCY_TOKEN=${PERCY_TOKEN_PIE_TOAST_PROVIDER} percy exec --allowed-hostname cloudfront.net -- npx playwright test -c ./playwright-lit-visual.config.ts", + "test:visual:ci": "yarn test:visual", + "test:browsers-setup": "npx playwright-lit-setup" + }, + "author": "Just Eat Takeaway.com - Design System Team", + "license": "Apache-2.0", + "devDependencies": { + "@custom-elements-manifest/analyzer": "0.9.0", + "@justeattakeaway/pie-components-config": "0.18.0", + "@justeattakeaway/pie-css": "0.13.1", + "cem-plugin-module-file-extensions": "0.0.5" + }, + "dependencies": { + "@justeattakeaway/pie-webc-core": "0.24.2" + }, + "volta": { + "extends": "../../../package.json" + }, + "customElements": "custom-elements.json", + "sideEffects": [ + "dist/*.js" + ] +} diff --git a/packages/components/pie-toast-provider/playwright-lit-visual.config.ts b/packages/components/pie-toast-provider/playwright-lit-visual.config.ts new file mode 100644 index 0000000000..fb0f14c480 --- /dev/null +++ b/packages/components/pie-toast-provider/playwright-lit-visual.config.ts @@ -0,0 +1,4 @@ +import { defineConfig } from '@sand4rt/experimental-ct-web'; +import { getPlaywrightVisualConfig } from '@justeattakeaway/pie-components-config'; + +export default defineConfig(getPlaywrightVisualConfig()); diff --git a/packages/components/pie-toast-provider/playwright-lit.config.ts b/packages/components/pie-toast-provider/playwright-lit.config.ts new file mode 100644 index 0000000000..e50b9373b3 --- /dev/null +++ b/packages/components/pie-toast-provider/playwright-lit.config.ts @@ -0,0 +1,4 @@ +import { defineConfig } from '@sand4rt/experimental-ct-web'; +import { getPlaywrightConfig } from '@justeattakeaway/pie-components-config'; + +export default defineConfig(getPlaywrightConfig()); diff --git a/packages/components/pie-toast-provider/src/defs-react.ts b/packages/components/pie-toast-provider/src/defs-react.ts new file mode 100644 index 0000000000..2714b9afa2 --- /dev/null +++ b/packages/components/pie-toast-provider/src/defs-react.ts @@ -0,0 +1,8 @@ +import type React from 'react'; +/** + * TODO: Verify if ReactBaseType can be set as a more specific React interface + * Use the React IntrinsicElements interface to find how to map standard HTML elements to existing React Interfaces + * Example: an HTML button maps to `React.ButtonHTMLAttributes` + * https://github.com/DefinitelyTyped/DefinitelyTyped/blob/0bb210867d16170c4a08d9ce5d132817651a0f80/types/react/index.d.ts#L2829 + */ +export type ReactBaseType = React.HTMLAttributes diff --git a/packages/components/pie-toast-provider/src/defs.ts b/packages/components/pie-toast-provider/src/defs.ts new file mode 100644 index 0000000000..e9a5c00337 --- /dev/null +++ b/packages/components/pie-toast-provider/src/defs.ts @@ -0,0 +1,3 @@ +// TODO - please remove the eslint disable comment below when you add props to this interface +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface ToastProviderProps {} diff --git a/packages/components/pie-toast-provider/src/index.ts b/packages/components/pie-toast-provider/src/index.ts new file mode 100644 index 0000000000..b9bc7e79fa --- /dev/null +++ b/packages/components/pie-toast-provider/src/index.ts @@ -0,0 +1,30 @@ +import { LitElement, html, unsafeCSS } from 'lit'; +import { RtlMixin, defineCustomElement } from '@justeattakeaway/pie-webc-core'; + +import styles from './toast-provider.scss?inline'; +import { type ToastProviderProps } from './defs'; + +// Valid values available to consumers +export * from './defs'; + +const componentSelector = 'pie-toast-provider'; + +/** + * @tagname pie-toast-provider + */ +export class PieToastProvider extends RtlMixin(LitElement) implements ToastProviderProps { + render () { + return html`

Hello world!

`; + } + + // Renders a `CSSResult` generated from SCSS by Vite + static styles = unsafeCSS(styles); +} + +defineCustomElement(componentSelector, PieToastProvider); + +declare global { + interface HTMLElementTagNameMap { + [componentSelector]: PieToastProvider; + } +} diff --git a/packages/components/pie-toast-provider/src/toast-provider.scss b/packages/components/pie-toast-provider/src/toast-provider.scss new file mode 100644 index 0000000000..6ffaedad64 --- /dev/null +++ b/packages/components/pie-toast-provider/src/toast-provider.scss @@ -0,0 +1 @@ +@use '@justeattakeaway/pie-css/scss' as p; diff --git a/packages/components/pie-toast-provider/test/accessibility/pie-toast-provider.spec.ts b/packages/components/pie-toast-provider/test/accessibility/pie-toast-provider.spec.ts new file mode 100644 index 0000000000..4b28a77e21 --- /dev/null +++ b/packages/components/pie-toast-provider/test/accessibility/pie-toast-provider.spec.ts @@ -0,0 +1,12 @@ +import { test, expect } from '@justeattakeaway/pie-webc-testing/src/playwright/webc-fixtures.ts'; +import { PieToastProvider } from '../../src/index.ts'; + +test.describe('PieToastProvider - Accessibility tests', () => { + test('a11y - should test the PieToastProvider component WCAG compliance', async ({ makeAxeBuilder, mount }) => { + await mount(PieToastProvider); + + const results = await makeAxeBuilder().analyze(); + + expect(results.violations).toEqual([]); + }); +}); diff --git a/packages/components/pie-toast-provider/test/component/pie-toast-provider.spec.ts b/packages/components/pie-toast-provider/test/component/pie-toast-provider.spec.ts new file mode 100644 index 0000000000..26ce1fc31a --- /dev/null +++ b/packages/components/pie-toast-provider/test/component/pie-toast-provider.spec.ts @@ -0,0 +1,17 @@ +import { test, expect } from '@sand4rt/experimental-ct-web'; +import { PieToastProvider } from '../../src/index.ts'; + +const componentSelector = '[data-test-id="pie-toast-provider"]'; + +test.describe('PieToastProvider - Component tests', () => { + test('should render successfully', async ({ mount, page }) => { + // Arrange + await mount(PieToastProvider); + + // Act + const toastProvider = page.locator(componentSelector); + + // Assert + expect(toastProvider).toBeVisible(); + }); +}); diff --git a/packages/components/pie-toast-provider/test/visual/pie-toast-provider.spec.ts b/packages/components/pie-toast-provider/test/visual/pie-toast-provider.spec.ts new file mode 100644 index 0000000000..63dd54df0a --- /dev/null +++ b/packages/components/pie-toast-provider/test/visual/pie-toast-provider.spec.ts @@ -0,0 +1,11 @@ +import { test } from '@sand4rt/experimental-ct-web'; +import percySnapshot from '@percy/playwright'; +import { PieToastProvider } from '../../src/index.ts'; + +test.describe('PieToastProvider - Visual tests`', () => { + test('should display the PieToastProvider component successfully', async ({ page, mount }) => { + await mount(PieToastProvider); + + await percySnapshot(page, 'PieToastProvider - Visual Test'); + }); +}); diff --git a/packages/components/pie-toast-provider/tsconfig.json b/packages/components/pie-toast-provider/tsconfig.json new file mode 100644 index 0000000000..e4ffd91463 --- /dev/null +++ b/packages/components/pie-toast-provider/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "@justeattakeaway/pie-components-config/tsconfig.json", + "compilerOptions": { + "baseUrl": ".", + "rootDir": ".", + }, + "include": ["src/**/*.ts","./declaration.d.ts", "test/**/*.ts", "playwright-lit-visual.config.ts", "playwright-lit.config.ts"], +} diff --git a/packages/components/pie-toast-provider/vite.config.js b/packages/components/pie-toast-provider/vite.config.js new file mode 100644 index 0000000000..cd07913d05 --- /dev/null +++ b/packages/components/pie-toast-provider/vite.config.js @@ -0,0 +1,3 @@ +import viteConfig from '@justeattakeaway/pie-components-config/vite.config'; + +export default viteConfig; diff --git a/packages/components/pie-webc/components/toast-provider.d.ts b/packages/components/pie-webc/components/toast-provider.d.ts new file mode 100644 index 0000000000..b700fb7fc7 --- /dev/null +++ b/packages/components/pie-webc/components/toast-provider.d.ts @@ -0,0 +1 @@ +export * from '@justeattakeaway/pie-toast-provider'; diff --git a/packages/components/pie-webc/components/toast-provider.js b/packages/components/pie-webc/components/toast-provider.js new file mode 100644 index 0000000000..b700fb7fc7 --- /dev/null +++ b/packages/components/pie-webc/components/toast-provider.js @@ -0,0 +1 @@ +export * from '@justeattakeaway/pie-toast-provider'; diff --git a/packages/components/pie-webc/package.json b/packages/components/pie-webc/package.json index 35326349f6..e163241a86 100644 --- a/packages/components/pie-webc/package.json +++ b/packages/components/pie-webc/package.json @@ -227,6 +227,16 @@ "import": "./react/toast.js", "require": "./react/toast.js", "types": "./react/toast.d.ts" + }, + "./components/toast-provider.js": { + "import": "./components/toast-provider.js", + "require": "./components/toast-provider.js", + "types": "./components/toast-provider.d.ts" + }, + "./react/toast-provider.js": { + "import": "./react/toast-provider.js", + "require": "./react/toast-provider.js", + "types": "./react/toast-provider.d.ts" } }, "bin": { @@ -266,7 +276,8 @@ "@justeattakeaway/pie-tag": "0.12.0", "@justeattakeaway/pie-text-input": "0.24.5", "@justeattakeaway/pie-textarea": "0.13.0", - "@justeattakeaway/pie-toast": "0.5.0" + "@justeattakeaway/pie-toast": "0.5.0", + "@justeattakeaway/pie-toast-provider": "0.0.0" }, "volta": { "extends": "../../../package.json" diff --git a/packages/components/pie-webc/react/toast-provider.d.ts b/packages/components/pie-webc/react/toast-provider.d.ts new file mode 100644 index 0000000000..462e0a3b8f --- /dev/null +++ b/packages/components/pie-webc/react/toast-provider.d.ts @@ -0,0 +1 @@ +export * from '@justeattakeaway/pie-toast-provider/dist/react.js'; diff --git a/packages/components/pie-webc/react/toast-provider.js b/packages/components/pie-webc/react/toast-provider.js new file mode 100644 index 0000000000..462e0a3b8f --- /dev/null +++ b/packages/components/pie-webc/react/toast-provider.js @@ -0,0 +1 @@ +export * from '@justeattakeaway/pie-toast-provider/dist/react.js'; diff --git a/yarn.lock b/yarn.lock index cc2ef9792b..ece1109852 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5162,6 +5162,18 @@ __metadata: languageName: unknown linkType: soft +"@justeattakeaway/pie-toast-provider@0.0.0, @justeattakeaway/pie-toast-provider@workspace:packages/components/pie-toast-provider": + version: 0.0.0-use.local + resolution: "@justeattakeaway/pie-toast-provider@workspace:packages/components/pie-toast-provider" + dependencies: + "@custom-elements-manifest/analyzer": 0.9.0 + "@justeattakeaway/pie-components-config": 0.18.0 + "@justeattakeaway/pie-css": 0.13.1 + "@justeattakeaway/pie-webc-core": 0.24.2 + cem-plugin-module-file-extensions: 0.0.5 + languageName: unknown + linkType: soft + "@justeattakeaway/pie-toast@0.5.0, @justeattakeaway/pie-toast@workspace:packages/components/pie-toast": version: 0.0.0-use.local resolution: "@justeattakeaway/pie-toast@workspace:packages/components/pie-toast" @@ -5224,6 +5236,7 @@ __metadata: "@justeattakeaway/pie-text-input": 0.24.5 "@justeattakeaway/pie-textarea": 0.13.0 "@justeattakeaway/pie-toast": 0.5.0 + "@justeattakeaway/pie-toast-provider": 0.0.0 chalk: 5.3.0 bin: add-components: ./src/index.js @@ -22925,6 +22938,7 @@ __metadata: "@justeattakeaway/pie-text-input": 0.24.5 "@justeattakeaway/pie-textarea": 0.13.0 "@justeattakeaway/pie-toast": 0.5.0 + "@justeattakeaway/pie-toast-provider": 0.0.0 "@storybook/addon-a11y": 8.3.0 "@storybook/addon-designs": 8.0.3 "@storybook/addon-essentials": 8.3.0