@bquery/bquery 1.6.0 → 1.7.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/README.md +716 -586
- package/dist/a11y/announce.d.ts +43 -0
- package/dist/a11y/announce.d.ts.map +1 -0
- package/dist/a11y/audit.d.ts +42 -0
- package/dist/a11y/audit.d.ts.map +1 -0
- package/dist/a11y/index.d.ts +53 -0
- package/dist/a11y/index.d.ts.map +1 -0
- package/dist/a11y/media-preferences.d.ts +77 -0
- package/dist/a11y/media-preferences.d.ts.map +1 -0
- package/dist/a11y/roving-tab-index.d.ts +38 -0
- package/dist/a11y/roving-tab-index.d.ts.map +1 -0
- package/dist/a11y/skip-link.d.ts +37 -0
- package/dist/a11y/skip-link.d.ts.map +1 -0
- package/dist/a11y/trap-focus.d.ts +49 -0
- package/dist/a11y/trap-focus.d.ts.map +1 -0
- package/dist/a11y/types.d.ts +152 -0
- package/dist/a11y/types.d.ts.map +1 -0
- package/dist/a11y-C5QOVvRn.js +421 -0
- package/dist/a11y-C5QOVvRn.js.map +1 -0
- package/dist/a11y.es.mjs +14 -0
- package/dist/component/component.d.ts.map +1 -1
- package/dist/component/html.d.ts.map +1 -1
- package/dist/component/index.d.ts +2 -1
- package/dist/component/index.d.ts.map +1 -1
- package/dist/component/library.d.ts.map +1 -1
- package/dist/component/scope.d.ts +138 -0
- package/dist/component/scope.d.ts.map +1 -0
- package/dist/component/types.d.ts +53 -1
- package/dist/component/types.d.ts.map +1 -1
- package/dist/component-CuuTijA6.js +684 -0
- package/dist/component-CuuTijA6.js.map +1 -0
- package/dist/component.es.mjs +9 -6
- package/dist/{config-DRmZZno3.js → config-BW35FKuA.js} +4 -4
- package/dist/{config-DRmZZno3.js.map → config-BW35FKuA.js.map} +1 -1
- package/dist/constraints-3lV9yyBw.js +100 -0
- package/dist/constraints-3lV9yyBw.js.map +1 -0
- package/dist/core/collection.d.ts +48 -0
- package/dist/core/collection.d.ts.map +1 -1
- package/dist/core/element.d.ts +92 -0
- package/dist/core/element.d.ts.map +1 -1
- package/dist/core/env.d.ts +18 -0
- package/dist/core/env.d.ts.map +1 -0
- package/dist/core/index.d.ts +1 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/shared.d.ts +8 -0
- package/dist/core/shared.d.ts.map +1 -1
- package/dist/core/utils/index.d.ts +52 -41
- package/dist/core/utils/index.d.ts.map +1 -1
- package/dist/core-Cjl7GUu8.js +717 -0
- package/dist/core-Cjl7GUu8.js.map +1 -0
- package/dist/core-DnlyjbF2.js +112 -0
- package/dist/core-DnlyjbF2.js.map +1 -0
- package/dist/core.es.mjs +45 -44
- package/dist/custom-directives-7wAShnnd.js +9 -0
- package/dist/custom-directives-7wAShnnd.js.map +1 -0
- package/dist/devtools/devtools.d.ts +212 -0
- package/dist/devtools/devtools.d.ts.map +1 -0
- package/dist/devtools/index.d.ts +20 -0
- package/dist/devtools/index.d.ts.map +1 -0
- package/dist/devtools/types.d.ts +69 -0
- package/dist/devtools/types.d.ts.map +1 -0
- package/dist/devtools-D2fQLhDN.js +122 -0
- package/dist/devtools-D2fQLhDN.js.map +1 -0
- package/dist/devtools.es.mjs +19 -0
- package/dist/dnd/draggable.d.ts +51 -0
- package/dist/dnd/draggable.d.ts.map +1 -0
- package/dist/dnd/droppable.d.ts +38 -0
- package/dist/dnd/droppable.d.ts.map +1 -0
- package/dist/dnd/index.d.ts +47 -0
- package/dist/dnd/index.d.ts.map +1 -0
- package/dist/dnd/sortable.d.ts +43 -0
- package/dist/dnd/sortable.d.ts.map +1 -0
- package/dist/dnd/types.d.ts +250 -0
- package/dist/dnd/types.d.ts.map +1 -0
- package/dist/dnd-B8EgyzaI.js +244 -0
- package/dist/dnd-B8EgyzaI.js.map +1 -0
- package/dist/dnd.es.mjs +6 -0
- package/dist/env-NeVmr4Gf.js +19 -0
- package/dist/env-NeVmr4Gf.js.map +1 -0
- package/dist/forms/create-form.d.ts +49 -0
- package/dist/forms/create-form.d.ts.map +1 -0
- package/dist/forms/index.d.ts +39 -0
- package/dist/forms/index.d.ts.map +1 -0
- package/dist/forms/types.d.ts +139 -0
- package/dist/forms/types.d.ts.map +1 -0
- package/dist/forms/validators.d.ts +179 -0
- package/dist/forms/validators.d.ts.map +1 -0
- package/dist/forms-C3yovgH9.js +141 -0
- package/dist/forms-C3yovgH9.js.map +1 -0
- package/dist/forms.es.mjs +14 -0
- package/dist/full.d.ts +35 -7
- package/dist/full.d.ts.map +1 -1
- package/dist/full.es.mjs +182 -91
- package/dist/full.iife.js +47 -31
- package/dist/full.iife.js.map +1 -1
- package/dist/full.umd.js +47 -31
- package/dist/full.umd.js.map +1 -1
- package/dist/i18n/formatting.d.ts +40 -0
- package/dist/i18n/formatting.d.ts.map +1 -0
- package/dist/i18n/i18n.d.ts +48 -0
- package/dist/i18n/i18n.d.ts.map +1 -0
- package/dist/i18n/index.d.ts +57 -0
- package/dist/i18n/index.d.ts.map +1 -0
- package/dist/i18n/translate.d.ts +83 -0
- package/dist/i18n/translate.d.ts.map +1 -0
- package/dist/i18n/types.d.ts +156 -0
- package/dist/i18n/types.d.ts.map +1 -0
- package/dist/i18n-BnnhTFOS.js +89 -0
- package/dist/i18n-BnnhTFOS.js.map +1 -0
- package/dist/i18n.es.mjs +6 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.es.mjs +227 -136
- package/dist/media/battery.d.ts +35 -0
- package/dist/media/battery.d.ts.map +1 -0
- package/dist/media/breakpoints.d.ts +51 -0
- package/dist/media/breakpoints.d.ts.map +1 -0
- package/dist/media/clipboard.d.ts +30 -0
- package/dist/media/clipboard.d.ts.map +1 -0
- package/dist/media/device-sensors.d.ts +54 -0
- package/dist/media/device-sensors.d.ts.map +1 -0
- package/dist/media/geolocation.d.ts +38 -0
- package/dist/media/geolocation.d.ts.map +1 -0
- package/dist/media/index.d.ts +42 -0
- package/dist/media/index.d.ts.map +1 -0
- package/dist/media/media-query.d.ts +36 -0
- package/dist/media/media-query.d.ts.map +1 -0
- package/dist/media/network.d.ts +35 -0
- package/dist/media/network.d.ts.map +1 -0
- package/dist/media/types.d.ts +173 -0
- package/dist/media/types.d.ts.map +1 -0
- package/dist/media/viewport.d.ts +32 -0
- package/dist/media/viewport.d.ts.map +1 -0
- package/dist/media-Di2Ta22s.js +340 -0
- package/dist/media-Di2Ta22s.js.map +1 -0
- package/dist/media.es.mjs +12 -0
- package/dist/motion/index.d.ts +7 -3
- package/dist/motion/index.d.ts.map +1 -1
- package/dist/motion/morph.d.ts +27 -0
- package/dist/motion/morph.d.ts.map +1 -0
- package/dist/motion/parallax.d.ts +30 -0
- package/dist/motion/parallax.d.ts.map +1 -0
- package/dist/motion/reduced-motion.d.ts +36 -3
- package/dist/motion/reduced-motion.d.ts.map +1 -1
- package/dist/motion/types.d.ts +58 -0
- package/dist/motion/types.d.ts.map +1 -1
- package/dist/motion/typewriter.d.ts +31 -0
- package/dist/motion/typewriter.d.ts.map +1 -0
- package/dist/motion-qPj_TYGv.js +530 -0
- package/dist/motion-qPj_TYGv.js.map +1 -0
- package/dist/motion.es.mjs +27 -23
- package/dist/{view-C70lA3vf.js → mount-SM07RUa6.js} +166 -160
- package/dist/mount-SM07RUa6.js.map +1 -0
- package/dist/{object-qGpWr6-J.js → object-BCk-1c8T.js} +5 -4
- package/dist/{object-qGpWr6-J.js.map → object-BCk-1c8T.js.map} +1 -1
- package/dist/{platform-Dr9b6fsq.js → platform-CPbCprb6.js} +21 -22
- package/dist/{platform-Dr9b6fsq.js.map → platform-CPbCprb6.js.map} +1 -1
- package/dist/platform.es.mjs +2 -2
- package/dist/plugin/index.d.ts +22 -0
- package/dist/plugin/index.d.ts.map +1 -0
- package/dist/plugin/registry.d.ts +108 -0
- package/dist/plugin/registry.d.ts.map +1 -0
- package/dist/plugin/types.d.ts +110 -0
- package/dist/plugin/types.d.ts.map +1 -0
- package/dist/plugin-cPoOHFLY.js +64 -0
- package/dist/plugin-cPoOHFLY.js.map +1 -0
- package/dist/plugin.es.mjs +9 -0
- package/dist/reactive/computed.d.ts +7 -0
- package/dist/reactive/computed.d.ts.map +1 -1
- package/dist/reactive-Cfv0RK6x.js +233 -0
- package/dist/reactive-Cfv0RK6x.js.map +1 -0
- package/dist/reactive.es.mjs +19 -20
- package/dist/registry-CWf368tT.js +26 -0
- package/dist/registry-CWf368tT.js.map +1 -0
- package/dist/router/bq-link.d.ts +112 -0
- package/dist/router/bq-link.d.ts.map +1 -0
- package/dist/router/constraints.d.ts +9 -0
- package/dist/router/constraints.d.ts.map +1 -0
- package/dist/router/index.d.ts +14 -6
- package/dist/router/index.d.ts.map +1 -1
- package/dist/router/match.d.ts +0 -1
- package/dist/router/match.d.ts.map +1 -1
- package/dist/router/path-pattern.d.ts +14 -0
- package/dist/router/path-pattern.d.ts.map +1 -0
- package/dist/router/query.d.ts.map +1 -1
- package/dist/router/router.d.ts +3 -1
- package/dist/router/router.d.ts.map +1 -1
- package/dist/router/types.d.ts +48 -4
- package/dist/router/types.d.ts.map +1 -1
- package/dist/router/use-route.d.ts +50 -0
- package/dist/router/use-route.d.ts.map +1 -0
- package/dist/router/utils.d.ts +3 -0
- package/dist/router/utils.d.ts.map +1 -1
- package/dist/router-BrthaP_z.js +473 -0
- package/dist/router-BrthaP_z.js.map +1 -0
- package/dist/router.es.mjs +13 -10
- package/dist/{sanitize-Bs2dkMby.js → sanitize-B1V4JswB.js} +2 -1
- package/dist/{sanitize-Bs2dkMby.js.map → sanitize-B1V4JswB.js.map} +1 -1
- package/dist/security/index.d.ts +2 -2
- package/dist/security/index.d.ts.map +1 -1
- package/dist/security.es.mjs +1 -1
- package/dist/ssr/hydrate.d.ts +65 -0
- package/dist/ssr/hydrate.d.ts.map +1 -0
- package/dist/ssr/index.d.ts +59 -0
- package/dist/ssr/index.d.ts.map +1 -0
- package/dist/ssr/render.d.ts +62 -0
- package/dist/ssr/render.d.ts.map +1 -0
- package/dist/ssr/serialize.d.ts +118 -0
- package/dist/ssr/serialize.d.ts.map +1 -0
- package/dist/ssr/types.d.ts +70 -0
- package/dist/ssr/types.d.ts.map +1 -0
- package/dist/ssr-B2qd_WBB.js +248 -0
- package/dist/ssr-B2qd_WBB.js.map +1 -0
- package/dist/ssr.es.mjs +9 -0
- package/dist/store/create-store.d.ts.map +1 -1
- package/dist/store/index.d.ts +1 -1
- package/dist/store/index.d.ts.map +1 -1
- package/dist/store/persisted.d.ts +38 -4
- package/dist/store/persisted.d.ts.map +1 -1
- package/dist/store/types.d.ts +138 -1
- package/dist/store/types.d.ts.map +1 -1
- package/dist/store/utils.d.ts +2 -2
- package/dist/store/utils.d.ts.map +1 -1
- package/dist/store-DWpyH6p5.js +338 -0
- package/dist/store-DWpyH6p5.js.map +1 -0
- package/dist/store.es.mjs +11 -10
- package/dist/storybook/index.d.ts.map +1 -1
- package/dist/storybook.es.mjs +1 -1
- package/dist/storybook.es.mjs.map +1 -1
- package/dist/testing/index.d.ts +23 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/testing.d.ts +156 -0
- package/dist/testing/testing.d.ts.map +1 -0
- package/dist/testing/types.d.ts +134 -0
- package/dist/testing/types.d.ts.map +1 -0
- package/dist/testing-CsqjNUyy.js +224 -0
- package/dist/testing-CsqjNUyy.js.map +1 -0
- package/dist/testing.es.mjs +9 -0
- package/dist/type-guards-Do9DWgNp.js +44 -0
- package/dist/type-guards-Do9DWgNp.js.map +1 -0
- package/dist/untrack-DJVQQ2WM.js +33 -0
- package/dist/untrack-DJVQQ2WM.js.map +1 -0
- package/dist/view/custom-directives.d.ts +20 -0
- package/dist/view/custom-directives.d.ts.map +1 -0
- package/dist/view/evaluate.d.ts.map +1 -1
- package/dist/view/process.d.ts.map +1 -1
- package/dist/view.es.mjs +9 -9
- package/package.json +177 -141
- package/src/a11y/announce.ts +131 -0
- package/src/a11y/audit.ts +314 -0
- package/src/a11y/index.ts +68 -0
- package/src/a11y/media-preferences.ts +255 -0
- package/src/a11y/roving-tab-index.ts +164 -0
- package/src/a11y/skip-link.ts +255 -0
- package/src/a11y/trap-focus.ts +184 -0
- package/src/a11y/types.ts +183 -0
- package/src/component/component.ts +104 -29
- package/src/component/html.ts +5 -5
- package/src/component/index.ts +2 -0
- package/src/component/library.ts +26 -2
- package/src/component/scope.ts +212 -0
- package/src/component/types.ts +94 -40
- package/src/core/collection.ts +707 -628
- package/src/core/element.ts +981 -774
- package/src/core/env.ts +60 -0
- package/src/core/index.ts +49 -48
- package/src/core/shared.ts +62 -13
- package/src/core/utils/index.ts +148 -83
- package/src/devtools/devtools.ts +410 -0
- package/src/devtools/index.ts +48 -0
- package/src/devtools/types.ts +104 -0
- package/src/dnd/draggable.ts +296 -0
- package/src/dnd/droppable.ts +228 -0
- package/src/dnd/index.ts +62 -0
- package/src/dnd/sortable.ts +307 -0
- package/src/dnd/types.ts +293 -0
- package/src/forms/create-form.ts +278 -0
- package/src/forms/index.ts +65 -0
- package/src/forms/types.ts +154 -0
- package/src/forms/validators.ts +265 -0
- package/src/full.ts +253 -2
- package/src/i18n/formatting.ts +67 -0
- package/src/i18n/i18n.ts +200 -0
- package/src/i18n/index.ts +67 -0
- package/src/i18n/translate.ts +182 -0
- package/src/i18n/types.ts +171 -0
- package/src/index.ts +108 -36
- package/src/media/battery.ts +116 -0
- package/src/media/breakpoints.ts +131 -0
- package/src/media/clipboard.ts +80 -0
- package/src/media/device-sensors.ts +158 -0
- package/src/media/geolocation.ts +119 -0
- package/src/media/index.ts +76 -0
- package/src/media/media-query.ts +92 -0
- package/src/media/network.ts +115 -0
- package/src/media/types.ts +177 -0
- package/src/media/viewport.ts +84 -0
- package/src/motion/index.ts +57 -48
- package/src/motion/morph.ts +151 -0
- package/src/motion/parallax.ts +120 -0
- package/src/motion/reduced-motion.ts +66 -17
- package/src/motion/types.ts +271 -208
- package/src/motion/typewriter.ts +164 -0
- package/src/plugin/index.ts +37 -0
- package/src/plugin/registry.ts +269 -0
- package/src/plugin/types.ts +137 -0
- package/src/reactive/computed.ts +130 -92
- package/src/router/bq-link.ts +279 -0
- package/src/router/constraints.ts +201 -0
- package/src/router/index.ts +49 -41
- package/src/router/match.ts +312 -106
- package/src/router/path-pattern.ts +52 -0
- package/src/router/query.ts +38 -35
- package/src/router/router.ts +402 -211
- package/src/router/types.ts +139 -93
- package/src/router/use-route.ts +68 -0
- package/src/router/utils.ts +157 -116
- package/src/security/index.ts +2 -7
- package/src/security/sanitize.ts +70 -70
- package/src/security/trusted-html.ts +71 -71
- package/src/ssr/hydrate.ts +82 -0
- package/src/ssr/index.ts +70 -0
- package/src/ssr/render.ts +508 -0
- package/src/ssr/serialize.ts +296 -0
- package/src/ssr/types.ts +81 -0
- package/src/store/create-store.ts +467 -329
- package/src/store/define-store.ts +49 -49
- package/src/store/index.ts +27 -22
- package/src/store/mapping.ts +74 -74
- package/src/store/persisted.ts +206 -19
- package/src/store/types.ts +157 -2
- package/src/store/utils.ts +135 -141
- package/src/store/watch.ts +53 -53
- package/src/storybook/index.ts +2 -1
- package/src/testing/index.ts +42 -0
- package/src/testing/testing.ts +593 -0
- package/src/testing/types.ts +170 -0
- package/src/view/custom-directives.ts +30 -0
- package/src/view/evaluate.ts +292 -290
- package/src/view/process.ts +108 -92
- package/dist/component-BEQgt5hl.js +0 -600
- package/dist/component-BEQgt5hl.js.map +0 -1
- package/dist/core-BGQJVw0-.js +0 -35
- package/dist/core-BGQJVw0-.js.map +0 -1
- package/dist/core-CCEabVHl.js +0 -648
- package/dist/core-CCEabVHl.js.map +0 -1
- package/dist/effect-AFRW_Plg.js +0 -84
- package/dist/effect-AFRW_Plg.js.map +0 -1
- package/dist/motion-D9TcHxOF.js +0 -415
- package/dist/motion-D9TcHxOF.js.map +0 -1
- package/dist/reactive-DSkct0dO.js +0 -254
- package/dist/reactive-DSkct0dO.js.map +0 -1
- package/dist/router-CbDhl8rS.js +0 -188
- package/dist/router-CbDhl8rS.js.map +0 -1
- package/dist/store-BwDvI45q.js +0 -263
- package/dist/store-BwDvI45q.js.map +0 -1
- package/dist/untrack-B0rVscTc.js +0 -7
- package/dist/untrack-B0rVscTc.js.map +0 -1
- package/dist/view-C70lA3vf.js.map +0 -1
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Component-scoped reactive primitives.
|
|
3
|
+
*
|
|
4
|
+
* Provides `useSignal`, `useComputed`, and `useEffect` that automatically
|
|
5
|
+
* dispose when their owning component disconnects from the DOM.
|
|
6
|
+
*
|
|
7
|
+
* @module bquery/component
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type { Computed } from '../reactive/computed';
|
|
11
|
+
import { computed } from '../reactive/computed';
|
|
12
|
+
import { detectDevEnvironment } from '../core/env';
|
|
13
|
+
import type { Signal } from '../reactive/core';
|
|
14
|
+
import { signal } from '../reactive/core';
|
|
15
|
+
import { effect } from '../reactive/effect';
|
|
16
|
+
import type { CleanupFn } from '../reactive/index';
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Holds disposable resources created inside a component scope.
|
|
20
|
+
* All registered disposers run when the component disconnects.
|
|
21
|
+
* @internal
|
|
22
|
+
*/
|
|
23
|
+
export interface ComponentScope {
|
|
24
|
+
/** Register a cleanup function to run on dispose */
|
|
25
|
+
addDisposer(fn: CleanupFn): void;
|
|
26
|
+
/** Dispose all registered resources */
|
|
27
|
+
dispose(): void;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** Currently active component scope. @internal */
|
|
31
|
+
let currentScope: ComponentScope | undefined;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Sets the active component scope.
|
|
35
|
+
* @internal
|
|
36
|
+
*/
|
|
37
|
+
export function setCurrentScope(scope: ComponentScope | undefined): ComponentScope | undefined {
|
|
38
|
+
const previousScope = currentScope;
|
|
39
|
+
currentScope = scope;
|
|
40
|
+
return previousScope;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Returns the active component scope, or undefined if none.
|
|
45
|
+
* @internal
|
|
46
|
+
*/
|
|
47
|
+
export function getCurrentScope(): ComponentScope | undefined {
|
|
48
|
+
return currentScope;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Creates a new component scope that tracks disposable resources.
|
|
53
|
+
* @internal
|
|
54
|
+
*/
|
|
55
|
+
export function createComponentScope(): ComponentScope {
|
|
56
|
+
const disposers: CleanupFn[] = [];
|
|
57
|
+
|
|
58
|
+
return {
|
|
59
|
+
addDisposer(fn: CleanupFn): void {
|
|
60
|
+
disposers.push(fn);
|
|
61
|
+
},
|
|
62
|
+
dispose(): void {
|
|
63
|
+
for (const fn of disposers) {
|
|
64
|
+
try {
|
|
65
|
+
fn();
|
|
66
|
+
} catch (error) {
|
|
67
|
+
if (
|
|
68
|
+
detectDevEnvironment() &&
|
|
69
|
+
typeof console !== 'undefined' &&
|
|
70
|
+
typeof console.error === 'function'
|
|
71
|
+
) {
|
|
72
|
+
console.error('bQuery component: Error disposing scoped resource', error);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
disposers.length = 0;
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Creates a reactive signal scoped to the current component.
|
|
83
|
+
*
|
|
84
|
+
* The signal is automatically disposed when the component disconnects
|
|
85
|
+
* from the DOM, removing all subscribers and preventing memory leaks.
|
|
86
|
+
*
|
|
87
|
+
* Must be called during a component lifecycle hook such as `connected`,
|
|
88
|
+
* `beforeMount`, `onAdopted`, or `onAttributeChanged`.
|
|
89
|
+
*
|
|
90
|
+
* Do not create scoped primitives from `render()`. Repeated renders can
|
|
91
|
+
* accumulate render-scoped resources until disconnect; prefer lifecycle hooks.
|
|
92
|
+
*
|
|
93
|
+
* @template T - The type of the signal value
|
|
94
|
+
* @param initialValue - The initial value of the signal
|
|
95
|
+
* @returns A new Signal instance that auto-disposes with the component
|
|
96
|
+
* @throws {Error} If called outside a component scope
|
|
97
|
+
*
|
|
98
|
+
* @example
|
|
99
|
+
* ```ts
|
|
100
|
+
* import { component, html, useSignal } from '@bquery/bquery/component';
|
|
101
|
+
*
|
|
102
|
+
* component('my-counter', {
|
|
103
|
+
* connected() {
|
|
104
|
+
* const count = useSignal(0);
|
|
105
|
+
* // count.dispose() is called automatically on disconnect
|
|
106
|
+
* },
|
|
107
|
+
* render({ state }) {
|
|
108
|
+
* return html`<span>${state.count}</span>`;
|
|
109
|
+
* },
|
|
110
|
+
* });
|
|
111
|
+
* ```
|
|
112
|
+
*/
|
|
113
|
+
export function useSignal<T>(initialValue: T): Signal<T> {
|
|
114
|
+
const scope = currentScope;
|
|
115
|
+
if (!scope) {
|
|
116
|
+
throw new Error(
|
|
117
|
+
'bQuery component: useSignal() must be called inside a component lifecycle hook. Avoid calling it directly from render()'
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
const s = signal(initialValue);
|
|
121
|
+
scope.addDisposer(() => s.dispose());
|
|
122
|
+
return s;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Creates a computed value scoped to the current component.
|
|
127
|
+
*
|
|
128
|
+
* The computed value's internal effect is automatically cleaned up
|
|
129
|
+
* when the component disconnects from the DOM.
|
|
130
|
+
*
|
|
131
|
+
* Must be called during a component lifecycle hook such as `connected`,
|
|
132
|
+
* `beforeMount`, `onAdopted`, or `onAttributeChanged`.
|
|
133
|
+
*
|
|
134
|
+
* Do not create scoped primitives from `render()`. Repeated renders can
|
|
135
|
+
* accumulate render-scoped resources until disconnect; prefer lifecycle hooks.
|
|
136
|
+
*
|
|
137
|
+
* @template T - The type of the computed value
|
|
138
|
+
* @param fn - Derivation function that reads reactive sources
|
|
139
|
+
* @returns A new Computed instance that auto-cleans-up with the component
|
|
140
|
+
* @throws {Error} If called outside a component scope
|
|
141
|
+
*
|
|
142
|
+
* @example
|
|
143
|
+
* ```ts
|
|
144
|
+
* import { component, html, useSignal, useComputed } from '@bquery/bquery/component';
|
|
145
|
+
*
|
|
146
|
+
* component('my-doubler', {
|
|
147
|
+
* connected() {
|
|
148
|
+
* const count = useSignal(1);
|
|
149
|
+
* const doubled = useComputed(() => count.value * 2);
|
|
150
|
+
* },
|
|
151
|
+
* render({ state }) {
|
|
152
|
+
* return html`<span>${state.doubled}</span>`;
|
|
153
|
+
* },
|
|
154
|
+
* });
|
|
155
|
+
* ```
|
|
156
|
+
*/
|
|
157
|
+
export function useComputed<T>(fn: () => T): Computed<T> {
|
|
158
|
+
const scope = currentScope;
|
|
159
|
+
if (!scope) {
|
|
160
|
+
throw new Error(
|
|
161
|
+
'bQuery component: useComputed() must be called inside a component lifecycle hook. Avoid calling it directly from render()'
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
const c = computed(fn);
|
|
165
|
+
scope.addDisposer(() => c.dispose());
|
|
166
|
+
return c;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Creates a side effect scoped to the current component.
|
|
171
|
+
*
|
|
172
|
+
* The effect runs immediately and re-runs when its reactive dependencies
|
|
173
|
+
* change. It is automatically disposed when the component disconnects
|
|
174
|
+
* from the DOM.
|
|
175
|
+
*
|
|
176
|
+
* Must be called during a component lifecycle hook such as `connected`,
|
|
177
|
+
* `beforeMount`, `onAdopted`, or `onAttributeChanged`.
|
|
178
|
+
*
|
|
179
|
+
* Do not create scoped primitives from `render()`. Repeated renders can
|
|
180
|
+
* accumulate render-scoped resources until disconnect; prefer lifecycle hooks.
|
|
181
|
+
*
|
|
182
|
+
* @param fn - The effect function; may return a cleanup function
|
|
183
|
+
* @returns A cleanup function to manually stop the effect early
|
|
184
|
+
* @throws {Error} If called outside a component scope
|
|
185
|
+
*
|
|
186
|
+
* @example
|
|
187
|
+
* ```ts
|
|
188
|
+
* import { component, useSignal, useEffect } from '@bquery/bquery/component';
|
|
189
|
+
*
|
|
190
|
+
* component('my-logger', {
|
|
191
|
+
* connected() {
|
|
192
|
+
* const count = useSignal(0);
|
|
193
|
+
* useEffect(() => {
|
|
194
|
+
* console.log('Count changed:', count.value);
|
|
195
|
+
* return () => console.log('Cleanup');
|
|
196
|
+
* });
|
|
197
|
+
* },
|
|
198
|
+
* render() { return '<p>Logger</p>'; },
|
|
199
|
+
* });
|
|
200
|
+
* ```
|
|
201
|
+
*/
|
|
202
|
+
export function useEffect(fn: () => void | CleanupFn): CleanupFn {
|
|
203
|
+
const scope = currentScope;
|
|
204
|
+
if (!scope) {
|
|
205
|
+
throw new Error(
|
|
206
|
+
'bQuery component: useEffect() must be called inside a component lifecycle hook. Avoid calling it directly from render()'
|
|
207
|
+
);
|
|
208
|
+
}
|
|
209
|
+
const cleanup = effect(fn);
|
|
210
|
+
scope.addDisposer(cleanup);
|
|
211
|
+
return cleanup;
|
|
212
|
+
}
|
package/src/component/types.ts
CHANGED
|
@@ -51,54 +51,48 @@ export type PropDefinition<T = unknown> = {
|
|
|
51
51
|
* When no explicit state generic is provided, component state falls back to
|
|
52
52
|
* an untyped string-keyed record for backwards compatibility.
|
|
53
53
|
*/
|
|
54
|
-
export type ComponentStateShape<
|
|
55
|
-
TState extends Record<string, unknown>
|
|
56
|
-
> = TState extends Record<string, unknown> ? TState : Record<string, unknown>;
|
|
54
|
+
export type ComponentStateShape<TState extends Record<string, unknown> | undefined = undefined> =
|
|
55
|
+
TState extends Record<string, unknown> ? TState : Record<string, unknown>;
|
|
57
56
|
|
|
58
57
|
/**
|
|
59
58
|
* Component state keys are string-based because runtime state access is backed
|
|
60
59
|
* by plain object properties.
|
|
61
60
|
*/
|
|
62
|
-
export type ComponentStateKey<
|
|
63
|
-
TState extends Record<string, unknown> | undefined = undefined,
|
|
64
|
-
> =
|
|
61
|
+
export type ComponentStateKey<TState extends Record<string, unknown> | undefined = undefined> =
|
|
65
62
|
keyof ComponentStateShape<TState> & string;
|
|
66
63
|
|
|
67
64
|
/**
|
|
68
65
|
* Public component element instance shape exposed by lifecycle hooks and
|
|
69
66
|
* `defineComponent()` return values.
|
|
70
67
|
*/
|
|
71
|
-
export type ComponentElement<
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
*/
|
|
100
|
-
getState<TResult = unknown>(key: string): TResult;
|
|
101
|
-
};
|
|
68
|
+
export type ComponentElement<TState extends Record<string, unknown> | undefined = undefined> =
|
|
69
|
+
HTMLElement & {
|
|
70
|
+
/**
|
|
71
|
+
* Updates a state property and triggers a re-render.
|
|
72
|
+
*
|
|
73
|
+
* @param key - The state property key
|
|
74
|
+
* @param value - The new value
|
|
75
|
+
*/
|
|
76
|
+
setState<TKey extends ComponentStateKey<TState>>(
|
|
77
|
+
key: TKey,
|
|
78
|
+
value: ComponentStateShape<TState>[TKey]
|
|
79
|
+
): void;
|
|
80
|
+
/**
|
|
81
|
+
* Gets a state property value.
|
|
82
|
+
*
|
|
83
|
+
* @param key - The state property key
|
|
84
|
+
* @returns The current value
|
|
85
|
+
*/
|
|
86
|
+
getState<TKey extends ComponentStateKey<TState>>(key: TKey): ComponentStateShape<TState>[TKey];
|
|
87
|
+
/**
|
|
88
|
+
* Gets a state property value with an explicit cast for backwards
|
|
89
|
+
* compatibility with the pre-typed-state API.
|
|
90
|
+
*
|
|
91
|
+
* @param key - The state property key
|
|
92
|
+
* @returns The current value cast to `TResult`
|
|
93
|
+
*/
|
|
94
|
+
getState<TResult = unknown>(key: string): TResult;
|
|
95
|
+
};
|
|
102
96
|
|
|
103
97
|
/**
|
|
104
98
|
* Constructor returned by `defineComponent()`.
|
|
@@ -185,8 +179,8 @@ type ComponentHookWithProps<
|
|
|
185
179
|
TState extends Record<string, unknown> | undefined = undefined,
|
|
186
180
|
TResult = void,
|
|
187
181
|
> = {
|
|
188
|
-
|
|
189
|
-
|
|
182
|
+
(this: ComponentElement<TState>, newProps: TProps, oldProps: TProps): TResult;
|
|
183
|
+
(newProps: TProps, oldProps: TProps): TResult;
|
|
190
184
|
};
|
|
191
185
|
type ComponentUpdatedHook<
|
|
192
186
|
TState extends Record<string, unknown> | undefined = undefined,
|
|
@@ -200,6 +194,17 @@ type ComponentErrorHook<TState extends Record<string, unknown> | undefined = und
|
|
|
200
194
|
(error: Error): void;
|
|
201
195
|
};
|
|
202
196
|
|
|
197
|
+
type ComponentAttributeChangedHook<TState extends Record<string, unknown> | undefined = undefined> =
|
|
198
|
+
{
|
|
199
|
+
(
|
|
200
|
+
this: ComponentElement<TState>,
|
|
201
|
+
name: string,
|
|
202
|
+
oldValue: string | null,
|
|
203
|
+
newValue: string | null
|
|
204
|
+
): void;
|
|
205
|
+
(name: string, oldValue: string | null, newValue: string | null): void;
|
|
206
|
+
};
|
|
207
|
+
|
|
203
208
|
type ComponentStateDefinition<TState extends Record<string, unknown> | undefined = undefined> =
|
|
204
209
|
TState extends Record<string, unknown>
|
|
205
210
|
? {
|
|
@@ -222,6 +227,15 @@ type ComponentSignalsDefinition<TSignals extends ComponentSignals = Record<strin
|
|
|
222
227
|
signals: TSignals;
|
|
223
228
|
};
|
|
224
229
|
|
|
230
|
+
/**
|
|
231
|
+
* Controls Shadow DOM mode for the component.
|
|
232
|
+
*
|
|
233
|
+
* - `true` or `'open'` — attach an open shadow root (default)
|
|
234
|
+
* - `'closed'` — attach a closed shadow root
|
|
235
|
+
* - `false` — no shadow root; render directly into the host element
|
|
236
|
+
*/
|
|
237
|
+
export type ShadowMode = boolean | 'open' | 'closed';
|
|
238
|
+
|
|
225
239
|
export type ComponentDefinition<
|
|
226
240
|
TProps extends Record<string, unknown> = Record<string, unknown>,
|
|
227
241
|
TState extends Record<string, unknown> | undefined = undefined,
|
|
@@ -230,8 +244,25 @@ export type ComponentDefinition<
|
|
|
230
244
|
ComponentSignalsDefinition<TSignals> & {
|
|
231
245
|
/** Prop definitions with types and defaults */
|
|
232
246
|
props?: Record<keyof TProps, PropDefinition>;
|
|
233
|
-
/**
|
|
247
|
+
/**
|
|
248
|
+
* CSS styles injected for the component.
|
|
249
|
+
*
|
|
250
|
+
* When `shadow` uses a shadow root (`true`, `'open'`, or `'closed'`), these
|
|
251
|
+
* styles are scoped to that shadow tree. When `shadow` is `false`, the
|
|
252
|
+
* generated `<style>` element is rendered into the host's light DOM and may
|
|
253
|
+
* therefore affect surrounding markup according to normal CSS cascade rules.
|
|
254
|
+
*/
|
|
234
255
|
styles?: string;
|
|
256
|
+
/**
|
|
257
|
+
* Controls Shadow DOM mode.
|
|
258
|
+
*
|
|
259
|
+
* - `true` or `'open'` — open shadow root (default)
|
|
260
|
+
* - `'closed'` — closed shadow root
|
|
261
|
+
* - `false` — no shadow root; render into the host element
|
|
262
|
+
*
|
|
263
|
+
* @default true
|
|
264
|
+
*/
|
|
265
|
+
shadow?: ShadowMode;
|
|
235
266
|
/**
|
|
236
267
|
* Extra sanitizer options merged with the framework base allowlist during render.
|
|
237
268
|
* Only opt in attributes/tags whose values you control or validate. Sensitive
|
|
@@ -239,12 +270,35 @@ export type ComponentDefinition<
|
|
|
239
270
|
* or UI-redressing risks if used with untrusted input.
|
|
240
271
|
*/
|
|
241
272
|
sanitize?: ComponentSanitizeOptions;
|
|
273
|
+
/**
|
|
274
|
+
* Additional attributes to observe beyond those declared in `props`.
|
|
275
|
+
*
|
|
276
|
+
* Useful when you want `onAttributeChanged` to fire for attributes
|
|
277
|
+
* that are not part of the typed props system.
|
|
278
|
+
*/
|
|
279
|
+
observeAttributes?: string[];
|
|
242
280
|
/** Lifecycle hook called before the component mounts (before first render) */
|
|
243
281
|
beforeMount?: ComponentHook<TState>;
|
|
244
282
|
/** Lifecycle hook called when component is added to DOM */
|
|
245
283
|
connected?: ComponentHook<TState>;
|
|
246
284
|
/** Lifecycle hook called when component is removed from DOM */
|
|
247
285
|
disconnected?: ComponentHook<TState>;
|
|
286
|
+
/**
|
|
287
|
+
* Lifecycle hook called when the component is moved to a new document
|
|
288
|
+
* (e.g. via `document.adoptNode`).
|
|
289
|
+
*/
|
|
290
|
+
onAdopted?: ComponentHook<TState>;
|
|
291
|
+
/**
|
|
292
|
+
* Lifecycle hook called when any observed attribute changes.
|
|
293
|
+
*
|
|
294
|
+
* Observed attributes are automatically derived from `props` keys
|
|
295
|
+
* plus any additional names in `observeAttributes`.
|
|
296
|
+
*
|
|
297
|
+
* @param name - The attribute name that changed
|
|
298
|
+
* @param oldValue - The previous attribute value (null if added)
|
|
299
|
+
* @param newValue - The new attribute value (null if removed)
|
|
300
|
+
*/
|
|
301
|
+
onAttributeChanged?: ComponentAttributeChangedHook<TState>;
|
|
248
302
|
/** Lifecycle hook called before an update render; return false to prevent */
|
|
249
303
|
beforeUpdate?: ComponentHookWithProps<TProps, TState, boolean | void>;
|
|
250
304
|
/** Lifecycle hook called after update renders; receives attribute change info when applicable */
|