@uh-design-system/component-library 0.4.0 → 0.4.2

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.
Files changed (151) hide show
  1. package/dist/cjs/component-library.cjs.js +3 -3
  2. package/dist/cjs/controlUtils-041de0fd.js +7 -0
  3. package/dist/cjs/ds-accordion_3.cjs.entry.js +27 -20
  4. package/dist/cjs/ds-checkbox-group.cjs.entry.js +156 -0
  5. package/dist/cjs/ds-checkbox.cjs.entry.js +153 -0
  6. package/dist/cjs/ds-input-validity.cjs.entry.js +38 -0
  7. package/dist/cjs/ds-link-with-arrow.cjs.entry.js +8 -7
  8. package/dist/cjs/ds-link.cjs.entry.js +11 -8
  9. package/dist/cjs/ds-text-input.cjs.entry.js +30 -6
  10. package/dist/cjs/ds-visually-hidden.cjs.entry.js +2 -2
  11. package/dist/cjs/{index-bfa0f441.js → index-b2bddcf4.js} +326 -125
  12. package/dist/cjs/{linkUtils-695da37c.js → linkUtils-e911e899.js} +10 -0
  13. package/dist/cjs/loader.cjs.js +2 -2
  14. package/dist/cjs/utils-c9113835.js +18 -0
  15. package/dist/collection/accessibility/accessibility.stories.js +10 -0
  16. package/dist/collection/accessibility/stories/ariaLabel.stories.js +19 -0
  17. package/dist/collection/accessibility/stories/ariaLabelledBy.stories.js +49 -0
  18. package/dist/collection/accessibility/stories/naming.stories.js +39 -0
  19. package/dist/collection/collection-manifest.json +4 -1
  20. package/dist/collection/components/00-foundations/icons/categories/information.js +4 -0
  21. package/dist/collection/components/00-foundations/typography/stories/typography.stories.js +133 -48
  22. package/dist/collection/components/01-base-components/ds-accordion/ds-accordion.css +1 -1
  23. package/dist/collection/components/01-base-components/ds-accordion/ds-accordion.js +6 -6
  24. package/dist/collection/components/01-base-components/ds-button/ds-button.css +9 -9
  25. package/dist/collection/components/01-base-components/ds-button/ds-button.js +2 -2
  26. package/dist/collection/components/01-base-components/ds-button/stories/ds-button.examples.stories.js +53 -12
  27. package/dist/collection/components/01-base-components/ds-button/stories/ds-button.features.stories.js +88 -55
  28. package/dist/collection/components/01-base-components/ds-button/stories/ds-button.stories.js +1 -1
  29. package/dist/collection/components/01-base-components/ds-checkbox/ds-checkbox.css +144 -0
  30. package/dist/collection/components/01-base-components/ds-checkbox/ds-checkbox.js +429 -0
  31. package/dist/collection/components/01-base-components/ds-checkbox/stories/ds-checkbox.features.stories.js +115 -0
  32. package/dist/collection/components/01-base-components/ds-checkbox/stories/ds-checkbox.stories.js +37 -0
  33. package/dist/collection/components/01-base-components/ds-checkbox-group/ds-checkbox-group.css +38 -0
  34. package/dist/collection/components/01-base-components/ds-checkbox-group/ds-checkbox-group.js +445 -0
  35. package/dist/collection/components/01-base-components/ds-checkbox-group/stories/ds-checkbox-group.features.stories.js +89 -0
  36. package/dist/collection/components/01-base-components/ds-checkbox-group/stories/ds-checkbox-group.stories.js +47 -0
  37. package/dist/collection/components/01-base-components/ds-icon/ds-icon.js +1 -1
  38. package/dist/collection/components/01-base-components/ds-icon/{ds-icon.stories.js → stories/ds-icon.stories.js} +12 -2
  39. package/dist/collection/components/01-base-components/ds-input-validity/ds-input-validity.css +31 -0
  40. package/dist/collection/components/01-base-components/ds-input-validity/ds-input-validity.js +114 -0
  41. package/dist/collection/components/01-base-components/ds-input-validity/stories/ds-input-validity.features.stories.js +17 -0
  42. package/dist/collection/components/01-base-components/ds-input-validity/stories/ds-input-validity.stories.js +21 -0
  43. package/dist/collection/components/01-base-components/ds-link/ds-link.css +19 -139
  44. package/dist/collection/components/01-base-components/ds-link/ds-link.js +68 -8
  45. package/dist/collection/components/01-base-components/ds-link/stories/ds-link.examples.stories.js +6 -2
  46. package/dist/collection/components/01-base-components/ds-link/stories/ds-link.features.stories.js +2 -2
  47. package/dist/collection/components/01-base-components/ds-link/stories/ds-link.stories.js +15 -4
  48. package/dist/collection/components/01-base-components/ds-link-with-arrow/ds-link-with-arrow.css +1 -139
  49. package/dist/collection/components/01-base-components/ds-link-with-arrow/ds-link-with-arrow.js +25 -5
  50. package/dist/collection/components/01-base-components/ds-link-with-arrow/stories/{ds-arrow-link.examples.stories.js → ds-link-with-arrow.examples.stories.js} +26 -3
  51. package/dist/collection/components/01-base-components/ds-link-with-arrow/stories/{ds-arrow-link.stories.js → ds-link-with-arrow.stories.js} +5 -4
  52. package/dist/collection/components/01-base-components/ds-text-input/ds-text-input.css +8 -11
  53. package/dist/collection/components/01-base-components/ds-text-input/ds-text-input.js +30 -5
  54. package/dist/collection/components/01-base-components/ds-text-input/stories/ds-text-input.examples.stories.js +29 -7
  55. package/dist/collection/components/01-base-components/ds-text-input/utils.js +0 -6
  56. package/dist/collection/components/01-base-components/ds-visually-hidden/ds-visually-hidden.js +1 -1
  57. package/dist/collection/utils/controls/controlUtils.js +2 -0
  58. package/dist/collection/utils/link/linkUtils.js +9 -0
  59. package/dist/collection/utils/typography/typographyUtils.js +39 -0
  60. package/dist/collection/utils/utils.js +24 -6
  61. package/dist/component-library/component-library.css +1 -1
  62. package/dist/component-library/component-library.esm.js +1 -1
  63. package/dist/component-library/controlUtils-9ca4087b.js +1 -0
  64. package/dist/component-library/ds-accordion_3.entry.js +1 -1
  65. package/dist/component-library/ds-checkbox-group.entry.js +1 -0
  66. package/dist/component-library/ds-checkbox.entry.js +1 -0
  67. package/dist/component-library/ds-input-validity.entry.js +1 -0
  68. package/dist/component-library/ds-link-with-arrow.entry.js +1 -1
  69. package/dist/component-library/ds-link.entry.js +1 -1
  70. package/dist/component-library/ds-text-input.entry.js +1 -1
  71. package/dist/component-library/ds-visually-hidden.entry.js +1 -1
  72. package/dist/component-library/index-50783b0c.js +2 -0
  73. package/dist/component-library/{linkUtils-3d1b28cf.js → linkUtils-fe63ff72.js} +1 -1
  74. package/dist/component-library/utils-b5843ae1.js +1 -0
  75. package/dist/components/attributes.js +1 -80
  76. package/dist/components/controlUtils.js +4 -0
  77. package/dist/components/ds-accordion.js +8 -8
  78. package/dist/components/ds-button2.js +4 -3
  79. package/dist/components/ds-checkbox-group.d.ts +11 -0
  80. package/dist/components/ds-checkbox-group.js +206 -0
  81. package/dist/components/ds-checkbox.d.ts +11 -0
  82. package/dist/components/ds-checkbox.js +6 -0
  83. package/dist/components/ds-checkbox2.js +185 -0
  84. package/dist/components/ds-icon2.js +24 -4
  85. package/dist/components/ds-input-validity.d.ts +11 -0
  86. package/dist/components/ds-input-validity.js +6 -0
  87. package/dist/components/ds-input-validity2.js +59 -0
  88. package/dist/components/ds-link-with-arrow.js +10 -8
  89. package/dist/components/ds-link.js +15 -9
  90. package/dist/components/ds-text-input.js +30 -7
  91. package/dist/components/ds-visually-hidden2.js +1 -1
  92. package/dist/components/index2.js +298 -130
  93. package/dist/components/index3.js +80 -0
  94. package/dist/components/linkUtils.js +10 -1
  95. package/dist/esm/component-library.js +4 -4
  96. package/dist/esm/controlUtils-9ca4087b.js +4 -0
  97. package/dist/esm/ds-accordion_3.entry.js +25 -18
  98. package/dist/esm/ds-checkbox-group.entry.js +152 -0
  99. package/dist/esm/ds-checkbox.entry.js +149 -0
  100. package/dist/esm/ds-input-validity.entry.js +34 -0
  101. package/dist/esm/ds-link-with-arrow.entry.js +8 -7
  102. package/dist/esm/ds-link.entry.js +11 -8
  103. package/dist/esm/ds-text-input.entry.js +30 -6
  104. package/dist/esm/ds-visually-hidden.entry.js +2 -2
  105. package/dist/esm/{index-42701395.js → index-50783b0c.js} +326 -126
  106. package/dist/esm/{linkUtils-3d1b28cf.js → linkUtils-fe63ff72.js} +10 -1
  107. package/dist/esm/loader.js +3 -3
  108. package/dist/esm/utils-b5843ae1.js +15 -0
  109. package/dist/types/accessibility/accessibility.stories.d.ts +3 -0
  110. package/dist/types/accessibility/stories/ariaLabel.stories.d.ts +5 -0
  111. package/dist/types/accessibility/stories/ariaLabelledBy.stories.d.ts +4 -0
  112. package/dist/types/accessibility/stories/naming.stories.d.ts +4 -0
  113. package/dist/types/components/00-foundations/typography/stories/typography.stories.d.ts +1 -0
  114. package/dist/types/components/01-base-components/ds-button/stories/ds-button.examples.stories.d.ts +2 -0
  115. package/dist/types/components/01-base-components/ds-button/stories/ds-button.features.stories.d.ts +4 -1
  116. package/dist/types/components/01-base-components/ds-checkbox/ds-checkbox.d.ts +49 -0
  117. package/dist/types/components/01-base-components/ds-checkbox/stories/ds-checkbox.features.stories.d.ts +13 -0
  118. package/dist/types/components/01-base-components/ds-checkbox/stories/ds-checkbox.stories.d.ts +7 -0
  119. package/dist/types/components/01-base-components/ds-checkbox-group/ds-checkbox-group.d.ts +56 -0
  120. package/dist/types/components/01-base-components/ds-checkbox-group/stories/ds-checkbox-group.features.stories.d.ts +11 -0
  121. package/dist/types/components/01-base-components/ds-checkbox-group/stories/ds-checkbox-group.stories.d.ts +7 -0
  122. package/dist/types/components/01-base-components/ds-icon/{ds-icon.stories.d.ts → stories/ds-icon.stories.d.ts} +2 -1
  123. package/dist/types/components/01-base-components/ds-input-validity/ds-input-validity.d.ts +12 -0
  124. package/dist/types/components/01-base-components/ds-input-validity/stories/ds-input-validity.features.stories.d.ts +7 -0
  125. package/dist/types/components/01-base-components/ds-input-validity/stories/ds-input-validity.stories.d.ts +7 -0
  126. package/dist/types/components/01-base-components/ds-link/ds-link.d.ts +4 -1
  127. package/dist/types/components/01-base-components/ds-link-with-arrow/ds-link-with-arrow.d.ts +1 -0
  128. package/dist/types/components/01-base-components/ds-text-input/ds-text-input.d.ts +5 -0
  129. package/dist/types/components/01-base-components/ds-text-input/utils.d.ts +0 -1
  130. package/dist/types/components.d.ts +142 -2
  131. package/dist/types/utils/controls/controlUtils.d.ts +2 -0
  132. package/dist/types/utils/link/linkUtils.d.ts +1 -0
  133. package/dist/types/utils/typography/typographyUtils.d.ts +5 -0
  134. package/dist/types/utils/utils.d.ts +10 -3
  135. package/package.json +19 -18
  136. package/dist/cjs/utils-8b73aa91.js +0 -10
  137. package/dist/collection/components/00-foundations/typography/typography.stories.js +0 -68
  138. package/dist/component-library/index-42701395.js +0 -2
  139. package/dist/component-library/utils-cca2a41a.js +0 -1
  140. package/dist/components/utils.js +0 -8
  141. package/dist/esm/utils-cca2a41a.js +0 -8
  142. package/dist/types/components/00-foundations/typography/typography.stories.d.ts +0 -7
  143. /package/dist/cjs/{attributes-f7831329.js → attributes-5f5b58be.js} +0 -0
  144. /package/dist/collection/components/01-base-components/ds-link-with-arrow/stories/{ds-arrow-link.features.stories.js → ds-link-with-arrow.features.stories.js} +0 -0
  145. /package/dist/collection/utils/{attributes.js → attributes/attributes.js} +0 -0
  146. /package/dist/component-library/{attributes-9419ac39.js → attributes-7d09be1b.js} +0 -0
  147. /package/dist/esm/{attributes-9419ac39.js → attributes-7d09be1b.js} +0 -0
  148. /package/dist/types/components/01-base-components/ds-link-with-arrow/stories/{ds-arrow-link.examples.stories.d.ts → ds-link-with-arrow.examples.stories.d.ts} +0 -0
  149. /package/dist/types/components/01-base-components/ds-link-with-arrow/stories/{ds-arrow-link.features.stories.d.ts → ds-link-with-arrow.features.stories.d.ts} +0 -0
  150. /package/dist/types/components/01-base-components/ds-link-with-arrow/stories/{ds-arrow-link.stories.d.ts → ds-link-with-arrow.stories.d.ts} +0 -0
  151. /package/dist/types/utils/{attributes.d.ts → attributes/attributes.d.ts} +0 -0
@@ -6,144 +6,6 @@
6
6
  --ds-breakpoint-xLarge: 90rem;
7
7
  }
8
8
 
9
- :root {
10
- --ds-borderWidth-none: 0px;
11
- --ds-borderWidth-hairline: 1px;
12
- --ds-borderWidth-thin: 2px;
13
- --ds-borderWidth-thick: 4px;
14
- --ds-borderWidth-xThick: 8px;
15
- --ds-borderRadius-none: 0px;
16
- }
17
-
18
- :root {
19
- --ds-breakpoint-xSmall: 20rem;
20
- --ds-breakpoint-small: 30rem;
21
- --ds-breakpoint-medium: 60rem;
22
- --ds-breakpoint-large: 75rem;
23
- --ds-breakpoint-xLarge: 90rem;
24
- }
25
-
26
- :root {
27
- --ds-fontFamily-heading: "Open Sans", sans-serif;
28
- --ds-fontFamily-body: "Open Sans", sans-serif;
29
- --ds-fontSize-12: 12px; /* 0.75rem */
30
- --ds-fontSize-14: 14px; /* 0.875rem */
31
- --ds-fontSize-16: 16px; /* 1rem */
32
- --ds-fontSize-18: 18px; /* 1.125rem */
33
- --ds-fontSize-20: 20px; /* 1.25rem */
34
- --ds-fontSize-22: 22px; /* 1.375rem */
35
- --ds-fontSize-24: 24px; /* 1.5rem */
36
- --ds-fontSize-26: 26px; /* 1.625rem */
37
- --ds-fontSize-30: 30px; /* 1.875rem */
38
- --ds-fontSize-32: 32px; /* 2rem */
39
- --ds-fontSize-36: 36px; /* 2.25rem */
40
- --ds-fontSize-40: 40px; /* 2.5rem */
41
- --ds-fontSize-48: 48px; /* 3rem */
42
- --ds-fontSize-56: 56px; /* 3.5rem */
43
- --ds-fontSize-64: 64px; /* 4rem */
44
- --ds-fontWeight-regular: 400;
45
- --ds-fontWeight-semibold: 600;
46
- --ds-fontWeight-semiboldPlus: 650;
47
- --ds-fontWeight-bold: 700;
48
- --ds-letterSpacing-xTight: -2;
49
- --ds-letterSpacing-tight: -1.4;
50
- --ds-letterSpacing-normal: -0.4;
51
- --ds-letterSpacing-wide: 0;
52
- --ds-letterSpacing-xWide: 0.4;
53
- --ds-lineHeight-small: 1;
54
- --ds-lineHeight-medium: 1.2;
55
- --ds-lineHeight-large: 1.5;
56
- --ds-lineHeight-xLarge: 1.75;
57
- --ds-fontWidth-normal: 100;
58
- --ds-fontWidth-condense: 90;
59
- --ds-number-style: proportional-figures; /* Varying spacing */
60
- }
61
-
62
- @supports (font-variation-settings: normal) {
63
- :root {
64
- --ds-fontFamily-heading: "Open Sans Variable", sans-serif;
65
- --ds-fontFamily-body: "Open Sans Variable", sans-serif;
66
- }
67
- }
68
- :root {
69
- --ds-breakpoint-xSmall: 20rem;
70
- --ds-breakpoint-small: 30rem;
71
- --ds-breakpoint-medium: 60rem;
72
- --ds-breakpoint-large: 75rem;
73
- --ds-breakpoint-xLarge: 90rem;
74
- }
75
-
76
- /* Body text styles */
77
- .ds-bodyText--2xLarge {
78
- color: var(--ds-textColor-default);
79
- font-family: var(--ds-fontFamily-body);
80
- font-size: var(--ds-fontSize-20);
81
- font-weight: var(--ds-fontWeight-regular);
82
- letter-spacing: var(--ds-letterSpacing-wide);
83
- line-height: var(--ds-lineHeight-large);
84
- }
85
- @media (min-width: 30rem) {
86
- .ds-bodyText--2xLarge {
87
- font-size: var(--ds-fontSize-22);
88
- }
89
- }
90
-
91
- .ds-bodyText--xLarge {
92
- color: var(--ds-textColor-default);
93
- font-family: var(--ds-fontFamily-body);
94
- font-size: var(--ds-fontSize-18);
95
- font-weight: var(--ds-fontWeight-regular);
96
- letter-spacing: var(--ds-letterSpacing-wide);
97
- line-height: var(--ds-lineHeight-large);
98
- }
99
- @media (min-width: 30rem) {
100
- .ds-bodyText--xLarge {
101
- font-size: var(--ds-fontSize-20);
102
- }
103
- }
104
-
105
- .ds-bodyText--large {
106
- color: var(--ds-textColor-default);
107
- font-family: var(--ds-fontFamily-body);
108
- font-size: var(--ds-fontSize-16);
109
- font-weight: var(--ds-fontWeight-regular);
110
- letter-spacing: var(--ds-letterSpacing-wide);
111
- line-height: var(--ds-lineHeight-large);
112
- }
113
- @media (min-width: 30rem) {
114
- .ds-bodyText--large {
115
- font-size: var(--ds-fontSize-18);
116
- }
117
- }
118
-
119
- .ds-bodyText--medium {
120
- color: var(--ds-textColor-default);
121
- font-family: var(--ds-fontFamily-body);
122
- font-size: var(--ds-fontSize-14);
123
- font-weight: var(--ds-fontWeight-regular);
124
- letter-spacing: var(--ds-letterSpacing-wide);
125
- line-height: var(--ds-lineHeight-large);
126
- }
127
- @media (min-width: 30rem) {
128
- .ds-bodyText--medium {
129
- font-size: var(--ds-fontSize-16);
130
- }
131
- }
132
-
133
- .ds-bodyText--small {
134
- color: var(--ds-textColor-default);
135
- font-family: var(--ds-fontFamily-body);
136
- font-size: var(--ds-fontSize-12);
137
- font-weight: var(--ds-fontWeight-regular);
138
- letter-spacing: var(--ds-letterSpacing-wide);
139
- line-height: var(--ds-lineHeight-large);
140
- }
141
- @media (min-width: 30rem) {
142
- .ds-bodyText--small {
143
- font-size: var(--ds-fontSize-14);
144
- }
145
- }
146
-
147
9
  :host {
148
10
  display: inline-block;
149
11
  }
@@ -157,7 +19,7 @@
157
19
  font-size: var(--ds-fontSize-16);
158
20
  text-decoration-line: none;
159
21
  }
160
- .ds-link-with-arrow:focus-visible, .ds-link-with-arrow:focus-within {
22
+ .ds-link-with-arrow:focus-visible {
161
23
  box-shadow: 0 0 0 var(--ds-borderWidth-thin) var(--ds-borderColor-white);
162
24
  outline-color: var(--ds-borderColor-black);
163
25
  outline-offset: var(--ds-borderWidth-thin);
@@ -1,8 +1,8 @@
1
1
  import { h } from "@stencil/core";
2
2
  import classNames from "classnames";
3
- import { inheritAriaAttributes } from "../../../utils/attributes";
4
- import { idGenerator } from "../ds-text-input/utils";
5
- import { opensInNewTab, visuallyHiddenAssistiveText } from "../../../utils/link/linkUtils";
3
+ import { inheritAriaAttributes } from "../../../utils/attributes/attributes";
4
+ import { getAriaLabel, opensInNewTab, visuallyHiddenAssistiveText } from "../../../utils/link/linkUtils";
5
+ import { idGenerator } from "../../../utils/utils";
6
6
  const visuallyHiddenAssistiveTextIdGenerator = idGenerator('visually-hidden-assistive-text');
7
7
  export class DsLinkWithArrow {
8
8
  inheritedAttributes = {};
@@ -15,8 +15,9 @@ export class DsLinkWithArrow {
15
15
  href;
16
16
  target;
17
17
  language;
18
+ linkAriaLabel;
18
19
  componentWillLoad() {
19
- this.inheritedAttributes = inheritAriaAttributes(this.el);
20
+ this.inheritedAttributes = inheritAriaAttributes(this.el, ['aria-label']);
20
21
  if (opensInNewTab(this.target)) {
21
22
  this.icon = 'arrow_outward';
22
23
  this.rel = 'noopener noreferrer';
@@ -28,7 +29,7 @@ export class DsLinkWithArrow {
28
29
  'ds-link-with-arrow__icon--start': this.iconPosition === 'start',
29
30
  'ds-link-with-arrow__icon--end': this.iconPosition === 'end',
30
31
  });
31
- return (h("a", { key: 'aa1a1272c0323f286e590f1a366f2101410a58c3', href: this.href, class: classes, rel: this.rel, target: this.target, ...this.inheritedAttributes }, h("slot", { key: 'e348b24c8c5418cf0f33e18c5337066b6eb579a2', name: "iconStart" }, this.iconPosition === 'start' && h("ds-icon", { key: 'e523092b3dc32f936139c53e74195b927a219c0f', name: this.icon, class: iconClasses, size: "1.4em" })), this.text, h("slot", { key: '0ec9d65ee348aa75108f9d87474551b6b3c4a0bb', name: "iconStart" }, this.iconPosition === 'end' && h("ds-icon", { key: '55b5ef6cc061bea9f68d784e4e9fb0ebdac0002c', name: this.icon, class: iconClasses, size: "1.4em" })), opensInNewTab(this.target) && (h("ds-visually-hidden", { key: '8c92b801ac0a1d52e12fead3c89703d41f90fa6a', id: this.visuallyHiddenAssistiveTextId }, visuallyHiddenAssistiveText(this.language ?? document.documentElement.lang)))));
32
+ return (h("a", { key: '5f43cc989011db22bd8f547957c76289e7bbbf45', href: this.href, class: classes, rel: this.rel, target: this.target, "aria-label": getAriaLabel(this.text, this.linkAriaLabel), ...this.inheritedAttributes }, h("slot", { key: '26615467438d0ae98a8138165cf5152796f2ab00', name: "iconStart" }, this.iconPosition === 'start' && h("ds-icon", { key: 'f34a2d05ed9c991e98aaa89f547bde0c1b677115', name: this.icon, class: iconClasses, size: "1.4em" })), this.text, h("slot", { key: 'be1ccadeaca632961ed3d44d1d94a26bf35d2963', name: "iconStart" }, this.iconPosition === 'end' && h("ds-icon", { key: '7bccce249754d661d9faeddbad2f9c4d8c207cfb', name: this.icon, class: iconClasses, size: "1.4em" })), opensInNewTab(this.target) && (h("ds-visually-hidden", { key: '4e864244ee939591f435715889e2f9a240f86d36', id: this.visuallyHiddenAssistiveTextId }, visuallyHiddenAssistiveText(this.language ?? document.documentElement.lang)))));
32
33
  }
33
34
  static get is() { return "ds-link-with-arrow"; }
34
35
  static get encapsulation() { return "shadow"; }
@@ -154,6 +155,25 @@ export class DsLinkWithArrow {
154
155
  "setter": false,
155
156
  "attribute": "lang",
156
157
  "reflect": false
158
+ },
159
+ "linkAriaLabel": {
160
+ "type": "string",
161
+ "mutable": false,
162
+ "complexType": {
163
+ "original": "string",
164
+ "resolved": "string",
165
+ "references": {}
166
+ },
167
+ "required": false,
168
+ "optional": true,
169
+ "docs": {
170
+ "tags": [],
171
+ "text": ""
172
+ },
173
+ "getter": false,
174
+ "setter": false,
175
+ "attribute": "aria-label",
176
+ "reflect": false
157
177
  }
158
178
  };
159
179
  }
@@ -1,6 +1,7 @@
1
1
  import { expect } from "@storybook/test";
2
2
  import { html } from "lit";
3
3
  import { getShadowRoot } from "../../../../utils/tests/testUtils";
4
+ import { litTemplateResultToString } from "../../../../utils/utils";
4
5
  const meta = {
5
6
  title: 'Base Components/LinkWithArrow/Examples',
6
7
  component: 'ds-link-with-arrow',
@@ -24,10 +25,32 @@ export const OpenInANewTab = {
24
25
  });
25
26
  }
26
27
  };
28
+ const iconAtTheEndDOM = html `
29
+ <div class="ds-sb-icon-at-the-end">
30
+ <ds-link-with-arrow text="Link with arrow icon" href="#" icon-position="end"></ds-link-with-arrow>
31
+ </div>
32
+ `;
27
33
  export const IconAtTheEnd = {
34
+ parameters: {
35
+ docs: {
36
+ source: {
37
+ code: litTemplateResultToString(iconAtTheEndDOM),
38
+ },
39
+ },
40
+ },
28
41
  render: () => html `
29
- <div style="display: flex; background-color: #F7F7F7; justify-content: end; align-items: end; outline: 1px solid; padding: 1em 0.6em; height: 200px; width: 100%;">
30
- <ds-link-with-arrow text="Link with arrow icon" href="#" icon-position="end"></ds-link-with-arrow>
31
- </div>
42
+ <style>
43
+ .ds-sb-icon-at-the-end {
44
+ display: flex;
45
+ background-color: #f7f7f7;
46
+ justify-content: end;
47
+ align-items: end;
48
+ outline: 1px solid;
49
+ padding: 1em 0.6em;
50
+ height: 200px;
51
+ width: 100%;
52
+ }
53
+ </style>
54
+ ${iconAtTheEndDOM}
32
55
  `
33
56
  };
@@ -1,10 +1,7 @@
1
- import { getAriaAttributeArgTypes } from "../../../../utils/attributes";
1
+ import { getAriaAttributeArgTypes } from "../../../../utils/attributes/attributes";
2
2
  const anchorAriaAttributes = [
3
3
  'aria-current',
4
- 'aria-describedby',
5
4
  'aria-haspopup',
6
- 'aria-label',
7
- 'aria-labelledby'
8
5
  ];
9
6
  const anchorAriaAttributeArgTypes = getAriaAttributeArgTypes(anchorAriaAttributes);
10
7
  const meta = {
@@ -35,6 +32,10 @@ export const Playground = {
35
32
  control: 'text',
36
33
  description: 'ISO 639 language code. Known languages are: "en", "fi", "sv". When undefined will use browser\'s language.',
37
34
  },
35
+ linkAriaLabel: {
36
+ name: 'aria-label',
37
+ control: 'text',
38
+ },
38
39
  ...anchorAriaAttributeArgTypes,
39
40
  },
40
41
  };
@@ -27,16 +27,6 @@
27
27
  line-height: var(--ds-lineHeight-large);
28
28
  color: var(--ds-textColor-default);
29
29
  }
30
- .ds-input--label-container label.required::after {
31
- content: " *";
32
- color: var(--ds-textColor-secondary);
33
- }
34
- .ds-input--label-container label.optional::after {
35
- content: " (" attr(data-optional-text, "optional") ")";
36
- color: var(--ds-textColor-secondary);
37
- font-size: var(--ds-fontSize-14);
38
- font-weight: var(--ds-fontWeight-regular);
39
- }
40
30
  .ds-input--label-container small {
41
31
  font-family: var(--ds-fontFamily-body);
42
32
  font-size: var(--ds-fontSize-14);
@@ -58,7 +48,14 @@
58
48
  border-color: var(--ds-borderColor-default);
59
49
  padding-inline: var(--ds-spacing-xSmall);
60
50
  }
61
- .ds-input--container:focus-visible, .ds-input--container:focus-within {
51
+ .ds-input--container:focus-visible {
52
+ box-shadow: 0 0 0 var(--ds-borderWidth-thin) var(--ds-borderColor-white);
53
+ outline-color: var(--ds-borderColor-black);
54
+ outline-offset: var(--ds-borderWidth-thin);
55
+ outline-style: solid;
56
+ outline-width: var(--ds-borderWidth-thin);
57
+ }
58
+ .ds-input--container:focus-within {
62
59
  box-shadow: 0 0 0 var(--ds-borderWidth-thin) var(--ds-borderColor-white);
63
60
  outline-color: var(--ds-borderColor-black);
64
61
  outline-offset: var(--ds-borderWidth-thin);
@@ -1,6 +1,7 @@
1
1
  import { Fragment, h } from "@stencil/core";
2
2
  import classNames from "classnames";
3
- import { idGenerator } from "./utils";
3
+ import { idGenerator } from "../../../utils/utils";
4
+ import { getOptionalText, getRequiredText } from "../../../utils/controls/controlUtils";
4
5
  const INPUT_TYPE_ICONS_MAP = {
5
6
  search: 'search',
6
7
  };
@@ -8,6 +9,7 @@ const INPUT_TYPE_ACTION_BUTTON_ICON_MAP = {
8
9
  search: ({ clearButtonVisible }) => (clearButtonVisible ? 'cancel_fill' : ''),
9
10
  password: ({ passwordInputVisible }) => (passwordInputVisible ? 'visibility_off_fill' : 'visibility_fill'),
10
11
  };
12
+ const inputIdGenerator = idGenerator('ds-input');
11
13
  const assistiveTextIdGenerator = idGenerator('ds-assistive-text');
12
14
  const visuallyHiddenAssistiveTextIdGenerator = idGenerator('visually-hidden-assistive-text');
13
15
  const successTextIdGenerator = idGenerator('success-text');
@@ -19,9 +21,12 @@ export class DsTextInput {
19
21
  visuallyHiddenAssistiveTextId = visuallyHiddenAssistiveTextIdGenerator.next().value;
20
22
  successTextId = successTextIdGenerator.next().value;
21
23
  errorTextId = errorTextIdGenerator.next().value;
24
+ hasPrefixSlot = false;
25
+ hasSuffixSlot = false;
26
+ el;
22
27
  label;
23
28
  placeholder;
24
- dsId = 'input';
29
+ dsId = inputIdGenerator.next().value;
25
30
  name;
26
31
  disabled;
27
32
  optional;
@@ -58,6 +63,19 @@ export class DsTextInput {
58
63
  this.inputElement.focus();
59
64
  this.clearButtonVisible = false;
60
65
  }
66
+ getLabelText = () => {
67
+ if (this.required) {
68
+ return getRequiredText(this.label);
69
+ }
70
+ if (this.optional) {
71
+ return getOptionalText(this.label, this.optionalText);
72
+ }
73
+ return this.label;
74
+ };
75
+ componentWillLoad() {
76
+ this.hasPrefixSlot = !!this.el.querySelector('[slot="prefix"]');
77
+ this.hasSuffixSlot = !!this.el.querySelector('[slot="suffix"]');
78
+ }
61
79
  onActionButtonClicked = (e) => {
62
80
  e.stopPropagation();
63
81
  switch (this.type) {
@@ -77,6 +95,9 @@ export class DsTextInput {
77
95
  return (h("slot", { name: className }, text && (h("div", { class: `${className}--container` }, h("ds-icon", { name: icon }), h("small", { id: textId, class: className }, text)))));
78
96
  }
79
97
  renderPrefixContent() {
98
+ if (this.hasPrefixSlot) {
99
+ return h("slot", { name: "prefix" });
100
+ }
80
101
  if (this.prefixText) {
81
102
  return (h("slot", { name: "prefix" }, h("span", { class: "prefix" }, this.prefixText)));
82
103
  }
@@ -87,6 +108,9 @@ export class DsTextInput {
87
108
  return null;
88
109
  }
89
110
  renderSuffixContent() {
111
+ if (this.hasSuffixSlot) {
112
+ return h("slot", { name: "suffix" });
113
+ }
90
114
  if (this.suffixText) {
91
115
  return (h("slot", { name: "suffix" }, h("span", { class: "suffix" }, this.suffixText)));
92
116
  }
@@ -104,14 +128,14 @@ export class DsTextInput {
104
128
  }
105
129
  render() {
106
130
  const inputType = this.type === 'password' && this.passwordInputVisible ? 'text' : this.type;
107
- return (h(Fragment, { key: 'fe9d038685d4912e0b760bed83e21a6ae8582535' }, h("div", { key: '4c4a662fcbcbf2c9a04986ad44b018736c8ba0d7', class: "ds-input--label-container" }, h("slot", { key: '8fea3c6a05e3f5314eae43c2f2eeedc47735278a', name: "label" }, h("label", { key: '33aa9fa1ab0eba6c36b0e882d8a71000a2a2ff40', "data-optional-text": this.optionalText, class: classNames({ required: this.required, optional: this.optional }), htmlFor: this.dsId }, this.label)), h("slot", { key: '13f7adf5a85a2f2d8d5f3e7b829ff86707f75a3d', name: "help-text" }, h("small", { key: '3595ee7deb43919aeabb938a2f0cc0ce78ca181d', id: this.assistiveTextId }, this.assistiveText), h("ds-visually-hidden", { key: '001fd7a38ef2034f7e650e86d00d5a30ee217c17', id: this.visuallyHiddenAssistiveTextId }, this.hiddenAssistiveText))), h("div", { key: 'ec9f2c0d6ff40bd6c8a4618ec238e966a0756c19', onMouseDown: () => (this.inputActive = true), onMouseUp: () => (this.inputActive = false), onClick: e => this.handleInputContainerClick(e), class: classNames('ds-input--container', {
131
+ return (h(Fragment, { key: '4d3ad7cc3f0d7c6aba4bcb8e5b05d0794b614f32' }, h("div", { key: '1cad6e50d1a9c0f4214824d1ff46a8418a095790', class: "ds-input--label-container" }, h("slot", { key: '67d096bb1eecd6ac492a5dcd14bd6f9bda21eb2c', name: "label" }, h("label", { key: 'cfffb9b06f2122dd80e4ad94831ca69b71e5a0de', htmlFor: this.dsId }, this.getLabelText())), h("slot", { key: '2256dfda0cf19eae50307b9badc2a2a97d9e190b', name: "help-text" }, h("small", { key: 'b9496a9afec60a4a64a0ff66505a7572362387ac', id: this.assistiveTextId }, this.assistiveText), h("ds-visually-hidden", { key: '23026b2453728e607802aabb7760f07229edeb7c', id: this.visuallyHiddenAssistiveTextId }, this.hiddenAssistiveText))), h("div", { key: '161a4d4eed706c5fd6ba2af90029e68b1c6b95c9', onMouseDown: () => (this.inputActive = true), onMouseUp: () => (this.inputActive = false), onClick: e => this.handleInputContainerClick(e), class: classNames('ds-input--container', {
108
132
  disabled: this.disabled,
109
133
  readonly: this.readonly,
110
134
  valid: !!this.successText,
111
135
  invalid: !!this.errorText,
112
136
  focus: this.hasFocus,
113
137
  active: !!this.inputActive,
114
- }) }, this.renderPrefixContent(), h("input", { key: '1cd22b415c330cb50c4c9663f6dec3a1e99e256b', ref: e => (this.inputElement = e), id: this.dsId, name: this.name, "aria-label": this.ariaLabel, "aria-labelledby": this.ariaLabelledBy, "aria-describedby": this.ariaDescribedby ||
138
+ }) }, this.renderPrefixContent(), h("input", { key: 'a04e9ed4de86a65290206ca62efde1c27d76aa80', ref: e => (this.inputElement = e), id: this.dsId, name: this.name, "aria-label": this.ariaLabel, "aria-labelledby": this.ariaLabelledBy, "aria-describedby": this.ariaDescribedby ||
115
139
  classNames(this.assistiveTextId, this.visuallyHiddenAssistiveTextId, {
116
140
  [this.successTextId]: this.successText,
117
141
  [this.errorTextId]: this.errorText,
@@ -187,7 +211,7 @@ export class DsTextInput {
187
211
  "setter": false,
188
212
  "attribute": "id",
189
213
  "reflect": false,
190
- "defaultValue": "'input'"
214
+ "defaultValue": "inputIdGenerator.next().value as string"
191
215
  },
192
216
  "name": {
193
217
  "type": "string",
@@ -701,4 +725,5 @@ export class DsTextInput {
701
725
  }
702
726
  };
703
727
  }
728
+ static get elementRef() { return "el"; }
704
729
  }
@@ -5,10 +5,20 @@ const meta = {
5
5
  };
6
6
  export default meta;
7
7
  export const CustomWidth = {
8
- render: () => html `<div>
9
- <ds-text-input label='Smaller input' style='width: 150px; margin-bottom: 1rem'></ds-text-input>
10
- <ds-text-input label='Full width input' style='width: 100%'></ds-text-input>
11
- </div>`,
8
+ render: () => html `
9
+ <style>
10
+ .ds-sb-custom-width {
11
+ display: flex;
12
+ flex-direction: column;
13
+ gap: 1rem;
14
+ }
15
+ </style>
16
+ <div class="ds-sb-custom-width">
17
+ <ds-text-input label='Smaller input' style='width: 150px'></ds-text-input>
18
+ <ds-text-input label='Full width input' style='width: 100%'></ds-text-input>
19
+ <!You can set any custom styles to the input element>
20
+ </div>
21
+ `,
12
22
  };
13
23
  export const UsingSlots = {
14
24
  render: () => html `
@@ -16,7 +26,7 @@ export const UsingSlots = {
16
26
  <label ds-id='label' slot='label'><b>Slotted label</b></label>
17
27
  <p slot='help-text'>Lorem ipsum</p>
18
28
  <ds-icon name='archive' slot='prefix'></ds-icon>
19
- <small slot='suffix' style='margin-right: var(--spacing-2xSmall)'>Suffix</small>
29
+ <small slot='suffix'>Suffix</small>
20
30
  <div slot='error-text'>Error text slot</div>
21
31
  <div slot='success-text'>Success text slot</div>
22
32
  </ds-text-input>
@@ -24,14 +34,26 @@ export const UsingSlots = {
24
34
  };
25
35
  export const FormValidation = {
26
36
  render: () => html `
27
- <form>
37
+ <style>
38
+ .ds-sb-form-validation {
39
+ display: inline-flex;
40
+ flex-direction: column;
41
+ gap: 1rem;
42
+ }
43
+ .ds-sb-form-validation .ds-sb-form-validation__buttons {
44
+ align-self: flex-end;
45
+ }
46
+ </style>
47
+ <form class="ds-sb-form-validation">
28
48
  <ds-text-input type="number" label="Minimum value" id="min" name="min" min="5" required></ds-text-input>
29
49
  <ds-text-input type="number" label="Maximum value" id="max" name="max" min="100" required></ds-text-input>
30
50
  <ds-text-input type="email" label="Email" id="email" name="email" required></ds-text-input>
31
51
  <ds-text-input type="tel" label="Telephone" id="tel" name="tel" required></ds-text-input>
32
52
  <ds-text-input type="password" label="Password" id="password" name="password" required action-button-aria-label="password toggle"></ds-text-input>
33
53
  <ds-text-input type="url" label="Url" id="url" name="url" required></ds-text-input>
34
- <ds-button style="margin-top: 0.5rem" type="submit" value="Submit"></ds-button>
54
+ <div class="button-group ds-sb-form-validation__buttons">
55
+ <ds-button type="submit" value="Submit"></ds-button>
56
+ </div>
35
57
  </form>
36
58
  `,
37
59
  };
@@ -8,9 +8,3 @@ export const textInputTypes = [
8
8
  'url',
9
9
  'number',
10
10
  ];
11
- export function* idGenerator(id) {
12
- let currentId = 1;
13
- while (true) {
14
- yield `${id}-${currentId++}`;
15
- }
16
- }
@@ -1,7 +1,7 @@
1
1
  import { h } from "@stencil/core";
2
2
  export class DsVisuallyHidden {
3
3
  render() {
4
- return (h("slot", { key: '3a7edab043d1612c06a4eb6fedacec27216f3be3' }));
4
+ return (h("slot", { key: '4307602964aa15c8d3f4fb0f4b89188cf0a8b55e' }));
5
5
  }
6
6
  static get is() { return "ds-visually-hidden"; }
7
7
  static get encapsulation() { return "shadow"; }
@@ -0,0 +1,2 @@
1
+ export const getOptionalText = (text, optionalText) => [text, Boolean(optionalText) ? optionalText : '(optional)'].join(' ');
2
+ export const getRequiredText = (text) => [text, '*'].join(' ');
@@ -9,3 +9,12 @@ export const visuallyHiddenAssistiveText = (lang) => {
9
9
  return 'Opens in a new tab';
10
10
  }
11
11
  };
12
+ export const getAriaLabel = (text, ariaLabel) => {
13
+ if (!ariaLabel) {
14
+ return undefined;
15
+ }
16
+ if (ariaLabel.startsWith(text)) {
17
+ return ariaLabel;
18
+ }
19
+ return [text, ariaLabel].join(' ');
20
+ };
@@ -104,3 +104,42 @@ export const getCSSClasses = (prefix) => {
104
104
  }
105
105
  return classNames;
106
106
  };
107
+ const getCSSVariableValue = (value) => {
108
+ if (value.startsWith('var(--')) {
109
+ const varName = value.slice(4, -1).trim();
110
+ return getComputedStyle(document.documentElement).getPropertyValue(varName);
111
+ }
112
+ return value;
113
+ };
114
+ const extractVariablesFromRule = (rule, variables) => {
115
+ for (const style of rule.style) {
116
+ variables[style] = getCSSVariableValue(rule.style.getPropertyValue(style));
117
+ }
118
+ };
119
+ export const headingSizes = ['2xLarge', 'xLarge', 'large', 'medium', 'small', 'xSmall'];
120
+ export const getHeadingVariables = (size, isDesktop) => {
121
+ const className = `ds-heading--${size}`;
122
+ const variables = {};
123
+ for (const sheet of document.styleSheets) {
124
+ try {
125
+ const rules = sheet.cssRules;
126
+ for (const rule of rules) {
127
+ if (rule instanceof CSSStyleRule && rule.selectorText.includes(className)) {
128
+ extractVariablesFromRule(rule, variables);
129
+ }
130
+ else if (isDesktop && rule instanceof CSSMediaRule && rule.conditionText.includes('(min-width: 30rem)')) {
131
+ const mediaRules = rule.cssRules;
132
+ for (const mediaRule of mediaRules) {
133
+ if (mediaRule instanceof CSSStyleRule && mediaRule.selectorText.includes(className)) {
134
+ extractVariablesFromRule(mediaRule, variables);
135
+ }
136
+ }
137
+ }
138
+ }
139
+ }
140
+ catch (e) {
141
+ console.warn('Unable to access stylesheet:', sheet.href, e);
142
+ }
143
+ }
144
+ return variables;
145
+ };
@@ -1,4 +1,4 @@
1
- export function generateLoremIpsum({ paragraphs = 1, wordsPerParagraph = 50, startWithLorem = true, consistent = false } = {}) {
1
+ export const generateLoremIpsum = ({ paragraphs = 1, wordsPerParagraph = 50, startWithLorem = true, consistent = false } = {}) => {
2
2
  const loremWords = [
3
3
  'lorem', 'ipsum', 'dolor', 'sit', 'amet', 'consectetur', 'adipiscing', 'elit',
4
4
  'sed', 'do', 'eiusmod', 'tempor', 'incididunt', 'ut', 'labore', 'et', 'dolore',
@@ -17,13 +17,13 @@ export function generateLoremIpsum({ paragraphs = 1, wordsPerParagraph = 50, sta
17
17
  };
18
18
  })()
19
19
  : () => Math.floor(Math.random() * loremWords.length);
20
- function generateParagraph(length) {
20
+ const generateParagraph = (length) => {
21
21
  const words = [];
22
22
  for (let i = 0; i < length; i++) {
23
23
  words.push(loremWords[randomGenerator()]);
24
24
  }
25
25
  return words.join(' ') + '.';
26
- }
26
+ };
27
27
  const generatedText = [];
28
28
  if (startWithLorem && paragraphs > 0) {
29
29
  generatedText.push('Lorem ipsum dolor sit amet');
@@ -32,9 +32,27 @@ export function generateLoremIpsum({ paragraphs = 1, wordsPerParagraph = 50, sta
32
32
  generatedText.push(generateParagraph(wordsPerParagraph));
33
33
  }
34
34
  return generatedText.join('\n\n');
35
- }
36
- export function remToPx(remString) {
35
+ };
36
+ export const formatAs = (value, suffix) => value.endsWith(suffix) ? value : `${value}${suffix}`;
37
+ export const formatAsRem = (value) => formatAs(value, 'rem');
38
+ export const formatAsPx = (value) => formatAs(value, 'px');
39
+ export const remToPx = (remString) => {
37
40
  const rootFontSize = 16;
38
41
  const rem = parseFloat(remString);
39
- return `${rem * rootFontSize}px`;
42
+ return formatAsPx(`${rem * rootFontSize}`);
43
+ };
44
+ export const pxToRem = (pxString) => {
45
+ const rootFontSize = 16;
46
+ const px = parseFloat(pxString);
47
+ return formatAsRem(`${px / rootFontSize}`);
48
+ };
49
+ export const litTemplateResultToString = (data) => {
50
+ const { strings, values } = data;
51
+ return strings.reduce((acc, s, i) => acc + s + [...values, ''][i], '');
52
+ };
53
+ export function* idGenerator(id) {
54
+ let currentId = 1;
55
+ while (true) {
56
+ yield `${id}-${currentId++}`;
57
+ }
40
58
  }