sibujs 1.0.0-beta.4 → 1.0.0-beta.6

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.
Files changed (85) hide show
  1. package/README.md +38 -31
  2. package/dist/browser.cjs +18 -6
  3. package/dist/browser.d.cts +12 -6
  4. package/dist/browser.d.ts +12 -6
  5. package/dist/browser.js +17 -440
  6. package/dist/build.cjs +68 -15
  7. package/dist/build.js +10 -8
  8. package/dist/cdn.global.js +4 -4
  9. package/dist/chunk-2X5NDXNG.js +877 -0
  10. package/dist/chunk-353KB3DI.js +271 -0
  11. package/dist/chunk-5OCBERWW.js +1094 -0
  12. package/dist/chunk-6BCDNGIH.js +1839 -0
  13. package/dist/chunk-6BDUQJ7K.js +949 -0
  14. package/dist/chunk-6DJQF4Z7.js +33 -0
  15. package/dist/chunk-AIPXZK5O.js +295 -0
  16. package/dist/chunk-BS5EYKCJ.js +26 -0
  17. package/dist/chunk-CHJ27IGK.js +26 -0
  18. package/dist/chunk-DKXVN442.js +90 -0
  19. package/dist/chunk-DZZMIMGL.js +725 -0
  20. package/dist/chunk-E6BNBVMK.js +457 -0
  21. package/dist/chunk-ESPA7SCH.js +567 -0
  22. package/dist/chunk-FDRU7W6W.js +365 -0
  23. package/dist/chunk-GVDEIJ3G.js +291 -0
  24. package/dist/chunk-HFHOFG6W.js +282 -0
  25. package/dist/chunk-HGKEBAW3.js +63 -0
  26. package/dist/chunk-HJNW3HLI.js +255 -0
  27. package/dist/chunk-HRIIH4JX.js +712 -0
  28. package/dist/chunk-JLOASJXU.js +654 -0
  29. package/dist/chunk-K5ZUMYVS.js +89 -0
  30. package/dist/chunk-K7JUDY3C.js +364 -0
  31. package/dist/chunk-KKV3DOAW.js +466 -0
  32. package/dist/chunk-MWE3PK5S.js +551 -0
  33. package/dist/chunk-MXR7LXGC.js +1084 -0
  34. package/dist/chunk-Q6XACQW3.js +1847 -0
  35. package/dist/chunk-QI6ZDDUR.js +35 -0
  36. package/dist/chunk-UKDBQVM3.js +346 -0
  37. package/dist/chunk-USPT25TC.js +365 -0
  38. package/dist/chunk-WGCQNOEQ.js +712 -0
  39. package/dist/chunk-XFW7B23S.js +282 -0
  40. package/dist/data.cjs +11 -3
  41. package/dist/data.js +26 -920
  42. package/dist/devtools.cjs +93 -8
  43. package/dist/devtools.d.cts +7 -3
  44. package/dist/devtools.d.ts +7 -3
  45. package/dist/devtools.js +38 -1046
  46. package/dist/ecosystem.cjs +14 -7
  47. package/dist/ecosystem.d.cts +2 -15
  48. package/dist/ecosystem.d.ts +2 -15
  49. package/dist/ecosystem.js +16 -356
  50. package/dist/extras.cjs +1148 -1008
  51. package/dist/extras.d.cts +15 -2356
  52. package/dist/extras.d.ts +15 -2356
  53. package/dist/extras.js +337 -4925
  54. package/dist/index.cjs +68 -15
  55. package/dist/index.d.cts +12 -8
  56. package/dist/index.d.ts +12 -8
  57. package/dist/index.js +14 -10
  58. package/dist/motion.js +21 -323
  59. package/dist/patterns.cjs +16 -5
  60. package/dist/patterns.d.cts +8 -0
  61. package/dist/patterns.d.ts +8 -0
  62. package/dist/patterns.js +15 -251
  63. package/dist/performance.js +36 -616
  64. package/dist/plugin-Bek4RhJY.d.cts +43 -0
  65. package/dist/plugin-Bek4RhJY.d.ts +43 -0
  66. package/dist/plugins.cjs +925 -41
  67. package/dist/plugins.d.cts +9 -3
  68. package/dist/plugins.d.ts +9 -3
  69. package/dist/plugins.js +109 -37
  70. package/dist/ssr-NFAIHWJJ.js +35 -0
  71. package/dist/ssr.cjs +25 -14
  72. package/dist/ssr.d.cts +209 -209
  73. package/dist/ssr.d.ts +209 -209
  74. package/dist/ssr.js +32 -685
  75. package/dist/startup-0Qv6aosO.d.cts +291 -0
  76. package/dist/startup-0Qv6aosO.d.ts +291 -0
  77. package/dist/tagFactory-D9e0QGIE.d.cts +23 -0
  78. package/dist/tagFactory-D9e0QGIE.d.ts +23 -0
  79. package/dist/ui.cjs +26 -13
  80. package/dist/ui.js +43 -826
  81. package/dist/widgets.cjs +61 -8
  82. package/dist/widgets.d.cts +3 -0
  83. package/dist/widgets.d.ts +3 -0
  84. package/dist/widgets.js +14 -531
  85. package/package.json +7 -2
package/README.md CHANGED
@@ -353,10 +353,13 @@ div({
353
353
  // Events
354
354
  on: { click: handleClick, mouseover: handleHover },
355
355
 
356
- // Ref
356
+ // Ref (reactive — works with resize(), draggable(), etc.)
357
357
  ref: myRef,
358
358
 
359
- // Any other attribute
359
+ // onElement callback — called after element creation
360
+ onElement: (el) => inputMask.bind(el),
361
+
362
+ // Any other attribute (empty strings set boolean attributes)
360
363
  "data-testid": "my-card",
361
364
  disabled: () => isDisabled(),
362
365
  });
@@ -417,10 +420,11 @@ batch(() => {
417
420
  ```ts
418
421
  import { ref, memo, memoFn, array, deepSignal, store } from "sibujs";
419
422
 
420
- // Mutable ref (non-reactive changing .current does NOT trigger updates)
421
- // Use for imperative access (focus, measure). For reactive element tracking, use signal instead.
422
- const ref = ref<HTMLElement>();
423
- ref.current; // the element
423
+ // Reactive ref — reading .current tracks, writing .current notifies
424
+ // Works with browser APIs like resize(), draggable(), dropZone()
425
+ const elRef = ref<HTMLElement>();
426
+ elRef.current; // read (tracks dependency)
427
+ elRef.current = myElement; // write (notifies subscribers)
424
428
 
425
429
  // Memoized value (alias for derived)
426
430
  const expensive = memo(() => heavyComputation(data()));
@@ -671,7 +675,7 @@ function App() {
671
675
  ${RouterLink({ to: "/", nodes: "Home" })}
672
676
  ${RouterLink({ to: "/about", nodes: "About" })}
673
677
  </nav>
674
- ${route()}
678
+ ${Route()}
675
679
  </div>`;
676
680
  }
677
681
 
@@ -751,22 +755,20 @@ can("RETRY"); // false (not in error state)
751
755
  ```ts
752
756
  import { form, required, email, minLength } from "sibujs/ui";
753
757
 
754
- const form = form({
755
- fields: {
756
- username: { initial: "", validators: [required(), minLength(3)] },
757
- email: { initial: "", validators: [required(), email()] },
758
- },
759
- onSubmit: (values) => api.register(values),
758
+ const myForm = form({
759
+ username: { initial: "", validators: [required(), minLength(3)] },
760
+ email: { initial: "", validators: [required(), email()] },
760
761
  });
761
762
 
762
763
  // Reactive getters
763
- form.fields.username.value();
764
- form.errors.username();
765
- form.isValid();
766
- form.isDirty();
764
+ myForm.fields.username.value();
765
+ myForm.fields.username.error();
766
+ myForm.isValid();
767
+ myForm.isDirty();
767
768
 
768
- // Handle submission
769
- form.handleSubmit();
769
+ // Handle submission (pass callback to handleSubmit)
770
+ const onSubmit = myForm.handleSubmit((values) => api.register(values));
771
+ // Attach to form: on: { submit: onSubmit }
770
772
  ```
771
773
 
772
774
  ### Global Store
@@ -780,7 +782,7 @@ const store = globalStore({
780
782
  increment: (state) => ({ ...state, count: state.count + 1 }),
781
783
  setUser: (state, user) => ({ ...state, user }),
782
784
  },
783
- middleware: [(action, state) => console.log(action, state)],
785
+ middleware: [(state, action, payload, next) => { console.log(action, state); next(); }],
784
786
  });
785
787
 
786
788
  store.dispatch("increment");
@@ -924,14 +926,16 @@ const disposeTitle = title(() => `(${unread()}) My App`);
924
926
  const { scheme } = colorScheme();
925
927
  scheme(); // "dark" | "light"
926
928
 
927
- // Drag and drop
928
- const { isDragging } = draggable(() => dragEl, { type: "card", id: 1 });
929
- const { isOver } = dropZone(() => dropEl, {
929
+ // Drag and drop — accepts ref or getter
930
+ const dragRef = ref<HTMLElement>();
931
+ const { isDragging } = draggable(dragRef, { type: "card", id: 1 });
932
+ const { isOver } = dropZone(dragRef, {
930
933
  onDrop: (data, event) => handleDrop(data),
931
934
  });
932
935
 
933
- // Resize observer
934
- const { width, height } = resize(() => element);
936
+ // Resize observer — accepts ref or getter
937
+ const elRef = ref<HTMLElement>();
938
+ const { width, height } = resize(elRef);
935
939
 
936
940
  // Scroll position
937
941
  const { scrollX, scrollY } = scroll();
@@ -1190,6 +1194,7 @@ tabs.activeTab(); // "general"
1190
1194
  tabs.setActiveTab("security");
1191
1195
  tabs.nextTab(); // keyboard arrow navigation
1192
1196
  tabs.prevTab();
1197
+ tabs.isActive("general"); // reactive check — safe inside each()
1193
1198
  ```
1194
1199
 
1195
1200
  ### Select
@@ -1224,6 +1229,7 @@ const accordion = accordion({
1224
1229
 
1225
1230
  accordion.toggle("faq-1");
1226
1231
  accordion.items(); // [{ id: "faq-1", label: "...", isExpanded: true }, ...]
1232
+ accordion.isExpanded("faq-1"); // reactive check — safe inside each()
1227
1233
  accordion.expandAll();
1228
1234
  accordion.collapseAll();
1229
1235
  ```
@@ -1291,6 +1297,7 @@ picker.nextMonth();
1291
1297
  picker.daysInMonth(); // [{ date, isCurrentMonth, isToday, isSelected, isDisabled }, ...]
1292
1298
  picker.select(new Date(2025, 5, 15));
1293
1299
  picker.selectedDate(); // Date
1300
+ picker.isSelected(someDate); // reactive check — safe inside each()
1294
1301
  ```
1295
1302
 
1296
1303
  ### Content Editable
@@ -1418,7 +1425,7 @@ import {
1418
1425
  startTransition,
1419
1426
  deferredValue,
1420
1427
  transitionState,
1421
- id,
1428
+ uniqueId,
1422
1429
  scheduleUpdate,
1423
1430
  yieldToMain,
1424
1431
  processInChunks,
@@ -1437,7 +1444,7 @@ const deferredQuery = deferredValue(() => query());
1437
1444
  const [isPending, startTransition] = transitionState();
1438
1445
 
1439
1446
  // Unique IDs (SSR-safe)
1440
- const id = id(); // "sibu-0"
1447
+ const myId = uniqueId(); // "sibu-0"
1441
1448
  const labelId = uniqueId("label"); // "sibu-1-label"
1442
1449
 
1443
1450
  // Priority-based scheduling
@@ -1461,7 +1468,7 @@ await processInChunks(bigArray, (item) => processItem(item), 50);
1461
1468
  import {
1462
1469
  enableDebug,
1463
1470
  debugLog,
1464
- performance,
1471
+ perfTracker,
1465
1472
  measureRender,
1466
1473
  getPerformanceReport,
1467
1474
  checkLeaks,
@@ -1474,7 +1481,7 @@ debugLog("Counter", "increment", { value: 5 });
1474
1481
  const MeasuredList = measureRender("ItemList", ItemList);
1475
1482
 
1476
1483
  // Manual performance tracking
1477
- const perf = performance("search");
1484
+ const perf = perfTracker("search");
1478
1485
  perf.startMeasure();
1479
1486
  // ... expensive operation
1480
1487
  perf.endMeasure();
@@ -1557,7 +1564,7 @@ const theme = createTheme({ colors: { primary: "#007bff" } });
1557
1564
 
1558
1565
  ---
1559
1566
 
1560
- ## Build (`sibu/build`)
1567
+ ## Build (`sibujs/build`)
1561
1568
 
1562
1569
  Bundler plugins and deployment utilities.
1563
1570
 
@@ -1575,7 +1582,7 @@ Additional build utilities: CDN deployment, type declaration generation, bundle
1575
1582
 
1576
1583
  ---
1577
1584
 
1578
- ## Testing (`sibu/testing`)
1585
+ ## Testing (`sibujs/testing`)
1579
1586
 
1580
1587
  Component testing utilities, accessibility testing, E2E helpers, snapshot testing, and visual regression support. Works with Vitest, Jest, and Playwright.
1581
1588
 
package/dist/browser.cjs CHANGED
@@ -58,9 +58,12 @@ function track(effectFn, subscriber) {
58
58
  }
59
59
  subscriberStack[stackTop] = subscriber;
60
60
  currentSubscriber = subscriber;
61
- effectFn();
62
- stackTop--;
63
- currentSubscriber = stackTop >= 0 ? subscriberStack[stackTop] : null;
61
+ try {
62
+ effectFn();
63
+ } finally {
64
+ stackTop--;
65
+ currentSubscriber = stackTop >= 0 ? subscriberStack[stackTop] : null;
66
+ }
64
67
  return () => cleanup(subscriber);
65
68
  }
66
69
  function suspendTracking() {
@@ -422,6 +425,9 @@ function effect(effectFn) {
422
425
  }
423
426
 
424
427
  // src/browser/resize.ts
428
+ function resolveTarget(target) {
429
+ return typeof target === "function" ? target : () => target.current;
430
+ }
425
431
  function resize(target) {
426
432
  const [width, setWidth] = signal(0);
427
433
  const [height, setHeight] = signal(0);
@@ -430,8 +436,9 @@ function resize(target) {
430
436
  return { width, height, dispose: () => {
431
437
  } };
432
438
  }
439
+ const getter = resolveTarget(target);
433
440
  const cleanup2 = effect(() => {
434
- const el = target();
441
+ const el = getter();
435
442
  if (observer) {
436
443
  observer.disconnect();
437
444
  observer = null;
@@ -690,6 +697,9 @@ function clipboard() {
690
697
  }
691
698
 
692
699
  // src/browser/dragDrop.ts
700
+ function resolveTarget2(target) {
701
+ return typeof target === "function" ? target : () => target.current;
702
+ }
693
703
  function draggable(element, data) {
694
704
  const [isDragging, setIsDragging] = signal(false);
695
705
  if (typeof window === "undefined") {
@@ -699,12 +709,13 @@ function draggable(element, data) {
699
709
  let currentEl = null;
700
710
  let onDragStart = null;
701
711
  let onDragEnd = null;
712
+ const getter = resolveTarget2(element);
702
713
  const cleanup2 = effect(() => {
703
714
  if (currentEl && onDragStart && onDragEnd) {
704
715
  currentEl.removeEventListener("dragstart", onDragStart);
705
716
  currentEl.removeEventListener("dragend", onDragEnd);
706
717
  }
707
- const el = element();
718
+ const el = getter();
708
719
  currentEl = el;
709
720
  if (!el) return;
710
721
  el.draggable = true;
@@ -741,6 +752,7 @@ function dropZone(element, options) {
741
752
  let onDragEnter = null;
742
753
  let onDragLeave = null;
743
754
  let onDrop = null;
755
+ const getter = resolveTarget2(element);
744
756
  const cleanup2 = effect(() => {
745
757
  if (currentEl && onDragOver && onDragEnter && onDragLeave && onDrop) {
746
758
  currentEl.removeEventListener("dragover", onDragOver);
@@ -748,7 +760,7 @@ function dropZone(element, options) {
748
760
  currentEl.removeEventListener("dragleave", onDragLeave);
749
761
  currentEl.removeEventListener("drop", onDrop);
750
762
  }
751
- const el = element();
763
+ const el = getter();
752
764
  currentEl = el;
753
765
  if (!el) return;
754
766
  onDragOver = (e) => {
@@ -10,14 +10,17 @@ declare function media(query: string): {
10
10
  dispose: () => void;
11
11
  };
12
12
 
13
+ type ElementTarget$1 = (() => HTMLElement | null) | {
14
+ current: HTMLElement | null;
15
+ };
13
16
  /**
14
17
  * resize tracks the dimensions of a target element reactively.
15
18
  * Uses the ResizeObserver API to monitor size changes.
16
19
  *
17
- * @param target Reactive getter returning the HTMLElement to observe (or null)
20
+ * @param target Reactive getter or ref returning the HTMLElement to observe (or null)
18
21
  * @returns Object with reactive width/height getters and a dispose function
19
22
  */
20
- declare function resize(target: () => HTMLElement | null): {
23
+ declare function resize(target: ElementTarget$1): {
21
24
  width: () => number;
22
25
  height: () => number;
23
26
  dispose: () => void;
@@ -120,16 +123,19 @@ declare function clipboard(): {
120
123
  dispose: () => void;
121
124
  };
122
125
 
126
+ type ElementTarget = (() => HTMLElement | null) | {
127
+ current: HTMLElement | null;
128
+ };
123
129
  /**
124
130
  * draggable makes an element draggable and tracks its dragging state.
125
131
  * Sets the `draggable` attribute and attaches dragstart/dragend listeners.
126
132
  * Serializes the provided data as JSON into the dataTransfer.
127
133
  *
128
- * @param element Reactive getter returning the HTMLElement to make draggable (or null)
134
+ * @param element Reactive getter or ref returning the HTMLElement to make draggable (or null)
129
135
  * @param data Optional data payload to transfer on drag
130
136
  * @returns Object with reactive isDragging getter and dispose function
131
137
  */
132
- declare function draggable(element: () => HTMLElement | null, data?: unknown): {
138
+ declare function draggable(element: ElementTarget, data?: unknown): {
133
139
  isDragging: () => boolean;
134
140
  dispose: () => void;
135
141
  };
@@ -138,11 +144,11 @@ declare function draggable(element: () => HTMLElement | null, data?: unknown): {
138
144
  * Listens for dragenter, dragleave, dragover, and drop events.
139
145
  * Calls options.onDrop with the parsed data payload and the DragEvent.
140
146
  *
141
- * @param element Reactive getter returning the HTMLElement to use as drop zone (or null)
147
+ * @param element Reactive getter or ref returning the HTMLElement to use as drop zone (or null)
142
148
  * @param options Object with onDrop callback receiving the transferred data and event
143
149
  * @returns Object with reactive isOver getter and dispose function
144
150
  */
145
- declare function dropZone(element: () => HTMLElement | null, options: {
151
+ declare function dropZone(element: ElementTarget, options: {
146
152
  onDrop: (data: unknown, event: DragEvent) => void;
147
153
  }): {
148
154
  isOver: () => boolean;
package/dist/browser.d.ts CHANGED
@@ -10,14 +10,17 @@ declare function media(query: string): {
10
10
  dispose: () => void;
11
11
  };
12
12
 
13
+ type ElementTarget$1 = (() => HTMLElement | null) | {
14
+ current: HTMLElement | null;
15
+ };
13
16
  /**
14
17
  * resize tracks the dimensions of a target element reactively.
15
18
  * Uses the ResizeObserver API to monitor size changes.
16
19
  *
17
- * @param target Reactive getter returning the HTMLElement to observe (or null)
20
+ * @param target Reactive getter or ref returning the HTMLElement to observe (or null)
18
21
  * @returns Object with reactive width/height getters and a dispose function
19
22
  */
20
- declare function resize(target: () => HTMLElement | null): {
23
+ declare function resize(target: ElementTarget$1): {
21
24
  width: () => number;
22
25
  height: () => number;
23
26
  dispose: () => void;
@@ -120,16 +123,19 @@ declare function clipboard(): {
120
123
  dispose: () => void;
121
124
  };
122
125
 
126
+ type ElementTarget = (() => HTMLElement | null) | {
127
+ current: HTMLElement | null;
128
+ };
123
129
  /**
124
130
  * draggable makes an element draggable and tracks its dragging state.
125
131
  * Sets the `draggable` attribute and attaches dragstart/dragend listeners.
126
132
  * Serializes the provided data as JSON into the dataTransfer.
127
133
  *
128
- * @param element Reactive getter returning the HTMLElement to make draggable (or null)
134
+ * @param element Reactive getter or ref returning the HTMLElement to make draggable (or null)
129
135
  * @param data Optional data payload to transfer on drag
130
136
  * @returns Object with reactive isDragging getter and dispose function
131
137
  */
132
- declare function draggable(element: () => HTMLElement | null, data?: unknown): {
138
+ declare function draggable(element: ElementTarget, data?: unknown): {
133
139
  isDragging: () => boolean;
134
140
  dispose: () => void;
135
141
  };
@@ -138,11 +144,11 @@ declare function draggable(element: () => HTMLElement | null, data?: unknown): {
138
144
  * Listens for dragenter, dragleave, dragover, and drop events.
139
145
  * Calls options.onDrop with the parsed data payload and the DragEvent.
140
146
  *
141
- * @param element Reactive getter returning the HTMLElement to use as drop zone (or null)
147
+ * @param element Reactive getter or ref returning the HTMLElement to use as drop zone (or null)
142
148
  * @param options Object with onDrop callback receiving the transferred data and event
143
149
  * @returns Object with reactive isOver getter and dispose function
144
150
  */
145
- declare function dropZone(element: () => HTMLElement | null, options: {
151
+ declare function dropZone(element: ElementTarget, options: {
146
152
  onDrop: (data: unknown, event: DragEvent) => void;
147
153
  }): {
148
154
  isOver: () => boolean;