@bquery/bquery 1.4.0 → 1.5.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 +139 -120
- package/dist/component/component.d.ts.map +1 -1
- package/dist/component/index.d.ts +2 -0
- package/dist/component/index.d.ts.map +1 -1
- package/dist/component/library.d.ts +34 -0
- package/dist/component/library.d.ts.map +1 -0
- package/dist/component/types.d.ts +10 -6
- package/dist/component/types.d.ts.map +1 -1
- package/dist/component-CY5MVoYN.js +531 -0
- package/dist/component-CY5MVoYN.js.map +1 -0
- package/dist/component.es.mjs +6 -184
- package/dist/config-DRmZZno3.js +40 -0
- package/dist/config-DRmZZno3.js.map +1 -0
- package/dist/core-CK2Mfpf4.js +648 -0
- package/dist/core-CK2Mfpf4.js.map +1 -0
- package/dist/core-DPdbItcq.js +112 -0
- package/dist/core-DPdbItcq.js.map +1 -0
- package/dist/core.es.mjs +45 -1261
- package/dist/full.d.ts +6 -6
- package/dist/full.d.ts.map +1 -1
- package/dist/full.es.mjs +98 -92
- package/dist/full.iife.js +173 -3
- package/dist/full.iife.js.map +1 -1
- package/dist/full.umd.js +173 -3
- package/dist/full.umd.js.map +1 -1
- package/dist/index.es.mjs +143 -139
- package/dist/motion/transition.d.ts +1 -1
- package/dist/motion/transition.d.ts.map +1 -1
- package/dist/motion/types.d.ts +11 -1
- package/dist/motion/types.d.ts.map +1 -1
- package/dist/motion-C5DRdPnO.js +415 -0
- package/dist/motion-C5DRdPnO.js.map +1 -0
- package/dist/motion.es.mjs +25 -361
- package/dist/object-qGpWr6-J.js +38 -0
- package/dist/object-qGpWr6-J.js.map +1 -0
- package/dist/platform/announcer.d.ts +59 -0
- package/dist/platform/announcer.d.ts.map +1 -0
- package/dist/platform/config.d.ts +92 -0
- package/dist/platform/config.d.ts.map +1 -0
- package/dist/platform/cookies.d.ts +45 -0
- package/dist/platform/cookies.d.ts.map +1 -0
- package/dist/platform/index.d.ts +8 -0
- package/dist/platform/index.d.ts.map +1 -1
- package/dist/platform/meta.d.ts +62 -0
- package/dist/platform/meta.d.ts.map +1 -0
- package/dist/platform-B7JhGBc7.js +361 -0
- package/dist/platform-B7JhGBc7.js.map +1 -0
- package/dist/platform.es.mjs +11 -248
- package/dist/reactive/async-data.d.ts +114 -0
- package/dist/reactive/async-data.d.ts.map +1 -0
- package/dist/reactive/index.d.ts +2 -2
- package/dist/reactive/index.d.ts.map +1 -1
- package/dist/reactive/signal.d.ts +2 -0
- package/dist/reactive/signal.d.ts.map +1 -1
- package/dist/reactive-BDya-ia8.js +253 -0
- package/dist/reactive-BDya-ia8.js.map +1 -0
- package/dist/reactive.es.mjs +18 -34
- package/dist/router-CijiICxt.js +188 -0
- package/dist/router-CijiICxt.js.map +1 -0
- package/dist/router.es.mjs +11 -200
- package/dist/sanitize-jyJ2ryE2.js +302 -0
- package/dist/sanitize-jyJ2ryE2.js.map +1 -0
- package/dist/security/constants.d.ts.map +1 -1
- package/dist/security.es.mjs +10 -56
- package/dist/store-CPK9E62U.js +262 -0
- package/dist/store-CPK9E62U.js.map +1 -0
- package/dist/store.es.mjs +12 -25
- package/dist/view-Cdi0g-qo.js +396 -0
- package/dist/view-Cdi0g-qo.js.map +1 -0
- package/dist/view.es.mjs +10 -430
- package/package.json +15 -11
- package/src/component/component.ts +319 -289
- package/src/component/index.ts +42 -40
- package/src/component/library.ts +504 -0
- package/src/component/types.ts +91 -85
- package/src/core/collection.ts +628 -628
- package/src/core/element.ts +774 -774
- package/src/core/index.ts +48 -48
- package/src/core/utils/function.ts +151 -151
- package/src/full.ts +223 -187
- package/src/motion/animate.ts +113 -113
- package/src/motion/flip.ts +176 -176
- package/src/motion/scroll.ts +57 -57
- package/src/motion/spring.ts +150 -150
- package/src/motion/timeline.ts +246 -246
- package/src/motion/transition.ts +53 -7
- package/src/motion/types.ts +208 -198
- package/src/platform/announcer.ts +208 -0
- package/src/platform/config.ts +163 -0
- package/src/platform/cookies.ts +165 -0
- package/src/platform/index.ts +39 -18
- package/src/platform/meta.ts +168 -0
- package/src/platform/storage.ts +215 -215
- package/src/reactive/async-data.ts +486 -0
- package/src/reactive/core.ts +114 -114
- package/src/reactive/effect.ts +54 -54
- package/src/reactive/index.ts +37 -23
- package/src/reactive/internals.ts +122 -122
- package/src/reactive/signal.ts +29 -20
- package/src/security/constants.ts +211 -209
- package/src/security/sanitize-core.ts +364 -364
- package/src/view/evaluate.ts +290 -290
- package/dist/batch-x7b2eZST.js +0 -13
- package/dist/batch-x7b2eZST.js.map +0 -1
- package/dist/component.es.mjs.map +0 -1
- package/dist/core-BhpuvPhy.js +0 -170
- package/dist/core-BhpuvPhy.js.map +0 -1
- package/dist/core.es.mjs.map +0 -1
- package/dist/full.es.mjs.map +0 -1
- package/dist/index.es.mjs.map +0 -1
- package/dist/motion.es.mjs.map +0 -1
- package/dist/persisted-DHoi3uEs.js +0 -278
- package/dist/persisted-DHoi3uEs.js.map +0 -1
- package/dist/platform.es.mjs.map +0 -1
- package/dist/reactive.es.mjs.map +0 -1
- package/dist/router.es.mjs.map +0 -1
- package/dist/sanitize-Cxvxa-DX.js +0 -283
- package/dist/sanitize-Cxvxa-DX.js.map +0 -1
- package/dist/security.es.mjs.map +0 -1
- package/dist/store.es.mjs.map +0 -1
- package/dist/type-guards-BdKlYYlS.js +0 -32
- package/dist/type-guards-BdKlYYlS.js.map +0 -1
- package/dist/untrack-DNnnqdlR.js +0 -6
- package/dist/untrack-DNnnqdlR.js.map +0 -1
- package/dist/view.es.mjs.map +0 -1
- package/dist/watch-DXXv3iAI.js +0 -58
- package/dist/watch-DXXv3iAI.js.map +0 -1
package/src/full.ts
CHANGED
|
@@ -1,187 +1,223 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* bQuery.js — Full Bundle
|
|
3
|
-
*
|
|
4
|
-
* This is the complete bundle containing all modules for CDN usage.
|
|
5
|
-
* Use this when you want all features without tree-shaking concerns.
|
|
6
|
-
*
|
|
7
|
-
* @module bquery/full
|
|
8
|
-
*
|
|
9
|
-
* @example CDN Usage (ES Modules)
|
|
10
|
-
* ```html
|
|
11
|
-
* <script type="module">
|
|
12
|
-
* import { $, signal, component } from 'https://unpkg.com/bquery@1/dist/full.es.mjs';
|
|
13
|
-
*
|
|
14
|
-
* const count = signal(0);
|
|
15
|
-
* $('#counter').text(count.value);
|
|
16
|
-
* </script>
|
|
17
|
-
* ```
|
|
18
|
-
*
|
|
19
|
-
* @example CDN Usage (UMD/Global)
|
|
20
|
-
* ```html
|
|
21
|
-
* <script src="https://unpkg.com/bquery@1/dist/full.umd.js"></script>
|
|
22
|
-
* <script>
|
|
23
|
-
* const { $, signal } = bQuery;
|
|
24
|
-
* const count = signal(0);
|
|
25
|
-
* </script>
|
|
26
|
-
* ```
|
|
27
|
-
*
|
|
28
|
-
* @example CDN Usage (IIFE)
|
|
29
|
-
* ```html
|
|
30
|
-
* <script src="https://unpkg.com/bquery@1/dist/full.iife.js"></script>
|
|
31
|
-
* <script>
|
|
32
|
-
* // bQuery is available as a global variable
|
|
33
|
-
* const { $, $$ } = bQuery;
|
|
34
|
-
* </script>
|
|
35
|
-
* ```
|
|
36
|
-
*/
|
|
37
|
-
|
|
38
|
-
// ============================================================================
|
|
39
|
-
// Core Module: Selectors, DOM operations, events, utilities
|
|
40
|
-
// ============================================================================
|
|
41
|
-
export { $, $$, BQueryCollection, BQueryElement, utils } from './core/index';
|
|
42
|
-
|
|
43
|
-
// ============================================================================
|
|
44
|
-
// Reactive Module: Signals, computed values, effects, batching
|
|
45
|
-
// ============================================================================
|
|
46
|
-
export {
|
|
47
|
-
Computed,
|
|
48
|
-
Signal,
|
|
49
|
-
batch,
|
|
50
|
-
computed,
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
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
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
} from './
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
// ============================================================================
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
1
|
+
/**
|
|
2
|
+
* bQuery.js — Full Bundle
|
|
3
|
+
*
|
|
4
|
+
* This is the complete bundle containing all modules for CDN usage.
|
|
5
|
+
* Use this when you want all features without tree-shaking concerns.
|
|
6
|
+
*
|
|
7
|
+
* @module bquery/full
|
|
8
|
+
*
|
|
9
|
+
* @example CDN Usage (ES Modules)
|
|
10
|
+
* ```html
|
|
11
|
+
* <script type="module">
|
|
12
|
+
* import { $, signal, component } from 'https://unpkg.com/bquery@1/dist/full.es.mjs';
|
|
13
|
+
*
|
|
14
|
+
* const count = signal(0);
|
|
15
|
+
* $('#counter').text(count.value);
|
|
16
|
+
* </script>
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* @example CDN Usage (UMD/Global)
|
|
20
|
+
* ```html
|
|
21
|
+
* <script src="https://unpkg.com/bquery@1/dist/full.umd.js"></script>
|
|
22
|
+
* <script>
|
|
23
|
+
* const { $, signal } = bQuery;
|
|
24
|
+
* const count = signal(0);
|
|
25
|
+
* </script>
|
|
26
|
+
* ```
|
|
27
|
+
*
|
|
28
|
+
* @example CDN Usage (IIFE)
|
|
29
|
+
* ```html
|
|
30
|
+
* <script src="https://unpkg.com/bquery@1/dist/full.iife.js"></script>
|
|
31
|
+
* <script>
|
|
32
|
+
* // bQuery is available as a global variable
|
|
33
|
+
* const { $, $$ } = bQuery;
|
|
34
|
+
* </script>
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
|
|
38
|
+
// ============================================================================
|
|
39
|
+
// Core Module: Selectors, DOM operations, events, utilities
|
|
40
|
+
// ============================================================================
|
|
41
|
+
export { $, $$, BQueryCollection, BQueryElement, utils } from './core/index';
|
|
42
|
+
|
|
43
|
+
// ============================================================================
|
|
44
|
+
// Reactive Module: Signals, computed values, effects, batching
|
|
45
|
+
// ============================================================================
|
|
46
|
+
export {
|
|
47
|
+
Computed,
|
|
48
|
+
Signal,
|
|
49
|
+
batch,
|
|
50
|
+
computed,
|
|
51
|
+
createUseFetch,
|
|
52
|
+
effect,
|
|
53
|
+
isComputed,
|
|
54
|
+
isSignal,
|
|
55
|
+
linkedSignal,
|
|
56
|
+
persistedSignal,
|
|
57
|
+
readonly,
|
|
58
|
+
signal,
|
|
59
|
+
useAsyncData,
|
|
60
|
+
useFetch,
|
|
61
|
+
untrack,
|
|
62
|
+
watch,
|
|
63
|
+
} from './reactive/index';
|
|
64
|
+
export type {
|
|
65
|
+
AsyncDataState,
|
|
66
|
+
AsyncDataStatus,
|
|
67
|
+
AsyncWatchSource,
|
|
68
|
+
CleanupFn,
|
|
69
|
+
FetchInput,
|
|
70
|
+
LinkedSignal,
|
|
71
|
+
Observer,
|
|
72
|
+
ReadonlySignal,
|
|
73
|
+
UseAsyncDataOptions,
|
|
74
|
+
UseFetchOptions,
|
|
75
|
+
} from './reactive/index';
|
|
76
|
+
|
|
77
|
+
// ============================================================================
|
|
78
|
+
// Component Module: Web Components helper with Shadow DOM
|
|
79
|
+
// ============================================================================
|
|
80
|
+
export { component, html, registerDefaultComponents, safeHtml } from './component/index';
|
|
81
|
+
export type {
|
|
82
|
+
ComponentDefinition,
|
|
83
|
+
DefaultComponentLibraryOptions,
|
|
84
|
+
PropDefinition,
|
|
85
|
+
RegisteredDefaultComponents,
|
|
86
|
+
} from './component/index';
|
|
87
|
+
|
|
88
|
+
// ============================================================================
|
|
89
|
+
// Motion Module: View transitions, FLIP animations, springs
|
|
90
|
+
// ============================================================================
|
|
91
|
+
export {
|
|
92
|
+
animate,
|
|
93
|
+
capturePosition,
|
|
94
|
+
easeInCubic,
|
|
95
|
+
easeInOutCubic,
|
|
96
|
+
easeInOutQuad,
|
|
97
|
+
easeInQuad,
|
|
98
|
+
easeOutBack,
|
|
99
|
+
easeOutCubic,
|
|
100
|
+
easeOutExpo,
|
|
101
|
+
easeOutQuad,
|
|
102
|
+
easingPresets,
|
|
103
|
+
flip,
|
|
104
|
+
flipElements,
|
|
105
|
+
flipList,
|
|
106
|
+
keyframePresets,
|
|
107
|
+
linear,
|
|
108
|
+
prefersReducedMotion,
|
|
109
|
+
scrollAnimate,
|
|
110
|
+
sequence,
|
|
111
|
+
spring,
|
|
112
|
+
springPresets,
|
|
113
|
+
stagger,
|
|
114
|
+
timeline,
|
|
115
|
+
transition,
|
|
116
|
+
} from './motion/index';
|
|
117
|
+
export type {
|
|
118
|
+
AnimateOptions,
|
|
119
|
+
EasingFunction,
|
|
120
|
+
ElementBounds,
|
|
121
|
+
FlipGroupOptions,
|
|
122
|
+
FlipOptions,
|
|
123
|
+
ScrollAnimateCleanup,
|
|
124
|
+
ScrollAnimateOptions,
|
|
125
|
+
SequenceOptions,
|
|
126
|
+
SequenceStep,
|
|
127
|
+
Spring,
|
|
128
|
+
SpringConfig,
|
|
129
|
+
StaggerFunction,
|
|
130
|
+
StaggerOptions,
|
|
131
|
+
TimelineConfig,
|
|
132
|
+
TimelineControls,
|
|
133
|
+
TimelineStep,
|
|
134
|
+
TransitionOptions,
|
|
135
|
+
} from './motion/index';
|
|
136
|
+
|
|
137
|
+
// ============================================================================
|
|
138
|
+
// Security Module: Sanitization, CSP compatibility, Trusted Types
|
|
139
|
+
// ============================================================================
|
|
140
|
+
export {
|
|
141
|
+
createTrustedHtml,
|
|
142
|
+
escapeHtml,
|
|
143
|
+
generateNonce,
|
|
144
|
+
getTrustedTypesPolicy,
|
|
145
|
+
hasCSPDirective,
|
|
146
|
+
isTrustedTypesSupported,
|
|
147
|
+
sanitize,
|
|
148
|
+
sanitizeHtml,
|
|
149
|
+
stripTags,
|
|
150
|
+
} from './security/index';
|
|
151
|
+
export type { SanitizeOptions } from './security/index';
|
|
152
|
+
|
|
153
|
+
// ============================================================================
|
|
154
|
+
// Platform Module: Storage, buckets, notifications, cache
|
|
155
|
+
// ============================================================================
|
|
156
|
+
export {
|
|
157
|
+
buckets,
|
|
158
|
+
cache,
|
|
159
|
+
defineBqueryConfig,
|
|
160
|
+
definePageMeta,
|
|
161
|
+
getBqueryConfig,
|
|
162
|
+
notifications,
|
|
163
|
+
storage,
|
|
164
|
+
useAnnouncer,
|
|
165
|
+
useCookie,
|
|
166
|
+
} from './platform/index';
|
|
167
|
+
export type {
|
|
168
|
+
AnnounceOptions,
|
|
169
|
+
AnnouncerHandle,
|
|
170
|
+
Bucket,
|
|
171
|
+
BqueryConfig,
|
|
172
|
+
CacheHandle,
|
|
173
|
+
IndexedDBOptions,
|
|
174
|
+
NotificationOptions,
|
|
175
|
+
PageMetaDefinition,
|
|
176
|
+
StorageAdapter,
|
|
177
|
+
UseAnnouncerOptions,
|
|
178
|
+
UseCookieOptions,
|
|
179
|
+
} from './platform/index';
|
|
180
|
+
|
|
181
|
+
// ============================================================================
|
|
182
|
+
// Router Module: SPA routing, navigation guards, lazy loading
|
|
183
|
+
// ============================================================================
|
|
184
|
+
export {
|
|
185
|
+
back,
|
|
186
|
+
createRouter,
|
|
187
|
+
currentRoute,
|
|
188
|
+
forward,
|
|
189
|
+
interceptLinks,
|
|
190
|
+
isActive,
|
|
191
|
+
isActiveSignal,
|
|
192
|
+
link,
|
|
193
|
+
navigate,
|
|
194
|
+
resolve,
|
|
195
|
+
} from './router/index';
|
|
196
|
+
export type {
|
|
197
|
+
NavigationGuard,
|
|
198
|
+
Route,
|
|
199
|
+
RouteDefinition,
|
|
200
|
+
Router,
|
|
201
|
+
RouterOptions,
|
|
202
|
+
} from './router/index';
|
|
203
|
+
|
|
204
|
+
// ============================================================================
|
|
205
|
+
// Store Module: Signal-based state management
|
|
206
|
+
// ============================================================================
|
|
207
|
+
export {
|
|
208
|
+
createPersistedStore,
|
|
209
|
+
createStore,
|
|
210
|
+
destroyStore,
|
|
211
|
+
getStore,
|
|
212
|
+
listStores,
|
|
213
|
+
mapActions,
|
|
214
|
+
mapState,
|
|
215
|
+
registerPlugin,
|
|
216
|
+
} from './store/index';
|
|
217
|
+
export type { StateFactory, Store, StoreDefinition, StorePlugin } from './store/index';
|
|
218
|
+
|
|
219
|
+
// ============================================================================
|
|
220
|
+
// View Module: Declarative DOM bindings without compiler
|
|
221
|
+
// ============================================================================
|
|
222
|
+
export { createTemplate, mount } from './view/index';
|
|
223
|
+
export type { BindingContext, MountOptions, View } from './view/index';
|
package/src/motion/animate.ts
CHANGED
|
@@ -1,113 +1,113 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Web Animations helpers.
|
|
3
|
-
*
|
|
4
|
-
* @module bquery/motion
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { prefersReducedMotion } from './reduced-motion';
|
|
8
|
-
import type { AnimateOptions } from './types';
|
|
9
|
-
|
|
10
|
-
/** @internal */
|
|
11
|
-
const isStyleValue = (value: unknown): value is string | number =>
|
|
12
|
-
typeof value === 'string' || typeof value === 'number';
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Convert camelCase property names to kebab-case for CSS.
|
|
16
|
-
* @internal
|
|
17
|
-
*/
|
|
18
|
-
const toKebabCase = (str: string): string => {
|
|
19
|
-
return str.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`);
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
/** @internal */
|
|
23
|
-
export const applyFinalKeyframeStyles = (
|
|
24
|
-
element: Element,
|
|
25
|
-
keyframes: Keyframe[] | PropertyIndexedKeyframes
|
|
26
|
-
): void => {
|
|
27
|
-
const htmlElement = element as HTMLElement;
|
|
28
|
-
const style = htmlElement.style;
|
|
29
|
-
|
|
30
|
-
if (Array.isArray(keyframes)) {
|
|
31
|
-
const last = keyframes[keyframes.length - 1];
|
|
32
|
-
if (!last) return;
|
|
33
|
-
for (const [prop, value] of Object.entries(last)) {
|
|
34
|
-
if (prop === 'offset' || prop === 'easing' || prop === 'composite') continue;
|
|
35
|
-
if (isStyleValue(value)) {
|
|
36
|
-
// Convert camelCase to kebab-case for CSS properties
|
|
37
|
-
const cssProp = prop.startsWith('--') ? prop : toKebabCase(prop);
|
|
38
|
-
style.setProperty(cssProp, String(value));
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
return;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
for (const [prop, value] of Object.entries(keyframes)) {
|
|
45
|
-
if (prop === 'offset' || prop === 'easing' || prop === 'composite') continue;
|
|
46
|
-
const finalValue = Array.isArray(value) ? value[value.length - 1] : value;
|
|
47
|
-
if (isStyleValue(finalValue)) {
|
|
48
|
-
// Convert camelCase to kebab-case for CSS properties
|
|
49
|
-
const cssProp = prop.startsWith('--') ? prop : toKebabCase(prop);
|
|
50
|
-
style.setProperty(cssProp, String(finalValue));
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Animate an element using the Web Animations API with reduced-motion fallback.
|
|
57
|
-
*
|
|
58
|
-
* @param element - Element to animate
|
|
59
|
-
* @param config - Animation configuration
|
|
60
|
-
* @returns Promise that resolves when animation completes
|
|
61
|
-
*
|
|
62
|
-
* @example
|
|
63
|
-
* ```ts
|
|
64
|
-
* await animate(element, {
|
|
65
|
-
* keyframes: [{ opacity: 0 }, { opacity: 1 }],
|
|
66
|
-
* options: { duration: 200, easing: 'ease-out' },
|
|
67
|
-
* });
|
|
68
|
-
* ```
|
|
69
|
-
*/
|
|
70
|
-
export const animate = (element: Element, config: AnimateOptions): Promise<void> => {
|
|
71
|
-
const { keyframes, options, commitStyles = true, respectReducedMotion = true, onFinish } = config;
|
|
72
|
-
|
|
73
|
-
if (respectReducedMotion && prefersReducedMotion()) {
|
|
74
|
-
if (commitStyles) {
|
|
75
|
-
applyFinalKeyframeStyles(element, keyframes);
|
|
76
|
-
}
|
|
77
|
-
onFinish?.();
|
|
78
|
-
return Promise.resolve();
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
const htmlElement = element as HTMLElement;
|
|
82
|
-
if (typeof htmlElement.animate !== 'function') {
|
|
83
|
-
if (commitStyles) {
|
|
84
|
-
applyFinalKeyframeStyles(element, keyframes);
|
|
85
|
-
}
|
|
86
|
-
onFinish?.();
|
|
87
|
-
return Promise.resolve();
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
return new Promise((resolve) => {
|
|
91
|
-
const animation = htmlElement.animate(keyframes, options);
|
|
92
|
-
let finalized = false;
|
|
93
|
-
const finalize = () => {
|
|
94
|
-
if (finalized) return;
|
|
95
|
-
finalized = true;
|
|
96
|
-
if (commitStyles) {
|
|
97
|
-
if (typeof animation.commitStyles === 'function') {
|
|
98
|
-
animation.commitStyles();
|
|
99
|
-
} else {
|
|
100
|
-
applyFinalKeyframeStyles(element, keyframes);
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
animation.cancel();
|
|
104
|
-
onFinish?.();
|
|
105
|
-
resolve();
|
|
106
|
-
};
|
|
107
|
-
|
|
108
|
-
animation.onfinish = finalize;
|
|
109
|
-
if (animation.finished) {
|
|
110
|
-
animation.finished.then(finalize).catch(finalize);
|
|
111
|
-
}
|
|
112
|
-
});
|
|
113
|
-
};
|
|
1
|
+
/**
|
|
2
|
+
* Web Animations helpers.
|
|
3
|
+
*
|
|
4
|
+
* @module bquery/motion
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { prefersReducedMotion } from './reduced-motion';
|
|
8
|
+
import type { AnimateOptions } from './types';
|
|
9
|
+
|
|
10
|
+
/** @internal */
|
|
11
|
+
const isStyleValue = (value: unknown): value is string | number =>
|
|
12
|
+
typeof value === 'string' || typeof value === 'number';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Convert camelCase property names to kebab-case for CSS.
|
|
16
|
+
* @internal
|
|
17
|
+
*/
|
|
18
|
+
const toKebabCase = (str: string): string => {
|
|
19
|
+
return str.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`);
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
/** @internal */
|
|
23
|
+
export const applyFinalKeyframeStyles = (
|
|
24
|
+
element: Element,
|
|
25
|
+
keyframes: Keyframe[] | PropertyIndexedKeyframes
|
|
26
|
+
): void => {
|
|
27
|
+
const htmlElement = element as HTMLElement;
|
|
28
|
+
const style = htmlElement.style;
|
|
29
|
+
|
|
30
|
+
if (Array.isArray(keyframes)) {
|
|
31
|
+
const last = keyframes[keyframes.length - 1];
|
|
32
|
+
if (!last) return;
|
|
33
|
+
for (const [prop, value] of Object.entries(last)) {
|
|
34
|
+
if (prop === 'offset' || prop === 'easing' || prop === 'composite') continue;
|
|
35
|
+
if (isStyleValue(value)) {
|
|
36
|
+
// Convert camelCase to kebab-case for CSS properties
|
|
37
|
+
const cssProp = prop.startsWith('--') ? prop : toKebabCase(prop);
|
|
38
|
+
style.setProperty(cssProp, String(value));
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
for (const [prop, value] of Object.entries(keyframes)) {
|
|
45
|
+
if (prop === 'offset' || prop === 'easing' || prop === 'composite') continue;
|
|
46
|
+
const finalValue = Array.isArray(value) ? value[value.length - 1] : value;
|
|
47
|
+
if (isStyleValue(finalValue)) {
|
|
48
|
+
// Convert camelCase to kebab-case for CSS properties
|
|
49
|
+
const cssProp = prop.startsWith('--') ? prop : toKebabCase(prop);
|
|
50
|
+
style.setProperty(cssProp, String(finalValue));
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Animate an element using the Web Animations API with reduced-motion fallback.
|
|
57
|
+
*
|
|
58
|
+
* @param element - Element to animate
|
|
59
|
+
* @param config - Animation configuration
|
|
60
|
+
* @returns Promise that resolves when animation completes
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* ```ts
|
|
64
|
+
* await animate(element, {
|
|
65
|
+
* keyframes: [{ opacity: 0 }, { opacity: 1 }],
|
|
66
|
+
* options: { duration: 200, easing: 'ease-out' },
|
|
67
|
+
* });
|
|
68
|
+
* ```
|
|
69
|
+
*/
|
|
70
|
+
export const animate = (element: Element, config: AnimateOptions): Promise<void> => {
|
|
71
|
+
const { keyframes, options, commitStyles = true, respectReducedMotion = true, onFinish } = config;
|
|
72
|
+
|
|
73
|
+
if (respectReducedMotion && prefersReducedMotion()) {
|
|
74
|
+
if (commitStyles) {
|
|
75
|
+
applyFinalKeyframeStyles(element, keyframes);
|
|
76
|
+
}
|
|
77
|
+
onFinish?.();
|
|
78
|
+
return Promise.resolve();
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const htmlElement = element as HTMLElement;
|
|
82
|
+
if (typeof htmlElement.animate !== 'function') {
|
|
83
|
+
if (commitStyles) {
|
|
84
|
+
applyFinalKeyframeStyles(element, keyframes);
|
|
85
|
+
}
|
|
86
|
+
onFinish?.();
|
|
87
|
+
return Promise.resolve();
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return new Promise((resolve) => {
|
|
91
|
+
const animation = htmlElement.animate(keyframes, options);
|
|
92
|
+
let finalized = false;
|
|
93
|
+
const finalize = () => {
|
|
94
|
+
if (finalized) return;
|
|
95
|
+
finalized = true;
|
|
96
|
+
if (commitStyles) {
|
|
97
|
+
if (typeof animation.commitStyles === 'function') {
|
|
98
|
+
animation.commitStyles();
|
|
99
|
+
} else {
|
|
100
|
+
applyFinalKeyframeStyles(element, keyframes);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
animation.cancel();
|
|
104
|
+
onFinish?.();
|
|
105
|
+
resolve();
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
animation.onfinish = finalize;
|
|
109
|
+
if (animation.finished) {
|
|
110
|
+
animation.finished.then(finalize).catch(finalize);
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
};
|