@justeattakeaway/pie-button 0.37.1 → 0.38.1-next.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/react.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import type { CSSResult } from 'lit';
2
2
  import type { LitElement } from 'lit';
3
3
  import type { PropertyValues } from 'lit';
4
- import type { ReactWebComponent } from '@lit-labs/react';
4
+ import type { ReactWebComponent } from '@lit/react';
5
5
  import type { TemplateResult } from 'lit';
6
6
 
7
7
  export declare interface ButtonProps {
@@ -33,6 +33,10 @@ export declare interface ButtonProps {
33
33
  * When true, displays a loading indicator inside the button.
34
34
  */
35
35
  isLoading: boolean;
36
+ /**
37
+ * When true, enables the responsive size feature.
38
+ */
39
+ isResponsive: boolean;
36
40
  /**
37
41
  * The name of the button, submitted as a pair with the button's value as part of the form data, when that button is used to submit the form.
38
42
  * [MDN reference](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attributes)
@@ -71,6 +75,10 @@ export declare interface ButtonProps {
71
75
  * [MDN reference](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attributes)
72
76
  */
73
77
  formtarget?: typeof formTargetTypes[number];
78
+ /**
79
+ * What size should be attributed to the button when isResponsive is true and the screen is wide.
80
+ */
81
+ responsiveSize?: typeof responsiveSizes[number];
74
82
  }
75
83
 
76
84
  export declare const formEncodingtypes: readonly ["application/x-www-form-urlencoded", "multipart/form-data", "text/plain"];
@@ -103,6 +111,7 @@ declare class PieButton_2 extends LitElement implements ButtonProps {
103
111
  disabled: boolean;
104
112
  isLoading: boolean;
105
113
  isFullWidth: boolean;
114
+ isResponsive: boolean;
106
115
  name?: string;
107
116
  value?: string;
108
117
  formaction: ButtonProps['formaction'];
@@ -110,6 +119,7 @@ declare class PieButton_2 extends LitElement implements ButtonProps {
110
119
  formmethod: ButtonProps['formmethod'];
111
120
  formnovalidate: ButtonProps['formnovalidate'];
112
121
  formtarget: ButtonProps['formtarget'];
122
+ responsiveSize?: ButtonProps['responsiveSize'];
113
123
  /**
114
124
  * This method creates an invisible button of the same type as pie-button. It is then clicked, and immediately removed from the DOM.
115
125
  * This is done so that we trigger native form actions, such as submit and reset in the browser. The performance impact of adding and removing a single button to the DOM
@@ -132,6 +142,8 @@ declare class PieButton_2 extends LitElement implements ButtonProps {
132
142
  static styles: CSSResult;
133
143
  }
134
144
 
145
+ export declare const responsiveSizes: readonly ["productive", "expressive"];
146
+
135
147
  export declare const sizes: readonly ["xsmall", "small-productive", "small-expressive", "medium", "large"];
136
148
 
137
149
  export declare const types: readonly ["submit", "button", "reset"];
package/dist/react.js CHANGED
@@ -1,78 +1,57 @@
1
- import * as w from "react";
1
+ import * as y from "react";
2
2
  import { PieButton as E } from "./index.js";
3
- import { formEncodingtypes as k, formMethodTypes as A, formTargetTypes as D, iconPlacements as G, sizes as H, types as O, variants as S } from "./index.js";
3
+ import { formEncodingtypes as k, formMethodTypes as C, formTargetTypes as S, iconPlacements as j, responsiveSizes as x, sizes as z, types as A, variants as H } from "./index.js";
4
4
  import "lit";
5
5
  import "lit/decorators.js";
6
+ import "lit/directives/if-defined.js";
6
7
  import "@justeattakeaway/pie-spinner";
7
8
  /**
8
9
  * @license
9
10
  * Copyright 2018 Google LLC
10
11
  * SPDX-License-Identifier: BSD-3-Clause
11
12
  */
12
- const b = /* @__PURE__ */ new Set(["children", "localName", "ref", "style", "className"]), g = /* @__PURE__ */ new WeakMap(), M = (t, o, m, p, d) => {
13
- const i = d == null ? void 0 : d[o];
14
- i === void 0 || m === p ? m == null && o in HTMLElement.prototype ? t.removeAttribute(o) : t[o] = m : ((r, n, u) => {
15
- let a = g.get(r);
16
- a === void 0 && g.set(r, a = /* @__PURE__ */ new Map());
17
- let l = a.get(n);
18
- u !== void 0 ? l === void 0 ? (a.set(n, l = { handleEvent: u }), r.addEventListener(n, l)) : l.handleEvent = u : l !== void 0 && (a.delete(n), r.removeEventListener(n, l));
19
- })(t, i, m);
20
- }, P = (t, o) => {
21
- typeof t == "function" ? t(o) : t.current = o;
22
- };
23
- function B(t = window.React, o, m, p, d) {
24
- let i, r, n;
25
- if (o === void 0) {
26
- const c = t;
27
- ({ tagName: r, elementClass: n, events: p, displayName: d } = c), i = c.react;
28
- } else
29
- i = t, n = m, r = o;
30
- const u = i.Component, a = i.createElement, l = new Set(Object.keys(p ?? {}));
31
- class f extends u {
32
- constructor() {
33
- super(...arguments), this.o = null;
34
- }
35
- t(e) {
36
- if (this.o !== null)
37
- for (const h in this.i)
38
- M(this.o, h, this.props[h], e ? e[h] : void 0, p);
39
- }
40
- componentDidMount() {
13
+ const N = /* @__PURE__ */ new Set(["children", "localName", "ref", "style", "className"]), v = /* @__PURE__ */ new WeakMap(), g = (t, c, a, l, u) => {
14
+ const m = u == null ? void 0 : u[c];
15
+ m === void 0 || a === l ? (t[c] = a, a == null && c in HTMLElement.prototype && t.removeAttribute(c)) : ((i, n, o) => {
16
+ let s = v.get(i);
17
+ s === void 0 && v.set(i, s = /* @__PURE__ */ new Map());
18
+ let r = s.get(n);
19
+ o !== void 0 ? r === void 0 ? (s.set(n, r = { handleEvent: o }), i.addEventListener(n, r)) : r.handleEvent = o : r !== void 0 && (s.delete(n), i.removeEventListener(n, r));
20
+ })(t, m, a);
21
+ }, h = ({ react: t, tagName: c, elementClass: a, events: l, displayName: u }) => {
22
+ const m = new Set(Object.keys(l ?? {})), i = t.forwardRef((n, o) => {
23
+ const s = t.useRef(null), r = t.useRef(null), p = {}, d = {};
24
+ for (const [e, f] of Object.entries(n))
25
+ N.has(e) ? p[e === "className" ? "class" : e] = f : m.has(e) || e in a.prototype ? d[e] = f : p[e] = f;
26
+ return t.useLayoutEffect(() => {
27
+ if (r.current !== null) {
28
+ for (const e in d)
29
+ g(r.current, e, n[e], s.current ? s.current[e] : void 0, l);
30
+ s.current = n;
31
+ }
32
+ }), t.useLayoutEffect(() => {
41
33
  var e;
42
- this.t(), (e = this.o) === null || e === void 0 || e.removeAttribute("defer-hydration");
43
- }
44
- componentDidUpdate(e) {
45
- this.t(e);
46
- }
47
- render() {
48
- const { _$Gl: e, ...h } = this.props;
49
- this.h !== e && (this.u = (s) => {
50
- e !== null && P(e, s), this.o = s, this.h = e;
51
- }), this.i = {};
52
- const v = { ref: this.u };
53
- for (const [s, y] of Object.entries(h))
54
- b.has(s) ? v[s === "className" ? "class" : s] = y : l.has(s) || s in n.prototype ? this.i[s] = y : v[s] = y;
55
- return v.suppressHydrationWarning = !0, a(r, v);
56
- }
57
- }
58
- f.displayName = d ?? n.name;
59
- const N = i.forwardRef((c, e) => a(f, { ...c, _$Gl: e }, c == null ? void 0 : c.children));
60
- return N.displayName = f.displayName, N;
61
- }
62
- const R = B({
34
+ (e = r.current) == null || e.removeAttribute("defer-hydration");
35
+ }, []), p.suppressHydrationWarning = !0, t.createElement(c, { ...p, ref: t.useCallback((e) => {
36
+ r.current = e, typeof o == "function" ? o(e) : o !== null && (o.current = e);
37
+ }, [o]) });
38
+ });
39
+ return i.displayName = u ?? a.name, i;
40
+ }, M = h({
63
41
  displayName: "PieButton",
64
42
  elementClass: E,
65
- react: w,
43
+ react: y,
66
44
  tagName: "pie-button",
67
45
  events: {}
68
46
  });
69
47
  export {
70
- R as PieButton,
48
+ M as PieButton,
71
49
  k as formEncodingtypes,
72
- A as formMethodTypes,
73
- D as formTargetTypes,
74
- G as iconPlacements,
75
- H as sizes,
76
- O as types,
77
- S as variants
50
+ C as formMethodTypes,
51
+ S as formTargetTypes,
52
+ j as iconPlacements,
53
+ x as responsiveSizes,
54
+ z as sizes,
55
+ A as types,
56
+ H as variants
78
57
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@justeattakeaway/pie-button",
3
- "version": "0.37.1",
3
+ "version": "0.38.1-next.0",
4
4
  "description": "PIE design system button built using web components",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -28,7 +28,7 @@
28
28
  "author": "Just Eat Takeaway.com - Design System Team",
29
29
  "license": "Apache-2.0",
30
30
  "devDependencies": {
31
- "@justeattakeaway/pie-components-config": "0.5.0"
31
+ "@justeattakeaway/pie-components-config": "0.6.0"
32
32
  },
33
33
  "volta": {
34
34
  "extends": "../../../package.json"
@@ -37,8 +37,8 @@
37
37
  "dist/*.js"
38
38
  ],
39
39
  "dependencies": {
40
- "@justeattakeaway/pie-spinner": "0.2.1",
41
- "@justeattakeaway/pie-webc-core": "0.11.0",
40
+ "@justeattakeaway/pie-spinner": "0.2.2-next.0",
41
+ "@justeattakeaway/pie-webc-core": "0.12.0-next.0",
42
42
  "element-internals-polyfill": "1.3.8"
43
43
  }
44
44
  }
package/src/button.scss CHANGED
@@ -6,6 +6,20 @@
6
6
  box-sizing: border-box;
7
7
  }
8
8
 
9
+ $breakpoint-wide: 768px;
10
+
11
+ /**
12
+ * Mixin for adding the responsive behaviour.
13
+ * Takes in the the particular settings for the wide breakpoint.
14
+ */
15
+ @mixin responsive-wide {
16
+ &[isResponsive] {
17
+ @media (min-width: $breakpoint-wide) {
18
+ @content;
19
+ }
20
+ }
21
+ }
22
+
9
23
  // Base button styles
10
24
  .o-btn {
11
25
  // Custom Property Declarations
@@ -14,11 +28,6 @@
14
28
  --btn-font-family: var(--dt-font-interactive-m-family);
15
29
  --btn-font-weight: var(--dt-font-interactive-m-weight);
16
30
 
17
- // The base values are set to the size default, which is for the medium button size
18
- --btn-padding: 10px var(--dt-spacing-e);
19
- --btn-font-size: #{p.font-size(--dt-font-size-20)};
20
- --btn-line-height: calc(var(--dt-font-size-20-line-height) * 1px);
21
-
22
31
  // The following values set to default background and color
23
32
  // currently this sets the primary button styles
24
33
  --btn-bg-color: var(--dt-color-interactive-brand);
@@ -30,11 +39,43 @@
30
39
  --btn-height--medium: 48px;
31
40
  --btn-height--large: 56px;
32
41
 
33
- // Set height to medium (the default state)
34
- --btn-height: var(--btn-height--medium);
35
-
36
- // Set icon size to the medium button icon size (the default state)
37
- --btn-icon-size: 24px;
42
+ /**
43
+ * Mixin for updating the button styles based on the size passed in.
44
+ * Takes in the name of the size to be used.
45
+ */
46
+ @mixin button-size($size) {
47
+ @if $size == 'xsmall' {
48
+ --btn-height: var(--btn-height--xsmall);
49
+ --btn-padding: 6px var(--dt-spacing-b);
50
+ --btn-font-size: #{p.font-size(--dt-font-size-14)};
51
+ --btn-line-height: calc(var(--dt-font-size-14-line-height) * 1px);
52
+ --btn-icon-size: 16px;
53
+ } @else if $size == 'small-expressive' {
54
+ --btn-height: var(--btn-height--small);
55
+ --btn-padding: 6px var(--dt-spacing-d);
56
+ --btn-font-size: #{p.font-size(--dt-font-size-20)};
57
+ --btn-line-height: calc(var(--dt-font-size-20-line-height) * 1px);
58
+ --btn-icon-size: 20px;
59
+ } @else if $size == 'small-productive' {
60
+ --btn-height: var(--btn-height--small);
61
+ --btn-padding: 8px var(--dt-spacing-d);
62
+ --btn-font-size: #{p.font-size(--dt-font-size-16)};
63
+ --btn-line-height: calc(var(--dt-font-size-16-line-height) * 1px);
64
+ --btn-icon-size: 20px;
65
+ } @else if $size == 'medium' {
66
+ --btn-height: var(--btn-height--medium);
67
+ --btn-padding: 10px var(--dt-spacing-e);
68
+ --btn-font-size: #{p.font-size(--dt-font-size-20)};
69
+ --btn-line-height: calc(var(--dt-font-size-20-line-height) * 1px);
70
+ --btn-icon-size: 24px;
71
+ } @else if $size == 'large' {
72
+ --btn-height: var(--btn-height--large);
73
+ --btn-padding: 14px var(--dt-spacing-e);
74
+ --btn-font-size: #{p.font-size(--dt-font-size-20)};
75
+ --btn-line-height: calc(var(--dt-font-size-20-line-height) * 1px);
76
+ --btn-icon-size: 24px;
77
+ }
78
+ }
38
79
 
39
80
  position: relative;
40
81
  display: flex;
@@ -71,7 +112,7 @@
71
112
  **/
72
113
  --btn-bg-color: var(--dt-color-interactive-primary);
73
114
 
74
- @include p.button-interactive-states('--dt-color-interactive-primary', 'alt');
115
+ @include p.button-interactive-states('--dt-color-interactive-primary', 'inverse');
75
116
  }
76
117
  }
77
118
 
@@ -160,40 +201,40 @@
160
201
  }
161
202
 
162
203
  &[size='xsmall'] {
163
- --btn-height: var(--btn-height--xsmall);
164
- --btn-padding: 6px var(--dt-spacing-b);
165
- --btn-font-size: #{p.font-size(--dt-font-size-14)};
166
- --btn-line-height: calc(var(--dt-font-size-14-line-height) * 1px);
167
- --btn-icon-size: 16px;
168
- }
169
-
170
- &[size='small-expressive'],
171
- &[size='small-productive'] {
172
- --btn-height: var(--btn-height--small);
173
- --btn-icon-size: 20px;
204
+ @include button-size(xsmall);
205
+ @include responsive-wide {
206
+ // productive is the default size when responsive is enabled
207
+ @include button-size(small-productive);
208
+
209
+ &[responsiveSize='expressive'] {
210
+ @include button-size(small-expressive);
211
+ }
212
+ }
174
213
  }
175
214
 
176
215
  &[size='small-expressive'] {
177
- --btn-padding: 6px var(--dt-spacing-d);
178
- --btn-font-size: #{p.font-size(--dt-font-size-20)};
179
- --btn-line-height: calc(var(--dt-font-size-20-line-height) * 1px);
216
+ @include button-size(small-expressive);
217
+ @include responsive-wide {
218
+ @include button-size(medium);
219
+ }
180
220
  }
181
221
 
182
222
  &[size='small-productive'] {
183
- --btn-padding: 8px var(--dt-spacing-d);
184
- --btn-font-size: #{p.font-size(--dt-font-size-16)};
185
- --btn-line-height: calc(var(--dt-font-size-16-line-height) * 1px);
223
+ @include button-size(small-productive);
224
+ @include responsive-wide {
225
+ @include button-size(medium);
226
+ }
186
227
  }
187
228
 
188
229
  &[size='medium'] {
189
- /* Same as default styles */
230
+ @include button-size(medium);
231
+ @include responsive-wide {
232
+ @include button-size(large);
233
+ }
190
234
  }
191
235
 
192
236
  &[size='large'] {
193
- --btn-height: var(--btn-height--large);
194
- --btn-padding: 14px var(--dt-spacing-e);
195
- --btn-font-size: #{p.font-size(--dt-font-size-20)};
196
- --btn-line-height: calc(var(--dt-font-size-20-line-height) * 1px);
237
+ @include button-size(large);
197
238
  }
198
239
 
199
240
  &[isLoading] {
package/src/defs.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export const sizes = ['xsmall', 'small-productive', 'small-expressive', 'medium', 'large'] as const;
2
+ export const responsiveSizes = ['productive', 'expressive'] as const;
2
3
  export const types = ['submit', 'button', 'reset'] as const;
3
4
  export const variants = [
4
5
  'primary', 'secondary', 'outline', 'outline-inverse', 'ghost',
@@ -42,6 +43,11 @@ export interface ButtonProps {
42
43
  */
43
44
  isLoading: boolean;
44
45
 
46
+ /**
47
+ * When true, enables the responsive size feature.
48
+ */
49
+ isResponsive: boolean;
50
+
45
51
  /**
46
52
  * The name of the button, submitted as a pair with the button's value as part of the form data, when that button is used to submit the form.
47
53
  * [MDN reference](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attributes)
@@ -86,4 +92,9 @@ export interface ButtonProps {
86
92
  * [MDN reference](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attributes)
87
93
  */
88
94
  formtarget?: typeof formTargetTypes[number]
95
+
96
+ /**
97
+ * What size should be attributed to the button when isResponsive is true and the screen is wide.
98
+ */
99
+ responsiveSize?: typeof responsiveSizes[number];
89
100
  }
package/src/index.ts CHANGED
@@ -2,6 +2,7 @@ import {
2
2
  LitElement, html, unsafeCSS, nothing, PropertyValues, TemplateResult,
3
3
  } from 'lit';
4
4
  import { property } from 'lit/decorators.js';
5
+ import { ifDefined } from 'lit/directives/if-defined.js';
5
6
  import { validPropertyValues, defineCustomElement } from '@justeattakeaway/pie-webc-core';
6
7
  import {
7
8
  ButtonProps, sizes, types, variants, iconPlacements,
@@ -89,6 +90,9 @@ export class PieButton extends LitElement implements ButtonProps {
89
90
  @property({ type: Boolean })
90
91
  public isFullWidth = false;
91
92
 
93
+ @property({ type: Boolean })
94
+ public isResponsive = false;
95
+
92
96
  @property({ type: String })
93
97
  public name?: string;
94
98
 
@@ -110,6 +114,9 @@ export class PieButton extends LitElement implements ButtonProps {
110
114
  @property()
111
115
  public formtarget: ButtonProps['formtarget'];
112
116
 
117
+ @property({ type: String })
118
+ public responsiveSize?: ButtonProps['responsiveSize'];
119
+
113
120
  /**
114
121
  * This method creates an invisible button of the same type as pie-button. It is then clicked, and immediately removed from the DOM.
115
122
  * This is done so that we trigger native form actions, such as submit and reset in the browser. The performance impact of adding and removing a single button to the DOM
@@ -222,7 +229,9 @@ export class PieButton extends LitElement implements ButtonProps {
222
229
  variant,
223
230
  size,
224
231
  isLoading,
232
+ isResponsive,
225
233
  iconPlacement,
234
+ responsiveSize,
226
235
  } = this;
227
236
 
228
237
  return html`
@@ -232,8 +241,10 @@ export class PieButton extends LitElement implements ButtonProps {
232
241
  type=${type}
233
242
  variant=${variant}
234
243
  size=${size}
244
+ responsiveSize=${ifDefined(responsiveSize)}
235
245
  ?disabled=${disabled}
236
246
  ?isFullWidth=${isFullWidth}
247
+ ?isResponsive=${isResponsive}
237
248
  ?isLoading=${isLoading}>
238
249
  ${isLoading ? this.renderSpinner() : nothing}
239
250
  ${iconPlacement === 'leading' ? html`<slot name="icon"></slot>` : nothing}