@a4ui/core 0.9.0 → 0.10.1

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.
@@ -0,0 +1,54 @@
1
+ import { JSX } from 'solid-js';
2
+ /** A single file entry rendered by {@link FileUpload}. The consumer owns this state. */
3
+ export interface UploadFile {
4
+ id: string;
5
+ name: string;
6
+ /** File size in bytes. */
7
+ size: number;
8
+ /** Upload progress, 0-100. */
9
+ progress: number;
10
+ status: 'pending' | 'uploading' | 'done' | 'error';
11
+ /** Optional preview/thumbnail URL (e.g. an object URL for an image). */
12
+ url?: string;
13
+ /** Error message when `status === 'error'`. */
14
+ error?: string;
15
+ }
16
+ export interface FileUploadProps {
17
+ files: UploadFile[];
18
+ /** Called with the newly chosen File[] (from drop or the file dialog). */
19
+ onAdd: (files: File[]) => void;
20
+ onRemove?: (id: string) => void;
21
+ onRetry?: (id: string) => void;
22
+ /** `accept` attribute for the hidden input, e.g. ".png,.jpg,application/pdf". */
23
+ accept?: string;
24
+ /** Allow choosing/dropping more than one file at a time. Default: `true`. */
25
+ multiple?: boolean;
26
+ /** Helper text shown inside the drop zone. */
27
+ hint?: string;
28
+ disabled?: boolean;
29
+ class?: string;
30
+ }
31
+ /**
32
+ * Advanced, controlled file uploader: a click-or-drag drop zone plus a list of
33
+ * files showing per-file progress, error/retry, a preview thumbnail, and a
34
+ * remove action. This component owns no file state — the consumer supplies
35
+ * `files` and performs the actual upload, updating `files` as progress comes in.
36
+ *
37
+ * @example
38
+ * ```tsx
39
+ * const [files, setFiles] = createSignal<UploadFile[]>([])
40
+ *
41
+ * <FileUpload
42
+ * files={files()}
43
+ * accept="image/*"
44
+ * onAdd={(added) => {
45
+ * const entries = added.map((f) => ({ id: crypto.randomUUID(), name: f.name, size: f.size, progress: 0, status: 'pending' as const }))
46
+ * setFiles((prev) => [...prev, ...entries])
47
+ * entries.forEach((entry, i) => upload(added[i], entry.id, setFiles))
48
+ * }}
49
+ * onRemove={(id) => setFiles((prev) => prev.filter((f) => f.id !== id))}
50
+ * onRetry={(id) => retryUpload(id, setFiles)}
51
+ * />
52
+ * ```
53
+ */
54
+ export declare function FileUpload(props: FileUploadProps): JSX.Element;
@@ -0,0 +1,35 @@
1
+ import { JSX } from 'solid-js';
2
+ /** One selectable option: a stable `value` and its display `label`. */
3
+ export interface MultiSelectOption {
4
+ value: string;
5
+ label: string;
6
+ }
7
+ export interface MultiSelectProps {
8
+ options: MultiSelectOption[];
9
+ value: string[];
10
+ onChange: (value: string[]) => void;
11
+ placeholder?: string;
12
+ /** Show a search box in the dropdown. Default `true`. */
13
+ searchable?: boolean;
14
+ disabled?: boolean;
15
+ class?: string;
16
+ }
17
+ /**
18
+ * Multi-select dropdown: the trigger shows selected options as removable
19
+ * chips, and the portaled popover lists (optionally search-filtered) options
20
+ * to toggle. Picking an option keeps the popover open so several values can
21
+ * be chosen in a row; the popover closes on outside click, Escape, scroll, or
22
+ * resize.
23
+ *
24
+ * @example
25
+ * ```tsx
26
+ * const [tags, setTags] = createSignal<string[]>([])
27
+ * <MultiSelect
28
+ * options={[{ value: 'a', label: 'Alpha' }, { value: 'b', label: 'Beta' }]}
29
+ * value={tags()}
30
+ * onChange={setTags}
31
+ * placeholder="Select tags…"
32
+ * />
33
+ * ```
34
+ */
35
+ export declare function MultiSelect(props: MultiSelectProps): JSX.Element;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@a4ui/core",
3
- "version": "0.9.0",
3
+ "version": "0.10.1",
4
4
  "description": "A4ui — Spatial Glass design system & component library for SolidJS (Kobalte behavior + Tailwind glass tokens + motion).",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -45,6 +45,11 @@
45
45
  "import": "./dist/commerce.js",
46
46
  "default": "./dist/commerce.js"
47
47
  },
48
+ "./charts": {
49
+ "types": "./dist/charts/index.d.ts",
50
+ "import": "./dist/charts.js",
51
+ "default": "./dist/charts.js"
52
+ },
48
53
  "./preset": {
49
54
  "import": "./preset.js",
50
55
  "default": "./preset.js"
@@ -1,173 +0,0 @@
1
- import { spread as g, mergeProps as f, insert as i, template as d, createComponent as v, effect as h, setAttribute as x, className as y, delegateEvents as E } from "solid-js/web";
2
- import { splitProps as m, createSignal as S, Show as L, For as p } from "solid-js";
3
- import { Star as C } from "lucide-solid";
4
- import { clsx as B } from "clsx";
5
- import { twMerge as R } from "tailwind-merge";
6
- function c(...e) {
7
- return R(B(e));
8
- }
9
- var T = /* @__PURE__ */ d("<span>");
10
- const D = {
11
- neutral: "bg-muted text-muted-foreground ring-border",
12
- success: "bg-emerald-500/15 text-emerald-600 ring-emerald-500/30",
13
- warning: "bg-amber-500/15 text-amber-600 ring-amber-500/30",
14
- danger: "bg-rose-500/15 text-rose-600 ring-rose-500/30",
15
- info: "bg-sky-500/15 text-sky-600 ring-sky-500/30"
16
- }, N = "badge inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-xs font-semibold ring-1 ring-inset whitespace-nowrap";
17
- function K(e) {
18
- const [r, n] = m(e, ["tone", "class", "children"]);
19
- return (() => {
20
- var t = T();
21
- return g(t, f({
22
- get class() {
23
- return c(N, D[r.tone ?? "neutral"], r.class);
24
- }
25
- }, n), !1, !0), i(t, () => r.children), t;
26
- })();
27
- }
28
- var M = /* @__PURE__ */ d("<button>");
29
- const G = {
30
- primary: "bg-primary text-primary-foreground hover:bg-primary/90",
31
- secondary: "bg-muted text-foreground hover:bg-muted/70",
32
- outline: "border border-border bg-transparent text-foreground hover:bg-muted",
33
- ghost: "bg-transparent text-foreground hover:bg-muted"
34
- }, H = "inline-flex items-center justify-center rounded-md px-3 py-2 text-sm font-medium transition-[color,background-color,transform] duration-150 active:scale-[0.97] focus:outline-none focus:ring-2 focus:ring-ring disabled:pointer-events-none disabled:opacity-50";
35
- function Q(e) {
36
- const [r, n] = m(e, ["variant", "class", "type", "children"]);
37
- return (() => {
38
- var t = M();
39
- return g(t, f({
40
- get type() {
41
- return r.type ?? "button";
42
- },
43
- get class() {
44
- return c(H, G[r.variant ?? "primary"], r.class);
45
- }
46
- }, n), !1, !0), i(t, () => r.children), t;
47
- })();
48
- }
49
- var $ = /* @__PURE__ */ d("<div>"), O = /* @__PURE__ */ d("<h2>");
50
- function W(e) {
51
- const [r, n] = m(e, ["class", "children", "glass", "glow"]), t = () => (r.glow ?? r.glass) === !0;
52
- return (() => {
53
- var u = $();
54
- return g(u, f({
55
- get class() {
56
- return c(r.glass ? "card rounded-xl text-card-foreground" : "rounded-xl border border-border bg-card text-card-foreground shadow-sm", t() && "glow-edge", r.class);
57
- }
58
- }, n), !1, !0), i(u, () => r.children), u;
59
- })();
60
- }
61
- function X(e) {
62
- const [r, n] = m(e, ["class", "children"]);
63
- return (() => {
64
- var t = $();
65
- return g(t, f({
66
- get class() {
67
- return c("flex flex-col space-y-1.5 p-6", r.class);
68
- }
69
- }, n), !1, !0), i(t, () => r.children), t;
70
- })();
71
- }
72
- function Y(e) {
73
- const [r, n] = m(e, ["class", "children"]);
74
- return (() => {
75
- var t = O();
76
- return g(t, f({
77
- get class() {
78
- return c("text-lg font-semibold leading-none tracking-tight", r.class);
79
- }
80
- }, n), !1, !0), i(t, () => r.children), t;
81
- })();
82
- }
83
- function Z(e) {
84
- const [r, n] = m(e, ["class", "children"]);
85
- return (() => {
86
- var t = $();
87
- return g(t, f({
88
- get class() {
89
- return c("p-6 pt-0", r.class);
90
- }
91
- }, n), !1, !0), i(t, () => r.children), t;
92
- })();
93
- }
94
- var P = /* @__PURE__ */ d("<div role=radiogroup>"), U = /* @__PURE__ */ d("<div role=img>"), j = /* @__PURE__ */ d('<button type=button role=radio class="rounded outline-none focus-visible:ring-2 focus-visible:ring-ring/40">');
95
- function ee(e) {
96
- const [r, n] = S(0), t = () => e.max ?? 5, u = () => Array.from({
97
- length: t()
98
- }, (o, a) => a + 1), A = () => r() > 0 ? r() : e.value, b = (o) => {
99
- var a;
100
- e.readonly || (a = e.onChange) == null || a.call(e, o);
101
- }, w = (o) => c("h-5 w-5 transition-colors", o <= A() ? "fill-primary text-primary" : "fill-transparent text-muted-foreground");
102
- return v(L, {
103
- get when() {
104
- return !e.readonly;
105
- },
106
- get fallback() {
107
- return (() => {
108
- var o = U();
109
- return i(o, v(p, {
110
- get each() {
111
- return u();
112
- },
113
- children: (a) => v(C, {
114
- get class() {
115
- return w(a);
116
- },
117
- "aria-hidden": "true"
118
- })
119
- })), h((a) => {
120
- var s = c("inline-flex items-center gap-1", e.class), l = `Rating ${e.value} of ${t()}`;
121
- return s !== a.e && y(o, a.e = s), l !== a.t && x(o, "aria-label", a.t = l), a;
122
- }, {
123
- e: void 0,
124
- t: void 0
125
- }), o;
126
- })();
127
- },
128
- get children() {
129
- var o = P();
130
- return o.addEventListener("mouseleave", () => n(0)), i(o, v(p, {
131
- get each() {
132
- return u();
133
- },
134
- children: (a) => (() => {
135
- var s = j();
136
- return s.$$keydown = (l) => {
137
- l.key === "ArrowRight" || l.key === "ArrowUp" ? (l.preventDefault(), b(Math.min(e.value + 1, t()))) : (l.key === "ArrowLeft" || l.key === "ArrowDown") && (l.preventDefault(), b(Math.max(e.value - 1, 0)));
138
- }, s.$$click = () => b(a), s.addEventListener("blur", () => n(0)), s.addEventListener("focus", () => n(a)), s.addEventListener("mouseenter", () => n(a)), i(s, v(C, {
139
- get class() {
140
- return w(a);
141
- },
142
- "aria-hidden": "true"
143
- })), h((l) => {
144
- var k = e.value === a, _ = `Rate ${a} of ${t()}`;
145
- return k !== l.e && x(s, "aria-checked", l.e = k), _ !== l.t && x(s, "aria-label", l.t = _), l;
146
- }, {
147
- e: void 0,
148
- t: void 0
149
- }), s;
150
- })()
151
- })), h(() => y(o, c("inline-flex items-center gap-1", e.class))), o;
152
- }
153
- });
154
- }
155
- E(["click", "keydown"]);
156
- var F = /* @__PURE__ */ d('<label><input type=checkbox class="h-4 w-4 rounded border-input accent-primary">');
157
- function re(e) {
158
- return (() => {
159
- var r = F(), n = r.firstChild;
160
- return n.addEventListener("change", (t) => e.onChange(t.currentTarget.checked)), i(r, () => e.label, null), h(() => y(r, c("inline-flex items-center gap-2 text-sm text-foreground", e.class))), h(() => n.checked = e.checked), r;
161
- })();
162
- }
163
- export {
164
- K as B,
165
- W as C,
166
- ee as R,
167
- Q as a,
168
- re as b,
169
- c,
170
- Z as d,
171
- X as e,
172
- Y as f
173
- };