@justeattakeaway/pie-link 0.2.0 → 0.3.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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@justeattakeaway/pie-link",
3
3
  "description": "PIE Design System Link built using Web Components",
4
- "version": "0.2.0",
4
+ "version": "0.3.0",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
7
  "module": "dist/index.js",
package/src/defs.ts CHANGED
@@ -1,15 +1,22 @@
1
1
  export const variants = ['default', 'high-visibility', 'inverse'] as const;
2
2
  export const sizes = ['small', 'medium'] as const;
3
+ export const iconPlacements = ['leading', 'trailing'] as const;
4
+ export const tags = ['a', 'button'] as const;
5
+ export const buttonTypes = ['submit', 'button', 'reset', 'menu'] as const;
3
6
 
4
7
  export interface LinkProps {
8
+ /**
9
+ * What HTML element the link should be such as a or button.
10
+ */
11
+ tag: typeof tags[number];
5
12
  /**
6
13
  * What style variant the link should be such as default, high-visibility or inverse.
7
14
  */
8
- variant?: typeof variants[number];
15
+ variant: typeof variants[number];
9
16
  /**
10
17
  * What size the link should be.
11
18
  */
12
- size?: typeof sizes[number];
19
+ size: typeof sizes[number];
13
20
  /**
14
21
  * The URL that the hyperlink should point to
15
22
  */
@@ -25,9 +32,17 @@ export interface LinkProps {
25
32
  /**
26
33
  * When true, the link text will be bold.
27
34
  */
28
- isBold?: boolean;
35
+ isBold: boolean;
29
36
  /**
30
37
  * When true, the link will be treated as a block box
31
38
  */
32
- isStandalone?: boolean;
39
+ isStandalone: boolean;
40
+ /**
41
+ * The placement of the icon slot, if provided, such as leading or trailing
42
+ */
43
+ iconPlacement?: typeof iconPlacements[number];
44
+ /**
45
+ * What type attribute should be applied if the tag is set to button. For example submit, button or menu.
46
+ */
47
+ type?: typeof buttonTypes[number];
33
48
  }
package/src/index.ts CHANGED
@@ -1,16 +1,27 @@
1
- import { LitElement, html, unsafeCSS } from 'lit';
1
+ import { LitElement, unsafeCSS, nothing } from 'lit';
2
+ import { html, unsafeStatic } from 'lit/static-html.js';
2
3
  import { property } from 'lit/decorators.js';
3
- import { ifDefined } from 'lit/directives/if-defined.js';
4
4
  import { validPropertyValues } from '@justeattakeaway/pie-webc-core';
5
5
  import styles from './link.scss?inline';
6
- import { LinkProps, variants, sizes } from './defs';
6
+ import {
7
+ LinkProps, variants, sizes, iconPlacements, tags, buttonTypes,
8
+ } from './defs';
7
9
 
8
10
  // Valid values available to consumers
9
11
  export * from './defs';
10
12
 
11
13
  const componentSelector = 'pie-link';
12
14
 
15
+ /**
16
+ * @slot icon - The icon slot
17
+ * @slot - Default slot
18
+ */
19
+
13
20
  export class PieLink extends LitElement implements LinkProps {
21
+ @property()
22
+ @validPropertyValues(componentSelector, tags, 'a')
23
+ public tag: LinkProps['tag'] = 'a';
24
+
14
25
  @property({ type: String })
15
26
  @validPropertyValues(componentSelector, variants, 'default')
16
27
  public variant: LinkProps['variant'] = 'default';
@@ -19,6 +30,10 @@ export class PieLink extends LitElement implements LinkProps {
19
30
  @validPropertyValues(componentSelector, sizes, 'medium')
20
31
  public size: LinkProps['size'] = 'medium';
21
32
 
33
+ @property({ type: String })
34
+ @validPropertyValues(componentSelector, iconPlacements, 'leading')
35
+ public iconPlacement: LinkProps['iconPlacement'] = 'leading';
36
+
22
37
  @property({ type: String, reflect: true })
23
38
  public href?: string;
24
39
 
@@ -34,24 +49,46 @@ export class PieLink extends LitElement implements LinkProps {
34
49
  @property({ type: Boolean })
35
50
  public isStandalone = false;
36
51
 
52
+ @property()
53
+ @validPropertyValues(componentSelector, buttonTypes, 'submit')
54
+ public type: LinkProps['type'] = 'submit';
55
+
37
56
  render () {
38
57
  const {
39
- variant, size, href, target, rel, isBold, isStandalone,
58
+ tag,
59
+ variant,
60
+ size,
61
+ iconPlacement,
62
+ isBold,
63
+ isStandalone,
64
+ href,
65
+ target,
66
+ rel,
67
+ type,
40
68
  } = this;
41
69
 
70
+ const element = unsafeStatic(tag);
71
+ const isButton = tag === 'button';
72
+
42
73
  return html`
43
- <a
74
+ <${element}
44
75
  data-test-id="pie-link"
45
76
  class="c-link"
77
+ tag="${tag}"
46
78
  variant=${variant}
47
79
  size=${size}
48
- href=${ifDefined(href)}
49
- target=${ifDefined(target)}
50
- rel=${ifDefined(rel)}
51
80
  ?isBold=${isBold}
52
- ?isStandalone=${isStandalone}>
53
- <slot></slot>
54
- </a>`;
81
+ ?isStandalone=${isStandalone}
82
+ href=${!isButton && href ? href : nothing}
83
+ target=${!isButton && target ? target : nothing}
84
+ rel=${!isButton && rel ? rel : nothing}
85
+ type=${isButton && type ? type : nothing}>
86
+ <span class="c-link-content">
87
+ ${iconPlacement === 'leading' ? html`<slot name="icon"></slot>` : nothing}
88
+ <slot></slot>
89
+ ${iconPlacement === 'trailing' ? html`<slot name="icon"></slot>` : nothing}
90
+ </span>
91
+ </${element}>`;
55
92
  }
56
93
 
57
94
  // Renders a `CSSResult` generated from SCSS by Vite
package/src/link.scss CHANGED
@@ -7,7 +7,9 @@
7
7
  --link-font-weight: var(--dt-font-weight-regular);
8
8
  --link-text-color: var(--dt-color-content-link);
9
9
  --link-text-decoration: var(--dt-font-style-underline);
10
+ --link-icon-size: 16px;
10
11
 
12
+ display: inline-block;
11
13
  font-family: var(--link-font-family);
12
14
  font-size: var(--link-font-size);
13
15
  line-height: var(--link-line-height);
@@ -16,6 +18,18 @@
16
18
  text-decoration: var(--link-text-decoration);
17
19
  cursor: pointer;
18
20
 
21
+ &[tag='a'] {
22
+ /* Same as default styles */
23
+ }
24
+
25
+ &[tag='button'] {
26
+ outline: none;
27
+ border: none;
28
+ user-select: none;
29
+ background: transparent;
30
+ padding: 0;
31
+ }
32
+
19
33
  &[variant='default'] {
20
34
  /* Same as default styles */
21
35
  }
@@ -45,3 +59,16 @@
45
59
  display: block;
46
60
  }
47
61
  }
62
+
63
+ .c-link-content {
64
+ display: flex;
65
+ gap: var(--dt-spacing-a);
66
+ }
67
+
68
+ ::slotted(.c-pieIcon),
69
+ ::slotted(svg) {
70
+ display: inline-flex;
71
+ margin-block-start: var(--dt-spacing-a);
72
+ height: var(--link-icon-size);
73
+ width: var(--link-icon-size);
74
+ }