fiboui 2.5.0 → 2.6.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.
@@ -1,8 +1,8 @@
1
1
  var A = Object.defineProperty;
2
2
  var D = (a, n, e) => n in a ? A(a, n, { enumerable: !0, configurable: !0, writable: !0, value: e }) : a[n] = e;
3
3
  var t = (a, n, e) => D(a, typeof n != "symbol" ? n + "" : n, e);
4
- import s, { useRef as T, useState as I, useEffect as L } from "react";
5
- import { at as F, au as q, ay as z, S as G } from "./client-C5fy1-Lh.js";
4
+ import s, { useRef as R, useState as I, useEffect as L } from "react";
5
+ import { at as F, au as q, ay as T, S as G } from "./client-De3cGjVE.js";
6
6
  const M = s.memo((a) => {
7
7
  const {
8
8
  text: n,
@@ -12,7 +12,7 @@ const M = s.memo((a) => {
12
12
  onHover: E,
13
13
  disabled: N,
14
14
  icon: S,
15
- shape: m,
15
+ shape: b,
16
16
  shadow: h,
17
17
  tone: v,
18
18
  motion: B,
@@ -28,25 +28,25 @@ const M = s.memo((a) => {
28
28
  lg: "px-[32px] py-[16px] text-[17px] gap-[10px] h-[56px]"
29
29
  };
30
30
  let c = "rounded-[14px]";
31
- m === "pill" ? c = "rounded-full" : m === "square" ? c = "rounded-[12px]" : m === "rect" ? c = "rounded-[2px]" : m === "rounded" ? c = "rounded-[8px]" : m === "sharp" && (c = "rounded-none");
31
+ b === "pill" ? c = "rounded-full" : b === "square" ? c = "rounded-[12px]" : b === "rect" ? c = "rounded-[2px]" : b === "rounded" ? c = "rounded-[8px]" : b === "sharp" && (c = "rounded-none");
32
32
  const u = v === "inverse";
33
33
  let i = "";
34
34
  e === "ghost" ? i = u ? "bg-transparent text-white shadow-none border border-transparent" : "bg-transparent text-[var(--fibo-on-surface)] shadow-none border border-transparent hover:bg-[color-mix(in_srgb,var(--fibo-on-surface)_8%,transparent)]" : e === "text" ? i = u ? "bg-transparent text-white shadow-none border-none px-2" : "bg-transparent text-[var(--fibo-on-surface)] shadow-none border-none px-2 hover:bg-[color-mix(in_srgb,var(--fibo-on-surface)_8%,transparent)]" : e === "soft" ? i = "bg-[color-mix(in_srgb,var(--fibo-primary)_12%,transparent)] text-[var(--fibo-primary)] shadow-none border-none hover:bg-[color-mix(in_srgb,var(--fibo-primary)_18%,transparent)]" : e === "outline" || e === "outlined" ? i = u ? "bg-black text-white shadow-none border border-[#3b3b3b]" : "bg-transparent border-[1.5px] border-[var(--fibo-outline,rgba(0,0,0,0.12))] text-[var(--fibo-on-surface)] shadow-none hover:bg-[color-mix(in_srgb,var(--fibo-on-surface)_6%,transparent)]" : e === "solid" ? i = u ? "bg-[#f2f2f2] text-black shadow-none border border-[#f2f2f2]" : "bg-[var(--fibo-primary)] text-[var(--fibo-on-primary)] shadow-none border-none hover:opacity-90" : e === "filled" || e === "primary" ? i = "bg-[var(--fibo-primary)] text-[var(--fibo-on-primary)] shadow-sm border-none hover:opacity-90 active:opacity-100" : e === "elevated" ? i = "bg-[var(--fibo-surface)] text-[var(--fibo-primary)] shadow-md border-none hover:shadow-lg" : e === "tonal" ? i = "bg-[var(--fibo-secondary-container)] text-[var(--fibo-on-secondary-container)] shadow-sm border-none" : e === "raw" && (i = "bg-transparent border-none shadow-none p-0 h-auto gap-0 text-inherit font-inherit hover:bg-transparent", c = ""), h === "soft" && e !== "raw" && (i += " shadow-[0_8px_20px_-6px_rgba(59,130,246,0.4)]");
35
- const f = g || {}, b = f.padding !== void 0 || f.paddingTop !== void 0 || f.paddingBottom !== void 0 || f.paddingLeft !== void 0 || f.paddingRight !== void 0 || f.fontSize !== void 0 || f.height !== void 0, r = f.borderRadius !== void 0, l = f.fontWeight !== void 0 || d === "xs" || u, y = e === "raw" || B === "none" || u || d === "xs", C = z(
35
+ const f = g || {}, m = f.padding !== void 0 || f.paddingTop !== void 0 || f.paddingBottom !== void 0 || f.paddingLeft !== void 0 || f.paddingRight !== void 0 || f.fontSize !== void 0 || f.height !== void 0, r = f.borderRadius !== void 0, l = f.fontWeight !== void 0 || d === "xs" || u, y = e === "raw" || B === "none" || u || d === "xs", C = T(
36
36
  "fibo-button",
37
37
  "inline-flex items-center justify-center whitespace-nowrap",
38
38
  l ? "" : "font-semibold",
39
39
  // Resting scale(1) so active:scale eases instead of snapping from none.
40
40
  y ? "" : "scale-100 active:scale-[0.96] transform transition-transform duration-200 ease-out",
41
41
  N ? "cursor-not-allowed opacity-60" : "cursor-pointer",
42
- e === "raw" || b ? "" : x[d],
42
+ e === "raw" || m ? "" : x[d],
43
43
  e === "raw" || r ? "" : c,
44
44
  k ? "flex-1 w-full" : "",
45
45
  `fibo-button-${e}`,
46
46
  i,
47
47
  w
48
- ), R = [];
49
- return S && R.push(S), n && R.push(n), a.children && (Array.isArray(a.children) ? R.push(...a.children) : R.push(a.children)), s.createElement(
48
+ ), z = [];
49
+ return S && z.push(S), n && z.push(n), a.children && (Array.isArray(a.children) ? z.push(...a.children) : z.push(a.children)), s.createElement(
50
50
  "button",
51
51
  {
52
52
  className: C,
@@ -69,7 +69,7 @@ const M = s.memo((a) => {
69
69
  type: _,
70
70
  style: f
71
71
  },
72
- ...R
72
+ ...z
73
73
  );
74
74
  });
75
75
  class $ extends q {
@@ -130,9 +130,13 @@ class $ extends q {
130
130
  return this._expand = e, this;
131
131
  }
132
132
  /**
133
- * HTML button type. Named `htmlType` because builders already expose React's
134
- * element `.type` (stampRenderable) — that property must stay the component.
133
+ * HTML button type. `.type('submit')` is what people write inside a Form.
134
+ * React still reads `element.type` as the component: a string sets this,
135
+ * a props object renders the button.
135
136
  */
137
+ type(e) {
138
+ return this._htmlType = e, this;
139
+ }
136
140
  htmlType(e) {
137
141
  return this._htmlType = e, this;
138
142
  }
@@ -176,12 +180,12 @@ const Z = F($), j = s.memo((a) => {
176
180
  disabled: E,
177
181
  name: N,
178
182
  value: S = "on",
179
- rules: m,
183
+ rules: b,
180
184
  error: h,
181
185
  className: v,
182
186
  style: B,
183
187
  id: k
184
- } = a, w = T(null), g = T(null), _ = n, [o, x] = I(_), c = e ? !!n : o;
188
+ } = a, w = R(null), g = R(null), _ = n, [o, x] = I(_), c = e ? !!n : o;
185
189
  L(() => {
186
190
  if (e) return;
187
191
  const r = w.current;
@@ -197,24 +201,24 @@ const Z = F($), j = s.memo((a) => {
197
201
  }, [e]), L(() => {
198
202
  const r = w.current, l = g.current;
199
203
  if (!r) return;
200
- m && (r.__fiboRules = m);
204
+ b && (r.__fiboRules = b);
201
205
  const y = l == null ? void 0 : l.querySelector(".fibo-field-error");
202
206
  l && (l.__fiboShowError = (C) => {
203
207
  y && (y.textContent = C ?? "", y.style.display = C ? "" : "none");
204
208
  });
205
- }, [m]);
209
+ }, [b]);
206
210
  const u = (r) => {
207
211
  if (E) return;
208
212
  const l = r.target.checked;
209
213
  e || x(l), d == null || d(l);
210
- }, i = z(
214
+ }, i = T(
211
215
  "fibo-switch-track w-[44px] h-[24px] rounded-full relative transition-colors duration-200 ease-in-out",
212
216
  E ? "cursor-not-allowed opacity-50" : "cursor-pointer",
213
217
  c ? "bg-[var(--fibo-primary,#3B82F6)]" : "bg-gray-200"
214
- ), f = z(
218
+ ), f = T(
215
219
  "absolute w-5 h-5 rounded-full bg-white top-[2px] left-[2px] transition-transform duration-200 ease-in-out shadow-sm",
216
220
  c ? "translate-x-[20px]" : "translate-x-0"
217
- ), b = {
221
+ ), m = {
218
222
  ref: w,
219
223
  id: k,
220
224
  type: "checkbox",
@@ -225,11 +229,11 @@ const Z = F($), j = s.memo((a) => {
225
229
  className: "sr-only",
226
230
  onChange: u
227
231
  };
228
- return e ? b.checked = !!n : b.defaultChecked = _, s.createElement(
232
+ return e ? m.checked = !!n : m.defaultChecked = _, s.createElement(
229
233
  "div",
230
234
  {
231
235
  ref: g,
232
- className: z("fibo-switch-container", v)
236
+ className: T("fibo-switch-container", v)
233
237
  },
234
238
  s.createElement(
235
239
  "label",
@@ -250,7 +254,7 @@ const Z = F($), j = s.memo((a) => {
250
254
  { className: "text-sm font-medium text-gray-700 select-none" },
251
255
  p
252
256
  ),
253
- s.createElement("input", b)
257
+ s.createElement("input", m)
254
258
  ),
255
259
  s.createElement(
256
260
  "span",
@@ -335,8 +339,8 @@ const ee = F(W), J = s.memo((a) => {
335
339
  name: E,
336
340
  direction: N,
337
341
  className: S,
338
- style: m
339
- } = a, h = T(null), v = s.useId(), B = E || v, k = n, [w, g] = I(k), _ = e ? n : w;
342
+ style: b
343
+ } = a, h = R(null), v = s.useId(), B = E || v, k = n, [w, g] = I(k), _ = e ? n : w;
340
344
  return L(() => {
341
345
  if (e) return;
342
346
  const o = h.current;
@@ -357,14 +361,14 @@ const ee = F(W), J = s.memo((a) => {
357
361
  {
358
362
  ref: h,
359
363
  role: "radiogroup",
360
- className: z(
364
+ className: T(
361
365
  `fibo-radio-group flex ${N === "vertical" ? "flex-col gap-2" : "flex-row gap-4"}`,
362
366
  S
363
367
  ),
364
- style: m
368
+ style: b
365
369
  },
366
370
  d.map((o) => {
367
- const x = _ === o.value, c = o.disabled, u = z(
371
+ const x = _ === o.value, c = o.disabled, u = T(
368
372
  "relative flex items-center justify-center w-[18px] h-[18px] rounded-full transition-all duration-200",
369
373
  x ? "border-[5px] border-[var(--fibo-primary,#3B82F6)]" : "border-2 border-gray-300"
370
374
  ), i = {
@@ -442,11 +446,11 @@ class K extends q {
442
446
  }
443
447
  }
444
448
  const te = F(K), O = s.memo((a) => {
445
- const n = s.useId(), e = a.id || n, d = T(null), p = T(!1), {
449
+ const n = s.useId(), e = a.id || n, d = R(null), p = R(!1), {
446
450
  containerClass: E,
447
451
  containerStyle: N,
448
452
  label: S,
449
- error: m,
453
+ error: b,
450
454
  value: h,
451
455
  controlled: v,
452
456
  rules: B,
@@ -465,10 +469,10 @@ const te = F(K), O = s.memo((a) => {
465
469
  const l = d.current;
466
470
  l && l.value !== r && (l.value = r);
467
471
  }), [h, _, v]), s.useEffect(() => {
468
- const b = d.current;
469
- if (!b) return;
470
- B && (b.__fiboRules = B);
471
- const r = b.closest(".fibo-textarea-container"), l = r == null ? void 0 : r.querySelector(".fibo-field-error");
472
+ const m = d.current;
473
+ if (!m) return;
474
+ B && (m.__fiboRules = B);
475
+ const r = m.closest(".fibo-textarea-container"), l = r == null ? void 0 : r.querySelector(".fibo-field-error");
472
476
  r && (r.__fiboShowError = (y) => {
473
477
  l && (l.textContent = y ?? "", l.style.display = y ? "" : "none");
474
478
  });
@@ -478,13 +482,13 @@ const te = F(K), O = s.memo((a) => {
478
482
  ref: d,
479
483
  id: e,
480
484
  className: "fibo-textarea-input w-full p-4 text-base bg-transparent outline-none relative z-10",
481
- onChange: (b) => {
482
- const r = b.target.value;
485
+ onChange: (m) => {
486
+ const r = m.target.value;
483
487
  v && c(r), _ && (p.current = !0, h.value = r, p.current = !1), k == null || k(r);
484
488
  },
485
- onBlur: (b) => {
489
+ onBlur: (m) => {
486
490
  var r;
487
- w == null || w(b.target.value), (r = g.onBlur) == null || r.call(g, b);
491
+ w == null || w(m.target.value), (r = g.onBlur) == null || r.call(g, m);
488
492
  },
489
493
  ...g
490
494
  };
@@ -506,9 +510,9 @@ const te = F(K), O = s.memo((a) => {
506
510
  {
507
511
  className: "fibo-field-error text-[var(--fibo-error,#b91c1c)] text-xs mt-1 ml-1",
508
512
  role: "alert",
509
- style: { display: m ? "" : "none" }
513
+ style: { display: b ? "" : "none" }
510
514
  },
511
- m || ""
515
+ b || ""
512
516
  )
513
517
  );
514
518
  });
@@ -576,7 +580,7 @@ class Q extends q {
576
580
  }
577
581
  build() {
578
582
  const d = {
579
- containerClass: z("fibo-textarea-container w-full", ...this._classNames),
583
+ containerClass: T("fibo-textarea-container w-full", ...this._classNames),
580
584
  containerStyle: this.getStyle(),
581
585
  label: this._label,
582
586
  error: this._error,
package/dist/index.d.ts CHANGED
@@ -153,16 +153,30 @@ export declare function ensureListId<T extends object>(item: T): ListEntity<T>;
153
153
  * Reactive list — auto-stamps a UUID `_id` on every object.
154
154
  * Use `_id` for update/remove/find; your domain fields stay free of ids.
155
155
  *
156
+ * `view('ship')` shows a subset. The full list stays in memory, so
157
+ * `view('')` shows every item again. `add` always writes to the full list.
158
+ *
156
159
  * ```ts
157
160
  * const todos = listSignal<{ title: string }>([])
158
161
  * todos.add({ title: 'Ship' }) // → { title: 'Ship', _id: '…' }
159
162
  * todos.update(todo._id, { title: 'Done' })
163
+ * todos.view('done')
164
+ * todos.view('')
160
165
  * todos.remove(todo._id)
161
166
  * ```
162
167
  */
163
168
  export declare class ListSignal<T extends object> extends Signal<ListEntity<T>[]> {
164
169
  private _$length?;
170
+ /** Full list. `.value` is this array, or a filtered slice while `view` is set. */
171
+ private _source;
172
+ private _query;
173
+ private _keys?;
165
174
  constructor(initial?: Array<T | ListEntity<T>>);
175
+ get value(): ListEntity<T>[];
176
+ /** Replaces the full list, then reapplies the current view. */
177
+ set value(next: ListEntity<T>[]);
178
+ /** Push the visible rows. An empty query shows `_source` itself. */
179
+ private publish;
166
180
  get length(): number;
167
181
  /**
168
182
  * Reactive length for plain templates:
@@ -175,9 +189,9 @@ export declare class ListSignal<T extends object> extends Signal<ListEntity<T>[]
175
189
  /** Replace the whole array (missing `_id`s are generated). */
176
190
  set(items: Array<T | ListEntity<T>>): this;
177
191
  clear(): this;
178
- /** Append items — each gets `_id` if not already set. */
192
+ /** Append items — each gets `_id` if not already set. Writes the full list. */
179
193
  add(...items: Array<T | ListEntity<T>>): this;
180
- /** Insert at index (clamped). */
194
+ /** Insert at index (clamped) in the full list. */
181
195
  insert(index: number, item: T | ListEntity<T>): this;
182
196
  /**
183
197
  * Patch by `_id` / `id` / predicate.
@@ -190,6 +204,13 @@ export declare class ListSignal<T extends object> extends Signal<ListEntity<T>[]
190
204
  remove(matcher: ListMatcher<ListEntity<T>>): this;
191
205
  delete(matcher: ListMatcher<ListEntity<T>>): this;
192
206
  find(matcher: ListMatcher<ListEntity<T>>): ListEntity<T> | undefined;
207
+ /**
208
+ * Show only rows that match `query`. The full list stays stored.
209
+ * `view('')` or `view()` shows every item again.
210
+ * `keys` limits the match to those fields (`['text']`).
211
+ */
212
+ view(query?: string, keys?: (keyof T)[]): this;
213
+ /** One-shot search. Does not change what `.value` shows. */
193
214
  search(query: string, keys?: (keyof T)[]): ListEntity<T>[];
194
215
  filter(predicate: (item: ListEntity<T>, index: number) => boolean): ListEntity<T>[];
195
216
  map<U>(fn: (item: ListEntity<T>, index: number) => U): U[];
@@ -815,8 +836,12 @@ declare abstract class FiboBuilder {
815
836
  paddingVertical(value: string | number): this;
816
837
  marginHorizontal(value: string | number): this;
817
838
  marginVertical(value: string | number): this;
839
+ /** Inline layout wins over a host that hardcodes flex on the element (Form, Scaffold). */
840
+ protected layoutStyle(patch: React$1.CSSProperties): this;
818
841
  flexDirection(direction: "row" | "column"): this;
819
- alignItems(alignment: "start" | "center" | "end" | "stretch"): this;
842
+ alignItems(alignment: "start" | "center" | "end" | "stretch" | "baseline"): this;
843
+ alignSelf(alignment: "start" | "center" | "end" | "stretch" | "baseline" | "auto"): this;
844
+ flexWrap(wrap: "wrap" | "nowrap" | "wrap-reverse"): this;
820
845
  /**
821
846
  * Main-axis distribution. Accepts Tailwind shortcuts (`between`) and CSS/Flutter
822
847
  * names (`space-between` / `spaceBetween`).
@@ -5709,11 +5734,14 @@ export declare const Row: () => RowBuilder & LogicalAxes & {
5709
5734
  declare class SpacerBuilder extends FiboBuilder {
5710
5735
  private _height?;
5711
5736
  private _width?;
5712
- private _direction?;
5737
+ private _grow?;
5738
+ private _expand?;
5713
5739
  height(value: string | number): this;
5714
5740
  width(value: string | number): this;
5715
5741
  vertical(): this;
5716
5742
  horizontal(): this;
5743
+ /** Grow factor inside a Row or Column. Does not turn the spacer into a flex container. */
5744
+ flex(value?: number | string): this;
5717
5745
  build(): React$1.ReactElement;
5718
5746
  }
5719
5747
  export declare const Spacer: () => SpacerBuilder & LogicalAxes & {
@@ -23240,9 +23268,11 @@ declare class ButtonBuilder extends FiboBuilder {
23240
23268
  motion(value: ButtonMotion): this;
23241
23269
  expand(value?: boolean): this;
23242
23270
  /**
23243
- * HTML button type. Named `htmlType` because builders already expose React's
23244
- * element `.type` (stampRenderable) — that property must stay the component.
23271
+ * HTML button type. `.type('submit')` is what people write inside a Form.
23272
+ * React still reads `element.type` as the component: a string sets this,
23273
+ * a props object renders the button.
23245
23274
  */
23275
+ type(value: "button" | "submit" | "reset"): this;
23246
23276
  htmlType(value: "button" | "submit" | "reset"): this;
23247
23277
  /** Shortcut for `.htmlType('submit')` inside a `Form`. */
23248
23278
  submit(): this;