@diniz/webcomponents 1.1.5 → 1.1.7

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.
@@ -0,0 +1,2424 @@
1
+ var C = Object.defineProperty;
2
+ var E = (l, s, t) => s in l ? C(l, s, { enumerable: !0, configurable: !0, writable: !0, value: t }) : l[s] = t;
3
+ var p = (l, s, t) => E(l, typeof s != "symbol" ? s + "" : s, t);
4
+ import y from "feather-icons";
5
+ function w(l) {
6
+ let s = l;
7
+ const t = /* @__PURE__ */ new Set();
8
+ return {
9
+ get: () => s,
10
+ set: (e) => {
11
+ Object.is(s, e) || (s = e, t.forEach((a) => a(s)));
12
+ },
13
+ subscribe: (e) => (t.add(e), () => t.delete(e))
14
+ };
15
+ }
16
+ class g extends HTMLElement {
17
+ constructor() {
18
+ super();
19
+ p(this, "state");
20
+ p(this, "signalUnsubs");
21
+ this.attachShadow({ mode: "open" }), this.state = {}, this.signalUnsubs = /* @__PURE__ */ new Set();
22
+ }
23
+ useSignal(t) {
24
+ const e = w(t), a = e.subscribe(() => this.render());
25
+ return this.signalUnsubs.add(a), e;
26
+ }
27
+ /**
28
+ * Create a signal bound to a specific HTML element
29
+ * Automatically updates the element's textContent when the signal value changes
30
+ * @param elementId - The ID of the HTML element to bind to
31
+ * @param initial - The initial value
32
+ * @returns A signal that auto-updates the element
33
+ *
34
+ * @example
35
+ * ```typescript
36
+ * private count = this.useSignalHtml('countValue', 0);
37
+ *
38
+ * private increment() {
39
+ * this.count.set(this.count.get() + 1);
40
+ * // Element with id="countValue" automatically updates
41
+ * }
42
+ * ```
43
+ */
44
+ useSignalHtml(t, e) {
45
+ const a = w(e), i = a.subscribe((r) => {
46
+ var n;
47
+ const o = (n = this.shadowRoot) == null ? void 0 : n.getElementById(t);
48
+ o && (o.textContent = String(r));
49
+ });
50
+ return this.signalUnsubs.add(i), requestAnimationFrame(() => {
51
+ var o;
52
+ const r = (o = this.shadowRoot) == null ? void 0 : o.getElementById(t);
53
+ r && (r.textContent = String(e));
54
+ }), a;
55
+ }
56
+ setState(t) {
57
+ this.state = { ...this.state, ...t }, this.render();
58
+ }
59
+ connectedCallback() {
60
+ this.render();
61
+ }
62
+ disconnectedCallback() {
63
+ this.signalUnsubs.forEach((t) => t()), this.signalUnsubs.clear();
64
+ }
65
+ render() {
66
+ }
67
+ }
68
+ const f = ':root{--color-primary: #24ec71;--color-primary-contrast: #ffffff;--color-ink: #0f172a;--color-muted: #f1f5f9;--color-header: #34a8eb;--color-border: #f3f5f7;--color-border-strong: #cbd5f5;--color-nav-bg: #222222;--color-nav-text: #ffffff;--shadow-primary: 0 8px 18px rgba(31, 111, 235, .25);--focus-ring: #9ec5ff;--radius-pill: 999px;--radius-md: 12px;--color-page-bg: #ffffff;--color-page-text: #0f172a}body{background:var(--color-page-bg);color:var(--color-page-text);margin:0;font-family:Segoe UI,system-ui,-apple-system,sans-serif}:host([data-ui="button"]){display:inline-block}:host([data-ui="table"]){display:block}:host([data-ui="layout"]){display:block}:host([data-ui="sidebar"]){display:block}.btn{align-items:center;border:1px solid transparent;border-radius:var(--radius-pill);cursor:pointer;display:inline-flex;font-family:inherit;font-size:.95rem;font-weight:600;gap:.5rem;line-height:1;padding:.65rem 1.2rem;transition:transform .12s ease,box-shadow .12s ease,background-color .12s ease}.btn:focus-visible{outline:3px solid var(--focus-ring);outline-offset:2px}.btn:active:not(:disabled){transform:translateY(1px)}.btn:disabled{cursor:not-allowed;opacity:.6}.btn.primary{background:var(--color-primary);color:var(--color-primary-contrast);box-shadow:var(--shadow-primary)}.btn.secondary{background:var(--color-muted);color:var(--color-ink);border-color:var(--color-border-strong)}.btn.ghost{background:transparent;color:var(--color-primary);border-color:var(--color-border-strong)}.btn.danger{background:#ef4444;color:#fff;border-color:#ef4444}.btn-danger:hover{background:#6626dc;border-color:#dc2626}.btn.has-icon{line-height:1.2}.btn .btn-icon{width:18px;height:18px;flex-shrink:0}.btn .btn-icon svg{width:100%;height:100%}.btn.icon-only{padding:.65rem;aspect-ratio:1}.btn.icon-only.sm{padding:.45rem}.btn.icon-only.lg{padding:.8rem}.btn.sm .btn-icon{width:14px;height:14px}.btn.lg .btn-icon{width:22px;height:22px}.btn.sm{font-size:.85rem;padding:.45rem .9rem;box-shadow:0 4px 12px #a7124426}.btn.md{font-size:.95rem;padding:.65rem 1.2rem}.btn.lg{font-size:1.05rem;padding:.8rem 1.5rem}.table-wrap{border:1px solid var(--color-border);border-radius:var(--radius-md);overflow:hidden}table{border-collapse:collapse;width:100%}thead{background:var(--color-header)}th,td{padding:.75rem 1rem;text-align:left;border-bottom:1px solid var(--color-border);font-size:.95rem;border-right:1px solid var(--color-border)}tr:last-child td{border-bottom:none}.align-left{text-align:left}.align-center{text-align:center}.align-right{text-align:right}.actions-cell{display:flex;gap:.5rem;justify-content:center}.app-nav{padding:1rem;background:var(--color-nav-bg);color:var(--color-nav-text)}.app-link{color:var(--color-nav-text);margin-right:1rem;text-decoration:none}.signal-demo,.theme-toggle{margin-top:16px;display:flex;align-items:center;gap:12px}.data-table{margin-top:15px}.dashboard-layout{display:grid;grid-template-columns:220px minmax(0,1fr);gap:24px;padding:24px}.dashboard-sidebar{background:var(--color-muted);border:1px solid var(--color-border);border-radius:var(--radius-md);padding:18px}.sidebar-title{margin:0 0 12px;font-size:1rem}.sidebar-nav{display:flex;flex-direction:column;gap:10px}.sidebar-link{color:var(--color-ink);text-decoration:none;font-weight:600}.dashboard-main{display:flex;flex-direction:column;gap:12px}.dashboard-actions{display:flex;flex-wrap:wrap;gap:12px}@media (max-width: 900px){.dashboard-layout{grid-template-columns:1fr}}:host([data-ui="input"]){display:block}.input-wrapper{display:flex;flex-direction:column;gap:.35rem}.input-label{font-size:.9rem;font-weight:600;color:var(--color-ink)}.input-field{padding:.6rem .85rem;font-size:.95rem;font-family:inherit;border:1.5px solid var(--color-border);border-radius:6px;background:var(--color-page-bg);color:var(--color-page-text);transition:border-color .15s ease,box-shadow .15s ease;outline:none}.input-field::placeholder{color:#94a3b8}.input-field:focus{border-color:var(--color-primary);box-shadow:0 0 0 3px #24ec7126}.input-field:disabled{background:var(--color-muted);cursor:not-allowed;opacity:.7}.input-wrapper.invalid .input-field{border-color:#ef4444}.input-wrapper.invalid .input-field:focus{box-shadow:0 0 0 3px #ef444426}.input-error{font-size:.8rem;color:#ef4444;display:flex;align-items:center;gap:.25rem}.input-error.hidden{display:none}:host([data-ui="checkbox"]){display:inline-flex;align-items:center;cursor:pointer;-webkit-user-select:none;user-select:none}:host([data-ui="checkbox"][disabled]){cursor:not-allowed;opacity:.6}.checkbox-container{display:inline-flex;align-items:center;gap:.75rem}.checkbox-box{position:relative;display:inline-flex;align-items:center;justify-content:center;border:2px solid var(--color-border, #cbd5e1);border-radius:var(--radius-sm, 4px);background:#fff;transition:all .2s;flex-shrink:0;box-sizing:border-box}.checkbox-box.size-sm{min-width:16px;max-width:16px;min-height:16px;max-height:16px}.checkbox-box.size-md{min-width:18px;max-width:18px;min-height:18px;max-height:18px}.checkbox-box.size-lg{min-width:20px;max-width:20px;min-height:20px;max-height:20px}.checkbox-box:hover:not(.disabled){border-color:var(--color-primary, #24ec71)}.checkbox-box.checked,.checkbox-box.indeterminate{background:var(--color-primary, #24ec71);border-color:var(--color-primary, #24ec71)}.checkbox-box.disabled{background:var(--color-muted, #f1f5f9);cursor:not-allowed}.checkbox-icon{display:none;color:#fff;position:absolute}.checkbox-box.checked .checkbox-icon.check,.checkbox-box.indeterminate .checkbox-icon.minus{display:block}.checkbox-icon.check{width:12px;height:12px}.checkbox-icon.minus{width:10px;height:10px}.checkbox-label{font-size:.95rem;color:var(--color-ink, #0f172a);line-height:1.5}.checkbox-container.size-sm .checkbox-label{font-size:.875rem}.checkbox-container.size-lg .checkbox-label{font-size:1rem}input[type=checkbox]{position:absolute;opacity:0;pointer-events:none}.modal-backdrop{display:none;position:fixed;top:0;right:0;bottom:0;left:0;background:#00000080;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:9999;animation:fadeIn .2s ease-out}.modal-backdrop.open{display:flex;align-items:center;justify-content:center;padding:1rem}.modal-content{background:var(--color-surface, white);border-radius:var(--radius-lg, 16px);box-shadow:0 20px 25px -5px #0000001a,0 10px 10px -5px #0000000a;max-height:90vh;display:flex;flex-direction:column;width:100%;animation:slideUp .2s ease-out}.modal-content.sm{max-width:400px}.modal-content.md{max-width:600px}.modal-content.lg{max-width:800px}.modal-content.xl{max-width:1200px}.modal-content.full{max-width:95vw}.modal-header{padding:1.5rem;border-bottom:1px solid var(--color-border, #e2e8f0);display:flex;align-items:center;justify-content:space-between}.modal-title{font-size:1.25rem;font-weight:600;color:var(--color-ink, #0f172a);margin:0}.modal-close{background:none;border:none;cursor:pointer;padding:.5rem;display:flex;align-items:center;justify-content:center;border-radius:var(--radius-md, 8px);color:var(--color-text-muted, #64748b);transition:all .2s}.modal-close:hover{background:var(--color-muted, #f1f5f9);color:var(--color-ink, #0f172a)}.modal-body{padding:1.5rem;overflow-y:auto;flex:1}.modal-footer{padding:1.5rem;border-top:1px solid var(--color-border, #e2e8f0);display:flex;gap:.75rem;justify-content:flex-end}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes slideUp{0%{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}:host([data-ui="select"]){display:block;width:90%}.select-container{position:relative;width:100%}.select-label{display:block;margin-bottom:.5rem;font-size:.875rem;font-weight:500;color:var(--color-ink, #0f172a)}.select-trigger{width:100%;padding:.625rem 1rem;background:#fff;border:1px solid var(--color-border, #e2e8f0);border-radius:var(--radius-md, 8px);display:flex;align-items:center;justify-content:space-between;cursor:pointer;transition:all .2s;font-size:.95rem;color:var(--color-ink, #0f172a)}.select-trigger:hover:not(:disabled){border-color:var(--color-primary, #24ec71)}.select-trigger:focus{outline:none;border-color:var(--color-primary, #24ec71);box-shadow:0 0 0 3px #24ec711a}.select-trigger:disabled{background:var(--color-muted, #f1f5f9);cursor:not-allowed;opacity:.6}.select-trigger.open{border-color:var(--color-primary, #24ec71)}.select-placeholder{color:var(--color-text-muted, #94a3b8);flex:1;text-align:left}.select-placeholder.has-selection{color:var(--color-ink, #0f172a)}.select-arrow{display:flex;transition:transform .2s;color:var(--color-text-muted, #64748b)}.select-arrow.open{transform:rotate(180deg)}.select-dropdown{position:absolute;top:calc(100% + .25rem);left:0;right:0;background:#fff;border:1px solid var(--color-border, #e2e8f0);border-radius:var(--radius-md, 8px);box-shadow:0 10px 15px -3px #0000001a,0 4px 6px -2px #0000000d;max-height:300px;overflow-y:auto;z-index:1000;display:none;animation:slideDown .15s ease-out}.select-dropdown.open{display:block}.select-search{width:100%;padding:.625rem 1rem;border:none;border-bottom:1px solid var(--color-border, #e2e8f0);font-size:.95rem;outline:none}.select-search:focus{background:var(--color-muted, #f1f5f9)}.select-option{padding:.625rem 1rem;cursor:pointer;transition:background .15s;color:var(--color-ink, #0f172a);font-size:.95rem}.select-option:hover:not(.disabled){background:var(--color-muted, #f1f5f9)}.select-option.selected{background:#24ec711a;color:var(--color-primary, #24ec71);font-weight:500}.select-option.disabled{opacity:.5;cursor:not-allowed}.select-empty{padding:1rem;text-align:center;color:var(--color-text-muted, #94a3b8);font-size:.875rem}@keyframes slideDown{0%{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:translateY(0)}}:host([data-ui="upload"]){display:block;width:100%}.upload{display:flex;flex-direction:column;gap:.75rem}.upload-label{font-size:.9rem;font-weight:700;color:var(--color-ink)}.upload-drop{border:1.5px dashed rgba(36,236,113,.55);border-radius:16px;background:linear-gradient(135deg,#24ec7114,#34a8eb14);padding:1.25rem 1.5rem;position:relative;transition:border-color .2s ease,box-shadow .2s ease,transform .2s ease}.upload-drop.dragging{border-color:var(--color-primary);box-shadow:0 16px 30px #24ec712e;transform:translateY(-2px)}.upload-drop.disabled{opacity:.6;cursor:not-allowed}.upload-input{position:absolute;top:0;right:0;bottom:0;left:0;opacity:0;cursor:pointer}.upload-content{display:grid;grid-template-columns:auto 1fr auto;gap:1rem;align-items:center}.upload-icon{width:46px;height:46px;border-radius:14px;display:grid;place-items:center;background:#0f172a;color:#fff;box-shadow:0 12px 20px #0f172a2e}.upload-icon svg{width:20px;height:20px}.upload-title{font-weight:700;color:var(--color-ink)}.upload-sub{font-size:.85rem;color:var(--color-text-muted, #64748b);margin-top:.2rem}.upload-btn{border:none;border-radius:999px;padding:.45rem 1rem;font-size:.85rem;font-weight:700;background:#0f172a;color:#fff;cursor:pointer;transition:transform .2s ease,box-shadow .2s ease}.upload-btn:hover:not(:disabled){transform:translateY(-1px);box-shadow:0 10px 16px #0f172a2e}.upload-btn:disabled{cursor:not-allowed;opacity:.5}.upload-helper{font-size:.85rem;color:var(--color-text-muted, #64748b)}.upload-list{list-style:none;padding:0;margin:0;display:grid;gap:.5rem}.upload-list li{display:grid;grid-template-columns:1fr auto auto;gap:.75rem;align-items:center;padding:.6rem .75rem;border-radius:12px;background:#fff;border:1px solid rgba(148,163,184,.35);font-size:.9rem;color:var(--color-ink)}.upload-meta{font-size:.78rem;color:var(--color-text-muted, #64748b)}.upload-remove{border:none;background:#ef44441a;color:#b91c1c;padding:.25rem .65rem;border-radius:999px;font-size:.75rem;font-weight:600;cursor:pointer}.upload-remove:hover{background:#ef444433}:host([data-ui="pagination"]){display:block}.pagination-container{display:flex;align-items:center;justify-content:space-between;gap:1rem;flex-wrap:wrap}.pagination-info{font-size:.9rem;color:var(--color-ink);opacity:.7}.pagination{display:flex;align-items:center;gap:.25rem}.page-btn{min-width:2.5rem;height:2.5rem;padding:.5rem;border:1px solid var(--color-border);background:#fff;color:var(--color-ink);font-size:.9rem;font-weight:500;border-radius:6px;cursor:pointer;transition:all .2s ease;display:flex;align-items:center;justify-content:center}.page-btn:hover:not(:disabled):not(.active){background:var(--color-muted);border-color:var(--color-border-strong)}.page-btn:disabled{opacity:.4;cursor:not-allowed}.page-btn.active{background:var(--color-primary);color:var(--color-primary-contrast);border-color:var(--color-primary);font-weight:600}.page-btn.ellipsis{border:none;background:transparent;cursor:default;pointer-events:none}.nav-btn{padding:.5rem .75rem}.nav-btn svg{width:16px;height:16px}:host([data-ui="stepper"]){display:block}.stepper-wrap{width:100%}.stepper-empty{padding:1rem;border:1px dashed var(--color-border);border-radius:var(--radius-md);color:var(--color-text-muted, #64748b);text-align:center;font-size:.9rem}.stepper{list-style:none;padding:0;margin:0;display:flex;flex-wrap:wrap;gap:1.25rem}.stepper.vertical{flex-direction:column;gap:1rem}.step{display:flex;align-items:center;position:relative}.stepper.vertical .step{flex-direction:column;align-items:flex-start}.step-trigger{display:flex;align-items:center;gap:.75rem;background:transparent;border:none;padding:0;cursor:pointer;text-align:left;font-family:inherit;color:var(--color-ink)}.step-trigger:disabled{cursor:not-allowed;opacity:.5}.step-node{width:2.1rem;height:2.1rem;border-radius:12px;background:var(--color-muted);border:1px solid var(--color-border-strong);display:inline-flex;align-items:center;justify-content:center;font-weight:700;font-size:.9rem;color:var(--color-ink);box-shadow:inset 0 0 0 1px #fff9}.step-text{display:flex;flex-direction:column;gap:.2rem}.step-title{font-weight:700;letter-spacing:.2px;font-size:.98rem}.step-desc{font-size:.85rem;color:var(--color-text-muted, #64748b)}.step-connector{width:48px;height:2px;margin:0 .65rem;background:linear-gradient(90deg,var(--color-border),rgba(255,255,255,0));flex-shrink:0}.stepper.vertical .step-connector{width:2px;height:28px;margin:.65rem 0 .25rem 1.05rem;background:linear-gradient(180deg,var(--color-border),rgba(255,255,255,0))}.step.complete .step-node{background:linear-gradient(135deg,#24ec71,#34a8eb);color:#0f172a;border-color:transparent;box-shadow:0 8px 18px #24ec7140}.step.complete .step-connector{background:linear-gradient(90deg,#24ec71,#34a8eb)}.stepper.vertical .step.complete .step-connector{background:linear-gradient(180deg,#24ec71,#34a8eb)}.step.active .step-node{background:#fff;color:var(--color-ink);border-color:var(--color-primary);box-shadow:0 0 0 4px #24ec712e,0 12px 20px #24ec7138;animation:stepGlow 1.6s ease-in-out infinite}.step.active .step-title{color:var(--color-ink)}.step.upcoming .step-title{color:var(--color-ink);opacity:.7}.step.error .step-node{background:#fee2e2;border-color:#f87171;color:#991b1b;box-shadow:0 8px 16px #ef444433}.step.warning .step-node{background:#fef3c7;border-color:#f59e0b;color:#92400e;box-shadow:0 8px 16px #f59e0b33}.stepper.sm .step-node{width:1.65rem;height:1.65rem;font-size:.75rem;border-radius:10px}.stepper.sm .step-title{font-size:.9rem}.stepper.sm .step-desc{font-size:.78rem}.stepper.lg .step-node{width:2.6rem;height:2.6rem;font-size:1.05rem;border-radius:14px}.stepper.lg .step-title{font-size:1.1rem}.stepper.lg .step-desc{font-size:.92rem}@keyframes stepGlow{0%,to{transform:translateY(0)}50%{transform:translateY(-2px)}}:host([data-ui="date-picker"]){display:block;width:100%}.date-picker-label{display:block;font-size:.9rem;font-weight:500;color:var(--color-ink);margin-bottom:.5rem}.date-picker-container{position:relative;display:flex;flex-direction:column;gap:.5rem}.date-input-wrapper{position:relative;display:flex;align-items:center;border:1px solid var(--color-border);border-radius:var(--radius-md);background:#fff;transition:all .2s ease}.date-input-wrapper:hover:not(.disabled){border-color:var(--color-border-strong)}.date-input-wrapper:focus-within{border-color:var(--color-primary);box-shadow:0 0 0 3px #24ec711a;outline:none}.date-input-wrapper.disabled{background:var(--color-muted);cursor:not-allowed;opacity:.6}.formatted-input{flex:1;border:none;padding:.75rem 1rem;font-size:.95rem;font-family:inherit;background:transparent;color:var(--color-ink);outline:none}.formatted-input:disabled{cursor:not-allowed;color:var(--color-ink);opacity:.7}.formatted-input::placeholder{color:#94a3b8;opacity:.7}.formatted-input.invalid{color:#dc2626}.hidden-date-input{position:absolute;opacity:0;width:100%;height:100%;top:0;left:0;pointer-events:none;cursor:pointer}.calendar-btn{padding:.5rem;margin-right:.5rem;border:none;background:transparent;cursor:pointer;display:flex;align-items:center;justify-content:center;color:var(--color-ink);opacity:.6;transition:all .2s ease;border-radius:6px}.calendar-btn:hover:not(:disabled){background:var(--color-muted);opacity:1}.calendar-btn:disabled{cursor:not-allowed;opacity:.3}.calendar-icon{width:20px;height:20px}.format-label{font-size:.75rem;color:var(--color-ink);opacity:.6;padding:0 .25rem;font-weight:500}:host([data-ui="layout"]){display:block;width:100%;height:100%}.layout-container{display:flex;width:100%;height:100%;background:var(--color-bg);position:relative}:host([data-ui="layout-header"]){display:block;width:100%;flex-shrink:0}.layout-header{display:flex;align-items:center;justify-content:space-between;padding:0 1.5rem;background:var(--color-surface);border-bottom:1px solid var(--color-border);box-shadow:0 1px 3px #0f172a0f}:host([data-ui="layout-footer"]){display:block;width:100%;flex-shrink:0}.layout-footer{display:flex;align-items:center;justify-content:space-between;padding:0 1.5rem;background:var(--color-surface);border-top:1px solid var(--color-border);box-shadow:0 -1px 3px #0f172a0f}:host([data-ui="layout-content"]){display:block;flex:1;overflow:auto;min-width:0}.layout-content{display:flex;flex-direction:column;width:100%;height:100%;position:relative}:host([data-ui="layout-sidebar"]){display:block;flex-shrink:0;background:var(--color-surface);border-right:1px solid var(--color-border);position:relative;overflow:hidden;height:100%}.layout-sidebar{display:flex;flex-direction:column;width:var(--sidebar-width, 240px);height:100%;background:var(--color-surface);transition:width .3s cubic-bezier(.4,0,.2,1);position:relative;border-right:1px solid var(--color-border);overflow:hidden}.layout-sidebar.collapsed{width:var(--sidebar-collapsed-width, 64px)}.sidebar-content{flex:1;overflow-y:auto;overflow-x:hidden;padding:1rem 0}.sidebar-toggle{position:absolute;bottom:1rem;right:0;width:40px;height:40px;padding:0;margin-right:.7rem;background:transparent;border:1px solid var(--color-border);border-radius:8px;color:var(--color-ink);cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all .2s ease}.sidebar-toggle:hover{background:var(--color-muted);border-color:var(--color-border-strong)}.sidebar-toggle:active{transform:scale(.95)}.toggle-icon{width:18px;height:18px;transition:transform .3s ease}.layout-sidebar.collapsed .toggle-icon{transform:rotate(180deg)}.sidebar-content::-webkit-scrollbar{width:6px}.sidebar-content::-webkit-scrollbar-track{background:transparent}.sidebar-content::-webkit-scrollbar-thumb{background:var(--color-border-strong);border-radius:3px}.sidebar-content::-webkit-scrollbar-thumb:hover{background:var(--color-ink);opacity:.6}@media (max-width: 768px){.layout-header,.layout-footer{padding:0 1rem}.layout-sidebar{position:absolute;left:0;top:0;height:100%;z-index:1000;box-shadow:2px 0 8px #0f172a26;transition:transform .3s cubic-bezier(.4,0,.2,1)}.layout-sidebar.collapsed{transform:translate(calc(-1 * var(--sidebar-width, 240px)))}}#ui-datepicker-div,.datepicker,.react-datepicker-popper{z-index:99999!important}';
69
+ class S extends g {
70
+ connectedCallback() {
71
+ this.setAttribute("data-ui", "button"), super.connectedCallback(), this.attachClickHandler();
72
+ }
73
+ static get observedAttributes() {
74
+ return ["variant", "size", "disabled", "type", "icon", "icon-position"];
75
+ }
76
+ attributeChangedCallback() {
77
+ this.render(), this.attachClickHandler();
78
+ }
79
+ attachClickHandler() {
80
+ if (!this.shadowRoot) return;
81
+ const s = this.shadowRoot.querySelector("button");
82
+ if (!s) return;
83
+ const t = s._clickHandler;
84
+ t && s.removeEventListener("click", t);
85
+ const e = (a) => {
86
+ const i = this.getType();
87
+ if (this.hasAttribute("disabled")) {
88
+ a.preventDefault(), a.stopPropagation();
89
+ return;
90
+ }
91
+ if (i === "submit") {
92
+ a.preventDefault(), a.stopPropagation();
93
+ let o = this.closest("form");
94
+ if (!o) {
95
+ let n = this.parentElement;
96
+ for (; n; ) {
97
+ if (n.tagName === "FORM") {
98
+ o = n;
99
+ break;
100
+ }
101
+ n = n.parentElement;
102
+ }
103
+ }
104
+ if (o) {
105
+ const n = new Event("submit", {
106
+ bubbles: !0,
107
+ cancelable: !0
108
+ });
109
+ o.dispatchEvent(n);
110
+ }
111
+ }
112
+ };
113
+ s._clickHandler = e, s.addEventListener("click", e);
114
+ }
115
+ getVariant() {
116
+ const s = this.getAttribute("variant");
117
+ return s === "secondary" || s === "ghost" || s === "danger" ? s : "primary";
118
+ }
119
+ getSize() {
120
+ const s = this.getAttribute("size");
121
+ return s === "sm" || s === "lg" ? s : "md";
122
+ }
123
+ getType() {
124
+ return this.getAttribute("type") ?? "button";
125
+ }
126
+ getIcon() {
127
+ var a;
128
+ const s = this.getAttribute("icon");
129
+ if (!s) return null;
130
+ const t = s.trim();
131
+ return { html: `<span class="btn-icon">${((a = y.icons[t]) == null ? void 0 : a.toSvg()) || ""}</span>`, name: t };
132
+ }
133
+ getIconPosition() {
134
+ return this.getAttribute("icon-position") === "right" ? "right" : "left";
135
+ }
136
+ render() {
137
+ const s = this.getVariant(), t = this.getSize(), e = this.hasAttribute("disabled"), a = this.getType(), i = this.getIcon(), r = this.getIconPosition(), o = i !== null, n = i ? i.html : "", d = this.innerHTML.trim(), c = o && !d;
138
+ let h;
139
+ o && d ? h = r === "left" ? `${n}<span>${d}</span>` : `<span>${d}</span>${n}` : o ? h = n : h = d, this.shadowRoot.innerHTML = `
140
+ <style>${f}</style>
141
+ <button
142
+ part="button"
143
+ class="btn ${s} ${t}${o ? " has-icon" : ""}${c ? " icon-only" : ""}"
144
+ type="${a}"
145
+ ${e ? "disabled" : ""}
146
+ >
147
+ ${h}
148
+ </button>
149
+ `;
150
+ }
151
+ }
152
+ customElements.define("ui-button", S);
153
+ class L extends g {
154
+ constructor() {
155
+ super();
156
+ p(this, "inputEl", null);
157
+ p(this, "customValidator", null);
158
+ p(this, "validationRule", null);
159
+ this.state = {
160
+ value: "",
161
+ valid: !0,
162
+ touched: !1,
163
+ error: ""
164
+ };
165
+ }
166
+ static get observedAttributes() {
167
+ return ["type", "label", "placeholder", "required", "pattern", "minlength", "maxlength", "min", "max", "error-message", "custom-error", "disabled", "name", "validate"];
168
+ }
169
+ connectedCallback() {
170
+ this.setAttribute("data-ui", "input"), super.connectedCallback();
171
+ }
172
+ attributeChangedCallback(t, e, a) {
173
+ e !== a && t !== "value" && this.render();
174
+ }
175
+ setCustomValidator(t) {
176
+ this.customValidator = t, this.validate();
177
+ }
178
+ get value() {
179
+ return this.state.value;
180
+ }
181
+ set value(t) {
182
+ this.state.value = t, this.inputEl && this.inputEl.value !== t && (this.inputEl.value = t), this.validate();
183
+ }
184
+ get isValid() {
185
+ return this.state.valid;
186
+ }
187
+ checkValidity() {
188
+ return this.state.touched = !0, this.validate();
189
+ }
190
+ reportValidity() {
191
+ this.state.touched = !0;
192
+ const t = this.validate();
193
+ return this.updateErrorDisplay(), !t && this.inputEl && this.inputEl.focus(), t;
194
+ }
195
+ getType() {
196
+ const t = this.getAttribute("type");
197
+ return ["text", "email", "password", "number", "tel", "url"].includes(t || "") ? t : "text";
198
+ }
199
+ getLabel() {
200
+ return this.getAttribute("label") || "";
201
+ }
202
+ getPlaceholder() {
203
+ return this.getAttribute("placeholder") || "";
204
+ }
205
+ getName() {
206
+ return this.getAttribute("name") || "";
207
+ }
208
+ getErrorMessage() {
209
+ return this.state.error ? this.state.error : this.getAttribute("error-message") || this.getAttribute("custom-error") || "";
210
+ }
211
+ getCustomError() {
212
+ return this.getAttribute("custom-error") || "";
213
+ }
214
+ parseValidationRule(t) {
215
+ return t.startsWith("email:") ? { type: "emailDomain", domain: t.slice(6) } : t.startsWith("match:") ? { type: "match", selector: t.slice(6) } : t.startsWith("min:") ? { type: "minLength", length: parseInt(t.slice(4), 10) } : t.startsWith("max:") ? { type: "maxLength", length: parseInt(t.slice(4), 10) } : t.startsWith("regex:") ? { type: "regex", pattern: t.slice(6) } : null;
216
+ }
217
+ applyValidationRule(t) {
218
+ const e = this.state.value;
219
+ switch (t.type) {
220
+ case "emailDomain":
221
+ if (!e.endsWith(`@${t.domain}`))
222
+ return { valid: !1, message: `Must end with @${t.domain}` };
223
+ break;
224
+ case "match":
225
+ const a = document.querySelector(t.selector);
226
+ if (a && e !== a.value)
227
+ return { valid: !1, message: "Values do not match" };
228
+ break;
229
+ case "minLength":
230
+ if (e.length < t.length)
231
+ return { valid: !1, message: `Must be at least ${t.length} characters` };
232
+ break;
233
+ case "maxLength":
234
+ if (e.length > t.length)
235
+ return { valid: !1, message: `Must be no more than ${t.length} characters` };
236
+ break;
237
+ case "regex":
238
+ try {
239
+ if (!new RegExp(t.pattern).test(e))
240
+ return { valid: !1, message: "Invalid format" };
241
+ } catch {
242
+ return { valid: !1, message: "Invalid validation pattern" };
243
+ }
244
+ break;
245
+ }
246
+ return { valid: !0 };
247
+ }
248
+ validate() {
249
+ if (!this.inputEl) return !0;
250
+ const t = this.getAttribute("validate");
251
+ if (t && (this.validationRule || (this.validationRule = this.parseValidationRule(t)), this.validationRule)) {
252
+ const e = this.applyValidationRule(this.validationRule);
253
+ return this.state.valid = e.valid, !e.valid && e.message && (this.state.error = e.message), this.state.valid;
254
+ }
255
+ if (this.customValidator) {
256
+ const e = this.customValidator(this.state.value, this.inputEl);
257
+ this.state.valid = e.valid, !e.valid && e.message && (this.state.error = e.message);
258
+ } else {
259
+ const e = this.inputEl.checkValidity();
260
+ this.state.valid = e, !e && this.state.touched && (this.state.error = this.inputEl.validationMessage || this.getErrorMessage()), e && (this.state.error = "");
261
+ }
262
+ return this.state.valid;
263
+ }
264
+ handleInput(t) {
265
+ const e = t.target;
266
+ this.state.value = e.value, this.state.touched = !0, this.validate(), this.updateErrorDisplay();
267
+ }
268
+ handleBlur() {
269
+ this.state.touched = !0, this.validate(), this.updateErrorDisplay();
270
+ }
271
+ updateErrorDisplay() {
272
+ if (!this.inputEl) return;
273
+ const t = this.shadowRoot.querySelector(".input-error"), e = this.shadowRoot.querySelector(".input-wrapper"), a = this.getName();
274
+ e && e.classList.toggle("invalid", !this.state.valid && this.state.touched), t && (!this.state.valid && this.state.touched && this.state.error ? (t.textContent = this.state.error, t.classList.remove("hidden")) : t.classList.add("hidden")), this.inputEl.setAttribute("aria-invalid", String(!this.state.valid && this.state.touched)), a && this.inputEl.setAttribute("aria-describedby", `${a}-error`);
275
+ }
276
+ needsRender() {
277
+ return this.hasAttribute("type") || this.hasAttribute("label") || this.hasAttribute("placeholder") || this.hasAttribute("required") || this.hasAttribute("pattern") || this.hasAttribute("disabled") || this.hasAttribute("name") || this.hasAttribute("minlength") || this.hasAttribute("maxlength") || this.hasAttribute("min") || this.hasAttribute("max") || this.hasAttribute("error-message") || this.hasAttribute("custom-error") || this.hasAttribute("validate");
278
+ }
279
+ render() {
280
+ const t = this.getType(), e = this.getLabel(), a = this.getPlaceholder(), i = this.getName(), r = this.getErrorMessage(), o = this.hasAttribute("required"), n = this.getAttribute("pattern"), d = this.getAttribute("minlength"), c = this.getAttribute("maxlength"), h = this.getAttribute("min"), u = this.getAttribute("max"), b = this.hasAttribute("disabled"), m = !this.state.valid && this.state.touched, v = e !== "";
281
+ this.shadowRoot.innerHTML = `
282
+ <style>${f}</style>
283
+ <div class="input-wrapper${m ? " invalid" : ""}${b ? " disabled" : ""}">
284
+ ${v ? `<label class="input-label">${e}${o ? " *" : ""}</label>` : ""}
285
+ <input
286
+ part="input"
287
+ class="input-field"
288
+ type="${t}"
289
+ placeholder="${a}"
290
+ name="${i}"
291
+ .value="${this.state.value}"
292
+ ${o ? "required" : ""}
293
+ ${n ? `pattern="${n}"` : ""}
294
+ ${d ? `minlength="${d}"` : ""}
295
+ ${c ? `maxlength="${c}"` : ""}
296
+ ${h ? `min="${h}"` : ""}
297
+ ${u ? `max="${u}"` : ""}
298
+ ${b ? "disabled" : ""}
299
+ aria-invalid="${m}"
300
+ aria-describedby="${i}-error"
301
+ />
302
+ <span class="input-error${m && r ? "" : " hidden"}" id="${i}-error" role="alert">${r}</span>
303
+ </div>
304
+ `, this.inputEl = this.shadowRoot.querySelector(".input-field"), this.inputEl && (this.inputEl.addEventListener("input", this.handleInput.bind(this)), this.inputEl.addEventListener("blur", this.handleBlur.bind(this)));
305
+ }
306
+ }
307
+ customElements.define("ui-input", L);
308
+ class z extends g {
309
+ constructor() {
310
+ super(...arguments);
311
+ p(this, "columns", []);
312
+ p(this, "rows", []);
313
+ }
314
+ connectedCallback() {
315
+ this.setAttribute("data-ui", "table"), super.connectedCallback();
316
+ }
317
+ set data(t) {
318
+ this.columns = t.columns, this.rows = t.rows, this.render();
319
+ }
320
+ get data() {
321
+ return { columns: this.columns, rows: this.rows };
322
+ }
323
+ render() {
324
+ const t = this.columns.filter((i) => i.visible !== !1), e = t.map(
325
+ (i) => `<th class="align-${i.align ?? "left"}">${i.label}</th>`
326
+ ).join(""), a = this.rows.map(
327
+ (i, r) => `<tr data-row-index="${r}">${t.map(
328
+ (o) => o.actions ? `<td class="align-center actions-cell">
329
+ ${o.actions.edit ? `<ui-button variant="primary" class='action-btn' icon='edit' size="sm" data-action="edit" data-row-index="${r}">Edit</ui-button>` : ""}
330
+ ${o.actions.delete ? `<ui-button variant="danger" class='action-btn' icon='trash' size="sm" data-action="delete" data-row-index="${r}">Delete</ui-button>` : ""}
331
+ </td>` : `<td class="align-${o.align ?? "left"}">${String(
332
+ i[o.key] ?? ""
333
+ )}</td>`
334
+ ).join("")}</tr>`
335
+ ).join("");
336
+ this.shadowRoot.innerHTML = `
337
+ <style>${f}</style>
338
+ <div class="table-wrap">
339
+ <table>
340
+ <thead><tr>${e}</tr></thead>
341
+ <tbody>${a}</tbody>
342
+ </table>
343
+ </div>
344
+ `, this.shadowRoot.querySelectorAll(".action-btn").forEach((i) => {
345
+ i.addEventListener("click", (r) => {
346
+ const o = r.currentTarget, n = o.dataset.action, d = parseInt(o.dataset.rowIndex || "0", 10), c = n === "edit" ? "edit-action" : "delete-action";
347
+ this.dispatchEvent(new CustomEvent(c, {
348
+ bubbles: !0,
349
+ composed: !0,
350
+ detail: { row: this.rows[d], rowIndex: d }
351
+ }));
352
+ });
353
+ });
354
+ }
355
+ }
356
+ customElements.define("ui-table", z);
357
+ class I extends g {
358
+ constructor() {
359
+ super(...arguments);
360
+ p(this, "inputElement", null);
361
+ p(this, "isConnected", !1);
362
+ p(this, "isInternalUpdate", !1);
363
+ p(this, "hasRendered", !1);
364
+ }
365
+ connectedCallback() {
366
+ this.setAttribute("data-ui", "date-picker"), super.connectedCallback(), this.isConnected = !0;
367
+ }
368
+ static get observedAttributes() {
369
+ return ["value", "format", "min", "max", "disabled", "placeholder", "label"];
370
+ }
371
+ attributeChangedCallback(t, e, a) {
372
+ if (!(!this.isConnected || e === a)) {
373
+ if (this.isInternalUpdate && t === "value") {
374
+ this.isInternalUpdate = !1;
375
+ return;
376
+ }
377
+ t === "value" ? this.updateInputValues() : this.render();
378
+ }
379
+ }
380
+ updateInputValues() {
381
+ if (!this.shadowRoot) return;
382
+ const t = this.shadowRoot.querySelector(".formatted-input"), e = this.shadowRoot.querySelector('input[type="date"]');
383
+ if (t && e) {
384
+ const a = this.getValue(), i = this.getFormat(), r = this.formatDate(a, i);
385
+ t.value = r, e.value = a;
386
+ }
387
+ }
388
+ getFormat() {
389
+ const t = this.getAttribute("format");
390
+ return t === "DD/MM/YYYY" || t === "MM/DD/YYYY" || t === "DD-MM-YYYY" || t === "MM-DD-YYYY" ? t : "YYYY-MM-DD";
391
+ }
392
+ getValue() {
393
+ return this.getAttribute("value") || "";
394
+ }
395
+ getMin() {
396
+ return this.getAttribute("min") || "";
397
+ }
398
+ getMax() {
399
+ return this.getAttribute("max") || "";
400
+ }
401
+ getPlaceholder() {
402
+ return this.getAttribute("placeholder") || this.getFormat();
403
+ }
404
+ getLabel() {
405
+ return this.getAttribute("label") || "";
406
+ }
407
+ isDisabled() {
408
+ return this.hasAttribute("disabled");
409
+ }
410
+ /**
411
+ * Convert date from ISO format (YYYY-MM-DD) to specified format
412
+ */
413
+ formatDate(t, e) {
414
+ if (!t) return "";
415
+ const a = t.split("-");
416
+ if (a.length !== 3) return t;
417
+ const [i, r, o] = a;
418
+ switch (e) {
419
+ case "DD/MM/YYYY":
420
+ return `${o}/${r}/${i}`;
421
+ case "MM/DD/YYYY":
422
+ return `${r}/${o}/${i}`;
423
+ case "DD-MM-YYYY":
424
+ return `${o}-${r}-${i}`;
425
+ case "MM-DD-YYYY":
426
+ return `${r}-${o}-${i}`;
427
+ case "YYYY-MM-DD":
428
+ default:
429
+ return t;
430
+ }
431
+ }
432
+ /**
433
+ * Convert date from specified format to ISO format (YYYY-MM-DD)
434
+ */
435
+ parseDate(t, e) {
436
+ if (!t) return "";
437
+ let a, i, r, o;
438
+ switch (e) {
439
+ case "DD/MM/YYYY":
440
+ if (a = t.split("/"), a.length !== 3) return "";
441
+ [o, r, i] = a;
442
+ break;
443
+ case "MM/DD/YYYY":
444
+ if (a = t.split("/"), a.length !== 3) return "";
445
+ [r, o, i] = a;
446
+ break;
447
+ case "DD-MM-YYYY":
448
+ if (a = t.split("-"), a.length !== 3) return "";
449
+ [o, r, i] = a;
450
+ break;
451
+ case "MM-DD-YYYY":
452
+ if (a = t.split("-"), a.length !== 3) return "";
453
+ [r, o, i] = a;
454
+ break;
455
+ case "YYYY-MM-DD":
456
+ default:
457
+ return t;
458
+ }
459
+ return r = r.padStart(2, "0"), o = o.padStart(2, "0"), `${i}-${r}-${o}`;
460
+ }
461
+ attachEventListeners() {
462
+ if (!this.shadowRoot) return;
463
+ const t = this.shadowRoot.querySelector(".formatted-input"), e = this.shadowRoot.querySelector('input[type="date"]'), a = this.shadowRoot.querySelector(".calendar-btn");
464
+ if (!t || !e) return;
465
+ const i = () => {
466
+ const r = t.value, o = this.getFormat(), n = this.parseDate(r, o);
467
+ this.isValidDate(n) ? (e.value = n, t.classList.remove("invalid"), this.dispatchDateChange(n)) : r === "" ? (e.value = "", t.classList.remove("invalid"), this.dispatchDateChange("")) : t.classList.add("invalid");
468
+ };
469
+ t.addEventListener("blur", i), t.addEventListener("keydown", (r) => {
470
+ r.key === "Enter" && (i(), t.blur());
471
+ }), e.addEventListener("change", (r) => {
472
+ const n = r.target.value, d = this.getFormat(), c = this.formatDate(n, d);
473
+ t.value = c, t.classList.remove("invalid"), this.dispatchDateChange(n);
474
+ }), a && a.addEventListener("click", async (r) => {
475
+ r.preventDefault(), r.stopPropagation(), e.style.pointerEvents = "auto";
476
+ try {
477
+ typeof e.showPicker == "function" ? e.showPicker() : (e.focus(), e.click());
478
+ } catch (o) {
479
+ console.log("Date picker error:", o), e.focus(), e.click();
480
+ } finally {
481
+ setTimeout(() => {
482
+ e.style.pointerEvents = "none";
483
+ }, 100);
484
+ }
485
+ });
486
+ }
487
+ isValidDate(t) {
488
+ if (!t) return !1;
489
+ const e = new Date(t);
490
+ return e instanceof Date && !isNaN(e.getTime());
491
+ }
492
+ dispatchDateChange(t) {
493
+ const e = this.getFormat(), a = this.formatDate(t, e);
494
+ this.dispatchEvent(
495
+ new CustomEvent("date-change", {
496
+ detail: {
497
+ value: t,
498
+ formattedValue: a,
499
+ format: e
500
+ },
501
+ bubbles: !0,
502
+ composed: !0
503
+ })
504
+ ), this.isInternalUpdate = !0, this.setAttribute("value", t);
505
+ }
506
+ /**
507
+ * Get the current value in ISO format (YYYY-MM-DD)
508
+ */
509
+ getISOValue() {
510
+ return this.getValue();
511
+ }
512
+ /**
513
+ * Get the current value in the specified format
514
+ */
515
+ getFormattedValue() {
516
+ const t = this.getValue(), e = this.getFormat();
517
+ return this.formatDate(t, e);
518
+ }
519
+ /**
520
+ * Set the date value (accepts ISO format)
521
+ */
522
+ setValue(t) {
523
+ this.setAttribute("value", t);
524
+ }
525
+ /**
526
+ * Clear the date value
527
+ */
528
+ clear() {
529
+ this.setAttribute("value", "");
530
+ }
531
+ render() {
532
+ const t = this.getValue(), e = this.getFormat(), a = this.getMin(), i = this.getMax(), r = this.isDisabled(), o = this.getPlaceholder(), n = this.getLabel(), d = this.formatDate(t, e), c = n !== "";
533
+ this.shadowRoot.innerHTML = `
534
+ <style>${f}</style>
535
+ <div class="date-picker-container">
536
+ ${c ? `<label class="date-picker-label">${n}</label>` : ""}
537
+ <div class="date-input-wrapper ${r ? "disabled" : ""}">
538
+ <input
539
+ type="text"
540
+ class="formatted-input"
541
+ part="input"
542
+ value="${d}"
543
+ placeholder="${o}"
544
+ ${r ? "disabled" : ""}
545
+ />
546
+ <button
547
+ class="calendar-btn"
548
+ type="button"
549
+ ${r ? "disabled" : ""}
550
+ title="Open calendar"
551
+ >
552
+ <svg class="calendar-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
553
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"/>
554
+ </svg>
555
+ </button>
556
+ <input
557
+ type="date"
558
+ class="hidden-date-input"
559
+ value="${t}"
560
+ ${a ? `min="${a}"` : ""}
561
+ ${i ? `max="${i}"` : ""}
562
+ ${r ? "disabled" : ""}
563
+ />
564
+ </div>
565
+ <div class="format-label">Format: ${e}</div>
566
+ </div>
567
+ `, this.attachEventListeners(), this.hasRendered = !0;
568
+ }
569
+ }
570
+ customElements.define("ui-date-picker", I);
571
+ class T extends g {
572
+ constructor() {
573
+ super(...arguments);
574
+ p(this, "_total", 0);
575
+ p(this, "_currentPage", 1);
576
+ p(this, "_pageSize", 10);
577
+ }
578
+ connectedCallback() {
579
+ this.setAttribute("data-ui", "pagination"), super.connectedCallback();
580
+ }
581
+ static get observedAttributes() {
582
+ return ["total", "current-page", "page-size"];
583
+ }
584
+ attributeChangedCallback(t, e, a) {
585
+ switch (t) {
586
+ case "total":
587
+ this._total = parseInt(a, 10) || 0;
588
+ break;
589
+ case "current-page":
590
+ this._currentPage = parseInt(a, 10) || 1;
591
+ break;
592
+ case "page-size":
593
+ this._pageSize = parseInt(a, 10) || 10;
594
+ break;
595
+ }
596
+ this.render();
597
+ }
598
+ get total() {
599
+ return this._total;
600
+ }
601
+ set total(t) {
602
+ this._total = t, this.setAttribute("total", String(t));
603
+ }
604
+ get currentPage() {
605
+ return this._currentPage;
606
+ }
607
+ set currentPage(t) {
608
+ this._currentPage = t, this.setAttribute("current-page", String(t));
609
+ }
610
+ get pageSize() {
611
+ return this._pageSize;
612
+ }
613
+ set pageSize(t) {
614
+ this._pageSize = t, this.setAttribute("page-size", String(t));
615
+ }
616
+ get totalPages() {
617
+ return Math.ceil(this._total / this._pageSize);
618
+ }
619
+ handlePageChange(t) {
620
+ t < 1 || t > this.totalPages || t === this._currentPage || (this.currentPage = t, this.dispatchEvent(
621
+ new CustomEvent("page-change", {
622
+ detail: {
623
+ page: t,
624
+ pageSize: this._pageSize,
625
+ total: this._total,
626
+ totalPages: this.totalPages
627
+ },
628
+ bubbles: !0,
629
+ composed: !0
630
+ })
631
+ ));
632
+ }
633
+ getPageNumbers() {
634
+ const t = this.totalPages, e = this._currentPage;
635
+ if (t <= 7)
636
+ return Array.from({ length: t }, (i, r) => r + 1);
637
+ const a = [];
638
+ return e <= 3 ? a.push(1, 2, 3, 4, "...", t) : e >= t - 2 ? a.push(1, "...", t - 3, t - 2, t - 1, t) : a.push(1, "...", e - 1, e, e + 1, "...", t), a;
639
+ }
640
+ render() {
641
+ const t = this.totalPages, e = this._currentPage, a = this.getPageNumbers(), i = (e - 1) * this._pageSize + 1, r = Math.min(e * this._pageSize, this._total);
642
+ this.shadowRoot.innerHTML = `
643
+ <style>${f}</style>
644
+ <div class="pagination-container">
645
+ <div class="pagination-info">
646
+ ${this._total > 0 ? `Showing ${i} to ${r} of ${this._total}` : "No results"}
647
+ </div>
648
+ ${t > 1 ? `
649
+ <nav class="pagination" role="navigation" aria-label="Pagination">
650
+ <button
651
+ class="page-btn nav-btn"
652
+ ${e === 1 ? "disabled" : ""}
653
+ data-page="prev"
654
+ aria-label="Previous page"
655
+ >
656
+ <svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
657
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"/>
658
+ </svg>
659
+ </button>
660
+ ${a.map((o) => o === "..." ? '<button class="page-btn ellipsis" disabled>...</button>' : `
661
+ <button
662
+ class="page-btn ${o === e ? "active" : ""}"
663
+ data-page="${o}"
664
+ aria-label="Page ${o}"
665
+ ${o === e ? 'aria-current="page"' : ""}
666
+ >
667
+ ${o}
668
+ </button>
669
+ `).join("")}
670
+ <button
671
+ class="page-btn nav-btn"
672
+ ${e === t ? "disabled" : ""}
673
+ data-page="next"
674
+ aria-label="Next page"
675
+ >
676
+ <svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
677
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"/>
678
+ </svg>
679
+ </button>
680
+ </nav>
681
+ ` : ""}
682
+ </div>
683
+ `, this.attachEventListeners();
684
+ }
685
+ attachEventListeners() {
686
+ this.shadowRoot && this.shadowRoot.addEventListener("click", (t) => {
687
+ const a = t.target.closest(".page-btn");
688
+ if (!a || a.disabled) return;
689
+ const i = a.dataset.page;
690
+ if (i === "prev")
691
+ this.handlePageChange(this._currentPage - 1);
692
+ else if (i === "next")
693
+ this.handlePageChange(this._currentPage + 1);
694
+ else if (i) {
695
+ const r = parseInt(i, 10);
696
+ isNaN(r) || this.handlePageChange(r);
697
+ }
698
+ });
699
+ }
700
+ }
701
+ customElements.define("ui-pagination", T);
702
+ class M extends g {
703
+ constructor() {
704
+ super(...arguments);
705
+ p(this, "isOpen", this.useSignal(!1));
706
+ }
707
+ connectedCallback() {
708
+ this.setAttribute("data-ui", "modal"), super.connectedCallback(), this.setupEventListeners();
709
+ }
710
+ static get observedAttributes() {
711
+ return ["open"];
712
+ }
713
+ attributeChangedCallback(t, e, a) {
714
+ t === "open" && e !== a && this.isOpen.set(a !== null);
715
+ }
716
+ setupEventListeners() {
717
+ document.addEventListener("keydown", (t) => {
718
+ t.key === "Escape" && this.isOpen.get() && !this.hasAttribute("no-close-on-escape") && this.close();
719
+ });
720
+ }
721
+ open() {
722
+ this.isOpen.set(!0), this.setAttribute("open", ""), this.dispatchEvent(new CustomEvent("modal-open", { bubbles: !0, composed: !0 })), document.body.style.overflow = "hidden";
723
+ }
724
+ close() {
725
+ this.isOpen.set(!1), this.removeAttribute("open"), this.dispatchEvent(new CustomEvent("modal-close", { bubbles: !0, composed: !0 })), document.body.style.overflow = "";
726
+ }
727
+ handleBackdropClick(t) {
728
+ t.target.classList.contains("modal-backdrop") && !this.hasAttribute("no-close-on-backdrop") && this.close();
729
+ }
730
+ render() {
731
+ const t = this.isOpen.get(), e = this.getAttribute("title") || "", a = this.getAttribute("size") || "md";
732
+ this.shadowRoot.innerHTML = `
733
+ <style>
734
+ ${f}
735
+
736
+ ::slotted([slot="footer"]) {
737
+ display: flex;
738
+ gap: 0.75rem;
739
+ width: 100%;
740
+ justify-content: flex-end;
741
+ }
742
+ </style>
743
+
744
+ <div class="modal-backdrop ${t ? "open" : ""}" part="backdrop">
745
+ <div class="modal-content ${a}" part="content" @click="${(o) => o.stopPropagation()}">
746
+ ${e ? `
747
+ <div class="modal-header" part="header">
748
+ <h2 class="modal-title">${e}</h2>
749
+ <button class="modal-close" part="close" aria-label="Close modal">
750
+ <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
751
+ <line x1="18" y1="6" x2="6" y2="18"></line>
752
+ <line x1="6" y1="6" x2="18" y2="18"></line>
753
+ </svg>
754
+ </button>
755
+ </div>
756
+ ` : ""}
757
+
758
+ <div class="modal-body" part="body">
759
+ <slot></slot>
760
+ </div>
761
+
762
+ <div class="modal-footer" part="footer">
763
+ <slot name="footer"></slot>
764
+ </div>
765
+ </div>
766
+ </div>
767
+ `;
768
+ const i = this.shadowRoot.querySelector(".modal-backdrop"), r = this.shadowRoot.querySelector(".modal-close");
769
+ i == null || i.addEventListener("click", (o) => this.handleBackdropClick(o)), r == null || r.addEventListener("click", () => this.close());
770
+ }
771
+ }
772
+ customElements.define("ui-modal", M);
773
+ class R extends g {
774
+ constructor() {
775
+ super(...arguments);
776
+ p(this, "isOpen", this.useSignal(!1));
777
+ p(this, "selectedValue", this.useSignal(""));
778
+ p(this, "searchTerm", this.useSignal(""));
779
+ p(this, "options", []);
780
+ }
781
+ connectedCallback() {
782
+ this.setAttribute("data-ui", "select"), super.connectedCallback(), this.parseOptions(), this.setupClickOutside();
783
+ }
784
+ static get observedAttributes() {
785
+ return ["value", "disabled", "placeholder", "options"];
786
+ }
787
+ attributeChangedCallback(t, e, a) {
788
+ t === "value" && e !== a && this.selectedValue.set(a || ""), t === "options" && e !== a && this.parseOptions(), this.render();
789
+ }
790
+ parseOptions() {
791
+ const t = this.getAttribute("options");
792
+ if (t)
793
+ try {
794
+ this.options = JSON.parse(t);
795
+ } catch (e) {
796
+ console.error("Invalid options JSON", e), this.options = [];
797
+ }
798
+ }
799
+ setupClickOutside() {
800
+ document.addEventListener("click", (t) => {
801
+ !t.composedPath().includes(this) && this.isOpen.get() && this.isOpen.set(!1);
802
+ });
803
+ }
804
+ toggleDropdown() {
805
+ this.hasAttribute("disabled") || (this.isOpen.set(!this.isOpen.get()), this.isOpen.get() || this.searchTerm.set(""));
806
+ }
807
+ selectOption(t) {
808
+ this.selectedValue.set(t), this.setAttribute("value", t), this.isOpen.set(!1), this.searchTerm.set(""), this.dispatchEvent(new CustomEvent("select-change", {
809
+ bubbles: !0,
810
+ composed: !0,
811
+ detail: {
812
+ value: t,
813
+ option: this.options.find((e) => e.value === t)
814
+ }
815
+ }));
816
+ }
817
+ handleSearch(t) {
818
+ this.searchTerm.set(t.toLowerCase());
819
+ }
820
+ getFilteredOptions() {
821
+ const t = this.searchTerm.get();
822
+ return t ? this.options.filter(
823
+ (e) => e.label.toLowerCase().includes(t) || e.value.toLowerCase().includes(t)
824
+ ) : this.options;
825
+ }
826
+ getSelectedLabel() {
827
+ const t = this.selectedValue.get(), e = this.options.find((a) => a.value === t);
828
+ return (e == null ? void 0 : e.label) || this.getAttribute("placeholder") || "Select an option";
829
+ }
830
+ render() {
831
+ const t = this.isOpen.get(), e = this.hasAttribute("disabled"), a = this.hasAttribute("searchable"), i = this.getAttribute("label") || "", r = this.getSelectedLabel(), o = this.getFilteredOptions(), n = this.selectedValue.get() !== "";
832
+ this.shadowRoot.innerHTML = `
833
+ <style>${f}</style>
834
+
835
+ <div class="select-container">
836
+ ${i ? `<label class="select-label">${i}</label>` : ""}
837
+
838
+ <div class="select-trigger ${t ? "open" : ""}" part="trigger" tabindex="0" ${e ? "disabled" : ""}>
839
+ <span class="select-placeholder ${n ? "has-selection" : ""}">${r}</span>
840
+ <span class="select-arrow ${t ? "open" : ""}">
841
+ <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
842
+ <polyline points="6 9 12 15 18 9"></polyline>
843
+ </svg>
844
+ </span>
845
+ </div>
846
+
847
+ <div class="select-dropdown ${t ? "open" : ""}" part="dropdown">
848
+ ${a ? `
849
+ <input
850
+ type="text"
851
+ class="select-search"
852
+ placeholder="Search..."
853
+ part="search"
854
+ >
855
+ ` : ""}
856
+
857
+ ${o.length > 0 ? o.map((u) => `
858
+ <div
859
+ class="select-option ${u.value === this.selectedValue.get() ? "selected" : ""} ${u.disabled ? "disabled" : ""}"
860
+ data-value="${u.value}"
861
+ part="option"
862
+ >
863
+ ${u.label}
864
+ </div>
865
+ `).join("") : `
866
+ <div class="select-empty">No options found</div>
867
+ `}
868
+ </div>
869
+ </div>
870
+ `;
871
+ const d = this.shadowRoot.querySelector(".select-trigger"), c = this.shadowRoot.querySelector(".select-search"), h = this.shadowRoot.querySelectorAll(".select-option:not(.disabled)");
872
+ d == null || d.addEventListener("click", () => this.toggleDropdown()), d == null || d.addEventListener("keydown", (u) => {
873
+ (u.key === "Enter" || u.key === " ") && (u.preventDefault(), this.toggleDropdown());
874
+ }), c == null || c.addEventListener("input", (u) => {
875
+ this.handleSearch(u.target.value);
876
+ }), c == null || c.addEventListener("click", (u) => u.stopPropagation()), h.forEach((u) => {
877
+ u.addEventListener("click", () => {
878
+ const b = u.getAttribute("data-value");
879
+ b && this.selectOption(b);
880
+ });
881
+ });
882
+ }
883
+ }
884
+ customElements.define("ui-select", R);
885
+ class D extends g {
886
+ constructor() {
887
+ super(...arguments);
888
+ p(this, "checked", this.useSignal(!1));
889
+ p(this, "indeterminate", this.useSignal(!1));
890
+ }
891
+ connectedCallback() {
892
+ this.setAttribute("data-ui", "checkbox"), super.connectedCallback();
893
+ }
894
+ static get observedAttributes() {
895
+ return ["checked", "disabled", "indeterminate"];
896
+ }
897
+ attributeChangedCallback(t, e, a) {
898
+ t === "checked" && e !== a && this.checked.set(a !== null), t === "indeterminate" && e !== a && this.indeterminate.set(a !== null), this.render();
899
+ }
900
+ handleChange() {
901
+ if (this.hasAttribute("disabled")) return;
902
+ this.indeterminate.get() && (this.indeterminate.set(!1), this.removeAttribute("indeterminate"));
903
+ const t = !this.checked.get();
904
+ this.checked.set(t), t ? this.setAttribute("checked", "") : this.removeAttribute("checked"), this.dispatchEvent(new CustomEvent("checkbox-change", {
905
+ bubbles: !0,
906
+ composed: !0,
907
+ detail: { checked: t }
908
+ }));
909
+ }
910
+ setChecked(t) {
911
+ this.checked.set(t), t ? this.setAttribute("checked", "") : this.removeAttribute("checked"), this.indeterminate.set(!1), this.removeAttribute("indeterminate");
912
+ }
913
+ setIndeterminate(t) {
914
+ this.indeterminate.set(t), t ? this.setAttribute("indeterminate", "") : this.removeAttribute("indeterminate");
915
+ }
916
+ render() {
917
+ const t = this.checked.get(), e = this.indeterminate.get(), a = this.hasAttribute("disabled"), i = this.getAttribute("label") || "", r = this.getAttribute("size") || "md", o = {
918
+ sm: "size-sm",
919
+ md: "size-md",
920
+ lg: "size-lg"
921
+ };
922
+ this.shadowRoot.innerHTML = `
923
+ <style>${f}</style>
924
+
925
+ <label class="checkbox-container ${o[r]}">
926
+ <input
927
+ type="checkbox"
928
+ ${t ? "checked" : ""}
929
+ ${a ? "disabled" : ""}
930
+ >
931
+ <div class="checkbox-box ${o[r]} ${t ? "checked" : ""} ${e ? "indeterminate" : ""} ${a ? "disabled" : ""}" part="checkbox">
932
+ <svg class="checkbox-icon check" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3">
933
+ <polyline points="20 6 9 17 4 12"></polyline>
934
+ </svg>
935
+ <svg class="checkbox-icon minus" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3">
936
+ <line x1="5" y1="12" x2="19" y2="12"></line>
937
+ </svg>
938
+ </div>
939
+ ${i ? `<span class="checkbox-label">${i}</span>` : "<slot></slot>"}
940
+ </label>
941
+ `;
942
+ const n = this.shadowRoot.querySelector(".checkbox-container");
943
+ n == null || n.addEventListener("click", (d) => {
944
+ d.preventDefault(), this.handleChange();
945
+ });
946
+ }
947
+ }
948
+ customElements.define("ui-checkbox", D);
949
+ const q = ':host{display:block}.tabs{background:var(--color-page-bg);border-radius:16px;box-shadow:0 1px 3px #0000000a,0 4px 12px #00000008;overflow:hidden;position:relative}.tablist{display:flex;position:relative;padding:8px;gap:4px;background:linear-gradient(180deg,#fafafa,#f5f5f5);border-bottom:1px solid rgba(0,0,0,.04)}.tab-indicator{position:absolute;bottom:8px;height:calc(100% - 16px);background:var(--color-page-bg);border-radius:10px;box-shadow:0 2px 8px #0000000f,0 1px 2px #0000000a;transition:transform .28s cubic-bezier(.4,0,.2,1),width .28s cubic-bezier(.4,0,.2,1);pointer-events:none;z-index:0}::slotted([slot="tab"]){-webkit-appearance:none;-moz-appearance:none;appearance:none;background:transparent;border:none;color:#64748b;cursor:pointer;font:600 13px/1 DM Sans,system-ui,-apple-system,sans-serif;letter-spacing:.02em;padding:10px 18px;position:relative;transition:color .2s ease;-webkit-user-select:none;user-select:none;white-space:nowrap;z-index:1}::slotted([slot="tab"]:hover){color:var(--color-ink)}::slotted([slot="tab"].is-active){color:var(--color-ink)}::slotted([slot="tab"]:focus-visible){outline:none}::slotted([slot="tab"]:focus-visible):after{content:"";position:absolute;top:6px;right:6px;bottom:6px;left:6px;border:2px solid var(--color-primary);border-radius:8px;pointer-events:none}.panels{padding:24px 28px;min-height:200px}::slotted([slot="panel"]){animation:fadeIn .3s ease}::slotted([slot="panel"]:not(.is-active)){display:none}@keyframes fadeIn{0%{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}@media (prefers-reduced-motion: reduce){.tab-indicator{transition:none}::slotted([slot="panel"]){animation:none}}';
950
+ class Y extends g {
951
+ constructor() {
952
+ super(...arguments);
953
+ p(this, "activeId", null);
954
+ p(this, "indicator", null);
955
+ p(this, "handleTabClick", (t) => {
956
+ const e = t.target;
957
+ if (!e) return;
958
+ const a = e.closest('[slot="tab"][data-tab]');
959
+ if (!a) return;
960
+ t.preventDefault();
961
+ const i = a.getAttribute("data-tab");
962
+ i && this.setActive(i);
963
+ });
964
+ }
965
+ static get observedAttributes() {
966
+ return ["active"];
967
+ }
968
+ connectedCallback() {
969
+ this.setAttribute("data-ui", "tabs"), super.connectedCallback(), this.addEventListener("click", this.handleTabClick);
970
+ }
971
+ disconnectedCallback() {
972
+ this.removeEventListener("click", this.handleTabClick), super.disconnectedCallback();
973
+ }
974
+ attributeChangedCallback(t, e, a) {
975
+ t === "active" && e !== a && (this.activeId = a, this.syncTabs());
976
+ }
977
+ setActive(t) {
978
+ this.activeId !== t && (this.activeId = t, this.setAttribute("active", t), this.syncTabs(), this.dispatchEvent(new CustomEvent("tab-change", {
979
+ bubbles: !0,
980
+ composed: !0,
981
+ detail: { id: t }
982
+ })));
983
+ }
984
+ getTabs() {
985
+ var e;
986
+ const t = (e = this.shadowRoot) == null ? void 0 : e.querySelector('slot[name="tab"]');
987
+ return t ? t.assignedElements({ flatten: !0 }) : [];
988
+ }
989
+ getPanels() {
990
+ var e;
991
+ const t = (e = this.shadowRoot) == null ? void 0 : e.querySelector('slot[name="panel"]');
992
+ return t ? t.assignedElements({ flatten: !0 }) : [];
993
+ }
994
+ getActiveId(t) {
995
+ const e = this.getAttribute("active");
996
+ if (e && t.some((i) => i.getAttribute("data-tab") === e))
997
+ return e;
998
+ if (this.activeId && t.some((i) => i.getAttribute("data-tab") === this.activeId))
999
+ return this.activeId;
1000
+ const a = t.find((i) => i.getAttribute("data-tab"));
1001
+ return (a == null ? void 0 : a.getAttribute("data-tab")) ?? null;
1002
+ }
1003
+ syncTabs() {
1004
+ const t = this.getTabs(), e = this.getPanels();
1005
+ if (t.length === 0) return;
1006
+ const a = this.getActiveId(t);
1007
+ a && (this.activeId = a, this.getAttribute("active") !== a && this.setAttribute("active", a), t.forEach((i) => {
1008
+ const r = i.getAttribute("data-tab");
1009
+ if (!r) return;
1010
+ const o = i.id || `tab-${r}`, n = r === a;
1011
+ i.id = o, i.setAttribute("role", "tab"), i.setAttribute("aria-selected", String(n)), i.setAttribute("tabindex", n ? "0" : "-1"), i.classList.toggle("is-active", n);
1012
+ }), e.forEach((i) => {
1013
+ const r = i.getAttribute("data-tab");
1014
+ if (!r) return;
1015
+ const o = i.id || `panel-${r}`, n = r === a;
1016
+ i.id = o, i.setAttribute("role", "tabpanel"), i.toggleAttribute("hidden", !n), i.classList.toggle("is-active", n);
1017
+ const d = t.find((c) => c.getAttribute("data-tab") === r);
1018
+ d && (d.setAttribute("aria-controls", o), i.setAttribute("aria-labelledby", d.id));
1019
+ }), this.updateIndicator(t, a));
1020
+ }
1021
+ updateIndicator(t, e) {
1022
+ if (!this.indicator) return;
1023
+ const a = t.find((n) => n.getAttribute("data-tab") === e);
1024
+ if (!a) return;
1025
+ const i = this.shadowRoot.querySelector(".tablist");
1026
+ if (!i) return;
1027
+ a.getBoundingClientRect(), i.getBoundingClientRect();
1028
+ const r = t.indexOf(a);
1029
+ let o = 0;
1030
+ for (let n = 0; n < r; n++)
1031
+ o += t[n].offsetWidth;
1032
+ this.indicator.style.transform = `translateX(${o}px)`, this.indicator.style.width = `${a.offsetWidth}px`;
1033
+ }
1034
+ render() {
1035
+ this.shadowRoot.innerHTML = `
1036
+ <style>${f}${q}</style>
1037
+ <div class="tabs">
1038
+ <div class="tablist" role="tablist">
1039
+ <div class="tab-indicator"></div>
1040
+ <slot name="tab"></slot>
1041
+ </div>
1042
+ <div class="panels">
1043
+ <slot name="panel"></slot>
1044
+ </div>
1045
+ </div>
1046
+ `, this.indicator = this.shadowRoot.querySelector(".tab-indicator");
1047
+ const t = this.shadowRoot.querySelector('slot[name="tab"]'), e = this.shadowRoot.querySelector('slot[name="panel"]');
1048
+ t == null || t.addEventListener("slotchange", () => this.syncTabs()), e == null || e.addEventListener("slotchange", () => this.syncTabs()), requestAnimationFrame(() => this.syncTabs());
1049
+ }
1050
+ }
1051
+ customElements.define("ui-tabs", Y);
1052
+ const P = ':host{display:block;--card-transition: all .3s cubic-bezier(.4, 0, .2, 1)}:host([data-ui="card"]){display:block}.card{background:#fff;padding:24px;box-sizing:border-box;width:100%;position:relative;transition:var(--card-transition);overflow:hidden}.card.rounded{border-radius:16px}.card.square{border-radius:0}.card.default{border:1px solid #e5e7eb;background:#fff}.card.elevated{border:none;background:linear-gradient(to bottom,#fff,#fafbfc)}.card.bordered{border:2px solid #e5e7eb;background:#fff}.card.ghost{border:1px dashed #d1d5db;background:transparent}.card.default:hover{border-color:#d1d5db;transform:translateY(-2px)}.card.elevated:hover{transform:translateY(-4px)}.card.bordered:hover{border-color:#9ca3af;background:#fafbfc}.card.ghost:hover{border-color:#9ca3af;background:#f9fafb80}.card.elevated:before{content:"";position:absolute;top:0;right:0;bottom:0;left:0;border-radius:inherit;padding:2px;background:linear-gradient(135deg,#6366f11a,#ec48991a);-webkit-mask:linear-gradient(#fff 0 0) content-box,linear-gradient(#fff 0 0);mask:linear-gradient(#fff 0 0) content-box,linear-gradient(#fff 0 0);-webkit-mask-composite:xor;mask-composite:exclude;opacity:0;transition:opacity .3s ease;pointer-events:none}.card.elevated:hover:before{opacity:1}.card ::slotted(*:first-child){margin-top:0}.card ::slotted(*:last-child){margin-bottom:0}.card:focus-within{outline:2px solid #9ec5ff;outline-offset:2px}@media (max-width: 768px){.card{padding:20px}.card.rounded{border-radius:12px}}@media (max-width: 480px){.card{padding:16px}.card.rounded{border-radius:10px}}@media print{.card{border:1px solid #e5e7eb;box-shadow:none!important;page-break-inside:avoid}}';
1053
+ class H extends g {
1054
+ connectedCallback() {
1055
+ this.setAttribute("data-ui", "card"), super.connectedCallback();
1056
+ }
1057
+ static get observedAttributes() {
1058
+ return ["shadow", "shadow-color", "rounded", "variant", "elevation"];
1059
+ }
1060
+ attributeChangedCallback() {
1061
+ this.render();
1062
+ }
1063
+ getShadow() {
1064
+ return this.hasAttribute("shadow") && this.getAttribute("shadow") !== "false";
1065
+ }
1066
+ getShadowColor() {
1067
+ return this.getAttribute("shadow-color") ?? "0, 0, 0";
1068
+ }
1069
+ getRounded() {
1070
+ return this.getAttribute("rounded") !== "false";
1071
+ }
1072
+ getVariant() {
1073
+ const s = this.getAttribute("variant");
1074
+ return s === "elevated" || s === "bordered" || s === "ghost" ? s : "default";
1075
+ }
1076
+ getElevation() {
1077
+ const s = this.getAttribute("elevation");
1078
+ return s === "none" || s === "sm" || s === "md" || s === "lg" || s === "xl" ? s : "sm";
1079
+ }
1080
+ render() {
1081
+ const s = this.getShadow(), t = this.getShadowColor(), e = this.getRounded(), a = this.getVariant(), i = this.getElevation();
1082
+ let r = "none";
1083
+ if (s)
1084
+ switch (i) {
1085
+ case "sm":
1086
+ r = `0 1px 2px rgba(${t}, 0.05), 0 1px 3px rgba(${t}, 0.1)`;
1087
+ break;
1088
+ case "md":
1089
+ r = `0 4px 6px rgba(${t}, 0.07), 0 2px 4px rgba(${t}, 0.06)`;
1090
+ break;
1091
+ case "lg":
1092
+ r = `0 10px 15px rgba(${t}, 0.1), 0 4px 6px rgba(${t}, 0.05)`;
1093
+ break;
1094
+ case "xl":
1095
+ r = `0 20px 25px rgba(${t}, 0.15), 0 10px 10px rgba(${t}, 0.04)`;
1096
+ break;
1097
+ default:
1098
+ r = "none";
1099
+ }
1100
+ this.shadowRoot.innerHTML = `
1101
+ <style>
1102
+ ${f}
1103
+ ${P}
1104
+
1105
+ .card.custom-shadow {
1106
+ box-shadow: ${r};
1107
+ }
1108
+
1109
+ .card.custom-shadow:hover {
1110
+ box-shadow: ${s && i !== "none" ? r.replace(/rgba\(([^)]+), ([\d.]+)\)/g, (o, n, d) => `rgba(${n}, ${Math.min(parseFloat(d) * 1.3, 0.25)})`) : "none"};
1111
+ }
1112
+ </style>
1113
+ <div class="card ${a} ${e ? "rounded" : "square"} ${s ? "custom-shadow" : "no-shadow"}">
1114
+ <slot></slot>
1115
+ </div>
1116
+ `;
1117
+ }
1118
+ }
1119
+ customElements.define("ui-card", H);
1120
+ const O = ":host{--toast-success: #10b981;--toast-error: #ef4444;--toast-warning: #f59e0b;--toast-info: #3b82f6;--toast-bg: rgba(255, 255, 255, .95);--toast-blur: blur(12px);--toast-shadow: 0 8px 32px rgba(0, 0, 0, .12), 0 2px 8px rgba(0, 0, 0, .08);--toast-border: rgba(255, 255, 255, .3);--toast-text: #1e293b;--toast-radius: 14px;--toast-icon-size: 20px}.toast-container{position:fixed;z-index:10000;pointer-events:none;display:flex;flex-direction:column;gap:12px;max-width:420px;padding:16px}.toast-container.top-right{top:0;right:0}.toast-container.top-left{top:0;left:0}.toast-container.bottom-right{bottom:0;right:0;flex-direction:column-reverse}.toast-container.bottom-left{bottom:0;left:0;flex-direction:column-reverse}.toast-container.top-center{top:0;left:50%;transform:translate(-50%)}.toast-container.bottom-center{bottom:0;left:50%;transform:translate(-50%);flex-direction:column-reverse}.toast{pointer-events:auto;background:var(--toast-bg);backdrop-filter:var(--toast-blur);-webkit-backdrop-filter:var(--toast-blur);border:1px solid var(--toast-border);border-radius:var(--toast-radius);box-shadow:var(--toast-shadow);padding:16px 20px;min-width:300px;max-width:100%;display:flex;align-items:flex-start;gap:14px;position:relative;overflow:hidden;opacity:0;transform:translate(100px);animation:toastSlideIn .4s cubic-bezier(.16,1,.3,1) forwards}.toast.closing{animation:toastSlideOut .3s cubic-bezier(.5,0,.75,0) forwards}.toast-container.top-left .toast,.toast-container.bottom-left .toast{transform:translate(-100px);animation:toastSlideInLeft .4s cubic-bezier(.16,1,.3,1) forwards}.toast-container.top-left .toast.closing,.toast-container.bottom-left .toast.closing{animation:toastSlideOutLeft .3s cubic-bezier(.5,0,.75,0) forwards}.toast-container.top-center .toast,.toast-container.bottom-center .toast{transform:translateY(-50px);animation:toastSlideInTop .4s cubic-bezier(.16,1,.3,1) forwards}.toast-container.top-center .toast.closing,.toast-container.bottom-center .toast.closing{animation:toastSlideOutTop .3s cubic-bezier(.5,0,.75,0) forwards}.toast-icon{flex-shrink:0;width:var(--toast-icon-size);height:var(--toast-icon-size);display:flex;align-items:center;justify-content:center;margin-top:2px}.toast-icon svg{width:100%;height:100%;stroke-width:2.5}.toast.success .toast-icon{color:var(--toast-success)}.toast.error .toast-icon{color:var(--toast-error)}.toast.warning .toast-icon{color:var(--toast-warning)}.toast.info .toast-icon{color:var(--toast-info)}.toast.success:before{background:linear-gradient(135deg,var(--toast-success),rgba(16,185,129,.7))}.toast.error:before{background:linear-gradient(135deg,var(--toast-error),rgba(239,68,68,.7))}.toast.warning:before{background:linear-gradient(135deg,var(--toast-warning),rgba(245,158,11,.7))}.toast.info:before{background:linear-gradient(135deg,var(--toast-info),rgba(59,130,246,.7))}.toast-content{flex:1;min-width:0}.toast-title{margin:0 0 4px;font-size:15px;font-weight:600;color:var(--toast-text);line-height:1.4}.toast-description{margin:0;font-size:13.5px;color:#64748b;line-height:1.5}.toast-close{flex-shrink:0;width:20px;height:20px;padding:0;border:none;background:transparent;color:#94a3b8;cursor:pointer;display:flex;align-items:center;justify-content:center;border-radius:4px;transition:all .15s ease;margin-top:2px}.toast-close:hover{background:#0000000d;color:var(--toast-text)}.toast-close svg{width:14px;height:14px;stroke-width:2.5}.toast-progress{position:absolute;bottom:0;left:0;height:3px;width:100%;border-radius:0 0 var(--toast-radius) var(--toast-radius);overflow:hidden;background:#0000000d}.toast-progress-bar{height:100%;width:100%;transform-origin:left;animation:toastProgress var(--duration) linear forwards}.toast.success .toast-progress-bar{background:var(--toast-success)}.toast.error .toast-progress-bar{background:var(--toast-error)}.toast.warning .toast-progress-bar{background:var(--toast-warning)}.toast.info .toast-progress-bar{background:var(--toast-info)}@keyframes toastSlideIn{0%{opacity:0;transform:translate(100px) scale(.95)}to{opacity:1;transform:translate(0) scale(1)}}@keyframes toastSlideOut{0%{opacity:1;transform:translate(0) scale(1)}to{opacity:0;transform:translate(100px) scale(.95)}}@keyframes toastSlideInLeft{0%{opacity:0;transform:translate(-100px) scale(.95)}to{opacity:1;transform:translate(0) scale(1)}}@keyframes toastSlideOutLeft{0%{opacity:1;transform:translate(0) scale(1)}to{opacity:0;transform:translate(-100px) scale(.95)}}@keyframes toastSlideInTop{0%{opacity:0;transform:translateY(-50px) scale(.95)}to{opacity:1;transform:translateY(0) scale(1)}}@keyframes toastSlideOutTop{0%{opacity:1;transform:translateY(0) scale(1)}to{opacity:0;transform:translateY(-50px) scale(.95)}}@keyframes toastProgress{0%{transform:scaleX(1)}to{transform:scaleX(0)}}@media (prefers-color-scheme: dark){:host{--toast-bg: rgba(30, 41, 59, .95);--toast-border: rgba(255, 255, 255, .1);--toast-text: #f1f5f9;--toast-shadow: 0 8px 32px rgba(0, 0, 0, .4), 0 2px 8px rgba(0, 0, 0, .2)}.toast-description{color:#94a3b8}.toast-close{color:#64748b}.toast-close:hover{background:#ffffff1a;color:var(--toast-text)}.toast-progress{background:#ffffff1a}}@media (max-width: 480px){.toast-container{max-width:calc(100vw - 32px);left:16px!important;right:16px!important;transform:none!important;padding:12px}.toast{min-width:0;width:100%}}";
1121
+ class F extends g {
1122
+ constructor() {
1123
+ super(...arguments);
1124
+ p(this, "toasts", /* @__PURE__ */ new Map());
1125
+ p(this, "toastCounter", 0);
1126
+ }
1127
+ connectedCallback() {
1128
+ this.setAttribute("data-ui", "toast"), super.connectedCallback();
1129
+ }
1130
+ static get observedAttributes() {
1131
+ return ["position"];
1132
+ }
1133
+ attributeChangedCallback() {
1134
+ this.render();
1135
+ }
1136
+ getPosition() {
1137
+ const t = this.getAttribute("position");
1138
+ return t === "top-left" || t === "bottom-right" || t === "bottom-left" || t === "top-center" || t === "bottom-center" ? t : "top-right";
1139
+ }
1140
+ getIcon(t) {
1141
+ var i;
1142
+ const a = {
1143
+ success: "check-circle",
1144
+ error: "x-circle",
1145
+ warning: "alert-triangle",
1146
+ info: "info"
1147
+ }[t];
1148
+ return ((i = y.icons[a]) == null ? void 0 : i.toSvg()) || "";
1149
+ }
1150
+ /**
1151
+ * Show a toast notification
1152
+ * @param config Toast configuration
1153
+ * @returns Toast ID for manual dismissal
1154
+ */
1155
+ show(t) {
1156
+ const {
1157
+ title: e,
1158
+ description: a = "",
1159
+ type: i = "info",
1160
+ duration: r = 5e3,
1161
+ closable: o = !0
1162
+ } = t, n = `toast-${++this.toastCounter}`, d = this.getIcon(i), c = document.createElement("div");
1163
+ c.className = `toast ${i}`, c.setAttribute("role", "alert"), c.setAttribute("aria-live", "polite"), c.innerHTML = `
1164
+ <div class="toast-icon">${d}</div>
1165
+ <div class="toast-content">
1166
+ <div class="toast-title">${this.escapeHtml(e)}</div>
1167
+ ${a ? `<div class="toast-description">${this.escapeHtml(a)}</div>` : ""}
1168
+ </div>
1169
+ ${o ? `
1170
+ <button class="toast-close" aria-label="Close notification">
1171
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor">
1172
+ <line x1="18" y1="6" x2="6" y2="18"></line>
1173
+ <line x1="6" y1="6" x2="18" y2="18"></line>
1174
+ </svg>
1175
+ </button>
1176
+ ` : ""}
1177
+ ${r > 0 ? `
1178
+ <div class="toast-progress">
1179
+ <div class="toast-progress-bar" style="--duration: ${r}ms"></div>
1180
+ </div>
1181
+ ` : ""}
1182
+ `;
1183
+ const h = this.shadowRoot.querySelector(".toast-container");
1184
+ if (h && h.appendChild(c), o) {
1185
+ const b = c.querySelector(".toast-close");
1186
+ b == null || b.addEventListener("click", () => this.dismiss(n));
1187
+ }
1188
+ let u;
1189
+ return r > 0 && (u = window.setTimeout(() => {
1190
+ this.dismiss(n);
1191
+ }, r)), this.toasts.set(n, { element: c, timer: u }), this.dispatchEvent(
1192
+ new CustomEvent("toast-show", {
1193
+ bubbles: !0,
1194
+ composed: !0,
1195
+ detail: { id: n, ...t }
1196
+ })
1197
+ ), n;
1198
+ }
1199
+ /**
1200
+ * Dismiss a specific toast
1201
+ */
1202
+ dismiss(t) {
1203
+ const e = this.toasts.get(t);
1204
+ e && (e.timer && clearTimeout(e.timer), e.element.classList.add("closing"), setTimeout(() => {
1205
+ e.element.remove(), this.toasts.delete(t), this.dispatchEvent(
1206
+ new CustomEvent("toast-dismiss", {
1207
+ bubbles: !0,
1208
+ composed: !0,
1209
+ detail: { id: t }
1210
+ })
1211
+ );
1212
+ }, 300));
1213
+ }
1214
+ /**
1215
+ * Dismiss all toasts
1216
+ */
1217
+ dismissAll() {
1218
+ Array.from(this.toasts.keys()).forEach((e) => this.dismiss(e));
1219
+ }
1220
+ /**
1221
+ * Convenience methods for different toast types
1222
+ */
1223
+ success(t, e, a) {
1224
+ return this.show({ title: t, description: e, type: "success", duration: a });
1225
+ }
1226
+ error(t, e, a) {
1227
+ return this.show({ title: t, description: e, type: "error", duration: a });
1228
+ }
1229
+ warning(t, e, a) {
1230
+ return this.show({ title: t, description: e, type: "warning", duration: a });
1231
+ }
1232
+ info(t, e, a) {
1233
+ return this.show({ title: t, description: e, type: "info", duration: a });
1234
+ }
1235
+ escapeHtml(t) {
1236
+ const e = document.createElement("div");
1237
+ return e.textContent = t, e.innerHTML;
1238
+ }
1239
+ render() {
1240
+ const t = this.getPosition();
1241
+ this.shadowRoot.innerHTML = `
1242
+ <style>
1243
+ ${f}
1244
+ ${O}
1245
+ </style>
1246
+ <div class="toast-container ${t}"></div>
1247
+ `;
1248
+ }
1249
+ }
1250
+ customElements.define("ui-toast", F);
1251
+ class U extends g {
1252
+ constructor() {
1253
+ super(...arguments);
1254
+ p(this, "steps", []);
1255
+ }
1256
+ connectedCallback() {
1257
+ this.setAttribute("data-ui", "stepper"), super.connectedCallback(), this.parseSteps();
1258
+ }
1259
+ static get observedAttributes() {
1260
+ return ["steps", "active", "orientation", "size"];
1261
+ }
1262
+ attributeChangedCallback(t, e, a) {
1263
+ if (t === "steps" && e !== a && this.parseSteps(), t === "active" && e !== a) {
1264
+ this.render();
1265
+ return;
1266
+ }
1267
+ this.render();
1268
+ }
1269
+ parseSteps() {
1270
+ const t = this.getAttribute("steps");
1271
+ if (!t) {
1272
+ this.steps = [];
1273
+ return;
1274
+ }
1275
+ try {
1276
+ const e = JSON.parse(t);
1277
+ this.steps = Array.isArray(e) ? e : [];
1278
+ } catch (e) {
1279
+ console.error("Invalid steps JSON", e), this.steps = [];
1280
+ }
1281
+ }
1282
+ getOrientation() {
1283
+ return this.getAttribute("orientation") === "vertical" ? "vertical" : "horizontal";
1284
+ }
1285
+ getSize() {
1286
+ const t = this.getAttribute("size");
1287
+ return t === "sm" || t === "lg" ? t : "md";
1288
+ }
1289
+ getActiveIndex(t) {
1290
+ const e = parseInt(this.getAttribute("active") || "1", 10);
1291
+ return Number.isNaN(e) || t <= 0 ? 1 : Math.min(Math.max(e, 1), t);
1292
+ }
1293
+ resolveState(t, e, a) {
1294
+ return t.state ? t.state : e + 1 < a ? "complete" : e + 1 === a ? "active" : "upcoming";
1295
+ }
1296
+ setActive(t) {
1297
+ const e = this.steps.length;
1298
+ if (e === 0) return;
1299
+ const a = Math.min(Math.max(t, 1), e);
1300
+ if (a === this.getActiveIndex(e)) return;
1301
+ this.setAttribute("active", String(a));
1302
+ const i = this.steps[a - 1], r = this.resolveState(i, a - 1, a);
1303
+ this.dispatchEvent(
1304
+ new CustomEvent("step-change", {
1305
+ bubbles: !0,
1306
+ composed: !0,
1307
+ detail: { index: a, step: i, state: r }
1308
+ })
1309
+ );
1310
+ }
1311
+ escapeHtml(t) {
1312
+ const e = document.createElement("div");
1313
+ return e.textContent = t, e.innerHTML;
1314
+ }
1315
+ render() {
1316
+ const t = this.getOrientation(), e = this.getSize(), a = this.steps, i = a.length, r = this.getActiveIndex(i);
1317
+ this.shadowRoot.innerHTML = `
1318
+ <style>${f}</style>
1319
+ <div class="stepper-wrap">
1320
+ ${i === 0 ? '<div class="stepper-empty">No steps configured</div>' : `
1321
+ <ol class="stepper ${t} ${e}" role="list">
1322
+ ${a.map((o, n) => {
1323
+ const d = this.resolveState(o, n, r), c = d === "active", h = o.disabled ? "disabled" : "";
1324
+ return `
1325
+ <li class="step ${d} ${h}" data-state="${d}">
1326
+ <button class="step-trigger" data-index="${n}" ${o.disabled ? "disabled" : ""} aria-current="${c ? "step" : "false"}">
1327
+ <span class="step-node">${n + 1}</span>
1328
+ <span class="step-text">
1329
+ <span class="step-title">${this.escapeHtml(o.title || `Step ${n + 1}`)}</span>
1330
+ ${o.description ? `<span class="step-desc">${this.escapeHtml(o.description)}</span>` : ""}
1331
+ </span>
1332
+ </button>
1333
+ ${n < i - 1 ? '<span class="step-connector" aria-hidden="true"></span>' : ""}
1334
+ </li>
1335
+ `;
1336
+ }).join("")}
1337
+ </ol>
1338
+ `}
1339
+ </div>
1340
+ `, this.shadowRoot.querySelectorAll(".step-trigger").forEach((o) => {
1341
+ o.addEventListener("click", () => {
1342
+ const n = parseInt(o.dataset.index || "0", 10);
1343
+ Number.isNaN(n) || this.setActive(n + 1);
1344
+ });
1345
+ });
1346
+ }
1347
+ }
1348
+ customElements.define("ui-stepper", U);
1349
+ class j extends g {
1350
+ constructor() {
1351
+ super(...arguments);
1352
+ p(this, "files", this.useSignal([]));
1353
+ p(this, "isDragging", this.useSignal(!1));
1354
+ }
1355
+ connectedCallback() {
1356
+ this.setAttribute("data-ui", "upload"), super.connectedCallback();
1357
+ }
1358
+ static get observedAttributes() {
1359
+ return ["accept", "multiple", "disabled", "label", "helper", "name"];
1360
+ }
1361
+ attributeChangedCallback() {
1362
+ this.render();
1363
+ }
1364
+ get value() {
1365
+ return this.files.get().map((t) => t.name).join(", ");
1366
+ }
1367
+ get filesValue() {
1368
+ return this.files.get();
1369
+ }
1370
+ set filesValue(t) {
1371
+ this.setFiles(t);
1372
+ }
1373
+ clear() {
1374
+ this.setFiles([]);
1375
+ }
1376
+ isDisabled() {
1377
+ return this.hasAttribute("disabled");
1378
+ }
1379
+ isMultiple() {
1380
+ return this.hasAttribute("multiple");
1381
+ }
1382
+ getAccept() {
1383
+ return this.getAttribute("accept") || "";
1384
+ }
1385
+ getLabel() {
1386
+ return this.getAttribute("label") || "Upload files";
1387
+ }
1388
+ getHelper() {
1389
+ return this.getAttribute("helper") || "";
1390
+ }
1391
+ setFiles(t) {
1392
+ const e = this.isMultiple() ? t : t.slice(0, 1);
1393
+ this.files.set(e), this.dispatchEvent(
1394
+ new CustomEvent("upload-change", {
1395
+ bubbles: !0,
1396
+ composed: !0,
1397
+ detail: { files: e }
1398
+ })
1399
+ );
1400
+ }
1401
+ formatSize(t) {
1402
+ if (t < 1024) return `${t} B`;
1403
+ const e = t / 1024;
1404
+ return e < 1024 ? `${e.toFixed(1)} KB` : `${(e / 1024).toFixed(1)} MB`;
1405
+ }
1406
+ syncInputFiles(t, e) {
1407
+ const a = new DataTransfer();
1408
+ e.forEach((i) => a.items.add(i)), t.files = a.files;
1409
+ }
1410
+ render() {
1411
+ const t = this.getAccept(), e = this.getLabel(), a = this.getHelper(), i = this.isDisabled(), r = this.isMultiple(), o = this.isDragging.get(), n = this.files.get();
1412
+ this.shadowRoot.innerHTML = `
1413
+ <style>${f}</style>
1414
+ <div class="upload">
1415
+ ${e ? `<label class="upload-label">${e}</label>` : ""}
1416
+ <div class="upload-drop ${o ? "dragging" : ""} ${i ? "disabled" : ""}" part="dropzone">
1417
+ <input
1418
+ class="upload-input"
1419
+ type="file"
1420
+ ${r ? "multiple" : ""}
1421
+ ${t ? `accept="${t}"` : ""}
1422
+ ${i ? "disabled" : ""}
1423
+ >
1424
+ <div class="upload-content">
1425
+ <div class="upload-icon" aria-hidden="true">
1426
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
1427
+ <path d="M12 16V4"></path>
1428
+ <path d="M8 8l4-4 4 4"></path>
1429
+ <path d="M4 16v4h16v-4"></path>
1430
+ </svg>
1431
+ </div>
1432
+ <div class="upload-text">
1433
+ <div class="upload-title">Drop files here or browse</div>
1434
+ <div class="upload-sub">
1435
+ ${t ? `Accepted: ${t}` : "Any file type supported"}
1436
+ </div>
1437
+ </div>
1438
+ <button class="upload-btn" type="button" ${i ? "disabled" : ""}>Browse</button>
1439
+ </div>
1440
+ </div>
1441
+ ${a ? `<div class="upload-helper">${a}</div>` : ""}
1442
+ ${n.length ? `
1443
+ <ul class="upload-list">
1444
+ ${n.map(
1445
+ (b, m) => `
1446
+ <li>
1447
+ <span>${b.name}</span>
1448
+ <span class="upload-meta">${this.formatSize(b.size)}</span>
1449
+ <button class="upload-remove" data-index="${m}" type="button">Remove</button>
1450
+ </li>
1451
+ `
1452
+ ).join("")}
1453
+ </ul>
1454
+ ` : ""}
1455
+ </div>
1456
+ `;
1457
+ const d = this.shadowRoot.querySelector(".upload-drop"), c = this.shadowRoot.querySelector(".upload-input"), h = this.shadowRoot.querySelector(".upload-btn"), u = this.shadowRoot.querySelectorAll(".upload-remove");
1458
+ !d || !c || (n.length ? this.syncInputFiles(c, n) : c.value = "", d.addEventListener("dragover", (b) => {
1459
+ i || (b.preventDefault(), this.isDragging.set(!0));
1460
+ }), d.addEventListener("dragleave", () => {
1461
+ this.isDragging.set(!1);
1462
+ }), d.addEventListener("drop", (b) => {
1463
+ var v;
1464
+ if (i) return;
1465
+ b.preventDefault(), this.isDragging.set(!1);
1466
+ const m = Array.from(((v = b.dataTransfer) == null ? void 0 : v.files) ?? []);
1467
+ m.length && (this.setFiles(m), this.syncInputFiles(c, this.files.get()));
1468
+ }), c.addEventListener("change", () => {
1469
+ const b = Array.from(c.files ?? []);
1470
+ this.setFiles(b);
1471
+ }), h == null || h.addEventListener("click", () => {
1472
+ i || c.click();
1473
+ }), u.forEach((b) => {
1474
+ b.addEventListener("click", () => {
1475
+ const m = parseInt(b.dataset.index || "0", 10), v = this.files.get().filter((st, A) => A !== m);
1476
+ this.setFiles(v), this.syncInputFiles(c, v);
1477
+ });
1478
+ }));
1479
+ }
1480
+ }
1481
+ customElements.define("ui-upload", j);
1482
+ class V extends g {
1483
+ connectedCallback() {
1484
+ this.setAttribute("data-ui", "layout"), super.connectedCallback();
1485
+ }
1486
+ static get observedAttributes() {
1487
+ return ["direction"];
1488
+ }
1489
+ attributeChangedCallback() {
1490
+ this.render();
1491
+ }
1492
+ getDirection() {
1493
+ const s = this.getAttribute("direction");
1494
+ return s === "horizontal" || s === "vertical" ? s : "auto";
1495
+ }
1496
+ detectDirection() {
1497
+ const s = this.getDirection();
1498
+ if (s !== "auto") return s;
1499
+ const t = this.querySelector("ui-layout-header"), e = this.querySelector("ui-layout-footer");
1500
+ return this.querySelector("ui-layout-sidebar") ? "horizontal" : "vertical";
1501
+ }
1502
+ render() {
1503
+ const s = this.detectDirection() === "horizontal" ? "row" : "column";
1504
+ this.shadowRoot.innerHTML = `
1505
+ <style>${f}</style>
1506
+ <div class="layout-container" style="flex-direction: ${s}">
1507
+ <slot></slot>
1508
+ </div>
1509
+ `;
1510
+ }
1511
+ }
1512
+ class B extends g {
1513
+ connectedCallback() {
1514
+ this.setAttribute("data-ui", "layout-header"), super.connectedCallback();
1515
+ }
1516
+ static get observedAttributes() {
1517
+ return ["height"];
1518
+ }
1519
+ attributeChangedCallback() {
1520
+ this.render();
1521
+ }
1522
+ getHeight() {
1523
+ const s = this.getAttribute("height");
1524
+ return s && /^\d+$/.test(s) ? s + "px" : s || "64px";
1525
+ }
1526
+ render() {
1527
+ const s = this.getHeight();
1528
+ this.shadowRoot.innerHTML = `
1529
+ <style>${f}</style>
1530
+ <header class="layout-header" style="height: ${s}">
1531
+ <slot></slot>
1532
+ </header>
1533
+ `;
1534
+ }
1535
+ }
1536
+ class N extends g {
1537
+ connectedCallback() {
1538
+ this.setAttribute("data-ui", "layout-footer"), super.connectedCallback();
1539
+ }
1540
+ static get observedAttributes() {
1541
+ return ["height"];
1542
+ }
1543
+ attributeChangedCallback() {
1544
+ this.render();
1545
+ }
1546
+ getHeight() {
1547
+ const s = this.getAttribute("height");
1548
+ return s && /^\d+$/.test(s) ? s + "px" : s || "56px";
1549
+ }
1550
+ render() {
1551
+ const s = this.getHeight();
1552
+ this.shadowRoot.innerHTML = `
1553
+ <style>${f}</style>
1554
+ <footer class="layout-footer" style="height: ${s}">
1555
+ <slot></slot>
1556
+ </footer>
1557
+ `;
1558
+ }
1559
+ }
1560
+ class _ extends g {
1561
+ connectedCallback() {
1562
+ this.setAttribute("data-ui", "layout-content"), super.connectedCallback();
1563
+ }
1564
+ render() {
1565
+ this.shadowRoot.innerHTML = `
1566
+ <style>${f}</style>
1567
+ <div class="layout-content">
1568
+ <slot></slot>
1569
+ </div>
1570
+ `;
1571
+ }
1572
+ }
1573
+ class W extends g {
1574
+ constructor() {
1575
+ super(...arguments);
1576
+ p(this, "isCollapsed", !1);
1577
+ p(this, "animating", !1);
1578
+ }
1579
+ connectedCallback() {
1580
+ this.setAttribute("data-ui", "layout-sidebar"), super.connectedCallback(), this.isCollapsed = this.hasAttribute("collapsed"), this.render(), this.attachEventListeners();
1581
+ }
1582
+ static get observedAttributes() {
1583
+ return ["collapsed", "width", "collapsed-width", "collapsible"];
1584
+ }
1585
+ attributeChangedCallback(t) {
1586
+ t === "collapsed" && (this.isCollapsed = this.hasAttribute("collapsed")), this.render();
1587
+ }
1588
+ getWidth() {
1589
+ const t = this.getAttribute("width");
1590
+ return t && /^\d+$/.test(t) ? t + "px" : t || "240px";
1591
+ }
1592
+ getCollapsedWidth() {
1593
+ const t = this.getAttribute("collapsed-width");
1594
+ return t && /^\d+$/.test(t) ? t + "px" : t || "64px";
1595
+ }
1596
+ isCollapsible() {
1597
+ return this.hasAttribute("collapsible");
1598
+ }
1599
+ attachEventListeners() {
1600
+ if (!this.shadowRoot) return;
1601
+ const t = this.shadowRoot.querySelector(".sidebar-toggle");
1602
+ t && t.addEventListener("click", () => this.toggleCollapse());
1603
+ }
1604
+ toggleCollapse() {
1605
+ this.animating || (this.animating = !0, this.isCollapsed = !this.isCollapsed, this.isCollapsed ? this.setAttribute("collapsed", "") : this.removeAttribute("collapsed"), this.dispatchEvent(
1606
+ new CustomEvent("collapsed-change", {
1607
+ detail: { collapsed: this.isCollapsed },
1608
+ bubbles: !0,
1609
+ composed: !0
1610
+ })
1611
+ ), setTimeout(() => {
1612
+ this.animating = !1;
1613
+ }, 300));
1614
+ }
1615
+ render() {
1616
+ const t = this.getWidth(), e = this.getCollapsedWidth(), a = this.isCollapsible();
1617
+ a && this.isCollapsed, this.shadowRoot.innerHTML = `
1618
+ <style>${f}</style>
1619
+ <aside class="layout-sidebar ${this.isCollapsed ? "collapsed" : ""}"
1620
+ style="--sidebar-width: ${t}; --sidebar-collapsed-width: ${e}">
1621
+ <div class="sidebar-content">
1622
+ <slot></slot>
1623
+ </div>
1624
+ ${a ? `
1625
+ <button class="sidebar-toggle" title="${this.isCollapsed ? "Expand" : "Collapse"}">
1626
+ <svg class="toggle-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
1627
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
1628
+ d="M15 19l-7-7 7-7"></path>
1629
+ </svg>
1630
+ </button>
1631
+ ` : ""}
1632
+ </aside>
1633
+ `, this.attachEventListeners();
1634
+ }
1635
+ }
1636
+ customElements.define("ui-layout", V);
1637
+ customElements.define("ui-layout-header", B);
1638
+ customElements.define("ui-layout-footer", N);
1639
+ customElements.define("ui-layout-content", _);
1640
+ customElements.define("ui-layout-sidebar", W);
1641
+ class J {
1642
+ constructor() {
1643
+ p(this, "baseURL", "");
1644
+ p(this, "defaultHeaders", {
1645
+ "Content-Type": "application/json"
1646
+ });
1647
+ p(this, "defaultTimeout", 3e4);
1648
+ p(this, "interceptors", {
1649
+ request: {
1650
+ handlers: [],
1651
+ use: (s, t) => {
1652
+ this.interceptors.request.handlers.push({ onFulfilled: s, onRejected: t });
1653
+ }
1654
+ },
1655
+ response: {
1656
+ handlers: [],
1657
+ use: (s, t) => {
1658
+ this.interceptors.response.handlers.push({ onFulfilled: s, onRejected: t });
1659
+ }
1660
+ }
1661
+ });
1662
+ }
1663
+ /**
1664
+ * Set base URL for all requests
1665
+ */
1666
+ setBaseURL(s) {
1667
+ this.baseURL = s;
1668
+ }
1669
+ /**
1670
+ * Get currently set base URL
1671
+ */
1672
+ getBaseURL() {
1673
+ return this.baseURL;
1674
+ }
1675
+ /**
1676
+ * Set default headers for all requests
1677
+ */
1678
+ setDefaultHeaders(s) {
1679
+ this.defaultHeaders = { ...this.defaultHeaders, ...s };
1680
+ }
1681
+ /**
1682
+ * Set default timeout for all requests (in ms)
1683
+ */
1684
+ setDefaultTimeout(s) {
1685
+ this.defaultTimeout = s;
1686
+ }
1687
+ /**
1688
+ * Execute request with interceptors
1689
+ */
1690
+ async executeRequest(s, t) {
1691
+ const e = s.startsWith("http") ? s : this.baseURL + s;
1692
+ let a = {
1693
+ method: "GET",
1694
+ headers: { ...this.defaultHeaders },
1695
+ timeout: this.defaultTimeout,
1696
+ ...t
1697
+ };
1698
+ for (const o of this.interceptors.request.handlers)
1699
+ try {
1700
+ a = await o.onFulfilled(a);
1701
+ } catch (n) {
1702
+ if (o.onRejected)
1703
+ a = await o.onRejected(n);
1704
+ else
1705
+ throw n;
1706
+ }
1707
+ const i = new AbortController(), r = setTimeout(() => i.abort(), a.timeout || this.defaultTimeout);
1708
+ try {
1709
+ const o = {
1710
+ method: a.method,
1711
+ headers: a.headers,
1712
+ signal: i.signal
1713
+ };
1714
+ a.body && a.method !== "GET" && (o.body = (typeof a.body == "string", a.body));
1715
+ const n = await fetch(e, o);
1716
+ let d;
1717
+ const c = n.headers.get("content-type");
1718
+ c != null && c.includes("application/json") ? d = n.ok ? await n.json() : null : c != null && c.includes("text") ? d = await n.text() : d = await n.blob();
1719
+ let h = {
1720
+ status: n.status,
1721
+ statusText: n.statusText,
1722
+ headers: n.headers,
1723
+ data: d
1724
+ };
1725
+ if (!n.ok) {
1726
+ const u = new Error(`HTTP ${n.status}: ${n.statusText}`);
1727
+ throw u.response = h, u.config = a, u;
1728
+ }
1729
+ for (const u of this.interceptors.response.handlers)
1730
+ try {
1731
+ h = await u.onFulfilled(h);
1732
+ } catch (b) {
1733
+ if (u.onRejected)
1734
+ h = await u.onRejected(b);
1735
+ else
1736
+ throw b;
1737
+ }
1738
+ return h.data;
1739
+ } catch (o) {
1740
+ throw o instanceof Error && o.name === "AbortError" ? new Error(`Request timeout after ${a.timeout}ms`) : o;
1741
+ } finally {
1742
+ clearTimeout(r);
1743
+ }
1744
+ }
1745
+ /**
1746
+ * GET request
1747
+ */
1748
+ async get(s, t) {
1749
+ return this.executeRequest(s, { ...t, method: "GET" });
1750
+ }
1751
+ /**
1752
+ * POST request
1753
+ */
1754
+ async post(s, t, e) {
1755
+ return this.executeRequest(s, {
1756
+ ...e,
1757
+ method: "POST",
1758
+ body: typeof t == "string" || t instanceof FormData ? t : JSON.stringify(t)
1759
+ });
1760
+ }
1761
+ /**
1762
+ * PUT request
1763
+ */
1764
+ async put(s, t, e) {
1765
+ return this.executeRequest(s, {
1766
+ ...e,
1767
+ method: "PUT",
1768
+ body: typeof t == "string" || t instanceof FormData ? t : JSON.stringify(t)
1769
+ });
1770
+ }
1771
+ /**
1772
+ * PATCH request
1773
+ */
1774
+ async patch(s, t, e) {
1775
+ return this.executeRequest(s, {
1776
+ ...e,
1777
+ method: "PATCH",
1778
+ body: typeof t == "string" || t instanceof FormData ? t : JSON.stringify(t)
1779
+ });
1780
+ }
1781
+ /**
1782
+ * DELETE request
1783
+ */
1784
+ async delete(s, t) {
1785
+ return this.executeRequest(s, { ...t, method: "DELETE" });
1786
+ }
1787
+ /**
1788
+ * HEAD request
1789
+ */
1790
+ async head(s, t) {
1791
+ return this.executeRequest(s, { ...t, method: "HEAD" });
1792
+ }
1793
+ }
1794
+ const nt = new J();
1795
+ function k(l, s) {
1796
+ return l ? l.querySelector(s) : null;
1797
+ }
1798
+ function lt(l, s) {
1799
+ return l ? l.querySelectorAll(s) : [];
1800
+ }
1801
+ function dt(l, s) {
1802
+ return l ? l.querySelector(`#${s}`) : null;
1803
+ }
1804
+ function ct(l, s, t, e, a) {
1805
+ if (!l) return null;
1806
+ const i = l.querySelector(`#${s}`);
1807
+ return i ? (i.addEventListener(t, e, a), i) : null;
1808
+ }
1809
+ function pt(l, s) {
1810
+ return k(l, s);
1811
+ }
1812
+ function ut(l, s) {
1813
+ return k(l, s);
1814
+ }
1815
+ function ht(l, s) {
1816
+ return k(l, s);
1817
+ }
1818
+ const G = "input, select, textarea, ui-input, ui-select, ui-date-picker, ui-checkbox, ui-upload";
1819
+ function $(l) {
1820
+ return l.getAttribute("name") || l.getAttribute("id") || "";
1821
+ }
1822
+ function X(l) {
1823
+ const s = l.tagName.toLowerCase();
1824
+ if (s === "ui-checkbox")
1825
+ return l.hasAttribute("checked");
1826
+ if (s === "ui-upload") {
1827
+ const a = l == null ? void 0 : l.filesValue;
1828
+ return Array.isArray(a) && a.length > 0 ? a : [];
1829
+ }
1830
+ const t = l == null ? void 0 : l.value;
1831
+ if (typeof t == "string" && t !== "")
1832
+ return t;
1833
+ const e = l.getAttribute("value");
1834
+ return e || "";
1835
+ }
1836
+ function bt(l, s = {}) {
1837
+ const { includeDisabled: t = !1, includeEmpty: e = !0 } = s, a = {}, i = /* @__PURE__ */ new Map();
1838
+ l.querySelectorAll('input[type="checkbox"]').forEach((o) => {
1839
+ const n = $(o);
1840
+ n && i.set(n, (i.get(n) || 0) + 1);
1841
+ });
1842
+ const r = Array.from(l.querySelectorAll(G));
1843
+ for (const o of r) {
1844
+ if (!t && (o.disabled || o.hasAttribute("disabled"))) continue;
1845
+ const n = $(o);
1846
+ if (!n) continue;
1847
+ if (o instanceof HTMLInputElement) {
1848
+ const c = o.type;
1849
+ if (c === "checkbox") {
1850
+ if ((i.get(n) || 0) > 1) {
1851
+ const u = a[n] || [];
1852
+ o.checked && u.push(o.value || "on"), a[n] = u;
1853
+ } else
1854
+ a[n] = o.checked;
1855
+ continue;
1856
+ }
1857
+ if (c === "radio") {
1858
+ o.checked && (a[n] = o.value);
1859
+ continue;
1860
+ }
1861
+ if (c === "file") {
1862
+ const h = Array.from(o.files ?? []);
1863
+ (e || h.length > 0) && (a[n] = h);
1864
+ continue;
1865
+ }
1866
+ (e || o.value !== "") && (a[n] = o.value);
1867
+ continue;
1868
+ }
1869
+ if (o instanceof HTMLSelectElement) {
1870
+ if (o.multiple) {
1871
+ const c = Array.from(o.selectedOptions).map((h) => h.value);
1872
+ (e || c.length > 0) && (a[n] = c);
1873
+ } else (e || o.value !== "") && (a[n] = o.value);
1874
+ continue;
1875
+ }
1876
+ if (o instanceof HTMLTextAreaElement) {
1877
+ (e || o.value !== "") && (a[n] = o.value);
1878
+ continue;
1879
+ }
1880
+ const d = X(o);
1881
+ (e || (Array.isArray(d) ? d.length > 0 : d !== "")) && (a[n] = d);
1882
+ }
1883
+ return a;
1884
+ }
1885
+ function gt(l) {
1886
+ const s = {};
1887
+ l.querySelectorAll("ui-input").forEach((i) => {
1888
+ var c;
1889
+ const r = (c = i.value) == null ? void 0 : c.trim(), o = i.getAttribute("name"), n = i.getAttribute("label") || o;
1890
+ i.getAttribute("required") !== null && !r && (s[o || ""] = `${n} is required`), r && o === "email" && (/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(r) || (s[o] = "Please enter a valid email address")), r && o === "phone" && (/^[\d\s\-\+\(\)]+$/.test(r) || (s[o] = "Please enter a valid phone number"));
1891
+ }), l.querySelectorAll("ui-select").forEach((i) => {
1892
+ const r = i.getAttribute("value"), o = i.getAttribute("name"), n = i.getAttribute("label") || o;
1893
+ i.getAttribute("required") !== null && !r && (s[o || ""] = `${n} is required`);
1894
+ });
1895
+ const a = l.querySelectorAll("ui-checkbox");
1896
+ return a.length > 0 && (Array.from(a).some((r) => r.checked || r.getAttribute("checked") !== null) || (s.checkboxes = "Please select at least one option")), {
1897
+ isValid: Object.keys(s).length === 0,
1898
+ errors: s
1899
+ };
1900
+ }
1901
+ const K = ":host{display:flex;flex-direction:column;width:100%;height:100vh;background:#f9fafb;box-sizing:border-box}ui-top-bar{display:block;width:100%;flex-shrink:0}.layout-container{display:flex;flex-direction:row;flex:1;width:100%;min-height:0}app-sidebar{display:block;width:280px;flex-shrink:0;border-right:1px solid #e5e7eb;overflow:hidden;background:linear-gradient(to bottom,#1f2937,#111827)}.main-area{flex:1 1 auto;overflow-y:auto;overflow-x:hidden;padding:32px 48px;background:#f9fafb;box-sizing:border-box;height:100%}.content-area{background:#fff;border-radius:12px;padding:32px;border:1px solid #e5e7eb;box-shadow:0 1px 2px #0000000d;box-sizing:border-box;margin-bottom:32px;transition:all .2s ease;width:100%}.content-area:hover{border-color:#d1d5db;box-shadow:0 1px 3px #00000014}::slotted(*){display:block!important;width:100%}.main-area::-webkit-scrollbar{width:8px}.main-area::-webkit-scrollbar-track{background:transparent}.main-area::-webkit-scrollbar-thumb{background:#d1d5db;border-radius:4px}.main-area::-webkit-scrollbar-thumb:hover{background:#9ca3af}@media (max-width: 1280px){.main-area{padding:24px 32px}.content-area{padding:28px}}@media (max-width: 768px){.layout-container{flex-direction:column}app-sidebar{width:100%;border-right:none;border-bottom:1px solid #e5e7eb;max-height:200px}.main-area{padding:16px 24px}.content-area{padding:20px;margin-bottom:20px}}", Q = `
1902
+ :host {
1903
+ display: block;
1904
+ width: 280px;
1905
+ height: 100%;
1906
+ box-sizing: border-box;
1907
+ }
1908
+
1909
+ .sidebar {
1910
+ background: linear-gradient(180deg, #1f2937 0%, #111827 100%);
1911
+ display: flex;
1912
+ flex-direction: column;
1913
+ gap: 8px;
1914
+ position: relative;
1915
+ overflow: hidden;
1916
+ padding: 0;
1917
+ width: 100%;
1918
+ height: 100%;
1919
+ }
1920
+
1921
+ .sidebar::before {
1922
+ content: '';
1923
+ position: absolute;
1924
+ top: -50%;
1925
+ left: -50%;
1926
+ width: 200%;
1927
+ height: 200%;
1928
+ background: radial-gradient(circle at 30% 20%, rgba(99, 102, 241, 0.06) 0%, transparent 50%);
1929
+ pointer-events: none;
1930
+ }
1931
+
1932
+ .sidebar-brand {
1933
+ display: flex;
1934
+ align-items: center;
1935
+ gap: 12px;
1936
+ padding: 20px 16px;
1937
+ border-bottom: 1px solid rgba(255, 255, 255, 0.08);
1938
+ margin: 0;
1939
+ position: relative;
1940
+ z-index: 1;
1941
+ flex-shrink: 0;
1942
+ }
1943
+
1944
+ .brand-icon {
1945
+ width: 40px;
1946
+ height: 40px;
1947
+ background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%);
1948
+ border-radius: 10px;
1949
+ display: flex;
1950
+ align-items: center;
1951
+ justify-content: center;
1952
+ box-shadow: 0 2px 8px rgba(99, 102, 241, 0.3);
1953
+ flex-shrink: 0;
1954
+ }
1955
+
1956
+ .brand-icon svg {
1957
+ width: 22px;
1958
+ height: 22px;
1959
+ stroke: white;
1960
+ }
1961
+
1962
+ .brand-text {
1963
+ font: 600 16px/1.2 "Sora", system-ui, sans-serif;
1964
+ color: #ffffff;
1965
+ letter-spacing: -0.01em;
1966
+ margin: 0;
1967
+ }
1968
+
1969
+ .brand-sub {
1970
+ font: 500 10px/1 "Inter", system-ui, sans-serif;
1971
+ color: rgba(255, 255, 255, 0.4);
1972
+ text-transform: uppercase;
1973
+ letter-spacing: 0.08em;
1974
+ margin: 0;
1975
+ }
1976
+
1977
+ .nav-section {
1978
+ display: flex;
1979
+ flex-direction: column;
1980
+ gap: 4px;
1981
+ padding: 0 12px;
1982
+ position: relative;
1983
+ z-index: 1;
1984
+ }
1985
+
1986
+ .nav-label {
1987
+ font: 600 11px/1 "Inter", system-ui, sans-serif;
1988
+ color: rgba(255, 255, 255, 0.35);
1989
+ text-transform: uppercase;
1990
+ letter-spacing: 0.1em;
1991
+ padding: 12px 8px 6px;
1992
+ margin: 4px 0 0;
1993
+ }
1994
+
1995
+ .sidebar-link {
1996
+ display: flex;
1997
+ align-items: center;
1998
+ gap: 12px;
1999
+ padding: 10px 12px;
2000
+ border-radius: 8px;
2001
+ color: rgba(255, 255, 255, 0.65);
2002
+ text-decoration: none;
2003
+ font: 500 14px/1.3 "Inter", system-ui, sans-serif;
2004
+ transition: all 200ms cubic-bezier(0.4, 0, 0.2, 1);
2005
+ position: relative;
2006
+ overflow: hidden;
2007
+ }
2008
+
2009
+ .sidebar-link::before {
2010
+ content: '';
2011
+ position: absolute;
2012
+ inset: 0;
2013
+ background: linear-gradient(135deg, rgba(99, 102, 241, 0.12) 0%, rgba(139, 92, 246, 0.08) 100%);
2014
+ border-radius: 8px;
2015
+ opacity: 0;
2016
+ transition: opacity 200ms ease;
2017
+ }
2018
+
2019
+ .sidebar-link:hover {
2020
+ color: #ffffff;
2021
+ background: rgba(255, 255, 255, 0.05);
2022
+ }
2023
+
2024
+ .sidebar-link:hover::before {
2025
+ opacity: 1;
2026
+ }
2027
+
2028
+ .sidebar-link.active {
2029
+ color: #ffffff;
2030
+ background: linear-gradient(135deg, rgba(99, 102, 241, 0.25) 0%, rgba(139, 92, 246, 0.2) 100%);
2031
+ }
2032
+
2033
+ .sidebar-link.active::after {
2034
+ content: '';
2035
+ position: absolute;
2036
+ left: 0;
2037
+ top: 50%;
2038
+ transform: translateY(-50%);
2039
+ width: 3px;
2040
+ height: 20px;
2041
+ background: linear-gradient(180deg, #6366f1 0%, #8b5cf6 100%);
2042
+ border-radius: 0 3px 3px 0;
2043
+ }
2044
+
2045
+ .link-icon {
2046
+ width: 18px;
2047
+ height: 18px;
2048
+ flex-shrink: 0;
2049
+ opacity: 0.65;
2050
+ transition: opacity 200ms ease;
2051
+ }
2052
+
2053
+ .sidebar-link:hover .link-icon,
2054
+ .sidebar-link.active .link-icon {
2055
+ opacity: 1;
2056
+ }
2057
+
2058
+ .link-icon svg {
2059
+ width: 100%;
2060
+ height: 100%;
2061
+ }
2062
+
2063
+ .sidebar-footer {
2064
+ margin-top: auto;
2065
+ padding: 16px 12px;
2066
+ border-top: 1px solid rgba(255, 255, 255, 0.08);
2067
+ position: relative;
2068
+ z-index: 1;
2069
+ flex-shrink: 0;
2070
+ }
2071
+
2072
+ .sidebar-link[data-link] {
2073
+ cursor: pointer;
2074
+ }
2075
+
2076
+ .nav-section:first-child {
2077
+ padding-top: 12px;
2078
+ }
2079
+ `;
2080
+ class Z extends g {
2081
+ constructor() {
2082
+ super(...arguments);
2083
+ p(this, "navItems", []);
2084
+ p(this, "footerItems", []);
2085
+ }
2086
+ connectedCallback() {
2087
+ this.setAttribute("data-ui", "sidebar"), super.connectedCallback(), this.updateActiveState(), window.addEventListener("popstate", () => this.updateActiveState()), document.addEventListener("click", () => this.updateActiveState());
2088
+ }
2089
+ set items(t) {
2090
+ this.navItems = t.map((e) => ({ ...e, active: !1 })), this.updateActiveState();
2091
+ }
2092
+ get items() {
2093
+ return this.navItems;
2094
+ }
2095
+ set footer(t) {
2096
+ this.footerItems = t, this.render();
2097
+ }
2098
+ get footer() {
2099
+ return this.footerItems;
2100
+ }
2101
+ updateActiveState() {
2102
+ if (this.navItems.length === 0) return;
2103
+ const t = window.location.pathname;
2104
+ this.navItems = this.navItems.map((e) => ({
2105
+ ...e,
2106
+ active: e.href === t
2107
+ })), this.render();
2108
+ }
2109
+ renderIcon(t) {
2110
+ var a;
2111
+ return ((a = y.icons[t]) == null ? void 0 : a.toSvg({ class: "" })) || "";
2112
+ }
2113
+ render() {
2114
+ const t = this.navItems.map((i) => `
2115
+ <a
2116
+ class="sidebar-link ${i.active ? "active" : ""}"
2117
+ href="${i.href}"
2118
+ data-link
2119
+ >
2120
+ <span class="link-icon">${this.renderIcon(i.icon)}</span>
2121
+ ${i.label}
2122
+ </a>
2123
+ `).join(""), e = this.footerItems.map((i) => `
2124
+ <a
2125
+ class="sidebar-link"
2126
+ href="${i.href}"
2127
+ target="_blank"
2128
+ rel="noopener"
2129
+ >
2130
+ <span class="link-icon">${this.renderIcon(i.icon)}</span>
2131
+ ${i.label}
2132
+ </a>
2133
+ `).join(""), a = this.footerItems.length > 0 ? `
2134
+ <div class="sidebar-footer">
2135
+ ${e}
2136
+ </div>
2137
+ ` : "";
2138
+ this.shadowRoot.innerHTML = `
2139
+ <style>${f}${Q}</style>
2140
+ <aside class="sidebar">
2141
+ <div class="sidebar-brand">
2142
+ <div class="brand-icon">
2143
+ ${this.renderIcon("hexagon")}
2144
+ </div>
2145
+ <div>
2146
+ <div class="brand-text">UI Kit</div>
2147
+ <div class="brand-sub">Components</div>
2148
+ </div>
2149
+ </div>
2150
+
2151
+ <nav class="nav-section">
2152
+ <div class="nav-label">Components</div>
2153
+ ${t}
2154
+ </nav>
2155
+
2156
+ ${a}
2157
+ </aside>
2158
+ `;
2159
+ }
2160
+ }
2161
+ customElements.define("app-sidebar", Z);
2162
+ const tt = ":host{display:block;border-bottom:1px solid #e5e7eb;box-shadow:0 1px 2px #0000000d}.top-bar{display:grid;grid-template-columns:1fr auto;align-items:center;gap:24px;padding:14px 48px;width:100%;box-sizing:border-box}.title-section{display:flex;flex-direction:column;gap:2px;min-width:0}.page-title{font:600 22px/1.2 Sora,system-ui,sans-serif;color:#0f172a;letter-spacing:-.01em;margin:0;word-break:break-word}.page-subtitle{font:400 13px/1.4 Inter,system-ui,sans-serif;color:#6b7280;margin:0;letter-spacing:-.005em;word-break:break-word}.actions-slot{display:flex;align-items:center;gap:8px;flex-shrink:0}@media (max-width: 1280px){.top-bar{gap:16px;padding:12px 32px}.page-title{font-size:20px}.page-subtitle{font-size:12px}}@media (max-width: 768px){.top-bar{grid-template-columns:1fr;gap:12px;padding:12px 24px}.page-title{font-size:18px}.page-subtitle{font-size:12px}.actions-slot{width:100%;justify-content:flex-end}}@media (max-width: 480px){.top-bar{padding:10px 16px;gap:10px}.page-title{font-size:16px}.page-subtitle{font-size:11px}}";
2163
+ class et extends g {
2164
+ connectedCallback() {
2165
+ this.setAttribute("data-ui", "top-bar"), super.connectedCallback();
2166
+ }
2167
+ static get observedAttributes() {
2168
+ return ["title", "subtitle", "bg-color"];
2169
+ }
2170
+ attributeChangedCallback() {
2171
+ this.render();
2172
+ }
2173
+ getTitle() {
2174
+ return this.getAttribute("title") ?? "Dashboard";
2175
+ }
2176
+ getSubtitle() {
2177
+ return this.getAttribute("subtitle") ?? "";
2178
+ }
2179
+ getBgColor() {
2180
+ return this.getAttribute("bg-color") ?? "var(--color-header)";
2181
+ }
2182
+ render() {
2183
+ const s = this.getSubtitle(), t = this.getBgColor();
2184
+ this.shadowRoot.innerHTML = `
2185
+ <style>
2186
+ ${f}
2187
+ ${tt}
2188
+ :host {
2189
+ background: ${t};
2190
+ }
2191
+ </style>
2192
+ <div class="top-bar">
2193
+ <div class="title-section">
2194
+ <h1 class="page-title">${this.getTitle()}</h1>
2195
+ ${s ? `<p class="page-subtitle">${s}</p>` : ""}
2196
+ </div>
2197
+ <div class="actions-slot">
2198
+ <slot></slot>
2199
+ </div>
2200
+ </div>
2201
+ `;
2202
+ }
2203
+ }
2204
+ customElements.define("ui-top-bar", et);
2205
+ const at = [
2206
+ {
2207
+ path: "/",
2208
+ layout: "app-layout",
2209
+ load: () => import("./home-page-XUM8cHP7.js"),
2210
+ component: "home-page"
2211
+ },
2212
+ {
2213
+ path: "/button",
2214
+ layout: "app-layout",
2215
+ load: () => import("./button-demo-BcfxxPSq.js"),
2216
+ component: "button-demo"
2217
+ },
2218
+ {
2219
+ path: "/layout",
2220
+ layout: "app-layout",
2221
+ load: () => import("./layout-demo-CJsZ6DI5.js"),
2222
+ component: "layout-demo"
2223
+ },
2224
+ {
2225
+ path: "/date-picker",
2226
+ layout: "app-layout",
2227
+ load: () => import("./date-picker-demo-B8y3zapN.js"),
2228
+ component: "date-picker-demo"
2229
+ },
2230
+ {
2231
+ path: "/table-demo",
2232
+ layout: "app-layout",
2233
+ load: () => import("./table-demo-x2ZD8cFh.js"),
2234
+ component: "table-demo"
2235
+ },
2236
+ {
2237
+ path: "/forms",
2238
+ layout: "app-layout",
2239
+ load: () => import("./form-demo-page-F1iLCgfh.js"),
2240
+ component: "form-demo-page"
2241
+ },
2242
+ {
2243
+ path: "/modal",
2244
+ layout: "app-layout",
2245
+ load: () => import("./modal-demo-page-YN2KgJ31.js"),
2246
+ component: "modal-demo-page"
2247
+ },
2248
+ {
2249
+ path: "/tabs",
2250
+ layout: "app-layout",
2251
+ load: () => import("./tabs-demo-BQBtZzw9.js"),
2252
+ component: "tabs-demo"
2253
+ },
2254
+ {
2255
+ path: "/card",
2256
+ layout: "app-layout",
2257
+ load: () => import("./card-demo-Cxp-wRGW.js"),
2258
+ component: "card-demo-page"
2259
+ },
2260
+ {
2261
+ path: "/toast",
2262
+ layout: "app-layout",
2263
+ load: () => import("./toast-demo-page-DLVacHXA.js"),
2264
+ component: "toast-demo-page"
2265
+ },
2266
+ {
2267
+ path: "/stepper",
2268
+ layout: "app-layout",
2269
+ load: () => import("./stepper-demo-page-BkcpKk_F.js"),
2270
+ component: "stepper-demo-page"
2271
+ }
2272
+ ];
2273
+ class it extends g {
2274
+ constructor() {
2275
+ super(...arguments);
2276
+ p(this, "pageTitle", "Dashboard");
2277
+ p(this, "pageSubtitle", "Explore our component library");
2278
+ p(this, "navItems", [
2279
+ { icon: "home", label: "Home", href: "/" },
2280
+ { icon: "box", label: "Button", href: "/button" },
2281
+ { icon: "layout", label: "Layout", href: "/layout" },
2282
+ { icon: "sliders", label: "Form Elements", href: "/forms" },
2283
+ { icon: "calendar", label: "Date Picker", href: "/date-picker" },
2284
+ { icon: "table", label: "Table", href: "/table-demo" },
2285
+ { icon: "square", label: "Modal", href: "/modal" },
2286
+ { icon: "folder", label: "Tabs", href: "/tabs" },
2287
+ { icon: "credit-card", label: "Card", href: "/card" },
2288
+ { icon: "message-circle", label: "Toast", href: "/toast" },
2289
+ { icon: "layers", label: "Stepper", href: "/stepper" }
2290
+ ]);
2291
+ p(this, "footerItems", [
2292
+ { icon: "github", label: "GitHub", href: "https://github.com/rodiniz/webcomponents" }
2293
+ ]);
2294
+ }
2295
+ connectedCallback() {
2296
+ this.setAttribute("data-ui", "layout"), super.connectedCallback(), this.updateTitle(), window.addEventListener("popstate", () => this.updateTitle()), document.addEventListener("click", () => this.updateTitle());
2297
+ }
2298
+ updateTitle() {
2299
+ const t = window.location.pathname, a = {
2300
+ "/": { title: "Web Components", subtitle: "A framework-agnostic component library" },
2301
+ "/button": { title: "Button", subtitle: "Flexible button with variants and sizes" },
2302
+ "/layout": { title: "Layout", subtitle: "Flexible page layouts with header, footer, sidebar, and content" },
2303
+ "/forms": { title: "Form Elements", subtitle: "Inputs, selects, checkboxes, uploads, and more" },
2304
+ "/date-picker": { title: "Date Picker", subtitle: "Date selection component" },
2305
+ "/table-demo": { title: "Table", subtitle: "Data table with actions" },
2306
+ "/modal": { title: "Modal", subtitle: "Dialog and overlay components" },
2307
+ "/tabs": { title: "Tabs", subtitle: "Tabbed navigation component" },
2308
+ "/card": { title: "Card", subtitle: "Flexible container component" },
2309
+ "/toast": { title: "Toast", subtitle: "Notification and alert system" },
2310
+ "/stepper": { title: "Stepper", subtitle: "Progressive step navigation" }
2311
+ }[t] || { title: "Dashboard", subtitle: "Explore our component library" };
2312
+ this.pageTitle = a.title, this.pageSubtitle = a.subtitle, this.render();
2313
+ }
2314
+ render() {
2315
+ this.shadowRoot.innerHTML = `
2316
+ <style>${f}${K}</style>
2317
+ <ui-top-bar title="${this.pageTitle}" subtitle="${this.pageSubtitle}"></ui-top-bar>
2318
+ <div class="layout-container">
2319
+ <app-sidebar></app-sidebar>
2320
+ <div class="main-area">
2321
+ <main class="content-area">
2322
+ <slot></slot>
2323
+ </main>
2324
+ </div>
2325
+ </div>
2326
+ `;
2327
+ const t = this.shadowRoot.querySelector("app-sidebar");
2328
+ t && (t.items = this.navItems, t.footer = this.footerItems);
2329
+ }
2330
+ }
2331
+ customElements.define("app-layout", it);
2332
+ function ft(l, s = "#app") {
2333
+ async function t() {
2334
+ const e = location.pathname, a = e, i = l.find((n) => n.path === a);
2335
+ if (!i) {
2336
+ if (a !== "/") {
2337
+ const n = "/";
2338
+ history.replaceState(null, "", n), await t();
2339
+ }
2340
+ return;
2341
+ }
2342
+ if (await i.load(), i.guard && !await i.guard()) {
2343
+ const d = "/";
2344
+ history.replaceState(null, "", d), await t();
2345
+ return;
2346
+ }
2347
+ const r = document.createElement(i.component), o = document.querySelector(s);
2348
+ o && (o.innerHTML = "", o.appendChild(r));
2349
+ }
2350
+ return window.addEventListener("popstate", t), window.addEventListener("DOMContentLoaded", t), document.addEventListener("click", (e) => {
2351
+ const i = e.composedPath().find(
2352
+ (r) => r instanceof Element && r.matches("[data-link]")
2353
+ );
2354
+ if (i) {
2355
+ e.preventDefault();
2356
+ const r = i.getAttribute("href") ?? "/", o = r;
2357
+ history.pushState(null, "", o), t();
2358
+ }
2359
+ }), t;
2360
+ }
2361
+ async function x() {
2362
+ const l = location.pathname, s = l, t = at.find((r) => r.path === s);
2363
+ if (!t) {
2364
+ if (s !== "/") {
2365
+ const r = "/";
2366
+ history.replaceState(null, "", r), await x();
2367
+ }
2368
+ return;
2369
+ }
2370
+ if (await t.load(), t.guard && !await t.guard()) {
2371
+ const o = "/";
2372
+ history.replaceState(null, "", o), await x();
2373
+ return;
2374
+ }
2375
+ const e = document.createElement(t.layout), a = document.createElement(t.component);
2376
+ e.appendChild(a);
2377
+ const i = document.querySelector("#app");
2378
+ i && (i.innerHTML = "", i.appendChild(e));
2379
+ }
2380
+ window.addEventListener("popstate", x);
2381
+ window.addEventListener("DOMContentLoaded", x);
2382
+ document.addEventListener("click", (l) => {
2383
+ const t = l.composedPath().find(
2384
+ (e) => e instanceof Element && e.matches("[data-link]")
2385
+ );
2386
+ if (t) {
2387
+ l.preventDefault();
2388
+ const e = t.getAttribute("href") ?? "/", a = e;
2389
+ history.pushState(null, "", a), x();
2390
+ }
2391
+ });
2392
+ export {
2393
+ ft as A,
2394
+ g as B,
2395
+ lt as C,
2396
+ J as H,
2397
+ S as U,
2398
+ pt as a,
2399
+ ut as b,
2400
+ k as c,
2401
+ ct as d,
2402
+ dt as e,
2403
+ H as f,
2404
+ bt as g,
2405
+ nt as h,
2406
+ D as i,
2407
+ I as j,
2408
+ L as k,
2409
+ V as l,
2410
+ _ as m,
2411
+ N as n,
2412
+ B as o,
2413
+ W as p,
2414
+ ht as q,
2415
+ M as r,
2416
+ T as s,
2417
+ R as t,
2418
+ U as u,
2419
+ gt as v,
2420
+ z as w,
2421
+ Y as x,
2422
+ F as y,
2423
+ j as z
2424
+ };