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.

439 lines (438 loc) 11.7 kB
import { Div as i, Img as I, Span as M, Button as Y } from "@base-framework/atoms"; import { Component as N, Data as z, Atom as k, DateTime as j } from "@base-framework/base"; import { B as A } from "./buttons-CVEwmPAi.js"; import { Icons as P } from "./icons.es.js"; const W = (e, t) => { const n = e ? e.getBoundingClientRect() : { top: 0, bottom: 0, left: 0 }, s = t.getBoundingClientRect(), o = 10, a = window.scrollX, l = window.scrollY; let c = n.left + a, f = n.bottom + l; const h = window.innerHeight - n.bottom, d = n.top; return c + s.width > window.innerWidth && (c = window.innerWidth - s.width - o), h < s.height && d > h ? f = n.top + l - s.height - o : h < s.height && (f = n.bottom + l - (s.height - h) - o), { x: c, y: f }; }; class lt extends N { /** * This will set up the data. * * @returns {object} */ setData() { const t = this.parent.data || new z(); return t.set({ position: { x: 0, y: 0 } }), t; } /** * This will get the class size. * * @returns {string} */ getSize() { switch (this.size || "lg") { // @ts-ignore case "sm": return "w-48"; // @ts-ignore case "md": return "w-64"; case "lg": return "w-[250px]"; // @ts-ignore case "xl": return "w-96"; // @ts-ignore case "2xl": return "w-[400px]"; // @ts-ignore case "fit": return "w-fit"; // @ts-ignore case "full": return "w-full"; } } /** * This will render the modal component. * * @returns {object} */ render() { const t = this.getSize(); return i({ class: `absolute inset-auto fadeIn mt-2 rounded-md p-0 shadow-lg bg-popover min-h-12 backdrop:bg-transparent text-inherit r z-30 ${t}`, popover: "manual", toggle: (n, { state: s }) => n.newState === "closed" ? s.open = !1 : null, style: "top: [[position.y]]px; left: [[position.x]]px" }, this.children); } /** * This will setup the states. * * @returns {object} */ setupStates() { return { open: { id: this.parent.getId(), callBack: (s) => { this.state.open === !1 && this.destroy(); } } }; } /** * Updates the dropdown position. * * @returns {void} */ updatePosition() { const t = this.button ?? null, n = this.panel, s = W(t, n); this.data.position = s; } /** * This will run after the setup. * * @returns {void} */ afterSetup() { this.panel.showPopover(), this.updatePosition(); } /** * This will check if the element clicked was in the * component of the button. * * @param {object} element * @returns {boolean} */ isOutsideClick(t) { return !this.panel.contains(t) && this.button && !this.button.contains(t); } /** * This will set up the events. * * @returns {array} */ setupEvents() { return [ ["click", document, (t) => { this.isOutsideClick(t.target) && (this.state.open = !1); }], ["resize", window, (t) => this.updatePosition()], ["scroll", document, (t) => this.updatePosition()] ]; } /** * This will override the set up to use the app shell. * * @param {object} container */ setContainer(t) { this.container = app.root; } /** * This will hide the popover before destroying. * * @returns {void} */ beforeDestroy() { this.panel.hidePopover(); } } const H = k(({ src: e, alt: t }) => e ? I({ class: "absolute w-full h-full rounded-full object-cover fadeIn", src: e, alt: t, /** * If there's an error loading the image, hide it. */ error: (n) => n.target.style.display = "none" }) : null), R = (e) => e.split(" ").map((t) => t.charAt(0)).join(""), B = (e) => !e || e.length < 2 ? e : R(e), X = (e) => M([e, (t, n) => { n.textContent = B(t); }]), S = { xs: "h-6 w-6", sm: "h-8 w-8", md: "h-12 w-12", lg: "h-16 w-16", xl: "h-24 w-24", "2xl": "h-32 w-32", "3xl": "h-48 w-48", default: "h-12 w-12" }, T = { xs: "text-[7px]", sm: "text-xs", md: "text-base", lg: "text-xl", xl: "text-2xl", "2xl": "text-3xl", "3xl": "text-4xl", default: "text-base" }, E = (e) => S[e] || S.default, G = (e) => T[e] || T.default, L = (e, t = null, n = "md") => { const s = B(e), o = G(n); return i( { class: ` flex items-center justify-center w-full h-full rounded-full bg-muted text-muted-foreground font-medium ${o} ` }, [ t ? X(t) : M({ class: "uppercase" }, s) ] ); }, ct = k(({ src: e, alt: t, fallbackText: n, watcherFallback: s, size: o }) => { const a = E(o); return i( { class: `relative flex items-center justify-center ${a}` }, [ H({ src: e, alt: t }), L(n, s, o) ] ); }), x = (e) => (e *= 1, e < 10 ? `0${e}` : String(e)), q = (e) => (e.indexOf("T") === -1 && e.indexOf(" ") === -1 && (e += "T00:00:01"), e.replace(" ", "T"), e), p = (e, t, n) => `${e}-${x(t + 1)}-${x(n)}`, J = (e) => e ? "bg-accent text-primary" : "", K = (e) => e ? "text-muted-foreground opacity-50" : "", Q = (e, t) => e === t, U = (e, t) => Q(e, t) ? "bg-primary text-primary-foreground" : "", V = (e, t, n, s) => { const o = U(t, s); return o || (e ? J(e) : n ? K(n) : "text-foreground"); }, C = (e) => { const { day: t, currentDate: n, date: s, isToday: o, isOutsideMonth: a, select: l, disabled: c } = e; return Y( { class: ` flex items-center justify-center h-9 w-auto p-0 font-normal text-sm rounded-md ${V(o, n, a, s)} hover:bg-muted/50 hover:text-muted-foreground focus:z-10 disabled:pointer-events-none disabled:opacity-50 `, disabled: c || t === null, "aria-label": t ? `Day ${t}` : null, // Only call select if it's not disabled. click: () => !c && l(s) }, t.toString() ); }, b = (e, t, n, s) => e === s.date && t === s.month && n === s.year, Z = (e, t, n, s = !1) => { const { year: o, month: a } = e, l = p(o, a, e.date), c = new Date(o, a, 1).getDay(), f = new Date(o, a + 1, 0).getDate(), h = new Date(o, a, 0).getDate(), d = [], D = a === 0 ? 11 : a - 1, w = a === 0 ? o - 1 : o; for (let r = c - 1; r >= 0; r--) { const u = h - r, g = b(u, D, w, t), m = new Date(w, D, u) < new Date(t.year, t.month, t.date), F = s && m; d.push( C({ day: u, currentDate: l, date: p(w, D, u), isToday: g, isOutsideMonth: !0, select: n, disabled: F }) ); } for (let r = 1; r <= f; r++) { const u = b(r, a, o, t), g = new Date(o, a, r) < new Date(t.year, t.month, t.date), m = s && g; d.push( C({ day: r, currentDate: l, date: p(o, a, r), isToday: u, isOutsideMonth: !1, select: n, disabled: m }) ); } const y = a === 11 ? 0 : a + 1, v = a === 11 ? o + 1 : o, O = (7 - d.length % 7) % 7; for (let r = 1; r <= O; r++) { const u = b(r, y, v, t), g = new Date(v, y, r) < new Date(t.year, t.month, t.date), m = s && g; d.push( C({ day: r, currentDate: l, date: p(v, y, r), isToday: u, isOutsideMonth: !0, select: n, disabled: m }) ); } return d; }, _ = (e) => i( { class: "flex items-center justify-center h-9 w-auto text-[0.8rem] font-normal text-muted-foreground" }, e ), $ = ({ label: e, click: t }) => A( { class: ` inline-flex items-center justify-center h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100 text-muted-foreground absolute ${e === "Previous" ? "left-1" : "right-1"} focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 `, click: t, "aria-label": `${e} month`, variant: "icon", icon: e === "Previous" ? P.chevron.single.left : P.chevron.single.right } ), tt = ({ next: e, previous: t }) => i({ class: "flex flex-auto min-h-12 text-sm font-medium relative justify-center items-center" }, [ M("[[monthName]] [[current.year]]"), $({ label: "Previous", click: t }), $({ label: "Next", click: e }) ]), et = () => ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"].map(_), nt = (e) => i({ class: "rdp w-full space-y-1" }, [ tt({ next: e.next, previous: e.previous }), i({ class: "flex flex-auto flex-col w-full", onSet: [ "currentDate", () => [ i({ class: "grid grid-cols-7" }, et()), i( { class: "grid grid-cols-7" }, Z( e.current, e.today, e.select, e.blockPriorDates ) ) ] ] }) ]); class ut extends N { /** * This will declare the props for the compiler. * * @returns {void} */ declareProps() { this.selectedDate = null, this.selectedCallBack = null, this.blockPriorDates = !1; } /** * This will get the selected data. * * @param {object} today * @returns {Date} */ getSelectedDate(t) { const n = this.selectedDate ? new Date(q(this.selectedDate)) : t; return new Date(n.getFullYear(), n.getMonth(), n.getDate()); } /** * This will set up the data for the calendar. * * @returns {Data} */ setData() { const t = /* @__PURE__ */ new Date(), n = this.getSelectedDate(t), s = n.getMonth(); return new z({ monthName: this.getMonthName(s), currentDate: `${n.getFullYear()}-${s + 1}-${n.getDate()}`, current: { date: n.getDate(), year: n.getFullYear(), month: s }, today: { date: t.getDate(), month: t.getMonth(), year: t.getFullYear() } }); } /** * This will get the name of the month. * * @param {number} month * @returns {string} */ getMonthName(t) { return j.monthNames[t]; } /** * This will go to the previous month. * * @returns {void} */ goToPreviousMonth() { const t = this.data; let n = t.current.month, s = t.current.year; n === 0 ? (n = 11, s--) : n--, this.setCurrentDate(n, s); } /** * This will go to the next month. * * @returns {void} */ goToNextMonth() { const t = this.data; let n = t.current.month, s = t.current.year; n === 11 ? (n = 0, s++) : n++, this.setCurrentDate(n, s); } /** * This will set the current month and year. * * @param {number} month * @param {number} year * @param {number} [date=null] * @returns {void} */ setCurrentDate(t, n, s = null) { const o = this.data; o.current.month = t, o.current.year = n, typeof s == "number" && (o.current.date = x(s)), o.currentDate = `${n}-${x(t + 1)}-${o.current.date}`, o.monthName = this.getMonthName(t); } /** * This will select a date. * * @param {string} date * @returns {void} */ selectDate(t) { const n = /* @__PURE__ */ new Date(t + "T00:00:00"); this.setCurrentDate(n.getMonth(), n.getFullYear(), n.getDate()), typeof this.selectedCallBack == "function" && this.selectedCallBack(this.data.currentDate); } /** * This will render the calendar. * * @returns {object} */ render() { return i({ class: "calendar-container p-3 rounded-md border min-w-80" }, [ nt({ current: this.data.current, today: this.data.today, select: (t) => this.selectDate(t), next: () => this.goToNextMonth(), previous: () => this.goToPreviousMonth(), blockPriorDates: this.blockPriorDates || !1 }) ]); } } export { ct as A, Z as C, C as D, p as F, nt as M, lt as P, _ as a, ut as b, q as c, W as g, x as p };