foldkit 0.85.0 → 0.86.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/task/dom.d.ts.map +1 -1
- package/dist/task/dom.js +6 -13
- package/dist/task/elementMovement.d.ts.map +1 -1
- package/dist/task/elementMovement.js +4 -5
- package/dist/task/index.d.ts +1 -1
- package/dist/task/index.d.ts.map +1 -1
- package/dist/task/index.js +1 -1
- package/dist/task/public.d.ts +1 -1
- package/dist/task/public.d.ts.map +1 -1
- package/dist/task/public.js +1 -1
- package/dist/task/timing.d.ts +23 -0
- package/dist/task/timing.d.ts.map +1 -1
- package/dist/task/timing.js +26 -0
- package/package.json +1 -1
package/dist/task/dom.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dom.d.ts","sourceRoot":"","sources":["../../src/task/dom.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,MAAM,EAMP,MAAM,QAAQ,CAAA;AAEf,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"dom.d.ts","sourceRoot":"","sources":["../../src/task/dom.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,MAAM,EAMP,MAAM,QAAQ,CAAA;AAEf,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AA8B5C;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,KAAK,GAAI,UAAU,MAAM,KAAG,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,eAAe,CAKxE,CAAA;AAEJ;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,SAAS,GACpB,UAAU,MAAM,EAChB,UAAU,QAAQ,CAAC;IAAE,aAAa,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,KAC7C,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,eAAe,CAgDlC,CAAA;AAuBJ;;;;;;;;;GASG;AACH,eAAO,MAAM,UAAU,GACrB,UAAU,MAAM,KACf,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,eAAe,CAclC,CAAA;AAEJ;;;;;;;;GAQG;AACH,eAAO,MAAM,YAAY,GACvB,UAAU,MAAM,KACf,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,eAAe,CAKlC,CAAA;AAEJ;;;;;;;;GAQG;AACH,eAAO,MAAM,cAAc,GACzB,UAAU,MAAM,KACf,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,eAAe,CAKlC,CAAA;AAEJ,0EAA0E;AAC1E,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,UAAU,CAAA;AAEhD;;;;;;;;GAQG;AACH,eAAO,MAAM,YAAY,GACvB,UAAU,MAAM,EAChB,WAAW,cAAc,KACxB,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,eAAe,CAiClC,CAAA"}
|
package/dist/task/dom.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Array, Effect, Equal, Function, Match as M, Number, Option, } from 'effect';
|
|
2
2
|
import { ElementNotFound } from './error.js';
|
|
3
|
+
import { afterRender } from './timing.js';
|
|
3
4
|
const BASE_DIALOG_Z_INDEX = 2147483600;
|
|
4
5
|
let openDialogCount = 0;
|
|
5
6
|
const dialogCleanups = new WeakMap();
|
|
@@ -11,14 +12,6 @@ const FOCUSABLE_SELECTOR = Array.join([
|
|
|
11
12
|
'textarea:not([disabled]):not([tabindex="-1"])',
|
|
12
13
|
'[tabindex]:not([tabindex="-1"])',
|
|
13
14
|
], ', ');
|
|
14
|
-
// NOTE: DOM tasks await one rAF before walking the tree. The runtime defers
|
|
15
|
-
// renders to the next animation frame and forks Commands on the microtask
|
|
16
|
-
// queue, so without this wait a Task that runs immediately after a dirtying
|
|
17
|
-
// Message would query the DOM before the matching VDOM patch has committed.
|
|
18
|
-
const awaitNextFrame = Effect.callback(resume => {
|
|
19
|
-
const handle = requestAnimationFrame(() => resume(Effect.void));
|
|
20
|
-
return Effect.sync(() => cancelAnimationFrame(handle));
|
|
21
|
-
});
|
|
22
15
|
const queryHTMLElement = (selector) => Effect.suspend(() => {
|
|
23
16
|
const element = document.querySelector(selector);
|
|
24
17
|
return element instanceof HTMLElement
|
|
@@ -49,7 +42,7 @@ const queryHTMLElement = (selector) => Effect.suspend(() => {
|
|
|
49
42
|
* ```
|
|
50
43
|
*/
|
|
51
44
|
export const focus = (selector) => Effect.gen(function* () {
|
|
52
|
-
yield*
|
|
45
|
+
yield* afterRender;
|
|
53
46
|
const element = yield* queryHTMLElement(selector);
|
|
54
47
|
element.focus();
|
|
55
48
|
});
|
|
@@ -69,7 +62,7 @@ export const focus = (selector) => Effect.gen(function* () {
|
|
|
69
62
|
* ```
|
|
70
63
|
*/
|
|
71
64
|
export const showModal = (selector, options) => Effect.gen(function* () {
|
|
72
|
-
yield*
|
|
65
|
+
yield* afterRender;
|
|
73
66
|
const element = document.querySelector(selector);
|
|
74
67
|
if (!(element instanceof HTMLDialogElement)) {
|
|
75
68
|
return yield* Effect.fail(new ElementNotFound({ selector }));
|
|
@@ -151,7 +144,7 @@ export const closeModal = (selector) => Effect.suspend(() => {
|
|
|
151
144
|
* ```
|
|
152
145
|
*/
|
|
153
146
|
export const clickElement = (selector) => Effect.gen(function* () {
|
|
154
|
-
yield*
|
|
147
|
+
yield* afterRender;
|
|
155
148
|
const element = yield* queryHTMLElement(selector);
|
|
156
149
|
element.click();
|
|
157
150
|
});
|
|
@@ -165,7 +158,7 @@ export const clickElement = (selector) => Effect.gen(function* () {
|
|
|
165
158
|
* ```
|
|
166
159
|
*/
|
|
167
160
|
export const scrollIntoView = (selector) => Effect.gen(function* () {
|
|
168
|
-
yield*
|
|
161
|
+
yield* afterRender;
|
|
169
162
|
const element = yield* queryHTMLElement(selector);
|
|
170
163
|
element.scrollIntoView({ block: 'nearest' });
|
|
171
164
|
});
|
|
@@ -179,7 +172,7 @@ export const scrollIntoView = (selector) => Effect.gen(function* () {
|
|
|
179
172
|
* ```
|
|
180
173
|
*/
|
|
181
174
|
export const advanceFocus = (selector, direction) => Effect.gen(function* () {
|
|
182
|
-
yield*
|
|
175
|
+
yield* afterRender;
|
|
183
176
|
const reference = yield* queryHTMLElement(selector);
|
|
184
177
|
const focusableElements = Array.fromIterable(document.querySelectorAll(FOCUSABLE_SELECTOR));
|
|
185
178
|
const referenceElementIndex = Array.findFirstIndex(focusableElements, Equal.equals(reference));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"elementMovement.d.ts","sourceRoot":"","sources":["../../src/task/elementMovement.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;
|
|
1
|
+
{"version":3,"file":"elementMovement.d.ts","sourceRoot":"","sources":["../../src/task/elementMovement.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAM/B;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,qBAAqB,GAAI,UAAU,MAAM,KAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAmCvE,CAAA"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Effect } from 'effect';
|
|
2
|
+
import { afterRender } from './timing.js';
|
|
2
3
|
const rectToPosition = (rect) => `${rect.x},${rect.y}`;
|
|
3
4
|
/**
|
|
4
5
|
* Detects if the element matching the given selector moves in the viewport.
|
|
@@ -18,11 +19,9 @@ const rectToPosition = (rect) => `${rect.x},${rect.y}`;
|
|
|
18
19
|
* )
|
|
19
20
|
* ```
|
|
20
21
|
*/
|
|
21
|
-
export const detectElementMovement = (selector) => Effect.
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
return;
|
|
25
|
-
}
|
|
22
|
+
export const detectElementMovement = (selector) => Effect.gen(function* () {
|
|
23
|
+
yield* afterRender;
|
|
24
|
+
return yield* Effect.callback((resume, signal) => {
|
|
26
25
|
const element = document.querySelector(selector);
|
|
27
26
|
if (!(element instanceof HTMLElement)) {
|
|
28
27
|
return resume(Effect.void);
|
package/dist/task/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ export { getTime, getTimeZone, getZonedTime, getZonedTimeIn } from './time.js';
|
|
|
3
3
|
export { advanceFocus, focus, showModal, closeModal, clickElement, scrollIntoView, } from './dom.js';
|
|
4
4
|
export type { FocusDirection } from './dom.js';
|
|
5
5
|
export { detectElementMovement } from './elementMovement.js';
|
|
6
|
-
export { delay, nextFrame, waitForAnimationSettled } from './timing.js';
|
|
6
|
+
export { afterRender, delay, nextFrame, waitForAnimationSettled, } from './timing.js';
|
|
7
7
|
export { randomInt, uuid } from './random.js';
|
|
8
8
|
export { lockScroll, unlockScroll } from './scrollLock.js';
|
|
9
9
|
export { inertOthers, restoreInert } from './inert.js';
|
package/dist/task/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/task/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAC3D,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAC9E,OAAO,EACL,YAAY,EACZ,KAAK,EACL,SAAS,EACT,UAAU,EACV,YAAY,EACZ,cAAc,GACf,MAAM,UAAU,CAAA;AACjB,YAAY,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAC9C,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAA;AAC5D,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/task/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAC3D,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAC9E,OAAO,EACL,YAAY,EACZ,KAAK,EACL,SAAS,EACT,UAAU,EACV,YAAY,EACZ,cAAc,GACf,MAAM,UAAU,CAAA;AACjB,YAAY,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAC9C,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAA;AAC5D,OAAO,EACL,WAAW,EACX,KAAK,EACL,SAAS,EACT,uBAAuB,GACxB,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,aAAa,CAAA;AAC7C,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAC1D,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA"}
|
package/dist/task/index.js
CHANGED
|
@@ -2,7 +2,7 @@ export { ElementNotFound, TimeZoneError } from './error.js';
|
|
|
2
2
|
export { getTime, getTimeZone, getZonedTime, getZonedTimeIn } from './time.js';
|
|
3
3
|
export { advanceFocus, focus, showModal, closeModal, clickElement, scrollIntoView, } from './dom.js';
|
|
4
4
|
export { detectElementMovement } from './elementMovement.js';
|
|
5
|
-
export { delay, nextFrame, waitForAnimationSettled } from './timing.js';
|
|
5
|
+
export { afterRender, delay, nextFrame, waitForAnimationSettled, } from './timing.js';
|
|
6
6
|
export { randomInt, uuid } from './random.js';
|
|
7
7
|
export { lockScroll, unlockScroll } from './scrollLock.js';
|
|
8
8
|
export { inertOthers, restoreInert } from './inert.js';
|
package/dist/task/public.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { ElementNotFound, TimeZoneError,
|
|
1
|
+
export { ElementNotFound, TimeZoneError, afterRender, clickElement, closeModal, delay, focus, getTime, getTimeZone, getZonedTime, getZonedTimeIn, nextFrame, randomInt, scrollIntoView, showModal, uuid, waitForAnimationSettled, } from './index.js';
|
|
2
2
|
//# sourceMappingURL=public.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../src/task/public.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,aAAa,EACb,
|
|
1
|
+
{"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../src/task/public.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,aAAa,EACb,WAAW,EACX,YAAY,EACZ,UAAU,EACV,KAAK,EACL,KAAK,EACL,OAAO,EACP,WAAW,EACX,YAAY,EACZ,cAAc,EACd,SAAS,EACT,SAAS,EACT,cAAc,EACd,SAAS,EACT,IAAI,EACJ,uBAAuB,GACxB,MAAM,YAAY,CAAA"}
|
package/dist/task/public.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { ElementNotFound, TimeZoneError,
|
|
1
|
+
export { ElementNotFound, TimeZoneError, afterRender, clickElement, closeModal, delay, focus, getTime, getTimeZone, getZonedTime, getZonedTimeIn, nextFrame, randomInt, scrollIntoView, showModal, uuid, waitForAnimationSettled, } from './index.js';
|
package/dist/task/timing.d.ts
CHANGED
|
@@ -9,6 +9,29 @@ import { Duration, Effect } from 'effect';
|
|
|
9
9
|
* ```
|
|
10
10
|
*/
|
|
11
11
|
export declare const delay: (duration: Duration.Input) => Effect.Effect<void>;
|
|
12
|
+
/**
|
|
13
|
+
* Completes after the runtime's next render commits. The runtime batches
|
|
14
|
+
* renders to `requestAnimationFrame`, so a Command, Subscription, or other
|
|
15
|
+
* Effect that runs immediately after a dirtying Message would otherwise
|
|
16
|
+
* query the DOM before the matching VDOM patch has applied. Yield this
|
|
17
|
+
* before any DOM read or write whose target was just brought into existence
|
|
18
|
+
* (or moved, or had its attributes changed) by the same Message.
|
|
19
|
+
*
|
|
20
|
+
* The Task DOM helpers (`focus`, `clickElement`, `scrollIntoView`, etc.)
|
|
21
|
+
* already gate themselves with this internally; reach for `afterRender`
|
|
22
|
+
* directly when building custom Commands or DOM-observing Subscriptions
|
|
23
|
+
* that need the same guarantee.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```typescript
|
|
27
|
+
* Effect.gen(function* () {
|
|
28
|
+
* yield* Task.afterRender
|
|
29
|
+
* const element = document.getElementById(id)
|
|
30
|
+
* // element reflects the post-Message DOM
|
|
31
|
+
* })
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export declare const afterRender: Effect.Effect<void>;
|
|
12
35
|
/**
|
|
13
36
|
* Completes after two animation frames, ensuring the browser has painted
|
|
14
37
|
* the current state before proceeding. Used for CSS transition orchestration —
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"timing.d.ts","sourceRoot":"","sources":["../../src/task/timing.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAEzC;;;;;;;;GAQG;AACH,eAAO,MAAM,KAAK,GAAI,UAAU,QAAQ,CAAC,KAAK,KAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAC3C,CAAA;AAExB;;;;;;;;;;GAUG;AACH,eAAO,MAAM,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAMxC,CAAA;AAEF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,uBAAuB,GAClC,UAAU,MAAM,KACf,MAAM,CAAC,MAAM,CAAC,IAAI,CAYjB,CAAA"}
|
|
1
|
+
{"version":3,"file":"timing.d.ts","sourceRoot":"","sources":["../../src/task/timing.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAEzC;;;;;;;;GAQG;AACH,eAAO,MAAM,KAAK,GAAI,UAAU,QAAQ,CAAC,KAAK,KAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAC3C,CAAA;AAExB;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAK3C,CAAA;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAMxC,CAAA;AAEF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,uBAAuB,GAClC,UAAU,MAAM,KACf,MAAM,CAAC,MAAM,CAAC,IAAI,CAYjB,CAAA"}
|
package/dist/task/timing.js
CHANGED
|
@@ -9,6 +9,32 @@ import { Effect } from 'effect';
|
|
|
9
9
|
* ```
|
|
10
10
|
*/
|
|
11
11
|
export const delay = (duration) => Effect.sleep(duration);
|
|
12
|
+
/**
|
|
13
|
+
* Completes after the runtime's next render commits. The runtime batches
|
|
14
|
+
* renders to `requestAnimationFrame`, so a Command, Subscription, or other
|
|
15
|
+
* Effect that runs immediately after a dirtying Message would otherwise
|
|
16
|
+
* query the DOM before the matching VDOM patch has applied. Yield this
|
|
17
|
+
* before any DOM read or write whose target was just brought into existence
|
|
18
|
+
* (or moved, or had its attributes changed) by the same Message.
|
|
19
|
+
*
|
|
20
|
+
* The Task DOM helpers (`focus`, `clickElement`, `scrollIntoView`, etc.)
|
|
21
|
+
* already gate themselves with this internally; reach for `afterRender`
|
|
22
|
+
* directly when building custom Commands or DOM-observing Subscriptions
|
|
23
|
+
* that need the same guarantee.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```typescript
|
|
27
|
+
* Effect.gen(function* () {
|
|
28
|
+
* yield* Task.afterRender
|
|
29
|
+
* const element = document.getElementById(id)
|
|
30
|
+
* // element reflects the post-Message DOM
|
|
31
|
+
* })
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export const afterRender = Effect.callback(resume => {
|
|
35
|
+
const handle = requestAnimationFrame(() => resume(Effect.void));
|
|
36
|
+
return Effect.sync(() => cancelAnimationFrame(handle));
|
|
37
|
+
});
|
|
12
38
|
/**
|
|
13
39
|
* Completes after two animation frames, ensuring the browser has painted
|
|
14
40
|
* the current state before proceeding. Used for CSS transition orchestration —
|