@justeattakeaway/pie-css 0.31.2 → 0.32.0
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/dist/components/button.css +552 -0
- package/docs/components/BUTTON.md +260 -0
- package/package.json +2 -2
- package/scss/_internal/components/button.scss +95 -0
- package/scss/_internal/{radio.scss → components/radio.scss} +1 -1
- package/scss/_internal/{typography.scss → helpers/typography.scss} +1 -1
- package/scss/mixins/_interactiveStates.scss +2 -2
- package/scss/mixins/components/_button.scss +434 -0
- package/scss/mixins/components/index.scss +1 -0
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
# PIE CSS Button Component Styles
|
|
2
|
+
|
|
3
|
+
[Source Code](https://github.com/justeattakeaway/pie/tree/main/packages/tools/pie-css) | [NPM Package](https://www.npmjs.com/package/@justeattakeaway/pie-css)
|
|
4
|
+
|
|
5
|
+
Style static HTML elements (such as `<div>`s) with PIE button design system styling. This is intended for non-interactive elements that need to visually resemble a button.
|
|
6
|
+
|
|
7
|
+
> **Important:** This is an extremely niche use case. Almost all consumers should use the [`pie-button`](https://webc.pie.design/?path=/docs/components-button--docs) web component instead, which provides full interactivity, keyboard navigation, form integration and accessibility out of the box. These CSS-only styles exist solely for rare situations where a **static, non-interactive element** needs to _look_ like a button — for example, a `<div>` inside a clickable card or banner where the parent element handles the interaction. If you are unsure whether you need this, please reach out to the Design System team via **#help-designsystem**.
|
|
8
|
+
|
|
9
|
+
## Table of Contents
|
|
10
|
+
|
|
11
|
+
- [When to Use This (and When Not To)](#when-to-use-this-and-when-not-to)
|
|
12
|
+
- [Installation](#installation)
|
|
13
|
+
- [Importing](#importing)
|
|
14
|
+
- [Basic Usage](#basic-usage)
|
|
15
|
+
- [Available Classes](#available-classes)
|
|
16
|
+
- [Sizes](#sizes)
|
|
17
|
+
- [Variants](#variants)
|
|
18
|
+
- [Modifiers](#modifiers)
|
|
19
|
+
- [Icons](#icons)
|
|
20
|
+
- [Accessibility](#accessibility)
|
|
21
|
+
|
|
22
|
+
## When to Use This (and When Not To)
|
|
23
|
+
|
|
24
|
+
**Do NOT use these CSS classes if:**
|
|
25
|
+
- You need a clickable button — use `pie-button`
|
|
26
|
+
- You need a link styled as a button — use `pie-button` with the `tag="a"` prop
|
|
27
|
+
- You need form submission — use `pie-button` with `type="submit"`
|
|
28
|
+
- You are building any interactive control
|
|
29
|
+
|
|
30
|
+
**Use these CSS classes only if:**
|
|
31
|
+
- You need a static, non-interactive element (like a `<div>`) to visually match a PIE button
|
|
32
|
+
- The element sits inside a parent that already handles the interaction (e.g. an `<a>` tag wrapping a banner ad)
|
|
33
|
+
- You have confirmed with the Design System team that this is the correct approach for your use case
|
|
34
|
+
|
|
35
|
+
## Installation
|
|
36
|
+
|
|
37
|
+
The button component styles are included as part of the `@justeattakeaway/pie-css` package:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
# Using Yarn
|
|
41
|
+
yarn add @justeattakeaway/pie-css
|
|
42
|
+
|
|
43
|
+
# Using NPM
|
|
44
|
+
npm install @justeattakeaway/pie-css
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Importing
|
|
48
|
+
|
|
49
|
+
### CSS Import (JavaScript/Framework)
|
|
50
|
+
|
|
51
|
+
Import the pre-compiled CSS file in your JavaScript/TypeScript application:
|
|
52
|
+
|
|
53
|
+
```javascript
|
|
54
|
+
import '@justeattakeaway/pie-css/dist/components/button.css';
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
**React Example:**
|
|
58
|
+
|
|
59
|
+
```jsx
|
|
60
|
+
import '@justeattakeaway/pie-css/dist/components/button.css';
|
|
61
|
+
|
|
62
|
+
function MyCard() {
|
|
63
|
+
return (
|
|
64
|
+
<div className="c-button c-button--primary c-button--medium">
|
|
65
|
+
Click me
|
|
66
|
+
</div>
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
**Vue Example:**
|
|
72
|
+
|
|
73
|
+
```html
|
|
74
|
+
<script setup>
|
|
75
|
+
import '@justeattakeaway/pie-css/dist/components/button.css';
|
|
76
|
+
</script>
|
|
77
|
+
|
|
78
|
+
<template>
|
|
79
|
+
<div class="c-button c-button--primary c-button--medium">
|
|
80
|
+
Click me
|
|
81
|
+
</div>
|
|
82
|
+
</template>
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Basic Usage
|
|
86
|
+
|
|
87
|
+
Apply the `c-button` class along with variant and size modifiers to a static element.
|
|
88
|
+
|
|
89
|
+
```html
|
|
90
|
+
<!-- Primary button, medium size -->
|
|
91
|
+
<div class="c-button c-button--primary c-button--medium">
|
|
92
|
+
Button label
|
|
93
|
+
</div>
|
|
94
|
+
|
|
95
|
+
<!-- Secondary button, small productive size -->
|
|
96
|
+
<div class="c-button c-button--secondary c-button--small-productive">
|
|
97
|
+
Button label
|
|
98
|
+
</div>
|
|
99
|
+
|
|
100
|
+
<!-- Disabled state -->
|
|
101
|
+
<div class="c-button c-button--primary c-button--medium c-button--disabled">
|
|
102
|
+
Disabled
|
|
103
|
+
</div>
|
|
104
|
+
|
|
105
|
+
<!-- Full width -->
|
|
106
|
+
<div class="c-button c-button--primary c-button--medium c-button--fullWidth">
|
|
107
|
+
Full width
|
|
108
|
+
</div>
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## Available Classes
|
|
112
|
+
|
|
113
|
+
### Base
|
|
114
|
+
|
|
115
|
+
| Class | Description |
|
|
116
|
+
|-------|-------------|
|
|
117
|
+
| `.c-button` | Base button layout, typography and custom properties. |
|
|
118
|
+
|
|
119
|
+
### Variants
|
|
120
|
+
|
|
121
|
+
| Class | Description |
|
|
122
|
+
|-------|-------------|
|
|
123
|
+
| `.c-button--primary` | Primary brand colour background |
|
|
124
|
+
| `.c-button--primary-alternative` | Primary alternative colour background |
|
|
125
|
+
| `.c-button--primary-alternative-dark` | Primary alternative dark colour background |
|
|
126
|
+
| `.c-button--secondary` | Secondary colour background |
|
|
127
|
+
| `.c-button--outline` | Transparent background with border |
|
|
128
|
+
| `.c-button--ghost` | Transparent background, no border |
|
|
129
|
+
| `.c-button--ghost-dark` | Transparent background, dark text |
|
|
130
|
+
| `.c-button--inverse` | Inverse colour background |
|
|
131
|
+
| `.c-button--ghost-inverse` | Transparent background, light text |
|
|
132
|
+
| `.c-button--outline-inverse` | Transparent background with border, light text |
|
|
133
|
+
| `.c-button--ghost-inverse-light` | Transparent background, light solid text |
|
|
134
|
+
| `.c-button--destructive` | Error/destructive colour background |
|
|
135
|
+
| `.c-button--destructive-ghost` | Transparent background, error text |
|
|
136
|
+
|
|
137
|
+
### Sizes
|
|
138
|
+
|
|
139
|
+
| Class | Description |
|
|
140
|
+
|-------|-------------|
|
|
141
|
+
| `.c-button--xsmall` | Extra small button |
|
|
142
|
+
| `.c-button--small-productive` | Small productive button |
|
|
143
|
+
| `.c-button--small-expressive` | Small expressive button |
|
|
144
|
+
| `.c-button--medium` | Medium button |
|
|
145
|
+
| `.c-button--large` | Large button |
|
|
146
|
+
|
|
147
|
+
### Modifiers
|
|
148
|
+
|
|
149
|
+
| Class | Description |
|
|
150
|
+
|-------|-------------|
|
|
151
|
+
| `.c-button--disabled` | Disabled appearance (cursor: not-allowed, pointer-events: none) |
|
|
152
|
+
| `.c-button--fullWidth` | Makes the button span 100% of its container |
|
|
153
|
+
| `.c-button--truncate` | Truncates the label with an ellipsis when text overflows the button's width |
|
|
154
|
+
| `.c-button--responsive` | Enables responsive size bumping at wider viewports |
|
|
155
|
+
| `.c-button--expressive` | Used with `--responsive` to prefer expressive sizing at wider viewports |
|
|
156
|
+
|
|
157
|
+
## Sizes
|
|
158
|
+
|
|
159
|
+
Each size sets the font size, line height, padding and icon size for the button.
|
|
160
|
+
|
|
161
|
+
| Size | Font | Icon Size | Responsive Bump |
|
|
162
|
+
|------|------|-----------|-----------------|
|
|
163
|
+
| `xsmall` | Interactive XS | 16px | small-productive (or small-expressive with `--expressive`) |
|
|
164
|
+
| `small-productive` | Interactive S | 20px | medium |
|
|
165
|
+
| `small-expressive` | Interactive L | 20px | medium |
|
|
166
|
+
| `medium` | Interactive L | 24px | large |
|
|
167
|
+
| `large` | Interactive L | 24px | No change |
|
|
168
|
+
|
|
169
|
+
### Responsive Behaviour
|
|
170
|
+
|
|
171
|
+
Add `.c-button--responsive` to enable automatic size bumping at viewports wider than 768px. By default the xsmall size bumps to small-productive; add `.c-button--expressive` to bump to small-expressive instead.
|
|
172
|
+
|
|
173
|
+
```html
|
|
174
|
+
<!-- Responsive: xsmall → small-productive at wide viewports -->
|
|
175
|
+
<div class="c-button c-button--primary c-button--xsmall c-button--responsive">
|
|
176
|
+
Responsive
|
|
177
|
+
</div>
|
|
178
|
+
|
|
179
|
+
<!-- Responsive + Expressive: xsmall → small-expressive at wide viewports -->
|
|
180
|
+
<div class="c-button c-button--primary c-button--xsmall c-button--responsive c-button--expressive">
|
|
181
|
+
Expressive
|
|
182
|
+
</div>
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
## Variants
|
|
186
|
+
|
|
187
|
+
All 13 variants are supported. Each sets the background colour, text colour and interactive hover/active states.
|
|
188
|
+
|
|
189
|
+
The `primary` variant includes special handling for `xsmall` and `small-productive` sizes, which use different colour tokens to ensure text remains accessible at smaller sizes.
|
|
190
|
+
|
|
191
|
+
Outline variants (`outline`, `outline-inverse`) include a 1px border and automatically offset vertical padding by 1px to maintain consistent overall height.
|
|
192
|
+
|
|
193
|
+
## Modifiers
|
|
194
|
+
|
|
195
|
+
### Disabled
|
|
196
|
+
|
|
197
|
+
The disabled modifier uses class-based selectors (`.c-button--disabled`) rather than the `:disabled` pseudo-class, because these CSS classes target non-interactive elements where `:disabled` is not applicable.
|
|
198
|
+
|
|
199
|
+
```html
|
|
200
|
+
<div class="c-button c-button--primary c-button--medium c-button--disabled">
|
|
201
|
+
Disabled
|
|
202
|
+
</div>
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### Full Width
|
|
206
|
+
|
|
207
|
+
```html
|
|
208
|
+
<div class="c-button c-button--primary c-button--medium c-button--fullWidth">
|
|
209
|
+
Full Width Button
|
|
210
|
+
</div>
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### Truncate
|
|
214
|
+
|
|
215
|
+
Add `.c-button--truncate` to truncate the button label with an ellipsis when text overflows the button's width. When using this modifier, the label **must** be wrapped in a `<span>` element — `text-overflow: ellipsis` does not work directly on flex containers, so the inner `<span>` is required. The button's width must also be constrained externally (e.g. via `c-button--fullWidth` inside a sized container, or a `max-width` on a parent element). Buttons are `inline-flex` by default and will grow to fit their content, so truncation only takes effect when something limits the button's width.
|
|
216
|
+
|
|
217
|
+
```html
|
|
218
|
+
<!-- Constrain the parent to force truncation -->
|
|
219
|
+
<div style="max-width: 200px;">
|
|
220
|
+
<div class="c-button c-button--primary c-button--medium c-button--fullWidth c-button--truncate">
|
|
221
|
+
<span>This label is too long and will be truncated with an ellipsis</span>
|
|
222
|
+
</div>
|
|
223
|
+
</div>
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
## Icons
|
|
227
|
+
|
|
228
|
+
Icon sizing within CSS-only buttons is built exclusively for [`@justeattakeaway/pie-icons-webc`](https://www.npmjs.com/package/@justeattakeaway/pie-icons-webc). Other icon libraries, inline SVGs, or custom icon elements are **not supported** and may not size or align correctly. We will not be adding support for other icon solutions.
|
|
229
|
+
|
|
230
|
+
A button can contain only one icon, either **leading** (before the label) or **trailing** (after the label). The icon size is determined automatically by the button size class.
|
|
231
|
+
|
|
232
|
+
### Leading icon
|
|
233
|
+
|
|
234
|
+
Place the icon element **before** the label text:
|
|
235
|
+
|
|
236
|
+
```html
|
|
237
|
+
<div class="c-button c-button--primary c-button--medium">
|
|
238
|
+
<icon-plus-circle></icon-plus-circle>
|
|
239
|
+
Add item
|
|
240
|
+
</div>
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
### Trailing icon
|
|
244
|
+
|
|
245
|
+
Place the icon element **after** the label text:
|
|
246
|
+
|
|
247
|
+
```html
|
|
248
|
+
<div class="c-button c-button--primary c-button--medium">
|
|
249
|
+
Next
|
|
250
|
+
<icon-plus-circle></icon-plus-circle>
|
|
251
|
+
</div>
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
## Accessibility
|
|
255
|
+
|
|
256
|
+
These CSS classes are intended for **non-interactive, visual-only** elements. They do not add any interactive behaviour such as keyboard handling, ARIA roles, or focus management.
|
|
257
|
+
|
|
258
|
+
If you need an interactive button, **do not use these classes** — use the [`pie-button`](https://webc.pie.design/?path=/docs/components-button--docs) web component instead, which provides full keyboard navigation, ARIA attributes and screen reader support out of the box.
|
|
259
|
+
|
|
260
|
+
If you are unsure whether you need CSS-only button styles or the `pie-button` web component, reach out to the Design System team via **#help-designsystem**.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@justeattakeaway/pie-css",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.32.0",
|
|
4
4
|
"description": "A styling library that provides both a shared collection of ready to use CSS styles to be used across JET web front-ends, and SCSS-based style helpers for our PIE Web Component library.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"cdnContentType": "text/css"
|
|
22
22
|
},
|
|
23
23
|
"scripts": {
|
|
24
|
-
"build": "run -T ts-node ./buildCss.ts && run -T
|
|
24
|
+
"build": "run -T ts-node ./buildCss.ts && run -T ts-node ./buildInternalScss.ts",
|
|
25
25
|
"generate:typography-docs": "node scripts/generate-typography-docs.js",
|
|
26
26
|
"lint:scripts": "run -T eslint .",
|
|
27
27
|
"lint:scripts:fix": "yarn lint:scripts --fix",
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
@use '../../mixins/components/button' as button;
|
|
2
|
+
|
|
3
|
+
// Base
|
|
4
|
+
.c-button {
|
|
5
|
+
@include button.button-base;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
// Variants
|
|
9
|
+
.c-button--primary {
|
|
10
|
+
@include button.button-variant('primary');
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.c-button--primary-alternative {
|
|
14
|
+
@include button.button-variant('primary-alternative');
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.c-button--primary-alternative-dark {
|
|
18
|
+
@include button.button-variant('primary-alternative-dark');
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.c-button--secondary {
|
|
22
|
+
@include button.button-variant('secondary');
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.c-button--outline {
|
|
26
|
+
@include button.button-variant('outline');
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.c-button--ghost {
|
|
30
|
+
@include button.button-variant('ghost');
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.c-button--ghost-dark {
|
|
34
|
+
@include button.button-variant('ghost-dark');
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.c-button--inverse {
|
|
38
|
+
@include button.button-variant('inverse');
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.c-button--ghost-inverse {
|
|
42
|
+
@include button.button-variant('ghost-inverse');
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.c-button--outline-inverse {
|
|
46
|
+
@include button.button-variant('outline-inverse');
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.c-button--ghost-inverse-light {
|
|
50
|
+
@include button.button-variant('ghost-inverse-light');
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.c-button--destructive {
|
|
54
|
+
@include button.button-variant('destructive');
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.c-button--destructive-ghost {
|
|
58
|
+
@include button.button-variant('destructive-ghost');
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Sizes
|
|
62
|
+
.c-button--xsmall {
|
|
63
|
+
@include button.button-size('xsmall');
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.c-button--small-expressive {
|
|
67
|
+
@include button.button-size('small-expressive');
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.c-button--small-productive {
|
|
71
|
+
@include button.button-size('small-productive');
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.c-button--medium {
|
|
75
|
+
@include button.button-size('medium');
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.c-button--large {
|
|
79
|
+
@include button.button-size('large');
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Full width
|
|
83
|
+
.c-button--fullWidth {
|
|
84
|
+
@include button.button-full-width;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Disabled
|
|
88
|
+
.c-button--disabled {
|
|
89
|
+
@include button.button-disabled;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Truncate
|
|
93
|
+
.c-button--truncate {
|
|
94
|
+
@include button.button-truncate;
|
|
95
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
@use '
|
|
1
|
+
@use '../../mixins/font-theme' as *;
|
|
2
2
|
|
|
3
3
|
$typography-names: font-heading-xs font-heading-s font-heading-m font-heading-l font-heading-xl font-heading-xxl
|
|
4
4
|
font-heading-xs-italic font-heading-s-italic font-heading-m-italic font-heading-l-italic font-heading-xl-italic font-heading-xxl-italic
|
|
@@ -57,16 +57,16 @@
|
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
/* stylelint-disable @justeattakeaway/pie-design-tokens -- SCSS interpolation produces valid tokens at compile time */
|
|
61
60
|
@supports (background-color: color-mix(in srgb, black, white)) {
|
|
62
61
|
&:hover:not(:disabled, .is-disabled, .is-dismissible) {
|
|
62
|
+
/* stylelint-disable-next-line @justeattakeaway/pie-design-tokens -- SCSS interpolation produces valid tokens at compile time */
|
|
63
63
|
--int-states-mixin-bg-color: color-mix(in srgb, var(--dt-color-hover-#{$level}-bg) var(--dt-color-hover-#{$level}), var(#{$bg-color}));
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
&:active:not(:disabled, .is-disabled, .is-dismissible),
|
|
67
67
|
&.is-loading:not(:disabled, .is-disabled) {
|
|
68
|
+
/* stylelint-disable-next-line @justeattakeaway/pie-design-tokens -- SCSS interpolation produces valid tokens at compile time */
|
|
68
69
|
--int-states-mixin-bg-color: color-mix(in srgb, var(--dt-color-active-#{$level}-bg) var(--dt-color-active-#{$level}), var(#{$bg-color}));
|
|
69
70
|
}
|
|
70
71
|
}
|
|
71
|
-
/* stylelint-enable @justeattakeaway/pie-design-tokens */
|
|
72
72
|
}
|