lilact 0.1.0 → 0.2.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.
Files changed (76) hide show
  1. package/README.md +13 -5
  2. package/dist/lilact.development.min.js +9657 -2
  3. package/dist/lilact.development.min.js.map +1 -1
  4. package/dist/lilact.production.min.js +1 -1
  5. package/dist/lilact.production.min.js.map +1 -1
  6. package/docs/assets/navigation.js +1 -1
  7. package/docs/assets/search.js +1 -1
  8. package/docs/classes/accessories.ErrorBoundary.html +11 -10
  9. package/docs/classes/accessories.Suspense.html +12 -22
  10. package/docs/classes/components.Component.html +11 -10
  11. package/docs/classes/components.HTMLComponent.html +11 -10
  12. package/docs/classes/components.RootComponent.html +11 -10
  13. package/docs/functions/accessories.Spinner.html +1 -1
  14. package/docs/functions/components.createComponent.html +1 -1
  15. package/docs/functions/components.createRoot.html +1 -1
  16. package/docs/functions/components.render.html +1 -1
  17. package/docs/functions/hooks.createContext.html +2 -2
  18. package/docs/functions/hooks.forwardRef.html +4 -0
  19. package/docs/functions/hooks.useActionState.html +1 -1
  20. package/docs/functions/hooks.useCallback.html +1 -1
  21. package/docs/functions/hooks.useContext.html +1 -1
  22. package/docs/functions/hooks.useEffect.html +1 -1
  23. package/docs/functions/hooks.useId.html +1 -1
  24. package/docs/functions/hooks.useImperativeHandle.html +7 -0
  25. package/docs/functions/hooks.useLayoutEffect.html +2 -2
  26. package/docs/functions/hooks.useLocalStorage.html +1 -1
  27. package/docs/functions/hooks.useMemo.html +2 -2
  28. package/docs/functions/hooks.useReducer.html +1 -1
  29. package/docs/functions/hooks.useRef.html +1 -1
  30. package/docs/functions/hooks.useState.html +2 -2
  31. package/docs/functions/hooks.useTransition.html +2 -2
  32. package/docs/functions/jsx.transpileJSX.html +1 -1
  33. package/docs/functions/run.lazy.html +7 -15
  34. package/docs/functions/run.runScripts.html +1 -1
  35. package/docs/functions/run.traceError.html +1 -1
  36. package/docs/functions/transition.CSSTransition.html +1 -1
  37. package/docs/functions/transition.Transition.html +15 -0
  38. package/docs/functions/transition.TransitionGroup.html +1 -1
  39. package/docs/index.html +9 -5
  40. package/docs/modules/hooks.html +1 -1
  41. package/docs/modules/jsx.html +1 -1
  42. package/docs/modules/transition.html +1 -1
  43. package/docs/static/demos/actionstate.jsx +4 -6
  44. package/docs/static/demos/context.jsx +1 -3
  45. package/docs/static/demos/lazy.jsx +5 -7
  46. package/docs/static/demos/modal.jsx +13 -15
  47. package/docs/static/demos/proptypes.jsx +5 -8
  48. package/docs/static/demos/reducer.jsx +21 -23
  49. package/docs/static/demos/suspense.jsx +4 -6
  50. package/docs/static/demos/transition.jsx +25 -25
  51. package/docs/static/demos/usetransition.jsx +2 -4
  52. package/docs/static/lilact.development.min.js +9657 -2
  53. package/docs/static/lilact.production.min.js +1 -1
  54. package/package.json +1 -1
  55. package/root/demos/actionstate.jsx +4 -6
  56. package/root/demos/context.jsx +1 -3
  57. package/root/demos/lazy.jsx +5 -7
  58. package/root/demos/modal.jsx +13 -15
  59. package/root/demos/proptypes.jsx +5 -8
  60. package/root/demos/reducer.jsx +21 -23
  61. package/root/demos/suspense.jsx +4 -6
  62. package/root/demos/transition.jsx +25 -25
  63. package/root/demos/usetransition.jsx +2 -4
  64. package/root/lilact.development.min.js +9657 -2
  65. package/root/lilact.production.min.js +1 -1
  66. package/src/accessories.jsx +12 -11
  67. package/src/components.jsx +9 -4
  68. package/src/hooks.jsx +82 -41
  69. package/src/jsx.js +1 -0
  70. package/src/lilact.jsx +5 -7
  71. package/src/pane.jsx +287 -0
  72. package/src/run.jsx +3 -17
  73. package/src/transition.jsx +32 -21
  74. package/webpack.config.js +1 -1
  75. package/docs/classes/transition.Transition.html +0 -31
  76. package/docs/variables/jsx.transpilerConfig.html +0 -1
package/src/hooks.jsx CHANGED
@@ -50,10 +50,10 @@ export function useHook()
50
50
  }
51
51
 
52
52
  /**
53
- * Adds state to a component using a React-like [value, setter] pattern.
53
+ * Adds state to a component using a [value, setter] pattern.
54
54
  *
55
55
  * @param {any} initialValue - Initial state value.
56
- * @returns {any} Hook result (implementation-dependent; typically `[state, setState]`).
56
+ * @returns {any} Hook result `[state, setState]`.
57
57
  */
58
58
  export function useState(val)
59
59
  {
@@ -82,25 +82,27 @@ export function useState(val)
82
82
  * @param {Array<any>} deps - Dependency list.
83
83
  * @returns {Function} Memoized callback.
84
84
  */
85
- export function useCallback(callback, deps=[{}])
85
+ export function useCallback(callback, deps=undefined)
86
86
  {
87
+ if( deps!==undefined && (typeof(deps)!=='object' || deps.constructor.name!=='Array') ) {
88
+ throw "callback dependencies must be an array or omitted.";
89
+ }
90
+
87
91
  const hk = Lilact.useHook();
88
92
 
89
93
  if( Lilact.isEmpty(hk) ) {
90
94
  hk.callback = callback;
91
- hk.deps = deps;
92
95
  }
93
96
  else {
94
- for(let d in deps) {
95
- if( !Lilact.defaultIsEqual(deps[d],hk.deps[d]) ) {
96
- hk.callback = callback;
97
+ if(deps!==undefined && hk?.deps!==undefined && Lilact.shallowEqual(deps, hk.deps)) return hk.callback;
98
+ }
97
99
 
98
- hk.deps = deps;
99
- break;
100
- }
101
- }
100
+ if(hk?.cleanup) {
101
+ hk.cleanup();
102
102
  }
103
103
 
104
+ hk.deps = deps;
105
+
104
106
  return hk.callback;
105
107
  }
106
108
 
@@ -108,7 +110,7 @@ export function useCallback(callback, deps=[{}])
108
110
  * Creates a context object for sharing a value through the component tree.
109
111
  *
110
112
  * @param {any} [defaultValue] - Initial context value when no Provider is present.
111
- * @returns {any} A context object (implementation-dependent).
113
+ * @returns {any} A context object
112
114
  */
113
115
  export function createContext(val)
114
116
  {
@@ -164,7 +166,7 @@ export function useId(prefix="N")
164
166
  /**
165
167
  * Starts a transition and returns helpers for pending updates vs immediate ones.
166
168
  *
167
- * @returns {any} Transition API (implementation-dependent; typically `[isPending, startTransition]`).
169
+ * @returns {any} `[isPending, startTransition]`
168
170
  */
169
171
  export function useTransition()
170
172
  {
@@ -267,25 +269,25 @@ export function useRef(val = null)
267
269
  * @param {Array<any>} [deps] - Dependency list.
268
270
  * @returns {void}
269
271
  */
270
- export function useLayoutEffect(setup, deps=[{}])
272
+ export function useLayoutEffect(setup, deps=undefined)
271
273
  {
272
- if(typeof(deps)!=='object' || deps.constructor.name!=='Array') {
273
- throw "effect dependencies must be an array or omitted.";
274
+ if( deps!==undefined && (typeof(deps)!=='object' || deps.constructor.name!=='Array') ) {
275
+ throw "layout effect dependencies must be an array or omitted.";
274
276
  }
275
277
 
276
278
  const hk = Lilact.useHook();
277
279
 
278
280
  if( !Lilact.isEmpty(hk) ) {
279
- if(deps.every((v,i)=> v === hk.deps[i])) return;
280
- if(hk.cleanup) {
281
- hk.cleanup();
282
- }
281
+ if(deps!==undefined && hk?.deps!==undefined && Lilact.shallowEqual(deps, hk.deps)) return;
282
+ }
283
+
284
+ if(hk?.cleanup) {
285
+ hk.cleanup();
283
286
  }
284
287
 
285
288
  hk.deps = deps;
286
289
  Lilact.layout_effects.add( ()=>{ hk.cleanup = setup(); });
287
290
  Lilact.current_component[0].component.forceUpdate();
288
-
289
291
  }
290
292
 
291
293
  /**
@@ -297,17 +299,18 @@ export function useLayoutEffect(setup, deps=[{}])
297
299
  */
298
300
  export function useEffect(setup, deps=[{}])
299
301
  {
300
- if(typeof(deps)!=='object' || deps.constructor.name!=='Array') {
302
+ if( deps!==undefined && (typeof(deps)!=='object' || deps.constructor.name!=='Array') ) {
301
303
  throw "effect dependencies must be an array or omitted.";
302
304
  }
303
305
 
304
306
  const hk = Lilact.useHook();
305
307
 
306
308
  if( !Lilact.isEmpty(hk) ) {
307
- if(deps.every((v,i)=> v === hk.deps[i])) return;
308
- if(hk.cleanup) {
309
- hk.cleanup();
310
- }
309
+ if(deps!==undefined && hk?.deps!==undefined && Lilact.shallowEqual(deps, hk.deps)) return;
310
+ }
311
+
312
+ if(hk?.cleanup) {
313
+ hk.cleanup();
311
314
  }
312
315
 
313
316
  hk.deps = deps;
@@ -322,24 +325,21 @@ export function useEffect(setup, deps=[{}])
322
325
  * @param {Array<any>} deps - Dependency list.
323
326
  * @returns {any} Memoized value.
324
327
  */
325
- export function useMemo(fn,deps=[])
328
+ export function useMemo(fn,deps=undefined)
326
329
  {
330
+ if( deps!==undefined && (typeof(deps)!=='object' || deps.constructor.name!=='Array') ) {
331
+ throw "memo dependencies must be an array or omitted.";
332
+ }
333
+
327
334
  const hk = Lilact.useHook();
328
335
 
329
- if( Lilact.isEmpty(hk) ) {
330
- hk.deps = deps;
331
- hk.value = fn();
332
- }
333
- else {
334
- for(let d in deps) {
335
- if( !Lilact.defaultIsEqual(deps[d],hk.deps[d]) ) {
336
- hk.deps = deps;
337
- hk.value = fn(hk.value);
338
- break;
339
- }
340
- }
336
+ if( !Lilact.isEmpty(hk) ) {
337
+ if(deps!==undefined && hk?.deps!==undefined && Lilact.shallowEqual(deps, hk.deps)) return hk.value;
341
338
  }
342
339
 
340
+ hk.deps = deps;
341
+ hk.value = fn(hk.value);
342
+
343
343
  return hk.value;
344
344
  }
345
345
 
@@ -348,7 +348,7 @@ export function useMemo(fn,deps=[])
348
348
  *
349
349
  * @param {Function} action - The async/queued action function.
350
350
  * @param {any} initialState - Initial state for the hook.
351
- * @returns {any} Hook result (implementation-dependent).
351
+ * @returns {any} Hook result
352
352
  */
353
353
  export function useActionState(fn, initial_state)
354
354
  {
@@ -383,7 +383,7 @@ export function useActionState(fn, initial_state)
383
383
  * @param {Function} reducer - Reducer function.
384
384
  * @param {any} initialArg - Initial state value (or initializer arg).
385
385
  * @param {Function} [init] - Optional initializer function for lazy initial state.
386
- * @returns {any} Hook result (implementation-dependent; typically `[state, dispatch]`).
386
+ * @returns {any} Hook result `[state, dispatch]`.
387
387
  */
388
388
  export function useReducer(reducer, initialArg, init)
389
389
  {
@@ -459,3 +459,44 @@ export function useDeferredValue(value, initialValue)
459
459
  }
460
460
 
461
461
 
462
+ /**
463
+ * Wraps a render function so that a parent can pass a `ref` into it.
464
+ * The forwarded `ref` is provided as the second argument to the render function: `(props, ref)`.
465
+ *
466
+ * @param {function(props: any, ref: any)} render
467
+ * The component render function that receives the props and the forwarded ref.
468
+ * @returns {}
469
+ */
470
+ export function forwardRef(render)
471
+ {
472
+ return (props)=>render({...props, ref: undefined}, props.ref);
473
+ }
474
+
475
+
476
+ /**
477
+ * Customizes the value that is exposed to the parent when it uses a `ref` on a component created with `forwardRef`.
478
+ * The object returned by `factory` becomes the value of `ref.current` for object refs.
479
+ *
480
+ * @param {Ref<any>} ref
481
+ * The ref that was received in your component (typically via `forwardRef` as the second argument).
482
+ * @param {function(): any} factory
483
+ * Function that returns the value to expose to the parent. Commonly an object with methods,
484
+ * or a DOM node reference.
485
+ * @param {Array<any>} [deps]
486
+ * Dependency list that controls when the exposed value is recalculated.
487
+ * @returns {void}
488
+ */
489
+ export function useImperativeHandle(ref, factory, deps)
490
+ {
491
+ if(deps!==undefined && ref?.deps!==undefined && Lilact.shallowEqual(deps, ref.deps)) return;
492
+
493
+ ref.deps = deps;
494
+
495
+ Lilact.setTimeout( ()=>{
496
+ if(typeof ref?.current !== 'object') {
497
+ ref.current = {};
498
+ }
499
+ Object.assign( ref.current, factory(), 0 );
500
+ });
501
+ }
502
+
package/src/jsx.js CHANGED
@@ -51,6 +51,7 @@
51
51
 
52
52
  import * as jsxAddons from './jsx.addons.js';
53
53
 
54
+ /** @ignore */
54
55
  export const transpilerConfig = {
55
56
  addons: jsxAddons,
56
57
  setFunctionLabels: true,
package/src/lilact.jsx CHANGED
@@ -47,6 +47,7 @@ import * as misc from './misc.jsx';
47
47
 
48
48
  import * as router from './router.jsx';
49
49
  import * as accessories from './accessories.jsx';
50
+ import {ResizablePane} from './pane.jsx';
50
51
 
51
52
  import {transpileJSX, transpilerConfig} from "./jsx";
52
53
 
@@ -61,7 +62,7 @@ import {transpileJSX, transpilerConfig} from "./jsx";
61
62
  * @property emotion - Handle to Emotion’s CSS-in-JS package for styling (https://github.com/emotion-js/emotion).
62
63
  */
63
64
  export const Lilact =
64
- {
65
+ {
65
66
 
66
67
  VERSION: "beta.0",
67
68
 
@@ -86,27 +87,24 @@ export const Lilact =
86
87
  ...router,
87
88
  ...accessories,
88
89
 
90
+ ResizablePane,
91
+
89
92
  transpileJSX,
90
93
  transpilerConfig,
91
94
 
92
95
  // Dependencies ()
93
96
 
94
97
  PropTypes,
98
+ //redux: {...redux, createSlice, createAsyncThunk},
95
99
  redux,
96
100
  emotion,
97
101
 
98
102
  }
99
103
 
100
-
101
- // or, if you prefer DOMContentLoaded:
102
104
  document.addEventListener('DOMContentLoaded', () => {
103
105
  Lilact.runScripts();
104
106
  });
105
107
 
106
- function yourFunctionHere() {
107
- // ...
108
- }
109
-
110
108
  ʔ if(DEBUG) {
111
109
  console.log(`Lilact (Version: ${Lilact.VERSION}) - Debug Mode`);
112
110
  console.log(`Copyright(C) 2024-2026 Arash Kazemi <contact.arash.kazemi@gmail.com>`);
package/src/pane.jsx ADDED
@@ -0,0 +1,287 @@
1
+ import { useEffect, useLayoutEffect, useMemo, useRef, useState, forwardRef, useImperativeHandle } from "./hooks.jsx";
2
+ import { Children } from "./misc.jsx";
3
+
4
+ function clamp(n, min, max) {
5
+ return Math.max(min, Math.min(max, n));
6
+ }
7
+
8
+ /**
9
+ * ResizablePane
10
+ *
11
+ * Features:
12
+ * - Supports "horizontal" (left/top size affects width) and "vertical" (affects height)
13
+ * - Initial position via props.position
14
+ * - Methods to set mode and position via ref:
15
+ * ref.current.setMode(mode)
16
+ * ref.current.setPosition(position)
17
+ * - Callback when size changes via onSizeChange
18
+ * - Children are rendered in two separate containers (no portals)
19
+ */
20
+ export const ResizablePane = forwardRef(function Pane(
21
+ {
22
+ mode = "horizontal", // "horizontal" | "vertical"
23
+ initialPosition, // optional (alias-ish to position)
24
+ position, // controlled position (number)
25
+ defaultPosition = 0.5, // used if position/initialPosition not provided
26
+ min = 0.1, // clamp in "percent of container" units: 0..1
27
+ max = 0.9, // clamp in "percent of container" units: 0..1
28
+ splitterSize = 8, // px thickness of the drag handle
29
+ onSizeChange, // (newPosition: number) => void
30
+ style,
31
+ className,
32
+ leftPaneStyle,
33
+ rightPaneStyle,
34
+ splitterStyle,
35
+ children, // expects two children: [A, B]
36
+ },
37
+ ref
38
+ ) {
39
+ const [internalMode, setInternalMode] = useState(mode);
40
+ const [pos, setPos] = useState(() => {
41
+ const start =
42
+ position ?? initialPosition ?? (defaultPosition != null ? defaultPosition : 0.5);
43
+ return clamp(start, min, max);
44
+ });
45
+
46
+ const containerRef = useRef(null);
47
+ const draggingRef = useRef(false);
48
+
49
+ const panes = Children.toArray(children);
50
+ const leftChild = panes[0] ?? null;
51
+ const rightChild = panes[1] ?? null;
52
+
53
+ const modeResolved = mode != null ? mode : internalMode;
54
+
55
+ // Keep internalMode aligned if mode is provided as a prop
56
+ useEffect(() => {
57
+ if (mode != null) setInternalMode(mode);
58
+ }, [mode]);
59
+
60
+ // Controlled position: update state when prop changes
61
+ useEffect(() => {
62
+ if (position == null) return;
63
+ setPos(clamp(position, min, max));
64
+ }, [position, min, max]);
65
+
66
+ const setPosition = (newPos) => {
67
+ const next = clamp(newPos, min, max);
68
+ if (position == null) setPos(next); // only update internal state if uncontrolled
69
+ onSizeChange?.(next);
70
+ };
71
+
72
+ const setMode = (nextMode) => {
73
+ const m = nextMode === "vertical" ? "vertical" : "horizontal";
74
+ if (mode == null) setInternalMode(m);
75
+ // If mode is controlled via prop, consumer should re-render with new prop.
76
+ };
77
+
78
+ useImperativeHandle(
79
+ ref,
80
+ () => ({
81
+ setPosition,
82
+ setMode,
83
+ getPosition: () => (position == null ? pos : clamp(position, min, max)),
84
+ getMode: () => modeResolved,
85
+ }),
86
+ [pos, position, min, max, modeResolved, onSizeChange, mode]
87
+ );
88
+
89
+ const updateFromClientXorY = (clientX, clientY) => {
90
+ const el = containerRef.current;
91
+ if (!el) return;
92
+
93
+ const rect = el.getBoundingClientRect();
94
+ let next;
95
+
96
+ if (modeResolved === "horizontal") {
97
+ const usable = rect.width;
98
+ if (usable <= 0) return;
99
+ next = (clientX - rect.left) / usable;
100
+ } else {
101
+ const usable = rect.height;
102
+ if (usable <= 0) return;
103
+ next = (clientY - rect.top) / usable;
104
+ }
105
+ setPosition(next);
106
+ };
107
+
108
+ const onPointerDown = (e) => {
109
+ e.preventDefault();
110
+ draggingRef.current = true;
111
+
112
+ // Capture pointer so we still get events outside the handle area.
113
+ try {
114
+ e.currentTarget.setPointerCapture?.(e.pointerId);
115
+ } catch {
116
+ // ignore
117
+ }
118
+
119
+ updateFromClientXorY(e.clientX, e.clientY);
120
+ };
121
+
122
+ const onPointerMove = (e) => {
123
+ if (!draggingRef.current) return;
124
+ updateFromClientXorY(e.clientX, e.clientY);
125
+ };
126
+
127
+ const stopDragging = () => {
128
+ draggingRef.current = false;
129
+ };
130
+
131
+ // Attach global listeners to ensure smooth dragging even if pointer capture fails
132
+ useEffect(() => {
133
+ const handleMove = (e) => {
134
+ if (!draggingRef.current) return;
135
+ updateFromClientXorY(e.clientX, e.clientY);
136
+ };
137
+ const handleUp = () => stopDragging();
138
+
139
+ window.addEventListener("pointermove", handleMove, { passive: false });
140
+ window.addEventListener("pointerup", handleUp, { passive: true });
141
+ window.addEventListener("pointercancel", handleUp, { passive: true });
142
+
143
+ return () => {
144
+ window.removeEventListener("pointermove", handleMove);
145
+ window.removeEventListener("pointerup", handleUp);
146
+ window.removeEventListener("pointercancel", handleUp);
147
+ };
148
+ }, [modeResolved, min, max, position, onSizeChange]);
149
+
150
+ const posResolved = position == null ? pos : clamp(position, min, max);
151
+
152
+ const sizes = useMemo(() => {
153
+ if (modeResolved === "horizontal") {
154
+ // left width = pos, splitter width = splitterSize, right flexes
155
+ // We set left/right as percentages and keep splitter fixed in px.
156
+ return {
157
+ left: `${posResolved * 100}%`,
158
+ right: `calc(${100 - posResolved * 100}% - ${splitterSize}px)`,
159
+ };
160
+ }
161
+ return {
162
+ left: `${posResolved * 100}%`,
163
+ right: `calc(${100 - posResolved * 100}% - ${splitterSize}px)`,
164
+ };
165
+ }, [modeResolved, posResolved, splitterSize]);
166
+
167
+ // Improve keyboard accessibility (arrow keys when handle is focused)
168
+ const onSplitterKeyDown = (e) => {
169
+ const step = 0.02;
170
+ let delta = 0;
171
+ if (modeResolved === "horizontal") {
172
+ if (e.key === "ArrowLeft") delta = -step;
173
+ if (e.key === "ArrowRight") delta = step;
174
+ } else {
175
+ if (e.key === "ArrowUp") delta = -step;
176
+ if (e.key === "ArrowDown") delta = step;
177
+ }
178
+ if (delta !== 0) {
179
+ e.preventDefault();
180
+ setPosition(posResolved + delta);
181
+ }
182
+ };
183
+
184
+ // Ensure position clamps correctly if min/max change
185
+ useLayoutEffect(() => {
186
+ setPos((p) => clamp(p, min, max));
187
+ }, [min, max]);
188
+
189
+ const rootStyle = {
190
+ display: "flex",
191
+ width: "100%",
192
+ height: "100%",
193
+ overflow: "hidden",
194
+ touchAction: "none",
195
+ ...(style || {}),
196
+ flexDirection: modeResolved === "horizontal" ? "row" : "column",
197
+ };
198
+
199
+ const leftPaneComputed =
200
+ modeResolved === "horizontal"
201
+ ? {
202
+ width: sizes.left,
203
+ flex: `0 0 ${sizes.left}`,
204
+ overflow: "auto",
205
+ ...(leftPaneStyle || {}),
206
+ }
207
+ : {
208
+ height: sizes.left,
209
+ flex: `0 0 ${sizes.left}`,
210
+ overflow: "auto",
211
+ ...(leftPaneStyle || {}),
212
+ };
213
+
214
+ const rightPaneComputed =
215
+ modeResolved === "horizontal"
216
+ ? {
217
+ width: `calc(${100 - posResolved * 100}% - ${splitterSize}px)`,
218
+ flex: `1 1 auto`,
219
+ overflow: "auto",
220
+ ...(rightPaneStyle || {}),
221
+ }
222
+ : {
223
+ height: `calc(${100 - posResolved * 100}% - ${splitterSize}px)`,
224
+ flex: `1 1 auto`,
225
+ overflow: "auto",
226
+ ...(rightPaneStyle || {}),
227
+ };
228
+
229
+ const splitterComputed =
230
+ modeResolved === "horizontal"
231
+ ? {
232
+ width: `${splitterSize}px`,
233
+ flex: `0 0 ${splitterSize}px`,
234
+ cursor: "col-resize",
235
+ background: "transparent",
236
+ ...(splitterStyle || {}),
237
+ }
238
+ : {
239
+ height: `${splitterSize}px`,
240
+ flex: `0 0 ${splitterSize}px`,
241
+ cursor: "row-resize",
242
+ background: "transparent",
243
+ ...(splitterStyle || {}),
244
+ };
245
+
246
+ const dividerVisualStyle =
247
+ modeResolved === "horizontal"
248
+ ? {
249
+ height: "100%",
250
+ width: "100%",
251
+ background: "rgba(0,0,0,0.08)",
252
+ }
253
+ : {
254
+ width: "100%",
255
+ height: "100%",
256
+ background: "rgba(0,0,0,0.08)",
257
+ };
258
+
259
+ return (
260
+ <div
261
+ ref={containerRef}
262
+ className={className}
263
+ style={rootStyle}
264
+ onPointerMove={onPointerMove}
265
+ >
266
+ <div style={leftPaneComputed}>{leftChild}</div>
267
+
268
+ <div
269
+ role="separator"
270
+ aria-orientation={modeResolved === "horizontal" ? "vertical" : "horizontal"}
271
+ aria-valuemin={min}
272
+ aria-valuemax={max}
273
+ aria-valuenow={posResolved}
274
+ tabIndex={0}
275
+ onPointerDown={onPointerDown}
276
+ onPointerUp={stopDragging}
277
+ onPointerCancel={stopDragging}
278
+ onKeyDown={onSplitterKeyDown}
279
+ style={splitterComputed}
280
+ >
281
+ <div style={dividerVisualStyle} />
282
+ </div>
283
+
284
+ <div style={rightPaneComputed}>{rightChild}</div>
285
+ </div>
286
+ );
287
+ });
package/src/run.jsx CHANGED
@@ -180,21 +180,7 @@ export function require(path, force_update)
180
180
 
181
181
  /**
182
182
  * Wrapper that enables async, code-split component loading. `lazy` should be used
183
- * outside the component definintion ot it will produce new components on each rerender.
184
- *
185
- *
186
- * @example
187
- * ```jsx
188
- * const LazyWidget = lazy(() => Lilact.require("./Widget"));
189
- *
190
- * export function Page() {
191
- * return (
192
- * <Suspense fallback={<Spinner/>}>
193
- * <LazyWidget />
194
- * </Suspense>
195
- * );
196
- * }
197
- * ```
183
+ * outside the component definintion or it will produce new components on each rerender.
198
184
  *
199
185
  * @param factory - A function with **no arguments** that returns a `Promise`.
200
186
  * The promise must resolve to a module whose module.exports.default is a Lilact component
@@ -202,12 +188,12 @@ export function require(path, force_update)
202
188
  *
203
189
  * @returns A Lilact component that should be rendered inside a {@link Suspense} boundary.
204
190
  */
205
- export function lazy(req_func) {
191
+ export function lazy(factory) {
206
192
  let status = "pending"; // pending | success | error
207
193
  let result; // component | error
208
194
 
209
195
  Lilact[LAZY] = true;
210
- result = req_func();
196
+ result = factory();
211
197
 
212
198
  if(Lilact.isThenable(result)) {
213
199
  result.then(