@dsn-starter-kit/components-web 1.0.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.
Files changed (161) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +120 -0
  3. package/dist/button/Button.d.ts +50 -0
  4. package/dist/button/Button.d.ts.map +1 -0
  5. package/dist/button/Button.js +247 -0
  6. package/dist/button/Button.js.map +1 -0
  7. package/dist/button/Button.test.d.ts +2 -0
  8. package/dist/button/Button.test.d.ts.map +1 -0
  9. package/dist/button/Button.test.js +299 -0
  10. package/dist/button/Button.test.js.map +1 -0
  11. package/dist/button/button-styles.generated.d.ts +2 -0
  12. package/dist/button/button-styles.generated.d.ts.map +1 -0
  13. package/dist/button/button-styles.generated.js +4 -0
  14. package/dist/button/button-styles.generated.js.map +1 -0
  15. package/dist/button/index.d.ts +3 -0
  16. package/dist/button/index.d.ts.map +1 -0
  17. package/dist/button/index.js +2 -0
  18. package/dist/button/index.js.map +1 -0
  19. package/dist/heading/Heading.d.ts +30 -0
  20. package/dist/heading/Heading.d.ts.map +1 -0
  21. package/dist/heading/Heading.js +79 -0
  22. package/dist/heading/Heading.js.map +1 -0
  23. package/dist/heading/Heading.test.d.ts +2 -0
  24. package/dist/heading/Heading.test.d.ts.map +1 -0
  25. package/dist/heading/Heading.test.js +157 -0
  26. package/dist/heading/Heading.test.js.map +1 -0
  27. package/dist/heading/heading-styles.generated.d.ts +2 -0
  28. package/dist/heading/heading-styles.generated.d.ts.map +1 -0
  29. package/dist/heading/heading-styles.generated.js +4 -0
  30. package/dist/heading/heading-styles.generated.js.map +1 -0
  31. package/dist/heading/index.d.ts +3 -0
  32. package/dist/heading/index.d.ts.map +1 -0
  33. package/dist/heading/index.js +2 -0
  34. package/dist/heading/index.js.map +1 -0
  35. package/dist/icon/Icon.d.ts +31 -0
  36. package/dist/icon/Icon.d.ts.map +1 -0
  37. package/dist/icon/Icon.js +110 -0
  38. package/dist/icon/Icon.js.map +1 -0
  39. package/dist/icon/Icon.test.d.ts +2 -0
  40. package/dist/icon/Icon.test.d.ts.map +1 -0
  41. package/dist/icon/Icon.test.js +193 -0
  42. package/dist/icon/Icon.test.js.map +1 -0
  43. package/dist/icon/icon-paths.generated.d.ts +2 -0
  44. package/dist/icon/icon-paths.generated.d.ts.map +1 -0
  45. package/dist/icon/icon-paths.generated.js +56 -0
  46. package/dist/icon/icon-paths.generated.js.map +1 -0
  47. package/dist/icon/icon-styles.generated.d.ts +2 -0
  48. package/dist/icon/icon-styles.generated.d.ts.map +1 -0
  49. package/dist/icon/icon-styles.generated.js +4 -0
  50. package/dist/icon/icon-styles.generated.js.map +1 -0
  51. package/dist/icon/index.d.ts +3 -0
  52. package/dist/icon/index.d.ts.map +1 -0
  53. package/dist/icon/index.js +2 -0
  54. package/dist/icon/index.js.map +1 -0
  55. package/dist/index.d.ts +52 -0
  56. package/dist/index.d.ts.map +1 -0
  57. package/dist/index.js +71 -0
  58. package/dist/index.js.map +1 -0
  59. package/dist/link/Link.d.ts +52 -0
  60. package/dist/link/Link.d.ts.map +1 -0
  61. package/dist/link/Link.js +260 -0
  62. package/dist/link/Link.js.map +1 -0
  63. package/dist/link/Link.test.d.ts +2 -0
  64. package/dist/link/Link.test.d.ts.map +1 -0
  65. package/dist/link/Link.test.js +256 -0
  66. package/dist/link/Link.test.js.map +1 -0
  67. package/dist/link/index.d.ts +3 -0
  68. package/dist/link/index.d.ts.map +1 -0
  69. package/dist/link/index.js +2 -0
  70. package/dist/link/index.js.map +1 -0
  71. package/dist/link/link-styles.generated.d.ts +2 -0
  72. package/dist/link/link-styles.generated.d.ts.map +1 -0
  73. package/dist/link/link-styles.generated.js +4 -0
  74. package/dist/link/link-styles.generated.js.map +1 -0
  75. package/dist/ordered-list/OrderedList.d.ts +32 -0
  76. package/dist/ordered-list/OrderedList.d.ts.map +1 -0
  77. package/dist/ordered-list/OrderedList.js +72 -0
  78. package/dist/ordered-list/OrderedList.js.map +1 -0
  79. package/dist/ordered-list/OrderedList.test.d.ts +2 -0
  80. package/dist/ordered-list/OrderedList.test.d.ts.map +1 -0
  81. package/dist/ordered-list/OrderedList.test.js +82 -0
  82. package/dist/ordered-list/OrderedList.test.js.map +1 -0
  83. package/dist/ordered-list/index.d.ts +2 -0
  84. package/dist/ordered-list/index.d.ts.map +1 -0
  85. package/dist/ordered-list/index.js +2 -0
  86. package/dist/ordered-list/index.js.map +1 -0
  87. package/dist/ordered-list/ordered-list-styles.generated.d.ts +2 -0
  88. package/dist/ordered-list/ordered-list-styles.generated.d.ts.map +1 -0
  89. package/dist/ordered-list/ordered-list-styles.generated.js +4 -0
  90. package/dist/ordered-list/ordered-list-styles.generated.js.map +1 -0
  91. package/dist/paragraph/Paragraph.d.ts +26 -0
  92. package/dist/paragraph/Paragraph.d.ts.map +1 -0
  93. package/dist/paragraph/Paragraph.js +60 -0
  94. package/dist/paragraph/Paragraph.js.map +1 -0
  95. package/dist/paragraph/Paragraph.test.d.ts +2 -0
  96. package/dist/paragraph/Paragraph.test.d.ts.map +1 -0
  97. package/dist/paragraph/Paragraph.test.js +121 -0
  98. package/dist/paragraph/Paragraph.test.js.map +1 -0
  99. package/dist/paragraph/index.d.ts +3 -0
  100. package/dist/paragraph/index.d.ts.map +1 -0
  101. package/dist/paragraph/index.js +2 -0
  102. package/dist/paragraph/index.js.map +1 -0
  103. package/dist/paragraph/paragraph-styles.generated.d.ts +2 -0
  104. package/dist/paragraph/paragraph-styles.generated.d.ts.map +1 -0
  105. package/dist/paragraph/paragraph-styles.generated.js +4 -0
  106. package/dist/paragraph/paragraph-styles.generated.js.map +1 -0
  107. package/dist/unordered-list/UnorderedList.d.ts +22 -0
  108. package/dist/unordered-list/UnorderedList.d.ts.map +1 -0
  109. package/dist/unordered-list/UnorderedList.js +42 -0
  110. package/dist/unordered-list/UnorderedList.js.map +1 -0
  111. package/dist/unordered-list/UnorderedList.test.d.ts +2 -0
  112. package/dist/unordered-list/UnorderedList.test.d.ts.map +1 -0
  113. package/dist/unordered-list/UnorderedList.test.js +56 -0
  114. package/dist/unordered-list/UnorderedList.test.js.map +1 -0
  115. package/dist/unordered-list/index.d.ts +2 -0
  116. package/dist/unordered-list/index.d.ts.map +1 -0
  117. package/dist/unordered-list/index.js +2 -0
  118. package/dist/unordered-list/index.js.map +1 -0
  119. package/dist/unordered-list/unordered-list-styles.generated.d.ts +2 -0
  120. package/dist/unordered-list/unordered-list-styles.generated.d.ts.map +1 -0
  121. package/dist/unordered-list/unordered-list-styles.generated.js +4 -0
  122. package/dist/unordered-list/unordered-list-styles.generated.js.map +1 -0
  123. package/package.json +42 -0
  124. package/src/button/Button.test.ts +360 -0
  125. package/src/button/Button.ts +299 -0
  126. package/src/button/button-demo.html +477 -0
  127. package/src/button/button-styles.generated.ts +3 -0
  128. package/src/button/button.shadow.css +20 -0
  129. package/src/button/index.ts +2 -0
  130. package/src/heading/Heading.test.ts +186 -0
  131. package/src/heading/Heading.ts +104 -0
  132. package/src/heading/heading-styles.generated.ts +3 -0
  133. package/src/heading/heading.shadow.css +11 -0
  134. package/src/heading/index.ts +2 -0
  135. package/src/icon/Icon.test.ts +228 -0
  136. package/src/icon/Icon.ts +136 -0
  137. package/src/icon/icon-paths.generated.ts +55 -0
  138. package/src/icon/icon-styles.generated.ts +3 -0
  139. package/src/icon/icon.shadow.css +13 -0
  140. package/src/icon/index.ts +2 -0
  141. package/src/index.ts +83 -0
  142. package/src/link/Link.test.ts +309 -0
  143. package/src/link/Link.ts +284 -0
  144. package/src/link/index.ts +2 -0
  145. package/src/link/link-styles.generated.ts +3 -0
  146. package/src/link/link.shadow.css +15 -0
  147. package/src/ordered-list/OrderedList.test.ts +97 -0
  148. package/src/ordered-list/OrderedList.ts +84 -0
  149. package/src/ordered-list/index.ts +1 -0
  150. package/src/ordered-list/ordered-list-styles.generated.ts +3 -0
  151. package/src/ordered-list/ordered-list.shadow.css +11 -0
  152. package/src/paragraph/Paragraph.test.ts +143 -0
  153. package/src/paragraph/Paragraph.ts +77 -0
  154. package/src/paragraph/index.ts +2 -0
  155. package/src/paragraph/paragraph-styles.generated.ts +3 -0
  156. package/src/paragraph/paragraph.shadow.css +11 -0
  157. package/src/unordered-list/UnorderedList.test.ts +66 -0
  158. package/src/unordered-list/UnorderedList.ts +50 -0
  159. package/src/unordered-list/index.ts +1 -0
  160. package/src/unordered-list/unordered-list-styles.generated.ts +3 -0
  161. package/src/unordered-list/unordered-list.shadow.css +11 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Jeffrey Lauwers
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,120 @@
1
+ # @dsn-starter-kit/components-web
2
+
3
+ Web Components for the design system: framework-agnostic custom elements using Shadow DOM.
4
+
5
+ ## Features
6
+
7
+ - Standard Web Components (Custom Elements v1)
8
+ - Shadow DOM encapsulation
9
+ - Shares CSS with HTML/CSS components (via build script)
10
+ - Works in any framework or vanilla HTML
11
+ - TypeScript typed
12
+ - Tree-shakeable: only register the components you need
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ pnpm add @dsn-starter-kit/components-web
18
+ ```
19
+
20
+ ## Usage
21
+
22
+ Components must be explicitly registered before use. This gives you control over bundle size and tag names.
23
+
24
+ ### Register all components
25
+
26
+ For quick setup, register all components at once:
27
+
28
+ ```ts
29
+ import { defineAllComponents } from '@dsn-starter-kit/components-web';
30
+
31
+ defineAllComponents();
32
+ ```
33
+
34
+ Then use in HTML:
35
+
36
+ ```html
37
+ <dsn-button variant="strong">Save</dsn-button>
38
+ <dsn-icon name="check" size="lg"></dsn-icon>
39
+ <dsn-heading level="1">Welcome</dsn-heading>
40
+ ```
41
+
42
+ ### Register specific components (recommended)
43
+
44
+ For optimal bundle size, register only the components you need:
45
+
46
+ ```ts
47
+ import { defineButton, defineIcon } from '@dsn-starter-kit/components-web';
48
+
49
+ defineButton();
50
+ defineIcon();
51
+ ```
52
+
53
+ ### Custom tag names
54
+
55
+ Register components with your own tag names to avoid conflicts:
56
+
57
+ ```ts
58
+ import { defineButton } from '@dsn-starter-kit/components-web';
59
+
60
+ defineButton('my-button');
61
+ ```
62
+
63
+ ```html
64
+ <my-button variant="strong">Save</my-button>
65
+ ```
66
+
67
+ ### JavaScript API
68
+
69
+ Access component properties programmatically:
70
+
71
+ ```ts
72
+ const button = document.querySelector('dsn-button');
73
+
74
+ // Properties
75
+ button.variant = 'strong';
76
+ button.size = 'large';
77
+ button.loading = true;
78
+ button.disabled = true;
79
+ button.fullWidth = true;
80
+ button.iconOnly = true;
81
+ ```
82
+
83
+ ## Available Components
84
+
85
+ | Component | Default Tag | Define Function | Key Attributes |
86
+ | --------- | ----------------- | ------------------- | --------------------------------------------------------------------------- |
87
+ | Button | `<dsn-button>` | `defineButton()` | `variant`, `size`, `disabled`, `loading`, `full-width`, `icon-only`, `type` |
88
+ | Icon | `<dsn-icon>` | `defineIcon()` | `name`, `size`, `aria-label` |
89
+ | Heading | `<dsn-heading>` | `defineHeading()` | `level`, `appearance` |
90
+ | Paragraph | `<dsn-paragraph>` | `defineParagraph()` | `variant` |
91
+ | Link | `<dsn-link>` | `defineLink()` | `href`, `disabled`, `current` |
92
+
93
+ ## TypeScript Support
94
+
95
+ All components are fully typed. Import types for use in your code:
96
+
97
+ ```ts
98
+ import type {
99
+ ButtonVariant,
100
+ ButtonSize,
101
+ } from '@dsn-starter-kit/components-web';
102
+ import type { IconName, IconSize } from '@dsn-starter-kit/components-web';
103
+ import type {
104
+ HeadingLevel,
105
+ HeadingAppearance,
106
+ } from '@dsn-starter-kit/components-web';
107
+ import type { ParagraphVariant } from '@dsn-starter-kit/components-web';
108
+ ```
109
+
110
+ ## Building
111
+
112
+ The build generates Shadow DOM CSS from shared sources, then compiles TypeScript:
113
+
114
+ ```bash
115
+ pnpm --filter @dsn-starter-kit/components-web build
116
+ ```
117
+
118
+ ## License
119
+
120
+ MIT
@@ -0,0 +1,50 @@
1
+ /**
2
+ * DSN Button Web Component
3
+ *
4
+ * A custom element that provides a styled button with multiple variants and sizes.
5
+ * Uses the same CSS classes and design tokens as the HTML and React button components.
6
+ *
7
+ * @example
8
+ * ```html
9
+ * <dsn-button variant="strong" size="default">Save</dsn-button>
10
+ * <dsn-button variant="strong-negative" size="small">Delete</dsn-button>
11
+ * <dsn-button variant="default" loading>Loading...</dsn-button>
12
+ * <dsn-button variant="subtle" icon-only aria-label="Close">×</dsn-button>
13
+ * ```
14
+ */
15
+ export type ButtonVariant = 'strong' | 'strong-negative' | 'strong-positive' | 'default' | 'default-negative' | 'default-positive' | 'subtle' | 'subtle-negative' | 'subtle-positive' | 'link';
16
+ export type ButtonSize = 'small' | 'default' | 'large';
17
+ export declare class DsnButton extends HTMLElement {
18
+ static get observedAttributes(): string[];
19
+ private _button;
20
+ private _iconStartSlot;
21
+ private _loaderEl;
22
+ constructor();
23
+ connectedCallback(): void;
24
+ attributeChangedCallback(name: string, _oldValue: string | null, _newValue: string | null): void;
25
+ private _updateLoader;
26
+ private _createLoaderSvg;
27
+ private _updateClasses;
28
+ private _updateDisabled;
29
+ private _updateType;
30
+ get variant(): ButtonVariant;
31
+ set variant(value: ButtonVariant);
32
+ get size(): ButtonSize;
33
+ set size(value: ButtonSize);
34
+ get disabled(): boolean;
35
+ set disabled(value: boolean);
36
+ get loading(): boolean;
37
+ set loading(value: boolean);
38
+ get fullWidth(): boolean;
39
+ set fullWidth(value: boolean);
40
+ get iconOnly(): boolean;
41
+ set iconOnly(value: boolean);
42
+ get type(): string;
43
+ set type(value: string);
44
+ get form(): HTMLFormElement | null;
45
+ focus(options?: FocusOptions): void;
46
+ blur(): void;
47
+ click(): void;
48
+ }
49
+ export declare function defineButton(tagName?: string): void;
50
+ //# sourceMappingURL=Button.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Button.d.ts","sourceRoot":"","sources":["../../src/button/Button.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,MAAM,MAAM,aAAa,GACrB,QAAQ,GACR,iBAAiB,GACjB,iBAAiB,GACjB,SAAS,GACT,kBAAkB,GAClB,kBAAkB,GAClB,QAAQ,GACR,iBAAiB,GACjB,iBAAiB,GACjB,MAAM,CAAC;AAEX,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,SAAS,GAAG,OAAO,CAAC;AAMvD,qBAAa,SAAU,SAAQ,WAAW;IACxC,MAAM,KAAK,kBAAkB,IAAI,MAAM,EAAE,CAUxC;IAED,OAAO,CAAC,OAAO,CAAoB;IACnC,OAAO,CAAC,cAAc,CAAkB;IACxC,OAAO,CAAC,SAAS,CAA2B;;IAyB5C,iBAAiB,IAAI,IAAI;IAMzB,wBAAwB,CACtB,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,GAAG,IAAI,EACxB,SAAS,EAAE,MAAM,GAAG,IAAI,GACvB,IAAI;IAwBP,OAAO,CAAC,aAAa;IAgBrB,OAAO,CAAC,gBAAgB;IA2BxB,OAAO,CAAC,cAAc;IA0BtB,OAAO,CAAC,eAAe;IAevB,OAAO,CAAC,WAAW;IAKnB,IAAI,OAAO,IAAI,aAAa,CAE3B;IAED,IAAI,OAAO,CAAC,KAAK,EAAE,aAAa,EAE/B;IAGD,IAAI,IAAI,IAAI,UAAU,CAErB;IAED,IAAI,IAAI,CAAC,KAAK,EAAE,UAAU,EAEzB;IAGD,IAAI,QAAQ,IAAI,OAAO,CAEtB;IAED,IAAI,QAAQ,CAAC,KAAK,EAAE,OAAO,EAM1B;IAGD,IAAI,OAAO,IAAI,OAAO,CAErB;IAED,IAAI,OAAO,CAAC,KAAK,EAAE,OAAO,EAMzB;IAGD,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED,IAAI,SAAS,CAAC,KAAK,EAAE,OAAO,EAM3B;IAGD,IAAI,QAAQ,IAAI,OAAO,CAEtB;IAED,IAAI,QAAQ,CAAC,KAAK,EAAE,OAAO,EAM1B;IAGD,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,IAAI,IAAI,CAAC,KAAK,EAAE,MAAM,EAErB;IAGD,IAAI,IAAI,IAAI,eAAe,GAAG,IAAI,CAEjC;IAGD,KAAK,CAAC,OAAO,CAAC,EAAE,YAAY,GAAG,IAAI;IAInC,IAAI,IAAI,IAAI;IAIZ,KAAK,IAAI,IAAI;CAGd;AAGD,wBAAgB,YAAY,CAAC,OAAO,SAAe,GAAG,IAAI,CAIzD"}
@@ -0,0 +1,247 @@
1
+ /**
2
+ * DSN Button Web Component
3
+ *
4
+ * A custom element that provides a styled button with multiple variants and sizes.
5
+ * Uses the same CSS classes and design tokens as the HTML and React button components.
6
+ *
7
+ * @example
8
+ * ```html
9
+ * <dsn-button variant="strong" size="default">Save</dsn-button>
10
+ * <dsn-button variant="strong-negative" size="small">Delete</dsn-button>
11
+ * <dsn-button variant="default" loading>Loading...</dsn-button>
12
+ * <dsn-button variant="subtle" icon-only aria-label="Close">×</dsn-button>
13
+ * ```
14
+ */
15
+ // Auto-generated CSS from shared source — run `node scripts/build-css.js` to regenerate
16
+ import { buttonStyles } from './button-styles.generated';
17
+ import { iconPaths } from '../icon/icon-paths.generated';
18
+ export class DsnButton extends HTMLElement {
19
+ static get observedAttributes() {
20
+ return [
21
+ 'variant',
22
+ 'size',
23
+ 'disabled',
24
+ 'loading',
25
+ 'full-width',
26
+ 'icon-only',
27
+ 'type',
28
+ ];
29
+ }
30
+ constructor() {
31
+ super();
32
+ this._loaderEl = null;
33
+ this.attachShadow({ mode: 'open' });
34
+ // Create the internal button element
35
+ this._button = document.createElement('button');
36
+ this._button.setAttribute('type', 'button');
37
+ this._iconStartSlot = document.createElement('slot');
38
+ this._iconStartSlot.setAttribute('name', 'icon-start');
39
+ this._button.appendChild(this._iconStartSlot);
40
+ this._button.appendChild(document.createElement('slot'));
41
+ const iconEndSlot = document.createElement('slot');
42
+ iconEndSlot.setAttribute('name', 'icon-end');
43
+ this._button.appendChild(iconEndSlot);
44
+ // Create style element with embedded CSS
45
+ const style = document.createElement('style');
46
+ style.textContent = buttonStyles;
47
+ this.shadowRoot.appendChild(style);
48
+ this.shadowRoot.appendChild(this._button);
49
+ }
50
+ connectedCallback() {
51
+ this._updateClasses();
52
+ this._updateDisabled();
53
+ this._updateType();
54
+ }
55
+ attributeChangedCallback(name, _oldValue, _newValue) {
56
+ switch (name) {
57
+ case 'variant':
58
+ case 'size':
59
+ case 'loading':
60
+ case 'full-width':
61
+ case 'icon-only':
62
+ this._updateClasses();
63
+ break;
64
+ case 'disabled':
65
+ this._updateDisabled();
66
+ break;
67
+ case 'type':
68
+ this._updateType();
69
+ break;
70
+ }
71
+ // Loading affects classes, disabled state, and loader icon
72
+ if (name === 'loading') {
73
+ this._updateDisabled();
74
+ this._updateLoader();
75
+ }
76
+ }
77
+ _updateLoader() {
78
+ if (this.loading) {
79
+ if (!this._loaderEl) {
80
+ this._loaderEl = this._createLoaderSvg();
81
+ }
82
+ // Hide the icon-start slot and show loader instead
83
+ this._iconStartSlot.style.display = 'none';
84
+ this._button.insertBefore(this._loaderEl, this._iconStartSlot);
85
+ }
86
+ else {
87
+ if (this._loaderEl && this._loaderEl.parentNode) {
88
+ this._loaderEl.remove();
89
+ }
90
+ this._iconStartSlot.style.display = '';
91
+ }
92
+ }
93
+ _createLoaderSvg() {
94
+ const ns = 'http://www.w3.org/2000/svg';
95
+ const svg = document.createElementNS(ns, 'svg');
96
+ svg.setAttribute('viewBox', '0 0 24 24');
97
+ svg.setAttribute('fill', 'none');
98
+ svg.setAttribute('stroke', 'currentColor');
99
+ svg.setAttribute('stroke-width', '2');
100
+ svg.setAttribute('stroke-linecap', 'round');
101
+ svg.setAttribute('stroke-linejoin', 'round');
102
+ svg.setAttribute('aria-hidden', 'true');
103
+ svg.classList.add('dsn-icon', 'dsn-button__loader');
104
+ const paths = iconPaths['loader'] || [];
105
+ paths.forEach((d) => {
106
+ const path = document.createElementNS(ns, 'path');
107
+ path.setAttribute('d', d);
108
+ // Skip the transparent fill path (bounding box)
109
+ if (d === 'M0 0h24v24H0z') {
110
+ path.setAttribute('stroke', 'none');
111
+ path.setAttribute('fill', 'none');
112
+ }
113
+ svg.appendChild(path);
114
+ });
115
+ return svg;
116
+ }
117
+ _updateClasses() {
118
+ const variant = this.variant;
119
+ const size = this.size;
120
+ const loading = this.loading;
121
+ const fullWidth = this.fullWidth;
122
+ const iconOnly = this.iconOnly;
123
+ const classes = [
124
+ 'dsn-button',
125
+ `dsn-button--${variant}`,
126
+ `dsn-button--size-${size}`,
127
+ ];
128
+ if (loading) {
129
+ classes.push('dsn-button--loading');
130
+ }
131
+ if (fullWidth) {
132
+ classes.push('dsn-button--full-width');
133
+ }
134
+ if (iconOnly) {
135
+ classes.push('dsn-button--icon-only');
136
+ }
137
+ this._button.className = classes.join(' ');
138
+ }
139
+ _updateDisabled() {
140
+ const isDisabled = this.disabled || this.loading;
141
+ if (isDisabled) {
142
+ this._button.setAttribute('disabled', '');
143
+ }
144
+ else {
145
+ this._button.removeAttribute('disabled');
146
+ }
147
+ if (this.loading) {
148
+ this._button.setAttribute('aria-busy', 'true');
149
+ }
150
+ else {
151
+ this._button.removeAttribute('aria-busy');
152
+ }
153
+ }
154
+ _updateType() {
155
+ this._button.setAttribute('type', this.type);
156
+ }
157
+ // Property: variant
158
+ get variant() {
159
+ return this.getAttribute('variant') || 'strong';
160
+ }
161
+ set variant(value) {
162
+ this.setAttribute('variant', value);
163
+ }
164
+ // Property: size
165
+ get size() {
166
+ return this.getAttribute('size') || 'default';
167
+ }
168
+ set size(value) {
169
+ this.setAttribute('size', value);
170
+ }
171
+ // Property: disabled
172
+ get disabled() {
173
+ return this.hasAttribute('disabled');
174
+ }
175
+ set disabled(value) {
176
+ if (value) {
177
+ this.setAttribute('disabled', '');
178
+ }
179
+ else {
180
+ this.removeAttribute('disabled');
181
+ }
182
+ }
183
+ // Property: loading
184
+ get loading() {
185
+ return this.hasAttribute('loading');
186
+ }
187
+ set loading(value) {
188
+ if (value) {
189
+ this.setAttribute('loading', '');
190
+ }
191
+ else {
192
+ this.removeAttribute('loading');
193
+ }
194
+ }
195
+ // Property: fullWidth (maps to full-width attribute)
196
+ get fullWidth() {
197
+ return this.hasAttribute('full-width');
198
+ }
199
+ set fullWidth(value) {
200
+ if (value) {
201
+ this.setAttribute('full-width', '');
202
+ }
203
+ else {
204
+ this.removeAttribute('full-width');
205
+ }
206
+ }
207
+ // Property: iconOnly (maps to icon-only attribute)
208
+ get iconOnly() {
209
+ return this.hasAttribute('icon-only');
210
+ }
211
+ set iconOnly(value) {
212
+ if (value) {
213
+ this.setAttribute('icon-only', '');
214
+ }
215
+ else {
216
+ this.removeAttribute('icon-only');
217
+ }
218
+ }
219
+ // Property: type
220
+ get type() {
221
+ return this.getAttribute('type') || 'button';
222
+ }
223
+ set type(value) {
224
+ this.setAttribute('type', value);
225
+ }
226
+ // Expose the internal button for form submission
227
+ get form() {
228
+ return this._button.form;
229
+ }
230
+ // Focus delegation
231
+ focus(options) {
232
+ this._button.focus(options);
233
+ }
234
+ blur() {
235
+ this._button.blur();
236
+ }
237
+ click() {
238
+ this._button.click();
239
+ }
240
+ }
241
+ // Register the custom element
242
+ export function defineButton(tagName = 'dsn-button') {
243
+ if (!customElements.get(tagName)) {
244
+ customElements.define(tagName, DsnButton);
245
+ }
246
+ }
247
+ //# sourceMappingURL=Button.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Button.js","sourceRoot":"","sources":["../../src/button/Button.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=Button.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Button.test.d.ts","sourceRoot":"","sources":["../../src/button/Button.test.ts"],"names":[],"mappings":""}