lilact 0.16.0 → 0.16.2

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 (65) hide show
  1. package/README.md +5 -5
  2. package/bin/bundle.cjs +19 -16
  3. package/bin/copy-demo.js +1 -1
  4. package/dist/lilact.development.js +115 -117
  5. package/dist/lilact.development.js.map +3 -3
  6. package/dist/lilact.development.min.js +19 -19
  7. package/dist/lilact.development.min.js.map +3 -3
  8. package/dist/lilact.production.min.js +19 -19
  9. package/docs/functions/accessories.DragHandle.html +2 -2
  10. package/docs/functions/timers.timeoutPromise.html +1 -1
  11. package/docs/index.html +4 -4
  12. package/docs/static/demos/pane.jsx +2 -1
  13. package/docs/static/index.html +1 -1
  14. package/docs/static/lilact.development.js +115 -117
  15. package/docs/static/lilact.development.js.map +3 -3
  16. package/docs/static/lilact.development.min.js +19 -19
  17. package/docs/static/lilact.development.min.js.map +3 -3
  18. package/docs/static/lilact.production.min.js +19 -19
  19. package/docs/variables/accessories.SplitPane.html +2 -2
  20. package/{root → examples}/demos/pane.jsx +2 -1
  21. package/{root → examples}/index.html +1 -1
  22. package/{root → examples}/lilact.development.js +115 -117
  23. package/{root → examples}/lilact.development.js.map +3 -3
  24. package/examples/lilact.development.min.js +107 -0
  25. package/{root → examples}/lilact.development.min.js.map +3 -3
  26. package/examples/lilact.production.min.js +106 -0
  27. package/package.json +3 -3
  28. package/scripts/build.mjs +29 -0
  29. package/scripts/copy-dist-to-examples.mjs +42 -0
  30. package/scripts/esbuild-preprocessor-plugin.cjs +29 -4
  31. package/scripts/preprocess.mjs +29 -1
  32. package/src/accessories.jsx +152 -161
  33. package/src/jsx.js +13 -15
  34. package/typedoc.json +1 -1
  35. package/root/lilact.development.min.js +0 -107
  36. package/root/lilact.production.min.js +0 -106
  37. package/scripts/copy-dist-to-root.mjs +0 -13
  38. /package/{root → examples}/demos/actionstate.jsx +0 -0
  39. /package/{root → examples}/demos/capture.jsx +0 -0
  40. /package/{root → examples}/demos/context.jsx +0 -0
  41. /package/{root → examples}/demos/css-transition.jsx +0 -0
  42. /package/{root → examples}/demos/error-boundary.jsx +0 -0
  43. /package/{root → examples}/demos/error-callback.jsx +0 -0
  44. /package/{root → examples}/demos/error-component-stack.jsx +0 -0
  45. /package/{root → examples}/demos/error-init.jsx +0 -0
  46. /package/{root → examples}/demos/error-parser.jsx +0 -0
  47. /package/{root → examples}/demos/form-elements.jsx +0 -0
  48. /package/{root → examples}/demos/forwardref.jsx +0 -0
  49. /package/{root → examples}/demos/lazy.jsx +0 -0
  50. /package/{root → examples}/demos/modal.jsx +0 -0
  51. /package/{root → examples}/demos/proptypes.jsx +0 -0
  52. /package/{root → examples}/demos/reducer.jsx +0 -0
  53. /package/{root → examples}/demos/redux.jsx +0 -0
  54. /package/{root → examples}/demos/router.jsx +0 -0
  55. /package/{root → examples}/demos/stopwatch.jsx +0 -0
  56. /package/{root → examples}/demos/suspense.jsx +0 -0
  57. /package/{root → examples}/demos/switch-transition.jsx +0 -0
  58. /package/{root → examples}/demos/transition.jsx +0 -0
  59. /package/{root → examples}/demos/usedefered.jsx +0 -0
  60. /package/{root → examples}/demos/usetransition.jsx +0 -0
  61. /package/{root → examples}/icon.png +0 -0
  62. /package/{root → examples}/prismjs/LICENSE.md +0 -0
  63. /package/{root → examples}/prismjs/prism-jsx.min.js +0 -0
  64. /package/{root → examples}/prismjs/prism.min.css +0 -0
  65. /package/{root → examples}/prismjs/prism.min.js +0 -0
package/README.md CHANGED
@@ -29,7 +29,7 @@ If you find Lilact useful, please consider sponsoring. Your support funds ongoin
29
29
 
30
30
  ## Overview
31
31
 
32
- `Lilact` is a very lightweight implementation of the React API designed to run in the browser. It can be used as a single script that is around `90kb` minified and around `32kb` gzipped, and includes its whole API.
32
+ `Lilact` is a very lightweight implementation of the React API designed to run in the browser. It can be used as a single script that is around `90kb` minified and around `32kb` gzipped and includes its whole API.
33
33
 
34
34
  `Lilact` is very fast, uses minimal resources, and handles memory very efficiently.
35
35
 
@@ -81,14 +81,14 @@ Note: modules are separated in the documentation to improve structure, but in pr
81
81
 
82
82
  ## ESBuild-based Bundler
83
83
 
84
- A `ESBuild` based bundler is available in the `bin` directory. It can be used like this:
84
+ An `ESBuild` based bundler is available in the `bin` directory. It can be used like this:
85
85
 
86
86
  ```bash
87
- npx lilact-bundle --entry client/App.jsx --mode production --name bundle.js --out public/dist
87
+ npx lilact-bundle --watch --minify --entry client/App.jsx --mode production --name bundle.js --out public/dist
88
88
  ```
89
89
 
90
- If you add a `--watch` argument, the bundler will not exit and keep watching the input file(s),
91
- and update the bundle if any file is changed.
90
+ If you add a `--watch` argument, the bundler will stay running and keep watching the input file(s),
91
+ and update the bundle if any file is changed.
92
92
 
93
93
  ---
94
94
 
package/bin/bundle.cjs CHANGED
@@ -100,7 +100,7 @@ function parseArgs(argv) {
100
100
  if (!k || !k.startsWith("--")) continue;
101
101
  const key = k.slice(2);
102
102
 
103
- if (key === "watch") {
103
+ if (key === "watch" || key === "minify") {
104
104
  args[key] = true;
105
105
  continue;
106
106
  }
@@ -118,18 +118,19 @@ async function run() {
118
118
 
119
119
  if (!userEntry) {
120
120
  console.error(
121
- "Usage: lilact-bundler --watch --entry ./path/to/entry.js --mode production --out ./dist --name bundle.js"
121
+ "Usage: lilact-bundler --watch --minify --entry ./path/to/entry.js --mode production --out ./dist --name bundle.js"
122
122
  );
123
123
  process.exit(1);
124
124
  }
125
125
 
126
126
  const name = args.name ?? "bundle.js";
127
127
  const mode = args.mode ?? "production";
128
- const watch = args.watch === true;
128
+ const watch = args?.watch === true;
129
+ const minify = args?.minify === true;
129
130
 
130
131
  const userOutDir = args.out
131
- ? path.resolve(userProjectRoot, args.out)
132
- : path.resolve(userProjectRoot, "dist");
132
+ ? path.resolve(userProjectRoot, args.out)
133
+ : path.resolve(userProjectRoot, "dist");
133
134
 
134
135
  const outFile = path.join(userOutDir, name);
135
136
 
@@ -155,10 +156,10 @@ async function run() {
155
156
  platform: "browser",
156
157
 
157
158
  outfile: outFile,
158
- sourcemap: mode === "development",
159
+ sourcemap: true,
159
160
  target: ["es2018"],
160
161
 
161
- minify: mode === "production",
162
+ minify: minify,
162
163
  define,
163
164
 
164
165
  absWorkingDir: userProjectRoot,
@@ -177,15 +178,23 @@ async function run() {
177
178
  ],
178
179
  });
179
180
 
181
+ const shutdown = async () => {
182
+ try {
183
+ await ctx.dispose();
184
+ } finally {
185
+ process.exit(0);
186
+ }
187
+ };
188
+
180
189
  const buildOpts = {
181
190
  entryPoints: [userEntry],
182
191
  bundle: true,
183
192
  format: "esm",
184
193
  platform: "browser",
185
194
  outfile: outFile,
186
- sourcemap: mode === "development",
195
+ sourcemap: true,
187
196
  target: ["es2018"],
188
- minify: mode === "production",
197
+ minify: minify,
189
198
  define,
190
199
  loader: { ".js": "js", ".jsx": "jsx", ".css": "css" },
191
200
  resolveExtensions: [".js", ".jsx", ".json"],
@@ -199,15 +208,9 @@ async function run() {
199
208
  console.log(`Watching... output: ${outFile}`);
200
209
  } else {
201
210
  await ctx.rebuild();
211
+ await shutdown();
202
212
  }
203
213
 
204
- const shutdown = async () => {
205
- try {
206
- await ctx.dispose();
207
- } finally {
208
- process.exit(0);
209
- }
210
- };
211
214
 
212
215
  process.on("SIGINT", shutdown);
213
216
  process.on("SIGTERM", shutdown);
package/bin/copy-demo.js CHANGED
@@ -19,7 +19,7 @@ function copyDirRecursive(src, dest) {
19
19
  }
20
20
 
21
21
  const typedocOut = process.env.TYPEDOC_OUT || 'docs';
22
- const from = path.resolve(__dirname, '..', 'root');
22
+ const from = path.resolve(__dirname, '..', 'examples');
23
23
  const to = path.resolve(__dirname, '..', typedocOut, 'static');
24
24
 
25
25
  copyDirRecursive(from, to);
@@ -4697,14 +4697,9 @@ function DragHandle({
4697
4697
  }, [endDrag]);
4698
4698
  return createComponent("div", { "role": "button", "tabIndex": 0, "style": { ...style, touchAction: "none" }, "className": cx2(className, isDragging ? "dragging" : ""), "onPointerDown": onPointerDown, "onPointerMove": onPointerMove, "onPointerUp": onPointerUp, "onPointerCancel": onPointerCancel }, children);
4699
4699
  }
4700
- var clamp = (n, min, max) => {
4701
- if (!Number.isFinite(n)) return n;
4702
- return Math.min(max, Math.max(min, n));
4703
- };
4704
4700
  var SplitPane = forwardRef(function SplitPane2({
4705
4701
  mode = "horizontal",
4706
4702
  position: position2,
4707
- // controlled: number | undefined/null
4708
4703
  defaultPosition = 0.5,
4709
4704
  min = 0.1,
4710
4705
  max = 0.9,
@@ -4712,135 +4707,139 @@ var SplitPane = forwardRef(function SplitPane2({
4712
4707
  onSizeChange,
4713
4708
  style,
4714
4709
  className,
4715
- leftPaneStyle,
4716
- rightPaneStyle,
4710
+ firstPaneStyle,
4711
+ secondPaneStyle,
4717
4712
  splitterStyle,
4718
4713
  children
4719
4714
  }, ref) {
4720
- var _a, _b;
4721
- const containerRef = useRef(null);
4722
- const panes = Children.toArray(children);
4723
- const leftChild = (_a = panes[0]) != null ? _a : null;
4724
- const rightChild = (_b = panes[1]) != null ? _b : null;
4725
- const isControlled = position2 != null;
4726
- const [internalMode, setInternalMode] = useState(mode);
4727
- const [posUncontrolled, setPosUncontrolled] = useState(
4728
- () => clamp(
4729
- position2 != null ? position2 : defaultPosition,
4730
- min,
4731
- max
4732
- )
4733
- );
4715
+ const initialMode = mode === "vertical" ? "vertical" : "horizontal";
4716
+ const [internalMode, setInternalMode] = useState(initialMode);
4717
+ const [internalPos, setInternalPos] = useState(clamp(defaultPosition, min, max));
4718
+ const posResolved = position2 == null ? internalPos : clamp(position2, min, max);
4734
4719
  useEffect(() => {
4735
- if (mode != null) setInternalMode(mode);
4720
+ if (position2 == null) return;
4721
+ setInternalPos(clamp(position2, min, max));
4722
+ }, [position2, min, max]);
4723
+ useEffect(() => {
4724
+ setInternalMode(mode === "vertical" ? "vertical" : "horizontal");
4736
4725
  }, [mode]);
4737
- useLayoutEffect(() => {
4738
- if (isControlled) return;
4739
- setPosUncontrolled((p) => clamp(p, min, max));
4740
- }, [min, max, isControlled]);
4741
- const posResolved = isControlled ? clamp(position2, min, max) : posUncontrolled;
4742
4726
  const setPosition = (next2) => {
4743
4727
  const clamped = clamp(next2, min, max);
4744
- if (!isControlled) setPosUncontrolled(clamped);
4728
+ if (position2 == null) setInternalPos(clamped);
4745
4729
  onSizeChange == null ? void 0 : onSizeChange(clamped);
4746
4730
  };
4747
- const draggingRef = useRef(false);
4748
- const pointerIdRef = useRef(null);
4749
- const updateFromClient = (clientX, clientY) => {
4731
+ useImperativeHandle(ref, () => ({
4732
+ setPosition,
4733
+ setMode: (nextMode) => setInternalMode(nextMode === "vertical" ? "vertical" : "horizontal"),
4734
+ getPosition: () => posResolved,
4735
+ getMode: () => internalMode
4736
+ }));
4737
+ const containerRef = useRef(null);
4738
+ const sizeRef = useRef({ w: 0, h: 0 });
4739
+ useLayoutEffect(() => {
4750
4740
  const el = containerRef.current;
4751
4741
  if (!el) return;
4742
+ const ro = new ResizeObserver(() => {
4743
+ const rect2 = el.getBoundingClientRect();
4744
+ sizeRef.current = { w: rect2.width, h: rect2.height };
4745
+ });
4746
+ ro.observe(el);
4752
4747
  const rect = el.getBoundingClientRect();
4748
+ sizeRef.current = { w: rect.width, h: rect.height };
4749
+ return () => ro.disconnect();
4750
+ }, []);
4751
+ const startPosRef = useRef(posResolved);
4752
+ const [dragging, setDragging] = useState(false);
4753
+ const handleStart = () => {
4754
+ setDragging(true);
4755
+ startPosRef.current = posResolved;
4756
+ };
4757
+ const handleDelta = (x, y, _data) => {
4758
+ const { w, h } = sizeRef.current;
4753
4759
  if (internalMode === "horizontal") {
4754
- const usable = rect.width;
4755
- if (!Number.isFinite(usable) || usable <= 0) return;
4756
- const raw = (clientX - rect.left) / usable;
4757
- if (!Number.isFinite(raw)) return;
4758
- setPosition(raw);
4760
+ setPosition(startPosRef.current + x / (w || 1));
4759
4761
  } else {
4760
- const usable = rect.height;
4761
- if (!Number.isFinite(usable) || usable <= 0) return;
4762
- const raw = (clientY - rect.top) / usable;
4763
- if (!Number.isFinite(raw)) return;
4764
- setPosition(raw);
4762
+ setPosition(startPosRef.current + y / (h || 1));
4765
4763
  }
4766
4764
  };
4767
- useEffect(() => {
4768
- const onMove = (e) => {
4769
- if (!draggingRef.current) return;
4770
- if (pointerIdRef.current != null && e.pointerId !== pointerIdRef.current) return;
4771
- updateFromClient(e.clientX, e.clientY);
4772
- };
4773
- const stop = (e) => {
4774
- if (!draggingRef.current) return;
4775
- if (pointerIdRef.current != null && e.pointerId !== pointerIdRef.current) return;
4776
- draggingRef.current = false;
4777
- pointerIdRef.current = null;
4778
- };
4779
- window.addEventListener("pointermove", onMove, { passive: true });
4780
- window.addEventListener("pointerup", stop, { passive: true });
4781
- window.addEventListener("pointercancel", stop, { passive: true });
4782
- return () => {
4783
- window.removeEventListener("pointermove", onMove);
4784
- window.removeEventListener("pointerup", stop);
4785
- window.removeEventListener("pointercancel", stop);
4786
- };
4787
- }, [internalMode]);
4788
- const onPointerDown = (e) => {
4789
- var _a2, _b2;
4790
- if (e.button != null && e.button !== 0) return;
4791
- e.preventDefault();
4792
- draggingRef.current = true;
4793
- pointerIdRef.current = e.pointerId;
4794
- try {
4795
- (_b2 = (_a2 = e.currentTarget).setPointerCapture) == null ? void 0 : _b2.call(_a2, e.pointerId);
4796
- } catch (e2) {
4797
- }
4798
- updateFromClient(e.clientX, e.clientY);
4765
+ const handleEnd = () => setDragging(false);
4766
+ const arr = Children.toArray(children);
4767
+ const firstChild = arr[0];
4768
+ const secondChild = arr[1];
4769
+ const p = posResolved;
4770
+ const pane1StyleAbs = internalMode === "horizontal" ? {
4771
+ position: "absolute",
4772
+ top: 0,
4773
+ bottom: 0,
4774
+ left: 0,
4775
+ width: `calc(${p} * (100% - ${splitterSize}px))`,
4776
+ overflow: "auto",
4777
+ ...firstPaneStyle || {}
4778
+ } : {
4779
+ position: "absolute",
4780
+ left: 0,
4781
+ right: 0,
4782
+ top: 0,
4783
+ height: `calc(${p} * (100% - ${splitterSize}px))`,
4784
+ overflow: "auto",
4785
+ ...firstPaneStyle || {}
4799
4786
  };
4800
- const onKeyDown = (e) => {
4801
- const step = 0.02;
4802
- let delta = 0;
4803
- if (internalMode === "horizontal") {
4804
- if (e.key === "ArrowLeft") delta = -step;
4805
- if (e.key === "ArrowRight") delta = step;
4806
- } else {
4807
- if (e.key === "ArrowUp") delta = -step;
4808
- if (e.key === "ArrowDown") delta = step;
4809
- }
4810
- if (delta !== 0) {
4811
- e.preventDefault();
4812
- setPosition(posResolved + delta);
4813
- }
4787
+ const pane2StyleAbs = internalMode === "horizontal" ? {
4788
+ position: "absolute",
4789
+ top: 0,
4790
+ bottom: 0,
4791
+ left: `calc(${p} * (100% - ${splitterSize}px) + ${splitterSize}px)`,
4792
+ right: 0,
4793
+ overflow: "auto",
4794
+ ...secondPaneStyle || {}
4795
+ } : {
4796
+ position: "absolute",
4797
+ left: 0,
4798
+ right: 0,
4799
+ top: `calc(${p} * (100% - ${splitterSize}px) + ${splitterSize}px)`,
4800
+ bottom: 0,
4801
+ overflow: "auto",
4802
+ ...secondPaneStyle || {}
4814
4803
  };
4815
- const sizes = useMemo(() => {
4816
- const leftPct = `${posResolved * 100}%`;
4817
- const rightCalc = `calc(${100 - posResolved * 100}% - ${splitterSize}px)`;
4818
- return { leftPct, rightCalc };
4819
- }, [posResolved, splitterSize]);
4820
- const rootStyle = {
4821
- display: "flex",
4822
- width: "100%",
4804
+ const splitterBase = {
4805
+ background: "rgba(0,0,0,0.08)",
4806
+ boxShadow: "inset 0 0 0 1px rgba(0,0,0,0.15)",
4807
+ zIndex: 10
4808
+ };
4809
+ const splitterAbsStyle = internalMode === "horizontal" ? {
4810
+ position: "absolute",
4811
+ top: 0,
4812
+ bottom: 0,
4813
+ left: `calc(${p} * (100% - ${splitterSize}px))`,
4814
+ width: splitterSize,
4823
4815
  height: "100%",
4824
- overflow: "hidden",
4816
+ cursor: dragging ? "col-resize" : "col-resize",
4817
+ touchAction: "none",
4818
+ pointerEvents: "auto",
4819
+ ...splitterBase,
4820
+ ...splitterStyle || {}
4821
+ } : {
4822
+ position: "absolute",
4823
+ left: 0,
4824
+ right: 0,
4825
+ top: `calc(${p} * (100% - ${splitterSize}px))`,
4826
+ height: splitterSize,
4827
+ width: "100%",
4828
+ cursor: dragging ? "row-resize" : "row-resize",
4825
4829
  touchAction: "none",
4826
- ...style || {},
4827
- flexDirection: internalMode === "horizontal" ? "row" : "column"
4830
+ pointerEvents: "auto",
4831
+ ...splitterBase,
4832
+ ...splitterStyle || {}
4828
4833
  };
4829
- const leftPaneComputed = internalMode === "horizontal" ? { width: sizes.leftPct, flex: `0 0 ${sizes.leftPct}`, overflow: "auto", ...leftPaneStyle || {} } : { height: sizes.leftPct, flex: `0 0 ${sizes.leftPct}`, overflow: "auto", ...leftPaneStyle || {} };
4830
- const rightPaneComputed = internalMode === "horizontal" ? { width: sizes.rightCalc, flex: "1 1 auto", overflow: "auto", ...rightPaneStyle || {} } : { height: sizes.rightCalc, flex: "1 1 auto", overflow: "auto", ...rightPaneStyle || {} };
4831
- const splitterComputed = internalMode === "horizontal" ? { width: `${splitterSize}px`, transform: "translateX(-50%)", height: "100%", flex: `0 0 ${splitterSize}px`, background: "rgba(0,0,0,0.08)", cursor: "col-resize", ...splitterStyle || {} } : { height: `${splitterSize}px`, transform: "translateY(-50%)", width: "100%", flex: `0 0 ${splitterSize}px`, background: "rgba(0,0,0,0.08)", cursor: "row-resize", ...splitterStyle || {} };
4832
- const dividerVisualStyle = internalMode === "horizontal" ? { height: "100%", width: "100%" } : { width: "100%", height: "100%" };
4833
- useImperativeHandle(ref, () => ({
4834
- setPosition,
4835
- setMode: (nextMode) => setInternalMode(nextMode === "vertical" ? "vertical" : "horizontal"),
4836
- getPosition: () => posResolved,
4837
- getMode: () => internalMode
4838
- }));
4839
- return createComponent("div", { "ref": containerRef, "className": className, "style": rootStyle }, createComponent("div", { "style": leftPaneComputed }, leftChild), createComponent("div", { "role": "separator", "aria-orientation": internalMode === "horizontal" ? "vertical" : "horizontal", "aria-valuemin": min, "aria-valuemax": max, "aria-valuenow": posResolved, "tabIndex": 0, "onPointerDown": onPointerDown, "onPointerCancel": () => {
4840
- draggingRef.current = false;
4841
- pointerIdRef.current = null;
4842
- }, "onKeyDown": onKeyDown, "style": splitterComputed }, createComponent("div", { "style": dividerVisualStyle })), createComponent("div", { "style": rightPaneComputed }, rightChild));
4834
+ return createComponent("div", { "ref": containerRef, "className": className, "style": {
4835
+ position: "relative",
4836
+ width: "100%",
4837
+ height: "100%",
4838
+ overflow: "hidden",
4839
+ ...style || {}
4840
+ } }, createComponent("div", { "style": pane1StyleAbs }, firstChild), createComponent("div", { "style": pane2StyleAbs }, secondChild), createComponent(DragHandle, { "onStart": handleStart, "onDelta": handleDelta, "onEnd": handleEnd, "style": splitterAbsStyle }));
4843
4841
  });
4842
+ var clamp = (v, min, max) => Math.max(min, Math.min(max, v));
4844
4843
 
4845
4844
  // .tmp/src/vlq.js
4846
4845
  var char_to_integer = {};
@@ -5301,10 +5300,10 @@ function parseXML(code2, index2, container2, look_behind = false) {
5301
5300
  if (res2[0] > index2) index2 = res2[0];
5302
5301
  else index2++;
5303
5302
  break;
5304
- case ">": {
5305
- const i3 = parseXMLContent(code2, index2, b2);
5306
- if (i3 === null) return;
5307
- if (i3 > index2) index2 = i3;
5303
+ case ">":
5304
+ const j = parseXMLContent(code2, index2, b2);
5305
+ if (j === null) return;
5306
+ if (j > index2) index2 = j;
5308
5307
  else index2++;
5309
5308
  if (b2.end) {
5310
5309
  if (container2) container2.children.push(b2);
@@ -5313,7 +5312,6 @@ function parseXML(code2, index2, container2, look_behind = false) {
5313
5312
  index2++;
5314
5313
  }
5315
5314
  break;
5316
- }
5317
5315
  case " ":
5318
5316
  case " ":
5319
5317
  case "\n":