@diniz/webcomponents 1.1.6 → 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.
@@ -1,1914 +1,33 @@
1
- var A = Object.defineProperty;
2
- var C = (l, a, t) => a in l ? A(l, a, { enumerable: !0, configurable: !0, writable: !0, value: t }) : l[a] = t;
3
- var u = (l, a, t) => C(l, typeof a != "symbol" ? a + "" : a, t);
4
- import w from "feather-icons";
5
- function y(l) {
6
- let a = l;
7
- const t = /* @__PURE__ */ new Set();
8
- return {
9
- get: () => a,
10
- set: (e) => {
11
- Object.is(a, e) || (a = e, t.forEach((s) => s(a)));
12
- },
13
- subscribe: (e) => (t.add(e), () => t.delete(e))
14
- };
15
- }
16
- class g extends HTMLElement {
17
- constructor() {
18
- super();
19
- u(this, "state");
20
- u(this, "signalUnsubs");
21
- this.attachShadow({ mode: "open" }), this.state = {}, this.signalUnsubs = /* @__PURE__ */ new Set();
22
- }
23
- useSignal(t) {
24
- const e = y(t), s = e.subscribe(() => this.render());
25
- return this.signalUnsubs.add(s), 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 s = y(e), i = s.subscribe((n) => {
46
- var o;
47
- const r = (o = this.shadowRoot) == null ? void 0 : o.getElementById(t);
48
- r && (r.textContent = String(n));
49
- });
50
- return this.signalUnsubs.add(i), requestAnimationFrame(() => {
51
- var r;
52
- const n = (r = this.shadowRoot) == null ? void 0 : r.getElementById(t);
53
- n && (n.textContent = String(e));
54
- }), s;
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 E 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 a = this.shadowRoot.querySelector("button");
82
- if (!a) return;
83
- const t = a._clickHandler;
84
- t && a.removeEventListener("click", t);
85
- const e = (s) => {
86
- const i = this.getType();
87
- if (this.hasAttribute("disabled")) {
88
- s.preventDefault(), s.stopPropagation();
89
- return;
90
- }
91
- if (i === "submit") {
92
- s.preventDefault(), s.stopPropagation();
93
- let r = this.closest("form");
94
- if (!r) {
95
- let o = this.parentElement;
96
- for (; o; ) {
97
- if (o.tagName === "FORM") {
98
- r = o;
99
- break;
100
- }
101
- o = o.parentElement;
102
- }
103
- }
104
- if (r) {
105
- const o = new Event("submit", {
106
- bubbles: !0,
107
- cancelable: !0
108
- });
109
- r.dispatchEvent(o);
110
- }
111
- }
112
- };
113
- a._clickHandler = e, a.addEventListener("click", e);
114
- }
115
- getVariant() {
116
- const a = this.getAttribute("variant");
117
- return a === "secondary" || a === "ghost" || a === "danger" ? a : "primary";
118
- }
119
- getSize() {
120
- const a = this.getAttribute("size");
121
- return a === "sm" || a === "lg" ? a : "md";
122
- }
123
- getType() {
124
- return this.getAttribute("type") ?? "button";
125
- }
126
- getIcon() {
127
- var s;
128
- const a = this.getAttribute("icon");
129
- if (!a) return null;
130
- const t = a.trim();
131
- return { html: `<span class="btn-icon">${((s = w.icons[t]) == null ? void 0 : s.toSvg()) || ""}</span>`, name: t };
132
- }
133
- getIconPosition() {
134
- return this.getAttribute("icon-position") === "right" ? "right" : "left";
135
- }
136
- render() {
137
- const a = this.getVariant(), t = this.getSize(), e = this.hasAttribute("disabled"), s = this.getType(), i = this.getIcon(), n = this.getIconPosition(), r = i !== null, o = i ? i.html : "", c = this.innerHTML.trim(), d = r && !c;
138
- let p;
139
- r && c ? p = n === "left" ? `${o}<span>${c}</span>` : `<span>${c}</span>${o}` : r ? p = o : p = c, this.shadowRoot.innerHTML = `
140
- <style>${f}</style>
141
- <button
142
- part="button"
143
- class="btn ${a} ${t}${r ? " has-icon" : ""}${d ? " icon-only" : ""}"
144
- type="${s}"
145
- ${e ? "disabled" : ""}
146
- >
147
- ${p}
148
- </button>
149
- `;
150
- }
151
- }
152
- customElements.define("ui-button", E);
153
- class S extends g {
154
- constructor() {
155
- super();
156
- u(this, "inputEl", null);
157
- u(this, "customValidator", null);
158
- u(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, s) {
173
- e !== s && 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 s = document.querySelector(t.selector);
226
- if (s && e !== s.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"), s = 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)), s && this.inputEl.setAttribute("aria-describedby", `${s}-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(), s = this.getPlaceholder(), i = this.getName(), n = this.getErrorMessage(), r = this.hasAttribute("required"), o = this.getAttribute("pattern"), c = this.getAttribute("minlength"), d = this.getAttribute("maxlength"), p = this.getAttribute("min"), h = 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}${r ? " *" : ""}</label>` : ""}
285
- <input
286
- part="input"
287
- class="input-field"
288
- type="${t}"
289
- placeholder="${s}"
290
- name="${i}"
291
- .value="${this.state.value}"
292
- ${r ? "required" : ""}
293
- ${o ? `pattern="${o}"` : ""}
294
- ${c ? `minlength="${c}"` : ""}
295
- ${d ? `maxlength="${d}"` : ""}
296
- ${p ? `min="${p}"` : ""}
297
- ${h ? `max="${h}"` : ""}
298
- ${b ? "disabled" : ""}
299
- aria-invalid="${m}"
300
- aria-describedby="${i}-error"
301
- />
302
- <span class="input-error${m && n ? "" : " hidden"}" id="${i}-error" role="alert">${n}</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", S);
308
- class L extends g {
309
- constructor() {
310
- super(...arguments);
311
- u(this, "columns", []);
312
- u(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(""), s = this.rows.map(
327
- (i, n) => `<tr data-row-index="${n}">${t.map(
328
- (r) => r.actions ? `<td class="align-center actions-cell">
329
- ${r.actions.edit ? `<ui-button variant="primary" class='action-btn' icon='edit' size="sm" data-action="edit" data-row-index="${n}">Edit</ui-button>` : ""}
330
- ${r.actions.delete ? `<ui-button variant="danger" class='action-btn' icon='trash' size="sm" data-action="delete" data-row-index="${n}">Delete</ui-button>` : ""}
331
- </td>` : `<td class="align-${r.align ?? "left"}">${String(
332
- i[r.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>${s}</tbody>
342
- </table>
343
- </div>
344
- `, this.shadowRoot.querySelectorAll(".action-btn").forEach((i) => {
345
- i.addEventListener("click", (n) => {
346
- const r = n.currentTarget, o = r.dataset.action, c = parseInt(r.dataset.rowIndex || "0", 10), d = o === "edit" ? "edit-action" : "delete-action";
347
- this.dispatchEvent(new CustomEvent(d, {
348
- bubbles: !0,
349
- composed: !0,
350
- detail: { row: this.rows[c], rowIndex: c }
351
- }));
352
- });
353
- });
354
- }
355
- }
356
- customElements.define("ui-table", L);
357
- class z extends g {
358
- constructor() {
359
- super(...arguments);
360
- u(this, "inputElement", null);
361
- u(this, "isConnected", !1);
362
- u(this, "isInternalUpdate", !1);
363
- u(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, s) {
372
- if (!(!this.isConnected || e === s)) {
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 s = this.getValue(), i = this.getFormat(), n = this.formatDate(s, i);
385
- t.value = n, e.value = s;
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 s = t.split("-");
416
- if (s.length !== 3) return t;
417
- const [i, n, r] = s;
418
- switch (e) {
419
- case "DD/MM/YYYY":
420
- return `${r}/${n}/${i}`;
421
- case "MM/DD/YYYY":
422
- return `${n}/${r}/${i}`;
423
- case "DD-MM-YYYY":
424
- return `${r}-${n}-${i}`;
425
- case "MM-DD-YYYY":
426
- return `${n}-${r}-${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 s, i, n, r;
438
- switch (e) {
439
- case "DD/MM/YYYY":
440
- if (s = t.split("/"), s.length !== 3) return "";
441
- [r, n, i] = s;
442
- break;
443
- case "MM/DD/YYYY":
444
- if (s = t.split("/"), s.length !== 3) return "";
445
- [n, r, i] = s;
446
- break;
447
- case "DD-MM-YYYY":
448
- if (s = t.split("-"), s.length !== 3) return "";
449
- [r, n, i] = s;
450
- break;
451
- case "MM-DD-YYYY":
452
- if (s = t.split("-"), s.length !== 3) return "";
453
- [n, r, i] = s;
454
- break;
455
- case "YYYY-MM-DD":
456
- default:
457
- return t;
458
- }
459
- return n = n.padStart(2, "0"), r = r.padStart(2, "0"), `${i}-${n}-${r}`;
460
- }
461
- attachEventListeners() {
462
- if (!this.shadowRoot) return;
463
- const t = this.shadowRoot.querySelector(".formatted-input"), e = this.shadowRoot.querySelector('input[type="date"]'), s = this.shadowRoot.querySelector(".calendar-btn");
464
- if (!t || !e) return;
465
- const i = () => {
466
- const n = t.value, r = this.getFormat(), o = this.parseDate(n, r);
467
- this.isValidDate(o) ? (e.value = o, t.classList.remove("invalid"), this.dispatchDateChange(o)) : n === "" ? (e.value = "", t.classList.remove("invalid"), this.dispatchDateChange("")) : t.classList.add("invalid");
468
- };
469
- t.addEventListener("blur", i), t.addEventListener("keydown", (n) => {
470
- n.key === "Enter" && (i(), t.blur());
471
- }), e.addEventListener("change", (n) => {
472
- const o = n.target.value, c = this.getFormat(), d = this.formatDate(o, c);
473
- t.value = d, t.classList.remove("invalid"), this.dispatchDateChange(o);
474
- }), s && s.addEventListener("click", async (n) => {
475
- n.preventDefault(), n.stopPropagation(), e.style.pointerEvents = "auto";
476
- try {
477
- typeof e.showPicker == "function" ? e.showPicker() : (e.focus(), e.click());
478
- } catch (r) {
479
- console.log("Date picker error:", r), 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(), s = this.formatDate(t, e);
494
- this.dispatchEvent(
495
- new CustomEvent("date-change", {
496
- detail: {
497
- value: t,
498
- formattedValue: s,
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(), s = this.getMin(), i = this.getMax(), n = this.isDisabled(), r = this.getPlaceholder(), o = this.getLabel(), c = this.formatDate(t, e), d = o !== "";
533
- this.shadowRoot.innerHTML = `
534
- <style>${f}</style>
535
- <div class="date-picker-container">
536
- ${d ? `<label class="date-picker-label">${o}</label>` : ""}
537
- <div class="date-input-wrapper ${n ? "disabled" : ""}">
538
- <input
539
- type="text"
540
- class="formatted-input"
541
- part="input"
542
- value="${c}"
543
- placeholder="${r}"
544
- ${n ? "disabled" : ""}
545
- />
546
- <button
547
- class="calendar-btn"
548
- type="button"
549
- ${n ? "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
- ${s ? `min="${s}"` : ""}
561
- ${i ? `max="${i}"` : ""}
562
- ${n ? "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", z);
571
- class I extends g {
572
- constructor() {
573
- super(...arguments);
574
- u(this, "_total", 0);
575
- u(this, "_currentPage", 1);
576
- u(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, s) {
585
- switch (t) {
586
- case "total":
587
- this._total = parseInt(s, 10) || 0;
588
- break;
589
- case "current-page":
590
- this._currentPage = parseInt(s, 10) || 1;
591
- break;
592
- case "page-size":
593
- this._pageSize = parseInt(s, 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, n) => n + 1);
637
- const s = [];
638
- return e <= 3 ? s.push(1, 2, 3, 4, "...", t) : e >= t - 2 ? s.push(1, "...", t - 3, t - 2, t - 1, t) : s.push(1, "...", e - 1, e, e + 1, "...", t), s;
639
- }
640
- render() {
641
- const t = this.totalPages, e = this._currentPage, s = this.getPageNumbers(), i = (e - 1) * this._pageSize + 1, n = 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 ${n} 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
- ${s.map((r) => r === "..." ? '<button class="page-btn ellipsis" disabled>...</button>' : `
661
- <button
662
- class="page-btn ${r === e ? "active" : ""}"
663
- data-page="${r}"
664
- aria-label="Page ${r}"
665
- ${r === e ? 'aria-current="page"' : ""}
666
- >
667
- ${r}
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 s = t.target.closest(".page-btn");
688
- if (!s || s.disabled) return;
689
- const i = s.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 n = parseInt(i, 10);
696
- isNaN(n) || this.handlePageChange(n);
697
- }
698
- });
699
- }
700
- }
701
- customElements.define("ui-pagination", I);
702
- class M extends g {
703
- constructor() {
704
- super(...arguments);
705
- u(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, s) {
714
- t === "open" && e !== s && this.isOpen.set(s !== 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") || "", s = 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 ${s}" part="content" @click="${(r) => r.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"), n = this.shadowRoot.querySelector(".modal-close");
769
- i == null || i.addEventListener("click", (r) => this.handleBackdropClick(r)), n == null || n.addEventListener("click", () => this.close());
770
- }
771
- }
772
- customElements.define("ui-modal", M);
773
- class R extends g {
774
- constructor() {
775
- super(...arguments);
776
- u(this, "isOpen", this.useSignal(!1));
777
- u(this, "selectedValue", this.useSignal(""));
778
- u(this, "searchTerm", this.useSignal(""));
779
- u(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, s) {
788
- t === "value" && e !== s && this.selectedValue.set(s || ""), t === "options" && e !== s && 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((s) => s.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"), s = this.hasAttribute("searchable"), i = this.getAttribute("label") || "", n = this.getSelectedLabel(), r = this.getFilteredOptions(), o = 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 ${o ? "has-selection" : ""}">${n}</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
- ${s ? `
849
- <input
850
- type="text"
851
- class="select-search"
852
- placeholder="Search..."
853
- part="search"
854
- >
855
- ` : ""}
856
-
857
- ${r.length > 0 ? r.map((h) => `
858
- <div
859
- class="select-option ${h.value === this.selectedValue.get() ? "selected" : ""} ${h.disabled ? "disabled" : ""}"
860
- data-value="${h.value}"
861
- part="option"
862
- >
863
- ${h.label}
864
- </div>
865
- `).join("") : `
866
- <div class="select-empty">No options found</div>
867
- `}
868
- </div>
869
- </div>
870
- `;
871
- const c = this.shadowRoot.querySelector(".select-trigger"), d = this.shadowRoot.querySelector(".select-search"), p = this.shadowRoot.querySelectorAll(".select-option:not(.disabled)");
872
- c == null || c.addEventListener("click", () => this.toggleDropdown()), c == null || c.addEventListener("keydown", (h) => {
873
- (h.key === "Enter" || h.key === " ") && (h.preventDefault(), this.toggleDropdown());
874
- }), d == null || d.addEventListener("input", (h) => {
875
- this.handleSearch(h.target.value);
876
- }), d == null || d.addEventListener("click", (h) => h.stopPropagation()), p.forEach((h) => {
877
- h.addEventListener("click", () => {
878
- const b = h.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
- u(this, "checked", this.useSignal(!1));
889
- u(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, s) {
898
- t === "checked" && e !== s && this.checked.set(s !== null), t === "indeterminate" && e !== s && this.indeterminate.set(s !== 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(), s = this.hasAttribute("disabled"), i = this.getAttribute("label") || "", n = this.getAttribute("size") || "md", r = {
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 ${r[n]}">
926
- <input
927
- type="checkbox"
928
- ${t ? "checked" : ""}
929
- ${s ? "disabled" : ""}
930
- >
931
- <div class="checkbox-box ${r[n]} ${t ? "checked" : ""} ${e ? "indeterminate" : ""} ${s ? "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 o = this.shadowRoot.querySelector(".checkbox-container");
943
- o == null || o.addEventListener("click", (c) => {
944
- c.preventDefault(), this.handleChange();
945
- });
946
- }
947
- }
948
- customElements.define("ui-checkbox", D);
949
- const T = ':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
- u(this, "activeId", null);
954
- u(this, "indicator", null);
955
- u(this, "handleTabClick", (t) => {
956
- const e = t.target;
957
- if (!e) return;
958
- const s = e.closest('[slot="tab"][data-tab]');
959
- if (!s) return;
960
- t.preventDefault();
961
- const i = s.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, s) {
975
- t === "active" && e !== s && (this.activeId = s, 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 s = t.find((i) => i.getAttribute("data-tab"));
1001
- return (s == null ? void 0 : s.getAttribute("data-tab")) ?? null;
1002
- }
1003
- syncTabs() {
1004
- const t = this.getTabs(), e = this.getPanels();
1005
- if (t.length === 0) return;
1006
- const s = this.getActiveId(t);
1007
- s && (this.activeId = s, this.getAttribute("active") !== s && this.setAttribute("active", s), t.forEach((i) => {
1008
- const n = i.getAttribute("data-tab");
1009
- if (!n) return;
1010
- const r = i.id || `tab-${n}`, o = n === s;
1011
- i.id = r, i.setAttribute("role", "tab"), i.setAttribute("aria-selected", String(o)), i.setAttribute("tabindex", o ? "0" : "-1"), i.classList.toggle("is-active", o);
1012
- }), e.forEach((i) => {
1013
- const n = i.getAttribute("data-tab");
1014
- if (!n) return;
1015
- const r = i.id || `panel-${n}`, o = n === s;
1016
- i.id = r, i.setAttribute("role", "tabpanel"), i.toggleAttribute("hidden", !o), i.classList.toggle("is-active", o);
1017
- const c = t.find((d) => d.getAttribute("data-tab") === n);
1018
- c && (c.setAttribute("aria-controls", r), i.setAttribute("aria-labelledby", c.id));
1019
- }), this.updateIndicator(t, s));
1020
- }
1021
- updateIndicator(t, e) {
1022
- if (!this.indicator) return;
1023
- const s = t.find((o) => o.getAttribute("data-tab") === e);
1024
- if (!s) return;
1025
- const i = this.shadowRoot.querySelector(".tablist");
1026
- if (!i) return;
1027
- s.getBoundingClientRect(), i.getBoundingClientRect();
1028
- const n = t.indexOf(s);
1029
- let r = 0;
1030
- for (let o = 0; o < n; o++)
1031
- r += t[o].offsetWidth;
1032
- this.indicator.style.transform = `translateX(${r}px)`, this.indicator.style.width = `${s.offsetWidth}px`;
1033
- }
1034
- render() {
1035
- this.shadowRoot.innerHTML = `
1036
- <style>${f}${T}</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 q = ':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 a = this.getAttribute("variant");
1074
- return a === "elevated" || a === "bordered" || a === "ghost" ? a : "default";
1075
- }
1076
- getElevation() {
1077
- const a = this.getAttribute("elevation");
1078
- return a === "none" || a === "sm" || a === "md" || a === "lg" || a === "xl" ? a : "sm";
1079
- }
1080
- render() {
1081
- const a = this.getShadow(), t = this.getShadowColor(), e = this.getRounded(), s = this.getVariant(), i = this.getElevation();
1082
- let n = "none";
1083
- if (a)
1084
- switch (i) {
1085
- case "sm":
1086
- n = `0 1px 2px rgba(${t}, 0.05), 0 1px 3px rgba(${t}, 0.1)`;
1087
- break;
1088
- case "md":
1089
- n = `0 4px 6px rgba(${t}, 0.07), 0 2px 4px rgba(${t}, 0.06)`;
1090
- break;
1091
- case "lg":
1092
- n = `0 10px 15px rgba(${t}, 0.1), 0 4px 6px rgba(${t}, 0.05)`;
1093
- break;
1094
- case "xl":
1095
- n = `0 20px 25px rgba(${t}, 0.15), 0 10px 10px rgba(${t}, 0.04)`;
1096
- break;
1097
- default:
1098
- n = "none";
1099
- }
1100
- this.shadowRoot.innerHTML = `
1101
- <style>
1102
- ${f}
1103
- ${q}
1104
-
1105
- .card.custom-shadow {
1106
- box-shadow: ${n};
1107
- }
1108
-
1109
- .card.custom-shadow:hover {
1110
- box-shadow: ${a && i !== "none" ? n.replace(/rgba\(([^)]+), ([\d.]+)\)/g, (r, o, c) => `rgba(${o}, ${Math.min(parseFloat(c) * 1.3, 0.25)})`) : "none"};
1111
- }
1112
- </style>
1113
- <div class="card ${s} ${e ? "rounded" : "square"} ${a ? "custom-shadow" : "no-shadow"}">
1114
- <slot></slot>
1115
- </div>
1116
- `;
1117
- }
1118
- }
1119
- customElements.define("ui-card", H);
1120
- const P = ":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 O extends g {
1122
- constructor() {
1123
- super(...arguments);
1124
- u(this, "toasts", /* @__PURE__ */ new Map());
1125
- u(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 s = {
1143
- success: "check-circle",
1144
- error: "x-circle",
1145
- warning: "alert-triangle",
1146
- info: "info"
1147
- }[t];
1148
- return ((i = w.icons[s]) == 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: s = "",
1159
- type: i = "info",
1160
- duration: n = 5e3,
1161
- closable: r = !0
1162
- } = t, o = `toast-${++this.toastCounter}`, c = this.getIcon(i), d = document.createElement("div");
1163
- d.className = `toast ${i}`, d.setAttribute("role", "alert"), d.setAttribute("aria-live", "polite"), d.innerHTML = `
1164
- <div class="toast-icon">${c}</div>
1165
- <div class="toast-content">
1166
- <div class="toast-title">${this.escapeHtml(e)}</div>
1167
- ${s ? `<div class="toast-description">${this.escapeHtml(s)}</div>` : ""}
1168
- </div>
1169
- ${r ? `
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
- ${n > 0 ? `
1178
- <div class="toast-progress">
1179
- <div class="toast-progress-bar" style="--duration: ${n}ms"></div>
1180
- </div>
1181
- ` : ""}
1182
- `;
1183
- const p = this.shadowRoot.querySelector(".toast-container");
1184
- if (p && p.appendChild(d), r) {
1185
- const b = d.querySelector(".toast-close");
1186
- b == null || b.addEventListener("click", () => this.dismiss(o));
1187
- }
1188
- let h;
1189
- return n > 0 && (h = window.setTimeout(() => {
1190
- this.dismiss(o);
1191
- }, n)), this.toasts.set(o, { element: d, timer: h }), this.dispatchEvent(
1192
- new CustomEvent("toast-show", {
1193
- bubbles: !0,
1194
- composed: !0,
1195
- detail: { id: o, ...t }
1196
- })
1197
- ), o;
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, s) {
1224
- return this.show({ title: t, description: e, type: "success", duration: s });
1225
- }
1226
- error(t, e, s) {
1227
- return this.show({ title: t, description: e, type: "error", duration: s });
1228
- }
1229
- warning(t, e, s) {
1230
- return this.show({ title: t, description: e, type: "warning", duration: s });
1231
- }
1232
- info(t, e, s) {
1233
- return this.show({ title: t, description: e, type: "info", duration: s });
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
- ${P}
1245
- </style>
1246
- <div class="toast-container ${t}"></div>
1247
- `;
1248
- }
1249
- }
1250
- customElements.define("ui-toast", O);
1251
- class F extends g {
1252
- constructor() {
1253
- super(...arguments);
1254
- u(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, s) {
1263
- if (t === "steps" && e !== s && this.parseSteps(), t === "active" && e !== s) {
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, s) {
1294
- return t.state ? t.state : e + 1 < s ? "complete" : e + 1 === s ? "active" : "upcoming";
1295
- }
1296
- setActive(t) {
1297
- const e = this.steps.length;
1298
- if (e === 0) return;
1299
- const s = Math.min(Math.max(t, 1), e);
1300
- if (s === this.getActiveIndex(e)) return;
1301
- this.setAttribute("active", String(s));
1302
- const i = this.steps[s - 1], n = this.resolveState(i, s - 1, s);
1303
- this.dispatchEvent(
1304
- new CustomEvent("step-change", {
1305
- bubbles: !0,
1306
- composed: !0,
1307
- detail: { index: s, step: i, state: n }
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(), s = this.steps, i = s.length, n = 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
- ${s.map((r, o) => {
1323
- const c = this.resolveState(r, o, n), d = c === "active", p = r.disabled ? "disabled" : "";
1324
- return `
1325
- <li class="step ${c} ${p}" data-state="${c}">
1326
- <button class="step-trigger" data-index="${o}" ${r.disabled ? "disabled" : ""} aria-current="${d ? "step" : "false"}">
1327
- <span class="step-node">${o + 1}</span>
1328
- <span class="step-text">
1329
- <span class="step-title">${this.escapeHtml(r.title || `Step ${o + 1}`)}</span>
1330
- ${r.description ? `<span class="step-desc">${this.escapeHtml(r.description)}</span>` : ""}
1331
- </span>
1332
- </button>
1333
- ${o < 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((r) => {
1341
- r.addEventListener("click", () => {
1342
- const o = parseInt(r.dataset.index || "0", 10);
1343
- Number.isNaN(o) || this.setActive(o + 1);
1344
- });
1345
- });
1346
- }
1347
- }
1348
- customElements.define("ui-stepper", F);
1349
- class U extends g {
1350
- constructor() {
1351
- super(...arguments);
1352
- u(this, "files", this.useSignal([]));
1353
- u(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 s = new DataTransfer();
1408
- e.forEach((i) => s.items.add(i)), t.files = s.files;
1409
- }
1410
- render() {
1411
- const t = this.getAccept(), e = this.getLabel(), s = this.getHelper(), i = this.isDisabled(), n = this.isMultiple(), r = this.isDragging.get(), o = 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 ${r ? "dragging" : ""} ${i ? "disabled" : ""}" part="dropzone">
1417
- <input
1418
- class="upload-input"
1419
- type="file"
1420
- ${n ? "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
- ${s ? `<div class="upload-helper">${s}</div>` : ""}
1442
- ${o.length ? `
1443
- <ul class="upload-list">
1444
- ${o.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 c = this.shadowRoot.querySelector(".upload-drop"), d = this.shadowRoot.querySelector(".upload-input"), p = this.shadowRoot.querySelector(".upload-btn"), h = this.shadowRoot.querySelectorAll(".upload-remove");
1458
- !c || !d || (o.length ? this.syncInputFiles(d, o) : d.value = "", c.addEventListener("dragover", (b) => {
1459
- i || (b.preventDefault(), this.isDragging.set(!0));
1460
- }), c.addEventListener("dragleave", () => {
1461
- this.isDragging.set(!1);
1462
- }), c.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(d, this.files.get()));
1468
- }), d.addEventListener("change", () => {
1469
- const b = Array.from(d.files ?? []);
1470
- this.setFiles(b);
1471
- }), p == null || p.addEventListener("click", () => {
1472
- i || d.click();
1473
- }), h.forEach((b) => {
1474
- b.addEventListener("click", () => {
1475
- const m = parseInt(b.dataset.index || "0", 10), v = this.files.get().filter((X, $) => $ !== m);
1476
- this.setFiles(v), this.syncInputFiles(d, v);
1477
- });
1478
- }));
1479
- }
1480
- }
1481
- customElements.define("ui-upload", U);
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 a = this.getAttribute("direction");
1494
- return a === "horizontal" || a === "vertical" ? a : "auto";
1495
- }
1496
- detectDirection() {
1497
- const a = this.getDirection();
1498
- if (a !== "auto") return a;
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 a = this.detectDirection() === "horizontal" ? "row" : "column";
1504
- this.shadowRoot.innerHTML = `
1505
- <style>${f}</style>
1506
- <div class="layout-container" style="flex-direction: ${a}">
1507
- <slot></slot>
1508
- </div>
1509
- `;
1510
- }
1511
- }
1512
- class j 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 a = this.getAttribute("height");
1524
- return a && /^\d+$/.test(a) ? a + "px" : a || "64px";
1525
- }
1526
- render() {
1527
- const a = this.getHeight();
1528
- this.shadowRoot.innerHTML = `
1529
- <style>${f}</style>
1530
- <header class="layout-header" style="height: ${a}">
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 a = this.getAttribute("height");
1548
- return a && /^\d+$/.test(a) ? a + "px" : a || "56px";
1549
- }
1550
- render() {
1551
- const a = this.getHeight();
1552
- this.shadowRoot.innerHTML = `
1553
- <style>${f}</style>
1554
- <footer class="layout-footer" style="height: ${a}">
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 B extends g {
1574
- constructor() {
1575
- super(...arguments);
1576
- u(this, "isCollapsed", !1);
1577
- u(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(), s = this.isCollapsible();
1617
- s && 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
- ${s ? `
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", j);
1638
- customElements.define("ui-layout-footer", N);
1639
- customElements.define("ui-layout-content", _);
1640
- customElements.define("ui-layout-sidebar", B);
1641
- class W {
1642
- constructor() {
1643
- u(this, "baseURL", "");
1644
- u(this, "defaultHeaders", {
1645
- "Content-Type": "application/json"
1646
- });
1647
- u(this, "defaultTimeout", 3e4);
1648
- u(this, "interceptors", {
1649
- request: {
1650
- handlers: [],
1651
- use: (a, t) => {
1652
- this.interceptors.request.handlers.push({ onFulfilled: a, onRejected: t });
1653
- }
1654
- },
1655
- response: {
1656
- handlers: [],
1657
- use: (a, t) => {
1658
- this.interceptors.response.handlers.push({ onFulfilled: a, onRejected: t });
1659
- }
1660
- }
1661
- });
1662
- }
1663
- /**
1664
- * Set base URL for all requests
1665
- */
1666
- setBaseURL(a) {
1667
- this.baseURL = a;
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(a) {
1679
- this.defaultHeaders = { ...this.defaultHeaders, ...a };
1680
- }
1681
- /**
1682
- * Set default timeout for all requests (in ms)
1683
- */
1684
- setDefaultTimeout(a) {
1685
- this.defaultTimeout = a;
1686
- }
1687
- /**
1688
- * Execute request with interceptors
1689
- */
1690
- async executeRequest(a, t) {
1691
- const e = a.startsWith("http") ? a : this.baseURL + a;
1692
- let s = {
1693
- method: "GET",
1694
- headers: { ...this.defaultHeaders },
1695
- timeout: this.defaultTimeout,
1696
- ...t
1697
- };
1698
- for (const r of this.interceptors.request.handlers)
1699
- try {
1700
- s = await r.onFulfilled(s);
1701
- } catch (o) {
1702
- if (r.onRejected)
1703
- s = await r.onRejected(o);
1704
- else
1705
- throw o;
1706
- }
1707
- const i = new AbortController(), n = setTimeout(() => i.abort(), s.timeout || this.defaultTimeout);
1708
- try {
1709
- const r = {
1710
- method: s.method,
1711
- headers: s.headers,
1712
- signal: i.signal
1713
- };
1714
- s.body && s.method !== "GET" && (r.body = (typeof s.body == "string", s.body));
1715
- const o = await fetch(e, r);
1716
- let c;
1717
- const d = o.headers.get("content-type");
1718
- d != null && d.includes("application/json") ? c = o.ok ? await o.json() : null : d != null && d.includes("text") ? c = await o.text() : c = await o.blob();
1719
- let p = {
1720
- status: o.status,
1721
- statusText: o.statusText,
1722
- headers: o.headers,
1723
- data: c
1724
- };
1725
- if (!o.ok) {
1726
- const h = new Error(`HTTP ${o.status}: ${o.statusText}`);
1727
- throw h.response = p, h.config = s, h;
1728
- }
1729
- for (const h of this.interceptors.response.handlers)
1730
- try {
1731
- p = await h.onFulfilled(p);
1732
- } catch (b) {
1733
- if (h.onRejected)
1734
- p = await h.onRejected(b);
1735
- else
1736
- throw b;
1737
- }
1738
- return p.data;
1739
- } catch (r) {
1740
- throw r instanceof Error && r.name === "AbortError" ? new Error(`Request timeout after ${s.timeout}ms`) : r;
1741
- } finally {
1742
- clearTimeout(n);
1743
- }
1744
- }
1745
- /**
1746
- * GET request
1747
- */
1748
- async get(a, t) {
1749
- return this.executeRequest(a, { ...t, method: "GET" });
1750
- }
1751
- /**
1752
- * POST request
1753
- */
1754
- async post(a, t, e) {
1755
- return this.executeRequest(a, {
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(a, t, e) {
1765
- return this.executeRequest(a, {
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(a, t, e) {
1775
- return this.executeRequest(a, {
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(a, t) {
1785
- return this.executeRequest(a, { ...t, method: "DELETE" });
1786
- }
1787
- /**
1788
- * HEAD request
1789
- */
1790
- async head(a, t) {
1791
- return this.executeRequest(a, { ...t, method: "HEAD" });
1792
- }
1793
- }
1794
- const Z = new W();
1795
- function x(l, a) {
1796
- return l ? l.querySelector(a) : null;
1797
- }
1798
- function tt(l, a) {
1799
- return l ? l.querySelectorAll(a) : [];
1800
- }
1801
- function et(l, a) {
1802
- return l ? l.querySelector(`#${a}`) : null;
1803
- }
1804
- function st(l, a, t, e, s) {
1805
- if (!l) return null;
1806
- const i = l.querySelector(`#${a}`);
1807
- return i ? (i.addEventListener(t, e, s), i) : null;
1808
- }
1809
- function at(l, a) {
1810
- return x(l, a);
1811
- }
1812
- function rt(l, a) {
1813
- return x(l, a);
1814
- }
1815
- function it(l, a) {
1816
- return x(l, a);
1817
- }
1818
- const J = "input, select, textarea, ui-input, ui-select, ui-date-picker, ui-checkbox, ui-upload";
1819
- function k(l) {
1820
- return l.getAttribute("name") || l.getAttribute("id") || "";
1821
- }
1822
- function G(l) {
1823
- const a = l.tagName.toLowerCase();
1824
- if (a === "ui-checkbox")
1825
- return l.hasAttribute("checked");
1826
- if (a === "ui-upload") {
1827
- const s = l == null ? void 0 : l.filesValue;
1828
- return Array.isArray(s) && s.length > 0 ? s : [];
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 ot(l, a = {}) {
1837
- const { includeDisabled: t = !1, includeEmpty: e = !0 } = a, s = {}, i = /* @__PURE__ */ new Map();
1838
- l.querySelectorAll('input[type="checkbox"]').forEach((r) => {
1839
- const o = k(r);
1840
- o && i.set(o, (i.get(o) || 0) + 1);
1841
- });
1842
- const n = Array.from(l.querySelectorAll(J));
1843
- for (const r of n) {
1844
- if (!t && (r.disabled || r.hasAttribute("disabled"))) continue;
1845
- const o = k(r);
1846
- if (!o) continue;
1847
- if (r instanceof HTMLInputElement) {
1848
- const d = r.type;
1849
- if (d === "checkbox") {
1850
- if ((i.get(o) || 0) > 1) {
1851
- const h = s[o] || [];
1852
- r.checked && h.push(r.value || "on"), s[o] = h;
1853
- } else
1854
- s[o] = r.checked;
1855
- continue;
1856
- }
1857
- if (d === "radio") {
1858
- r.checked && (s[o] = r.value);
1859
- continue;
1860
- }
1861
- if (d === "file") {
1862
- const p = Array.from(r.files ?? []);
1863
- (e || p.length > 0) && (s[o] = p);
1864
- continue;
1865
- }
1866
- (e || r.value !== "") && (s[o] = r.value);
1867
- continue;
1868
- }
1869
- if (r instanceof HTMLSelectElement) {
1870
- if (r.multiple) {
1871
- const d = Array.from(r.selectedOptions).map((p) => p.value);
1872
- (e || d.length > 0) && (s[o] = d);
1873
- } else (e || r.value !== "") && (s[o] = r.value);
1874
- continue;
1875
- }
1876
- if (r instanceof HTMLTextAreaElement) {
1877
- (e || r.value !== "") && (s[o] = r.value);
1878
- continue;
1879
- }
1880
- const c = G(r);
1881
- (e || (Array.isArray(c) ? c.length > 0 : c !== "")) && (s[o] = c);
1882
- }
1883
- return s;
1884
- }
1
+ import { B as s, H as t, U as o, f as I, i as U, j as r, k as n, l as u, m as y, n as l, o as d, p as i, r as p, s as m, t as b, u as q, w as C, x as L, y as T, z as c, d as g, A as B, e as E, g as P, h, c as k, C as x, q as H, b as S, a as f } from "./index-DiYekJaQ.js";
1885
2
  export {
1886
- W as HTTPClient,
1887
- E as UIButton,
1888
- H as UICard,
1889
- D as UICheckbox,
1890
- z as UIDatePicker,
1891
- S as UIInput,
1892
- V as UILayout,
1893
- _ as UILayoutContent,
1894
- N as UILayoutFooter,
1895
- j as UILayoutHeader,
1896
- B as UILayoutSidebar,
1897
- M as UIModal,
1898
- I as UIPagination,
1899
- R as UISelect,
1900
- F as UIStepper,
1901
- L as UITable,
1902
- Y as UITabs,
1903
- O as UIToast,
1904
- U as UIUpload,
1905
- st as addEventListenerById,
1906
- et as getElementById,
1907
- ot as getFormValues,
1908
- Z as http,
1909
- x as queryElement,
1910
- tt as queryElements,
1911
- it as queryModal,
1912
- rt as queryPagination,
1913
- at as queryTable
3
+ s as BaseComponent,
4
+ t as HTTPClient,
5
+ o as UIButton,
6
+ I as UICard,
7
+ U as UICheckbox,
8
+ r as UIDatePicker,
9
+ n as UIInput,
10
+ u as UILayout,
11
+ y as UILayoutContent,
12
+ l as UILayoutFooter,
13
+ d as UILayoutHeader,
14
+ i as UILayoutSidebar,
15
+ p as UIModal,
16
+ m as UIPagination,
17
+ b as UISelect,
18
+ q as UIStepper,
19
+ C as UITable,
20
+ L as UITabs,
21
+ T as UIToast,
22
+ c as UIUpload,
23
+ g as addEventListenerById,
24
+ B as createRouter,
25
+ E as getElementById,
26
+ P as getFormValues,
27
+ h as http,
28
+ k as queryElement,
29
+ x as queryElements,
30
+ H as queryModal,
31
+ S as queryPagination,
32
+ f as queryTable
1914
33
  };