@justeattakeaway/pie-link 0.2.0 → 0.4.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/README.md CHANGED
@@ -57,15 +57,21 @@ import { PieLink } from '@justeattakeaway/pie-link/dist/react';
57
57
 
58
58
  ## Props
59
59
 
60
- | Property | Type | Default | Description |
61
- | ------------ | ----------- | ------------- | --------------------------------------------------------------------------- |
62
- | variant | `String` | `default` | Variant of the link, one of variants default, high-visibility or inverse |
63
- | size | `String` | `medium` | Size of the link, one of `sizes` – `medium`, `small` |
64
- | href | `String` | `undefined` | Native html `href` attribute |
65
- | rel | `String` | `undefined` | Native html `rel` attribute |
66
- | target | `String` | `undefined` | Native html `target` attribute |
67
- | isBold | `Boolean` | `false` | If `true`, sets the link text bold |
68
- | isStandalone | `Boolean` | `false` | If `true`, sets the link as a block element |
60
+ | Property | Type | Default | Description |
61
+ | ------------- | ----------- | ------------- | ---------------------------------------------------------------------------------------------------- |
62
+ | tag | `String` | `a` | The rendered HTML element of the link, one of `tags` `a`, `button` |
63
+ | variant | `String` | `default` | Variant of the link, one of `variants` – `default`, `high-visibility`, `inverse` |
64
+ | size | `String` | `medium` | Size of the link, one of `sizes` – `medium`, `small` |
65
+ | underline | `String` | `default` | The underline behavior of the link, one of `underlineTypes` – `default`, `reversed` |
66
+ | href | `String` | `undefined` | Native html `href` attribute |
67
+ | rel | `String` | `undefined` | Native html `rel` attribute |
68
+ | target | `String` | `undefined` | Native html `target` attribute |
69
+ | type | `String` | `submit` | Native html `type` attribute if the tag is set to `button` |
70
+ | isBold | `Boolean` | `false` | If `true`, sets the link text bold |
71
+ | isStandalone | `Boolean` | `false` | If `true`, sets the link as a block element |
72
+ | hasVisited | `Boolean` | `false` | If `true`, the link will apply the styles for the visited state |
73
+ | iconPlacement | `String` | `leading` | Icon placements of the icon slot, if provided, one of `iconPlacements` - `leading`, `trailing` |
74
+ | aria | `object` | `undefined` | The ARIA labels used for the link. |
69
75
 
70
76
  In your markup or JSX, you can then use these to set the properties for the `pie-link` component:
71
77
 
@@ -77,6 +83,28 @@ In your markup or JSX, you can then use these to set the properties for the `pie
77
83
  <PieLink></PieLink>
78
84
  ```
79
85
 
86
+ ## Slots
87
+
88
+ | Slot | Description |
89
+ | ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
90
+ | Default slot | The default slot is used to pass text into the link component. |
91
+ | icon | Used to pass in an icon to the link component. The icon placement can be controlled via the `iconPlacement` prop and we recommend using `pie-icons-webc` for defining this icon, but this can also accept an SVG icon. |
92
+
93
+ ### Using `pie-icons-webc` with the `pie-link` icon slot
94
+
95
+ We recommend using `pie-icons-webc` when using the `icon` slot. Here is an example of how you would do this:
96
+
97
+ ```html
98
+ <!--
99
+ Note that pie-link and the icons that you want to use will need to be imported as components into your application.
100
+ See the `pie-icons-webc` README for more info on importing these icons.
101
+ -->
102
+ <pie-link>
103
+ <icon-plus-circle slot="icon"></icon-plus-circle>
104
+ Search
105
+ </pie-link>
106
+ ```
107
+
80
108
  ## Testing
81
109
 
82
110
  ### Browser tests
package/dist/index.d.ts CHANGED
@@ -1,16 +1,36 @@
1
1
  import type { CSSResult } from 'lit';
2
2
  import type { LitElement } from 'lit';
3
- import type { TemplateResult } from 'lit-html';
3
+ import type { TemplateResult } from 'lit';
4
+
5
+ export declare type AriaProps = {
6
+ label?: string;
7
+ };
8
+
9
+ export declare const buttonTypes: readonly ["submit", "button", "reset", "menu"];
10
+
11
+ export declare const iconPlacements: readonly ["leading", "trailing"];
4
12
 
5
13
  export declare interface LinkProps {
14
+ /**
15
+ * The ARIA labels used for the link.
16
+ */
17
+ aria?: AriaProps;
18
+ /**
19
+ * What HTML element the link should be such as a or button.
20
+ */
21
+ tag: typeof tags[number];
6
22
  /**
7
23
  * What style variant the link should be such as default, high-visibility or inverse.
8
24
  */
9
- variant?: typeof variants[number];
25
+ variant: typeof variants[number];
10
26
  /**
11
27
  * What size the link should be.
12
28
  */
13
- size?: typeof sizes[number];
29
+ size: typeof sizes[number];
30
+ /**
31
+ * What underline behavior the link should have such as default or reversed
32
+ */
33
+ underline: typeof underlineTypes[number];
14
34
  /**
15
35
  * The URL that the hyperlink should point to
16
36
  */
@@ -26,27 +46,71 @@ export declare interface LinkProps {
26
46
  /**
27
47
  * When true, the link text will be bold.
28
48
  */
29
- isBold?: boolean;
49
+ isBold: boolean;
50
+ /**
51
+ * When true, the link will be treated as a block element
52
+ */
53
+ isStandalone: boolean;
30
54
  /**
31
- * When true, the link will be treated as a block box
55
+ * When true, the link will apply the styles for the visited state',
32
56
  */
33
- isStandalone?: boolean;
57
+ hasVisited: boolean;
58
+ /**
59
+ * The placement of the icon slot, if provided, such as leading or trailing
60
+ */
61
+ iconPlacement?: typeof iconPlacements[number];
62
+ /**
63
+ * What type attribute should be applied if the tag is set to button. For example submit, button or menu.
64
+ */
65
+ type?: typeof buttonTypes[number];
34
66
  }
35
67
 
68
+ /**
69
+ * @slot icon - The icon slot
70
+ * @slot - Default slot
71
+ */
36
72
  export declare class PieLink extends LitElement implements LinkProps {
73
+ tag: LinkProps['tag'];
37
74
  variant: LinkProps['variant'];
38
75
  size: LinkProps['size'];
76
+ underline: LinkProps['underline'];
77
+ iconPlacement: LinkProps['iconPlacement'];
39
78
  href?: string;
40
79
  target?: string;
41
80
  rel?: string;
42
81
  isBold: boolean;
43
82
  isStandalone: boolean;
44
- render(): TemplateResult<1>;
83
+ hasVisited: boolean;
84
+ type: LinkProps['type'];
85
+ aria: AriaProps;
86
+ /**
87
+ * Renders the link content.
88
+ *
89
+ * @private
90
+ */
91
+ private renderContent;
92
+ /**
93
+ * Renders the link as a button element.
94
+ *
95
+ * @private
96
+ */
97
+ private renderButton;
98
+ /**
99
+ * Renders the link as an anchor element.
100
+ *
101
+ * @private
102
+ */
103
+ private renderAnchor;
104
+ render(): TemplateResult;
45
105
  static styles: CSSResult;
46
106
  }
47
107
 
48
108
  export declare const sizes: readonly ["small", "medium"];
49
109
 
110
+ export declare const tags: readonly ["a", "button"];
111
+
112
+ export declare const underlineTypes: readonly ["default", "reversed"];
113
+
50
114
  export declare const variants: readonly ["default", "high-visibility", "inverse"];
51
115
 
52
116
  export { }
package/dist/index.js CHANGED
@@ -1,86 +1,152 @@
1
- import { unsafeCSS as k, LitElement as g, html as m } from "lit";
2
- import { property as s } from "lit/decorators.js";
3
- import { ifDefined as d } from "lit/directives/if-defined.js";
1
+ import { unsafeCSS as g, LitElement as k, html as u, nothing as s } from "lit";
2
+ import { property as i } from "lit/decorators.js";
4
3
  import "lit/decorators/property.js";
5
- const v = (c, n, r) => function(t, e) {
6
- const i = `#${e}`;
7
- Object.defineProperty(t, e, {
4
+ const d = (h, t, c) => function(o, r) {
5
+ const l = `#${r}`;
6
+ Object.defineProperty(o, r, {
8
7
  get() {
9
- return this[i];
8
+ return this[l];
10
9
  },
11
- set(f) {
12
- const h = this[i];
13
- n.includes(f) ? this[i] = f : (console.error(
14
- `<${c}> Invalid value "${f}" provided for property "${e}".`,
15
- `Must be one of: ${n.join(" | ")}.`,
16
- `Falling back to default value: "${r}"`
17
- ), this[i] = r), this.requestUpdate(e, h);
10
+ set(v) {
11
+ const f = this[l];
12
+ t.includes(v) ? this[l] = v : (console.error(
13
+ `<${h}> Invalid value "${v}" provided for property "${r}".`,
14
+ `Must be one of: ${t.join(" | ")}.`,
15
+ `Falling back to default value: "${c}"`
16
+ ), this[l] = c), this.requestUpdate(r, f);
18
17
  }
19
18
  });
20
- }, u = `.c-link{--link-font-family: var(--dt-font-interactive-m-family);--link-font-size: calc(var(--dt-font-size-16) * 1px);--link-line-height: calc(var(--dt-font-size-16-line-height) * 1px);--link-font-weight: var(--dt-font-weight-regular);--link-text-color: var(--dt-color-content-link);--link-text-decoration: var(--dt-font-style-underline);font-family:var(--link-font-family);font-size:var(--link-font-size);line-height:var(--link-line-height);font-weight:var(--link-font-weight);color:var(--link-text-color);text-decoration:var(--link-text-decoration);cursor:pointer}.c-link[variant=high-visibility]{--link-text-color: var(--dt-color-content-link-distinct)}.c-link[variant=inverse]{--link-text-color: var(--dt-color-content-link-inverse)}.c-link[size=small]{--link-font-size: calc(var(--dt-font-size-14) * 1px);--link-line-height: calc(var(--dt-font-size-14-line-height) * 1px)}.c-link[isBold]{--link-font-weight: var(--dt-font-weight-bold)}.c-link[isStandalone]{display:block}
21
- `, y = ["default", "high-visibility", "inverse"], z = ["small", "medium"];
22
- var x = Object.defineProperty, S = Object.getOwnPropertyDescriptor, a = (c, n, r, l) => {
23
- for (var t = l > 1 ? void 0 : l ? S(n, r) : n, e = c.length - 1, i; e >= 0; e--)
24
- (i = c[e]) && (t = (l ? i(n, r, t) : i(t)) || t);
25
- return l && t && x(n, r, t), t;
19
+ }, y = `.c-link{--link-font-family: var(--dt-font-interactive-m-family);--link-font-size: calc(var(--dt-font-size-16) * 1px);--link-line-height: calc(var(--dt-font-size-16-line-height) * 1px);--link-font-weight: var(--dt-font-weight-regular);--link-text-color: var(--dt-color-content-link);--link-text-decoration: var(--dt-font-style-underline);--link-icon-size: 16px;display:inline-block;font-family:var(--link-font-family);font-size:var(--link-font-size);line-height:var(--link-line-height);font-weight:var(--link-font-weight);color:var(--link-text-color);text-decoration:var(--link-text-decoration);cursor:pointer}.c-link[tag=button]{outline:none;border:none;user-select:none;background:transparent;padding:0}.c-link[variant=high-visibility]{--link-text-color: var(--dt-color-content-link-distinct)}.c-link[variant=inverse]{--link-text-color: var(--dt-color-content-link-inverse)}.c-link[size=small]{--link-font-size: calc(var(--dt-font-size-14) * 1px);--link-line-height: calc(var(--dt-font-size-14-line-height) * 1px)}.c-link[underline=default]:hover,.c-link[underline=default]:active,.c-link[underline=reversed]{--link-text-decoration: none}.c-link[underline=reversed]:hover,.c-link[underline=reversed]:active{--link-text-decoration: var(--dt-font-style-underline)}.c-link[isBold]{--link-font-weight: var(--dt-font-weight-bold)}.c-link[isStandalone]{display:block}.c-link[hasVisited]:visited{color:var(--dt-color-content-link-visited)}.c-link[hasVisited]:visited[variant=inverse]{color:var(--dt-color-content-link-visited-inverse)}.c-link:focus-visible{box-shadow:0 0 0 2px var(--dt-color-focus-outer)}.c-link-content{display:flex;gap:var(--dt-spacing-a)}::slotted(.c-pieIcon),::slotted(svg){display:inline-flex;margin-block-start:var(--dt-spacing-a);height:var(--link-icon-size);width:var(--link-icon-size)}
20
+ `, m = ["default", "high-visibility", "inverse"], b = ["small", "medium"], $ = ["leading", "trailing"], x = ["a", "button"], z = ["submit", "button", "reset", "menu"], S = ["default", "reversed"];
21
+ var B = Object.defineProperty, P = Object.getOwnPropertyDescriptor, n = (h, t, c, p) => {
22
+ for (var o = p > 1 ? void 0 : p ? P(t, c) : t, r = h.length - 1, l; r >= 0; r--)
23
+ (l = h[r]) && (o = (p ? l(t, c, o) : l(o)) || o);
24
+ return p && o && B(t, c, o), o;
26
25
  };
27
- const p = "pie-link";
28
- class o extends g {
26
+ const a = "pie-link";
27
+ class e extends k {
29
28
  constructor() {
30
- super(...arguments), this.variant = "default", this.size = "medium", this.isBold = !1, this.isStandalone = !1;
29
+ super(...arguments), this.tag = "a", this.variant = "default", this.size = "medium", this.underline = "default", this.iconPlacement = "leading", this.isBold = !1, this.isStandalone = !1, this.hasVisited = !1, this.type = "submit";
31
30
  }
32
- render() {
33
- const {
34
- variant: n,
35
- size: r,
36
- href: l,
37
- target: t,
38
- rel: e,
39
- isBold: i,
40
- isStandalone: f
41
- } = this;
42
- return m`
31
+ /**
32
+ * Renders the link content.
33
+ *
34
+ * @private
35
+ */
36
+ renderContent() {
37
+ const { iconPlacement: t } = this;
38
+ return u`
39
+ <span class="c-link-content">
40
+ ${t === "leading" ? u`<slot name="icon"></slot>` : s}
41
+ <slot></slot>
42
+ ${t === "trailing" ? u`<slot name="icon"></slot>` : s}
43
+ </span>`;
44
+ }
45
+ /**
46
+ * Renders the link as a button element.
47
+ *
48
+ * @private
49
+ */
50
+ renderButton() {
51
+ var t;
52
+ return u`
53
+ <button
54
+ data-test-id="pie-link"
55
+ class="c-link"
56
+ tag=${this.tag}
57
+ variant=${this.variant}
58
+ size=${this.size}
59
+ underline=${this.underline}
60
+ ?isBold=${this.isBold}
61
+ ?isStandalone=${this.isStandalone}
62
+ ?hasVisited=${this.hasVisited}
63
+ type=${this.type || s}
64
+ aria-label=${((t = this.aria) == null ? void 0 : t.label) || s}>
65
+ ${this.renderContent()}
66
+ </button>`;
67
+ }
68
+ /**
69
+ * Renders the link as an anchor element.
70
+ *
71
+ * @private
72
+ */
73
+ renderAnchor() {
74
+ var t;
75
+ return u`
43
76
  <a
44
77
  data-test-id="pie-link"
45
78
  class="c-link"
46
- variant=${n}
47
- size=${r}
48
- href=${d(l)}
49
- target=${d(t)}
50
- rel=${d(e)}
51
- ?isBold=${i}
52
- ?isStandalone=${f}>
53
- <slot></slot>
79
+ tag=${this.tag}
80
+ variant=${this.variant}
81
+ size=${this.size}
82
+ underline=${this.underline}
83
+ ?isBold=${this.isBold}
84
+ ?isStandalone=${this.isStandalone}
85
+ ?hasVisited=${this.hasVisited}
86
+ href=${this.href || s}
87
+ target=${this.target || s}
88
+ rel=${this.rel || s}
89
+ aria-label=${((t = this.aria) == null ? void 0 : t.label) || s}>
90
+ ${this.renderContent()}
54
91
  </a>`;
55
92
  }
93
+ render() {
94
+ return this.tag === "button" ? this.renderButton() : this.renderAnchor();
95
+ }
56
96
  }
57
- o.styles = k(u);
58
- a([
59
- s({ type: String }),
60
- v(p, y, "default")
61
- ], o.prototype, "variant", 2);
62
- a([
63
- s({ type: String }),
64
- v(p, z, "medium")
65
- ], o.prototype, "size", 2);
66
- a([
67
- s({ type: String, reflect: !0 })
68
- ], o.prototype, "href", 2);
69
- a([
70
- s({ type: String, reflect: !0 })
71
- ], o.prototype, "target", 2);
72
- a([
73
- s({ type: String, reflect: !0 })
74
- ], o.prototype, "rel", 2);
75
- a([
76
- s({ type: Boolean })
77
- ], o.prototype, "isBold", 2);
78
- a([
79
- s({ type: Boolean })
80
- ], o.prototype, "isStandalone", 2);
81
- customElements.define(p, o);
97
+ e.styles = g(y);
98
+ n([
99
+ i(),
100
+ d(a, x, "a")
101
+ ], e.prototype, "tag", 2);
102
+ n([
103
+ i({ type: String }),
104
+ d(a, m, "default")
105
+ ], e.prototype, "variant", 2);
106
+ n([
107
+ i({ type: String }),
108
+ d(a, b, "medium")
109
+ ], e.prototype, "size", 2);
110
+ n([
111
+ i({ type: String }),
112
+ d(a, S, "default")
113
+ ], e.prototype, "underline", 2);
114
+ n([
115
+ i({ type: String }),
116
+ d(a, $, "leading")
117
+ ], e.prototype, "iconPlacement", 2);
118
+ n([
119
+ i({ type: String, reflect: !0 })
120
+ ], e.prototype, "href", 2);
121
+ n([
122
+ i({ type: String, reflect: !0 })
123
+ ], e.prototype, "target", 2);
124
+ n([
125
+ i({ type: String, reflect: !0 })
126
+ ], e.prototype, "rel", 2);
127
+ n([
128
+ i({ type: Boolean })
129
+ ], e.prototype, "isBold", 2);
130
+ n([
131
+ i({ type: Boolean })
132
+ ], e.prototype, "isStandalone", 2);
133
+ n([
134
+ i({ type: Boolean })
135
+ ], e.prototype, "hasVisited", 2);
136
+ n([
137
+ i(),
138
+ d(a, z, "submit")
139
+ ], e.prototype, "type", 2);
140
+ n([
141
+ i({ type: Object })
142
+ ], e.prototype, "aria", 2);
143
+ customElements.define(a, e);
82
144
  export {
83
- o as PieLink,
84
- z as sizes,
85
- y as variants
145
+ e as PieLink,
146
+ z as buttonTypes,
147
+ $ as iconPlacements,
148
+ b as sizes,
149
+ x as tags,
150
+ S as underlineTypes,
151
+ m as variants
86
152
  };
package/dist/react.d.ts CHANGED
@@ -1,17 +1,37 @@
1
1
  import type { CSSResult } from 'lit';
2
2
  import type { LitElement } from 'lit';
3
3
  import type { ReactWebComponent } from '@lit-labs/react';
4
- import type { TemplateResult } from 'lit-html';
4
+ import type { TemplateResult } from 'lit';
5
+
6
+ export declare type AriaProps = {
7
+ label?: string;
8
+ };
9
+
10
+ export declare const buttonTypes: readonly ["submit", "button", "reset", "menu"];
11
+
12
+ export declare const iconPlacements: readonly ["leading", "trailing"];
5
13
 
6
14
  export declare interface LinkProps {
15
+ /**
16
+ * The ARIA labels used for the link.
17
+ */
18
+ aria?: AriaProps;
19
+ /**
20
+ * What HTML element the link should be such as a or button.
21
+ */
22
+ tag: typeof tags[number];
7
23
  /**
8
24
  * What style variant the link should be such as default, high-visibility or inverse.
9
25
  */
10
- variant?: typeof variants[number];
26
+ variant: typeof variants[number];
11
27
  /**
12
28
  * What size the link should be.
13
29
  */
14
- size?: typeof sizes[number];
30
+ size: typeof sizes[number];
31
+ /**
32
+ * What underline behavior the link should have such as default or reversed
33
+ */
34
+ underline: typeof underlineTypes[number];
15
35
  /**
16
36
  * The URL that the hyperlink should point to
17
37
  */
@@ -27,29 +47,73 @@ export declare interface LinkProps {
27
47
  /**
28
48
  * When true, the link text will be bold.
29
49
  */
30
- isBold?: boolean;
50
+ isBold: boolean;
51
+ /**
52
+ * When true, the link will be treated as a block element
53
+ */
54
+ isStandalone: boolean;
31
55
  /**
32
- * When true, the link will be treated as a block box
56
+ * When true, the link will apply the styles for the visited state',
33
57
  */
34
- isStandalone?: boolean;
58
+ hasVisited: boolean;
59
+ /**
60
+ * The placement of the icon slot, if provided, such as leading or trailing
61
+ */
62
+ iconPlacement?: typeof iconPlacements[number];
63
+ /**
64
+ * What type attribute should be applied if the tag is set to button. For example submit, button or menu.
65
+ */
66
+ type?: typeof buttonTypes[number];
35
67
  }
36
68
 
37
69
  export declare const PieLink: ReactWebComponent<PieLink_2, {}>;
38
70
 
71
+ /**
72
+ * @slot icon - The icon slot
73
+ * @slot - Default slot
74
+ */
39
75
  declare class PieLink_2 extends LitElement implements LinkProps {
76
+ tag: LinkProps['tag'];
40
77
  variant: LinkProps['variant'];
41
78
  size: LinkProps['size'];
79
+ underline: LinkProps['underline'];
80
+ iconPlacement: LinkProps['iconPlacement'];
42
81
  href?: string;
43
82
  target?: string;
44
83
  rel?: string;
45
84
  isBold: boolean;
46
85
  isStandalone: boolean;
47
- render(): TemplateResult<1>;
86
+ hasVisited: boolean;
87
+ type: LinkProps['type'];
88
+ aria: AriaProps;
89
+ /**
90
+ * Renders the link content.
91
+ *
92
+ * @private
93
+ */
94
+ private renderContent;
95
+ /**
96
+ * Renders the link as a button element.
97
+ *
98
+ * @private
99
+ */
100
+ private renderButton;
101
+ /**
102
+ * Renders the link as an anchor element.
103
+ *
104
+ * @private
105
+ */
106
+ private renderAnchor;
107
+ render(): TemplateResult;
48
108
  static styles: CSSResult;
49
109
  }
50
110
 
51
111
  export declare const sizes: readonly ["small", "medium"];
52
112
 
113
+ export declare const tags: readonly ["a", "button"];
114
+
115
+ export declare const underlineTypes: readonly ["default", "reversed"];
116
+
53
117
  export declare const variants: readonly ["default", "high-visibility", "inverse"];
54
118
 
55
119
  export { }