@duskmoon-dev/el-stepper 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/index.js +467 -0
- package/dist/cjs/index.js.map +11 -0
- package/dist/cjs/register.js +470 -0
- package/dist/cjs/register.js.map +12 -0
- package/dist/esm/index.js +435 -0
- package/dist/esm/index.js.map +11 -0
- package/dist/esm/register.js +433 -0
- package/dist/esm/register.js.map +12 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/dist/types/el-dm-stepper.d.ts +121 -0
- package/dist/types/el-dm-stepper.d.ts.map +1 -0
- package/dist/types/index.d.ts +19 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/register.d.ts +2 -0
- package/dist/types/register.d.ts.map +1 -0
- package/package.json +58 -0
|
@@ -0,0 +1,467 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __moduleCache = /* @__PURE__ */ new WeakMap;
|
|
6
|
+
var __toCommonJS = (from) => {
|
|
7
|
+
var entry = __moduleCache.get(from), desc;
|
|
8
|
+
if (entry)
|
|
9
|
+
return entry;
|
|
10
|
+
entry = __defProp({}, "__esModule", { value: true });
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function")
|
|
12
|
+
__getOwnPropNames(from).map((key) => !__hasOwnProp.call(entry, key) && __defProp(entry, key, {
|
|
13
|
+
get: () => from[key],
|
|
14
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
15
|
+
}));
|
|
16
|
+
__moduleCache.set(from, entry);
|
|
17
|
+
return entry;
|
|
18
|
+
};
|
|
19
|
+
var __export = (target, all) => {
|
|
20
|
+
for (var name in all)
|
|
21
|
+
__defProp(target, name, {
|
|
22
|
+
get: all[name],
|
|
23
|
+
enumerable: true,
|
|
24
|
+
configurable: true,
|
|
25
|
+
set: (newValue) => all[name] = () => newValue
|
|
26
|
+
});
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
// src/index.ts
|
|
30
|
+
var exports_src = {};
|
|
31
|
+
__export(exports_src, {
|
|
32
|
+
register: () => register,
|
|
33
|
+
ElDmStepper: () => ElDmStepper,
|
|
34
|
+
ElDmStep: () => ElDmStep
|
|
35
|
+
});
|
|
36
|
+
module.exports = __toCommonJS(exports_src);
|
|
37
|
+
|
|
38
|
+
// src/el-dm-stepper.ts
|
|
39
|
+
var import_el_core = require("@duskmoon-dev/el-core");
|
|
40
|
+
var COLOR_MAP = {
|
|
41
|
+
primary: "var(--color-primary)",
|
|
42
|
+
secondary: "var(--color-secondary)",
|
|
43
|
+
tertiary: "var(--color-tertiary)",
|
|
44
|
+
success: "var(--color-success)",
|
|
45
|
+
warning: "var(--color-warning)",
|
|
46
|
+
error: "var(--color-error)",
|
|
47
|
+
info: "var(--color-info)"
|
|
48
|
+
};
|
|
49
|
+
var styles = import_el_core.css`
|
|
50
|
+
:host {
|
|
51
|
+
display: block;
|
|
52
|
+
font-family: var(--font-family-sans, system-ui, sans-serif);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
:host([hidden]) {
|
|
56
|
+
display: none !important;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.stepper {
|
|
60
|
+
display: flex;
|
|
61
|
+
gap: 0;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.stepper--horizontal {
|
|
65
|
+
flex-direction: row;
|
|
66
|
+
align-items: flex-start;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.stepper--vertical {
|
|
70
|
+
flex-direction: column;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.step {
|
|
74
|
+
display: flex;
|
|
75
|
+
position: relative;
|
|
76
|
+
flex: 1;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.stepper--horizontal .step {
|
|
80
|
+
flex-direction: column;
|
|
81
|
+
align-items: center;
|
|
82
|
+
text-align: center;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.stepper--vertical .step {
|
|
86
|
+
flex-direction: row;
|
|
87
|
+
align-items: flex-start;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
.step-header {
|
|
91
|
+
display: flex;
|
|
92
|
+
align-items: center;
|
|
93
|
+
position: relative;
|
|
94
|
+
z-index: 1;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
.stepper--horizontal .step-header {
|
|
98
|
+
flex-direction: column;
|
|
99
|
+
width: 100%;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
.stepper--vertical .step-header {
|
|
103
|
+
flex-direction: row;
|
|
104
|
+
min-height: 4rem;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.step-indicator-wrapper {
|
|
108
|
+
display: flex;
|
|
109
|
+
align-items: center;
|
|
110
|
+
position: relative;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
.stepper--horizontal .step-indicator-wrapper {
|
|
114
|
+
width: 100%;
|
|
115
|
+
justify-content: center;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
.step-indicator {
|
|
119
|
+
display: flex;
|
|
120
|
+
align-items: center;
|
|
121
|
+
justify-content: center;
|
|
122
|
+
width: 2rem;
|
|
123
|
+
height: 2rem;
|
|
124
|
+
border-radius: 50%;
|
|
125
|
+
font-size: 0.875rem;
|
|
126
|
+
font-weight: 600;
|
|
127
|
+
flex-shrink: 0;
|
|
128
|
+
transition: all 0.2s ease;
|
|
129
|
+
background-color: var(--color-surface-variant, #e0e0e0);
|
|
130
|
+
color: var(--color-on-surface-variant, #666);
|
|
131
|
+
border: 2px solid transparent;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
.step--clickable .step-indicator {
|
|
135
|
+
cursor: pointer;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
.step--clickable .step-indicator:hover {
|
|
139
|
+
transform: scale(1.1);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
.step--completed .step-indicator {
|
|
143
|
+
background-color: var(--stepper-color, var(--color-primary));
|
|
144
|
+
color: var(--color-on-primary, #fff);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
.step--current .step-indicator {
|
|
148
|
+
background-color: var(--color-surface, #fff);
|
|
149
|
+
color: var(--stepper-color, var(--color-primary));
|
|
150
|
+
border-color: var(--stepper-color, var(--color-primary));
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
.step--upcoming .step-indicator {
|
|
154
|
+
background-color: var(--color-surface-variant, #e0e0e0);
|
|
155
|
+
color: var(--color-on-surface-variant, #666);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
.step-content {
|
|
159
|
+
display: flex;
|
|
160
|
+
flex-direction: column;
|
|
161
|
+
gap: 0.25rem;
|
|
162
|
+
padding: 0.5rem 0;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
.stepper--horizontal .step-content {
|
|
166
|
+
align-items: center;
|
|
167
|
+
padding: 0.5rem 0.5rem 0;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
.stepper--vertical .step-content {
|
|
171
|
+
padding-left: 0.75rem;
|
|
172
|
+
padding-top: 0.25rem;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
.step-label {
|
|
176
|
+
font-size: 0.875rem;
|
|
177
|
+
font-weight: 500;
|
|
178
|
+
color: var(--color-on-surface, #1a1a1a);
|
|
179
|
+
transition: color 0.2s ease;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
.step--clickable .step-label {
|
|
183
|
+
cursor: pointer;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
.step--upcoming .step-label {
|
|
187
|
+
color: var(--color-on-surface-variant, #666);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
.step--current .step-label {
|
|
191
|
+
color: var(--stepper-color, var(--color-primary));
|
|
192
|
+
font-weight: 600;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
.step-description {
|
|
196
|
+
font-size: 0.75rem;
|
|
197
|
+
color: var(--color-on-surface-variant, #666);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/* Connector lines */
|
|
201
|
+
.connector {
|
|
202
|
+
position: absolute;
|
|
203
|
+
background-color: var(--color-surface-variant, #e0e0e0);
|
|
204
|
+
transition: background-color 0.2s ease;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
.step--completed .connector {
|
|
208
|
+
background-color: var(--stepper-color, var(--color-primary));
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
.stepper--horizontal .connector {
|
|
212
|
+
height: 2px;
|
|
213
|
+
top: 1rem;
|
|
214
|
+
left: calc(50% + 1rem + 0.25rem);
|
|
215
|
+
right: calc(-50% + 1rem + 0.25rem);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
.stepper--horizontal .step:last-child .connector {
|
|
219
|
+
display: none;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
.stepper--vertical .connector {
|
|
223
|
+
width: 2px;
|
|
224
|
+
left: calc(1rem - 1px);
|
|
225
|
+
top: 2.5rem;
|
|
226
|
+
bottom: 0.5rem;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
.stepper--vertical .step:last-child .connector {
|
|
230
|
+
display: none;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/* Icon support */
|
|
234
|
+
.step-icon {
|
|
235
|
+
font-size: 1rem;
|
|
236
|
+
line-height: 1;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/* Completed checkmark */
|
|
240
|
+
.step--completed .step-indicator::after {
|
|
241
|
+
content: '';
|
|
242
|
+
}
|
|
243
|
+
`;
|
|
244
|
+
|
|
245
|
+
class ElDmStepper extends import_el_core.BaseElement {
|
|
246
|
+
static properties = {
|
|
247
|
+
steps: { type: Array, reflect: false, default: [] },
|
|
248
|
+
current: { type: Number, reflect: true, default: 0 },
|
|
249
|
+
orientation: { type: String, reflect: true, default: "horizontal" },
|
|
250
|
+
color: { type: String, reflect: true, default: "primary" },
|
|
251
|
+
clickable: { type: Boolean, reflect: true, default: false }
|
|
252
|
+
};
|
|
253
|
+
constructor() {
|
|
254
|
+
super();
|
|
255
|
+
this.attachStyles(styles);
|
|
256
|
+
}
|
|
257
|
+
connectedCallback() {
|
|
258
|
+
super.connectedCallback();
|
|
259
|
+
this.addEventListener("click", this._handleClick.bind(this));
|
|
260
|
+
}
|
|
261
|
+
disconnectedCallback() {
|
|
262
|
+
super.disconnectedCallback();
|
|
263
|
+
this.removeEventListener("click", this._handleClick.bind(this));
|
|
264
|
+
}
|
|
265
|
+
_handleClick(e) {
|
|
266
|
+
if (!this.clickable)
|
|
267
|
+
return;
|
|
268
|
+
const target = e.target;
|
|
269
|
+
const stepEl = target.closest("[data-step-index]");
|
|
270
|
+
if (!stepEl)
|
|
271
|
+
return;
|
|
272
|
+
const index = parseInt(stepEl.dataset.stepIndex || "0", 10);
|
|
273
|
+
if (index !== this.current) {
|
|
274
|
+
const oldValue = this.current;
|
|
275
|
+
this.current = index;
|
|
276
|
+
this.emit("change", { current: index, previous: oldValue });
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
_getStepState(index) {
|
|
280
|
+
if (index < this.current)
|
|
281
|
+
return "completed";
|
|
282
|
+
if (index === this.current)
|
|
283
|
+
return "current";
|
|
284
|
+
return "upcoming";
|
|
285
|
+
}
|
|
286
|
+
_renderStepIndicator(step, index, state) {
|
|
287
|
+
if (state === "completed") {
|
|
288
|
+
return step.icon ? `<span class="step-icon">${step.icon}</span>` : `<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"></polyline></svg>`;
|
|
289
|
+
}
|
|
290
|
+
if (step.icon) {
|
|
291
|
+
return `<span class="step-icon">${step.icon}</span>`;
|
|
292
|
+
}
|
|
293
|
+
return `${index + 1}`;
|
|
294
|
+
}
|
|
295
|
+
render() {
|
|
296
|
+
const stepsArray = Array.isArray(this.steps) ? this.steps : [];
|
|
297
|
+
const colorValue = COLOR_MAP[this.color] || COLOR_MAP.primary;
|
|
298
|
+
const stepsHtml = stepsArray.map((step, index) => {
|
|
299
|
+
const state = this._getStepState(index);
|
|
300
|
+
const stateClass = `step--${state}`;
|
|
301
|
+
const clickableClass = this.clickable ? "step--clickable" : "";
|
|
302
|
+
return `
|
|
303
|
+
<div
|
|
304
|
+
class="step ${stateClass} ${clickableClass}"
|
|
305
|
+
data-step-index="${index}"
|
|
306
|
+
part="step"
|
|
307
|
+
>
|
|
308
|
+
<div class="step-header">
|
|
309
|
+
<div class="step-indicator-wrapper">
|
|
310
|
+
<div class="step-indicator" part="indicator">
|
|
311
|
+
${this._renderStepIndicator(step, index, state)}
|
|
312
|
+
</div>
|
|
313
|
+
<div class="connector" part="connector"></div>
|
|
314
|
+
</div>
|
|
315
|
+
<div class="step-content" part="content">
|
|
316
|
+
<span class="step-label" part="label">${step.label}</span>
|
|
317
|
+
${step.description ? `<span class="step-description" part="description">${step.description}</span>` : ""}
|
|
318
|
+
</div>
|
|
319
|
+
</div>
|
|
320
|
+
</div>
|
|
321
|
+
`;
|
|
322
|
+
}).join("");
|
|
323
|
+
return `
|
|
324
|
+
<div
|
|
325
|
+
class="stepper stepper--${this.orientation}"
|
|
326
|
+
style="--stepper-color: ${colorValue}"
|
|
327
|
+
role="navigation"
|
|
328
|
+
aria-label="Progress steps"
|
|
329
|
+
part="stepper"
|
|
330
|
+
>
|
|
331
|
+
${stepsHtml}
|
|
332
|
+
</div>
|
|
333
|
+
`;
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
var stepStyles = import_el_core.css`
|
|
337
|
+
:host {
|
|
338
|
+
display: flex;
|
|
339
|
+
position: relative;
|
|
340
|
+
flex: 1;
|
|
341
|
+
font-family: var(--font-family-sans, system-ui, sans-serif);
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
:host([hidden]) {
|
|
345
|
+
display: none !important;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
:host([orientation='horizontal']) {
|
|
349
|
+
flex-direction: column;
|
|
350
|
+
align-items: center;
|
|
351
|
+
text-align: center;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
:host([orientation='vertical']) {
|
|
355
|
+
flex-direction: row;
|
|
356
|
+
align-items: flex-start;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
.step-indicator {
|
|
360
|
+
display: flex;
|
|
361
|
+
align-items: center;
|
|
362
|
+
justify-content: center;
|
|
363
|
+
width: 2rem;
|
|
364
|
+
height: 2rem;
|
|
365
|
+
border-radius: 50%;
|
|
366
|
+
font-size: 0.875rem;
|
|
367
|
+
font-weight: 600;
|
|
368
|
+
flex-shrink: 0;
|
|
369
|
+
transition: all 0.2s ease;
|
|
370
|
+
background-color: var(--color-surface-variant, #e0e0e0);
|
|
371
|
+
color: var(--color-on-surface-variant, #666);
|
|
372
|
+
border: 2px solid transparent;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
:host([status='completed']) .step-indicator {
|
|
376
|
+
background-color: var(--step-color, var(--color-primary));
|
|
377
|
+
color: var(--color-on-primary, #fff);
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
:host([status='current']) .step-indicator {
|
|
381
|
+
background-color: var(--color-surface, #fff);
|
|
382
|
+
color: var(--step-color, var(--color-primary));
|
|
383
|
+
border-color: var(--step-color, var(--color-primary));
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
.step-content {
|
|
387
|
+
display: flex;
|
|
388
|
+
flex-direction: column;
|
|
389
|
+
gap: 0.25rem;
|
|
390
|
+
padding: 0.5rem;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
.step-label {
|
|
394
|
+
font-size: 0.875rem;
|
|
395
|
+
font-weight: 500;
|
|
396
|
+
color: var(--color-on-surface, #1a1a1a);
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
:host([status='current']) .step-label {
|
|
400
|
+
color: var(--step-color, var(--color-primary));
|
|
401
|
+
font-weight: 600;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
:host([status='upcoming']) .step-label {
|
|
405
|
+
color: var(--color-on-surface-variant, #666);
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
.step-description {
|
|
409
|
+
font-size: 0.75rem;
|
|
410
|
+
color: var(--color-on-surface-variant, #666);
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
::slotted(*) {
|
|
414
|
+
margin-top: 0.5rem;
|
|
415
|
+
}
|
|
416
|
+
`;
|
|
417
|
+
|
|
418
|
+
class ElDmStep extends import_el_core.BaseElement {
|
|
419
|
+
static properties = {
|
|
420
|
+
label: { type: String, reflect: true },
|
|
421
|
+
description: { type: String, reflect: true },
|
|
422
|
+
icon: { type: String, reflect: true },
|
|
423
|
+
status: { type: String, reflect: true, default: "upcoming" },
|
|
424
|
+
orientation: { type: String, reflect: true, default: "horizontal" },
|
|
425
|
+
color: { type: String, reflect: true, default: "primary" },
|
|
426
|
+
stepNumber: { type: Number, reflect: true, attribute: "step-number", default: 1 }
|
|
427
|
+
};
|
|
428
|
+
constructor() {
|
|
429
|
+
super();
|
|
430
|
+
this.attachStyles(stepStyles);
|
|
431
|
+
}
|
|
432
|
+
_renderIndicator() {
|
|
433
|
+
if (this.status === "completed" && !this.icon) {
|
|
434
|
+
return `<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"></polyline></svg>`;
|
|
435
|
+
}
|
|
436
|
+
if (this.icon) {
|
|
437
|
+
return this.icon;
|
|
438
|
+
}
|
|
439
|
+
return `${this.stepNumber}`;
|
|
440
|
+
}
|
|
441
|
+
render() {
|
|
442
|
+
const colorValue = COLOR_MAP[this.color] || COLOR_MAP.primary;
|
|
443
|
+
return `
|
|
444
|
+
<div class="step-indicator" style="--step-color: ${colorValue}" part="indicator">
|
|
445
|
+
<slot name="icon">${this._renderIndicator()}</slot>
|
|
446
|
+
</div>
|
|
447
|
+
<div class="step-content" part="content">
|
|
448
|
+
${this.label ? `<span class="step-label" part="label">${this.label}</span>` : ""}
|
|
449
|
+
${this.description ? `<span class="step-description" part="description">${this.description}</span>` : ""}
|
|
450
|
+
<slot></slot>
|
|
451
|
+
</div>
|
|
452
|
+
`;
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
// src/index.ts
|
|
457
|
+
function register() {
|
|
458
|
+
if (!customElements.get("el-dm-stepper")) {
|
|
459
|
+
customElements.define("el-dm-stepper", ElDmStepper);
|
|
460
|
+
}
|
|
461
|
+
if (!customElements.get("el-dm-step")) {
|
|
462
|
+
customElements.define("el-dm-step", ElDmStep);
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
//# debugId=A610C42F6A83A50C64756E2164756E21
|
|
467
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/el-dm-stepper.ts", "../../src/index.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"/**\n * DuskMoon Stepper Element\n *\n * A multi-step progress indicator/wizard component.\n * Uses custom CSS with theme variables for consistent theming.\n *\n * @element el-dm-stepper\n *\n * @attr {string} steps - JSON array of step objects [{label, description?, icon?}]\n * @attr {number} current - Current step index (0-based)\n * @attr {string} orientation - Layout orientation: horizontal, vertical\n * @attr {string} color - Stepper color: primary, secondary, tertiary, success, warning, error, info\n * @attr {boolean} clickable - Whether steps are clickable for navigation\n *\n * @fires change - Fired when step changes via click\n *\n * @csspart stepper - The stepper container\n * @csspart step - Individual step wrapper\n * @csspart indicator - The step number/icon circle\n * @csspart content - The step label and description wrapper\n * @csspart label - The step label text\n * @csspart description - The step description text\n * @csspart connector - The connector line between steps\n */\n\nimport { BaseElement, css } from '@duskmoon-dev/el-core';\n\nexport interface StepData {\n label: string;\n description?: string;\n icon?: string;\n}\n\nexport type StepperOrientation = 'horizontal' | 'vertical';\nexport type StepperColor =\n | 'primary'\n | 'secondary'\n | 'tertiary'\n | 'success'\n | 'warning'\n | 'error'\n | 'info';\n\nconst COLOR_MAP: Record<string, string> = {\n primary: 'var(--color-primary)',\n secondary: 'var(--color-secondary)',\n tertiary: 'var(--color-tertiary)',\n success: 'var(--color-success)',\n warning: 'var(--color-warning)',\n error: 'var(--color-error)',\n info: 'var(--color-info)',\n};\n\nconst styles = css`\n :host {\n display: block;\n font-family: var(--font-family-sans, system-ui, sans-serif);\n }\n\n :host([hidden]) {\n display: none !important;\n }\n\n .stepper {\n display: flex;\n gap: 0;\n }\n\n .stepper--horizontal {\n flex-direction: row;\n align-items: flex-start;\n }\n\n .stepper--vertical {\n flex-direction: column;\n }\n\n .step {\n display: flex;\n position: relative;\n flex: 1;\n }\n\n .stepper--horizontal .step {\n flex-direction: column;\n align-items: center;\n text-align: center;\n }\n\n .stepper--vertical .step {\n flex-direction: row;\n align-items: flex-start;\n }\n\n .step-header {\n display: flex;\n align-items: center;\n position: relative;\n z-index: 1;\n }\n\n .stepper--horizontal .step-header {\n flex-direction: column;\n width: 100%;\n }\n\n .stepper--vertical .step-header {\n flex-direction: row;\n min-height: 4rem;\n }\n\n .step-indicator-wrapper {\n display: flex;\n align-items: center;\n position: relative;\n }\n\n .stepper--horizontal .step-indicator-wrapper {\n width: 100%;\n justify-content: center;\n }\n\n .step-indicator {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 2rem;\n height: 2rem;\n border-radius: 50%;\n font-size: 0.875rem;\n font-weight: 600;\n flex-shrink: 0;\n transition: all 0.2s ease;\n background-color: var(--color-surface-variant, #e0e0e0);\n color: var(--color-on-surface-variant, #666);\n border: 2px solid transparent;\n }\n\n .step--clickable .step-indicator {\n cursor: pointer;\n }\n\n .step--clickable .step-indicator:hover {\n transform: scale(1.1);\n }\n\n .step--completed .step-indicator {\n background-color: var(--stepper-color, var(--color-primary));\n color: var(--color-on-primary, #fff);\n }\n\n .step--current .step-indicator {\n background-color: var(--color-surface, #fff);\n color: var(--stepper-color, var(--color-primary));\n border-color: var(--stepper-color, var(--color-primary));\n }\n\n .step--upcoming .step-indicator {\n background-color: var(--color-surface-variant, #e0e0e0);\n color: var(--color-on-surface-variant, #666);\n }\n\n .step-content {\n display: flex;\n flex-direction: column;\n gap: 0.25rem;\n padding: 0.5rem 0;\n }\n\n .stepper--horizontal .step-content {\n align-items: center;\n padding: 0.5rem 0.5rem 0;\n }\n\n .stepper--vertical .step-content {\n padding-left: 0.75rem;\n padding-top: 0.25rem;\n }\n\n .step-label {\n font-size: 0.875rem;\n font-weight: 500;\n color: var(--color-on-surface, #1a1a1a);\n transition: color 0.2s ease;\n }\n\n .step--clickable .step-label {\n cursor: pointer;\n }\n\n .step--upcoming .step-label {\n color: var(--color-on-surface-variant, #666);\n }\n\n .step--current .step-label {\n color: var(--stepper-color, var(--color-primary));\n font-weight: 600;\n }\n\n .step-description {\n font-size: 0.75rem;\n color: var(--color-on-surface-variant, #666);\n }\n\n /* Connector lines */\n .connector {\n position: absolute;\n background-color: var(--color-surface-variant, #e0e0e0);\n transition: background-color 0.2s ease;\n }\n\n .step--completed .connector {\n background-color: var(--stepper-color, var(--color-primary));\n }\n\n .stepper--horizontal .connector {\n height: 2px;\n top: 1rem;\n left: calc(50% + 1rem + 0.25rem);\n right: calc(-50% + 1rem + 0.25rem);\n }\n\n .stepper--horizontal .step:last-child .connector {\n display: none;\n }\n\n .stepper--vertical .connector {\n width: 2px;\n left: calc(1rem - 1px);\n top: 2.5rem;\n bottom: 0.5rem;\n }\n\n .stepper--vertical .step:last-child .connector {\n display: none;\n }\n\n /* Icon support */\n .step-icon {\n font-size: 1rem;\n line-height: 1;\n }\n\n /* Completed checkmark */\n .step--completed .step-indicator::after {\n content: '';\n }\n`;\n\nexport class ElDmStepper extends BaseElement {\n static properties = {\n steps: { type: Array, reflect: false, default: [] },\n current: { type: Number, reflect: true, default: 0 },\n orientation: { type: String, reflect: true, default: 'horizontal' },\n color: { type: String, reflect: true, default: 'primary' },\n clickable: { type: Boolean, reflect: true, default: false },\n };\n\n declare steps: StepData[];\n declare current: number;\n declare orientation: StepperOrientation;\n declare color: StepperColor;\n declare clickable: boolean;\n\n constructor() {\n super();\n this.attachStyles(styles);\n }\n\n connectedCallback(): void {\n super.connectedCallback();\n this.addEventListener('click', this._handleClick.bind(this));\n }\n\n disconnectedCallback(): void {\n super.disconnectedCallback();\n this.removeEventListener('click', this._handleClick.bind(this));\n }\n\n private _handleClick(e: Event): void {\n if (!this.clickable) return;\n\n const target = e.target as HTMLElement;\n const stepEl = target.closest('[data-step-index]') as HTMLElement;\n if (!stepEl) return;\n\n const index = parseInt(stepEl.dataset.stepIndex || '0', 10);\n if (index !== this.current) {\n const oldValue = this.current;\n this.current = index;\n this.emit('change', { current: index, previous: oldValue });\n }\n }\n\n private _getStepState(index: number): 'completed' | 'current' | 'upcoming' {\n if (index < this.current) return 'completed';\n if (index === this.current) return 'current';\n return 'upcoming';\n }\n\n private _renderStepIndicator(step: StepData, index: number, state: string): string {\n if (state === 'completed') {\n return step.icon\n ? `<span class=\"step-icon\">${step.icon}</span>`\n : `<svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>`;\n }\n if (step.icon) {\n return `<span class=\"step-icon\">${step.icon}</span>`;\n }\n return `${index + 1}`;\n }\n\n render(): string {\n const stepsArray = Array.isArray(this.steps) ? this.steps : [];\n const colorValue = COLOR_MAP[this.color] || COLOR_MAP.primary;\n\n const stepsHtml = stepsArray\n .map((step, index) => {\n const state = this._getStepState(index);\n const stateClass = `step--${state}`;\n const clickableClass = this.clickable ? 'step--clickable' : '';\n\n return `\n <div\n class=\"step ${stateClass} ${clickableClass}\"\n data-step-index=\"${index}\"\n part=\"step\"\n >\n <div class=\"step-header\">\n <div class=\"step-indicator-wrapper\">\n <div class=\"step-indicator\" part=\"indicator\">\n ${this._renderStepIndicator(step, index, state)}\n </div>\n <div class=\"connector\" part=\"connector\"></div>\n </div>\n <div class=\"step-content\" part=\"content\">\n <span class=\"step-label\" part=\"label\">${step.label}</span>\n ${step.description ? `<span class=\"step-description\" part=\"description\">${step.description}</span>` : ''}\n </div>\n </div>\n </div>\n `;\n })\n .join('');\n\n return `\n <div\n class=\"stepper stepper--${this.orientation}\"\n style=\"--stepper-color: ${colorValue}\"\n role=\"navigation\"\n aria-label=\"Progress steps\"\n part=\"stepper\"\n >\n ${stepsHtml}\n </div>\n `;\n }\n}\n\n/**\n * DuskMoon Step Element\n *\n * Individual step element for use within el-dm-stepper.\n * Allows for custom content and styling of individual steps.\n *\n * @element el-dm-step\n *\n * @attr {string} label - Step label text\n * @attr {string} description - Optional description text\n * @attr {string} icon - Optional icon (text/emoji/html)\n * @attr {string} status - Step status: completed, current, upcoming\n *\n * @slot - Default slot for custom step content\n * @slot icon - Slot for custom icon content\n *\n * @csspart step - The step container\n * @csspart indicator - The step indicator circle\n * @csspart content - The content wrapper\n * @csspart label - The label text\n * @csspart description - The description text\n */\n\nconst stepStyles = css`\n :host {\n display: flex;\n position: relative;\n flex: 1;\n font-family: var(--font-family-sans, system-ui, sans-serif);\n }\n\n :host([hidden]) {\n display: none !important;\n }\n\n :host([orientation='horizontal']) {\n flex-direction: column;\n align-items: center;\n text-align: center;\n }\n\n :host([orientation='vertical']) {\n flex-direction: row;\n align-items: flex-start;\n }\n\n .step-indicator {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 2rem;\n height: 2rem;\n border-radius: 50%;\n font-size: 0.875rem;\n font-weight: 600;\n flex-shrink: 0;\n transition: all 0.2s ease;\n background-color: var(--color-surface-variant, #e0e0e0);\n color: var(--color-on-surface-variant, #666);\n border: 2px solid transparent;\n }\n\n :host([status='completed']) .step-indicator {\n background-color: var(--step-color, var(--color-primary));\n color: var(--color-on-primary, #fff);\n }\n\n :host([status='current']) .step-indicator {\n background-color: var(--color-surface, #fff);\n color: var(--step-color, var(--color-primary));\n border-color: var(--step-color, var(--color-primary));\n }\n\n .step-content {\n display: flex;\n flex-direction: column;\n gap: 0.25rem;\n padding: 0.5rem;\n }\n\n .step-label {\n font-size: 0.875rem;\n font-weight: 500;\n color: var(--color-on-surface, #1a1a1a);\n }\n\n :host([status='current']) .step-label {\n color: var(--step-color, var(--color-primary));\n font-weight: 600;\n }\n\n :host([status='upcoming']) .step-label {\n color: var(--color-on-surface-variant, #666);\n }\n\n .step-description {\n font-size: 0.75rem;\n color: var(--color-on-surface-variant, #666);\n }\n\n ::slotted(*) {\n margin-top: 0.5rem;\n }\n`;\n\nexport class ElDmStep extends BaseElement {\n static properties = {\n label: { type: String, reflect: true },\n description: { type: String, reflect: true },\n icon: { type: String, reflect: true },\n status: { type: String, reflect: true, default: 'upcoming' },\n orientation: { type: String, reflect: true, default: 'horizontal' },\n color: { type: String, reflect: true, default: 'primary' },\n stepNumber: { type: Number, reflect: true, attribute: 'step-number', default: 1 },\n };\n\n declare label: string;\n declare description: string;\n declare icon: string;\n declare status: 'completed' | 'current' | 'upcoming';\n declare orientation: 'horizontal' | 'vertical';\n declare color: string;\n declare stepNumber: number;\n\n constructor() {\n super();\n this.attachStyles(stepStyles);\n }\n\n private _renderIndicator(): string {\n if (this.status === 'completed' && !this.icon) {\n return `<svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>`;\n }\n if (this.icon) {\n return this.icon;\n }\n return `${this.stepNumber}`;\n }\n\n render(): string {\n const colorValue = COLOR_MAP[this.color] || COLOR_MAP.primary;\n\n return `\n <div class=\"step-indicator\" style=\"--step-color: ${colorValue}\" part=\"indicator\">\n <slot name=\"icon\">${this._renderIndicator()}</slot>\n </div>\n <div class=\"step-content\" part=\"content\">\n ${this.label ? `<span class=\"step-label\" part=\"label\">${this.label}</span>` : ''}\n ${this.description ? `<span class=\"step-description\" part=\"description\">${this.description}</span>` : ''}\n <slot></slot>\n </div>\n `;\n }\n}\n",
|
|
6
|
+
"/**\n * @duskmoon-dev/el-stepper\n *\n * DuskMoon Stepper custom elements for multi-step progress indicators\n */\n\nimport { ElDmStepper, ElDmStep } from './el-dm-stepper.js';\n\nexport { ElDmStepper, ElDmStep };\nexport type { StepData, StepperOrientation, StepperColor } from './el-dm-stepper.js';\n\n/**\n * Register the el-dm-stepper and el-dm-step custom elements\n *\n * @example\n * ```ts\n * import { register } from '@duskmoon-dev/el-stepper';\n * register();\n * ```\n */\nexport function register(): void {\n if (!customElements.get('el-dm-stepper')) {\n customElements.define('el-dm-stepper', ElDmStepper);\n }\n if (!customElements.get('el-dm-step')) {\n customElements.define('el-dm-step', ElDmStep);\n }\n}\n"
|
|
7
|
+
],
|
|
8
|
+
"mappings": "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",
|
|
9
|
+
"debugId": "A610C42F6A83A50C64756E2164756E21",
|
|
10
|
+
"names": []
|
|
11
|
+
}
|