UNPKG

@base-framework/ui

Version:

This is a UI package that adds components and atoms that use Tailwind CSS and a theme based on Shadcn.

1,451 lines (1,450 loc) 40.2 kB
import { Div as n, H5 as _, P as b, I as g, Li as O, Span as a, Ul as V, Button as m, OnState as v, Label as W, Form as R, H2 as A, Header as B, Footer as M, A as Y, H3 as G, Checkbox as J, Nav as K, Input as C, UseParent as Q, Time as X, Dialog as Z } from "@base-framework/atoms"; import { Atom as c, Component as p, Html as L, Dom as ee, base as te, Data as k, Builder as U, Jot as S, DateTime as $ } from "@base-framework/base"; import { P as D, b as se } from "./calendar-BDqm833e.js"; import { B as h, I as x } from "./buttons-CVEwmPAi.js"; import { Icons as u } from "./icons.es.js"; import { a as w } from "./veil-D4dRxILB.js"; import { Timer as oe, List as ne, DynamicTime as re } from "@base-framework/organisms"; const P = { info: { borderColor: "border-blue-500", bgColor: "bg-muted/10", iconColor: "text-blue-500" }, warning: { bgColor: "bg-muted/10", borderColor: "border-warning", iconColor: "text-warning" }, destructive: { bgColor: "bg-muted/10", borderColor: "border-destructive", iconColor: "text-red-500" }, success: { bgColor: "bg-muted/10", borderColor: "border-emerald-500", iconColor: "text-emerald-500" }, default: { borderColor: "border", bgColor: "bg-muted/10", iconColor: "text-muted-foreground" } }, le = (e, t) => n({ class: `flex items-center justify-center h-6 w-6 mr-3 ${t}` }, [ g({ html: e }) ]), ie = (e) => _({ class: "font-semibold" }, e), ae = (e) => b({ class: "text-sm text-muted-foreground" }, e), mt = c(({ title: e, description: t, icon: s, type: o = "default" }) => { const { borderColor: r, bgColor: l, iconColor: i } = P[o] || P.default; return n({ class: `flex items-start p-4 border rounded-lg ${l} ${r}` }, [ // Icon and content s && le(s, i), n({ class: "flex flex-col" }, [ ie(e), ae(t) ]) ]); }); class ce extends p { /** * This will declare the props for the compiler. * * @returns {void} */ declareProps() { this.removingClass = ""; } /** * This will remove the component from the DOM after a delay. * * @returns {void} */ remove() { this.prepareDestroy(), this.removeContext(); const t = this.panel, s = this.removingClass; if (!s) { L.removeElement(t); return; } ee.addClass(t, s), te.on("animationend", t, (o) => L.removeElement(t)); } } const de = (e) => a({ class: "ml-auto text-xs tracking-widest opacity-60" }, e), ue = (e) => a({ class: "flex w-4 h-4", html: e }), he = (e) => a({ class: "flex-auto" }, e), me = (e, t) => O({ class: "relative flex cursor-pointer hover:bg-muted/50 select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0", click: () => t(e) }, [ e.icon && ue(e.icon), he(e.label), e.shortcut && de(e.shortcut) ]), fe = (e, t) => V({ class: "grid gap-2" }, [ e.map((s) => me(s, t)) ]), ge = (e) => n({ class: "w-full z-10" }, [ n({ class: "max-h-60 border rounded-md overflow-y-auto p-1 grid gap-2 divide-y divide-border", for: ["groups", (t) => fe(t, e)] }) ]), be = ({ label: e, icon: t, toggleDropdown: s }) => m({ cache: "button", class: `inline-flex items-center justify-between rounded-md border border-input bg-background px-2 py-2 text-sm font-medium hover:bg-muted focus:outline-none transition duration-150 ease-in-out`, click: s }, [ e && a(e), t && g({ html: t }) ]), pe = ({ onSelect: e }) => n([ v( "open", (t, s, o) => t ? new D({ cache: "dropdown", parent: o, button: o.button }, [ ge(e) ]) : null ) ]); class ft extends p { /** * This will declare the props for the compiler. * * @returns {void} */ declareProps() { this.label = null, this.icon = null, this.onSelect = null, this.groups = []; } /** * Initializes component data. * * @returns {Data} */ setData() { return new k({ groups: this.groups || [] }); } /** * Initializes the component state. * * @returns {object} */ setupStates() { return { open: !1, selectedItem: null }; } /** * Toggles the dropdown open state. * * @returns {void} */ toggleDropdown() { this.state.toggle("open"); } /** * Handles item selection within the dropdown. * * @param {object} item - The selected item object * @returns {void} */ handleSelect(t) { this.state.selectedItem = t, this.state.open = !1, typeof this.onSelect == "function" && this.onSelect(t); } /** * Renders the Dropdown component. * * @returns {object} */ render() { return n({ class: "relative" }, [ be({ label: this.label, icon: this.icon, toggleDropdown: this.toggleDropdown.bind(this) }), pe({ onSelect: this.handleSelect.bind(this) }) ]); } } const xe = c((e, t) => n({ ...e, class: "flex flex-auto flex-col space-y-2" }, t)), we = c((e, t) => W({ ...e, class: "flex auto text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70" }, t)), ye = c((e, t) => b({ ...e, class: "text-sm text-muted-foreground italic" }, t)), ve = c((e, t) => b({ ...e, class: "text-sm text-destructive" }, t)), Ce = (e) => e.tag === "input" || e.tag === "select" || e.tag === "textarea", q = (e, t, s) => e.map((o) => (o.children && o.children.length > 0 && (o.children = q(o.children, t, s)), o.required && Ce(o) ? { ...o, aria: { invalid: ["hasError"] }, invalid: s, input: t } : o)), ke = c((e, t) => { const r = q(t, (l) => { l.target.checkValidity() && e.setError(null); }, (l) => { e.setError(l.target.validationMessage); }); return n({ ...e, class: "w-full" }, r); }), gt = w( { /** * The initial state of the FormField. * * @member {object} state * @returns {object} */ state() { return { error: null, hasError: !1, value: this.defaultValue ?? "" }; }, /** * Renders the FormField component. * * @returns {object} */ render() { const e = this.name, t = this.getId(`${e}`), { label: s, description: o } = this, r = (l) => { this.state.error = l, this.state.hasError = !!l; }; return n({ class: "flex flex-auto space-y-4" }, [ xe([ we({ htmlFor: t }, s), ke({ id: t, name: e, value: this.state.value, setError: r }, this.children), o && ye({ id: this.getId("description") }, o), n({ onState: ["error", (l) => l && ve(l)] }) ]) ]); } } ), Se = (e, t, s = null) => { e.target.checkValidity() && (e.preventDefault(), s && s(e, t)); }, De = c( (e, t) => R({ ...e, submit: (s, o) => Se(s, o, e.submit), class: `w-full ${e.class ?? ""}` }, t) ), bt = c((e, t) => n({ ...e, class: `space-y-6 p-4 md:p-6 divide-y ${e.class || ""}` }, t)), pt = c((e, t = []) => n({ class: "space-y-3 py-4" }, [ e.title && A({ class: "font-semibold" }, e.title), ...t ])), xt = (e, t) => n({ class: "flex justify-between" }, [ a({ class: "text-muted-foreground" }, e), a(t) ]), Ie = ({ title: e, description: t, back: s, icon: o, options: r = [] }) => B({ class: "modal-header bg-background/80 backdrop-blur-md sticky flex flex-none items-center py-4 px-6 z-10" }, [ /** * Back Button */ s && h({ variant: "icon", icon: u.arrows.left, class: "mr-2 p-0 flex sm:hidden", click: (l, i) => i.close() }), /** * Icon */ o && n({ class: "mr-2 w-12 h-12 rounded-full bg-muted flex flex-none items-center justify-center" }, [x(o)]), /** * Title and Description */ n({ class: "flex flex-auto flex-row justify-between w-full ml-2 gap-2" }, [ n({ class: "flex flex-auto flex-col" }, [ A({ class: "text-lg font-semibold m-0 truncate" }, e), t && n({ class: "text-sm text-muted-foreground truncate" }, t) ]), ...r ]) ]), Te = c((e, t) => n({ popover: "manual", class: `modal m-auto top-0 right-0 bottom-0 left-0 fixed z-20 grid w-full h-full max-h-screen gap-2 lg:border bg-background text-foreground shadow-xl break-words p-0 ${e.class}`, click: (s, o) => { s.target === o.panel && (s.preventDefault(), s.stopPropagation(), o.state.open = !1); } }, [ De({ class: "modal-content relative bg-background z-[1] flex flex-auto flex-col space-y-4", submit: (s, o) => e.onSubmit && e.onSubmit(o) }, [ Ie(e), n({ class: "modal-body flex flex-grow flex-col overflow-y-auto py-0 px-6 z-0" }, t), M({ class: "modal-footer sticky bg-background/80 backdrop-blur-md flex flex-none justify-between py-4 px-6 z-10" }, e.buttons) ]) ])), $e = (e) => U.render(e, app.root); class wt extends p { /** * This will declare the props for the compiler. * * @returns {void} */ declareProps() { this.title = null, this.description = null, this.size = null, this.type = null, this.hidePrimaryButton = !1, this.icon = null, this.onSubmit = null, this.onClose = null, this.back = !1; } /** * This will render the modal component. * * @returns {object} */ render() { const t = this.getMainClass(), s = this.title || "", o = this.description || null; return Te( { class: t, title: s, description: o, options: this.headerOptions(), buttons: this.getButtons(), onSubmit: (r) => { this.onSubmit && this.onSubmit(r), this.destroy(); }, icon: this.icon, back: this.back ?? !1, aria: { expanded: ["open"] } }, this.children ); } /** * This will setup the states. * * @returns {object} */ setupStates() { return { open: { state: !1, callBack: (t) => { t || this.destroy(); } } }; } /** * This will get the header options. * * @returns {Array<object>} */ headerOptions() { return []; } /** * This will get the buttons for the modal. * * @returns {array} */ getButtons() { return [ h({ variant: "outline", click: () => this.destroy() }, "Cancel"), this.hidePrimaryButton !== !0 && h({ variant: "primary", type: "submit" }, "Save") ]; } /** * This will check if the click was outside the component. * * @param {object} element * @returns {boolean} */ isOutsideClick(t) { return !this.panel.contains(t); } /** * This will get the size class. * * @returns {string} */ getSizeClass() { switch (this.size) { // case 'sm': // return 'sm max-w-[646px]'; case "lg": return "lg max-w-[900px]"; case "xl": return "xl max-w-[1400px]"; default: return "md max-w-[760px]"; } } /** * This will get the type class. * * @returns {string} */ getTypeClass() { switch (this.type) { case "right": return "right right-0"; case "left": return "left left-0"; default: return ""; } } /** * This will get the modal class. * * @returns {string} */ getMainClass() { return this.getSizeClass() + " " + this.getTypeClass(); } /** * This will override the set up to use the app shell. * * @param {object} container */ setContainer(t) { this.container = app.root; } /** * This will open the modal. * * @returns {void} */ open() { $e(this), this.showModal(); } /** * This will show the modal. * * @protected * @returns {void} */ showModal() { window.setTimeout(() => this.panel.showPopover(), 10), this.state.open = !0, document.documentElement.style.overflowY = "hidden"; } /** * This will hide the modal. * * @protected * @returns {void} */ beforeDestroy() { this.panel.hidePopover(), this.state.open = !1, typeof this.onClose == "function" && this.onClose(), document.documentElement.style.overflowY = "auto"; } } const F = { info: { bgColor: "bg-muted/10", borderColor: "border-blue-500", iconColor: "text-blue-500" }, warning: { bgColor: "bg-muted/10", borderColor: "border-warning", iconColor: "text-warning" }, destructive: { bgColor: "bg-muted/10", borderColor: "border-destructive", iconColor: "text-red-500" }, success: { bgColor: "bg-muted/10", borderColor: "border-emerald-500", iconColor: "text-emerald-500" }, default: { bgColor: "bg-muted/10", borderColor: "border", iconColor: "text-muted-foreground" } }, Ae = (e) => B({ class: "flex justify-center" }, [ G({ class: "text-lg font-bold mb-0" }, e) ]), Be = c(({ href: e, class: t }, s) => Y({ class: `pullRightIn bg-popover text-popover-foreground relative flex flex-auto flex-col justify-start shadow-lg pointer-events-auto p-4 border rounded-md min-w-[340px] max-w-[450px] mt-4 ${t}`, href: e, role: "alert" }, s)), Me = c(({ close: e, class: t }, s) => n({ class: `pullRightIn bg-popover text-popover-foreground relative flex flex-auto flex-col justify-start shadow-lg pointer-events-auto p-4 border rounded-md min-w-[340px] max-w-[450px] mt-4 ${t}`, click: () => e(), role: "alert" }, s)); class Le extends ce { /** * This will declare the props for the compiler. * * @returns {void} */ declareProps() { this.removingClass = "pullRight", this.secondaryAction = null, this.primaryAction = null, this.primary = !1, this.secondary = !1, this.title = null, this.description = null, this.icon = null, this.onClick = null; } /** * This will be called when the component is created. * * @returns {void} */ onCreated() { this.duration = this.duration || 4e3; } /** * This will render the component. * * @returns {object} */ render() { const { bgColor: t, borderColor: s, iconColor: o } = this.getTypeStyles(), r = this.href || null, l = this.getChildren(o); return r ? Be({ href: r, class: `${t} ${s}` }, l) : Me({ close: this.close.bind(this), class: `${t} ${s}` }, l); } /** * This will be called after the component is set up. * * @returns {void} */ afterSetup() { const t = this.duration; t !== "infinite" && (this.timer = new oe(t, this.close.bind(this)), this.timer.start()); } /** * This will get the style properties based on the notification type. * * @returns {object} */ getTypeStyles() { const t = this.type || "default"; return F[t] || F.default; } /** * This will get the buttons for the notification. * * @returns {array} */ getButtons() { return [ n({ class: "flex flex-row mt-6 gap-2" }, [ this.secondary && h({ variant: "outline", click: () => this.secondaryAction && this.secondaryAction() }, this.secondary), this.primary && h({ click: () => this.primaryAction && this.primaryAction() }, this.primary) ]) ]; } /** * This will get the children for the notification. * * @param {string} iconColor * @returns {array} */ getChildren(t) { return [ n({ class: "flex items-start" }, [ this.icon && g({ class: `mr-4 ${t}`, html: this.icon }), n({ class: "flex flex-auto flex-col" }, [ n({ class: "flex flex-auto flex-row items-center w-full pr-12" }, [ this.title && Ae(this.title) ]), b({ class: "text-base text-muted-foreground m-0 pr-12" }, this.description), (this.primary || this.secondary) && M({ class: "margin-top-24 flex align-center" }, this.getButtons()) ]) ]), h({ class: "absolute top-[12px] right-[12px]", variant: "icon", icon: u.x, click: this.close.bind(this) }) ]; } /** * This will close the notification. * * @param {object} e The event object. * @returns {void} */ close(t) { t && t.stopPropagation(), this.duration !== "infinite" && this.timer.stop(), this.onClick && this.onClick(), this.destroy(); } } let Pe = 0; class yt extends p { /** * This will render the component. * * @returns {object} */ render() { return n({ class: "notification-container pointer-events-none inset-auto bg-transparent backdrop:bg-transparent overflow-visible fixed bottom-[80px] right-0 z-50 p-5", popover: "manual" }, [ new ne({ cache: "list", key: "id", role: "list", rowItem: (t) => new Le(t) }) ]); } /** * This will add a notification. * * @param {object} props * @returns {void} */ addNotice(t = {}) { t.id = Pe++, t.callBack = () => this.removeNotice(t), this.list.append([t]), this.panel.hidePopover(), this.panel.showPopover(); } /** * This will remove a notification. * * @param {object} notice * @returns {void} */ removeNotice(t) { this.list.delete(t.id); } } const N = window.matchMedia, I = c(({ value: e, label: t, icon: s }) => m({ class: 'text-sm gap-1 font-medium leading-none disabled:cursor-not-allowed disabled:opacity-70 flex flex-col items-center justify-between rounded-md border-2 bg-popover p-4 hover:bg-accent hover:text-accent-foreground data-[state="active"]:border-primary [&:has([data-state="active"])]:border-primary', onState: ["method", { active: e }], dataSet: ["method", ["state", e, "active"]], click: (o, { state: r }) => { r.method = e, localStorage.setItem("theme", e), e === "system" && localStorage.removeItem("theme"), Fe(e); } }, [ x(s), a(t) ])), Fe = (e) => { var o; const t = document.documentElement; if (e === "system" && (e = (o = window.matchMedia) != null && o.call(window, "(prefers-color-scheme: dark)").matches ? "dark" : "light"), N && !N("(prefers-color-scheme: " + e + ")").matches) { t.classList.add(e); return; } const s = e === "light" ? "dark" : "light"; t.classList.remove(s); }, vt = S( { /** * This will render the component. * * @returns {object} */ render() { return n({ class: "flex flex-auto flex-col" }, [ n({ class: "grid grid-cols-3 gap-4" }, [ I({ label: "System", value: "system", icon: u.adjustments.horizontal }), I({ label: "Light", value: "light", icon: u.sun }), I({ label: "Dark", value: "dark", icon: u.moon }) ]) ]); }, /** * This will setup the states. * * @returns {object} */ state() { return { method: window.localStorage.getItem("theme") ?? "system" }; } } ), Ct = w( { /** * The initial state of the Toggle. * * @returns {object} */ state() { return { active: this.active ?? !1 }; }, /** * This is added to check the checkbox after the component is rendered. * to see if the bind updated the checked value. * * @returns {void} */ after() { this.state.active = this.checkbox.checked; }, /** * Renders the Toggle component. * * @returns {object} */ render() { return m({ class: "relative inline-flex h-6 w-11 min-w-11 items-center rounded-full bg-muted transition-colors focus:outline-none", onState: ["active", { "bg-primary": !0, "bg-muted": !1 }], click: (t, { state: s }) => { s.toggle("active"), this.checkbox.checked = s.active; } }, [ J({ cache: "checkbox", class: "opacity-0 absolute top-0 left-0 bottom-0 right-0 w-full h-full", /** * This will add the default checked before binding. * If binding it will override the default checked value. */ checked: this.state.active, bind: this.bind, required: this.required }), a({ class: "absolute h-5 w-5 bg-background rounded-full shadow-md transform transition-transform", onState: ["active", { "translate-x-[22px]": !0, "translate-x-[2px]": !1 }] }) ]); } } ), y = { ONLINE: "online", OFFLINE: "offline", BUSY: "busy", AWAY: "away" }, f = { ONLINE: "bg-green-500", OFFLINE: "bg-gray-500", BUSY: "bg-red-500", AWAY: "bg-yellow-500" }, Ne = (e = "") => (e = e.toUpperCase(), f[e] || f.OFFLINE), kt = (e) => n({ class: `absolute bottom-0 right-0 w-3 h-3 border-2 rounded-full ${Ne(e)}` }), St = ({ propName: e = "status" } = {}) => n({ class: "absolute bottom-0 right-0 w-3 h-3 border-2 rounded-full", onSet: [e, { [f.ONLINE]: y.ONLINE, [f.OFFLINE]: y.OFFLINE, [f.BUSY]: y.BUSY, [f.AWAY]: y.AWAY }] }), ze = (e, t) => Y( { href: e, "aria-current": t === "Breadcrumb" && "page", // Only set aria-current on the last item class: "text-muted-foreground font-medium hover:text-foreground" }, [a(t)] ), Ee = () => x({ class: "mx-3 text-muted-foreground", "aria-hidden": !0, size: "xs" }, u.chevron.single.right), je = (e) => n({ class: "flex items-center" }, [ e.href ? ze(e.href, e.label) : a(e.label), e.separator && Ee() ]), Dt = S( { /** * Set initial data * * @returns {Data} */ setData() { return new k({ // @ts-ignore items: this.items || [] }); }, /** * Render Breadcrumb Component * * @returns {object} */ render() { const e = this.data.items.length - 1; return K( { "aria-label": "Breadcrumb", class: "flex items-center space-x-1 text-sm" }, [ n({ role: "list", class: "flex items-center", for: ["items", (t, s) => je({ href: t.href, label: t.label, separator: s < e })] }) ] ); } } ), z = { xs: "h-1 w-1", sm: "h-2 w-2", md: "h-4 w-4", lg: "h-8 w-8", xl: "h-12 w-12", "2xl": "h-16 w-16", "3xl": "h-24 w-24", default: "h-4 w-4" }, Oe = (e) => z[e] || z.default, Ve = ({ index: e, size: t }) => n({ class: `${t} rounded-full bg-muted cursor-pointer` }, [ a({ class: "block w-full h-full rounded-full transition-colors", onSet: ["activeIndex", { "bg-primary": e, "shadow-md": e }], click: (s, { data: o, onClick: r }) => { o.activeIndex = e, r && r(e); } }) ]), Ye = (e, t) => Array.from({ length: e }, (s, o) => Ve({ index: o, size: t })), It = S( { /** * Defines component data (props). * * @returns {Data} */ setData() { return new k({ // @ts-ignore count: this.count || 4, // total dots // @ts-ignore activeIndex: this.activeIndex || 0 }); }, /** * Renders the dots. * * @returns {object} */ render() { const e = this.gap || "gap-2", t = Oe(this.size || "sm"), s = Ye(this.data.count, t); return n( { class: "flex justify-center items-center py-2" }, [ n({ class: `flex ${e}` }, s) ] ); } } ), Ue = ({ toggleDropdown: e }) => m( { cache: "button", class: "relative z-[2] inline-flex items-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 border border-input bg-background hover:bg-muted h-10 px-4 py-2 justify-between", click: e }, [ a({ onState: ["selectedLabel", (t) => t || "Select item..."] }), g({ html: u.chevron.upDown }) ] ), qe = (e, t, s) => O({ class: "flex flex-auto items-center cursor-pointer p-2 hover:bg-muted/50 rounded-sm", click: () => t(e), onState: [s, "selectedValue", { "bg-secondary": e.value }] }, [ e.icon && a({ class: "mr-2 flex items-baseline" }, [x({ size: "xs" }, e.icon)]), a({ class: "text-base font-normal" }, e.label) ]), He = (e, t) => n({ class: "w-full border rounded-md" }, [ V({ class: "max-h-60 overflow-y-auto p-2 grid gap-1", for: ["items", (s) => qe(s, e, t)] }) ]), _e = ({ onSelect: e, state: t }) => n({ class: "flex flex-auto flex-col" }, [ v( "open", (s, o, r) => s ? new D({ cache: "dropdown", parent: r, button: r.button }, [ He(e, t) ]) : null ) ]), Tt = S( { /** * This will set up the data. * * @returns {Data} */ setData() { return new k({ // @ts-ignore items: this.items || [] }); }, /** * This will set up the states. * * @returns {object} */ state() { return { open: !1, selectedLabel: "", selectedValue: "" }; }, /** * This will set the state item. * * @param {object} item * @returns {void} */ setStateItem(e) { const t = this.state; t.selectedValue = e.value, t.selectedLabel = e.label, t.open = !1; }, /** * Handles the selection of an item. * * @param {object} item * @returns {void} */ select(e) { this.setStateItem(e), typeof this.onSelect == "function" && this.onSelect(e, this.parent); }, /** * Selects the first item in the list. * * @returns {void} */ selectFirstItem() { const e = this.data.items[0]; this.select(e); }, /** * Toggles the dropdown open state. * * @returns {void} */ toggleDropdown() { this.state.toggle("open"); }, /** * This will run after the component is set up. * * @returns {void} */ after() { if (this.selectFirst === !0 && this.state.selectedValue === "") { const e = this.data.items[0]; e && this.setStateItem(e); } }, /** * This will render the component. * * @returns {object} */ render() { const e = this.class || "", t = this.maxWidth || "max-w-[250px]", s = this.width || "w-full"; return n({ class: `relative ${s} flex flex-auto flex-col ${t} ${e}` }, [ // @ts-ignore Ue({ toggleDropdown: this.toggleDropdown.bind(this) }), _e({ // @ts-ignore state: this.state, // @ts-ignore onSelect: this.select.bind(this) }), // Hidden required input for form validation // @ts-ignore this.required && C({ class: "opacity-0 absolute top-0 left-0 z-[1]", type: "text", // @ts-ignore name: this.name, required: !0, // @ts-ignore value: ["[[selectedValue]]", this.state] }) ]); } } ), H = ({ icon: e, click: t, ariaLabel: s }) => h({ variant: "icon", class: "flex flex-none", click: t, icon: e, "aria-label": s }), We = ({ click: e }) => H({ icon: u.circleMinus, click: e, ariaLabel: "Decrement" }), Re = ({ click: e }) => H({ icon: u.circlePlus, click: e, ariaLabel: "Increment" }), Ge = ({ bind: e, min: t, max: s, readonly: o = !1 }) => Q(({ state: r }) => C({ value: ["[[count]]", r], bind: e, blur: (l, { state: i }) => { let d = parseInt(l.target.value, 10); isNaN(d) && (d = t ?? 0), t !== void 0 && (d = Math.max(d, t)), s !== void 0 && (d = Math.min(d, s)), i.count = d; }, class: "flex flex-auto text-lg font-medium bg-transparent text-center border min-w-0", readonly: o, min: t, max: s, type: "number", "aria-label": "Counter" })), $t = w( { /** * Initial state for the counter component. * * @member {object} state */ state() { return { count: { state: this.initialCount ?? 0, callBack: (e) => this.change && this.change(e) } }; }, /** * Renders the Counter component. * * @returns {object} */ render() { const e = this.class ?? ""; return n({ class: `flex flex-auto items-center justify-between space-x-4 p-4 ${e}` }, [ We({ click: () => this.state.decrement("count") }), Ge({ bind: this.bind, readonly: this.readonly, min: this.min, max: this.max }), Re({ click: () => this.state.increment("count") }) ]); } } ), Je = ({ bind: e, required: t }) => C({ cache: "input", class: "opacity-0 absolute top-0 left-0 w-full h-full pointer-events-none", bind: e, required: t }), Ke = ({ bind: e, required: t, toggleOpen: s }) => m({ class: "relative flex items-center gap-2 w-full justify-between border border-input bg-background hover:bg-muted rounded-md h-10 px-4 py-2", click: s }, [ Je({ bind: e, required: t }), a({ onState: ["selectedDate", (o) => o ? $.format("standard", o) : "Pick a date"] }), g({ html: u.calendar.days }) ]), Qe = ({ handleDateSelect: e, blockPriorDates: t }) => n({ class: "absolute mt-1 z-10 bg-background rounded-md shadow-lg" }, [ v( "open", (s, o, r) => s ? new D({ cache: "dropdown", parent: r, button: r.panel, size: "fit" }, [ new se({ selectedDate: r.state.selectedDate, selectedCallBack: e, blockPriorDates: t }) ]) : null ) ]), At = w( { /** * The initial state of the DatePicker. * * @member {object} state */ state() { return { selectedDate: this.selectedDate ?? null, open: !1 }; }, /** * This is added to check the input after the component is rendered. * to see if the bind updated the input value. * * @returns {void} */ after() { this.state.selectedDate = this.input.value; }, /** * Renders the DatePicker component. * * @returns {object} */ render() { const e = (s, { state: o }) => o.toggle("open"), t = (s) => { this.state.selectedDate = s, this.state.open = !1, this.input.value = s, typeof this.onChange == "function" && this.onChange(s); }; return n({ class: "relative w-full max-w-[320px]" }, [ Ke({ toggleOpen: e, bind: this.bind, required: this.required }), Qe({ handleDateSelect: t, blockPriorDates: this.blockPriorDates || !1 }) ]); } } ), Bt = ({ dateTime: e = "", remoteTimeZone: t = "America/Denver", filter: s = null }) => X([ new re({ dateTime: e, filter: s || ((o) => { const r = $.getLocalTime(o, !0, !1, t); return $.getTimeFrame(r); }) }) ]); function Xe({ bind: e, required: t }) { return C({ cache: "input", class: "opacity-0 absolute top-0 left-0 w-full h-full pointer-events-none", bind: e, required: t }); } function Ze({ bind: e, required: t, toggleOpen: s }) { return m( { class: "relative flex items-center gap-2 w-full justify-between border border-input bg-background hover:bg-muted rounded-md h-10 px-4 py-2", click: s }, [ Xe({ bind: e, required: t }), a({ onState: ["selectedTime", (o) => o || "Pick a time"] }), g({ html: u.clock }) ] ); } function T({ items: e, handleTimeSelect: t, state: s, stateValue: o, pad: r = !1 }) { return n( { class: "flex flex-col max-h-[200px] overflow-y-auto" }, e.map((l) => { let i = r ? l.toString().padStart(2, "0") : l.toString(); return m({ text: i, class: "hover:bg-muted/50 rounded-md px-2 py-1", click: () => t({ [o]: i }), onState: [s, o, { "bg-muted": i }] }); }) ); } function et({ handleTimeSelect: e }) { return n( { class: "absolute mt-1 z-10 bg-background rounded-md shadow-lg" }, [ v( "open", (t, s, o) => t ? new D( { cache: "dropdown", parent: o, button: o.panel, size: "fit" }, [ n( { class: "flex flex-auto flex-col border rounded-md shadow-md" }, [ n( { class: "grid grid-cols-3 gap-2 p-4 text-center max-h-[220px] min-w-[240px]" }, [ // Hours column T({ items: Array.from({ length: 12 }, (r, l) => l + 1), handleTimeSelect: e, state: o.state, stateValue: "hour", pad: !0 }), // Minutes column T({ items: Array.from({ length: 60 }, (r, l) => l), handleTimeSelect: e, state: o.state, stateValue: "minute", pad: !0 }), // AM/PM column T({ items: ["AM", "PM"], handleTimeSelect: e, state: o.state, stateValue: "meridian" }) ] ) ] ) ] ) : null ) ] ); } function E(e) { if (!e) return { hour: null, minute: null, meridian: null }; const t = /^(\d{1,2}):(\d{2})(?::(\d{2}))?\s?(AM|PM)?$/i, s = e.match(t); if (!s) return { hour: null, minute: null, meridian: null }; let [, o, r, , l] = s, i = parseInt(o, 10), d = parseInt(r, 10); return i < 0 || i > 23 || d < 0 || d > 59 ? { hour: null, minute: null, meridian: null } : (l ? (l = l.toUpperCase(), l === "PM" && i < 12 ? i += 12 : l === "AM" && i === 12 && (i = 12)) : i === 0 ? (l = "AM", i = 12) : i < 12 ? l = "AM" : i === 12 ? l = "PM" : (l = "PM", i -= 12), { hour: i.toString().padStart(2, "0"), minute: d.toString().padStart(2, "0"), meridian: l }); } const Mt = w( { /** * The initial shallow state of the TimePicker. * * @member {object} state */ state() { const e = this.selectedTime ?? null, { hour: t, minute: s, meridian: o } = E(e); return { selectedTime: e, open: !1, hour: t, minute: s, meridian: o }; }, /** * Updates the state after the input is rendered. * * @returns {void} */ after() { if (this.input.value) { const { hour: e, minute: t, meridian: s } = E(this.input.value); this.state.set({ hour: e, minute: t, meridian: s, selectedTime: this.input.value }); } }, /** * Renders the TimePicker component. * * @returns {object} */ render() { const e = (s, { state: o }) => o.toggle("open"), t = ({ hour: s, minute: o, meridian: r }) => { if (s && (this.state.hour = s), o && (this.state.minute = o), r && (this.state.meridian = r), this.state.hour && this.state.minute && this.state.meridian) { const l = `${this.state.hour}:${this.state.minute} ${this.state.meridian}`; this.state.selectedTime = l, this.state.open = !1, this.input.value = l, typeof this.change == "function" && this.change(l); } }; return n( { class: "relative w-full max-w-[320px]" }, [ Ze({ toggleOpen: e, bind: this.bind, required: this.required }), et({ handleTimeSelect: t }) ] ); } } ), tt = (e, t) => n({ class: `hidden md:flex items-start justify-center w-6 h-6 mr-3 ${t}` }, [ x({ size: "lg" }, e) ]), st = ({ title: e }) => B({ class: "flex flex-auto items-center" }, [ A({ class: "text-lg font-semibold" }, e) ]), ot = c((e, t) => Z( { class: `fixed pullUpIn z-30 w-[98%] border md:w-full max-w-lg bg-popover text-foreground shadow-lg duration-200 rounded-lg flex flex-auto flex-col bottom-4 top-auto inset-auto m-auto md:bottom-0 md:top-0 left-0 right-0 ${e.class}`, click: e.click, aria: { expanded: ["open"] } }, [ n({ class: "flex flex-auto p-6 pb-12 md:pb-6" }, [ // Icon and content e.icon && tt(e.icon, e.iconColor), n({ class: "flex flex-auto flex-col gap-4" }, [ n({ class: "flex flex-auto flex-col space-y-2" }, [ st(e), e.description && b({ class: "flex flex-auto flex-col text-sm text-muted-foreground" }, e.description), n({ class: "flex flex-auto flex-col text-sm text-muted-foreground" }, t) ]), e.buttons && M({ class: "flex flex-col-reverse sm:flex-row sm:justify-end mt-6 gap-2 sm:gap-0 sm:space-x-2" }, e.buttons) ]) ]) ] )), nt = (e) => U.render(e, app.root), j = { info: { borderColor: "border-blue-500", bgColor: "bg-muted/10", iconColor: "text-blue-500" }, warning: { bgColor: "bg-muted/10", borderColor: "border-warning", iconColor: "text-warning" }, destructive: { bgColor: "bg-muted/10", borderColor: "border-destructive", iconColor: "text-red-500" }, success: { bgColor: "bg-muted/10", borderColor: "border-emerald-500", iconColor: "text-emerald-500" }, default: { borderColor: "border", bgColor: "bg-muted/10", iconColor: "text-muted-foreground" } }; class rt extends p { /** * This will declare the props for the compiler. * * @returns {void} */ declareProps() { this.title = null, this.description = null, this.type = "", this.icon = null, this.onClose = null, this.hideFooter = !1, this.buttons = null; } /** * This will render the modal component. * * @returns {object} */ render() { const t = (d) => { d.target === this.panel && this.close(); }, { borderColor: s, bgColor: o, iconColor: r } = j[this.type] || j.default, l = `${this.getMainClass()} ${o} ${s}`, i = this.title || "Dialog Title"; return ot({ class: l, title: i, click: t, icon: this.icon, iconColor: r, description: this.description, buttons: this.getButtons() }, this.children); } /** * This will get the buttons for the modal. * * @returns {array} */ getButtons() { return this.hideFooter ? null : this.buttons ? this.buttons : [ h({ variant: "outline", click: () => this.close() }, "Close") ]; } /** * This will setup the states. * * @returns {object} */ setupStates() { return { open: !1 }; } /** * This will get the modal class. * * @returns {string} */ getMainClass() { return ""; } /** * This will open the modal. * * @returns {void} */ open() { nt(this), this.panel.showModal(), this.state.open = !0; } /** * This will close the modal. * * @returns {void} */ close() { this.state.open = !1, this.panel.close(), typeof this.onClose == "function" && this.onClose(), this.destroy(); } } class Lt extends rt { /** * This will declare the props for the compiler. * * @returns {void} */ declareProps() { this.confirmTextLabel = null, this.confirmed = null; } /** * This will get the buttons for the modal. * * @returns {array} */ getButtons() { const t = this.confirmTextLabel || "Confirm"; return [ h({ variant: "outline", click: () => this.close() }, "Cancel"), h({ variant: "primary", click: () => this.confirm() }, t) ]; } /** * This will confirm the action. * * @returns {void} */ confirm() { this.confirmed && this.confirmed(), this.close(); } } export { mt as A, Dt as B, Tt as C, ce as D, ot as E, xe as F, rt as G, wt as M, yt as N, Re as P, xt as S, vt as T, me as a, ft as b, ge as c, we as d, ye as e, ve as f, ke as g, gt as h, De as i, bt as j, pt as k, Le as l, Ct as m, kt as n, St as o, y as p, f as q, Ne as r, It as s, We as t, Ge as u, $t as v, At as w, Bt as x, Mt as y, Lt as z };