@duskmoon-dev/el-button 0.1.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/dist/esm/index.js CHANGED
@@ -1,5 +1,20 @@
1
1
  // src/el-dm-button.ts
2
2
  import { BaseElement, css } from "@duskmoon-dev/el-core";
3
+ import { css as buttonCSS } from "@duskmoon-dev/core/components/button";
4
+ var VARIANT_CLASSES = {
5
+ primary: "btn-primary",
6
+ secondary: "btn-secondary",
7
+ tertiary: "btn-tertiary",
8
+ ghost: "btn-ghost",
9
+ outline: "btn-outline"
10
+ };
11
+ var SIZE_CLASSES = {
12
+ xs: "btn-xs",
13
+ sm: "btn-sm",
14
+ md: "btn-md",
15
+ lg: "btn-lg"
16
+ };
17
+ var coreStyles = buttonCSS.replace(/@layer\s+components\s*\{/, "").replace(/\}\s*$/, "");
3
18
  var styles = css`
4
19
  :host {
5
20
  display: inline-flex;
@@ -10,187 +25,18 @@ var styles = css`
10
25
  display: none !important;
11
26
  }
12
27
 
13
- button {
14
- display: inline-flex;
15
- align-items: center;
16
- justify-content: center;
17
- gap: var(--dm-spacing-sm, 0.5rem);
18
- border: 1px solid transparent;
19
- border-radius: var(--dm-button-border-radius, var(--dm-radius-md, 0.5rem));
20
- font-family: inherit;
21
- font-weight: var(--dm-font-weight-semibold, 600);
22
- cursor: pointer;
23
- transition:
24
- background-color var(--dm-transition-fast, 150ms ease),
25
- border-color var(--dm-transition-fast, 150ms ease),
26
- color var(--dm-transition-fast, 150ms ease),
27
- box-shadow var(--dm-transition-fast, 150ms ease);
28
- -webkit-appearance: none;
29
- appearance: none;
30
- user-select: none;
31
- white-space: nowrap;
32
- }
33
-
34
- button:focus-visible {
35
- outline: none;
36
- box-shadow: var(--dm-focus-ring-offset, 0 0 0 2px white, 0 0 0 4px var(--dm-primary, #3b82f6));
37
- }
38
-
39
- button:disabled {
40
- cursor: not-allowed;
41
- opacity: 0.5;
42
- }
43
-
44
- /* Size variants */
45
- :host([size='xs']) button {
46
- padding: var(--dm-button-padding-y, 0.25rem) var(--dm-button-padding-x, 0.5rem);
47
- font-size: var(--dm-button-font-size, var(--dm-font-size-xs, 0.75rem));
48
- gap: var(--dm-spacing-xs, 0.25rem);
49
- }
50
-
51
- :host([size='sm']) button {
52
- padding: var(--dm-button-padding-y, 0.375rem) var(--dm-button-padding-x, 0.75rem);
53
- font-size: var(--dm-button-font-size, var(--dm-font-size-sm, 0.875rem));
54
- }
55
-
56
- :host(:not([size])) button,
57
- :host([size='md']) button {
58
- padding: var(--dm-button-padding-y, 0.5rem) var(--dm-button-padding-x, 1rem);
59
- font-size: var(--dm-button-font-size, var(--dm-font-size-md, 1rem));
60
- }
61
-
62
- :host([size='lg']) button {
63
- padding: var(--dm-button-padding-y, 0.625rem) var(--dm-button-padding-x, 1.25rem);
64
- font-size: var(--dm-button-font-size, var(--dm-font-size-lg, 1.125rem));
65
- }
66
-
67
- :host([size='xl']) button {
68
- padding: var(--dm-button-padding-y, 0.75rem) var(--dm-button-padding-x, 1.5rem);
69
- font-size: var(--dm-button-font-size, var(--dm-font-size-xl, 1.25rem));
70
- }
71
-
72
- /* Primary variant (default) */
73
- :host(:not([variant])) button,
74
- :host([variant='primary']) button {
75
- background-color: var(--dm-primary, #3b82f6);
76
- color: white;
77
- border-color: var(--dm-primary, #3b82f6);
78
- }
79
-
80
- :host(:not([variant])) button:hover:not(:disabled),
81
- :host([variant='primary']) button:hover:not(:disabled) {
82
- background-color: var(--dm-primary-hover, #2563eb);
83
- border-color: var(--dm-primary-hover, #2563eb);
84
- }
85
-
86
- :host(:not([variant])) button:active:not(:disabled),
87
- :host([variant='primary']) button:active:not(:disabled) {
88
- background-color: var(--dm-primary-active, #1d4ed8);
89
- border-color: var(--dm-primary-active, #1d4ed8);
90
- }
91
-
92
- /* Secondary variant */
93
- :host([variant='secondary']) button {
94
- background-color: var(--dm-secondary, #6b7280);
95
- color: white;
96
- border-color: var(--dm-secondary, #6b7280);
97
- }
98
-
99
- :host([variant='secondary']) button:hover:not(:disabled) {
100
- background-color: var(--dm-secondary-hover, #4b5563);
101
- border-color: var(--dm-secondary-hover, #4b5563);
102
- }
103
-
104
- :host([variant='secondary']) button:active:not(:disabled) {
105
- background-color: var(--dm-secondary-active, #374151);
106
- border-color: var(--dm-secondary-active, #374151);
107
- }
28
+ /* Import core button styles */
29
+ ${coreStyles}
108
30
 
109
- /* Tertiary variant */
110
- :host([variant='tertiary']) button {
111
- background-color: var(--dm-gray-100, #f3f4f6);
112
- color: var(--dm-gray-800, #1f2937);
113
- border-color: var(--dm-gray-100, #f3f4f6);
114
- }
115
-
116
- :host([variant='tertiary']) button:hover:not(:disabled) {
117
- background-color: var(--dm-gray-200, #e5e7eb);
118
- border-color: var(--dm-gray-200, #e5e7eb);
119
- }
120
-
121
- :host([variant='tertiary']) button:active:not(:disabled) {
122
- background-color: var(--dm-gray-300, #d1d5db);
123
- border-color: var(--dm-gray-300, #d1d5db);
124
- }
125
-
126
- /* Ghost variant */
127
- :host([variant='ghost']) button {
128
- background-color: transparent;
129
- color: var(--dm-primary, #3b82f6);
130
- border-color: transparent;
131
- }
132
-
133
- :host([variant='ghost']) button:hover:not(:disabled) {
134
- background-color: var(--dm-gray-100, #f3f4f6);
135
- }
136
-
137
- :host([variant='ghost']) button:active:not(:disabled) {
138
- background-color: var(--dm-gray-200, #e5e7eb);
139
- }
140
-
141
- /* Outline variant */
142
- :host([variant='outline']) button {
143
- background-color: transparent;
144
- color: var(--dm-primary, #3b82f6);
145
- border-color: var(--dm-primary, #3b82f6);
146
- }
147
-
148
- :host([variant='outline']) button:hover:not(:disabled) {
149
- background-color: var(--dm-primary, #3b82f6);
150
- color: white;
151
- }
152
-
153
- :host([variant='outline']) button:active:not(:disabled) {
154
- background-color: var(--dm-primary-hover, #2563eb);
155
- border-color: var(--dm-primary-hover, #2563eb);
156
- color: white;
157
- }
158
-
159
- /* Loading state */
160
- :host([loading]) button {
161
- position: relative;
162
- pointer-events: none;
163
- }
164
-
165
- :host([loading]) .content {
166
- visibility: hidden;
167
- }
168
-
169
- .spinner {
170
- display: none;
171
- position: absolute;
172
- width: 1em;
173
- height: 1em;
174
- border: 2px solid currentColor;
175
- border-top-color: transparent;
176
- border-radius: 50%;
177
- animation: spin 0.6s linear infinite;
178
- }
179
-
180
- :host([loading]) .spinner {
181
- display: block;
182
- }
183
-
184
- @keyframes spin {
185
- to {
186
- transform: rotate(360deg);
187
- }
31
+ /* Web component specific adjustments */
32
+ .btn {
33
+ font-family: inherit;
188
34
  }
189
35
 
190
36
  .content {
191
37
  display: inline-flex;
192
38
  align-items: center;
193
- gap: inherit;
39
+ gap: 0.5rem;
194
40
  }
195
41
 
196
42
  ::slotted(*) {
@@ -233,16 +79,29 @@ class ElDmButton extends BaseElement {
233
79
  super.connectedCallback();
234
80
  this.addEventListener("click", this._handleClick.bind(this));
235
81
  }
82
+ _getButtonClasses() {
83
+ const classes = ["btn"];
84
+ const variantClass = VARIANT_CLASSES[this.variant] || "btn-primary";
85
+ classes.push(variantClass);
86
+ if (this.size && SIZE_CLASSES[this.size]) {
87
+ classes.push(SIZE_CLASSES[this.size]);
88
+ }
89
+ if (this.loading) {
90
+ classes.push("btn-loading");
91
+ }
92
+ return classes.join(" ");
93
+ }
236
94
  render() {
237
95
  const isDisabled = this.disabled || this.loading;
96
+ const buttonClasses = this._getButtonClasses();
238
97
  return `
239
98
  <button
99
+ class="${buttonClasses}"
240
100
  part="button"
241
101
  type="${this.type || "button"}"
242
102
  ${isDisabled ? "disabled" : ""}
243
103
  aria-busy="${this.loading ? "true" : "false"}"
244
104
  >
245
- <span class="spinner" part="spinner"></span>
246
105
  <span class="content" part="content">
247
106
  <slot name="prefix" part="prefix"></slot>
248
107
  <slot></slot>
@@ -264,5 +123,5 @@ export {
264
123
  ElDmButton
265
124
  };
266
125
 
267
- //# debugId=34924FBAB96FCC1F64756E2164756E21
126
+ //# debugId=D0EBC89330E2DFE064756E2164756E21
268
127
  //# sourceMappingURL=index.js.map
@@ -2,10 +2,10 @@
2
2
  "version": 3,
3
3
  "sources": ["../../src/el-dm-button.ts", "../../src/index.ts"],
4
4
  "sourcesContent": [
5
- "/**\n * DuskMoon Button Element\n *\n * A customizable button component with multiple variants and sizes.\n *\n * @element el-dm-button\n *\n * @attr {string} variant - Button variant: primary, secondary, tertiary, ghost, outline\n * @attr {string} size - Button size: xs, sm, md, lg, xl\n * @attr {boolean} disabled - Whether the button is disabled\n * @attr {string} type - Button type: button, submit, reset\n * @attr {boolean} loading - Whether the button is in loading state\n *\n * @slot - Default slot for button content\n * @slot prefix - Content before the main text\n * @slot suffix - Content after the main text\n *\n * @csspart button - The native button element\n * @csspart content - The content wrapper\n * @csspart prefix - The prefix slot wrapper\n * @csspart suffix - The suffix slot wrapper\n * @csspart spinner - The loading spinner\n *\n * @fires click - Fired when button is clicked (native event)\n *\n * @cssprop --dm-button-padding-x - Horizontal padding\n * @cssprop --dm-button-padding-y - Vertical padding\n * @cssprop --dm-button-font-size - Font size\n * @cssprop --dm-button-border-radius - Border radius\n */\n\nimport { BaseElement, css } from '@duskmoon-dev/el-core';\nimport type { Size, Variant } from '@duskmoon-dev/el-core';\n\nconst styles = css`\n :host {\n display: inline-flex;\n vertical-align: middle;\n }\n\n :host([hidden]) {\n display: none !important;\n }\n\n button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: var(--dm-spacing-sm, 0.5rem);\n border: 1px solid transparent;\n border-radius: var(--dm-button-border-radius, var(--dm-radius-md, 0.5rem));\n font-family: inherit;\n font-weight: var(--dm-font-weight-semibold, 600);\n cursor: pointer;\n transition:\n background-color var(--dm-transition-fast, 150ms ease),\n border-color var(--dm-transition-fast, 150ms ease),\n color var(--dm-transition-fast, 150ms ease),\n box-shadow var(--dm-transition-fast, 150ms ease);\n -webkit-appearance: none;\n appearance: none;\n user-select: none;\n white-space: nowrap;\n }\n\n button:focus-visible {\n outline: none;\n box-shadow: var(--dm-focus-ring-offset, 0 0 0 2px white, 0 0 0 4px var(--dm-primary, #3b82f6));\n }\n\n button:disabled {\n cursor: not-allowed;\n opacity: 0.5;\n }\n\n /* Size variants */\n :host([size='xs']) button {\n padding: var(--dm-button-padding-y, 0.25rem) var(--dm-button-padding-x, 0.5rem);\n font-size: var(--dm-button-font-size, var(--dm-font-size-xs, 0.75rem));\n gap: var(--dm-spacing-xs, 0.25rem);\n }\n\n :host([size='sm']) button {\n padding: var(--dm-button-padding-y, 0.375rem) var(--dm-button-padding-x, 0.75rem);\n font-size: var(--dm-button-font-size, var(--dm-font-size-sm, 0.875rem));\n }\n\n :host(:not([size])) button,\n :host([size='md']) button {\n padding: var(--dm-button-padding-y, 0.5rem) var(--dm-button-padding-x, 1rem);\n font-size: var(--dm-button-font-size, var(--dm-font-size-md, 1rem));\n }\n\n :host([size='lg']) button {\n padding: var(--dm-button-padding-y, 0.625rem) var(--dm-button-padding-x, 1.25rem);\n font-size: var(--dm-button-font-size, var(--dm-font-size-lg, 1.125rem));\n }\n\n :host([size='xl']) button {\n padding: var(--dm-button-padding-y, 0.75rem) var(--dm-button-padding-x, 1.5rem);\n font-size: var(--dm-button-font-size, var(--dm-font-size-xl, 1.25rem));\n }\n\n /* Primary variant (default) */\n :host(:not([variant])) button,\n :host([variant='primary']) button {\n background-color: var(--dm-primary, #3b82f6);\n color: white;\n border-color: var(--dm-primary, #3b82f6);\n }\n\n :host(:not([variant])) button:hover:not(:disabled),\n :host([variant='primary']) button:hover:not(:disabled) {\n background-color: var(--dm-primary-hover, #2563eb);\n border-color: var(--dm-primary-hover, #2563eb);\n }\n\n :host(:not([variant])) button:active:not(:disabled),\n :host([variant='primary']) button:active:not(:disabled) {\n background-color: var(--dm-primary-active, #1d4ed8);\n border-color: var(--dm-primary-active, #1d4ed8);\n }\n\n /* Secondary variant */\n :host([variant='secondary']) button {\n background-color: var(--dm-secondary, #6b7280);\n color: white;\n border-color: var(--dm-secondary, #6b7280);\n }\n\n :host([variant='secondary']) button:hover:not(:disabled) {\n background-color: var(--dm-secondary-hover, #4b5563);\n border-color: var(--dm-secondary-hover, #4b5563);\n }\n\n :host([variant='secondary']) button:active:not(:disabled) {\n background-color: var(--dm-secondary-active, #374151);\n border-color: var(--dm-secondary-active, #374151);\n }\n\n /* Tertiary variant */\n :host([variant='tertiary']) button {\n background-color: var(--dm-gray-100, #f3f4f6);\n color: var(--dm-gray-800, #1f2937);\n border-color: var(--dm-gray-100, #f3f4f6);\n }\n\n :host([variant='tertiary']) button:hover:not(:disabled) {\n background-color: var(--dm-gray-200, #e5e7eb);\n border-color: var(--dm-gray-200, #e5e7eb);\n }\n\n :host([variant='tertiary']) button:active:not(:disabled) {\n background-color: var(--dm-gray-300, #d1d5db);\n border-color: var(--dm-gray-300, #d1d5db);\n }\n\n /* Ghost variant */\n :host([variant='ghost']) button {\n background-color: transparent;\n color: var(--dm-primary, #3b82f6);\n border-color: transparent;\n }\n\n :host([variant='ghost']) button:hover:not(:disabled) {\n background-color: var(--dm-gray-100, #f3f4f6);\n }\n\n :host([variant='ghost']) button:active:not(:disabled) {\n background-color: var(--dm-gray-200, #e5e7eb);\n }\n\n /* Outline variant */\n :host([variant='outline']) button {\n background-color: transparent;\n color: var(--dm-primary, #3b82f6);\n border-color: var(--dm-primary, #3b82f6);\n }\n\n :host([variant='outline']) button:hover:not(:disabled) {\n background-color: var(--dm-primary, #3b82f6);\n color: white;\n }\n\n :host([variant='outline']) button:active:not(:disabled) {\n background-color: var(--dm-primary-hover, #2563eb);\n border-color: var(--dm-primary-hover, #2563eb);\n color: white;\n }\n\n /* Loading state */\n :host([loading]) button {\n position: relative;\n pointer-events: none;\n }\n\n :host([loading]) .content {\n visibility: hidden;\n }\n\n .spinner {\n display: none;\n position: absolute;\n width: 1em;\n height: 1em;\n border: 2px solid currentColor;\n border-top-color: transparent;\n border-radius: 50%;\n animation: spin 0.6s linear infinite;\n }\n\n :host([loading]) .spinner {\n display: block;\n }\n\n @keyframes spin {\n to {\n transform: rotate(360deg);\n }\n }\n\n .content {\n display: inline-flex;\n align-items: center;\n gap: inherit;\n }\n\n ::slotted(*) {\n display: inline-flex;\n align-items: center;\n }\n`;\n\nexport class ElDmButton extends BaseElement {\n static properties = {\n variant: { type: String, reflect: true },\n size: { type: String, reflect: true },\n disabled: { type: Boolean, reflect: true },\n type: { type: String, reflect: true, default: 'button' },\n loading: { type: Boolean, reflect: true },\n };\n\n /** Button variant */\n declare variant: Variant;\n\n /** Button size */\n declare size: Size;\n\n /** Whether the button is disabled */\n declare disabled: boolean;\n\n /** Button type (button, submit, reset) */\n declare type: 'button' | 'submit' | 'reset';\n\n /** Whether the button is in loading state */\n declare loading: boolean;\n\n constructor() {\n super();\n this.attachStyles(styles);\n }\n\n /**\n * Handle click events\n */\n private _handleClick(event: MouseEvent): void {\n if (this.disabled || this.loading) {\n event.preventDefault();\n event.stopPropagation();\n return;\n }\n\n // Handle form submission\n if (this.type === 'submit') {\n const form = this.closest('form');\n if (form) {\n form.requestSubmit();\n }\n } else if (this.type === 'reset') {\n const form = this.closest('form');\n if (form) {\n form.reset();\n }\n }\n }\n\n connectedCallback(): void {\n super.connectedCallback();\n this.addEventListener('click', this._handleClick.bind(this));\n }\n\n render(): string {\n const isDisabled = this.disabled || this.loading;\n\n return `\n <button\n part=\"button\"\n type=\"${this.type || 'button'}\"\n ${isDisabled ? 'disabled' : ''}\n aria-busy=\"${this.loading ? 'true' : 'false'}\"\n >\n <span class=\"spinner\" part=\"spinner\"></span>\n <span class=\"content\" part=\"content\">\n <slot name=\"prefix\" part=\"prefix\"></slot>\n <slot></slot>\n <slot name=\"suffix\" part=\"suffix\"></slot>\n </span>\n </button>\n `;\n }\n}\n",
5
+ "/**\n * DuskMoon Button Element\n *\n * A customizable button component with multiple variants and sizes.\n * Uses styles from @duskmoon-dev/core for consistent theming.\n *\n * @element el-dm-button\n *\n * @attr {string} variant - Button variant: primary, secondary, tertiary, ghost, outline\n * @attr {string} size - Button size: xs, sm, md, lg\n * @attr {boolean} disabled - Whether the button is disabled\n * @attr {string} type - Button type: button, submit, reset\n * @attr {boolean} loading - Whether the button is in loading state\n *\n * @slot - Default slot for button content\n * @slot prefix - Content before the main text\n * @slot suffix - Content after the main text\n *\n * @csspart button - The native button element\n * @csspart content - The content wrapper\n * @csspart prefix - The prefix slot wrapper\n * @csspart suffix - The suffix slot wrapper\n *\n * @fires click - Fired when button is clicked (native event)\n */\n\nimport { BaseElement, css } from '@duskmoon-dev/el-core';\nimport { css as buttonCSS } from '@duskmoon-dev/core/components/button';\n\n// Map of variant attribute values to CSS classes\nconst VARIANT_CLASSES: Record<string, string> = {\n primary: 'btn-primary',\n secondary: 'btn-secondary',\n tertiary: 'btn-tertiary',\n ghost: 'btn-ghost',\n outline: 'btn-outline',\n};\n\n// Map of size attribute values to CSS classes\nconst SIZE_CLASSES: Record<string, string> = {\n xs: 'btn-xs',\n sm: 'btn-sm',\n md: 'btn-md',\n lg: 'btn-lg',\n};\n\nexport type ButtonVariant = 'primary' | 'secondary' | 'tertiary' | 'ghost' | 'outline';\nexport type ButtonSize = 'xs' | 'sm' | 'md' | 'lg';\n\n// Strip @layer wrapper for Shadow DOM compatibility and add host styles\nconst coreStyles = buttonCSS.replace(/@layer\\s+components\\s*\\{/, '').replace(/\\}\\s*$/, '');\n\nconst styles = css`\n :host {\n display: inline-flex;\n vertical-align: middle;\n }\n\n :host([hidden]) {\n display: none !important;\n }\n\n /* Import core button styles */\n ${coreStyles}\n\n /* Web component specific adjustments */\n .btn {\n font-family: inherit;\n }\n\n .content {\n display: inline-flex;\n align-items: center;\n gap: 0.5rem;\n }\n\n ::slotted(*) {\n display: inline-flex;\n align-items: center;\n }\n`;\n\nexport class ElDmButton extends BaseElement {\n static properties = {\n variant: { type: String, reflect: true },\n size: { type: String, reflect: true },\n disabled: { type: Boolean, reflect: true },\n type: { type: String, reflect: true, default: 'button' },\n loading: { type: Boolean, reflect: true },\n };\n\n /** Button variant */\n declare variant: ButtonVariant;\n\n /** Button size */\n declare size: ButtonSize;\n\n /** Whether the button is disabled */\n declare disabled: boolean;\n\n /** Button type (button, submit, reset) */\n declare type: 'button' | 'submit' | 'reset';\n\n /** Whether the button is in loading state */\n declare loading: boolean;\n\n constructor() {\n super();\n this.attachStyles(styles);\n }\n\n /**\n * Handle click events\n */\n private _handleClick(event: MouseEvent): void {\n if (this.disabled || this.loading) {\n event.preventDefault();\n event.stopPropagation();\n return;\n }\n\n // Handle form submission\n if (this.type === 'submit') {\n const form = this.closest('form');\n if (form) {\n form.requestSubmit();\n }\n } else if (this.type === 'reset') {\n const form = this.closest('form');\n if (form) {\n form.reset();\n }\n }\n }\n\n connectedCallback(): void {\n super.connectedCallback();\n this.addEventListener('click', this._handleClick.bind(this));\n }\n\n /**\n * Build CSS class string for the button\n */\n private _getButtonClasses(): string {\n const classes = ['btn'];\n\n // Add variant class (default to primary)\n const variantClass = VARIANT_CLASSES[this.variant] || 'btn-primary';\n classes.push(variantClass);\n\n // Add size class if specified\n if (this.size && SIZE_CLASSES[this.size]) {\n classes.push(SIZE_CLASSES[this.size]);\n }\n\n // Add loading class\n if (this.loading) {\n classes.push('btn-loading');\n }\n\n return classes.join(' ');\n }\n\n render(): string {\n const isDisabled = this.disabled || this.loading;\n const buttonClasses = this._getButtonClasses();\n\n return `\n <button\n class=\"${buttonClasses}\"\n part=\"button\"\n type=\"${this.type || 'button'}\"\n ${isDisabled ? 'disabled' : ''}\n aria-busy=\"${this.loading ? 'true' : 'false'}\"\n >\n <span class=\"content\" part=\"content\">\n <slot name=\"prefix\" part=\"prefix\"></slot>\n <slot></slot>\n <slot name=\"suffix\" part=\"suffix\"></slot>\n </span>\n </button>\n `;\n }\n}\n",
6
6
  "/**\n * @duskmoon-dev/el-button\n *\n * DuskMoon Button custom element\n */\n\nimport { ElDmButton } from './el-dm-button.js';\n\nexport { ElDmButton };\n\n/**\n * Register the el-dm-button custom element\n *\n * @example\n * ```ts\n * import { register } from '@duskmoon-dev/el-button';\n * register();\n * ```\n */\nexport function register(): void {\n if (!customElements.get('el-dm-button')) {\n customElements.define('el-dm-button', ElDmButton);\n }\n}\n"
7
7
  ],
8
- "mappings": "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",
9
- "debugId": "34924FBAB96FCC1F64756E2164756E21",
8
+ "mappings": ";AA0BA;AACA,gBAAS;AAGT,IAAM,kBAA0C;AAAA,EAC9C,SAAS;AAAA,EACT,WAAW;AAAA,EACX,UAAU;AAAA,EACV,OAAO;AAAA,EACP,SAAS;AACX;AAGA,IAAM,eAAuC;AAAA,EAC3C,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACN;AAMA,IAAM,aAAa,UAAU,QAAQ,4BAA4B,EAAE,EAAE,QAAQ,UAAU,EAAE;AAEzF,IAAM,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAWX;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAmBG,MAAM,mBAAmB,YAAY;AAAA,SACnC,aAAa;AAAA,IAClB,SAAS,EAAE,MAAM,QAAQ,SAAS,KAAK;AAAA,IACvC,MAAM,EAAE,MAAM,QAAQ,SAAS,KAAK;AAAA,IACpC,UAAU,EAAE,MAAM,SAAS,SAAS,KAAK;AAAA,IACzC,MAAM,EAAE,MAAM,QAAQ,SAAS,MAAM,SAAS,SAAS;AAAA,IACvD,SAAS,EAAE,MAAM,SAAS,SAAS,KAAK;AAAA,EAC1C;AAAA,EAiBA,WAAW,GAAG;AAAA,IACZ,MAAM;AAAA,IACN,KAAK,aAAa,MAAM;AAAA;AAAA,EAMlB,YAAY,CAAC,OAAyB;AAAA,IAC5C,IAAI,KAAK,YAAY,KAAK,SAAS;AAAA,MACjC,MAAM,eAAe;AAAA,MACrB,MAAM,gBAAgB;AAAA,MACtB;AAAA,IACF;AAAA,IAGA,IAAI,KAAK,SAAS,UAAU;AAAA,MAC1B,MAAM,OAAO,KAAK,QAAQ,MAAM;AAAA,MAChC,IAAI,MAAM;AAAA,QACR,KAAK,cAAc;AAAA,MACrB;AAAA,IACF,EAAO,SAAI,KAAK,SAAS,SAAS;AAAA,MAChC,MAAM,OAAO,KAAK,QAAQ,MAAM;AAAA,MAChC,IAAI,MAAM;AAAA,QACR,KAAK,MAAM;AAAA,MACb;AAAA,IACF;AAAA;AAAA,EAGF,iBAAiB,GAAS;AAAA,IACxB,MAAM,kBAAkB;AAAA,IACxB,KAAK,iBAAiB,SAAS,KAAK,aAAa,KAAK,IAAI,CAAC;AAAA;AAAA,EAMrD,iBAAiB,GAAW;AAAA,IAClC,MAAM,UAAU,CAAC,KAAK;AAAA,IAGtB,MAAM,eAAe,gBAAgB,KAAK,YAAY;AAAA,IACtD,QAAQ,KAAK,YAAY;AAAA,IAGzB,IAAI,KAAK,QAAQ,aAAa,KAAK,OAAO;AAAA,MACxC,QAAQ,KAAK,aAAa,KAAK,KAAK;AAAA,IACtC;AAAA,IAGA,IAAI,KAAK,SAAS;AAAA,MAChB,QAAQ,KAAK,aAAa;AAAA,IAC5B;AAAA,IAEA,OAAO,QAAQ,KAAK,GAAG;AAAA;AAAA,EAGzB,MAAM,GAAW;AAAA,IACf,MAAM,aAAa,KAAK,YAAY,KAAK;AAAA,IACzC,MAAM,gBAAgB,KAAK,kBAAkB;AAAA,IAE7C,OAAO;AAAA;AAAA,iBAEM;AAAA;AAAA,gBAED,KAAK,QAAQ;AAAA,UACnB,aAAa,aAAa;AAAA,qBACf,KAAK,UAAU,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAU7C;;;ACpKO,SAAS,QAAQ,GAAS;AAAA,EAC/B,IAAI,CAAC,eAAe,IAAI,cAAc,GAAG;AAAA,IACvC,eAAe,OAAO,gBAAgB,UAAU;AAAA,EAClD;AAAA;",
9
+ "debugId": "D0EBC89330E2DFE064756E2164756E21",
10
10
  "names": []
11
11
  }
@@ -0,0 +1,126 @@
1
+ // src/el-dm-button.ts
2
+ import { BaseElement, css } from "@duskmoon-dev/el-core";
3
+ import { css as buttonCSS } from "@duskmoon-dev/core/components/button";
4
+ var VARIANT_CLASSES = {
5
+ primary: "btn-primary",
6
+ secondary: "btn-secondary",
7
+ tertiary: "btn-tertiary",
8
+ ghost: "btn-ghost",
9
+ outline: "btn-outline"
10
+ };
11
+ var SIZE_CLASSES = {
12
+ xs: "btn-xs",
13
+ sm: "btn-sm",
14
+ md: "btn-md",
15
+ lg: "btn-lg"
16
+ };
17
+ var coreStyles = buttonCSS.replace(/@layer\s+components\s*\{/, "").replace(/\}\s*$/, "");
18
+ var styles = css`
19
+ :host {
20
+ display: inline-flex;
21
+ vertical-align: middle;
22
+ }
23
+
24
+ :host([hidden]) {
25
+ display: none !important;
26
+ }
27
+
28
+ /* Import core button styles */
29
+ ${coreStyles}
30
+
31
+ /* Web component specific adjustments */
32
+ .btn {
33
+ font-family: inherit;
34
+ }
35
+
36
+ .content {
37
+ display: inline-flex;
38
+ align-items: center;
39
+ gap: 0.5rem;
40
+ }
41
+
42
+ ::slotted(*) {
43
+ display: inline-flex;
44
+ align-items: center;
45
+ }
46
+ `;
47
+
48
+ class ElDmButton extends BaseElement {
49
+ static properties = {
50
+ variant: { type: String, reflect: true },
51
+ size: { type: String, reflect: true },
52
+ disabled: { type: Boolean, reflect: true },
53
+ type: { type: String, reflect: true, default: "button" },
54
+ loading: { type: Boolean, reflect: true }
55
+ };
56
+ constructor() {
57
+ super();
58
+ this.attachStyles(styles);
59
+ }
60
+ _handleClick(event) {
61
+ if (this.disabled || this.loading) {
62
+ event.preventDefault();
63
+ event.stopPropagation();
64
+ return;
65
+ }
66
+ if (this.type === "submit") {
67
+ const form = this.closest("form");
68
+ if (form) {
69
+ form.requestSubmit();
70
+ }
71
+ } else if (this.type === "reset") {
72
+ const form = this.closest("form");
73
+ if (form) {
74
+ form.reset();
75
+ }
76
+ }
77
+ }
78
+ connectedCallback() {
79
+ super.connectedCallback();
80
+ this.addEventListener("click", this._handleClick.bind(this));
81
+ }
82
+ _getButtonClasses() {
83
+ const classes = ["btn"];
84
+ const variantClass = VARIANT_CLASSES[this.variant] || "btn-primary";
85
+ classes.push(variantClass);
86
+ if (this.size && SIZE_CLASSES[this.size]) {
87
+ classes.push(SIZE_CLASSES[this.size]);
88
+ }
89
+ if (this.loading) {
90
+ classes.push("btn-loading");
91
+ }
92
+ return classes.join(" ");
93
+ }
94
+ render() {
95
+ const isDisabled = this.disabled || this.loading;
96
+ const buttonClasses = this._getButtonClasses();
97
+ return `
98
+ <button
99
+ class="${buttonClasses}"
100
+ part="button"
101
+ type="${this.type || "button"}"
102
+ ${isDisabled ? "disabled" : ""}
103
+ aria-busy="${this.loading ? "true" : "false"}"
104
+ >
105
+ <span class="content" part="content">
106
+ <slot name="prefix" part="prefix"></slot>
107
+ <slot></slot>
108
+ <slot name="suffix" part="suffix"></slot>
109
+ </span>
110
+ </button>
111
+ `;
112
+ }
113
+ }
114
+
115
+ // src/index.ts
116
+ function register() {
117
+ if (!customElements.get("el-dm-button")) {
118
+ customElements.define("el-dm-button", ElDmButton);
119
+ }
120
+ }
121
+
122
+ // src/register.ts
123
+ register();
124
+
125
+ //# debugId=C9785BD7C2C7BB9864756E2164756E21
126
+ //# sourceMappingURL=register.js.map
@@ -0,0 +1,12 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/el-dm-button.ts", "../../src/index.ts", "../../src/register.ts"],
4
+ "sourcesContent": [
5
+ "/**\n * DuskMoon Button Element\n *\n * A customizable button component with multiple variants and sizes.\n * Uses styles from @duskmoon-dev/core for consistent theming.\n *\n * @element el-dm-button\n *\n * @attr {string} variant - Button variant: primary, secondary, tertiary, ghost, outline\n * @attr {string} size - Button size: xs, sm, md, lg\n * @attr {boolean} disabled - Whether the button is disabled\n * @attr {string} type - Button type: button, submit, reset\n * @attr {boolean} loading - Whether the button is in loading state\n *\n * @slot - Default slot for button content\n * @slot prefix - Content before the main text\n * @slot suffix - Content after the main text\n *\n * @csspart button - The native button element\n * @csspart content - The content wrapper\n * @csspart prefix - The prefix slot wrapper\n * @csspart suffix - The suffix slot wrapper\n *\n * @fires click - Fired when button is clicked (native event)\n */\n\nimport { BaseElement, css } from '@duskmoon-dev/el-core';\nimport { css as buttonCSS } from '@duskmoon-dev/core/components/button';\n\n// Map of variant attribute values to CSS classes\nconst VARIANT_CLASSES: Record<string, string> = {\n primary: 'btn-primary',\n secondary: 'btn-secondary',\n tertiary: 'btn-tertiary',\n ghost: 'btn-ghost',\n outline: 'btn-outline',\n};\n\n// Map of size attribute values to CSS classes\nconst SIZE_CLASSES: Record<string, string> = {\n xs: 'btn-xs',\n sm: 'btn-sm',\n md: 'btn-md',\n lg: 'btn-lg',\n};\n\nexport type ButtonVariant = 'primary' | 'secondary' | 'tertiary' | 'ghost' | 'outline';\nexport type ButtonSize = 'xs' | 'sm' | 'md' | 'lg';\n\n// Strip @layer wrapper for Shadow DOM compatibility and add host styles\nconst coreStyles = buttonCSS.replace(/@layer\\s+components\\s*\\{/, '').replace(/\\}\\s*$/, '');\n\nconst styles = css`\n :host {\n display: inline-flex;\n vertical-align: middle;\n }\n\n :host([hidden]) {\n display: none !important;\n }\n\n /* Import core button styles */\n ${coreStyles}\n\n /* Web component specific adjustments */\n .btn {\n font-family: inherit;\n }\n\n .content {\n display: inline-flex;\n align-items: center;\n gap: 0.5rem;\n }\n\n ::slotted(*) {\n display: inline-flex;\n align-items: center;\n }\n`;\n\nexport class ElDmButton extends BaseElement {\n static properties = {\n variant: { type: String, reflect: true },\n size: { type: String, reflect: true },\n disabled: { type: Boolean, reflect: true },\n type: { type: String, reflect: true, default: 'button' },\n loading: { type: Boolean, reflect: true },\n };\n\n /** Button variant */\n declare variant: ButtonVariant;\n\n /** Button size */\n declare size: ButtonSize;\n\n /** Whether the button is disabled */\n declare disabled: boolean;\n\n /** Button type (button, submit, reset) */\n declare type: 'button' | 'submit' | 'reset';\n\n /** Whether the button is in loading state */\n declare loading: boolean;\n\n constructor() {\n super();\n this.attachStyles(styles);\n }\n\n /**\n * Handle click events\n */\n private _handleClick(event: MouseEvent): void {\n if (this.disabled || this.loading) {\n event.preventDefault();\n event.stopPropagation();\n return;\n }\n\n // Handle form submission\n if (this.type === 'submit') {\n const form = this.closest('form');\n if (form) {\n form.requestSubmit();\n }\n } else if (this.type === 'reset') {\n const form = this.closest('form');\n if (form) {\n form.reset();\n }\n }\n }\n\n connectedCallback(): void {\n super.connectedCallback();\n this.addEventListener('click', this._handleClick.bind(this));\n }\n\n /**\n * Build CSS class string for the button\n */\n private _getButtonClasses(): string {\n const classes = ['btn'];\n\n // Add variant class (default to primary)\n const variantClass = VARIANT_CLASSES[this.variant] || 'btn-primary';\n classes.push(variantClass);\n\n // Add size class if specified\n if (this.size && SIZE_CLASSES[this.size]) {\n classes.push(SIZE_CLASSES[this.size]);\n }\n\n // Add loading class\n if (this.loading) {\n classes.push('btn-loading');\n }\n\n return classes.join(' ');\n }\n\n render(): string {\n const isDisabled = this.disabled || this.loading;\n const buttonClasses = this._getButtonClasses();\n\n return `\n <button\n class=\"${buttonClasses}\"\n part=\"button\"\n type=\"${this.type || 'button'}\"\n ${isDisabled ? 'disabled' : ''}\n aria-busy=\"${this.loading ? 'true' : 'false'}\"\n >\n <span class=\"content\" part=\"content\">\n <slot name=\"prefix\" part=\"prefix\"></slot>\n <slot></slot>\n <slot name=\"suffix\" part=\"suffix\"></slot>\n </span>\n </button>\n `;\n }\n}\n",
6
+ "/**\n * @duskmoon-dev/el-button\n *\n * DuskMoon Button custom element\n */\n\nimport { ElDmButton } from './el-dm-button.js';\n\nexport { ElDmButton };\n\n/**\n * Register the el-dm-button custom element\n *\n * @example\n * ```ts\n * import { register } from '@duskmoon-dev/el-button';\n * register();\n * ```\n */\nexport function register(): void {\n if (!customElements.get('el-dm-button')) {\n customElements.define('el-dm-button', ElDmButton);\n }\n}\n",
7
+ "/**\n * Auto-register el-dm-button custom element\n *\n * @example\n * ```ts\n * import '@duskmoon-dev/el-button/register';\n *\n * // Now you can use <el-dm-button> in HTML\n * ```\n */\nimport { register } from './index.js';\n\nregister();\n"
8
+ ],
9
+ "mappings": ";AA0BA;AACA,gBAAS;AAGT,IAAM,kBAA0C;AAAA,EAC9C,SAAS;AAAA,EACT,WAAW;AAAA,EACX,UAAU;AAAA,EACV,OAAO;AAAA,EACP,SAAS;AACX;AAGA,IAAM,eAAuC;AAAA,EAC3C,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACN;AAMA,IAAM,aAAa,UAAU,QAAQ,4BAA4B,EAAE,EAAE,QAAQ,UAAU,EAAE;AAEzF,IAAM,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAWX;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAmBG,MAAM,mBAAmB,YAAY;AAAA,SACnC,aAAa;AAAA,IAClB,SAAS,EAAE,MAAM,QAAQ,SAAS,KAAK;AAAA,IACvC,MAAM,EAAE,MAAM,QAAQ,SAAS,KAAK;AAAA,IACpC,UAAU,EAAE,MAAM,SAAS,SAAS,KAAK;AAAA,IACzC,MAAM,EAAE,MAAM,QAAQ,SAAS,MAAM,SAAS,SAAS;AAAA,IACvD,SAAS,EAAE,MAAM,SAAS,SAAS,KAAK;AAAA,EAC1C;AAAA,EAiBA,WAAW,GAAG;AAAA,IACZ,MAAM;AAAA,IACN,KAAK,aAAa,MAAM;AAAA;AAAA,EAMlB,YAAY,CAAC,OAAyB;AAAA,IAC5C,IAAI,KAAK,YAAY,KAAK,SAAS;AAAA,MACjC,MAAM,eAAe;AAAA,MACrB,MAAM,gBAAgB;AAAA,MACtB;AAAA,IACF;AAAA,IAGA,IAAI,KAAK,SAAS,UAAU;AAAA,MAC1B,MAAM,OAAO,KAAK,QAAQ,MAAM;AAAA,MAChC,IAAI,MAAM;AAAA,QACR,KAAK,cAAc;AAAA,MACrB;AAAA,IACF,EAAO,SAAI,KAAK,SAAS,SAAS;AAAA,MAChC,MAAM,OAAO,KAAK,QAAQ,MAAM;AAAA,MAChC,IAAI,MAAM;AAAA,QACR,KAAK,MAAM;AAAA,MACb;AAAA,IACF;AAAA;AAAA,EAGF,iBAAiB,GAAS;AAAA,IACxB,MAAM,kBAAkB;AAAA,IACxB,KAAK,iBAAiB,SAAS,KAAK,aAAa,KAAK,IAAI,CAAC;AAAA;AAAA,EAMrD,iBAAiB,GAAW;AAAA,IAClC,MAAM,UAAU,CAAC,KAAK;AAAA,IAGtB,MAAM,eAAe,gBAAgB,KAAK,YAAY;AAAA,IACtD,QAAQ,KAAK,YAAY;AAAA,IAGzB,IAAI,KAAK,QAAQ,aAAa,KAAK,OAAO;AAAA,MACxC,QAAQ,KAAK,aAAa,KAAK,KAAK;AAAA,IACtC;AAAA,IAGA,IAAI,KAAK,SAAS;AAAA,MAChB,QAAQ,KAAK,aAAa;AAAA,IAC5B;AAAA,IAEA,OAAO,QAAQ,KAAK,GAAG;AAAA;AAAA,EAGzB,MAAM,GAAW;AAAA,IACf,MAAM,aAAa,KAAK,YAAY,KAAK;AAAA,IACzC,MAAM,gBAAgB,KAAK,kBAAkB;AAAA,IAE7C,OAAO;AAAA;AAAA,iBAEM;AAAA;AAAA,gBAED,KAAK,QAAQ;AAAA,UACnB,aAAa,aAAa;AAAA,qBACf,KAAK,UAAU,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAU7C;;;ACpKO,SAAS,QAAQ,GAAS;AAAA,EAC/B,IAAI,CAAC,eAAe,IAAI,cAAc,GAAG;AAAA,IACvC,eAAe,OAAO,gBAAgB,UAAU;AAAA,EAClD;AAAA;;;ACVF,SAAS;",
10
+ "debugId": "C9785BD7C2C7BB9864756E2164756E21",
11
+ "names": []
12
+ }