@astralui/core 0.1.1 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -0
- package/dist/index.cjs +227 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +102 -1
- package/dist/index.d.ts +102 -1
- package/dist/index.js +217 -1
- package/dist/index.js.map +1 -1
- package/dist/styles.css +294 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -13,6 +13,10 @@ dependency-free UI components. No CSS-in-JS runtime: just CSS variables +
|
|
|
13
13
|
- 🌗 **Color scheme** - `ColorSchemeProvider` / `useColorScheme` (persisted, `data-astral-scheme` on `<html>`).
|
|
14
14
|
- 🖌️ **Per-brand theming** - `AstralThemeProvider` generates a brand palette from a single hex and injects per-scheme overrides at runtime (with live preview).
|
|
15
15
|
- 🧩 **Components** - `AstralModal`, `AstralDrawer`, `AstralSelect`, `AstralMenu`, `AstralPinInput`, `AstralToaster` + `notifications`, `DateInput`, `Spinner`.
|
|
16
|
+
- 🌌 **Backgrounds** - `SpaceBackground` (animated starfield) and `GridBackground` (masked technical grid) for auth screens, heroes, and splash pages.
|
|
17
|
+
- 📊 **Charts** - dependency-free, prop-driven `Sparkline`, `Delta`, `Donut`, `FunnelBars`, `StackedBars` (pure SVG + CSS, theme-aware).
|
|
18
|
+
- 🔐 **Auth surface** - `AuthShell` / `AuthCard` + `au-auth-*` classes for sign-in / sign-up / verify / onboarding screens.
|
|
19
|
+
- ❓ **ConfirmModal** - a confirmation/alert dialog (with a `danger` variant) built on `AstralModal`.
|
|
16
20
|
|
|
17
21
|
## Install
|
|
18
22
|
|
|
@@ -89,6 +93,12 @@ notifications.update({ id: 'x', message: 'Done', color: 'green', loading: false,
|
|
|
89
93
|
| `DateInput` | Freeze-proof native date / datetime-local input. |
|
|
90
94
|
| `Spinner` | Theme-aware loading spinner. |
|
|
91
95
|
| `notifications` + `AstralToaster` | Toast system. |
|
|
96
|
+
| `SpaceBackground` | Animated cosmic backdrop with a twinkling starfield (wrap your content as children). |
|
|
97
|
+
| `GridBackground` | Subtle technical grid with a brand-tinted glow, edge-masked. |
|
|
98
|
+
| `Sparkline` / `Delta` | Inline KPI sparkline; period-over-period delta badge. |
|
|
99
|
+
| `Donut` / `FunnelBars` / `StackedBars` | Interactive, linked-hover charts (pure SVG + CSS). |
|
|
100
|
+
| `AuthShell` / `AuthCard` | Centered auth/onboarding layout on a cosmic or wash backdrop. |
|
|
101
|
+
| `ConfirmModal` | Confirmation dialog (supports a `danger` variant). |
|
|
92
102
|
| `generateColors(hex)` | 10-shade palette from one color. |
|
|
93
103
|
|
|
94
104
|
## Token reference
|
package/dist/index.cjs
CHANGED
|
@@ -599,6 +599,222 @@ function Spinner2({ size = 24, className, style }) {
|
|
|
599
599
|
}
|
|
600
600
|
);
|
|
601
601
|
}
|
|
602
|
+
function cls(base, extra) {
|
|
603
|
+
return extra ? `${base} ${extra}` : base;
|
|
604
|
+
}
|
|
605
|
+
function SpaceBackground({ children, className, style, fixed }) {
|
|
606
|
+
const s = fixed ? { position: "fixed", inset: 0, ...style } : style ?? {};
|
|
607
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cls("astral-space-bg", className), style: s, children: [
|
|
608
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "astral-stars", "aria-hidden": "true" }),
|
|
609
|
+
children
|
|
610
|
+
] });
|
|
611
|
+
}
|
|
612
|
+
function GridBackground({ children, className, style, fixed }) {
|
|
613
|
+
const s = fixed ? { position: "fixed", inset: 0, ...style } : style ?? {};
|
|
614
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cls("astral-grid-bg", className), style: s, children });
|
|
615
|
+
}
|
|
616
|
+
function chartColor(c) {
|
|
617
|
+
if (c.startsWith("var(") || c.startsWith("#") || c.startsWith("rgb") || c.startsWith("hsl")) return c;
|
|
618
|
+
return `var(--astral-color-${c.replace(".", "-")})`;
|
|
619
|
+
}
|
|
620
|
+
function Sparkline({ points, color }) {
|
|
621
|
+
if (!points || points.length < 2 || points.every((p) => p === 0)) return null;
|
|
622
|
+
const w = 100, h = 28;
|
|
623
|
+
const max = Math.max(...points), min = Math.min(...points);
|
|
624
|
+
const range = max - min || 1;
|
|
625
|
+
const step = w / (points.length - 1);
|
|
626
|
+
const d = points.map((p, i) => `${i === 0 ? "M" : "L"}${(i * step).toFixed(1)},${(h - (p - min) / range * h).toFixed(1)}`).join(" ");
|
|
627
|
+
return /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "au-spark", viewBox: `0 0 ${w} ${h}`, preserveAspectRatio: "none", "aria-hidden": true, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d, fill: "none", stroke: chartColor(color), strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round" }) });
|
|
628
|
+
}
|
|
629
|
+
function Delta({ current, previous }) {
|
|
630
|
+
if (previous == null || previous === 0) return null;
|
|
631
|
+
const pct = Math.round((current - previous) / previous * 100);
|
|
632
|
+
if (pct === 0) return null;
|
|
633
|
+
const up = pct > 0;
|
|
634
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("span", { className: `au-delta ${up ? "up" : "down"}`, children: [
|
|
635
|
+
up ? "\u25B2" : "\u25BC",
|
|
636
|
+
" ",
|
|
637
|
+
Math.abs(pct),
|
|
638
|
+
"%"
|
|
639
|
+
] });
|
|
640
|
+
}
|
|
641
|
+
function Donut({ data, centerValue, centerLabel }) {
|
|
642
|
+
const [hovered, setHovered] = react.useState(null);
|
|
643
|
+
const total = data.reduce((s, d) => s + d.value, 0) || 1;
|
|
644
|
+
const c = 75, r = 58, sw = 18, circ = 2 * Math.PI * r;
|
|
645
|
+
let offset = 0;
|
|
646
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "au-donut", children: [
|
|
647
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "au-donut-ring", children: [
|
|
648
|
+
/* @__PURE__ */ jsxRuntime.jsxs("svg", { width: 150, height: 150, viewBox: "0 0 150 150", children: [
|
|
649
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: c, cy: c, r, fill: "none", stroke: "var(--au-surface-2)", strokeWidth: sw }),
|
|
650
|
+
data.map((d, i) => {
|
|
651
|
+
const dash = d.value / total * circ;
|
|
652
|
+
const el = /* @__PURE__ */ jsxRuntime.jsx(
|
|
653
|
+
"circle",
|
|
654
|
+
{
|
|
655
|
+
cx: c,
|
|
656
|
+
cy: c,
|
|
657
|
+
r,
|
|
658
|
+
fill: "none",
|
|
659
|
+
stroke: chartColor(d.color),
|
|
660
|
+
strokeWidth: hovered === i ? sw + 4 : sw,
|
|
661
|
+
strokeDasharray: `${dash} ${circ - dash}`,
|
|
662
|
+
strokeDashoffset: -offset,
|
|
663
|
+
transform: `rotate(-90 ${c} ${c})`,
|
|
664
|
+
style: {
|
|
665
|
+
opacity: hovered == null || hovered === i ? 1 : 0.28,
|
|
666
|
+
transition: "opacity .15s, stroke-width .15s",
|
|
667
|
+
cursor: "pointer"
|
|
668
|
+
},
|
|
669
|
+
onMouseEnter: () => setHovered(i),
|
|
670
|
+
onMouseLeave: () => setHovered(null)
|
|
671
|
+
},
|
|
672
|
+
i
|
|
673
|
+
);
|
|
674
|
+
offset += dash;
|
|
675
|
+
return el;
|
|
676
|
+
})
|
|
677
|
+
] }),
|
|
678
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "au-donut-ctr", children: [
|
|
679
|
+
/* @__PURE__ */ jsxRuntime.jsx("b", { children: centerValue }),
|
|
680
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: centerLabel })
|
|
681
|
+
] })
|
|
682
|
+
] }),
|
|
683
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "au-donut-legend", children: data.map((d, i) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
684
|
+
"div",
|
|
685
|
+
{
|
|
686
|
+
className: `au-dl ${hovered === i ? "on" : hovered != null ? "off" : ""}`,
|
|
687
|
+
onMouseEnter: () => setHovered(i),
|
|
688
|
+
onMouseLeave: () => setHovered(null),
|
|
689
|
+
children: [
|
|
690
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "dot", style: { background: chartColor(d.color) } }),
|
|
691
|
+
/* @__PURE__ */ jsxRuntime.jsx("b", { children: d.value.toLocaleString() }),
|
|
692
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "dll", children: d.name })
|
|
693
|
+
]
|
|
694
|
+
},
|
|
695
|
+
i
|
|
696
|
+
)) })
|
|
697
|
+
] });
|
|
698
|
+
}
|
|
699
|
+
function FunnelBars({ data }) {
|
|
700
|
+
const [hov, setHov] = react.useState(null);
|
|
701
|
+
const max = Math.max(...data.map((d) => d.value), 1);
|
|
702
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "au-funnel", children: data.map((d, i) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
703
|
+
"div",
|
|
704
|
+
{
|
|
705
|
+
className: `au-fbar ${hov === i ? "on" : hov != null ? "off" : ""}`,
|
|
706
|
+
onMouseEnter: () => setHov(i),
|
|
707
|
+
onMouseLeave: () => setHov(null),
|
|
708
|
+
children: [
|
|
709
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "au-fbar-label", children: d.stage }),
|
|
710
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "au-fbar-track", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "au-fbar-fill", style: { width: `${d.value / max * 100}%`, background: chartColor(d.color) } }) }),
|
|
711
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "au-fbar-val", children: d.value.toLocaleString() })
|
|
712
|
+
]
|
|
713
|
+
},
|
|
714
|
+
d.stage
|
|
715
|
+
)) });
|
|
716
|
+
}
|
|
717
|
+
function StackedBars({ rows, series }) {
|
|
718
|
+
const [hovSeries, setHovSeries] = react.useState(null);
|
|
719
|
+
const [hovSeg, setHovSeg] = react.useState(null);
|
|
720
|
+
const max = Math.max(...rows.map((r) => r.values.reduce((a, b) => a + b, 0)), 1);
|
|
721
|
+
const anyHover = hovSeries != null || hovSeg != null;
|
|
722
|
+
const active = (row, s) => hovSeries != null ? s === hovSeries : hovSeg != null ? hovSeg.row === row && hovSeg.s === s : true;
|
|
723
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "au-usage", children: [
|
|
724
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "au-usage-legend", children: series.map((s, si) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
725
|
+
"div",
|
|
726
|
+
{
|
|
727
|
+
className: `au-ulg ${hovSeries === si ? "on" : hovSeries != null ? "off" : ""}`,
|
|
728
|
+
onMouseEnter: () => setHovSeries(si),
|
|
729
|
+
onMouseLeave: () => setHovSeries(null),
|
|
730
|
+
children: [
|
|
731
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "dot", style: { background: chartColor(s.color) } }),
|
|
732
|
+
s.label
|
|
733
|
+
]
|
|
734
|
+
},
|
|
735
|
+
si
|
|
736
|
+
)) }),
|
|
737
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "au-usage-rows", children: rows.map((r, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `au-urow ${hovSeg?.row === i ? "on" : ""}`, children: [
|
|
738
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "au-urow-label", title: r.label, children: r.label }),
|
|
739
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "au-utrack", children: r.values.map((v, si) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
740
|
+
"div",
|
|
741
|
+
{
|
|
742
|
+
className: "au-useg",
|
|
743
|
+
onMouseEnter: () => setHovSeg({ row: i, s: si }),
|
|
744
|
+
onMouseLeave: () => setHovSeg(null),
|
|
745
|
+
style: {
|
|
746
|
+
width: `${v / max * 100}%`,
|
|
747
|
+
background: chartColor(series[si].color),
|
|
748
|
+
opacity: anyHover && !active(i, si) ? 0.2 : 1,
|
|
749
|
+
filter: anyHover && active(i, si) ? "brightness(1.2)" : void 0
|
|
750
|
+
}
|
|
751
|
+
},
|
|
752
|
+
si
|
|
753
|
+
)) }),
|
|
754
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "au-unums", children: r.values.map((v, si) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
755
|
+
"b",
|
|
756
|
+
{
|
|
757
|
+
style: {
|
|
758
|
+
color: chartColor(series[si].color),
|
|
759
|
+
opacity: anyHover && !active(i, si) ? 0.28 : 1,
|
|
760
|
+
textShadow: anyHover && active(i, si) ? `0 0 10px ${chartColor(series[si].color)}` : void 0
|
|
761
|
+
},
|
|
762
|
+
children: v.toLocaleString()
|
|
763
|
+
},
|
|
764
|
+
si
|
|
765
|
+
)) })
|
|
766
|
+
] }, i)) })
|
|
767
|
+
] });
|
|
768
|
+
}
|
|
769
|
+
function AuthShell({ children, backdrop = "space", topLeft, topRight, className, style }) {
|
|
770
|
+
const cls2 = `au-auth${backdrop === "space" ? " astral-space-bg" : ""}${className ? " " + className : ""}`;
|
|
771
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cls2, style, children: [
|
|
772
|
+
backdrop === "space" ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "astral-stars", "aria-hidden": "true" }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "au-auth-bg", "aria-hidden": "true" }),
|
|
773
|
+
topLeft,
|
|
774
|
+
topRight ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "au-auth-lang", children: topRight }) : null,
|
|
775
|
+
children
|
|
776
|
+
] });
|
|
777
|
+
}
|
|
778
|
+
function AuthCard({ children, banner, className, style }) {
|
|
779
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `au-auth-card${className ? " " + className : ""}`, style, children: [
|
|
780
|
+
banner ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "au-auth-banner", children: banner }) : null,
|
|
781
|
+
children
|
|
782
|
+
] });
|
|
783
|
+
}
|
|
784
|
+
function ConfirmModal({
|
|
785
|
+
opened,
|
|
786
|
+
onClose,
|
|
787
|
+
onConfirm,
|
|
788
|
+
title,
|
|
789
|
+
message,
|
|
790
|
+
confirmLabel = "Confirm",
|
|
791
|
+
cancelLabel = "Cancel",
|
|
792
|
+
danger,
|
|
793
|
+
loading,
|
|
794
|
+
width = 420,
|
|
795
|
+
children
|
|
796
|
+
}) {
|
|
797
|
+
return /* @__PURE__ */ jsxRuntime.jsx(AstralModal, { opened, onClose, title, width, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "clay-form", children: [
|
|
798
|
+
message != null && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: 13, lineHeight: 1.55, color: "var(--au-dim)" }, children: message }),
|
|
799
|
+
children,
|
|
800
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "clay-actions", children: [
|
|
801
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "au-btn", onClick: onClose, disabled: loading, children: cancelLabel }),
|
|
802
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
803
|
+
"button",
|
|
804
|
+
{
|
|
805
|
+
type: "button",
|
|
806
|
+
className: `au-btn ${danger ? "solidred" : "primary"}`,
|
|
807
|
+
onClick: onConfirm,
|
|
808
|
+
disabled: loading,
|
|
809
|
+
children: [
|
|
810
|
+
loading ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "au-spinner", style: { width: 14, height: 14 } }) : null,
|
|
811
|
+
confirmLabel
|
|
812
|
+
]
|
|
813
|
+
}
|
|
814
|
+
)
|
|
815
|
+
] })
|
|
816
|
+
] }) });
|
|
817
|
+
}
|
|
602
818
|
|
|
603
819
|
exports.AstralDrawer = AstralDrawer;
|
|
604
820
|
exports.AstralMenu = AstralMenu;
|
|
@@ -607,10 +823,21 @@ exports.AstralPinInput = AstralPinInput;
|
|
|
607
823
|
exports.AstralSelect = AstralSelect;
|
|
608
824
|
exports.AstralThemeProvider = AstralThemeProvider;
|
|
609
825
|
exports.AstralToaster = AstralToaster;
|
|
826
|
+
exports.AuthCard = AuthCard;
|
|
827
|
+
exports.AuthShell = AuthShell;
|
|
610
828
|
exports.ColorSchemeProvider = ColorSchemeProvider;
|
|
829
|
+
exports.ConfirmModal = ConfirmModal;
|
|
611
830
|
exports.DateInput = DateInput;
|
|
831
|
+
exports.Delta = Delta;
|
|
832
|
+
exports.Donut = Donut;
|
|
833
|
+
exports.FunnelBars = FunnelBars;
|
|
834
|
+
exports.GridBackground = GridBackground;
|
|
835
|
+
exports.SpaceBackground = SpaceBackground;
|
|
836
|
+
exports.Sparkline = Sparkline;
|
|
612
837
|
exports.Spinner = Spinner2;
|
|
838
|
+
exports.StackedBars = StackedBars;
|
|
613
839
|
exports.buildOrgCss = buildOrgCss;
|
|
840
|
+
exports.chartColor = chartColor;
|
|
614
841
|
exports.dateTimeToInputStr = dateTimeToInputStr;
|
|
615
842
|
exports.dateToInputStr = dateToInputStr;
|
|
616
843
|
exports.generateColors = generateColors;
|