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.
Files changed (164) hide show
  1. package/Icon/r +0 -0
  2. package/LICENSE.TXT +26 -0
  3. package/README.md +116 -0
  4. package/bin/copy-demo.js +26 -0
  5. package/bin/transpile-dir.js +112 -0
  6. package/bin/transpile.js +137 -0
  7. package/dist/lilact.development.js +9344 -0
  8. package/dist/lilact.development.js.map +1 -0
  9. package/dist/lilact.production.min.js +63 -0
  10. package/dist/lilact.production.min.js.map +1 -0
  11. package/docs/.nojekyll +1 -0
  12. package/docs/assets/hierarchy.js +1 -0
  13. package/docs/assets/highlight.css +71 -0
  14. package/docs/assets/icons.js +18 -0
  15. package/docs/assets/icons.svg +1 -0
  16. package/docs/assets/main.js +60 -0
  17. package/docs/assets/navigation.js +1 -0
  18. package/docs/assets/search.js +1 -0
  19. package/docs/assets/style.css +1633 -0
  20. package/docs/classes/accessories.ErrorBoundary.html +37 -0
  21. package/docs/classes/accessories.Suspense.html +41 -0
  22. package/docs/classes/components.Component.html +45 -0
  23. package/docs/classes/components.HTMLComponent.html +32 -0
  24. package/docs/classes/components.RootComponent.html +32 -0
  25. package/docs/classes/transition.Transition.html +31 -0
  26. package/docs/functions/accessories.Spinner.html +9 -0
  27. package/docs/functions/components.createComponent.html +8 -0
  28. package/docs/functions/components.createRoot.html +5 -0
  29. package/docs/functions/components.render.html +5 -0
  30. package/docs/functions/hooks.createContext.html +3 -0
  31. package/docs/functions/hooks.useActionState.html +3 -0
  32. package/docs/functions/hooks.useCallback.html +5 -0
  33. package/docs/functions/hooks.useContext.html +3 -0
  34. package/docs/functions/hooks.useDeferredValue.html +4 -0
  35. package/docs/functions/hooks.useEffect.html +3 -0
  36. package/docs/functions/hooks.useHook.html +5 -0
  37. package/docs/functions/hooks.useId.html +4 -0
  38. package/docs/functions/hooks.useLayoutEffect.html +3 -0
  39. package/docs/functions/hooks.useLocalStorage.html +4 -0
  40. package/docs/functions/hooks.useMemo.html +4 -0
  41. package/docs/functions/hooks.useReducer.html +6 -0
  42. package/docs/functions/hooks.useRef.html +4 -0
  43. package/docs/functions/hooks.useState.html +3 -0
  44. package/docs/functions/hooks.useTransition.html +3 -0
  45. package/docs/functions/jsx.transpileJSX.html +6 -0
  46. package/docs/functions/misc.Fragment.html +3 -0
  47. package/docs/functions/misc.classNames.html +2 -0
  48. package/docs/functions/misc.deepEqual.html +3 -0
  49. package/docs/functions/misc.findDOMNode.html +3 -0
  50. package/docs/functions/misc.getComponentByPointer.html +3 -0
  51. package/docs/functions/misc.isAsync.html +3 -0
  52. package/docs/functions/misc.isClass.html +3 -0
  53. package/docs/functions/misc.isEmpty.html +3 -0
  54. package/docs/functions/misc.isError.html +3 -0
  55. package/docs/functions/misc.isThenable.html +3 -0
  56. package/docs/functions/misc.isValidElement.html +3 -0
  57. package/docs/functions/misc.shallowEqual.html +3 -0
  58. package/docs/functions/redux.Provider.html +5 -0
  59. package/docs/functions/redux.connect.html +5 -0
  60. package/docs/functions/redux.useDispatch.html +3 -0
  61. package/docs/functions/redux.useSelector.html +5 -0
  62. package/docs/functions/redux.useStore.html +3 -0
  63. package/docs/functions/router.HashRouter.html +5 -0
  64. package/docs/functions/router.Link.html +12 -0
  65. package/docs/functions/router.NavLink.html +10 -0
  66. package/docs/functions/router.Route.html +6 -0
  67. package/docs/functions/router.Routes.html +4 -0
  68. package/docs/functions/router.useLocation.html +3 -0
  69. package/docs/functions/router.useNavigate.html +3 -0
  70. package/docs/functions/run.require.html +14 -0
  71. package/docs/functions/run.run.html +13 -0
  72. package/docs/functions/run.runScripts.html +7 -0
  73. package/docs/functions/run.traceError.html +6 -0
  74. package/docs/functions/timers.animationFramePromise.html +3 -0
  75. package/docs/functions/timers.clearInterval.html +2 -0
  76. package/docs/functions/timers.clearTimeout.html +2 -0
  77. package/docs/functions/timers.grabTimers.html +3 -0
  78. package/docs/functions/timers.pauseTimers.html +2 -0
  79. package/docs/functions/timers.releaseTimers.html +2 -0
  80. package/docs/functions/timers.resetTimers.html +2 -0
  81. package/docs/functions/timers.resumeTimers.html +2 -0
  82. package/docs/functions/timers.setInterval.html +5 -0
  83. package/docs/functions/timers.setTimeout.html +4 -0
  84. package/docs/functions/timers.timeoutPromise.html +4 -0
  85. package/docs/functions/transition.CSSTransition.html +18 -0
  86. package/docs/functions/transition.TransitionGroup.html +5 -0
  87. package/docs/hierarchy.html +1 -0
  88. package/docs/index.html +88 -0
  89. package/docs/media/icon.png +0 -0
  90. package/docs/modules/accessories.html +1 -0
  91. package/docs/modules/components.html +1 -0
  92. package/docs/modules/hooks.html +1 -0
  93. package/docs/modules/jsx.html +1 -0
  94. package/docs/modules/misc.html +1 -0
  95. package/docs/modules/redux.html +1 -0
  96. package/docs/modules/router.html +1 -0
  97. package/docs/modules/run.html +1 -0
  98. package/docs/modules/timers.html +1 -0
  99. package/docs/modules/transition.html +1 -0
  100. package/docs/modules.html +1 -0
  101. package/docs/static/demos/actionstate.jsx +41 -0
  102. package/docs/static/demos/boundary.jsx +52 -0
  103. package/docs/static/demos/context.jsx +68 -0
  104. package/docs/static/demos/css-transition.jsx +65 -0
  105. package/docs/static/demos/modal.jsx +41 -0
  106. package/docs/static/demos/proptypes.jsx +37 -0
  107. package/docs/static/demos/reducer.jsx +71 -0
  108. package/docs/static/demos/redux.jsx +58 -0
  109. package/docs/static/demos/router.jsx +153 -0
  110. package/docs/static/demos/stopwatch.jsx +42 -0
  111. package/docs/static/demos/suspense.jsx +48 -0
  112. package/docs/static/demos/transition.jsx +40 -0
  113. package/docs/static/demos/use-differed.jsx +30 -0
  114. package/docs/static/demos/usetransition.jsx +37 -0
  115. package/docs/static/index.html +212 -0
  116. package/docs/static/lilact.development.js +9344 -0
  117. package/docs/static/lilact.production.min.js +63 -0
  118. package/docs/static/prismjs/LICENSE.md +21 -0
  119. package/docs/static/prismjs/prism-jsx.min.js +1 -0
  120. package/docs/static/prismjs/prism.min.css +1 -0
  121. package/docs/static/prismjs/prism.min.js +16 -0
  122. package/docs/variables/jsx.transpilerConfig.html +1 -0
  123. package/docs/variables/misc.Children.html +10 -0
  124. package/icon.png +0 -0
  125. package/package.json +39 -0
  126. package/root/demos/actionstate.jsx +41 -0
  127. package/root/demos/boundary.jsx +52 -0
  128. package/root/demos/context.jsx +68 -0
  129. package/root/demos/css-transition.jsx +65 -0
  130. package/root/demos/modal.jsx +41 -0
  131. package/root/demos/proptypes.jsx +37 -0
  132. package/root/demos/reducer.jsx +71 -0
  133. package/root/demos/redux.jsx +58 -0
  134. package/root/demos/router.jsx +153 -0
  135. package/root/demos/stopwatch.jsx +42 -0
  136. package/root/demos/suspense.jsx +48 -0
  137. package/root/demos/transition.jsx +40 -0
  138. package/root/demos/use-differed.jsx +30 -0
  139. package/root/demos/usetransition.jsx +37 -0
  140. package/root/index.html +212 -0
  141. package/root/lilact.development.js +9344 -0
  142. package/root/lilact.production.min.js +63 -0
  143. package/root/prismjs/LICENSE.md +21 -0
  144. package/root/prismjs/prism-jsx.min.js +1 -0
  145. package/root/prismjs/prism.min.css +1 -0
  146. package/root/prismjs/prism.min.js +16 -0
  147. package/src/accessories.jsx +287 -0
  148. package/src/components.jsx +1063 -0
  149. package/src/events.jsx +175 -0
  150. package/src/hooks.jsx +461 -0
  151. package/src/jsx.addons.js +70 -0
  152. package/src/jsx.js +1168 -0
  153. package/src/lilact.jsx +115 -0
  154. package/src/loader.cjs +59 -0
  155. package/src/misc.jsx +419 -0
  156. package/src/redux.jsx +198 -0
  157. package/src/router.jsx +282 -0
  158. package/src/run.jsx +275 -0
  159. package/src/timers.jsx +313 -0
  160. package/src/transition.jsx +244 -0
  161. package/src/vlq.js +94 -0
  162. package/tsconfig.json +15 -0
  163. package/typedoc.json +23 -0
  164. package/webpack.config.js +196 -0
@@ -0,0 +1,68 @@
1
+ const { createContext, useContext, useState, render } = Lilact;
2
+ const { css, cx } = Lilact.emotion;
3
+
4
+ const ThemeContext = createContext(null);
5
+
6
+ function Form({ children }) {
7
+ return (
8
+ <Panel title="Welcome">
9
+ <Button>Sign up</Button>
10
+ <Button>Log in</Button>
11
+ </Panel>
12
+ );
13
+ }
14
+
15
+ function Panel({ title, children }) {
16
+ const theme = useContext(ThemeContext);
17
+ const className = 'panel-' + theme;
18
+ return (
19
+ <section className={cx(className,css`
20
+
21
+ &.panel-dark {
22
+ background: #333;
23
+ color: #eee;
24
+ }
25
+ `)}>
26
+ <h1 className={css`
27
+ &:hover {
28
+ color: red;
29
+ }
30
+
31
+ `}>{title}
32
+ </h1>
33
+ {children}
34
+ </section>
35
+ )
36
+ }
37
+
38
+ function Button({ children }) {
39
+ const theme = useContext(ThemeContext);
40
+ const className = 'button-' + theme;
41
+ return (
42
+ <button className={className}>
43
+ {children}
44
+ </button>
45
+ );
46
+ }
47
+
48
+ function Demo() {
49
+ const [theme, setTheme] = useState('dark');
50
+
51
+ return (
52
+ <ThemeContext.Provider value={theme}>
53
+ <Form />
54
+ <label>
55
+ <input
56
+ type="checkbox"
57
+ checked={theme === 'dark'}
58
+ onchange={(e) => {
59
+ setTheme(e.target.checked ? 'dark' : 'light')
60
+ }}
61
+ />
62
+ Use dark mode
63
+ </label>
64
+ </ThemeContext.Provider>
65
+ )
66
+ }
67
+
68
+ module.exports = Demo;
@@ -0,0 +1,65 @@
1
+ const { Transition, CSSTransition, render, useState, useRef } = Lilact;
2
+
3
+
4
+ Lilact.emotion.injectGlobal(`
5
+ .test {
6
+ -position: absolute;
7
+ transition: opacity 1000ms, transform 1000ms;
8
+ }
9
+
10
+ .test-appear {
11
+ opacity: 0;
12
+ }
13
+ .test-enter-active, .test-enter-done {
14
+ opacity: 1;
15
+ -transform: scale(1);
16
+ }
17
+ .test-exit-active, .test-exit-done {
18
+ opacity: 0.2;
19
+ -transform: scale(0.9);
20
+ }
21
+
22
+ `);
23
+
24
+
25
+ function Demo()
26
+ {
27
+ const [inProp, setInProp] = useState(false);
28
+ const nodeRef = useRef(null);
29
+
30
+ const chs = [];
31
+
32
+ for(let i=0; i<10;i++) chs.push( <div className='test'>{i}</div> );
33
+
34
+ return (
35
+ <div>
36
+
37
+ <CSSTransition in={inProp} classNames='test'
38
+
39
+ onEnter={function(){console.log('onEnter', arguments)}}
40
+ onEntering={function(){console.log('onEntering', arguments)}}
41
+ onEntered={function(){console.log('onEntered', arguments)}}
42
+ onExit={function(){console.log('onExit', arguments)}}
43
+ onExiting={function(){console.log('onExiting', arguments)}}
44
+ onExited={function(){console.log('onExited', arguments)}}
45
+
46
+ timeout={1000}
47
+
48
+ unmountOnExit={false}
49
+ mountOnEnter={false}
50
+ >
51
+ {chs}
52
+ </CSSTransition>
53
+
54
+ <button ref={nodeRef} className="test" onClick={() => setInProp(!inProp)}>
55
+ Click to {inProp?" OUT":" IN"}
56
+ </button>
57
+
58
+ <br/>
59
+ <br/>
60
+
61
+ </div>
62
+ );
63
+ }
64
+
65
+ module.exports = Demo;
@@ -0,0 +1,41 @@
1
+ const { useEffect, useRef, useState, render } = Lilact;
2
+
3
+ function ModalDialog({ isOpen, children }) {
4
+ const ref = useRef();
5
+ useEffect(() => {
6
+
7
+ if (!isOpen) {
8
+ return;
9
+ }
10
+ const dialog = ref.current;
11
+
12
+ dialog.showModal();
13
+
14
+ return () => {
15
+ dialog.close();
16
+ };
17
+ }, [isOpen]);
18
+
19
+ return <dialog ref={ref}>{children}</dialog>;
20
+ }
21
+
22
+ function Demo() {
23
+ const [show, setShow] = useState(false);
24
+ console.log(show);
25
+ return (
26
+ <>
27
+ <button onClick={() => setShow(true)}>
28
+ Open dialog
29
+ </button>
30
+ <ModalDialog isOpen={show}>
31
+ Hello there!
32
+ <br />
33
+ <button onClick={() => {
34
+ setShow(false);
35
+ }}>Close</button>
36
+ </ModalDialog>
37
+ </>
38
+ );
39
+ }
40
+
41
+ module.exports = Demo;
@@ -0,0 +1,37 @@
1
+ const { PropTypes, createRoot } = Lilact;
2
+
3
+ function UserCard({ name, age, tags, onClick }) {
4
+ return (
5
+ <div onClick={onClick} style={{border:'1px solid #ddd', padding:8, width:200}}>
6
+ <h4>{name}</h4>
7
+ <div>Age: {age}</div>
8
+ <ul>{tags.map((t,i) => <li key={i}>{t}</li>)}</ul>
9
+ </div>
10
+ );
11
+ }
12
+
13
+ UserCard.propTypes = {
14
+ name: PropTypes.string.isRequired,
15
+ age: PropTypes.number,
16
+ tags: PropTypes.arrayOf(PropTypes.string),
17
+ onClick: PropTypes.func,
18
+ };
19
+
20
+ UserCard.defaultProps = {
21
+ age: 0,
22
+ tags: [],
23
+ onClick: () => {},
24
+ };
25
+
26
+ /* App render */
27
+ function Demo() {
28
+ return (
29
+ <div><p>Check your browser console to see the logs.</p>
30
+ <UserCard name="Alex" age={29} tags={['react','js']} />
31
+ {/* Missing name -> will warn in dev console */}
32
+ <UserCard age={"not-a-number"} />
33
+ </div>
34
+ );
35
+ }
36
+
37
+ module.exports = Demo;
@@ -0,0 +1,71 @@
1
+ const { useReducer, render } = Lilact;
2
+
3
+ function createInitialState(username) {
4
+ const initialTodos = [];
5
+ for (let i = 0; i < 10; i++) {
6
+ initialTodos.push({
7
+ id: i,
8
+ text: username + "'s task #" + (i + 1)
9
+ });
10
+ }
11
+ return {
12
+ draft: '',
13
+ todos: initialTodos,
14
+ };
15
+ }
16
+
17
+ function reducer(state, action) {
18
+
19
+ switch (action.type) {
20
+ case 'changed_draft': {
21
+ return {
22
+ draft: action.nextDraft,
23
+ todos: state.todos,
24
+ };
25
+ };
26
+ case 'added_todo': {
27
+ return {
28
+ draft: '',
29
+ todos: [{
30
+ id: state.todos.length,
31
+ text: state.draft
32
+ }, ...state.todos]
33
+ }
34
+ }
35
+ }
36
+ throw Error('Unknown action: ' + action.type);
37
+ }
38
+
39
+ function Demo({ username })
40
+ {
41
+ const [state, dispatch] = useReducer(
42
+ reducer,
43
+ username,
44
+ createInitialState
45
+ );
46
+ return (
47
+ <>
48
+ <input
49
+ value={state.draft}
50
+ onChange={e => {
51
+ dispatch({
52
+ type: 'changed_draft',
53
+ nextDraft: e.target.value
54
+ })
55
+ }}
56
+ />
57
+ <button onClick={() => {
58
+ dispatch({ type: 'added_todo' });
59
+ }}>Add</button>
60
+ <ul>
61
+ {state.todos.map(item => (
62
+ <li key={item.id}>
63
+ {item.text}
64
+ </li>
65
+ ))}
66
+ </ul>
67
+ </>
68
+ );
69
+ }
70
+
71
+ module.exports = Demo;
@@ -0,0 +1,58 @@
1
+ const { Provider, useSelector, useDispatch, connect, render } = Lilact;
2
+ const { createStore } = Lilact.redux;
3
+
4
+ // Reducer + store
5
+ function counterReducer(state = { count: 0 }, action) {
6
+ switch (action.type) {
7
+ case "INCREMENT": return { count: state.count + 1 };
8
+ case "DECREMENT": return { count: state.count - 1 };
9
+ default: return state;
10
+ }
11
+ }
12
+ const store = createStore(counterReducer);
13
+
14
+ // Hooks-based component
15
+ function CounterHooks() {
16
+ const count = useSelector(state => state.count);
17
+ const dispatch = useDispatch();
18
+ return (
19
+ <div>
20
+ <h3>Hooks Counter</h3>
21
+ <div>Count: {count}</div>
22
+ <button onClick={() => dispatch({ type: "DECREMENT" })}>-</button>
23
+ <button onClick={() => dispatch({ type: "INCREMENT" })}>+</button>
24
+ </div>
25
+ );
26
+ }
27
+
28
+ // connect-based component
29
+ function CounterView({ count, increment, decrement }) {
30
+ return (
31
+ <div>
32
+ <h3>Connected Counter</h3>
33
+ <div>Count: {count}</div>
34
+ <button onClick={decrement}>-</button>
35
+ <button onClick={increment}>+</button>
36
+ </div>
37
+ );
38
+ }
39
+ const mapState = (state) => ({ count: state.count });
40
+ const mapDispatch = (dispatch) => ({
41
+
42
+ increment: () => { dispatch({ type: "INCREMENT" })},
43
+ decrement: () => { dispatch({ type: "DECREMENT" })}
44
+ });
45
+ const ConnectedCounter = connect(mapState, mapDispatch)(CounterView);
46
+
47
+ function Demo({ username })
48
+ {
49
+ return <Provider store={store}>
50
+ <div>
51
+ <CounterHooks />
52
+ <ConnectedCounter />
53
+ </div>
54
+ </Provider>;
55
+ }
56
+
57
+ module.exports = Demo;
58
+
@@ -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;