@justeattakeaway/pie-webc 0.8.5 → 0.8.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/docs/browser-support.md +58 -0
- package/docs/component-versions.md +42 -0
- package/docs/css-setup.md +117 -0
- package/docs/css-variables.md +49 -0
- package/docs/customising-components.md +117 -0
- package/docs/events.md +116 -0
- package/docs/framework-integration-guides/nextjs-14.md +74 -0
- package/docs/framework-integration-guides/no-framework.md +49 -0
- package/docs/framework-integration-guides/nuxt-3.md +119 -0
- package/docs/framework-integration-guides/react-19.md +62 -0
- package/docs/framework-integration-guides/vue-3.md +44 -0
- package/docs/getting-started.md +36 -0
- package/docs/typescript-usage.md +113 -0
- package/docs/typography.md +120 -0
- package/package.json +33 -32
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Browser support
|
|
2
|
+
|
|
3
|
+
Users have access to hundreds of versions of browsers, so instead of assessing them all individually, we've come up with a rating system that defines different levels of browser support and the testing requirements for each level. We've assigned the highest ratings to the browsers that are most commonly used by our customers.
|
|
4
|
+
|
|
5
|
+
> This list needs to be reviewed often to stay up to date with the browsers chosen by our users.
|
|
6
|
+
|
|
7
|
+
## Table of Contents
|
|
8
|
+
|
|
9
|
+
- [Priority definitions](#priority-definitions)
|
|
10
|
+
- [Browsers and their ratings](#browsers-and-their-ratings)
|
|
11
|
+
- [Desktop](#desktop)
|
|
12
|
+
- [Mobile](#mobile)
|
|
13
|
+
- [Devices](#devices)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
## Priority definitions
|
|
17
|
+
|
|
18
|
+
| Priority Level | Description |
|
|
19
|
+
|----------------|-------------|
|
|
20
|
+
| **A** – Fully Supported | - Testing is required<br/>- All content must be available<br/>- Layout must comply with the design, unless technical needs prevent this<br/>- All functionality must be available and work as required |
|
|
21
|
+
| **B** – Mostly Supported | - Testing is required<br/>- User should be able to place an order or carry out the main function of the page<br/>- Layout doesn't have to be identical to the design, but should retain its functionality |
|
|
22
|
+
| **C** – Not Supported | - Testing is not required<br/>- Browsers rated at B or C may have a better user experience than expected |
|
|
23
|
+
|
|
24
|
+
> A good example of this would be users browsing using Opera. The reason we don't "Fully Support" this browser is simply down to user metrics, not the quality of the browser. We'd actually expect most functionality to work with no real issues, although we don't officially test in this browser.
|
|
25
|
+
|
|
26
|
+
## Browsers and their ratings
|
|
27
|
+
|
|
28
|
+
### Desktop
|
|
29
|
+
|
|
30
|
+
| Browser | Grading |
|
|
31
|
+
|---------|---------|
|
|
32
|
+
| Chrome, last 3 versions (MacOS & Windows) | A |
|
|
33
|
+
| Edge, last 3 versions (Windows) | A |
|
|
34
|
+
| Firefox, last 3 versions (MacOS & Windows) | A |
|
|
35
|
+
| Safari (MacOS), last 3 versions | A |
|
|
36
|
+
| All other browsers & versions | C |
|
|
37
|
+
|
|
38
|
+
### Mobile
|
|
39
|
+
|
|
40
|
+
| Browser | Grading |
|
|
41
|
+
|---------|---------|
|
|
42
|
+
| Safari (iPhone), last 3 versions | A |
|
|
43
|
+
| Safari (iPad), last 3 versions | A |
|
|
44
|
+
| Chrome (Mobile), last 3 versions | A |
|
|
45
|
+
| Samsung Internet, last 3 versions | B |
|
|
46
|
+
| All other browsers & versions | C |
|
|
47
|
+
|
|
48
|
+
## Devices
|
|
49
|
+
|
|
50
|
+
To give an idea of what devices are worth testing on, these are the current recommended device types based on our analytics:
|
|
51
|
+
|
|
52
|
+
| Device | Models |
|
|
53
|
+
|--------|--------|
|
|
54
|
+
| iPhone | Xs to latest (all variants such as SE Gen 2, Pro and Mini) |
|
|
55
|
+
| iPad / iPad mini | iPad Air (Gen 3) to latest (all variants such as Mini & Pro) |
|
|
56
|
+
| Samsung Galaxy | S21 FE to latest |
|
|
57
|
+
| Samsung Galaxy Tab | S8 to latest |
|
|
58
|
+
| Google Pixel | 5a, 7 |
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Component Versions
|
|
2
|
+
|
|
3
|
+
An important feature of web components is that they must be registered in the DOM before they can be used. This tells the browser what component to use when it tries to parse a particular selector such as `<pie-button>`.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
- [How we register components](#how-we-register-components)
|
|
7
|
+
- [Version mismatch issues](#version-mismatch-issues)
|
|
8
|
+
- [The `v` attribute](#the-v-attribute)
|
|
9
|
+
|
|
10
|
+
## How we register components
|
|
11
|
+
PIE web **components will register themselves automatically** when they are imported into the DOM. An illustration of what this looks like under the hood is like this:
|
|
12
|
+
|
|
13
|
+
```js
|
|
14
|
+
class MyComponent extends HTMLElement {
|
|
15
|
+
// Logic omitted for simplicity
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// Register the component as a custom element. This tells the browser to use this class when it encounters the <my-component> tag in the DOM.
|
|
19
|
+
customElements.define('my-component', MyComponent);
|
|
20
|
+
```
|
|
21
|
+
We have some safeguarding in place to ensure this registration only happens once. If you import the same component multiple times (which can easily happen in a complex application), you may see a warning in development mode stating that the component has already been registered.
|
|
22
|
+
|
|
23
|
+
Consumers of PIE web components will never have to perform this step themselves, as it is handled automatically by the component library.
|
|
24
|
+
|
|
25
|
+
## Version mismatch issues
|
|
26
|
+
|
|
27
|
+
One possible issue when using PIE web components is when multiple versions of the same component are registered in the DOM. This can happen if you have multiple versions of the component library installed, or if you import the same component multiple times in your application.
|
|
28
|
+
This most often occurs in **micro-frontend applications**, where multiple teams are working on different parts of the application and may not be aware of each other's dependencies.
|
|
29
|
+
|
|
30
|
+
When this happens, you may see a registration warning as previously mentioned. However our built-in safeguarding will not prevent you from potentially using a component version you were not expecting, as it depends which version was registered first. This could mean the component behaves differently than you expect, or even fails to render at all if the version is incompatible with your application.
|
|
31
|
+
|
|
32
|
+
To avoid this issue, we recommend that teams working on different parts of the application coordinate on which versions of the component library they are using.
|
|
33
|
+
|
|
34
|
+
## The `v` attribute
|
|
35
|
+
|
|
36
|
+
All of our web components have a `v` attribute that indicates the version of the component. This can be particularly useful when debugging issues related to version mismatches. Simply inspect the component in the browser's developer tools and look for the `v` attribute to see which version of the component is being used.
|
|
37
|
+
|
|
38
|
+
This attribute is automatically set by the component library during build. It should be compatible with server-side rendering, so it should be visible in the HTML returned from the server.
|
|
39
|
+
|
|
40
|
+
```html
|
|
41
|
+
<pie-button v="1.0.0"></pie-button>
|
|
42
|
+
```
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# CSS setup
|
|
2
|
+
[Source code](https://github.com/justeattakeaway/pie/tree/main/packages/tools/pie-css) | [NPM package](https://www.npmjs.com/package/@justeattakeaway/pie-css)
|
|
3
|
+
|
|
4
|
+
In order for our components to render correctly, you will need to install our base CSS package, `@justeattakeaway/pie-css`. This package contains all the CSS variables and base styles required for our components to work correctly.
|
|
5
|
+
Most of these CSS variables are what are known as [Design Tokens](https://pie.design/foundations/design-tokens/). They are a vital part of our design system, and are used to ensure consistency across all of our components.
|
|
6
|
+
|
|
7
|
+
## Table of Contents
|
|
8
|
+
|
|
9
|
+
- [Installation](#installation)
|
|
10
|
+
- [Usage](#usage)
|
|
11
|
+
- [JS or Framework import (via bundler)](#js-or-framework-import-via-bundler)
|
|
12
|
+
- [React](#react)
|
|
13
|
+
- [Vue](#vue)
|
|
14
|
+
- [Nuxt](#nuxt)
|
|
15
|
+
- [SCSS](#scss)
|
|
16
|
+
- [CDN](#cdn)
|
|
17
|
+
- [TypeScript usage](#typescript-usage)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
## Installation
|
|
21
|
+
|
|
22
|
+
Simply install the package using your preferred package manager:
|
|
23
|
+
|
|
24
|
+
**Using Yarn:**
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
yarn add @justeattakeaway/pie-css
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
**Using NPM:**
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npm install @justeattakeaway/pie-css
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Usage
|
|
37
|
+
|
|
38
|
+
How you include these styles will largely depend on the type of application you are building (and your own preference), but here are a few examples:
|
|
39
|
+
|
|
40
|
+
### JS or Framework import (via bundler)
|
|
41
|
+
```javascript
|
|
42
|
+
// This is ensure the index.css file is included in your bundle
|
|
43
|
+
import '@justeattakeaway/pie-css';
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
#### React
|
|
47
|
+
In React (or NextJS), you could add the import to your `App.js` file:
|
|
48
|
+
|
|
49
|
+
```javascript
|
|
50
|
+
import '@justeattakeaway/pie-css';
|
|
51
|
+
|
|
52
|
+
function App () {
|
|
53
|
+
return (
|
|
54
|
+
…
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export default App;
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
#### Vue
|
|
62
|
+
|
|
63
|
+
Similarly, in Vue 3, you will likely include it as part of your `/src/main.ts` file:
|
|
64
|
+
|
|
65
|
+
```javascript
|
|
66
|
+
import { createApp } from 'vue';
|
|
67
|
+
import '@justeattakeaway/pie-css';
|
|
68
|
+
import App from './App.vue';
|
|
69
|
+
|
|
70
|
+
createApp(App).mount('#app');
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
#### Nuxt
|
|
74
|
+
|
|
75
|
+
If you are using Nuxt, you can import the CSS into your `nuxt.config.js` file.
|
|
76
|
+
|
|
77
|
+
```javascript
|
|
78
|
+
// Nuxt v3
|
|
79
|
+
export default defineNuxtConfig({
|
|
80
|
+
css: ['@justeattakeaway/pie-css'],
|
|
81
|
+
…
|
|
82
|
+
});
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
```javascript
|
|
86
|
+
export default {
|
|
87
|
+
css: [
|
|
88
|
+
'@justeattakeaway/pie-css',
|
|
89
|
+
],
|
|
90
|
+
…
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### SCSS
|
|
95
|
+
If you are using Sass, you could import the CSS file as part of your styles directly.
|
|
96
|
+
|
|
97
|
+
```css
|
|
98
|
+
@use 'node_modules/@justeattakeaway/pie-css/dist/index.css';
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### CDN
|
|
102
|
+
We also provide a CDN version of the CSS file, which you can include in your HTML file. However we would suggest avoiding this approach and favour package installation instead. If you do want to use the CDN, you must ensure you keep the version in the link up to date.
|
|
103
|
+
|
|
104
|
+
```html
|
|
105
|
+
<link rel="stylesheet" href="https://pie-design-system-cdn.production.jet-external.com/pie-css/v0.16.0/index.css">
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### TypeScript usage
|
|
109
|
+
If you are using TypeScript, you may need to add a declaration file to your project to avoid TypeScript errors when importing the CSS file. How you do this will depend on your project setup, but one way could be to create a types file (e.g. `src/types/pie-css.d.ts`) with the following content:
|
|
110
|
+
|
|
111
|
+
```ts
|
|
112
|
+
declare module '*.css';
|
|
113
|
+
declare module '@justeattakeaway/pie-css';
|
|
114
|
+
```
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
For more information on what styles are included in the CSS package, please refer to the [package readme](https://www.npmjs.com/package/@justeattakeaway/pie-css).
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# CSS variables
|
|
2
|
+
|
|
3
|
+
In order to enable a degree of visual customisation, PIE web components expose a set of CSS variables.
|
|
4
|
+
|
|
5
|
+
The main purpose of using CSS variables is to provide a straightforward mechanism for consumers to style and adapt PIE web components to their specific needs.
|
|
6
|
+
|
|
7
|
+
It provides an abstraction layer that allows users to customise the appearance of components. Instead of requiring to resort to complex CSS selectors to override styles in the Shadow DOM, these variables can be used to control components visual aspects.
|
|
8
|
+
|
|
9
|
+
## Usage benefits
|
|
10
|
+
|
|
11
|
+
- **Easy customisation**: Consumers can easily modify the appearance of the components by simply redefining the CSS variables that were exposed. CSS variables offer a well-defined public API for styling, allowing controlled access to visual aspects of the component without risking breaking the internal structure.
|
|
12
|
+
|
|
13
|
+
- **Readability and maintainability**: Descriptive variable names such as `--toast-provider-z-index` are easy to understand and maintain.
|
|
14
|
+
|
|
15
|
+
- **Dynamic styling with JavaScript**: CSS variables can be easily manipulated via JavaScript. This creates possibilities for updating values depending on the application state or other specific conditions.
|
|
16
|
+
|
|
17
|
+
## Examples
|
|
18
|
+
|
|
19
|
+
CSS variables provided by the component can be overridden using standard CSS techniques.
|
|
20
|
+
|
|
21
|
+
Inline style:
|
|
22
|
+
|
|
23
|
+
```html
|
|
24
|
+
<pie-toast-provider style="--toast-provider-z-index: 7000;"></pie-toast-provider>
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
CSS selector:
|
|
28
|
+
|
|
29
|
+
```html
|
|
30
|
+
<pie-toast-provider class="toast-override"></pie-toast-provider>
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
```css
|
|
34
|
+
.toast-override {
|
|
35
|
+
--toast-provider-z-index: 7000;
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## How to start using CSS variables
|
|
40
|
+
|
|
41
|
+
In the first place, it is necessary to verify if the component exposes any CSS variables. If that is the case, the component documentation will provide a section with a list of available CSS variables.
|
|
42
|
+
|
|
43
|
+
Alternatively, the "Styles" tab in Dev Tools can show the component CSS variables that are available. These should be listed under the `:host` selector.
|
|
44
|
+
|
|
45
|
+
```css
|
|
46
|
+
:host {
|
|
47
|
+
--toast-provider-z-index: var(--dt-z-index-toast);
|
|
48
|
+
}
|
|
49
|
+
```
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# Customising components
|
|
2
|
+
Sometimes there is a need to customise a component's styling more than can be achieved with props or CSS variable overrides. Whilst these situations are uncommon, we recognise that components have to be flexible enough to allow people to do this.
|
|
3
|
+
|
|
4
|
+
> If a component provides CSS parts to override, you will find them in the component readme file or overview page in Storybook.
|
|
5
|
+
|
|
6
|
+
**Warning!** Customising components is not a recommended pattern. It should be used sparingly, and is always worth discussing with the Design System team first. When you customise the component styles, **you must take responsibility for ensuring future updates to the component do not regress your customised styles**.
|
|
7
|
+
|
|
8
|
+
## Table of Contents
|
|
9
|
+
- [CSS Parts](#css-parts)
|
|
10
|
+
- [Writing custom styles](#writing-custom-styles)
|
|
11
|
+
- [Example of risky CSS](#example-of-risky-css)
|
|
12
|
+
- [The problem](#the-problem)
|
|
13
|
+
- [The solution: all: initial](#the-solution-all-initial)
|
|
14
|
+
- [Warning](#warning)
|
|
15
|
+
|
|
16
|
+
## CSS Parts
|
|
17
|
+
CSS Parts are a way to expose areas of a component's template for consumers to apply their own CSS to.
|
|
18
|
+
|
|
19
|
+
An example of this is our Tag component. As you can see, we can fully customise how the component looks by writing our own CSS to be used in the `::part(body)` and `::part(icon)`.
|
|
20
|
+
|
|
21
|
+
Not all components provide parts. If you feel your use-case requires them, please reach out to the team to discuss.
|
|
22
|
+
|
|
23
|
+
## Writing custom styles
|
|
24
|
+
One risk with writing your own styles is that, if you are not careful, you might write some CSS that the base component styles could override in future updates.
|
|
25
|
+
|
|
26
|
+
### Example of risky CSS
|
|
27
|
+
Let's imagine our component `<example-component>` has the following structure:
|
|
28
|
+
|
|
29
|
+
```html
|
|
30
|
+
<div class="c-exampleComponent">
|
|
31
|
+
<span part="primary" class="c-exampleComponent__box c-exampleComponent__box--primary">
|
|
32
|
+
<slot name="primary"></slot>
|
|
33
|
+
</span>
|
|
34
|
+
<span part="secondary" class="c-exampleComponent__box c-exampleComponent__box--secondary">
|
|
35
|
+
<slot name="secondary"></slot>
|
|
36
|
+
</span>
|
|
37
|
+
</div>
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
And this is our CSS:
|
|
41
|
+
|
|
42
|
+
```css
|
|
43
|
+
.c-exampleComponent {
|
|
44
|
+
background-color: lightgreen;
|
|
45
|
+
padding: 1.5rem;
|
|
46
|
+
/* Other styles skipped */
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.c-exampleComponent__box {
|
|
50
|
+
padding: 1rem;
|
|
51
|
+
border-radius: 4px;
|
|
52
|
+
font-family: sans-serif;
|
|
53
|
+
/* Other styles skipped */
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.c-exampleComponent__box--primary {
|
|
57
|
+
background-color: coral;
|
|
58
|
+
/* Other styles skipped */
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.c-exampleComponent__box--secondary {
|
|
62
|
+
background-color: lightblue;
|
|
63
|
+
/* Other styles skipped */
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
We are happy with the default padding around the primary box. It matches our design requirements. However, we need more padding on the secondary box. So we use the exposed CSS part to modify it:
|
|
68
|
+
|
|
69
|
+
```css
|
|
70
|
+
example-component::part(secondary) {
|
|
71
|
+
padding: 2rem;
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Now our secondary box has larger padding. Excellent!
|
|
76
|
+
|
|
77
|
+
### The problem
|
|
78
|
+
There is a risk with our strategy. Let's imagine that six months later, our team releases a new version of the component library. We've decided to add a border to all boxes.
|
|
79
|
+
|
|
80
|
+
The base CSS for `.c-exampleComponent__box` is now:
|
|
81
|
+
|
|
82
|
+
```css
|
|
83
|
+
.c-exampleComponent__box {
|
|
84
|
+
padding: 1rem;
|
|
85
|
+
border-radius: 4px;
|
|
86
|
+
font-family: sans-serif;
|
|
87
|
+
border: 3px solid rgba(0,0,0,0.5); /* <-- New style! */
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Because our custom CSS for `::part(secondary)` only overrides the padding, it inherits the new border property from the base styles. This was not part of our original design and is an unintended regression.
|
|
92
|
+
|
|
93
|
+
### The solution: `all: initial`
|
|
94
|
+
To protect your custom styles from being affected by future changes to the component's base styles, you should take full control of the part's styling.
|
|
95
|
+
|
|
96
|
+
You can do this by using `all: initial` to reset all of the component's base styles on that part. This creates a clean slate, ensuring that only the CSS you explicitly define is applied.
|
|
97
|
+
|
|
98
|
+
Here is the safe way to write the custom styles for our secondary part:
|
|
99
|
+
|
|
100
|
+
```css
|
|
101
|
+
example-component::part(secondary) {
|
|
102
|
+
/* 1. Reset all base styles from the component */
|
|
103
|
+
all: initial;
|
|
104
|
+
|
|
105
|
+
/* 2. Now, re-apply ALL styles needed for your design */
|
|
106
|
+
background-color: lightblue;
|
|
107
|
+
padding: 2rem;
|
|
108
|
+
border-radius: 4px;
|
|
109
|
+
font-family: sans-serif;
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
By doing this, you are no longer inheriting any styles from `.c-exampleComponent__box`. When the component library is updated with the new border, your custom-styled part will be completely unaffected, looking exactly as you designed it.
|
|
114
|
+
|
|
115
|
+
## Warning
|
|
116
|
+
|
|
117
|
+
Remember that when you use `all: initial`, you lose **all** base styles from the component. You are responsible for re-applying every style needed. This approach is safer for long-term maintenance but requires more upfront work.
|
package/docs/events.md
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# Events
|
|
2
|
+
Some of our web components emit custom events that can be listened to by the application. These events are used to communicate changes in the component's state or to notify the application of user interactions.
|
|
3
|
+
We use events because they are a browser-native way to communicate between components and applications. They allow for a decoupled architecture, where components can emit events without needing to know who is listening to them.
|
|
4
|
+
This makes it easier to build modular and reusable components that can be used in different contexts.
|
|
5
|
+
|
|
6
|
+
> If a component emits its own events, they will be documented in the components documentation - look for the "Events" section in the component's README or Overview page in Storybook.
|
|
7
|
+
|
|
8
|
+
## Table of Contents
|
|
9
|
+
|
|
10
|
+
- [Naming convention](#naming-convention)
|
|
11
|
+
- [Listening to custom events](#listening-to-custom-events)
|
|
12
|
+
- [Vanilla JS](#custom-events-in-vanilla-js)
|
|
13
|
+
- [Vue](#custom-events-in-vue)
|
|
14
|
+
- [React](#custom-events-in-react)
|
|
15
|
+
- [Listening to native events](#listening-to-native-events)
|
|
16
|
+
- [Vanilla JS](#native-events-in-vanilla-js)
|
|
17
|
+
- [Vue](#native-events-in-vue)
|
|
18
|
+
- [React](#native-events-in-react)
|
|
19
|
+
|
|
20
|
+
## Naming convention
|
|
21
|
+
The events dispatched by PIE web components are named using `pie-<component-name>-<event-name>`. For example, `pie-modal-leading-action-click` is dispatched when the leading action button in a modal is clicked.
|
|
22
|
+
We follow this naming convention to ensure that events are unique and easily identifiable.
|
|
23
|
+
|
|
24
|
+
> Sometimes components can simply emit native events, such as `input` or `change`. In these cases, there is no need to create a custom event. The native event will bubble up from the component and can be listened to like any other event.
|
|
25
|
+
|
|
26
|
+
## Listening to custom events
|
|
27
|
+
Listening to custom events is similar to listening to native events and can be achieved in a number of ways depending on the application framework you are using. Below are some examples of how to listen to events in different frameworks.
|
|
28
|
+
|
|
29
|
+
### Custom events in Vanilla JS
|
|
30
|
+
```js
|
|
31
|
+
const modal = document.querySelector('pie-modal');
|
|
32
|
+
modal.addEventListener('pie-modal-leading-action-click', (e) => {
|
|
33
|
+
console.log('Leading action clicked!', e);
|
|
34
|
+
});
|
|
35
|
+
```
|
|
36
|
+
### Custom events in Vue
|
|
37
|
+
```html
|
|
38
|
+
<template>
|
|
39
|
+
<pie-modal @pie-modal-leading-action-click="handleClick"></pie-modal>
|
|
40
|
+
</template>
|
|
41
|
+
<script>
|
|
42
|
+
export default {
|
|
43
|
+
methods: {
|
|
44
|
+
handleClick(event) {
|
|
45
|
+
console.log('Leading action clicked!', event);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
</script>
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Custom events in React
|
|
53
|
+
|
|
54
|
+
React is a little different to other frameworks, because a common pattern is to pass callback functions as props rather than using event listeners.
|
|
55
|
+
To enable this, we provide a React-specific wrapper for each component that allows engineers to pass callback functions as props.
|
|
56
|
+
The naming convention for these props is `on<EventName>` (camel case). For example, `onPieModalLeadingActionClick` is the prop that can be used to listen to the `pie-modal-leading-action-click` event.
|
|
57
|
+
|
|
58
|
+
> It is vital that you import the component from the `react` entrypoint.
|
|
59
|
+
|
|
60
|
+
```jsx
|
|
61
|
+
// Please note the import path for React components
|
|
62
|
+
import { PieModal } from '@justeattakeaway/pie-webc/react/modal.js';
|
|
63
|
+
|
|
64
|
+
function App() {
|
|
65
|
+
const handleClick = (event) => {
|
|
66
|
+
console.log('Leading action clicked!', event);
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
return (
|
|
70
|
+
<PieModal onPieModalLeadingActionClick={handleClick}></PieModal>
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
## Listening to native events
|
|
75
|
+
You can still attach event listeners to native events that are emitted by the component. These events are not prefixed with `pie-` and can be listened to like any other native event on an HTML element.
|
|
76
|
+
|
|
77
|
+
### Native events in Vanilla JS
|
|
78
|
+
|
|
79
|
+
```js
|
|
80
|
+
const divider = document.querySelector('pie-divider');
|
|
81
|
+
divider.addEventListener('click', (e) => {
|
|
82
|
+
console.log('Divider clicked!', e);
|
|
83
|
+
});
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Native events in Vue
|
|
87
|
+
|
|
88
|
+
```html
|
|
89
|
+
<template>
|
|
90
|
+
<pie-divider @click="handleClick"></pie-divider>
|
|
91
|
+
</template>
|
|
92
|
+
<script>
|
|
93
|
+
export default {
|
|
94
|
+
methods: {
|
|
95
|
+
handleClick(event) {
|
|
96
|
+
console.log('Divider clicked!', event);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
</script>
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Native events in React
|
|
104
|
+
```jsx
|
|
105
|
+
// Please note the import path for React components
|
|
106
|
+
import { PieDivider } from '@justeattakeaway/pie-webc/react/divider.js';
|
|
107
|
+
function App() {
|
|
108
|
+
const handleClick = (event) => {
|
|
109
|
+
console.log('Divider clicked!', event);
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
return (
|
|
113
|
+
<PieDivider onClick={handleClick}></PieDivider>
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
```
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# Next.js 14
|
|
2
|
+
|
|
3
|
+
This guide will show you how to set up the PIE Web Components in a Next.js 14 applications.
|
|
4
|
+
|
|
5
|
+
> This guide assumes you have first followed the [Getting started](https://webc.pie.design/?path=/docs/introduction-getting-started--docs), [Typography](https://webc.pie.design/?path=/docs/introduction-typography--docs) and [CSS setup](https://webc.pie.design/?path=/docs/introduction-css-setup--docs) guides.
|
|
6
|
+
> Please make sure to follow them before continuing with this guide.
|
|
7
|
+
|
|
8
|
+
## Table of Contents
|
|
9
|
+
|
|
10
|
+
- [Dependencies](#dependencies)
|
|
11
|
+
- [Next.js config](#nextjs-config)
|
|
12
|
+
- [Usage](#usage)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
## Dependencies
|
|
16
|
+
The first step is to install some React and Next.js specific dependencies:
|
|
17
|
+
|
|
18
|
+
**Using Yarn:**
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
yarn add @lit-labs/nextjs @lit/react
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
**Using NPM:**
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
npm install @lit-labs/nextjs @lit/react
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Next.js config
|
|
31
|
+
|
|
32
|
+
We need to update our `next.config.js` file to enable server-side rendering (SSR).
|
|
33
|
+
|
|
34
|
+
Example minimal config file:
|
|
35
|
+
|
|
36
|
+
```js
|
|
37
|
+
// Example - ./next.config.js
|
|
38
|
+
const withLitSSR = require('@lit-labs/nextjs')();
|
|
39
|
+
|
|
40
|
+
/** @type {import('next').NextConfig} */
|
|
41
|
+
const nextConfig = {
|
|
42
|
+
reactStrictMode: true,
|
|
43
|
+
swcMinify: true,
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
module.exports = withLitSSR(nextConfig);
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Usage
|
|
50
|
+
|
|
51
|
+
> If you are using the app router structure, please ensure you add `use client` to the top of the files that directly import the PIE components. This does **not** prevent SSR, it just means that PIE components cannot be used directly in React server-components. These client components can then be imported into RSCs.
|
|
52
|
+
|
|
53
|
+
For React-based applications, there is a `/react/` entry point in both `@justeattakeaway/pie-webc` and `@justeattakeaway/pie-icons-webc` as shown in the example code below:
|
|
54
|
+
|
|
55
|
+
```jsx
|
|
56
|
+
"use client"
|
|
57
|
+
|
|
58
|
+
import { PieButton } from "@justeattakeaway/pie-webc/react/button.js";
|
|
59
|
+
import { PieLink } from "@justeattakeaway/pie-webc/react/link.js";
|
|
60
|
+
import { IconCamera } from "@justeattakeaway/pie-icons-webc/dist/react/IconCamera";
|
|
61
|
+
|
|
62
|
+
export default function SomeComponent() {
|
|
63
|
+
return (
|
|
64
|
+
<div>
|
|
65
|
+
<PieButton size="small-productive" iconPlacement="leading">
|
|
66
|
+
<IconCamera slot="icon"></IconCamera>
|
|
67
|
+
Camera Button
|
|
68
|
+
</PieButton>
|
|
69
|
+
</div>
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
You should now be able to use any components you need in your Next.js application!
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# No framework
|
|
2
|
+
|
|
3
|
+
This guide will show you how to set up the PIE Web Components in a web application without any specific framework.
|
|
4
|
+
|
|
5
|
+
> This guide assumes you have first followed the [Getting started](https://webc.pie.design/?path=/docs/introduction-getting-started--docs), [Typography](https://webc.pie.design/?path=/docs/introduction-typography--docs) and [CSS setup](https://webc.pie.design/?path=/docs/introduction-css-setup--docs) guides.
|
|
6
|
+
> Please make sure to follow them before continuing with this guide.
|
|
7
|
+
|
|
8
|
+
## Table of Contents
|
|
9
|
+
|
|
10
|
+
- [Dependencies](#dependencies)
|
|
11
|
+
- [Usage](#usage)
|
|
12
|
+
|
|
13
|
+
## Dependencies
|
|
14
|
+
Please refer to the [Getting started](https://webc.pie.design/?path=/docs/introduction-getting-started--docs) guide for the dependencies required to use PIE Web Components in your application.
|
|
15
|
+
|
|
16
|
+
## Usage
|
|
17
|
+
Please ensure that you import the components **without any destructuring**. Simply import the package.
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
import '@justeattakeaway/pie-webc/components/button.js';
|
|
21
|
+
import '@justeattakeaway/pie-webc/components/icon-button.js';
|
|
22
|
+
import '@justeattakeaway/pie-icons-webc/dist/IconClose.js';
|
|
23
|
+
import '@justeattakeaway/pie-css';
|
|
24
|
+
|
|
25
|
+
document.querySelector<HTMLDivElement>('#app')!.innerHTML = `
|
|
26
|
+
<div class="card">
|
|
27
|
+
<pie-button id="counter" type="button">count is 0</pie-button>
|
|
28
|
+
<pie-icon-button>
|
|
29
|
+
<icon-close></icon-close>
|
|
30
|
+
</pie-icon-button>
|
|
31
|
+
</div>
|
|
32
|
+
`;
|
|
33
|
+
|
|
34
|
+
function setupCounter(button: HTMLElement) {
|
|
35
|
+
let counter = 0;
|
|
36
|
+
const updateText = () => {
|
|
37
|
+
button.textContent = `count is ${counter}`;
|
|
38
|
+
};
|
|
39
|
+
button.addEventListener('click', () => {
|
|
40
|
+
counter++;
|
|
41
|
+
updateText();
|
|
42
|
+
});
|
|
43
|
+
updateText();
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
setupCounter(document.querySelector<HTMLElement>('#counter')!);
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
You should now be able to use any components you need in your application!
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# Nuxt 3
|
|
2
|
+
|
|
3
|
+
This guide will show you how to set up the PIE Web Components in a Nuxt 3 application.
|
|
4
|
+
|
|
5
|
+
> This guide assumes you have first followed the [Getting started](https://webc.pie.design/?path=/docs/introduction-getting-started--docs), [Typography](https://webc.pie.design/?path=/docs/introduction-typography--docs) and [CSS setup](https://webc.pie.design/?path=/docs/introduction-css-setup--docs) guides.
|
|
6
|
+
> Please make sure to follow them before continuing with this guide.
|
|
7
|
+
|
|
8
|
+
## Table of Contents
|
|
9
|
+
|
|
10
|
+
- [Dependencies](#dependencies)
|
|
11
|
+
- [Nuxt config](#nuxt-config)
|
|
12
|
+
- [Usage](#usage)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
## Dependencies
|
|
16
|
+
The first step is to install some React and Next.js specific dependencies:
|
|
17
|
+
|
|
18
|
+
**Using Yarn:**
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
yarn add nuxt-ssr-lit
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
**Using NPM:**
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
npm install nuxt-ssr-lit
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Nuxt config
|
|
31
|
+
|
|
32
|
+
To get our components working, ensure you are applying the following rules to your `nuxt.config.ts` file:
|
|
33
|
+
|
|
34
|
+
```js
|
|
35
|
+
export default defineNuxtConfig({
|
|
36
|
+
ssr: true,
|
|
37
|
+
|
|
38
|
+
nitro: {
|
|
39
|
+
moduleSideEffects: [
|
|
40
|
+
'@justeattakeaway/pie-icons-webc',
|
|
41
|
+
'@justeattakeaway/pie-webc',
|
|
42
|
+
],
|
|
43
|
+
},
|
|
44
|
+
|
|
45
|
+
modules: [['nuxt-ssr-lit', { litElementPrefix: ['pie-', 'icon-'] }]],
|
|
46
|
+
|
|
47
|
+
imports: {
|
|
48
|
+
transform: {
|
|
49
|
+
exclude: [/\bpie-\b/, /\bicon-\b/],
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
|
|
53
|
+
css: ['@justeattakeaway/pie-css'],
|
|
54
|
+
devtools: { enabled: true },
|
|
55
|
+
|
|
56
|
+
devServer: {
|
|
57
|
+
port: 3002,
|
|
58
|
+
},
|
|
59
|
+
|
|
60
|
+
compatibilityDate: '2024-07-23',
|
|
61
|
+
});
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Nuxt Configuration Breakdown
|
|
65
|
+
|
|
66
|
+
#### 1. **Server-Side Rendering**
|
|
67
|
+
- **`ssr: true`**
|
|
68
|
+
Enables **Server-Side Rendering (SSR)** for improved SEO and faster initial page loads by rendering pages on the server.
|
|
69
|
+
|
|
70
|
+
#### 2. **Nitro Configuration**
|
|
71
|
+
- **`moduleSideEffects`**
|
|
72
|
+
Includes the following modules during the build to ensure side effects like custom element registration:
|
|
73
|
+
- `@justeattakeaway/pie-icons-webc`
|
|
74
|
+
- `@justeattakeaway/pie-webc`
|
|
75
|
+
|
|
76
|
+
#### 3. **Modules**
|
|
77
|
+
- Adds the **`nuxt-ssr-lit`** module to enable SSR compatibility for Lit web components.
|
|
78
|
+
- **`litElementPrefix`** specifies the prefixes for custom elements to be treated as Lit elements:
|
|
79
|
+
- `pie-`
|
|
80
|
+
- `icon-`
|
|
81
|
+
|
|
82
|
+
#### 4. **Imports**
|
|
83
|
+
- **`imports.transform.exclude`**
|
|
84
|
+
Prevents Nuxt from automatically transforming imports matching these patterns:
|
|
85
|
+
- `pie-`
|
|
86
|
+
- `icon-`
|
|
87
|
+
|
|
88
|
+
#### 5. **Global CSS**
|
|
89
|
+
- Includes global styles from the `@justeattakeaway/pie-css` package for styling custom components.
|
|
90
|
+
|
|
91
|
+
#### 6. **Compatibility Date**
|
|
92
|
+
- **`compatibilityDate: '2024-07-23'`**
|
|
93
|
+
Ensures behaviour aligns with Nuxt's functionality as of the specified date, preventing breaking changes introduced after this date.
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
## Usage
|
|
97
|
+
|
|
98
|
+
It is recommended to import all components from [@justeattakeaway/pie-webc](https://www.npmjs.com/package/@justeattakeaway/pie-webc).
|
|
99
|
+
|
|
100
|
+
In your components, you should be able to render components like so:
|
|
101
|
+
|
|
102
|
+
```html
|
|
103
|
+
<script setup>
|
|
104
|
+
// No need to destructure any imports - just directly import the js file
|
|
105
|
+
import '@justeattakeaway/pie-webc/components/button.js';
|
|
106
|
+
import '@justeattakeaway/pie-icons-webc/dist/IconCamera.js';
|
|
107
|
+
</script>
|
|
108
|
+
|
|
109
|
+
<template>
|
|
110
|
+
<div>
|
|
111
|
+
<pie-button size="small-productive" iconPlacement="leading">
|
|
112
|
+
<icon-camera slot="icon"></icon-camera>
|
|
113
|
+
hello, world
|
|
114
|
+
</pie-button>
|
|
115
|
+
</div>
|
|
116
|
+
</template>
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
You should now be able to use any components you need in your Nuxt application!
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# React 19
|
|
2
|
+
|
|
3
|
+
This guide will show you how to set up the PIE Web Components in a React 19 application.
|
|
4
|
+
|
|
5
|
+
> This guide assumes you have first followed the [Getting started](https://webc.pie.design/?path=/docs/introduction-getting-started--docs), [Typography](https://webc.pie.design/?path=/docs/introduction-typography--docs) and [CSS setup](https://webc.pie.design/?path=/docs/introduction-css-setup--docs) guides.
|
|
6
|
+
> Please make sure to follow them before continuing with this guide.
|
|
7
|
+
|
|
8
|
+
## Table of Contents
|
|
9
|
+
|
|
10
|
+
- [Dependencies](#dependencies)
|
|
11
|
+
- [Usage](#usage)
|
|
12
|
+
|
|
13
|
+
## Dependencies
|
|
14
|
+
The first step is to install the React specific dependency:
|
|
15
|
+
|
|
16
|
+
**Using Yarn:**
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
yarn add @lit/react
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
**Using NPM:**
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm install @lit/react
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Usage
|
|
29
|
+
|
|
30
|
+
For React-based applications, there is a `/react/` entry point in both `@justeattakeaway/pie-webc` and `@justeattakeaway/pie-icons-webc` as shown in the example code below:
|
|
31
|
+
|
|
32
|
+
```tsx
|
|
33
|
+
import { useState } from 'react';
|
|
34
|
+
import { PieButton } from '@justeattakeaway/pie-webc/react/button.js';
|
|
35
|
+
import { PieIconButton } from '@justeattakeaway/pie-webc/react/icon-button.js';
|
|
36
|
+
import { IconClose } from '@justeattakeaway/pie-icons-webc/dist/react/IconClose.js';
|
|
37
|
+
|
|
38
|
+
import './App.css';
|
|
39
|
+
import '@justeattakeaway/pie-css';
|
|
40
|
+
|
|
41
|
+
function App() {
|
|
42
|
+
const [count, setCount] = useState(0);
|
|
43
|
+
|
|
44
|
+
return (
|
|
45
|
+
<>
|
|
46
|
+
<div className="card">
|
|
47
|
+
<PieButton onClick={() => setCount((count) => count + 1)}>
|
|
48
|
+
count is {count}
|
|
49
|
+
</PieButton>
|
|
50
|
+
|
|
51
|
+
<PieIconButton>
|
|
52
|
+
<IconClose></IconClose>
|
|
53
|
+
</PieIconButton>
|
|
54
|
+
</div>
|
|
55
|
+
</>
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export default App;
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
You should now be able to use any components you need in your React application!
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Vue 3
|
|
2
|
+
|
|
3
|
+
This guide will show you how to set up the PIE Web Components in a Vue 3 application.
|
|
4
|
+
|
|
5
|
+
> This guide assumes you have first followed the [Getting started](https://webc.pie.design/?path=/docs/introduction-getting-started--docs), [Typography](https://webc.pie.design/?path=/docs/introduction-typography--docs) and [CSS setup](https://webc.pie.design/?path=/docs/introduction-css-setup--docs) guides.
|
|
6
|
+
> Please make sure to follow them before continuing with this guide.
|
|
7
|
+
|
|
8
|
+
## Table of Contents
|
|
9
|
+
|
|
10
|
+
- [Dependencies](#dependencies)
|
|
11
|
+
- [Usage](#usage)
|
|
12
|
+
|
|
13
|
+
## Dependencies
|
|
14
|
+
There are no vue-specific dependencies required. Please refer to the [Getting started](https://webc.pie.design/?path=/docs/introduction-getting-started--docs) guide for the dependencies required to use PIE Web Components in your application.
|
|
15
|
+
|
|
16
|
+
## Usage
|
|
17
|
+
Please ensure that you import the components **without any destructuring**. Simply import the package.
|
|
18
|
+
|
|
19
|
+
```html
|
|
20
|
+
<script setup lang="ts">
|
|
21
|
+
import { ref } from 'vue';
|
|
22
|
+
import '@justeattakeaway/pie-webc/components/button.js';
|
|
23
|
+
import '@justeattakeaway/pie-webc/components/icon-button.js';
|
|
24
|
+
import '@justeattakeaway/pie-icons-webc/dist/IconClose.js';
|
|
25
|
+
|
|
26
|
+
import '@justeattakeaway/pie-css';
|
|
27
|
+
</script>
|
|
28
|
+
|
|
29
|
+
<template>
|
|
30
|
+
<div class="card">
|
|
31
|
+
<pie-button @click="count++"> count is {{ count }} </pie-button>
|
|
32
|
+
|
|
33
|
+
<pie-icon-button>
|
|
34
|
+
<icon-close></icon-close>
|
|
35
|
+
</pie-icon-button>
|
|
36
|
+
</div>
|
|
37
|
+
</template>
|
|
38
|
+
|
|
39
|
+
<script lang="ts">
|
|
40
|
+
const count = ref(0);
|
|
41
|
+
</script>
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
You should now be able to use any components you need in your Vue application!
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# PIE Web Components
|
|
2
|
+
[Source code](https://github.com/justeattakeaway/pie) | [Design Documentation](https://pie.design/)
|
|
3
|
+
|
|
4
|
+
PIE Web Components is the web variant of the Just Eat Takeaway.com (JET) Design System, PIE. It is built using native web components to provide a consistent, accessible, and reusable set of components for building UIs across different products and applications.
|
|
5
|
+
|
|
6
|
+
## `@justeattakeaway/pie-webc`
|
|
7
|
+
|
|
8
|
+
`@justeattakeaway/pie-webc` is the web implementation of [JET's PIE Design system](https://pie.design/), built using [Web Components](https://developer.mozilla.org/en-US/docs/Web/API/Web_components). Using Web Components allows us to build our components once and use them across all of our web UIs, regardless of the framework they have been built with. Our source code is open source, and can be found on [Github](https://github.com/justeattakeaway/pie).
|
|
9
|
+
|
|
10
|
+
### Getting Started
|
|
11
|
+
|
|
12
|
+
Setting up our web components differs slightly depending on your framework. However, regardless of your tech stack, the **first step** is to install our core packages:
|
|
13
|
+
|
|
14
|
+
- The core component library: [@justeattakeaway/pie-webc](https://www.npmjs.com/package/@justeattakeaway/pie-webc)
|
|
15
|
+
- Base styles used by the components: [@justeattakeaway/pie-css](https://www.npmjs.com/package/@justeattakeaway/pie-css)
|
|
16
|
+
- Icons used by some of the components: [@justeattakeaway/pie-icons-webc](https://www.npmjs.com/package/@justeattakeaway/pie-icons-webc)
|
|
17
|
+
|
|
18
|
+
> 💡 While components are also available as individual packages, we recommend using `@justeattakeaway/pie-webc` as the **single entry point**. This approach is the easiest way to get started with and ensures you stay up to date.
|
|
19
|
+
|
|
20
|
+
**Using Yarn:**
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
yarn add @justeattakeaway/pie-webc @justeattakeaway/pie-css @justeattakeaway/pie-icons-webc
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
**Using NPM:**
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npm install @justeattakeaway/pie-webc @justeattakeaway/pie-css @justeattakeaway/pie-icons-webc
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
From here, you will need to set up Typography and base CSS styles. Please read the [Typography](https://webc.pie.design/?path=/docs/introduction-typography--docs) and [CSS setup](https://webc.pie.design/?path=/docs/introduction-css-setup--docs) pages for more information.
|
|
33
|
+
|
|
34
|
+
### What components can I use?
|
|
35
|
+
|
|
36
|
+
We keep an up to date list of component statuses on the PIE Storybook. Anything in `Beta` or `Stable` is ready to use in your project!
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# TypeScript usage
|
|
2
|
+
Using TypeScript with our components is straightforward. Each component package exports its types, which can be imported and used in your application where needed.
|
|
3
|
+
Below are examples of how to use the types in different frameworks and are all fairly similar.
|
|
4
|
+
|
|
5
|
+
Our published components contain `index.d.ts` and `react.d.ts` files that contain the types for the component and its props. These files are automatically generated during the build process and are used by the TypeScript compiler to provide type checking and intellisense in your IDE. You should not need to import or interact with these files. They can be viewed in the `dist` directory of the component packages.
|
|
6
|
+
|
|
7
|
+
> Note that the examples below are using the `PieSelect` component, but the same principles apply to all components in the PIE web components library.
|
|
8
|
+
> Also please bear in mind that these are minimal examples to demonstrate how to use the types, and you will likely need to adapt them to your specific use case. Simply reusing the example code in your application is unlikely to work as-is.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
### React
|
|
13
|
+
Import any types you want to use from the component file. Please note the **react** entry point in the path.
|
|
14
|
+
It is important to specify the `type` keyword when importing types as this will ensure the TypeScript compiler will not try to compile the types into JavaScript code.
|
|
15
|
+
|
|
16
|
+
```tsx
|
|
17
|
+
import { PieSelect, type SelectProps } from "@justeattakeaway/pie-webc/react/select.js";
|
|
18
|
+
|
|
19
|
+
export default function Select() {
|
|
20
|
+
const options: SelectProps['options'] = [
|
|
21
|
+
{
|
|
22
|
+
tag: 'optgroup',
|
|
23
|
+
label: 'Animals',
|
|
24
|
+
options: [
|
|
25
|
+
{
|
|
26
|
+
tag: 'option',
|
|
27
|
+
text: 'Cat',
|
|
28
|
+
value: 'cat',
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
tag: 'option',
|
|
32
|
+
text: 'Dog',
|
|
33
|
+
value: 'dog',
|
|
34
|
+
},
|
|
35
|
+
],
|
|
36
|
+
},
|
|
37
|
+
];
|
|
38
|
+
|
|
39
|
+
return (
|
|
40
|
+
<PieSelect options={options} />
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Vue
|
|
46
|
+
|
|
47
|
+
```html
|
|
48
|
+
<template>
|
|
49
|
+
<pie-select :options="options"></pie-select>
|
|
50
|
+
</template>
|
|
51
|
+
|
|
52
|
+
<script setup lang="ts">
|
|
53
|
+
import '@justeattakeaway/pie-webc/components/select.js';
|
|
54
|
+
import type { SelectProps } from '@justeattakeaway/pie-webc/components/select.js';
|
|
55
|
+
|
|
56
|
+
const options: SelectProps['options'] = [
|
|
57
|
+
{
|
|
58
|
+
tag: 'optgroup',
|
|
59
|
+
label: 'Animal',
|
|
60
|
+
options: [
|
|
61
|
+
{
|
|
62
|
+
tag: 'option',
|
|
63
|
+
text: 'Cat',
|
|
64
|
+
value: 'cat',
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
tag: 'option',
|
|
68
|
+
text: 'Dog',
|
|
69
|
+
value: 'dog',
|
|
70
|
+
},
|
|
71
|
+
],
|
|
72
|
+
},
|
|
73
|
+
];
|
|
74
|
+
</script>
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Plain TypeScript
|
|
78
|
+
|
|
79
|
+
```html
|
|
80
|
+
<pie-select id="mySelect"></pie-select>
|
|
81
|
+
|
|
82
|
+
<script type="module" src="./main.ts"></script>
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
```ts
|
|
86
|
+
// main.ts
|
|
87
|
+
import '@justeattakeaway/pie-webc/components/select.js';
|
|
88
|
+
import type { SelectProps, PieSelect } from '@justeattakeaway/pie-webc/components/select.js';
|
|
89
|
+
|
|
90
|
+
const options: SelectProps['options'] = [
|
|
91
|
+
{
|
|
92
|
+
tag: 'optgroup',
|
|
93
|
+
label: 'Animal',
|
|
94
|
+
options: [
|
|
95
|
+
{
|
|
96
|
+
tag: 'option',
|
|
97
|
+
text: 'Cat',
|
|
98
|
+
value: 'cat',
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
tag: 'option',
|
|
102
|
+
text: 'Dog',
|
|
103
|
+
value: 'dog',
|
|
104
|
+
},
|
|
105
|
+
],
|
|
106
|
+
},
|
|
107
|
+
];
|
|
108
|
+
|
|
109
|
+
// Using type casting here just to specify the element cannot be null. This is not always a good practice.
|
|
110
|
+
const pieSelect = document.querySelector('pie-select') as PieSelect;
|
|
111
|
+
|
|
112
|
+
pieSelect.options = options;
|
|
113
|
+
```
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# Typography
|
|
2
|
+
In order for our components to look and feel like the rest of the Just Eat Takeaway.com family, we need to ensure that we are using the correct typography and styles. This document will cover how to set up typography in your application.
|
|
3
|
+
|
|
4
|
+
## Table of Contents
|
|
5
|
+
|
|
6
|
+
- [The JETSansDigital Variable Font](#the-jetsansdigital-variable-font)
|
|
7
|
+
- [Font Loading](#font-loading)
|
|
8
|
+
- [Italic Font Usage](#italic-font-usage)
|
|
9
|
+
- [Font Optimisation (subsetting)](#font-optimisation-subsetting)
|
|
10
|
+
|
|
11
|
+
## The JETSansDigital Variable Font
|
|
12
|
+
|
|
13
|
+
`JETSansDigital` is a variable font (VF) containing all font weights and styles in a single file.
|
|
14
|
+
|
|
15
|
+
The font is available in two versions via our CDN:
|
|
16
|
+
|
|
17
|
+
| Version | URL | Recommended Use |
|
|
18
|
+
| ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
19
|
+
| **Base** | [JETSansDigital-VF-opt.woff2](https://pie-design-system-cdn.production.jet-external.com/fonts/JETSansDigital-VF-opt.woff2) | Default choice. Includes Latin characters and supports common European languages (English, French, Spanish, German, etc.). |
|
|
20
|
+
| **Extended** | [JETSansDigital-VF-optimised-extended.woff2](https://pie-design-system-cdn.production.jet-external.com/fonts/JETSansDigital-VF-optimised-extended.woff2) | Use when your app supports additional languages such as Hebrew, Bulgarian, or other Cyrillic-based languages. This version is larger in file size. |
|
|
21
|
+
|
|
22
|
+
## Font Loading
|
|
23
|
+
|
|
24
|
+
Add the following code into the `<head>` of your application:
|
|
25
|
+
|
|
26
|
+
```html
|
|
27
|
+
<link rel="preload" href="https://pie-design-system-cdn.production.jet-external.com/fonts/JETSansDigital-VF-opt.woff2" as="font" type="font/woff2" crossorigin>
|
|
28
|
+
<style>
|
|
29
|
+
@font-face {
|
|
30
|
+
font-family: JETSansDigital;
|
|
31
|
+
src: url('https://pie-design-system-cdn.production.jet-external.com/fonts/JETSansDigital-VF-opt.woff2') format("woff2");
|
|
32
|
+
font-weight: 100 1000;
|
|
33
|
+
font-stretch: 25% 151%;
|
|
34
|
+
font-style: oblique 0deg 20deg;
|
|
35
|
+
font-display: swap;
|
|
36
|
+
}
|
|
37
|
+
body {
|
|
38
|
+
font-feature-settings: "tnum"; /* Enable tabular numbers */
|
|
39
|
+
}
|
|
40
|
+
</style>
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
- The first link tag will load in the `JETSansDigital` font file. The `rel=preload` attribute tells the browser to download and cache it as soon as possible.
|
|
44
|
+
|
|
45
|
+
- The `@font-face` declaration is then to apply the `JETSansDigital` font as soon as it's available (and as it's inline in the head of the page, it won't wait for the rest of the CSS to be parsed until it renders the font).
|
|
46
|
+
|
|
47
|
+
```shell
|
|
48
|
+
# If your application needs extended language support, replace the font URL with the extended version.
|
|
49
|
+
https://pie-design-system-cdn.production.jet-external.com/fonts/JETSansDigital-VF-optimised-extended.woff2
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Italic Font Usage
|
|
53
|
+
|
|
54
|
+
Safari has a known issue with variable fonts that use the `oblique` angle range syntax in `@font-face` declarations. When applying `font-style: italic`, Safari doesn't properly apply the slant axis and may create a synthetic italic that appears incorrectly rendered or "double bold."
|
|
55
|
+
|
|
56
|
+
To fix this, you must include `font-variation-settings: "slnt" -20` alongside `font-style: italic` when styling it:
|
|
57
|
+
|
|
58
|
+
```css
|
|
59
|
+
.italic-text {
|
|
60
|
+
font-style: italic;
|
|
61
|
+
font-variation-settings: "slnt" -20;
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Font Optimisation (subsetting)
|
|
66
|
+
|
|
67
|
+
The standard fontset comes with a huge number of glyphs and layout features that aren't required for use on the web. Therefore we optimise this fontset using a process called font-subsetting. Subsetting is the process of removing parts of the base fontset, to leave only the glyphs and features that you require.
|
|
68
|
+
|
|
69
|
+
### How to subset a font
|
|
70
|
+
|
|
71
|
+
To subset a base font like the one we use, you will need to use a command line tool called `pyftsubset` which is available as part of the fonttools library. For more information on installing `pyftsubset`, see this blog post which explains how to do that and covers any associated dependencies you'll also need (such as `pip`).
|
|
72
|
+
|
|
73
|
+
Once you have `pyftsubset` installed you can optimise your font!
|
|
74
|
+
|
|
75
|
+
For `JETSansDigital`, we subset `JETSansDigital-VF.ttf` with the following rules:
|
|
76
|
+
|
|
77
|
+
```shell
|
|
78
|
+
# JETSansDigital-VF
|
|
79
|
+
pyftsubset "JETSansDigital-VF.ttf" --output-file="JETSansDigital-VF-opt.woff2" --flavor=woff2 --layout-features=ccmp,locl,mark,mkmk,kern,dnom,numr,frac,tnum --unicodes=U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
and for our extended subset, we use the following extended unicode settings:
|
|
83
|
+
|
|
84
|
+
```shell
|
|
85
|
+
# JETSansDigital-VF-optimised-extended
|
|
86
|
+
pyftsubset "JETSansDigital-VF.ttf" --output-file="JETSansDigital-VF-optimised-extended.woff2" --flavor=woff2 --layout-features=ccmp,locl,mark,mkmk,kern,dnom,numr,frac,tnum --unicodes=U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD,U+0100-017F,U+0400-04FF,U+0401,U+0451,U+0404,U+0454,U+0406,U+0456,U+0407,U+0457,U+040D,U+045D,U+040E,U+045E,U+0490,U+0491,U+0590-05FF
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Breaking the command down
|
|
90
|
+
|
|
91
|
+
So what do the above commands actually do and what does each setting mean?
|
|
92
|
+
|
|
93
|
+
Let's break it down step-by-step:
|
|
94
|
+
|
|
95
|
+
- `pyftsubset "JETSansDigital-VF.ttf" --output-file="JETSansDigital-VF-opt.woff2"`
|
|
96
|
+
|
|
97
|
+
This runs the pyftsubset tool on the `JETSansDigital-VF.ttf` file and outputs the results file as `JETSansDigital-VF-opt.woff2`.
|
|
98
|
+
|
|
99
|
+
- `--flavor=woff2`
|
|
100
|
+
|
|
101
|
+
Optimise the file in `woff2` format (can be set to `woff` to output the file as a woff, as well as needing to change the `--output-file` value).
|
|
102
|
+
|
|
103
|
+
- `--layout-features=ccmp,locl,mark,mkmk,kern,dnom,numr,frac,tnum`
|
|
104
|
+
|
|
105
|
+
Keeps the specified layout features as part of the sub-setted font. For more details on each of these layout features, check out the following resources:
|
|
106
|
+
|
|
107
|
+
- [`ccmp`](https://docs.microsoft.com/en-us/typography/opentype/spec/features_ae#ccmp) – This feature permits composition/decompostion of glyphs.
|
|
108
|
+
- [`locl`](https://www.preusstype.com/techdata/otf_locl.php) – Allow localised variants of specific letters/glyphs.
|
|
109
|
+
- [`mark`](https://docs.microsoft.com/en-us/typography/opentype/spec/features_ko#tag-mark) – Positions mark glyphs with respect to base glyphs.
|
|
110
|
+
- [`mkmk`](https://docs.microsoft.com/en-us/typography/opentype/spec/features_ko#tag-mkmk) – Positions mark glyphs with respect to other marks.
|
|
111
|
+
- [`kern`](https://www.preusstype.com/techdata/otf_kern.php) – Adjusts the amount of space between glyphs, generally to provide optically consistent spacing between glyphs.
|
|
112
|
+
- [`dnom`](https://www.preusstype.com/techdata/otf_dnom.php) – Short for denominators, this replaces selected figures which follow a slash with denominator figures.
|
|
113
|
+
- [`numr`](https://www.preusstype.com/techdata/otf_numr.php) – Short for numerators, this replaces selected figures which precede a slash with numerator figures, and replaces the typographic slash with the fraction slash.
|
|
114
|
+
- [`frac`](https://www.preusstype.com/techdata/otf_frac.php) – Short for fractions, this replaces figures separated by a slash with 'common' (diagonal) fractions.
|
|
115
|
+
- [`tnum`](https://www.fonts.com/content/learning/fontology/level-3/numbers/proportional-vs-tabular-figures) – Short for tabular figures, this deals with number spacing.
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
- `--unicodes=U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD`
|
|
119
|
+
|
|
120
|
+
Specifies which characters to include as part of our optimised set. This character set is the same as those specified by Google font sets – more information on which [can be found in this blog post](https://markoskon.com/creating-font-subsets/#characters).
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@justeattakeaway/pie-webc",
|
|
3
3
|
"description": "Component bundle containing all PIE web components",
|
|
4
|
-
"version": "0.8.
|
|
4
|
+
"version": "0.8.6",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "https://github.com/justeattakeaway/pie",
|
|
@@ -11,7 +11,8 @@
|
|
|
11
11
|
"type": "module",
|
|
12
12
|
"files": [
|
|
13
13
|
"**/*.js",
|
|
14
|
-
"**/*.d.ts"
|
|
14
|
+
"**/*.d.ts",
|
|
15
|
+
"docs/**/*.md"
|
|
15
16
|
],
|
|
16
17
|
"exports": {
|
|
17
18
|
"./components/assistive-text.js": {
|
|
@@ -811,36 +812,36 @@
|
|
|
811
812
|
"chalk": "5.3.0"
|
|
812
813
|
},
|
|
813
814
|
"dependencies": {
|
|
814
|
-
"@justeattakeaway/pie-assistive-text": "0.11.
|
|
815
|
-
"@justeattakeaway/pie-avatar": "0.4.
|
|
816
|
-
"@justeattakeaway/pie-breadcrumb": "0.7.
|
|
817
|
-
"@justeattakeaway/pie-button": "1.12.
|
|
818
|
-
"@justeattakeaway/pie-card": "0.26.
|
|
819
|
-
"@justeattakeaway/pie-checkbox": "1.0.
|
|
820
|
-
"@justeattakeaway/pie-checkbox-group": "1.0.
|
|
821
|
-
"@justeattakeaway/pie-chip": "0.15.
|
|
822
|
-
"@justeattakeaway/pie-cookie-banner": "1.7.
|
|
823
|
-
"@justeattakeaway/pie-data-table": "0.3.
|
|
824
|
-
"@justeattakeaway/pie-divider": "1.5.
|
|
825
|
-
"@justeattakeaway/pie-form-label": "0.18.
|
|
826
|
-
"@justeattakeaway/pie-icon-button": "2.6.
|
|
827
|
-
"@justeattakeaway/pie-link": "1.3.
|
|
828
|
-
"@justeattakeaway/pie-list": "0.0.
|
|
829
|
-
"@justeattakeaway/pie-lottie-player": "0.3.
|
|
830
|
-
"@justeattakeaway/pie-modal": "1.25.
|
|
831
|
-
"@justeattakeaway/pie-notification": "0.21.
|
|
832
|
-
"@justeattakeaway/pie-radio": "1.1.
|
|
833
|
-
"@justeattakeaway/pie-radio-group": "1.0.
|
|
834
|
-
"@justeattakeaway/pie-select": "0.8.
|
|
835
|
-
"@justeattakeaway/pie-spinner": "1.4.
|
|
836
|
-
"@justeattakeaway/pie-switch": "2.3.
|
|
837
|
-
"@justeattakeaway/pie-tabs": "0.1.
|
|
838
|
-
"@justeattakeaway/pie-tag": "0.22.
|
|
839
|
-
"@justeattakeaway/pie-text-input": "0.29.
|
|
840
|
-
"@justeattakeaway/pie-textarea": "0.17.
|
|
841
|
-
"@justeattakeaway/pie-thumbnail": "0.8.
|
|
842
|
-
"@justeattakeaway/pie-toast": "0.12.
|
|
843
|
-
"@justeattakeaway/pie-toast-provider": "0.7.
|
|
815
|
+
"@justeattakeaway/pie-assistive-text": "0.11.16",
|
|
816
|
+
"@justeattakeaway/pie-avatar": "0.4.17",
|
|
817
|
+
"@justeattakeaway/pie-breadcrumb": "0.7.19",
|
|
818
|
+
"@justeattakeaway/pie-button": "1.12.4",
|
|
819
|
+
"@justeattakeaway/pie-card": "0.26.13",
|
|
820
|
+
"@justeattakeaway/pie-checkbox": "1.0.9",
|
|
821
|
+
"@justeattakeaway/pie-checkbox-group": "1.0.9",
|
|
822
|
+
"@justeattakeaway/pie-chip": "0.15.14",
|
|
823
|
+
"@justeattakeaway/pie-cookie-banner": "1.7.10",
|
|
824
|
+
"@justeattakeaway/pie-data-table": "0.3.4",
|
|
825
|
+
"@justeattakeaway/pie-divider": "1.5.11",
|
|
826
|
+
"@justeattakeaway/pie-form-label": "0.18.12",
|
|
827
|
+
"@justeattakeaway/pie-icon-button": "2.6.5",
|
|
828
|
+
"@justeattakeaway/pie-link": "1.3.14",
|
|
829
|
+
"@justeattakeaway/pie-list": "0.0.16",
|
|
830
|
+
"@justeattakeaway/pie-lottie-player": "0.3.6",
|
|
831
|
+
"@justeattakeaway/pie-modal": "1.25.2",
|
|
832
|
+
"@justeattakeaway/pie-notification": "0.21.10",
|
|
833
|
+
"@justeattakeaway/pie-radio": "1.1.1",
|
|
834
|
+
"@justeattakeaway/pie-radio-group": "1.0.9",
|
|
835
|
+
"@justeattakeaway/pie-select": "0.8.17",
|
|
836
|
+
"@justeattakeaway/pie-spinner": "1.4.4",
|
|
837
|
+
"@justeattakeaway/pie-switch": "2.3.16",
|
|
838
|
+
"@justeattakeaway/pie-tabs": "0.1.12",
|
|
839
|
+
"@justeattakeaway/pie-tag": "0.22.8",
|
|
840
|
+
"@justeattakeaway/pie-text-input": "0.29.17",
|
|
841
|
+
"@justeattakeaway/pie-textarea": "0.17.16",
|
|
842
|
+
"@justeattakeaway/pie-thumbnail": "0.8.17",
|
|
843
|
+
"@justeattakeaway/pie-toast": "0.12.25",
|
|
844
|
+
"@justeattakeaway/pie-toast-provider": "0.7.26"
|
|
844
845
|
},
|
|
845
846
|
"volta": {
|
|
846
847
|
"extends": "../../../package.json"
|