lilact 0.0.0
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.
- package/Icon/r +0 -0
- package/LICENSE.TXT +26 -0
- package/README.md +116 -0
- package/bin/copy-demo.js +26 -0
- package/bin/transpile-dir.js +112 -0
- package/bin/transpile.js +137 -0
- package/dist/lilact.development.js +9344 -0
- package/dist/lilact.development.js.map +1 -0
- package/dist/lilact.production.min.js +63 -0
- package/dist/lilact.production.min.js.map +1 -0
- package/docs/.nojekyll +1 -0
- package/docs/assets/hierarchy.js +1 -0
- package/docs/assets/highlight.css +71 -0
- package/docs/assets/icons.js +18 -0
- package/docs/assets/icons.svg +1 -0
- package/docs/assets/main.js +60 -0
- package/docs/assets/navigation.js +1 -0
- package/docs/assets/search.js +1 -0
- package/docs/assets/style.css +1633 -0
- package/docs/classes/accessories.ErrorBoundary.html +37 -0
- package/docs/classes/accessories.Suspense.html +41 -0
- package/docs/classes/components.Component.html +45 -0
- package/docs/classes/components.HTMLComponent.html +32 -0
- package/docs/classes/components.RootComponent.html +32 -0
- package/docs/classes/transition.Transition.html +31 -0
- package/docs/functions/accessories.Spinner.html +9 -0
- package/docs/functions/components.createComponent.html +8 -0
- package/docs/functions/components.createRoot.html +5 -0
- package/docs/functions/components.render.html +5 -0
- package/docs/functions/hooks.createContext.html +3 -0
- package/docs/functions/hooks.useActionState.html +3 -0
- package/docs/functions/hooks.useCallback.html +5 -0
- package/docs/functions/hooks.useContext.html +3 -0
- package/docs/functions/hooks.useDeferredValue.html +4 -0
- package/docs/functions/hooks.useEffect.html +3 -0
- package/docs/functions/hooks.useHook.html +5 -0
- package/docs/functions/hooks.useId.html +4 -0
- package/docs/functions/hooks.useLayoutEffect.html +3 -0
- package/docs/functions/hooks.useLocalStorage.html +4 -0
- package/docs/functions/hooks.useMemo.html +4 -0
- package/docs/functions/hooks.useReducer.html +6 -0
- package/docs/functions/hooks.useRef.html +4 -0
- package/docs/functions/hooks.useState.html +3 -0
- package/docs/functions/hooks.useTransition.html +3 -0
- package/docs/functions/jsx.transpileJSX.html +6 -0
- package/docs/functions/misc.Fragment.html +3 -0
- package/docs/functions/misc.classNames.html +2 -0
- package/docs/functions/misc.deepEqual.html +3 -0
- package/docs/functions/misc.findDOMNode.html +3 -0
- package/docs/functions/misc.getComponentByPointer.html +3 -0
- package/docs/functions/misc.isAsync.html +3 -0
- package/docs/functions/misc.isClass.html +3 -0
- package/docs/functions/misc.isEmpty.html +3 -0
- package/docs/functions/misc.isError.html +3 -0
- package/docs/functions/misc.isThenable.html +3 -0
- package/docs/functions/misc.isValidElement.html +3 -0
- package/docs/functions/misc.shallowEqual.html +3 -0
- package/docs/functions/redux.Provider.html +5 -0
- package/docs/functions/redux.connect.html +5 -0
- package/docs/functions/redux.useDispatch.html +3 -0
- package/docs/functions/redux.useSelector.html +5 -0
- package/docs/functions/redux.useStore.html +3 -0
- package/docs/functions/router.HashRouter.html +5 -0
- package/docs/functions/router.Link.html +12 -0
- package/docs/functions/router.NavLink.html +10 -0
- package/docs/functions/router.Route.html +6 -0
- package/docs/functions/router.Routes.html +4 -0
- package/docs/functions/router.useLocation.html +3 -0
- package/docs/functions/router.useNavigate.html +3 -0
- package/docs/functions/run.require.html +14 -0
- package/docs/functions/run.run.html +13 -0
- package/docs/functions/run.runScripts.html +7 -0
- package/docs/functions/run.traceError.html +6 -0
- package/docs/functions/timers.animationFramePromise.html +3 -0
- package/docs/functions/timers.clearInterval.html +2 -0
- package/docs/functions/timers.clearTimeout.html +2 -0
- package/docs/functions/timers.grabTimers.html +3 -0
- package/docs/functions/timers.pauseTimers.html +2 -0
- package/docs/functions/timers.releaseTimers.html +2 -0
- package/docs/functions/timers.resetTimers.html +2 -0
- package/docs/functions/timers.resumeTimers.html +2 -0
- package/docs/functions/timers.setInterval.html +5 -0
- package/docs/functions/timers.setTimeout.html +4 -0
- package/docs/functions/timers.timeoutPromise.html +4 -0
- package/docs/functions/transition.CSSTransition.html +18 -0
- package/docs/functions/transition.TransitionGroup.html +5 -0
- package/docs/hierarchy.html +1 -0
- package/docs/index.html +88 -0
- package/docs/media/icon.png +0 -0
- package/docs/modules/accessories.html +1 -0
- package/docs/modules/components.html +1 -0
- package/docs/modules/hooks.html +1 -0
- package/docs/modules/jsx.html +1 -0
- package/docs/modules/misc.html +1 -0
- package/docs/modules/redux.html +1 -0
- package/docs/modules/router.html +1 -0
- package/docs/modules/run.html +1 -0
- package/docs/modules/timers.html +1 -0
- package/docs/modules/transition.html +1 -0
- package/docs/modules.html +1 -0
- package/docs/static/demos/actionstate.jsx +41 -0
- package/docs/static/demos/boundary.jsx +52 -0
- package/docs/static/demos/context.jsx +68 -0
- package/docs/static/demos/css-transition.jsx +65 -0
- package/docs/static/demos/modal.jsx +41 -0
- package/docs/static/demos/proptypes.jsx +37 -0
- package/docs/static/demos/reducer.jsx +71 -0
- package/docs/static/demos/redux.jsx +58 -0
- package/docs/static/demos/router.jsx +153 -0
- package/docs/static/demos/stopwatch.jsx +42 -0
- package/docs/static/demos/suspense.jsx +48 -0
- package/docs/static/demos/transition.jsx +40 -0
- package/docs/static/demos/use-differed.jsx +30 -0
- package/docs/static/demos/usetransition.jsx +37 -0
- package/docs/static/index.html +212 -0
- package/docs/static/lilact.development.js +9344 -0
- package/docs/static/lilact.production.min.js +63 -0
- package/docs/static/prismjs/LICENSE.md +21 -0
- package/docs/static/prismjs/prism-jsx.min.js +1 -0
- package/docs/static/prismjs/prism.min.css +1 -0
- package/docs/static/prismjs/prism.min.js +16 -0
- package/docs/variables/jsx.transpilerConfig.html +1 -0
- package/docs/variables/misc.Children.html +10 -0
- package/icon.png +0 -0
- package/package.json +39 -0
- package/root/demos/actionstate.jsx +41 -0
- package/root/demos/boundary.jsx +52 -0
- package/root/demos/context.jsx +68 -0
- package/root/demos/css-transition.jsx +65 -0
- package/root/demos/modal.jsx +41 -0
- package/root/demos/proptypes.jsx +37 -0
- package/root/demos/reducer.jsx +71 -0
- package/root/demos/redux.jsx +58 -0
- package/root/demos/router.jsx +153 -0
- package/root/demos/stopwatch.jsx +42 -0
- package/root/demos/suspense.jsx +48 -0
- package/root/demos/transition.jsx +40 -0
- package/root/demos/use-differed.jsx +30 -0
- package/root/demos/usetransition.jsx +37 -0
- package/root/index.html +212 -0
- package/root/lilact.development.js +9344 -0
- package/root/lilact.production.min.js +63 -0
- package/root/prismjs/LICENSE.md +21 -0
- package/root/prismjs/prism-jsx.min.js +1 -0
- package/root/prismjs/prism.min.css +1 -0
- package/root/prismjs/prism.min.js +16 -0
- package/src/accessories.jsx +287 -0
- package/src/components.jsx +1063 -0
- package/src/events.jsx +175 -0
- package/src/hooks.jsx +461 -0
- package/src/jsx.addons.js +70 -0
- package/src/jsx.js +1168 -0
- package/src/lilact.jsx +115 -0
- package/src/loader.cjs +59 -0
- package/src/misc.jsx +419 -0
- package/src/redux.jsx +198 -0
- package/src/router.jsx +282 -0
- package/src/run.jsx +275 -0
- package/src/timers.jsx +313 -0
- package/src/transition.jsx +244 -0
- package/src/vlq.js +94 -0
- package/tsconfig.json +15 -0
- package/typedoc.json +23 -0
- package/webpack.config.js +196 -0
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
const { createRoot,HashRouter,
|
|
2
|
+
NavLink,
|
|
3
|
+
Routes,
|
|
4
|
+
Route,
|
|
5
|
+
useNavigate,
|
|
6
|
+
useLocation,
|
|
7
|
+
useState
|
|
8
|
+
} = Lilact;
|
|
9
|
+
|
|
10
|
+
/* Simple pages */
|
|
11
|
+
function Home() {
|
|
12
|
+
const loc = useLocation();
|
|
13
|
+
return (
|
|
14
|
+
<div>
|
|
15
|
+
<h2>Home</h2>
|
|
16
|
+
<p>Welcome to the home page.</p>
|
|
17
|
+
{loc.state?.from && (
|
|
18
|
+
<p>
|
|
19
|
+
<strong>Arrived from:</strong> {loc.state.from}
|
|
20
|
+
</p>
|
|
21
|
+
)}
|
|
22
|
+
</div>
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function About() {
|
|
27
|
+
const loc = useLocation();
|
|
28
|
+
return (
|
|
29
|
+
<div>
|
|
30
|
+
<h2>About</h2>
|
|
31
|
+
<p>This is the about page.</p>
|
|
32
|
+
{loc.state?.message && (
|
|
33
|
+
<p>
|
|
34
|
+
<strong>Message:</strong> {loc.state.message}
|
|
35
|
+
</p>
|
|
36
|
+
)}
|
|
37
|
+
</div>
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function Profile({ name = "Guest" }) {
|
|
42
|
+
const loc = useLocation();
|
|
43
|
+
return (
|
|
44
|
+
<div>
|
|
45
|
+
<h2>Profile</h2>
|
|
46
|
+
<p>Signed in as: {name}</p>
|
|
47
|
+
{loc.state?.note && (
|
|
48
|
+
<p>
|
|
49
|
+
<strong>Note:</strong> {loc.state.note}
|
|
50
|
+
</p>
|
|
51
|
+
)}
|
|
52
|
+
</div>
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function NotFound() {
|
|
57
|
+
const loc = useLocation();
|
|
58
|
+
return (
|
|
59
|
+
<div>
|
|
60
|
+
<h2>404</h2>
|
|
61
|
+
<p>No match for <code>{loc.pathname}</code></p>
|
|
62
|
+
</div>
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/* Component demonstrating useNavigate and NavLink state */
|
|
67
|
+
function NavControls() {
|
|
68
|
+
const navigate = useNavigate();
|
|
69
|
+
|
|
70
|
+
return (
|
|
71
|
+
<div style={{ marginTop: 12 }}>
|
|
72
|
+
<button onClick={() => navigate("/", { state: { from: "NavControls button" } })}>
|
|
73
|
+
Go Home (with state)
|
|
74
|
+
</button>
|
|
75
|
+
<button
|
|
76
|
+
onClick={() =>
|
|
77
|
+
navigate("/about", { state: { message: "Hello from NavControls" } })
|
|
78
|
+
}
|
|
79
|
+
style={{ marginLeft: 8 }}
|
|
80
|
+
>
|
|
81
|
+
Go About (with state)
|
|
82
|
+
</button>
|
|
83
|
+
<button
|
|
84
|
+
onClick={() =>
|
|
85
|
+
navigate("/profile", { replace: true, state: { note: "Profile via replace" } })
|
|
86
|
+
}
|
|
87
|
+
style={{ marginLeft: 8 }}
|
|
88
|
+
>
|
|
89
|
+
Go Profile (replace + state)
|
|
90
|
+
</button>
|
|
91
|
+
<button onClick={() => navigate(-1)} style={{ marginLeft: 8 }}>
|
|
92
|
+
Back
|
|
93
|
+
</button>
|
|
94
|
+
</div>
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/* App with nav and routes; NavLink uses 'to' as object with pathname + state */
|
|
99
|
+
function Demo() {
|
|
100
|
+
const navStyle = {
|
|
101
|
+
padding: 12,
|
|
102
|
+
borderBottom: "1px solid #ddd",
|
|
103
|
+
marginBottom: 12,
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
const linkStyle = ({ isActive }) => ({
|
|
107
|
+
marginRight: 12,
|
|
108
|
+
padding: "6px 8px",
|
|
109
|
+
borderRadius: 4,
|
|
110
|
+
textDecoration: "none",
|
|
111
|
+
color: isActive ? "#fff" : "#0366d6",
|
|
112
|
+
background: isActive ? "#0366d6" : "transparent",
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
return (
|
|
116
|
+
<HashRouter>
|
|
117
|
+
<nav style={navStyle}>
|
|
118
|
+
<NavLink to={{ pathname: "/" }} end style={linkStyle} state={{ from: "NavLink Home" }}>
|
|
119
|
+
Home
|
|
120
|
+
</NavLink>
|
|
121
|
+
|
|
122
|
+
<NavLink
|
|
123
|
+
to={{ pathname: "/about" }}
|
|
124
|
+
style={linkStyle}
|
|
125
|
+
state={{ message: "Hello from NavLink About" }}
|
|
126
|
+
>
|
|
127
|
+
About
|
|
128
|
+
</NavLink>
|
|
129
|
+
|
|
130
|
+
<NavLink
|
|
131
|
+
to={{ pathname: "/profile" }}
|
|
132
|
+
style={linkStyle}
|
|
133
|
+
state={{ note: "Visited via NavLink" }}
|
|
134
|
+
>
|
|
135
|
+
Profile
|
|
136
|
+
</NavLink>
|
|
137
|
+
</nav>
|
|
138
|
+
|
|
139
|
+
<main style={{ padding: 12 }}>
|
|
140
|
+
<Routes>
|
|
141
|
+
<Route path="/" element={<Home />} />
|
|
142
|
+
<Route path="/about" element={<About />} />
|
|
143
|
+
<Route path="/profile" element={<Profile name="Alice" />} />
|
|
144
|
+
<Route path="*" element={<NotFound />} />
|
|
145
|
+
</Routes>
|
|
146
|
+
|
|
147
|
+
<NavControls />
|
|
148
|
+
</main>
|
|
149
|
+
</HashRouter>
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
module.exports = Demo;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
const { useState, useRef, render } = Lilact;
|
|
2
|
+
|
|
3
|
+
function Demo()
|
|
4
|
+
{
|
|
5
|
+
|
|
6
|
+
const [startTime, setStartTime] = useState(null);
|
|
7
|
+
const [now, setNow] = useState(null);
|
|
8
|
+
const intervalRef = useRef(null);
|
|
9
|
+
|
|
10
|
+
function handleStart() {
|
|
11
|
+
setStartTime(Date.now());
|
|
12
|
+
setNow(Date.now());
|
|
13
|
+
|
|
14
|
+
clearInterval(intervalRef.current);
|
|
15
|
+
intervalRef.current = setInterval(() => {
|
|
16
|
+
setNow(Date.now());
|
|
17
|
+
}, 50);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function handleStop() {
|
|
21
|
+
clearInterval(intervalRef.current);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
let secondsPassed = 0;
|
|
25
|
+
if (startTime != null && now != null) {
|
|
26
|
+
secondsPassed = (now - startTime) / 1000;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return (
|
|
30
|
+
<>
|
|
31
|
+
<h1>Time passed: {secondsPassed.toFixed(3)} </h1>
|
|
32
|
+
<button onClick={handleStart} >
|
|
33
|
+
Start
|
|
34
|
+
</button>
|
|
35
|
+
<button onClick={handleStop} >
|
|
36
|
+
Stop
|
|
37
|
+
</button>
|
|
38
|
+
</>
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
module.exports = Demo;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
const {Suspense, Spinner} = Lilact;
|
|
2
|
+
|
|
3
|
+
// resource factory that throws its internal promise until resolved
|
|
4
|
+
function createResource(delay, value) {
|
|
5
|
+
let status = "pending";
|
|
6
|
+
let result;
|
|
7
|
+
const p = new Promise((res) => setTimeout(() => res(value), delay)).then(
|
|
8
|
+
(r) => {
|
|
9
|
+
status = "success";
|
|
10
|
+
result = r;
|
|
11
|
+
},
|
|
12
|
+
(e) => {
|
|
13
|
+
status = "error";
|
|
14
|
+
result = e;
|
|
15
|
+
}
|
|
16
|
+
);
|
|
17
|
+
return {
|
|
18
|
+
read() {
|
|
19
|
+
if (status === "pending") throw p;
|
|
20
|
+
if (status === "error") throw result;
|
|
21
|
+
return result;
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const r1 = createResource(500, "First ready (500ms)");
|
|
27
|
+
const r2 = createResource(1200, "Second ready (1200ms)");
|
|
28
|
+
|
|
29
|
+
function Child1() {
|
|
30
|
+
const v = r1.read();
|
|
31
|
+
return <div>{v}</div>;
|
|
32
|
+
}
|
|
33
|
+
function Child2() {
|
|
34
|
+
const v = r2.read();
|
|
35
|
+
return <div>{v}</div>;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function Demo() {
|
|
39
|
+
return (
|
|
40
|
+
<Suspense minDelay={200} minShowTime={400} fallback={<Spinner/>}>
|
|
41
|
+
<Child1 />
|
|
42
|
+
<Child2 />
|
|
43
|
+
</Suspense>
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
module.exports = Demo;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
const { useState, Transition } = Lilact;
|
|
2
|
+
|
|
3
|
+
function Demo() {
|
|
4
|
+
const [inProp, setInProp] = useState(false);
|
|
5
|
+
|
|
6
|
+
const toggleVisibility = () => {
|
|
7
|
+
setInProp((prev) => !prev);
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
return <>
|
|
11
|
+
<p>See the console for logs.</p>
|
|
12
|
+
<div>
|
|
13
|
+
<button onClick={toggleVisibility}>
|
|
14
|
+
{inProp ? 'Hide Component' : 'Show Component'}
|
|
15
|
+
</button>
|
|
16
|
+
<Transition
|
|
17
|
+
in={inProp}
|
|
18
|
+
timeout={1000}
|
|
19
|
+
mountOnEnter={false}
|
|
20
|
+
onEnter={() => console.log('Enter')}
|
|
21
|
+
onExit={() => console.log('Exit')}
|
|
22
|
+
onEntering={() => console.log('Entering')}
|
|
23
|
+
onExiting={() => console.log('Exiting')}
|
|
24
|
+
onEntered={() => console.log('Entered')}
|
|
25
|
+
onExited={() => console.log('Exited')}
|
|
26
|
+
>
|
|
27
|
+
{(state) => (
|
|
28
|
+
<div>
|
|
29
|
+
{state === 'entering' && <p>Hello, World! (Entering)</p>}
|
|
30
|
+
{state === 'exiting' && <p>Hello, World! (Exiting)</p>}
|
|
31
|
+
{state === 'entered' && <p>Hello, World! (Visible)</p>}
|
|
32
|
+
{state === 'exited' && <p>Hello, World! (Hidden)</p>}
|
|
33
|
+
</div>
|
|
34
|
+
)}
|
|
35
|
+
</Transition>
|
|
36
|
+
</div>
|
|
37
|
+
</>;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
module.exports = Demo;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
const { useState, useDeferredValue, render } = Lilact;
|
|
2
|
+
|
|
3
|
+
function ExpensiveList({ query }) {
|
|
4
|
+
const items = Array.from({ length: 5000 }, (_, i) => `${query} item ${i}`);
|
|
5
|
+
return (
|
|
6
|
+
<ul>
|
|
7
|
+
{items.map((it) => (
|
|
8
|
+
<li key={it}>{it}</li>
|
|
9
|
+
))}
|
|
10
|
+
</ul>
|
|
11
|
+
);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function Demo() {
|
|
15
|
+
const [q, setQ] = useState("");
|
|
16
|
+
const deferredQ = useDeferredValue(q, "loading...");
|
|
17
|
+
|
|
18
|
+
return (
|
|
19
|
+
<div>
|
|
20
|
+
<input value={q} onChange={(e) => setQ(e.target.value)} placeholder="Type to search..." />
|
|
21
|
+
<p>Live: {q}</p>
|
|
22
|
+
<p>Deferred: {deferredQ}</p>
|
|
23
|
+
<div style={{ height: 300, overflow: "auto", border: "1px solid #ccc" }}>
|
|
24
|
+
<ExpensiveList query={deferredQ} />
|
|
25
|
+
</div>
|
|
26
|
+
</div>
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
module.exports = Demo;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
const { useTransition, useState, useCallback, useId, render } = Lilact;
|
|
2
|
+
const { css, cx } = Lilact.emotion;
|
|
3
|
+
|
|
4
|
+
const Demo = ()=>{
|
|
5
|
+
|
|
6
|
+
const [isPending, startTrans] = useTransition();
|
|
7
|
+
const [bg,setBg] = useState("yellow");
|
|
8
|
+
|
|
9
|
+
const id = useId();
|
|
10
|
+
|
|
11
|
+
const startCB = useCallback ( ()=>{
|
|
12
|
+
|
|
13
|
+
setBg("pink");
|
|
14
|
+
|
|
15
|
+
startTrans( async ()=>{
|
|
16
|
+
|
|
17
|
+
await new Promise( (res,rej)=>{setTimeout(res, 1000)} );
|
|
18
|
+
|
|
19
|
+
setBg("lightgreen");
|
|
20
|
+
|
|
21
|
+
startTrans( async()=> {
|
|
22
|
+
await new Promise( (res,rej)=>{setTimeout(res, 1000)} );
|
|
23
|
+
});
|
|
24
|
+
} )
|
|
25
|
+
}, [] );
|
|
26
|
+
return (
|
|
27
|
+
|
|
28
|
+
<div className={css({background:bg})}>
|
|
29
|
+
<h4>{id}</h4>
|
|
30
|
+
{isPending? <b>PENDING...</b> : <i>NOT PENDING</i>}
|
|
31
|
+
<button onclick={startCB}>START CB</button>
|
|
32
|
+
</div>
|
|
33
|
+
|
|
34
|
+
);
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
module.exports = Demo;
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8"/>
|
|
5
|
+
<title>Lilact Demo</title>
|
|
6
|
+
<script src='./lilact.development.js' type="module"></script>
|
|
7
|
+
|
|
8
|
+
<script src="prismjs/prism.min.js"></script>
|
|
9
|
+
<script src="prismjs/prism-jsx.min.js"></script>
|
|
10
|
+
<link rel="stylesheet" href="prismjs/prism.min.css">
|
|
11
|
+
|
|
12
|
+
</head>
|
|
13
|
+
|
|
14
|
+
<body></body>
|
|
15
|
+
|
|
16
|
+
<script type='text/jsx'>
|
|
17
|
+
|
|
18
|
+
const { useRef, useEffect, useState, Suspense, Spinner, run, render } = Lilact;
|
|
19
|
+
const { css,cx,injectGlobal } = Lilact.emotion;
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
const cache = new Map();
|
|
23
|
+
|
|
24
|
+
function createResource(url) {
|
|
25
|
+
let record = cache.get(url);
|
|
26
|
+
if (!record) {
|
|
27
|
+
record = {
|
|
28
|
+
status: "pending",
|
|
29
|
+
promise: null,
|
|
30
|
+
data: null,
|
|
31
|
+
error: null,
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
record.promise = fetch(url)
|
|
35
|
+
.then(r => {
|
|
36
|
+
if (!r.ok) throw new Error(`HTTP ${r.status}`);
|
|
37
|
+
return r.text();
|
|
38
|
+
})
|
|
39
|
+
.then(data => {
|
|
40
|
+
record.status = "success";
|
|
41
|
+
record.data = data;
|
|
42
|
+
})
|
|
43
|
+
.catch(err => {
|
|
44
|
+
record.status = "error";
|
|
45
|
+
record.error = err;
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
cache.set(url, record);
|
|
49
|
+
}
|
|
50
|
+
return {
|
|
51
|
+
read() {
|
|
52
|
+
if (record.status === "pending") throw record.promise;
|
|
53
|
+
if (record.status === "error") throw record.error;
|
|
54
|
+
return record.data;
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
injectGlobal({"*:not(code):not(code *)" : {fontFamily: "Ubuntu, 'Segoe UI', 'Noto Sans', helvetica, sans", fontSize: "14px"}});
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
injectGlobal({ code: { whiteSpace: "pre !important",
|
|
65
|
+
padding: "10px 0",
|
|
66
|
+
fontSize: "14px !important",
|
|
67
|
+
display: "block",
|
|
68
|
+
overflowWrap: "anywhere" }
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
injectGlobal({ code: { whiteSpace: "pre !important",
|
|
73
|
+
padding: "10px 0",
|
|
74
|
+
fontSize: "14px !important",
|
|
75
|
+
display: "block",
|
|
76
|
+
overflowWrap: "anywhere" }
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
const outer = css({
|
|
81
|
+
display: "flex",
|
|
82
|
+
flexDirection: "row",
|
|
83
|
+
gap: 2,
|
|
84
|
+
alignItems: "stretch",
|
|
85
|
+
width: "100%",
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
const collapsible = css({
|
|
89
|
+
width: "100%",
|
|
90
|
+
display: "block",
|
|
91
|
+
fontSize: "16px"
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
const responsiveOuter = css({
|
|
95
|
+
"@media (max-width: 600px)": {
|
|
96
|
+
flexDirection: "column",
|
|
97
|
+
},
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
const pane = css({ flex: "1 1 0",
|
|
101
|
+
border: "1px solid",
|
|
102
|
+
height: "400px",
|
|
103
|
+
minHeight: "400px",
|
|
104
|
+
overflowY: "auto",
|
|
105
|
+
padding: "10px"
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
function DemoView({ file })
|
|
111
|
+
{
|
|
112
|
+
const [isOpen, setOpen] = useState(false);
|
|
113
|
+
|
|
114
|
+
const viewRef = useRef();
|
|
115
|
+
const codeRef = useRef();
|
|
116
|
+
|
|
117
|
+
const resource = createResource("./demos/"+file);
|
|
118
|
+
const code = resource.read(); // Suspense will handle the promise
|
|
119
|
+
|
|
120
|
+
if(isOpen) {
|
|
121
|
+
useEffect(() => {
|
|
122
|
+
const Comp = run(code);
|
|
123
|
+
Lilact.render(<Comp/>, viewRef.current);
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
useEffect(() => {
|
|
127
|
+
Prism.highlightElement(codeRef.current);
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
return <>
|
|
132
|
+
<button onClick={()=>setOpen(!isOpen)} className={collapsible}>
|
|
133
|
+
{(isOpen?'- ':'+ ')+file}
|
|
134
|
+
</button>
|
|
135
|
+
{isOpen &&
|
|
136
|
+
<div style={{width:"100%"}}>
|
|
137
|
+
<div className={cx(responsiveOuter,outer)}>
|
|
138
|
+
<div className={pane} style={{background:"#f5f2f0"}}>
|
|
139
|
+
<code className="language-jsx" ref={codeRef}>{code}</code>
|
|
140
|
+
</div>
|
|
141
|
+
<div className={pane} ref={viewRef}></div>
|
|
142
|
+
</div>
|
|
143
|
+
</div>
|
|
144
|
+
}
|
|
145
|
+
</>;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
function DemoBlock({file})
|
|
150
|
+
{
|
|
151
|
+
return <>
|
|
152
|
+
<div>
|
|
153
|
+
<Suspense fallback={<Spinner/>}>
|
|
154
|
+
<DemoView file={file} />
|
|
155
|
+
</Suspense>
|
|
156
|
+
</div>
|
|
157
|
+
</>
|
|
158
|
+
;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
function App()
|
|
163
|
+
{
|
|
164
|
+
const demos =[
|
|
165
|
+
'stopwatch.jsx',
|
|
166
|
+
'modal.jsx',
|
|
167
|
+
'actionstate.jsx',
|
|
168
|
+
'context.jsx',
|
|
169
|
+
'proptypes.jsx',
|
|
170
|
+
'router.jsx',
|
|
171
|
+
'use-differed.jsx',
|
|
172
|
+
'boundary.jsx',
|
|
173
|
+
'css-transition.jsx',
|
|
174
|
+
'reducer.jsx',
|
|
175
|
+
'usetransition.jsx',
|
|
176
|
+
'redux.jsx',
|
|
177
|
+
'suspense.jsx',
|
|
178
|
+
'transition.jsx'
|
|
179
|
+
];
|
|
180
|
+
|
|
181
|
+
return <>
|
|
182
|
+
<h3>Lilact Demos</h3>
|
|
183
|
+
|
|
184
|
+
<p>These scripts are transpiled and run directly in your browser. You have already loaded the complete Lilact toolchain!</p>
|
|
185
|
+
|
|
186
|
+
<p>These examples are not meant to be pretty.
|
|
187
|
+
|
|
188
|
+
These are bare minimum examples of the React API implemented in Lilact.</p>
|
|
189
|
+
|
|
190
|
+
<p>Note that we are using the development version here to have proptypes warnings.
|
|
191
|
+
If you switch to production mode proptypes won't check anything.</p>
|
|
192
|
+
|
|
193
|
+
<p>In many examples like boundary or proptypes you should have your browser console opened to see the logs.</p>
|
|
194
|
+
|
|
195
|
+
<p>See the{" "}<a href="../">Lilact Documentation</a>{" "}for more info.</p>
|
|
196
|
+
|
|
197
|
+
{demos.map((x)=><DemoBlock file={x}/>)}
|
|
198
|
+
|
|
199
|
+
<hr/>
|
|
200
|
+
<p>
|
|
201
|
+
Copyright (C) 2024-2026 Arash Kazemi {" <contact.arash.kazemi@gmail.com>"}. All rights reserved.
|
|
202
|
+
<br/><br/>
|
|
203
|
+
Lilact project is subject to the terms of BSD-2-Clause License. See the `LICENSE.TXT` file for more details.
|
|
204
|
+
</p>
|
|
205
|
+
</>
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
render(<App/>, document.body);
|
|
209
|
+
|
|
210
|
+
</script>
|
|
211
|
+
|
|
212
|
+
</html>
|