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,855 lines 58.5 kB
import { Button as x, Div as o, On as C, Span as L, Th as N, UseParent as E, I as Q, Thead as V, Tr as G, Table as B, P as v, Li as y, Time as X, Nav as g, Ul as f, Section as I, Canvas as q } from "@base-framework/atoms"; import { Atom as d, Component as p, Data as T, DateTime as K, router as w, NavLink as M, DataTracker as U, Jot as _, base as O, Dom as W } from "@base-framework/base"; import { B as P, I as J } from "./buttons-CHEs54Wl.js"; import { Icons as S } from "./icons.es.js"; import { TableBody as Z, DataTableBody as ee, ScrollableTableBody as te, List as se, IntervalTimer as ae } from "@base-framework/organisms"; import { C as ie, I as ne, H as oe } from "./inputs-9udyzkHR.js"; import { A as le, P as re } from "./range-calendar-BMWSJTE0.js"; import { V as m } from "./veil-CqnAmj-D.js"; d((t, e) => ({ class: "flex items-center px-4 py-2", ...t, children: e })); d(({ value: t, label: e }) => x({ class: "inline-flex flex-auto items-center justify-center whitespace-nowrap rounded-md px-8 py-1 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow", onState: ["performance", { active: t }], dataSet: ["performance", ["state", t, "active"]], click: (s, { state: a }) => a.performance = t }, e)); class gt extends p { /** * This will declare the props for the compiler. * * @returns {void} */ declareProps() { this.class = ""; } /** * This will render the component. * * @returns {object} */ render() { return o({ class: this.class || "" }, this.children); } } const ce = (t) => { const e = new Date(t, 11, 31), s = new Date(t, 0, 1); return e.getDay() === 4 || // December 31 is a Thursday s.getDay() === 4; }, de = (t) => { const e = new Date(t.valueOf()), s = (e.getDay() + 6) % 7; e.setDate(e.getDate() - s + 3); const a = e.getFullYear(), i = new Date(a, 0, 4); i.setDate(i.getDate() - (i.getDay() + 6) % 7); const n = Math.ceil((e - i) / 6048e5) + 1; return n > 52 && !ce(a) ? { weekNumber: 1, year: a + 1 } : { weekNumber: n, year: a }; }, he = (t, e, s) => { if (s === 0) return []; const a = new Date(t, e, 0).getDate(); return Array.from( { length: s }, (i, n) => new Date(t, e - 1, a - s + n + 1) ); }, ue = (t, e, s) => Array.from({ length: s }, (a, i) => new Date(t, e + 1, i + 1)), $ = (t, e) => { const s = new Date(e, 0, 4), a = (s.getDay() + 6) % 7, i = new Date(s); i.setDate(s.getDate() - a); const n = new Date(i); return n.setDate(i.getDate() + (t - 1) * 7), n; }, pt = (t, e) => { const s = new Date(t, e, 1).getDay(), a = new Date(t, e + 1, 0).getDate(), i = []; let n = []; for (let l = 1 - s; l <= a; l++) { const c = new Date(t, e, l); n.push(l > 0 ? c : null), (n.length === 7 || l === a) && (i.push([...n]), n = []); } return i; }, bt = (t, e) => { const s = new Date(t, e + 1, 0).getDate(), a = []; let i = []; for (let n = 1; n <= s; n++) i.push(new Date(t, e, n)), i.length === 7 && (a.push(i), i = []); return i.length > 0 && a.push(i), a; }, fe = (t, e, s) => { const a = /* @__PURE__ */ new Date(); return a.getDate() === t && a.getMonth() === e && a.getFullYear() === s; }, me = ({ day: t, month: e, year: s, weekNumber: a, selectWeek: i }) => { const n = fe(t, e, s); return x({ text: t || "", disabled: !t, class: ` px-2 py-1 text-center rounded-md ${n ? "bg-accent text-accent-foreground" : ""} hover:bg-primary hover:text-primary-foreground `, click: () => i(a, s) }); }, ge = (t, e) => { const s = new Date(t, e, 1).getDay(), a = new Date(t, e + 1, 0).getDate(), i = he(t, e, s), n = Array.from({ length: a }, (h, k) => new Date(t, e, k + 1)), l = (i.length + n.length) % 7, c = l === 0 ? 0 : 7 - l, r = ue(t, e, c), u = [...i, ...n, ...r], b = []; for (let h = 0; h < u.length; h += 7) { const k = u.slice(h, h + 7), D = k.find((F) => F) || new Date(t, e, 1), { weekNumber: H, year: Y } = de(D); b.push({ weekNumber: H, year: Y, days: k }); } return b; }, pe = ({ selectWeek: t }) => C("month", (e, s, { data: a }) => { const { year: i, month: n, currentDate: l } = a, c = ge(i, n); return o( { class: "grid grid-cols-8 gap-1 text-sm px-4 py-2" }, [ // Header row: "Week" label + day-of-week labels o({ class: "text-xs text-center col-span-1 text-muted-foreground flex items-center" }, "Week"), o( { class: "grid grid-cols-7 col-span-7 text-center text-muted-foreground items-center" }, ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"].map( (r) => L({ class: "px-1 py-1", text: r }) ) ), // Render each "week" row ...c.map( ({ weekNumber: r, days: u, year: b }) => o({ class: "grid grid-cols-8 col-span-8 items-center ring-primary rounded-sm px-1", onSet: ["currentWeek", { ring: r }] }, [ // Left column: ISO week number o({ class: "font-medium text-center col-span-1 rounded-sm cursor-pointer", click: () => t(r, b), // If you have a 'currentWeek' state, you can highlight it with 'onSet' onSet: ["currentWeek", { "text-primary-foreground": r, "bg-primary": r }], text: r ? `W${r}` : "" }), // The 7 cells for each day in the row o( { class: "grid grid-cols-7 col-span-7 text-center" }, u.map( (h) => me({ year: h?.getFullYear() || null, month: h?.getMonth() || null, day: h?.getDate() || null, weekNumber: r, selectWeek: t }) ) ) ]) ) ] ); }), z = ({ label: t, click: e }) => P( { class: ` inline-flex items-center justify-center h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100 text-muted-foreground absolute ${t === "Previous" ? "left-1" : "right-1"} focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 `, click: e, "aria-label": `${t} month`, variant: "icon", icon: t === "Previous" ? S.chevron.single.left : S.chevron.single.right } ), be = ({ next: t, previous: e }) => o({ class: "flex flex-auto min-h-12 text-sm font-medium relative justify-center items-center" }, [ L("[[monthName]] [[year]]"), z({ label: "Previous", click: e }), z({ label: "Next", click: t }) ]); class kt extends p { /** * This will declare the props for the compiler. * * @returns {void} */ declareProps() { this.selectedDate = null, this.selectedWeek = null, this.selectedCallBack = null; } /** * Initializes the calendar data. * * @returns {Data} */ setData() { const e = /* @__PURE__ */ new Date(), s = this.selectedWeek || this.calculateCurrentWeek(e), a = $(s, e.getFullYear()); return new T({ monthName: this.getMonthName(a.getMonth()), year: a.getFullYear(), month: a.getMonth(), currentDate: a.getDate(), currentWeek: s }); } /** * Determines the current selected date. * * @param {Date} today * @returns {Date} */ getSelectedDate(e) { const s = this.selectedDate ? new Date(this.selectedDate) : e; return new Date(s.getFullYear(), s.getMonth(), s.getDate()); } /** * Calculates the ISO week number for a given date. * * @param {Date} date * @returns {number} */ calculateCurrentWeek(e) { const s = new Date(e.valueOf()), a = (e.getDay() + 6) % 7; s.setDate(s.getDate() - a + 3); const i = s.valueOf(); return s.setMonth(0, 1), s.getDay() !== 4 && s.setMonth(0, 1 + (4 - s.getDay() + 7) % 7), 1 + Math.ceil((i - s) / 6048e5); } /** * Gets the name of the month. * * @param {number} month * @returns {string} */ getMonthName(e) { return K.monthNames[e]; } /** * Updates the calendar to show the previous month. * * @returns {void} */ goToPreviousMonth() { const e = this.data; let { year: s, month: a } = e; a === 0 ? (a = 11, s--) : a--, this.setDate(a, s); } /** * Updates the calendar to show the next month. * * @returns {void} */ goToNextMonth() { const e = this.data; let { year: s, month: a } = e; a === 11 ? (a = 0, s++) : a++, this.setDate(a, s); } /** * Sets the selected date. * * @param {number} month * @param {number} year * @param {number|null} [date=null] * @returns {void} */ setDate(e, s, a) { this.data.set({ year: s, month: e, monthName: this.getMonthName(e) }), a && (this.data.currentDate = a); } /** * Handles week selection. * * @param {number} weekNumber * @returns {void} */ selectWeek(e, s) { this.data.currentWeek = e; const a = $(e, s); this.setDate(a.getMonth(), a.getFullYear(), a.getDate()), typeof this.selectedCallBack == "function" && this.selectedCallBack(e); } /** * Renders the WeekCalendar component. * * @returns {object} */ render() { return o({ class: "week-calendar-container border rounded-md p-3" }, [ be({ next: () => this.goToNextMonth(), previous: () => this.goToPreviousMonth() }), pe({ selectWeek: (e, s) => this.selectWeek(e, s) }) ]); } } const ke = (t, e) => { const s = t.toggleAllSelectedRows(); e.state.checked = !s; }, we = (t) => N({ class: `cursor-pointer py-3 px-4 text-base w-10 ${t.class || ""}` }, [ E((e) => new ie({ class: "mr-2", onChange: (s, a) => ke(e, a) })) ]), xe = ({ align: t, sortable: e, key: s, label: a, sort: i, class: n }) => { const l = t || "justify-start"; return N({ class: `cursor-pointer py-3 px-4 text-base ${n || ""}`, click: e && (() => i(s)) }, [ o({ class: `flex flex-auto w-full items-center ${l}` }, [ L(a), e && Q({ class: "ml-2", html: S.arrows.upDown }) ]) ]); }, R = (t) => V([ G({ class: "text-muted-foreground border-b", map: [ t.headers, (e) => e.label === "checkbox" ? we({ toggle: t.toggle }) : xe({ align: e.align, sortable: e.sortable, key: e.key, label: e.label, sort: t.sort }) ] }) ]), ye = ({ key: t, rows: e, selectRow: s, rowItem: a, emptyState: i, skeleton: n, columnCount: l }) => new Z({ cache: "list", key: t, items: e, rowItem: (c) => a(c, s), class: "divide-y divide-border", emptyState: i, skeleton: n, columnCount: l }); class j extends p { /** * Initializes component data. * * @returns {Data} */ setData() { let e = this.rows && this.rows.length > 0; return (this.loadMoreItems || this.tableData) && !e && (e = null), new T({ selectedRows: [], // @ts-ignore hasItems: e, selected: !1 }); } /** * This will toggle all selected rows. * * @returns {boolean} */ toggleAllSelectedRows() { const e = this.list.getRows(), s = this.data.selectedRows.length === e.length, a = s ? [] : e; return this.data.selectedRows = a, this.updateSelected(), this.updateTable(!s), s; } /** * This will update the selected state. * * @returns {void} */ updateSelected() { const e = this.data.get("selectedRows"); this.data.selected = e.length > 0; } /** * This will get the selected rows. * * @returns {Array<object>} */ getSelectedRows() { return this.data.get("selectedRows"); } /** * This will update the table rows. * * @protected * @param {boolean} selected * @returns {void} */ updateTable(e) { const s = this.list.getRows(); s.forEach((a) => a.selected = e), this.list.setRows(s); } /** * Handles row selection. * * @param {object} row */ selectRow(e) { const s = e.selected ?? !1; e.selected = !s; const a = this.data.get("selectedRows"), i = e.selected ? [...a, e] : a.filter((n) => n !== e); this.data.selectedRows = i, this.updateSelected(); } /** * Gets the number of header columns. * * @returns {number} */ getHeaderColCount() { return this.customHeader ? this.customHeader?.children[0]?.children?.length : this.headers ? this.headers.length : 3; } /** * Renders the DataTable component. * * @returns {object} */ render() { const e = this.border !== !1 ? "border" : "", s = this.getHeaderColCount(); return o({ class: "w-full flex flex-auto flex-col" }, [ C("hasItems", (a) => a === !1 && this.emptyState ? this.emptyState() : null), o({ class: `w-full rounded-md ${e} overflow-x-auto`, onSet: ["hasItems", { hidden: !1 }] }, [ B({ class: "w-full" }, [ // @ts-ignore this.headers && R({ headers: this.headers, sort: (a) => this.sortRows(a) }), // @ts-ignore this.customHeader ?? null, ye({ // @ts-ignore key: this.key, // @ts-ignore rows: this.rows, // @ts-ignore selectRow: this.selectRow.bind(this), // @ts-ignore rowItem: this.rowItem, // @ts-ignore emptyState: this.emptyState, // @ts-ignore skeleton: this.skeleton, columnCount: s }) ]) ]) ]); } /** * This will remove items from the list. * * @public * @param {array} items * @returns {void} */ remove(e) { this.list.remove(e); } /** * This will set the items in the list. * * @public * @param {array} rows * @returns {void} */ setRows(e) { this.list.setRows(e); } /** * This will append items to the list. * * @public * @param {array|object} items * @returns {void} */ append(e) { this.list.append(e); } /** * This will mingle the new items with the old items. * * @public * @param {Array<Object>} newItems * @param {boolean} withDelete * @returns {void} */ mingle(e, s = !1) { this.list.mingle(e, s); } /** * This will prepend items to the list. * * @public * @param {array|object} items * @returns {void} */ prepend(e) { this.list.prepend(e); } /** * This will remove the selected rows. * * @returns {void} */ beforeDestroy() { this.data.selectedRows = []; } } const ve = (t) => new ee({ cache: "list", loadMoreItems: t.loadMoreItems, offset: t.offset, limit: t.limit, key: t.key, tableData: t.tableData, items: t.items, rowItem: (e) => t.rowItem(e, t.selectRow), class: "divide-y divide-border", skeleton: t.skeleton, columnCount: t.columnCount }); class De extends j { /** * Renders the DataTable component. * * @returns {object} */ render() { const e = this.border !== !1 ? "border" : "", s = this.getHeaderColCount(); return o({ class: "w-full flex flex-auto flex-col" }, [ C("hasItems", (a) => a === !1 && this.emptyState ? this.emptyState() : null), o({ class: `w-full rounded-md ${e} overflow-x-auto`, onSet: ["hasItems", { hidden: !1 }] }, [ B({ class: "w-full" }, [ // @ts-ignore this.headers && R({ headers: this.headers, sort: (a) => this.sortRows(a) }), // @ts-ignore this.customHeader ?? null, ve({ // @ts-ignore loadMoreItems: this.loadMoreItems, // @ts-ignore offset: this.offset, // @ts-ignore limit: this.limit, // @ts-ignore class: this.class, // @ts-ignore tableData: this.tableData, // @ts-ignore key: this.key, // @ts-ignore items: this.rows, // @ts-ignore selectRow: this.selectRow.bind(this), // @ts-ignore rowItem: this.rowItem, // @ts-ignore skeleton: this.skeleton, columnCount: s }) ]) ]) ]); } /** * Refreshes the list. * * @returns {void} */ refresh() { this.list.refresh(); } } const wt = d((t) => new De( { cache: t.cache ?? "list", tableData: t.data, loadMoreItems: t.loadMoreItems, offset: t.offset, limit: t.limit, class: t.class, key: t.key, rows: t.rows, rowItem: t.rowItem, headers: t.headers, customHeader: t.customHeader, border: t.border, emptyState: t.emptyState, skeleton: t.skeleton } )), Se = (t) => new te({ cache: "list", scrollContainer: t.scrollContainer, loadMoreItems: t.loadMoreItems, offset: t.offset, limit: t.limit, key: t.key, tableData: t.tableData, items: t.items, rowItem: (e) => t.rowItem(e, t.selectRow), class: "divide-y divide-border", skeleton: t.skeleton, columnCount: t.columnCount }); class Ce extends j { /** * Renders the DataTable component. * * @returns {object} */ render() { const e = this.border !== !1 ? "border" : "", s = this.getHeaderColCount(); return o({ class: "w-full flex flex-auto flex-col" }, [ C("hasItems", (a) => a === !1 && this.emptyState ? this.emptyState() : null), o({ class: `w-full rounded-md ${e} overflow-x-auto`, onSet: ["hasItems", { hidden: !1 }] }, [ B({ class: "w-full" }, [ // @ts-ignore this.headers && R({ headers: this.headers, sort: (a) => this.sortRows(a) }), // @ts-ignore this.customHeader ?? null, Se({ // @ts-ignore scrollContainer: this.scrollContainer, // @ts-ignore loadMoreItems: this.loadMoreItems, // @ts-ignore offset: this.offset, // @ts-ignore limit: this.limit, // @ts-ignore class: this.class, // @ts-ignore tableData: this.tableData, // @ts-ignore key: this.key, // @ts-ignore items: this.rows, // @ts-ignore selectRow: this.selectRow.bind(this), // @ts-ignore rowItem: this.rowItem, // @ts-ignore skeleton: this.skeleton, columnCount: s }) ]) ]) ]); } /** * Refreshes the list. * * @returns {void} */ refresh() { this.list.refresh(); } } const xt = d((t) => new Ce( { cache: t.cache ?? "list", tableData: t.data, scrollContainer: t.scrollContainer, loadMoreItems: t.loadMoreItems, offset: t.offset, limit: t.limit, class: t.class, key: t.key, rows: t.rows, rowItem: t.rowItem, headers: t.headers, customHeader: t.customHeader, border: t.border, emptyState: t.emptyState, skeleton: t.skeleton } )), Le = d(({ name: t, email: e }) => o({ class: "min-w-0 flex-auto" }, [ v({ class: "text-base font-semibold leading-6 m-0" }, t), v({ class: "truncate text-sm leading-5 text-muted-foreground m-0" }, e) ])), Ie = () => o({ class: "flex items-center gap-x-1.5" }, [ o({ class: "flex-none rounded-full bg-emerald-500/20 p-1" }, [ o({ class: "h-1.5 w-1.5 rounded-full bg-emerald-500" }) ]), v({ class: "text-xs leading-5 text-gray-500" }, "Online") ]), Be = (t) => v({ class: "text-xs leading-5 text-muted-foreground" }, [ L("Last seen "), X({ datetime: t }, "3h ago") ]), Te = (t, e) => t === "online" ? Ie() : Be(e), Me = d(({ role: t, lastSeen: e, status: s }) => o({ class: "hidden shrink-0 sm:flex sm:flex-col sm:items-end" }, [ v({ class: "text-sm leading-6 m-0" }, t), Te(s, e) ])), Pe = (t) => t.split(" ").map((s) => s[0]).join(""), Re = d((t) => y({ class: "fadeIn flex justify-between gap-x-6 py-4 px-4 rounded-md hover:bg-muted/50" }, [ o({ class: "flex min-w-0 gap-x-4" }, [ le({ src: t.image, alt: t.name, fallbackText: Pe(t.name) }), Le({ name: t.name, email: t.email }) ]), Me({ role: t.role, lastSeen: t.lastSeen, status: t.status }) ])), yt = d((t) => new se({ cache: "list", key: "name", items: t.users, role: "list", class: "divide-y divide-border", rowItem: Re })), Oe = (t, e) => e.includes(t), We = (t, e, s) => t.exact ? s === e : Oe(e, s), $e = ({ text: t, href: e, exact: s, hidden: a }) => new M({ text: t, href: e, exact: s, dataSet: ["selected", ["state", !0, "active"]], class: `${a ? "hidden" : "inline-flex"} items-center justify-center whitespace-nowrap px-3 py-1.5 text-sm font-medium transition-all rounded-md focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-ring focus-visible:ring-offset-background hover:bg-primary hover:text-primary-foreground disabled:opacity-50 disabled:pointer-events-none data-[state=active]:bg-primary data-[state=active]:text-primary-foreground data-[state=active]:shadow-sm` }); class vt extends p { /** * This will declare the props for the compiler. * * @returns {void} */ declareProps() { this.options = [], this.class = ""; } /** * This will configure the links. */ beforeSetup() { this.links = []; } /** * This will render the component. * * @returns {object} */ render() { return g( { class: `flex items-center justify-center p-2 text-muted-foreground rounded-md ${this.class || ""}` }, [ f({ class: "flex gap-x-4", map: [this.options, (e) => this.addLink(e)], watch: { value: ["[[path]]", w.data], callBack: this.updateLinks.bind(this) } }) ] ); } /** * This will update the links. * * @returns {void} */ afterSetup() { const e = w.data.path; this.updateLinks(e); } /** * This will update the links based on the current path. * * @param {string} path * @returns {void} */ updateLinks(e) { let s = !1; this.deactivateAllLinks(); for (const a of this.links) { if (!a.rendered) continue; We(a, a.getLinkPath(), e) ? (this.updateLink(a, !0), s = !0) : this.updateLink(a, !1); } !s && this.links[0] && this.updateLink(this.links[0], !0); } /** * This will deactivate all links. * * @returns {void} */ deactivateAllLinks() { for (const e of this.links) this.updateLink(e, !1); } /** * This will update the link's active state. * * @param {object} link * @param {boolean} selected * @returns {void} */ updateLink(e, s) { e.update(s); } /** * This will add a link to the navigation. * * @param {object} option * @returns {object} */ addLink({ label: e, href: s, exact: a, hidden: i }) { const n = $e({ text: e, href: s, exact: a, hidden: i }); return this.links.push(n), n; } /** * This will clear the links. * * @returns {void} */ beforeDestroy() { this.links = []; } } const Dt = d((t) => { const e = t.margin || "m-4 ml-0"; return t.allowHistory = t.allowHistory === !0, o({ class: `flex-none ${e}` }, [ P({ variant: "back", class: "ghost", ...t }) ]); }); class A extends p { /** * This will declare the props for the compiler. * * @returns {void} */ declareProps() { this.class = ""; } /** * This will render the component. * * @returns {object} */ render() { return o( { class: this.getClassName(), onSet: ["loading", { loading: !0 }] }, [ this.addBody() ] ); } /** * This will get the overlay className. * * @returns {string} */ getClassName() { return `absolute overlay left-0 top-0 right-0 z-20 h-svh max-h-svh min-h-svh bg-background pointer-events-auto lg:left-16 pb-[calc(env(safe-area-inset-bottom)+56px)] will-change-contents ${this.class || ""}`; } /** * This will setup and render the component. * * @param {object} container * @returns {void} */ setContainer(e) { this.container = app.root; } /** * This will setup the overlay states. * * @returns {object} */ setupStates() { return { loading: !1 }; } /** * This will set the loading state.= to true. * * @returns {void} */ addLoading() { this.state.loading = !0; } /** * This will set the loading state to false. * * @returns {void} */ removeLoading() { this.state.loading = !1; } /** * This will add the body of the overlay. * * @returns {object} */ addBody() { return o({ class: "body fadeIn flex flex-auto flex-col bg-background" }, this.getContents()); } /** * This will get the body contents. * * @returns {array|null} */ getContents() { return this.children; } } U.addType("dockableOverlay", (t) => { if (!t) return; const e = t.component; e && e.rendered === !0 && e.state.docked === !1 && e.destroy(); }); class St extends A { /** * This will stop presistence. * * @returns {void} */ onCreated() { this.dockSize = this.maxSize || 1024; } /** * This will render the component. * * @returns {object} */ render() { const e = this.container; return o( { onState: [ ["loading", { loading: !0 }], ["docked", (s, a) => { s ? (a.className = this.getDockedClassName(), e.appendChild(a), document.documentElement.style.overflowY = "auto") : (a.className = this.getClassName(), app.root.appendChild(a), document.documentElement.style.overflowY = "hidden"); }] ] }, [ this.addBody() ] ); } /** * This will get the docked className. * * @returns {string} */ getDockedClassName() { return "flex flex-auto flex-col bg-background flex will-change-contents " + (this.class || ""); } /** * This will setup and render the component. * * @param {object} container * @returns {void} */ setup(e) { this.container = e, this.initialize(); } /** * This will setup the overlay states. * * @returns {object} */ setupStates() { return { loading: !1, docked: this.canDock() }; } /** * This will check the dock size. * * @returns {void} */ afterSetup() { U.add( this.container, "dockableOverlay", { component: this } ), this.onResize(); } /** * This will setup the overlay events. * * @returns {Array<object>} */ setupEvents() { return [ ["resize", globalThis, () => this.onResize()] ]; } /** * This will check if the overlay can dock. * * @returns {boolean} */ canDock() { return globalThis.innerWidth >= this.dockSize; } /** * This will handle the overlay resize. * * @returns {void} */ onResize() { this.state.docked = this.canDock(); } /** * This will resume scrolling when the overlay is being removed. * * @returns {void} */ beforeDestroy() { document.documentElement.style.overflowY = "auto"; } } class Ct extends A { /** * This will get the overlay type. * * @returns {string} */ getClassName() { return "overlay relative inline top-[0px] left-0 bottom-0 right-0 flex-col bg-background z-20 lg:left-[64px] lg:top-0 will-change-contents " + (this.class || ""); } /** * This will setup and render the component. * * @param {object} container * @returns {void} */ setup(e) { this.container = e, this.initialize(); } } const ze = d(({ index: t, click: e, state: s }, a) => y({ class: "p-2 cursor-pointer hover:bg-muted/50", onState: [ [s, "selectedIndex", { "bg-accent": t, "text-white": t }] ], click: () => e(t) }, a)), Ne = d(({ selectOption: t, state: e }) => f({ class: "border rounded-md list-none m-0 p-0 max-h-[400px] overflow-y-auto", for: ["filteredOptions", (s, a) => ze({ index: a, click: t, state: e }, s.label)] })), Ue = d((t) => o({ class: "relative flex items-center" }, [ ne({ cache: "input", class: t.class ?? "", placeholder: t.placeholder ?? "Search...", bind: t.bind ?? [t.state, "searchQuery"], keyup: (e, s) => { s.state && (s.state.open = !1), typeof t.filterOptions == "function" && t.filterOptions(), s.dropdown && s.dropdown.updatePosition(), t.keyup && t.keyup(e, s); }, pointerup: (e, s) => { typeof s.toggleDropdown == "function" && s.toggleDropdown(); }, keydown: (e) => [ typeof t.handleKeyDown == "function" && t.handleKeyDown(e) ] }), t.icon && o({ class: "absolute flex right-0 mr-2" }, [ J(t.icon) ]) ])), je = (t) => o({ class: "relative flex fle-auto flex-col", onState: ["open", (e, s, a) => { if (e) return new re({ cache: "dropdown", parent: a, button: a.input, size: "xl" }, [ Ne(t) ]); }] }), Lt = _( { /** * This will set up the data object. * * @returns {object} - The data object. */ setData() { const t = this.options || []; return new T({ options: t, filteredOptions: t }); }, /** * This will set up the state object. * * @returns {object} - The state object. */ state() { return { searchQuery: "", selectedIndex: -1, open: !1 }; }, /** * This will set the selected index by query. * * @returns {void} */ setSelectedIndexByQuery() { const t = this.data.filteredOptions; let { searchQuery: e } = this.state; e = e.toLowerCase(); const s = t.findIndex((a) => a.label.toLowerCase() === e); s >= 0 && (this.state.selectedIndex = s); }, /** * This will filter the options. * * @returns {void} */ filterOptions() { const t = this.state.searchQuery.toLowerCase(); if (t === "" || t.length === 0) { this.data.filteredOptions = this.data.options; return; } const e = this.data.get("options"); this.data.filteredOptions = e.filter( (s) => s.label.toLowerCase().includes(t) ); }, /** * This will get the selected value. * * @returns {object} */ getValue() { const { selectedIndex: t } = this.state; return t < 0 ? null : this.data.get(`filteredOptions[${t}]`); }, /** * This will select an option. * * @param {number} index - The index of the option. * @returns {void} */ selectOption(t) { this.state.selectedIndex = t; const e = this.data.get(`filteredOptions[${t}]`); this.state.searchQuery = e.label, this.state.open = !1, typeof this.onSelect == "function" && this.onSelect(e); }, /** * Toggles the dropdown open state. */ toggleDropdown() { this.state.toggle("open"), this.state.open && this.setSelectedIndexByQuery(); }, /** * This will handle key down events. * * @param {object} event - The event object. * @returns {void} */ handleKeyDown(t) { const e = this.data.filteredOptions, { selectedIndex: s } = this.state; t.key === "ArrowDown" ? (t.preventDefault(), this.state.selectedIndex = Math.min(s + 1, e.length - 1)) : t.key === "ArrowUp" ? (t.preventDefault(), this.state.selectedIndex = Math.max(s - 1, 0)) : t.key === "Enter" && s >= 0 && (t.preventDefault(), this.selectOption(s)); }, /** * This will render the component. * * @returns {object} - The rendered component. */ render() { return o({ class: "relative w-full max-w-md" }, [ Ue({ // @ts-ignore state: this.state, // @ts-ignore icon: this.icon, // @ts-ignore placeholder: this.placeholder, // @ts-ignore filterOptions: this.filterOptions.bind(this), // @ts-ignore handleKeyDown: this.handleKeyDown.bind(this) }), je({ // @ts-ignore state: this.state, // @ts-ignore setSelected: this.setSelectedIndexByQuery.bind(this), // @ts-ignore selectOption: this.selectOption.bind(this) }) ]); } } ), Ae = (t) => y( { class: "inline-flex flex-auto items-center justify-center whitespace-nowrap rounded-sm text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-primary data-[state=active]:text-primary-foreground data-[state=active]:shadow-sm", dataStateSet: ["selected", ["state", t.value, "active"]] }, [ x({ class: "flex flex-auto justify-center items-center px-3 py-1.5 rounded-md", onState: ["selected", { selected: t.value }], click: (e) => t.callBack(t.value) }, t.label) ] ), He = (t, e) => (t.callBack = e, Ae(t)), Ye = (t) => g({ class: `tab items-center justify-center rounded-md bg-muted p-1 text-muted-foreground ${t.class}` }, [ f({ class: "flex flex-auto flex-row", map: [t.options, (e) => He(e, t.callBack)] }) ]); class It extends m { /** * This will declare the props for the compiler. * * @returns {void} */ declareProps() { this.options = [], this.class = "", this.callBack = null; } /** * This will render the component. * * @returns {object} */ render() { const e = this.select.bind(this); return o({ class: "" }, [ Ye({ class: this.class, options: this.options, callBack: e }), I({ class: "tab-content", onState: ["selected", this.updateContent.bind(this)] }) ]); } /** * This will get the first value. * * @returns {*} */ getFirstValue() { return this.options[0]?.value; } /** * This will update the component. * * @returns {void} */ update() { const e = this.state.get("selected"); this.select(null), this.select(e); } /** * This will select a value. * * @param {*} value * @returns {void} */ select(e) { this.state.selected = e; } /** * This will update the content. * * @param {*} value * @returns {object} */ updateContent(e) { const s = this.options; if (!s || s.length < 1) return; const a = s[0]; for (const i of s) if (i.value === e) return i.layout; return a.layout; } /** * This will setup the states. * * @returns {object} */ setupStates() { const e = this.callBack, s = typeof e; return { selected: { state: this.getFirstValue(), callBack(a) { s === "function" && e(a); } } }; } } const Fe = (t) => y( { class: "inline-flex flex-auto items-center justify-center whitespace-nowrap rounded-sm text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-primary data-[state=active]:text-primary-foreground data-[state=active]:shadow-sm", dataStateSet: ["selected", ["state", t.value, "active"]] }, [ x({ class: "flex flex-auto justify-center items-center px-3 py-1.5 rounded-md disabled:opacity-50 disabled:cursor-not-allowed", onState: ["selected", { selected: t.value }], click: (e) => t.callBack(t.value), disabled: t.disabled }, t.label) ] ), Ee = (t, e) => (t.callBack = e, Fe(t)), Qe = (t) => g({ class: `tab items-center justify-center rounded-md bg-muted p-1 text-muted-foreground ${t.class}` }, [ f({ class: "flex flex-auto flex-row", map: [t.options, (e) => Ee(e, t.callBack)] }) ]); class Bt extends m { /** * This will declare the props for the compiler. * * @returns {void} */ declareProps() { this.options = [], this.class = "", this.onSelect = null; } /** * This will render the component. * * @returns {object} */ render() { const e = this.select.bind(this); return Qe({ class: this.class, options: this.options, callBack: e }); } /** * This will select a value. * * @param {*} value * @returns {void} */ select(e) { this.state.selected = e, typeof this.onSelect == "function" && this.onSelect(e, this.parent); } /** * This will setup the states. * * @returns {object} */ setupStates() { return { selected: this.options[0]?.value || null }; } } const Ve = (t, e) => new RegExp(`${t}($|/|\\.).*`).test(e), Ge = (t, e) => { const s = t.getLinkPath(); return t.exact ? e === s : Ve(s, e); }, Xe = ({ text: t, href: e, exact: s }) => new M({ text: t, href: e, exact: s, dataSet: ["selected", ["state", !0, "active"]], class: "inline-flex flex-auto items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-primary data-[state=active]:text-primary-foreground data-[state=active]:shadow-sm" }); class qe extends m { /** * This will declare the props for the compiler. * * @returns {void} */ declareProps() { this.options = [], this.class = "", this.onSelect = null; } /** * This will configure the links. */ beforeSetup() { this.links = []; } /** * This will render the component. * * @returns {object} */ render() { return g({ class: `tab items-center justify-center rounded-md bg-muted p-1 text-muted-foreground ${this.class}` }, [ f({ class: "flex flex-auto flex-row", map: [this.options, (e) => this.addLink(e)], watch: { value: ["[[path]]", w.data], callBack: this.updateLinks.bind(this) } }) ]); } /** * This will update the links. * * @returns {void} */ afterSetup() { const e = w.data.path; this.updateLinks(e); } /** * This will update the links. * * @param {string} value * @returns {void} */ updateLinks(e) { let s = !1, a = this.links[0]; this.deactivateAllLinks(); for (const i of this.links) if (i.rendered !== !1 && (s = Ge(i, e), s === !0)) { this.updateLink(i, !0); break; } s !== !0 && a && this.updateLink(a, !0); } /** * This will deactivate all links. * * @returns {void} */ deactivateAllLinks() { for (const e of this.links) this.updateLink(e, !1); } /** * This will update the link. * * @param {object} link * @param {boolean} selected * @returns {void} */ updateLink(e, s) { e.update(s); } /** * This will add a link. * * @param {object} option * @returns {object} */ addLink({ label: e, href: s, exact: a }) { const i = Xe({ text: e, href: s, exact: a }); return this.links.push(i), i; } /** * This will remove all the links. * * @returns {void} */ beforeDestroy() { this.links = []; } } class Tt extends m { /** * This will declare the props for the compiler. * * @returns {void} */ declareProps() { this.options = [], this.class = ""; } /** * This will render the component. * * @returns {object} */ render() { return o({ class: "tab-panel" }, [ new qe({ class: this.class, options: this.options }), I({ class: "tab-content", switch: this.addGroup() }) ]); } /** * This will add the group. * * @returns {array} */ addGroup() { let e; const s = [], a = this.options; for (let i = 0, n = a.length; i < n; i++) e = a[i], s.push( { uri: e.uri || e.href, component: e.component, title: e.title || null, persist: !0 } ); return s; } } const Ke = (t) => y( { class: "relative inline-flex items-center justify-center whitespace-nowrap text-sm font-medium text-muted-foreground transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:text-foreground after:absolute after:bottom-0 after:left-0 after:right-0 after:h-0.5 after:bg-primary after:transition-all after:duration-200 after:scale-x-0 data-[state=active]:after:scale-x-100", dataStateSet: ["selected", ["state", t.value, "active"]] }, [ x({ class: "flex flex-auto justify-center items-center px-4 py-3 cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed", onState: ["selected", { selected: t.value }], click: (e) => t.callBack(t.value) }, t.label) ] ), _e = (t, e) => (t.callBack = e, Ke(t)), Je = (t) => g({ class: `border-b border-border ${t.class}` }, [ f({ class: "flex flex-row items-center", map: [t.options, (e) => _e(e, t.callBack)] }) ]); class Mt extends m { /** * This will declare the props for the compiler. * * @returns {void} */ declareProps() { this.options = [], this.class = "", this.onSelect = null; } /** * This will render the component. * * @returns {object} */ render() { const e = this.select.bind(this); return o({ class: "underlined-button-tab-panel" }, [ Je({ class: this.class, options: this.options, callBack: e }), I({ class: "tab-content pt-6", onState: ["selected", this.updateContent.bind(this)] }) ]); } /** * This will get the first value. * * @returns {*} */ getFirstValue() { return this.options[0]?.value; } /** * This will select an option. * * @param {*} value * @returns {void} */ select(e) { this.state.selected = e; } /** * This will update the content. * * @param {*} value * @returns {object} */ updateContent(e) { const s = this.options; if (!s || s.length < 1) return; const a = s[0]; for (const i of s) if (i.value === e) return i.component; return a.component; } /** * This will setup the states. * * @returns {object} */ setupStates() { const e = this.onSelect, s = typeof e; return { selected: { state: this.getFirstValue(), callBack(a) { s === "function" && e(a); } } }; } } const Ze = (t) => y( { class: "relative inline-flex items-center justify-center whitespace-nowrap text-sm font-medium text-muted-foreground transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:text-foreground after:absolute after:bottom-0 after:left-0 after:right-0 after:h-0.5 after:bg-primary after:transition-all after:duration-200 after:scale-x-0 data-[state=active]:after:scale-x-100", dataStateSet: ["selected", ["state", t.value, "active"]] }, [ x({ class: "flex flex-auto justify-center items-center px-4 py-3 disabled:opacity-50 disabled:cursor-not-allowed cursor-pointer", onState: ["selected", { selected: t.value }], click: (e) => t.callBack(t.value), disabled: t.disabled }, t.label) ] ), et = (t, e) => (t.callBack = e, Ze(t)), tt = (t) => g({ class: `border-b border-border ${t.class}` }, [ f({ class: "flex flex-row items-center", map: [t.options, (e) => et(e, t.callBack)] }) ]); class Pt extends m { /** * This will declare the props for the compiler. * * @returns {void} */ declareProps() { this.options = [], this.class = "", this.onSelect = null; } /** * This will render the component. * * @returns {object} */ render() { const e = this.select.bind(this); return tt({ class: this.class, options: this.options, callBack: e }); } /** * This will select an option. * * @param {*} value * @returns {void} */ select(e) { this.state.selected = e, typeof this.onSelect == "function" && this.onSelect(e, this.parent); } /** * This will setup the states. * * @returns {object} */ setupStates() { return { selected: this.options[0]?.value || null }; } } const st = (t, e) => new RegExp(`${t}($|/|\\.).*`).test(e), at = (t, e) => { const s = t.getLinkPath(); return t.exact ? e === s : st(s, e); }, it = ({ text: t, href: e, exact: s }) => new M({ text: t, href: e, exact: s, dataSet: ["selected", ["state", !0, "active"]], class: "relative inline-flex items-center justify-center whitespace-nowrap px-4 py-3 text-sm font-medium text-muted-foreground transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:text-foreground after:absolute after:bottom-0 after:left-0 after:right-0 after:h-0.5 after:bg-primary after:transition-all after:duration-200 after:scale-x-0 data-[state=active]:after:scale-x-100" }); class nt extends m { /** * This will declare the props for the compiler. * * @returns {void} */ declareProps() { this.options = [], this.class = "", this.onSelect = null; } /** * This will configure the links. */ beforeSetup() { this.links = []; } /** * This will render the component. * * @returns {object} */ render() { return g({ class: `border-b border-border ${this.class}` }, [ f({ class: "flex flex-row items-center", map: [this.options, (e) => this.addLink(e)], watch: { value: ["[[path]]", w.data], callBack: this.updateLinks.bind(this) } }) ]); } /** * This will update the links. * * @returns {void} */ afterSetup() { const e = w.data.path; this.updateLinks(e); } /** * This will update the links. * * @param {string} value * @returns {void} */ updateLinks(e) { let s = !1, a = this.links[0]; this.deactivateAllLinks(); for (const i of this.links) if (i.rendered !== !1 && (s = at(i, e), s === !0)) { this.updateLink(i, !0); break; } s !== !0 && a && this.updateLink(a, !0); } /** * This will deactivate all links. * * @returns {void} */ deactivateAllLinks() { for (const e of this.links) this.updateLink(e, !1); } /** * This will update the link. * * @param {object} link * @param {boolean} selected * @returns {void} */ updateLink(e, s) { e.update(s); } /** * This will add a link. * * @param {object} option * @returns {object} */ addLink({ label: e, href: s, exact: a }) { const i = it({ text: e, href: s, exact: a }); return this.links.push(i), i; } /** * This will remove all the links. * * @returns {void} */ beforeDestroy() { this.links = []; } } class Rt extends m { /** * This will declare the props for the compiler. * * @returns {void} */ declareProps() { this.options = [], this.class = ""; } /** * This will render the component. * * @returns {object} */ render() { return o({ class: "underlined-tab-panel flex flex-auto flex-col" }, [ new nt({ class: this.class, options: this.options }), I({ class: "tab-content pt-6 flex flex-auto flex-col", switch: this.addGroup() }) ]); } /** * This will add the group. * * @returns {array} */ addGroup() { let e; const s = [], a = this.options; for (let i = 0, n = a.length; i < n; i++) e = a[i], s.push( { uri: e.uri || e.href, component: e.component, title: e.title || null, persist: !0 } ); return s; } } class ot extends p { /** * Runs before rendering, sets up defaults, a timer for drawing, * and basic canvas properties. * * @returns {void} */ onCreated() { this.lineWidth = this.lineWidth || 3, this.lineColor = this.lineColor || "#000000", this.canvas = null, this.ctx = null, this.status = "stopped"; const e = 1e3 / 60; this.timer = new ae(e, this.draw.bind(this)), this.width = 0, this.height = 0, this.signed = !1, this.mouse = { x: 0, y: 0, status: "up" }, this.margin = this.margin || { x: 40, y: 60 }, this.targetSize = this.targetSize || { width: 740, height: 345 }, this.baseLineWidth = this.baseLineWidth || 2, this.baseStrokeColor = this.baseStrokeColor || "#000000"; } /** * Renders a <canvas> element. * * @returns {object} Layout definition for the canvas. */ render() { return q({ style: "touch-action: none; -webkit-user-select: none; -webkit-touch-callout: none;" }); } /** * Called before the component is destroyed. Stops the timer * to prevent memory leaks or ongoing animation. * * @returns {void} */ beforeDestroy() { this.stopTimer(); } /** * Called after component setup. Initializes canvas context, * schedules a resize, and draws the initial content. * * @returns {void} */ afterSetup() { this.canvas = this.panel, this.ctx = this.canva