@base-framework/ui
Version:
This is a UI package that adds components and atoms that use Tailwind CSS and a theme based on Shadcn.
327 lines (326 loc) • 8.99 kB
JavaScript
import { Span as c, Div as l, Legend as b, Fieldset as f, UseParent as x, Input as C } from "@base-framework/atoms";
import { Atom as s, Html as p } from "@base-framework/base";
import { a as u } from "./veil-D4dRxILB.js";
import { f as h, e as y, g as k } from "./inputs-nzivW9Dr.js";
const a = {
gray: {
backgroundColor: "bg-gray-50",
textColor: "text-gray-600",
ringColor: "ring-gray-500/10"
},
red: {
backgroundColor: "bg-red-50",
textColor: "text-red-700",
ringColor: "ring-red-600/10"
},
yellow: {
backgroundColor: "bg-yellow-50",
textColor: "text-yellow-800",
ringColor: "ring-yellow-600/20"
},
green: {
backgroundColor: "bg-green-50",
textColor: "text-green-700",
ringColor: "ring-green-600/20"
},
blue: {
backgroundColor: "bg-blue-50",
textColor: "text-blue-700",
ringColor: "ring-blue-700/10"
},
indigo: {
backgroundColor: "bg-indigo-50",
textColor: "text-indigo-700",
ringColor: "ring-indigo-700/10"
},
purple: {
backgroundColor: "bg-purple-50",
textColor: "text-purple-700",
ringColor: "ring-purple-700/10"
},
pink: {
backgroundColor: "bg-pink-50",
textColor: "text-pink-700",
ringColor: "ring-pink-700/10"
},
primary: {
backgroundColor: "bg-primary",
textColor: "text-primary-foreground",
ringColor: "ring-primary/10"
},
secondary: {
backgroundColor: "bg-secondary",
textColor: "text-secondary-foreground",
ringColor: "ring-secondary/10"
},
destructive: {
backgroundColor: "bg-destructive",
textColor: "text-destructive-foreground",
ringColor: "ring-destructive/10"
},
warning: {
backgroundColor: "bg-warning",
textColor: "text-warning-foreground",
ringColor: "ring-warning/10"
},
outline: {
backgroundColor: "bg-background",
textColor: "text-primary",
ringColor: "ring-input"
},
ghost: {
backgroundColor: "bg-background",
textColor: "text-primary",
ringColor: "ring-background"
},
link: {
backgroundColor: "bg-background",
textColor: "text-primary",
ringColor: "ring-background"
}
}, w = (t) => a[t] || a.gray, $ = (t) => {
const { backgroundColor: e, textColor: r, ringColor: o } = w(t);
return `inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors ${e} ${r} ${o}`;
}, T = s((t, e) => {
const r = $(t == null ? void 0 : t.type);
return c({ ...t, class: r }, e);
}), L = s((t, e) => {
const r = t.margin ?? "my-5 mx-5", o = t.padding ?? "p-4";
return l({
...t,
class: `rounded-lg border bg-card text-card-foreground shadow-md min-w-[120px] min-h-[80px] ${r} ${o} ${t.class || ""}`
}, e);
}), v = s((t, e) => b({
...t,
class: ` font-medium bg-background -mt-4 -mx-1 px-2 py-2 ${t.class || ""}`
}, e)), I = s((t, e) => {
const r = t.border === "full" ? "border rounded-md" : "border-t";
return f({
...t,
class: `p-6 ${r} ${t.class || ""}`
}, [
t.legend && v(t.legend),
l({ class: "flex flex-auto flex-col space-y-6" }, e)
]);
}), G = u(
{
/**
* This will create the initial state of the RangeSlider.
*
* @returns {object}
*/
state() {
return {
value: this.value ?? 0,
min: this.min ?? 0,
max: this.max ?? 100,
filledPercentage: this.getFillPercentage(this.value)
};
},
/**
* This will get the fill percentage of the range slider.
*
* @param {number} value
* @returns {number}
*/
getFillPercentage(t) {
return (t - this.min) / (this.max - this.min) * 100;
},
/**
* This will render the RangeSlider component.
*
* @returns {object}
*/
render() {
return l({ class: "relative w-full h-4 flex items-center" }, [
// Track
l({ class: "absolute h-2 w-full rounded-full bg-muted" }),
x(({ state: t }) => [
// Filled Track
l({
class: "absolute h-2 bg-primary rounded-full",
style: ["width: [[filledPercentage]]%", t]
}),
// Thumb
l({
class: `
absolute block h-5 w-5 rounded-full border-2 border-primary bg-background
ring-offset-background transition-colors focus-visible:outline-none
focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2
disabled:pointer-events-none disabled:opacity-50 transform -translate-x-1/2
`.trim(),
style: ["left: [[filledPercentage]]%", t]
}),
// Hidden Range Input
C({
type: "range",
min: ["[[min]]", t],
max: ["[[max]]", t],
value: ["[[value]]", t],
// Incorporate your new classes here
class: `
absolute w-full h-full opacity-0 cursor-pointer
${h}
${y}
${this.class || ""}
`.trim(),
bind: this.bind,
input: (e) => {
const r = Number(e.target.value);
this.state.value = r, this.state.filledPercentage = this.getFillPercentage(r), typeof this.change == "function" && this.change(r);
}
})
])
]);
}
}
), R = s((t) => ({
tag: "select",
...t,
class: `${k} ${t.class || ""}`.trim(),
onCreated(e) {
t.options && p.setupSelectOptions(e, t.options);
}
})), P = (t) => !t || isNaN(t) ? null : t, i = (t, e) => {
const r = t, o = 16, n = 2 * Math.PI * o, d = r / 100 * n, m = `
<svg class="w-40 h-40 mx-auto" viewBox="0 0 36 36" xmlns="http://www.w3.org/2000/svg">
<!-- Background Circle -->
<circle
cx="18"
cy="18"
r="${o}"
fill="none"
stroke="currentColor"
stroke-width="4"
class="bg-muted"
stroke-opacity="0.2"
/>
<!-- Progress Circle -->
<circle
cx="18"
cy="18"
r="${o}"
fill="none"
stroke="currentColor"
stroke-width="4"
class="stroke-primary"
stroke-dasharray="${n}"
stroke-dashoffset="${n - d}"
stroke-linecap="round"
class="${e}"
/>
<!-- Percentage Text -->
<text
x="18"
y="20"
class="text-[0.25em] font-medium fill-primary"
text-anchor="middle"
dominant-baseline="middle">
${r}%
</text>
</svg>
`;
return l({
class: "circle-graph text-inherit",
html: m
});
}, O = s((t) => {
const e = t.progress || 0, r = t.class || "", o = i(e, r);
return l({
class: "circle-graph-wrap",
onSet: [
t.prop,
(n) => (n = P(n), n ? i(n, r) : o)
]
}, [o]);
}), S = () => l({
class: "absolute h-full rounded-full bg-primary transition-all duration-300",
style: "width: [[progress]]%;"
}), V = u(
{
/**
* This will render the progress bar component.
*
* @returns {object}
*/
render() {
return l({ class: "relative w-full h-4 rounded-full bg-muted" }, [
S()
]);
},
/**
* This will initialize the state.
*
* @returns {object}
*/
state() {
return {
progress: this.progress ?? 0
};
},
/**
* This will reset the progress bar.
*
* @returns {void}
*/
reset() {
this.state.progress = 0;
},
/**
* This will update the progress bar from a file upload.
*
* @param {object} evt
* @returns {void}
*/
uploadProgress(t) {
if (t.lengthComputable) {
const r = Math.round(t.loaded * 100 / t.total);
this.set(r);
}
},
/**
* This will set the progress of the progress bar.
*
* @param {number} progress
* @returns {void}
*/
set(t) {
t < 0 && (t = 0), t > 100 && (t = 100), this.state.progress = t;
}
}
), D = ({ class: t, shape: e = "rectangle", width: r = "w-full", height: o = "h-4" }) => l({
class: `bg-muted animate-pulse ${r} ${o} ${e === "circle" ? "rounded-full" : "rounded-md"} ${t || ""}`
}), g = {
top: "bottom-full left-1/2 transform -translate-x-1/2 mb-2",
"top-right": "bottom-full left-full transform -translate-x-1 mb-2",
"top-left": "bottom-full right-full transform translate-x-1 mb-2",
bottom: "top-full left-1/2 transform -translate-x-1/2 mt-2",
"bottom-right": "top-full left-full transform -translate-x-1 mt-2",
"bottom-left": "top-full right-full transform translate-x-1 mt-2",
left: "top-1/2 right-full transform -translate-y-1/2 mr-2",
right: "top-1/2 left-full transform -translate-y-1/2 ml-2"
}, E = (t) => g[t] || g.top, M = s(({ position: t = "top", content: e }, r) => {
const o = E(t);
return Array.isArray(r) === !1 && (r = [r]), l({ class: "relative group inline-block" }, [
...r,
// Tooltip box
c({
class: `
absolute z-20 px-2 py-1 border text-sm bg-background rounded shadow-md opacity-0 whitespace-nowrap
group-hover:opacity-100 transition-opacity duration-200 ${o} pointer-events-none
`
}, e)
]);
});
export {
T as B,
L as C,
I as F,
v as L,
V as P,
G as R,
R as S,
M as T,
O as a,
D as b
};