@justeattakeaway/pie-css 0.31.1 → 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.
@@ -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**.
@@ -104,7 +104,7 @@ To use the mixin as part of the full set of PIE SCSS Utilities, you can import t
104
104
  @use '@justeattakeaway/pie-css/scss' as p;
105
105
 
106
106
  .my-element {
107
- @include p.font-theme('heading-l');
107
+ @include p.font-theme('font-heading-l');
108
108
  }
109
109
  ```
110
110
 
@@ -114,7 +114,7 @@ Alternatively, you can import the mixin directly, without importing the other SC
114
114
  @use '@justeattakeaway/pie-css/scss/mixins/font-theme' as *;
115
115
 
116
116
  .my-element {
117
- @include font-theme('heading-l');
117
+ @include font-theme('font-heading-l');
118
118
  }
119
119
  ```
120
120
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@justeattakeaway/pie-css",
3
- "version": "0.31.1",
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 sass --load-path=../../../node_modules scss/_internal/typography.scss dist/helpers/typography.css --no-source-map && run -T sass --load-path=../../../node_modules scss/_internal/radio.scss dist/components/radio.css --no-source-map",
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 '../mixins/components/radio' as radio;
1
+ @use '../../mixins/components/radio' as radio;
2
2
 
3
3
  .c-radio {
4
4
  @include radio.radio-input-base;
@@ -1,4 +1,4 @@
1
- @use '../mixins/font-theme' as *;
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
  }