@base-framework/ui 1.2.3 → 1.2.4

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.
@@ -1,7 +1,8 @@
1
- import { Span as c, Div as o, Legend as f, Fieldset as x, H4 as C, P as h, UseParent as u, Input as y } from "@base-framework/atoms";
2
- import { Atom as s, Html as p } from "@base-framework/base";
3
- import { f as d, g as k, h as w, i as $ } from "./image-T4fJLqgd.js";
4
- const a = {
1
+ import { Span as d, Div as n, Legend as h, Fieldset as p, H4 as y, P as k, UseParent as b, Input as w } from "@base-framework/atoms";
2
+ import { Atom as s, Html as $ } from "@base-framework/base";
3
+ import { U as v } from "./buttons-DthWscX3.js";
4
+ import { f as m, g as P, h as S, i as E } from "./image-T4fJLqgd.js";
5
+ const g = {
5
6
  gray: {
6
7
  backgroundColor: "bg-gray-50",
7
8
  textColor: "text-gray-600",
@@ -76,58 +77,66 @@ const a = {
76
77
  backgroundColor: "bg-background",
77
78
  textColor: "text-primary",
78
79
  ringColor: "ring-background"
80
+ },
81
+ blur: {
82
+ backgroundColor: "bg-background/40 backdrop-blur-sm",
83
+ textColor: "text-foreground",
84
+ ringColor: "ring-white/10"
79
85
  }
80
- }, v = (r) => a[r] || a.gray, P = (r) => {
81
- const { backgroundColor: e, textColor: t, ringColor: l } = v(r);
82
- return `inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors ${e} ${t} ${l}`;
83
- }, L = s((r, e) => {
84
- const t = P(r?.type);
85
- return c({ ...r, class: t }, e);
86
- }), G = s((r, e) => {
87
- const t = r.margin ?? "my-5 mx-5", l = r.padding ?? "p-4", n = r.border ?? "border-border";
88
- return r.hover && (r.class += " hover:shadow-lg hover:bg-muted/50"), o({
86
+ }, B = (r) => g[r] || g.gray, F = (r, e = {}) => {
87
+ const t = B(r), o = e.backgroundColor ?? t.backgroundColor, l = e.textColor ?? t.textColor, a = e.ringColor ?? t.ringColor;
88
+ return `inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors ${o} ${l} ${a}`;
89
+ }, U = s((r, e) => {
90
+ const { type: t, icon: o, size: l = "xs", backgroundColor: a, textColor: i, ringColor: f, ...x } = r, C = F(t, { backgroundColor: a, textColor: i, ringColor: f });
91
+ return d({ ...x, class: C }, [
92
+ o ? v({ size: l, class: "mr-1" }, o) : null,
93
+ ...e || []
94
+ ]);
95
+ }), V = s((r, e) => {
96
+ const t = r.margin ?? "my-5 mx-5", o = r.padding ?? "p-4", l = r.border ?? "border-border";
97
+ return r.hover && (r.class += " hover:shadow-lg hover:bg-muted/50"), n({
89
98
  ...r,
90
99
  // @ts-ignore
91
- class: `rounded-lg ${n} bg-card text-card-foreground shadow-md min-w-[120px] min-h-[80px] ${t} ${l} ${r.class || ""}`
100
+ class: `rounded-lg ${l} bg-card text-card-foreground shadow-md min-w-[120px] min-h-[80px] ${t} ${o} ${r.class || ""}`
92
101
  }, e);
93
- }), S = s((r, e) => f({
102
+ }), N = s((r, e) => h({
94
103
  ...r,
95
104
  // @ts-ignore
96
105
  class: ` font-medium -mt-4 -mx-1 px-2 py-2 ${r.class || ""}`
97
- }, e)), I = s((r, e) => {
106
+ }, e)), _ = s((r, e) => {
98
107
  const t = r.border === "full" ? "border rounded-md" : "border-t";
99
- return x({
108
+ return p({
100
109
  ...r,
101
110
  // @ts-ignore
102
111
  class: `p-6 ${t} ${r.class || ""}`
103
112
  }, [
104
113
  // @ts-ignore
105
- r.legend && S(r.legend),
106
- o({ class: "flex flex-auto flex-col gap-y-6" }, e)
114
+ r.legend && N(r.legend),
115
+ n({ class: "flex flex-auto flex-col gap-y-6" }, e)
107
116
  ]);
108
- }), R = s((r, e) => {
117
+ }), z = s((r, e) => {
109
118
  const t = r.border === !0 ? "border-t" : "";
110
- return o({
119
+ return n({
111
120
  ...r,
112
121
  // @ts-ignore
113
122
  class: `grid grid-cols-1 gap-y-4 sm:grid-cols-[1fr_2fr] sm:gap-x-6 pt-8 ${t} ${r.class || ""}`
114
123
  }, [
115
124
  // @ts-ignore
116
- r.label && o({
125
+ r.label && n({
117
126
  // @ts-ignore
118
127
  ...r.labelProps,
119
128
  // @ts-ignore
120
129
  class: `flex flex-auto flex-col gap-y-1 ${r.labelProps?.class || ""}`
121
130
  }, [
122
131
  // @ts-ignore
123
- C({ class: "text-base" }, r.label),
132
+ y({ class: "text-base" }, r.label),
124
133
  // @ts-ignore
125
- r.description && h({ class: "text-sm text-muted-foreground" }, r.description)
134
+ r.description && k({ class: "text-sm text-muted-foreground" }, r.description)
126
135
  ]),
127
136
  // Controls container: grows to fill remaining space, spacing between items
128
- o({ class: "flex flex-col gap-y-4" }, e)
137
+ n({ class: "flex flex-col gap-y-4" }, e)
129
138
  ]);
130
- }), O = d(
139
+ }), D = m(
131
140
  {
132
141
  /**
133
142
  * This will create the initial state of the RangeSlider.
@@ -157,17 +166,17 @@ const a = {
157
166
  * @returns {object}
158
167
  */
159
168
  render() {
160
- return o({ class: "relative w-full h-4 flex items-center" }, [
169
+ return n({ class: "relative w-full h-4 flex items-center" }, [
161
170
  // Track
162
- o({ class: "absolute h-2 w-full rounded-full bg-muted" }),
163
- u(({ state: r }) => [
171
+ n({ class: "absolute h-2 w-full rounded-full bg-muted" }),
172
+ b(({ state: r }) => [
164
173
  // Filled Track
165
- o({
174
+ n({
166
175
  class: "absolute h-2 bg-primary rounded-full",
167
176
  style: ["width: [[filledPercentage]]%", r]
168
177
  }),
169
178
  // Thumb
170
- o({
179
+ n({
171
180
  class: `
172
181
  absolute block h-5 w-5 rounded-full border-2 border-primary bg-background
173
182
  ring-offset-background transition-colors focus-visible:outline-none
@@ -177,7 +186,7 @@ const a = {
177
186
  style: ["left: [[filledPercentage]]%", r]
178
187
  }),
179
188
  // Hidden Range Input
180
- y({
189
+ w({
181
190
  type: "range",
182
191
  min: ["[[min]]", r],
183
192
  max: ["[[max]]", r],
@@ -185,8 +194,8 @@ const a = {
185
194
  // Incorporate your new classes here
186
195
  class: `
187
196
  absolute w-full h-full opacity-0 cursor-pointer
188
- ${k}
189
- ${w}
197
+ ${P}
198
+ ${S}
190
199
  ${this.class || ""}
191
200
  `.trim(),
192
201
  bind: this.bind,
@@ -199,22 +208,22 @@ const a = {
199
208
  ]);
200
209
  }
201
210
  }
202
- ), V = s((r) => ({
211
+ ), H = s((r) => ({
203
212
  tag: "select",
204
213
  onCreated(e) {
205
- r.options && p.setupSelectOptions(e, r.options);
214
+ r.options && $.setupSelectOptions(e, r.options);
206
215
  },
207
216
  ...r,
208
217
  // @ts-ignore
209
- class: `${$} ${r.class || ""}`.trim()
210
- })), E = (r) => !r || isNaN(r) ? null : r, i = (r, e) => {
211
- const t = r, l = 16, n = 2 * Math.PI * l, b = t / 100 * n, m = `
218
+ class: `${E} ${r.class || ""}`.trim()
219
+ })), A = (r) => !r || isNaN(r) ? null : r, c = (r, e) => {
220
+ const t = r, o = 16, l = 2 * Math.PI * o, a = t / 100 * l, i = `
212
221
  <svg class="w-40 h-40 mx-auto" viewBox="0 0 36 36" xmlns="http://www.w3.org/2000/svg">
213
222
  <!-- Background Circle -->
214
223
  <circle
215
224
  cx="18"
216
225
  cy="18"
217
- r="${l}"
226
+ r="${o}"
218
227
  fill="none"
219
228
  stroke="currentColor"
220
229
  stroke-width="4"
@@ -225,13 +234,13 @@ const a = {
225
234
  <circle
226
235
  cx="18"
227
236
  cy="18"
228
- r="${l}"
237
+ r="${o}"
229
238
  fill="none"
230
239
  stroke="currentColor"
231
240
  stroke-width="4"
232
241
  class="stroke-primary"
233
- stroke-dasharray="${n}"
234
- stroke-dashoffset="${n - b}"
242
+ stroke-dasharray="${l}"
243
+ stroke-dashoffset="${l - a}"
235
244
  stroke-linecap="round"
236
245
  class="${e}"
237
246
  />
@@ -246,24 +255,24 @@ const a = {
246
255
  </text>
247
256
  </svg>
248
257
  `;
249
- return o({
258
+ return n({
250
259
  class: "circle-graph text-inherit",
251
- html: m
260
+ html: i
252
261
  });
253
- }, _ = s((r) => {
254
- const e = r.progress || 0, t = r.class || "", l = i(e, t);
255
- return o({
262
+ }, M = s((r) => {
263
+ const e = r.progress || 0, t = r.class || "", o = c(e, t);
264
+ return n({
256
265
  class: "circle-graph-wrap",
257
266
  onSet: [
258
267
  // @ts-ignore
259
268
  r.prop,
260
- (n) => (n = E(n), n ? i(n, t) : l)
269
+ (l) => (l = A(l), l ? c(l, t) : o)
261
270
  ]
262
- }, [l]);
263
- }), B = () => u(({ state: r }) => o({
271
+ }, [o]);
272
+ }), T = () => b(({ state: r }) => n({
264
273
  class: "absolute h-full rounded-full bg-primary transition-all duration-300",
265
274
  style: ["width: [[progress]]%;", r]
266
- })), D = d(
275
+ })), J = m(
267
276
  {
268
277
  /**
269
278
  * This will render the progress bar component.
@@ -271,8 +280,8 @@ const a = {
271
280
  * @returns {object}
272
281
  */
273
282
  render() {
274
- return o({ class: "relative w-full h-4 rounded-full bg-muted" }, [
275
- B()
283
+ return n({ class: "relative w-full h-4 rounded-full bg-muted" }, [
284
+ T()
276
285
  ]);
277
286
  },
278
287
  /**
@@ -315,7 +324,7 @@ const a = {
315
324
  r < 0 && (r = 0), r > 100 && (r = 100), this.state.progress = r;
316
325
  }
317
326
  }
318
- ), g = {
327
+ ), u = {
319
328
  top: "bottom-full left-1/2 transform -translate-x-1/2 mb-2",
320
329
  "top-right": "bottom-full left-full transform -translate-x-1 mb-2",
321
330
  "top-left": "bottom-full right-full transform translate-x-1 mb-2",
@@ -324,28 +333,28 @@ const a = {
324
333
  "bottom-left": "top-full right-full transform translate-x-1 mt-2",
325
334
  left: "top-1/2 right-full transform -translate-y-1/2 mr-2",
326
335
  right: "top-1/2 left-full transform -translate-y-1/2 ml-2"
327
- }, F = (r) => g[String(r)] || g.top, H = s(({ position: r = "top", content: e }, t) => {
328
- const l = F(r);
329
- return Array.isArray(t) === !1 && (t = [t]), o({ class: "relative group inline-block" }, [
336
+ }, I = (r) => u[String(r)] || u.top, Y = s(({ position: r = "top", content: e }, t) => {
337
+ const o = I(r);
338
+ return Array.isArray(t) === !1 && (t = [t]), n({ class: "relative group inline-block" }, [
330
339
  ...t,
331
340
  // Tooltip box
332
- c({
341
+ d({
333
342
  class: `
334
343
  absolute z-20 px-2 py-1 border text-sm bg-background rounded shadow-md opacity-0 whitespace-nowrap
335
- group-hover:opacity-100 transition-opacity duration-200 ${l} pointer-events-none
344
+ group-hover:opacity-100 transition-opacity duration-200 ${o} pointer-events-none
336
345
  `
337
346
  }, e)
338
347
  ]);
339
348
  });
340
349
  export {
341
- L as B,
342
- G as C,
343
- I as F,
344
- S as L,
345
- D as P,
346
- O as R,
347
- V as S,
348
- H as T,
349
- _ as a,
350
- R as b
350
+ U as B,
351
+ V as C,
352
+ _ as F,
353
+ N as L,
354
+ J as P,
355
+ D as R,
356
+ H as S,
357
+ Y as T,
358
+ M as a,
359
+ z as b
351
360
  };
@@ -15,3 +15,4 @@ export default Button;
15
15
  * @returns {object}
16
16
  */
17
17
  export const LoadingButton: (...args: any[]) => object;
18
+ export { CircleButton, CircleToggleButton, ToggleButton } from "./toggle-button.js";
@@ -0,0 +1,104 @@
1
+ /**
2
+ * ToggleButton
3
+ *
4
+ * A social-action style button (like, comment, share) with:
5
+ * - An icon that switches between inactive/active states on click
6
+ * - An optional value/count displayed alongside the icon
7
+ * - Reactive value support via `dataKey` to watch a parent data property
8
+ * - A `toggle` callback called with the new boolean state on each click
9
+ *
10
+ * @example
11
+ * // Static value
12
+ * new ToggleButton({ icon: Icons.heart, activeIcon: Icons.heartSolid, value: 234, toggle: (active) => {} })
13
+ *
14
+ * // Reactive value from parent data (watches `likeCount` key)
15
+ * new ToggleButton({ icon: Icons.heart, dataKey: 'likeCount', toggle: (active) => {} })
16
+ */
17
+ export class ToggleButton extends Component {
18
+ /** @type {string|null} SVG icon string for the inactive state */
19
+ icon: string | null;
20
+ /** @type {string|null} SVG icon string for the active state. Falls back to `icon` when not set. */
21
+ activeIcon: string | null;
22
+ /** @type {string|number|null} Static count/value displayed next to the icon */
23
+ value: string | number | null;
24
+ /** @type {string|null} Data key to reactively watch for the displayed value */
25
+ dataKey: string | null;
26
+ /** @type {boolean} Initial active state */
27
+ active: boolean;
28
+ /** @type {Function|null} Called with the new boolean active state after each toggle */
29
+ toggle: Function | null;
30
+ /** @type {string} Icon size: xs | sm | md | lg */
31
+ size: string;
32
+ /**
33
+ * Set up internal states.
34
+ *
35
+ * @returns {object}
36
+ */
37
+ setupStates(): object;
38
+ /**
39
+ * Toggle the active state and fire the callback.
40
+ *
41
+ * @returns {void}
42
+ */
43
+ handleToggle(): void;
44
+ /**
45
+ * Render the toggle button.
46
+ *
47
+ * @returns {object}
48
+ */
49
+ render(): object;
50
+ }
51
+ /**
52
+ * CircleToggleButton
53
+ *
54
+ * A circular blur/tint button like the overlay controls in image viewers or media players.
55
+ * Defaults to `bg-background/40 backdrop-blur-sm text-foreground`.
56
+ * When active, applies the `activeClass` you supply (e.g. `bg-background text-foreground`).
57
+ *
58
+ * @example
59
+ * new CircleToggleButton({ icon: Icons.heart, size: 'md', activeClass: 'bg-background', toggle: (active) => {} })
60
+ * new CircleToggleButton({ icon: Icons.arrows.left, size: 'md' })
61
+ */
62
+ export class CircleToggleButton extends Component {
63
+ /** @type {string|null} Icon for inactive state */
64
+ icon: string | null;
65
+ /** @type {string|null} Icon for active state — falls back to `icon` */
66
+ activeIcon: string | null;
67
+ /** @type {boolean} Initial active state */
68
+ active: boolean;
69
+ /** @type {string} Size token: xs | sm | md | lg | xl | 2xl */
70
+ size: string;
71
+ /** @type {string} Extra Tailwind classes applied when active */
72
+ activeClass: string;
73
+ /** @type {Function|null} Called with the new boolean state on each click */
74
+ toggle: Function | null;
75
+ /**
76
+ * Set up internal states.
77
+ *
78
+ * @returns {object}
79
+ */
80
+ setupStates(): object;
81
+ /**
82
+ * Toggle active state and fire callback.
83
+ *
84
+ * @returns {void}
85
+ */
86
+ handleToggle(): void;
87
+ /**
88
+ * Render the circular toggle button.
89
+ *
90
+ * @returns {object}
91
+ */
92
+ render(): object;
93
+ }
94
+ /**
95
+ * CircleButton
96
+ *
97
+ * A non-toggling circular blur/tint button (e.g. back, share, menu).
98
+ * Same visual style as CircleToggleButton without the toggle state.
99
+ *
100
+ * @example
101
+ * CircleButton({ icon: Icons.arrows.left, size: 'md', click: () => {} })
102
+ */
103
+ export const CircleButton: (...args: any[]) => object;
104
+ import { Component } from '@base-framework/base';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@base-framework/ui",
3
- "version": "1.2.3",
3
+ "version": "1.2.4",
4
4
  "description": "This is a UI package that adds components and atoms that use Tailwind CSS and a theme based on Shadcn.",
5
5
  "main": "./dist/index.es.js",
6
6
  "scripts": {
@@ -1,138 +0,0 @@
1
- import { I as y, Span as v, Button as o } from "@base-framework/atoms";
2
- import { Atom as i } from "@base-framework/base";
3
- import { Icons as b } from "./icons.es.js";
4
- const z = {
5
- xs: "w-4 h-4",
6
- sm: "w-6 h-6",
7
- md: "w-8 h-8",
8
- lg: "w-10 h-10",
9
- xl: "w-12 h-12",
10
- "2xl": "w-14 h-14",
11
- "3xl": "w-16 h-16"
12
- }, r = i((n, s) => {
13
- const t = z[n.size || "sm"];
14
- return y({
15
- ...n,
16
- // @ts-ignore
17
- class: `stroke-current icon-size ${t} ${n.class || ""}`,
18
- html: s[0]?.textContent
19
- });
20
- }), u = {
21
- xs: "w-4 h-4",
22
- // 16px - matches Icon
23
- sm: "w-6 h-6",
24
- // 24px - matches Icon
25
- md: "w-8 h-8",
26
- // 32px - matches Icon
27
- lg: "w-10 h-10",
28
- // 40px - matches Icon
29
- xl: "w-12 h-12",
30
- // 48px - matches Icon
31
- "2xl": "w-14 h-14",
32
- // 56px - matches Icon
33
- "3xl": "w-16 h-16"
34
- // 64px - matches Icon
35
- }, m = {
36
- xs: "16px",
37
- sm: "24px",
38
- md: "32px",
39
- lg: "40px",
40
- xl: "48px",
41
- "2xl": "56px",
42
- "3xl": "64px"
43
- }, d = {
44
- outlined: "material-symbols-outlined",
45
- filled: "material-symbols-filled",
46
- rounded: "material-symbols-rounded",
47
- sharp: "material-symbols-sharp"
48
- }, f = i((n) => {
49
- const s = n.size || "sm", t = n.variant || "outlined", l = u[s] || u.sm, a = m[s] || m.sm, w = d[t] || d.outlined;
50
- return v({
51
- ...n,
52
- // @ts-ignore
53
- class: `inline-flex items-center justify-center ${w} ${l} ${n.class || ""}`,
54
- // @ts-ignore
55
- style: `font-size: ${a}; ${n.style || ""}`,
56
- // Remove props that shouldn't be passed to the DOM element
57
- size: void 0,
58
- variant: void 0,
59
- name: void 0
60
- // @ts-ignore
61
- }, n.name);
62
- }), c = (n = {}, s) => s ? typeof s == "string" && s.includes("<svg") ? r(n, s) : typeof s == "object" && s.name ? f({
63
- ...n,
64
- name: s.name,
65
- variant: s.variant || n.variant || "outlined"
66
- }) : typeof s == "string" ? f({
67
- ...n,
68
- name: s
69
- }) : r(n, s) : null, U = (n) => n ? !!(typeof n == "object" && n.name || typeof n == "string" && !n.includes("<svg")) : !1, j = (n) => typeof n == "string" && n.includes("<svg"), e = (n) => i((s, t) => o({
70
- ...n,
71
- ...s,
72
- // @ts-ignore
73
- class: `bttn ${n.class} ${s.class || ""}`
74
- }, t)), x = i(
75
- (n, s) => o({
76
- ...n,
77
- // @ts-ignore
78
- class: n.class
79
- }, [
80
- // @ts-ignore
81
- n.icon && n.position !== "right" ? c({ size: n.size || "sm", class: n.animation ?? null }, n.icon) : null,
82
- ...s || [],
83
- // @ts-ignore
84
- n.icon && n.position === "right" ? c({ size: n.size || "sm", class: n.animation ?? null }, n.icon) : null
85
- ])
86
- ), h = (n) => i((s, t) => x({
87
- ...n,
88
- ...s,
89
- // @ts-ignore
90
- class: `bttn ${n.class} ${s.class || ""}`
91
- }, t)), k = (n) => () => {
92
- if (n.allowHistory === !0 && globalThis.history.length > 2) {
93
- globalThis.history.back();
94
- return;
95
- }
96
- n.backUrl && app.navigate(n.backUrl);
97
- }, $ = (n) => i((s, t) => (s.icon = s.icon || b.arrows.left, s.click = s.click || k(s), x({
98
- ...n,
99
- ...s
100
- }, t))), I = i((n, s) => {
101
- const t = n.size || "md", l = {
102
- xs: "w-6 h-6",
103
- sm: "w-8 h-8",
104
- md: "w-10 h-10",
105
- lg: "w-12 h-12",
106
- xl: "w-14 h-14"
107
- }, a = n.backgroundClass || "bg-background/30 hover:bg-background/50";
108
- return o({
109
- ...n,
110
- // @ts-ignore
111
- class: `circle-icon-btn inline-flex items-center justify-center rounded-full ${a} text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring ring-offset-background transition-colors disabled:pointer-events-none disabled:opacity-50 cursor-pointer ${l[t] || l.md} ${n.class || ""}`
112
- }, [
113
- // @ts-ignore
114
- n.icon ? c({ size: t === "xs" ? "xs" : "sm" }, n.icon) : null,
115
- ...s || []
116
- ]);
117
- }), g = {
118
- primary: e({ class: "primary" }),
119
- secondary: e({ class: "secondary" }),
120
- destructive: e({ class: "destructive" }),
121
- warning: e({ class: "warning" }),
122
- outline: e({ class: "outline" }),
123
- ghost: e({ class: "ghost" }),
124
- link: e({ class: "link" }),
125
- icon: h({ class: "icon" }),
126
- withIcon: h({ class: "with-icon" }),
127
- back: $({ class: "with-icon back-button" }),
128
- circleIcon: I
129
- }, B = i((n, s) => (g[n.variant] || g.primary)(n, s)), S = i((n, s) => B({ ...n, variant: "withIcon", icon: b.loading, animation: "animate-spin" }, s));
130
- export {
131
- B,
132
- r as I,
133
- S as L,
134
- f as M,
135
- c as U,
136
- U as a,
137
- j as i
138
- };