@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
JavaScript
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