lilact 0.16.3 → 0.18.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/dist/lilact.development.js +227 -151
- package/dist/lilact.development.js.map +3 -3
- package/dist/lilact.development.min.js +20 -20
- package/dist/lilact.development.min.js.map +3 -3
- package/dist/lilact.production.min.js +20 -20
- package/docs/assets/hierarchy.js +1 -1
- package/docs/assets/navigation.js +1 -1
- package/docs/assets/search.js +1 -1
- package/docs/classes/accessories.ErrorBoundary.html +8 -8
- package/docs/classes/accessories.Suspense.html +7 -7
- package/docs/classes/components.Component.html +11 -11
- package/docs/classes/components.HTMLComponent.html +11 -11
- package/docs/classes/components.RootComponent.html +11 -11
- package/docs/functions/components.createComponent.html +1 -1
- package/docs/functions/components.createRoot.html +1 -1
- package/docs/functions/components.memo.html +7 -0
- package/docs/functions/components.render.html +1 -1
- package/docs/functions/hooks.startTransition.html +6 -0
- package/docs/functions/hooks.useActionState.html +1 -1
- package/docs/functions/hooks.useDebugValue.html +5 -0
- package/docs/functions/hooks.useDeferredValue.html +1 -1
- package/docs/functions/hooks.useEffect.html +5 -4
- package/docs/functions/hooks.useImperativeHandle.html +1 -1
- package/docs/functions/hooks.useInsertionEffect.html +6 -0
- package/docs/functions/hooks.useLayoutEffect.html +3 -2
- package/docs/functions/hooks.useMemo.html +3 -2
- package/docs/functions/hooks.useReducer.html +1 -1
- package/docs/functions/misc.Fragment.html +2 -2
- package/docs/functions/misc.deepEqual.html +1 -1
- package/docs/functions/misc.findDOMNode.html +1 -1
- package/docs/functions/misc.forwardRef.html +1 -1
- package/docs/functions/misc.getComponentByPointer.html +1 -1
- package/docs/functions/misc.isAsync.html +1 -1
- package/docs/functions/misc.isClass.html +1 -1
- package/docs/functions/misc.isEmpty.html +1 -1
- package/docs/functions/misc.isError.html +1 -1
- package/docs/functions/misc.isThenable.html +1 -1
- package/docs/functions/{misc.isValidElement.html → misc.isValidComponent.html} +1 -1
- package/docs/functions/misc.shallowEqual.html +3 -2
- package/docs/functions/misc.toBool.html +1 -1
- package/docs/functions/timers.timeoutPromise.html +10 -7
- package/docs/hierarchy.html +1 -1
- package/docs/modules/components.html +1 -1
- package/docs/modules/hooks.html +1 -1
- package/docs/modules/misc.html +1 -1
- package/docs/static/demos/actionstate.jsx +2 -2
- package/docs/static/demos/memo.jsx +26 -0
- package/docs/static/demos/priorities.jsx +68 -0
- package/docs/static/index.html +3 -1
- package/docs/static/lilact.development.js +227 -151
- package/docs/static/lilact.development.js.map +3 -3
- package/docs/static/lilact.development.min.js +20 -20
- package/docs/static/lilact.development.min.js.map +3 -3
- package/docs/static/lilact.production.min.js +20 -20
- package/docs/variables/misc.Children.html +2 -2
- package/docs/variables/misc.isValidElement.html +7 -0
- package/examples/demos/actionstate.jsx +2 -2
- package/examples/demos/memo.jsx +26 -0
- package/examples/demos/priorities.jsx +68 -0
- package/examples/index.html +3 -1
- package/examples/lilact.development.js +227 -151
- package/examples/lilact.development.js.map +3 -3
- package/examples/lilact.development.min.js +20 -20
- package/examples/lilact.development.min.js.map +3 -3
- package/examples/lilact.production.min.js +20 -20
- package/package.json +1 -1
- package/src/components.jsx +126 -40
- package/src/hooks.jsx +84 -11
- package/src/lilact.jsx +1 -1
- package/src/misc.jsx +13 -8
package/src/components.jsx
CHANGED
|
@@ -94,7 +94,12 @@ class ComponentCache
|
|
|
94
94
|
{
|
|
95
95
|
this.current_map.forEach( (arr)=>{
|
|
96
96
|
arr.slice(arr[IDX]).forEach((ex)=>{
|
|
97
|
-
if(ex.cleanup)
|
|
97
|
+
if(ex.cleanup) {
|
|
98
|
+
ex.cleanup();
|
|
99
|
+
}
|
|
100
|
+
else if(ex.element) {
|
|
101
|
+
ex.element.parentElement.removeChild(ex.element);
|
|
102
|
+
}
|
|
98
103
|
});
|
|
99
104
|
});
|
|
100
105
|
|
|
@@ -157,19 +162,23 @@ class ComponentCore
|
|
|
157
162
|
}
|
|
158
163
|
|
|
159
164
|
/*
|
|
160
|
-
//let do_rerender = true;
|
|
161
|
-
|
|
162
|
-
// if(this.outlet && this.entity[MEMOIZED]) {
|
|
163
|
-
// if(shallowEqual(this.props, next_props)) do_rerender=false;
|
|
164
|
-
// delete this.entity[MEMOIZED];
|
|
165
|
-
// }
|
|
166
|
-
|
|
167
|
-
if(do_rerender) {
|
|
168
165
|
*/
|
|
169
166
|
// TODO: should componentDidUpdate be called after arranging/appending the outlet or before?
|
|
170
167
|
apply(next_props = this.props, next_state = this.next_state || this.state)
|
|
171
168
|
{
|
|
172
169
|
|
|
170
|
+
let do_rerender = true;
|
|
171
|
+
|
|
172
|
+
if(this.outlet && this?.[MEMOIZED]) {
|
|
173
|
+
|
|
174
|
+
if( shallowEqual(this.props, next_props, "children") &&
|
|
175
|
+
shallowEqual(this.props?.children, next_props?.children) ) {
|
|
176
|
+
do_rerender=false;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
if(do_rerender) {
|
|
181
|
+
|
|
173
182
|
if(DEBUG) {
|
|
174
183
|
|
|
175
184
|
if(this.entity?.propTypes) {
|
|
@@ -303,13 +312,14 @@ if(DEBUG) {
|
|
|
303
312
|
if(this.cache) this.cache.commit();
|
|
304
313
|
|
|
305
314
|
|
|
306
|
-
|
|
315
|
+
if(this.element) this.arrangeOutlet();
|
|
307
316
|
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
317
|
+
if(this.component.componentDidUpdate) {
|
|
318
|
+
this.component.componentDidUpdate(prev_props, prev_state, this.last_snapshot);
|
|
319
|
+
}
|
|
311
320
|
|
|
312
|
-
|
|
321
|
+
if(this.last_snapshot) delete this.last_snapshot;
|
|
322
|
+
}
|
|
313
323
|
|
|
314
324
|
}
|
|
315
325
|
|
|
@@ -630,17 +640,25 @@ function constructFunc(core, parent) // returns {text} or component, and not com
|
|
|
630
640
|
// do nothing...
|
|
631
641
|
}
|
|
632
642
|
else {
|
|
633
|
-
|
|
634
|
-
|
|
643
|
+
let entity = core.entity;
|
|
644
|
+
let memoized = false;
|
|
645
|
+
|
|
646
|
+
if(typeof(entity)==='object' && entity[MEMOIZED]) {
|
|
647
|
+
memoized = true;
|
|
648
|
+
entity = entity[MEMOIZED];
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
if(typeof(entity)==='string') {
|
|
652
|
+
comp = new HTMLComponent(entity, core.props);
|
|
635
653
|
}
|
|
636
654
|
else {
|
|
637
655
|
|
|
638
|
-
if( isClass(
|
|
639
|
-
if(
|
|
640
|
-
core.props = { ...
|
|
656
|
+
if( isClass(entity) ) {
|
|
657
|
+
if(entity?.defaultProps) {
|
|
658
|
+
core.props = { ...entity.defaultProps, ...core.props };
|
|
641
659
|
}
|
|
642
660
|
|
|
643
|
-
comp = new
|
|
661
|
+
comp = new entity(core.props);
|
|
644
662
|
|
|
645
663
|
const desc = Object.getOwnPropertyDescriptor(comp, "state");
|
|
646
664
|
if(desc) {
|
|
@@ -662,35 +680,35 @@ function constructFunc(core, parent) // returns {text} or component, and not com
|
|
|
662
680
|
}
|
|
663
681
|
}
|
|
664
682
|
}
|
|
665
|
-
else if(typeof(
|
|
683
|
+
else if(typeof(entity)==='function') {
|
|
666
684
|
|
|
667
|
-
if(
|
|
668
|
-
core.props = { ...
|
|
685
|
+
if(entity?.defaultProps) {
|
|
686
|
+
core.props = { ...entity.defaultProps, ...core.props };
|
|
669
687
|
}
|
|
670
688
|
|
|
671
689
|
comp = new Component(core.props);
|
|
672
690
|
|
|
673
691
|
// the binding is not necessary and is not according to the specs,
|
|
674
692
|
// probably not even recommended! but helpful.
|
|
675
|
-
comp.render =
|
|
693
|
+
comp.render = entity.bind(comp);
|
|
676
694
|
comp[CORE].hooks = [];
|
|
677
695
|
comp[CORE].hook_index = 0;
|
|
678
696
|
}
|
|
679
697
|
else {
|
|
680
|
-
throw new Error("
|
|
698
|
+
throw new Error("Error in constructing component.");
|
|
681
699
|
}
|
|
682
700
|
|
|
683
|
-
comp[CORE].entity =
|
|
701
|
+
comp[CORE].entity = entity;
|
|
684
702
|
|
|
685
703
|
if(core.container) {
|
|
686
704
|
comp[CORE].container = core.container;
|
|
687
705
|
}
|
|
688
706
|
}
|
|
689
707
|
|
|
708
|
+
if(memoized) comp[CORE][MEMOIZED] = true;
|
|
690
709
|
}
|
|
691
710
|
|
|
692
711
|
if(parent instanceof ComponentCore) comp[CORE].parent = parent;
|
|
693
|
-
|
|
694
712
|
return comp;
|
|
695
713
|
}
|
|
696
714
|
|
|
@@ -716,23 +734,58 @@ function prepareCore(parent, core)
|
|
|
716
734
|
|
|
717
735
|
function doUpdates()
|
|
718
736
|
{
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
let _update_cbs = Lilact.update_cbs;
|
|
722
|
-
let _update_set = Lilact.update_set;
|
|
737
|
+
/*
|
|
738
|
+
Priority:
|
|
723
739
|
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
740
|
+
- Render + enqueue DOM work (runs in the same task where you schedule the update).
|
|
741
|
+
- Apply DOM updates (do this synchronously before you schedule any effects that must happen before paint).
|
|
742
|
+
- Insertion effects (run immediately after DOM is in place, still before paint).
|
|
743
|
+
- Layout effects (run immediately after insertion effects, still before paint).
|
|
744
|
+
- Passive effects (useEffect)
|
|
727
745
|
|
|
728
|
-
|
|
746
|
+
schedule them for after paint using requestAnimationFrame, typically:
|
|
747
|
+
run the “after paint” work in the next frame or in a callback scheduled such that it runs after the browser has performed the paint.
|
|
748
|
+
|
|
749
|
+
|
|
750
|
+
Current task: render → DOM updates → insertion effects → layout effects
|
|
751
|
+
Next paint timing boundary: requestAnimationFrame callback → passive effects (useEffect)
|
|
752
|
+
*/
|
|
753
|
+
|
|
754
|
+
|
|
755
|
+
clearTimeout(Lilact.effect_timeout);
|
|
756
|
+
|
|
757
|
+
const _update_set = Lilact.update_set;
|
|
758
|
+
const _update_cbs = Lilact.update_cbs;
|
|
759
|
+
Lilact.update_set = new Set;
|
|
760
|
+
Lilact.update_cbs = new Set;
|
|
761
|
+
|
|
762
|
+
for(const u of _update_set) u.apply();
|
|
763
|
+
for(const cb of _update_cbs) cb();
|
|
764
|
+
processEffects();
|
|
729
765
|
|
|
730
|
-
for(const u of _update_set) u.apply();
|
|
731
|
-
for(const cb of _update_cbs) cb();
|
|
732
|
-
});
|
|
733
766
|
}
|
|
734
767
|
|
|
735
768
|
|
|
769
|
+
/** @ignore */
|
|
770
|
+
export function processEffects()
|
|
771
|
+
{
|
|
772
|
+
const _insertion_effects = Lilact.insertion_effects;
|
|
773
|
+
const _layout_effects = Lilact.layout_effects;
|
|
774
|
+
const _passive_effects = Lilact.passive_effects;
|
|
775
|
+
|
|
776
|
+
Lilact.insertion_effects = new Set;
|
|
777
|
+
Lilact.layout_effects = new Set;
|
|
778
|
+
Lilact.passive_effects = new Set;
|
|
779
|
+
|
|
780
|
+
for(const ie of _insertion_effects) ie();
|
|
781
|
+
for(const le of _layout_effects) le();
|
|
782
|
+
|
|
783
|
+
requestAnimationFrame(()=>{
|
|
784
|
+
for(const pe of _passive_effects) pe();
|
|
785
|
+
});
|
|
786
|
+
|
|
787
|
+
}
|
|
788
|
+
|
|
736
789
|
function decode(html)
|
|
737
790
|
{
|
|
738
791
|
decode.parser ??= new DOMParser;
|
|
@@ -1049,8 +1102,12 @@ export class RootComponent extends HTMLComponent
|
|
|
1049
1102
|
|
|
1050
1103
|
export function createComponent(entity, props={}, ...children)
|
|
1051
1104
|
{
|
|
1052
|
-
|
|
1053
|
-
|
|
1105
|
+
|
|
1106
|
+
if (typeof(entity)!=='string' && typeof(entity)!=='function' )
|
|
1107
|
+
{
|
|
1108
|
+
if(typeof(entity)!=='object' || !entity[MEMOIZED]) {
|
|
1109
|
+
throw new Error("Invalid entity for createComponent.");
|
|
1110
|
+
}
|
|
1054
1111
|
}
|
|
1055
1112
|
|
|
1056
1113
|
for(let i=0; i<children.length; i++) {
|
|
@@ -1141,6 +1198,21 @@ export function render(component, element)
|
|
|
1141
1198
|
return createRoot(element).render(component);
|
|
1142
1199
|
}
|
|
1143
1200
|
|
|
1201
|
+
/**
|
|
1202
|
+
* Memoizes the given component. The memoized component will only rerender if its props or children are modified.
|
|
1203
|
+
* Unlike React, Lilact memo also works on class components.
|
|
1204
|
+
*
|
|
1205
|
+
* @param {Object} component - Component instance to render.
|
|
1206
|
+
*
|
|
1207
|
+
* @returns {component} - Memoized component.
|
|
1208
|
+
*/
|
|
1209
|
+
|
|
1210
|
+
export function memo(component)
|
|
1211
|
+
{
|
|
1212
|
+
return { [MEMOIZED]: component }
|
|
1213
|
+
}
|
|
1214
|
+
|
|
1215
|
+
|
|
1144
1216
|
/** @ignore */
|
|
1145
1217
|
export const createElement = createComponent;
|
|
1146
1218
|
|
|
@@ -1155,6 +1227,18 @@ export let update_cbs = new Set;
|
|
|
1155
1227
|
export let roots = new Set;
|
|
1156
1228
|
/** @ignore */
|
|
1157
1229
|
export let layout_effects = new Set;
|
|
1230
|
+
/** @ignore */
|
|
1231
|
+
export let insertion_effects = new Set;
|
|
1232
|
+
/** @ignore */
|
|
1233
|
+
export let passive_effects = new Set;
|
|
1234
|
+
|
|
1235
|
+
|
|
1236
|
+
/** @ignore */
|
|
1237
|
+
export let update_timeout = undefined;
|
|
1238
|
+
/** @ignore */
|
|
1239
|
+
export let effect_timeout = undefined;
|
|
1240
|
+
/** @ignore */
|
|
1241
|
+
export let update_interval_margin = 0;
|
|
1158
1242
|
|
|
1159
1243
|
/** @ignore */
|
|
1160
1244
|
export const special_attributes = new Set([
|
|
@@ -1201,3 +1285,5 @@ export const length_css_attributes_set = new Set([
|
|
|
1201
1285
|
export const boolean_html_attributes_set = new
|
|
1202
1286
|
Set(["disabled", "readOnly", "required", "checked", "multiple",
|
|
1203
1287
|
"hidden","open","loop","muted","controls","playsInline","allowFullScreen"]);
|
|
1288
|
+
|
|
1289
|
+
|
package/src/hooks.jsx
CHANGED
|
@@ -182,12 +182,12 @@ export function useTransition()
|
|
|
182
182
|
|
|
183
183
|
(async function(core, hk, fn) {
|
|
184
184
|
|
|
185
|
-
hk.count
|
|
186
|
-
|
|
187
|
-
if(hk.count===1) {
|
|
185
|
+
if(hk.count===0) {
|
|
188
186
|
core.component.forceUpdate();
|
|
189
187
|
}
|
|
190
188
|
|
|
189
|
+
hk.count++;
|
|
190
|
+
|
|
191
191
|
await fn();
|
|
192
192
|
|
|
193
193
|
hk.count--;
|
|
@@ -269,13 +269,14 @@ export function useRef(initialValue = null)
|
|
|
269
269
|
* Runs an effect synchronously after all DOM mutations but before the browser paints.
|
|
270
270
|
*
|
|
271
271
|
* @param {Function} effect - Effect callback.
|
|
272
|
-
* @param {Array<any>} [deps]
|
|
272
|
+
* @param {Array<any>} [deps] Optional dependency list (or an object for shallow comparison)
|
|
273
|
+
* used to determine when to re-run the effect.
|
|
273
274
|
* @returns {void}
|
|
274
275
|
*/
|
|
275
276
|
export function useLayoutEffect(effect, deps=undefined)
|
|
276
277
|
{
|
|
277
278
|
if( deps!==undefined && (typeof(deps)!=='object' || deps.constructor.name!=='Array') ) {
|
|
278
|
-
throw new Error("Layout effect dependencies must be an array or omitted.");
|
|
279
|
+
throw new Error("Layout effect dependencies must be an array, object or omitted.");
|
|
279
280
|
}
|
|
280
281
|
|
|
281
282
|
const hk = useHook();
|
|
@@ -290,20 +291,55 @@ export function useLayoutEffect(effect, deps=undefined)
|
|
|
290
291
|
|
|
291
292
|
hk.deps = deps;
|
|
292
293
|
Lilact.layout_effects.add( ()=>{ hk.cleanup = effect(); });
|
|
293
|
-
|
|
294
|
+
|
|
295
|
+
Lilact.clearTimeout( Lilact.effect_timeout );
|
|
296
|
+
Lilact.setTimeout( Lilact.processEffects, 0 );
|
|
294
297
|
}
|
|
295
298
|
|
|
296
299
|
/**
|
|
297
300
|
* Runs a side effect after render commits.
|
|
298
301
|
*
|
|
299
|
-
* @param
|
|
300
|
-
* @param {Array<any>} [deps]
|
|
302
|
+
* @param effect - Callback invoked.
|
|
303
|
+
* @param {Array<any>} [deps] Optional dependency list (or an object for shallow comparison)
|
|
304
|
+
* used to determine when to re-run the effect.
|
|
301
305
|
* @returns {void}
|
|
302
306
|
*/
|
|
303
307
|
export function useEffect(effect, deps=undefined)
|
|
304
308
|
{
|
|
305
309
|
if( deps!==undefined && (typeof(deps)!=='object' || deps.constructor.name!=='Array') ) {
|
|
306
|
-
throw new Error("Effect dependencies must be an array or omitted.");
|
|
310
|
+
throw new Error("Effect dependencies must be an array, object or omitted.");
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
const hk = useHook();
|
|
314
|
+
|
|
315
|
+
if( !isEmpty(hk) ) {
|
|
316
|
+
if(deps!==undefined && hk?.deps!==undefined && shallowEqual(deps, hk.deps)) return;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
if(hk?.cleanup) {
|
|
320
|
+
hk.cleanup();
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
hk.deps = deps;
|
|
324
|
+
Lilact.passive_effects.add( ()=>{ hk.cleanup = effect(); });
|
|
325
|
+
|
|
326
|
+
Lilact.clearTimeout( Lilact.effect_timeout );
|
|
327
|
+
Lilact.setTimeout( Lilact.processEffects, 0 );
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* Executes a side effect after the DOM updates have been committed.
|
|
333
|
+
*
|
|
334
|
+
* @param effect - Callback invoked after render commit.
|
|
335
|
+
* @param {Array<any>} [deps] Optional dependency list (or an object for shallow comparison)
|
|
336
|
+
* used to determine when to re-run the effect.
|
|
337
|
+
* @returns void
|
|
338
|
+
*/
|
|
339
|
+
export function useInsertionEffect(effect, deps=undefined)
|
|
340
|
+
{
|
|
341
|
+
if( deps!==undefined && (typeof(deps)!=='object' || deps.constructor.name!=='Array') ) {
|
|
342
|
+
throw new Error("Insertion effect dependencies must be an array, object, or omitted.");
|
|
307
343
|
}
|
|
308
344
|
|
|
309
345
|
const hk = useHook();
|
|
@@ -317,15 +353,19 @@ export function useEffect(effect, deps=undefined)
|
|
|
317
353
|
}
|
|
318
354
|
|
|
319
355
|
hk.deps = deps;
|
|
320
|
-
Lilact.
|
|
356
|
+
Lilact.insertion_effects.add( ()=>{ hk.cleanup = effect(); });
|
|
321
357
|
|
|
358
|
+
Lilact.clearTimeout( Lilact.effect_timeout );
|
|
359
|
+
Lilact.setTimeout( Lilact.processEffects, 0 );
|
|
322
360
|
}
|
|
323
361
|
|
|
362
|
+
|
|
324
363
|
/**
|
|
325
364
|
* Memoizes a computed value until dependencies change.
|
|
326
365
|
*
|
|
327
366
|
* @param {Function} factory - Function that creates the value.
|
|
328
|
-
* @param {Array<any>} deps
|
|
367
|
+
* @param {Array<any>} [deps] Optional dependency list (or an object for shallow comparison)
|
|
368
|
+
* used to determine when to recompute the value.
|
|
329
369
|
* @returns {any} Memoized value.
|
|
330
370
|
*/
|
|
331
371
|
export function useMemo(factory,deps=undefined)
|
|
@@ -487,3 +527,36 @@ export function useImperativeHandle(ref, factory, deps=undefined)
|
|
|
487
527
|
|
|
488
528
|
}
|
|
489
529
|
|
|
530
|
+
|
|
531
|
+
/**
|
|
532
|
+
* A hook for debug purposes. By default it only logs the output to console, but it can be overrided
|
|
533
|
+
* for the development environment.
|
|
534
|
+
*
|
|
535
|
+
* @param {any} val
|
|
536
|
+
* The debug value.
|
|
537
|
+
* @param {function(): any} formatter
|
|
538
|
+
* Function that creates a representation of the value.
|
|
539
|
+
* @returns {void}
|
|
540
|
+
*/
|
|
541
|
+
export function useDebugValue(val, formatter=(x)=>x)
|
|
542
|
+
{
|
|
543
|
+
if(DEBUG) {
|
|
544
|
+
console.log(formatter(val));
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
|
|
549
|
+
/**
|
|
550
|
+
* Schedule a state update as a low-priority transition.
|
|
551
|
+
*
|
|
552
|
+
* Updates triggered inside the transition callback are treated as lower priority than
|
|
553
|
+
* updates outside of it.
|
|
554
|
+
*
|
|
555
|
+
* @param transition - Function that performs the state updates for the transition.
|
|
556
|
+
* @returns void
|
|
557
|
+
*/
|
|
558
|
+
export function startTransition(transition)
|
|
559
|
+
{
|
|
560
|
+
transition();
|
|
561
|
+
}
|
|
562
|
+
|
package/src/lilact.jsx
CHANGED
package/src/misc.jsx
CHANGED
|
@@ -54,10 +54,18 @@ const typeOf = (input) => {
|
|
|
54
54
|
* @param value - Value to inspect.
|
|
55
55
|
* @returns True if the value is a class component; otherwise false.
|
|
56
56
|
*/
|
|
57
|
-
export const
|
|
57
|
+
export const isValidComponent = (value) => {
|
|
58
58
|
return value[CORE]!==undefined || value[TEXT]!==undefined;
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
+
/**
|
|
62
|
+
* Checks whether a value is a Lilact component. It is the same as `isValidComponent`.
|
|
63
|
+
*
|
|
64
|
+
* @param value - Value to inspect.
|
|
65
|
+
* @returns True if the value is a class component; otherwise false.
|
|
66
|
+
*/
|
|
67
|
+
export const isValidElement = isValidComponent
|
|
68
|
+
|
|
61
69
|
/**
|
|
62
70
|
* Utility to find the underlying DOM node for a mounted Lilact component.
|
|
63
71
|
*
|
|
@@ -212,9 +220,10 @@ export function isEmpty(value) {
|
|
|
212
220
|
*
|
|
213
221
|
* @param source - First object to compare.
|
|
214
222
|
* @param target - Second object to compare.
|
|
223
|
+
* @param ignore - specific property/index to be ignored in comparison.
|
|
215
224
|
* @returns True if shallowly equal; otherwise false.
|
|
216
225
|
*/
|
|
217
|
-
export const shallowEqual = (source, target) => {
|
|
226
|
+
export const shallowEqual = (source, target, ignore) => {
|
|
218
227
|
if (typeOf(source) !== typeOf(target)) {
|
|
219
228
|
return false;
|
|
220
229
|
}
|
|
@@ -223,9 +232,9 @@ export const shallowEqual = (source, target) => {
|
|
|
223
232
|
if (source.length !== target.length) {
|
|
224
233
|
return false;
|
|
225
234
|
}
|
|
226
|
-
return source.every((el, index) => el === target[index]);
|
|
235
|
+
return source.every((el, index) => el === target[index] || index===ignore );
|
|
227
236
|
} else if (typeOf(source) === "object") {
|
|
228
|
-
return Object.keys(source).every((key) => source[key] === target[key]);
|
|
237
|
+
return Object.keys(source).every((key) => source[key] === target[key] || key===ignore );
|
|
229
238
|
} else if (typeOf(source) === "date") {
|
|
230
239
|
return source.getTime() === target.getTime();
|
|
231
240
|
}
|
|
@@ -337,10 +346,6 @@ export function toBool(value) {
|
|
|
337
346
|
|
|
338
347
|
// Internals
|
|
339
348
|
|
|
340
|
-
/** @ignore */
|
|
341
|
-
export let update_timeout = undefined;
|
|
342
|
-
/** @ignore */
|
|
343
|
-
export let update_interval_margin = 0;
|
|
344
349
|
/** @ignore */
|
|
345
350
|
export let id_num = Math.floor(Math.random()*10000);
|
|
346
351
|
/** @ignore */
|