foldkit 0.153.0 → 0.154.0-canary.4e7d8d4010be
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/html/index.d.ts +81 -10
- package/dist/html/index.d.ts.map +1 -1
- package/dist/html/index.js +50 -40
- package/dist/html/public.d.ts +1 -1
- package/dist/html/public.d.ts.map +1 -1
- package/dist/html/public.js +1 -1
- package/dist/mount/index.d.ts +167 -114
- package/dist/mount/index.d.ts.map +1 -1
- package/dist/mount/index.js +47 -63
- package/dist/test/apps/bubbling.d.ts +10 -0
- package/dist/test/apps/bubbling.d.ts.map +1 -1
- package/dist/test/apps/bubbling.js +52 -1
- package/dist/test/apps/focusBoundary.d.ts +26 -0
- package/dist/test/apps/focusBoundary.d.ts.map +1 -0
- package/dist/test/apps/focusBoundary.js +37 -0
- package/dist/test/apps/mountPanel.d.ts.map +1 -1
- package/dist/test/apps/mountPanel.js +24 -13
- package/dist/test/scene.d.ts +10 -6
- package/dist/test/scene.d.ts.map +1 -1
- package/dist/test/scene.js +167 -57
- package/dist/update/public.d.ts +1 -1
- package/dist/update/public.d.ts.map +1 -1
- package/dist/update/update.d.ts +73 -40
- package/dist/update/update.d.ts.map +1 -1
- package/dist/update/update.js +26 -22
- package/package.json +1 -1
package/dist/html/index.js
CHANGED
|
@@ -59,6 +59,24 @@ const keyboardModifiers = (event) => ({
|
|
|
59
59
|
altKey: event.altKey,
|
|
60
60
|
metaKey: event.metaKey,
|
|
61
61
|
});
|
|
62
|
+
const isDevToolsFocusTarget = (target) => target instanceof Element && target.id === DEVTOOLS_HOST_ID;
|
|
63
|
+
const isFocusInsideCurrentTarget = (event) => event.currentTarget instanceof Element &&
|
|
64
|
+
event.relatedTarget instanceof Node &&
|
|
65
|
+
event.currentTarget.contains(event.relatedTarget);
|
|
66
|
+
/** Whether an event handler leaves the browser's default action in place or
|
|
67
|
+
* prevents it synchronously. */
|
|
68
|
+
export const DefaultAction = S.Literals(['Allow', 'Prevent']);
|
|
69
|
+
/** Whether an event continues through its DOM propagation path or stops after
|
|
70
|
+
* the handlers on its current element have run. */
|
|
71
|
+
export const EventPropagation = S.Literals(['Bubble', 'Stop']);
|
|
72
|
+
/** Declarative controls for an `OnClick` handler. Omitted
|
|
73
|
+
* fields keep the browser default, allow the click to bubble, and leave focus
|
|
74
|
+
* unchanged. */
|
|
75
|
+
export const ClickOptions = S.Struct({
|
|
76
|
+
defaultAction: S.optional(DefaultAction),
|
|
77
|
+
propagation: S.optional(EventPropagation),
|
|
78
|
+
focusSelector: S.optional(S.String),
|
|
79
|
+
});
|
|
62
80
|
/** Text direction for the document root, applied to `dir` on the `<html>`
|
|
63
81
|
* element. `Auto` defers to the browser's first-strong-character heuristic. */
|
|
64
82
|
export const TextDirection = S.Literals(['Ltr', 'Rtl', 'Auto']);
|
|
@@ -99,7 +117,7 @@ export const __endReplayRender = () => {
|
|
|
99
117
|
* rendering them to the DOM, so the marker is invisible at runtime but
|
|
100
118
|
* observable by VNode walkers (Scene tests). */
|
|
101
119
|
export const FOLDKIT_MOUNT_KEY = 'foldkitMount';
|
|
102
|
-
const { Key, Class, Id, Title, Lang, Dir, Tabindex, Hidden, Contenteditable, Draggable, Accesskey, Translate, Inert, Popover, Popovertarget, Popovertargetaction, OnClick,
|
|
120
|
+
const { Key, Class, Id, Title, Lang, Dir, Tabindex, Hidden, Contenteditable, Draggable, Accesskey, Translate, Inert, Popover, Popovertarget, Popovertargetaction, OnClick, OnDoubleClick, OnMouseDown, OnMouseUp, OnMouseEnter, OnMouseLeave, OnMouseOver, OnMouseOut, OnMouseMove, OnPointerMove, OnPointerLeave, OnPointerDown, OnPointerUp, OnKeyDown, OnKeyDownPreventDefault, OnKeyDownFocus, OnKeyUp, OnKeyUpPreventDefault, OnKeyPress, OnFocus, OnBlur, OnFocusEnter, OnFocusLeave, OnInput, OnChange, OnFileChange, OnSubmit, OnReset, OnScroll, OnWheel, OnCopy, OnCut, OnPaste, OnPastePreventDefault, OnCopyText, OnCutText, OnCancel, OnToggle, OnContextMenu, OnDragStart, OnDrag, OnDragEnd, OnDragEnter, OnDragLeave, OnDragOver, AllowDrop, OnDrop, OnDropFiles, OnTouchStart, OnTouchEnd, OnTouchMove, OnTouchCancel, OnAnimationStart, OnAnimationEnd, OnAnimationIteration, OnTransitionEnd, OnLoad, OnError, OnPlay, OnPause, OnEnded, OnTimeUpdate, OnVolumeChange, OnSelect, Value, Checked, Selected, Open, Placeholder, Name, Disabled, Readonly, Required, Autofocus, Spellcheck, Autocorrect, Autocapitalize, InputMode, EnterKeyHint, Multiple, Type, Accept, Autocomplete, Pattern, Maxlength, Minlength, Size, Cols, Rows, Max, Min, Step, For, Href, Src, Alt, Target, Rel, Download, Action, Method, Enctype, Novalidate, Formaction, Formmethod, Formnovalidate, Formtarget, Formenctype, Colspan, Rowspan, Scope, Headers, Span, Start, Reversed, CiteAttr, Datetime, Wrap, List, FormAttr, LabelAttr, ContentAttr, Charset, HttpEquiv, Srcset, Sizes, Loading, Decoding, Fetchpriority, Crossorigin, Referrerpolicy, Integrity, Hreflang, Ping, Sandbox, Allow, Srcdoc, Autoplay, Controls, Loop, Muted, Poster, Preload, Playsinline, High, Low, Optimum, Usemap, Ismap, Role, AriaLabel, AriaLabelledBy, AriaDescribedBy, AriaHidden, AriaExpanded, AriaSelected, AriaChecked, AriaDisabled, AriaRequired, AriaInvalid, AriaLive, AriaControls, AriaCurrent, AriaOrientation, AriaPressed, AriaHasPopup, AriaActiveDescendant, AriaSort, AriaMultiSelectable, AriaModal, AriaBusy, AriaErrorMessage, AriaRoleDescription, AriaAtomic, AriaAutocomplete, AriaColcount, AriaColindex, AriaColspan, AriaDescription, AriaDetails, AriaFlowto, AriaKeyshortcuts, AriaLevel, AriaOwns, AriaPlaceholder, AriaPosinset, AriaReadonly, AriaRelevant, AriaRowcount, AriaRowindex, AriaRowspan, AriaSetsize, AriaValuemax, AriaValuemin, AriaValuenow, AriaValuetext, Attribute, DataAttribute, Style, InnerHTML, ViewBox, Xmlns, Fill, FillRule, ClipRule, Stroke, StrokeWidth, StrokeLinecap, StrokeLinejoin, D, Cx, Cy, R, X, Y, Width, Height, X1, Y1, X2, Y2, Points, Transform, Opacity, StrokeDasharray, StrokeDashoffset, Dx, Dy, Rotate, TextAnchor, DominantBaseline, AlignmentBaseline, BaselineShift, TextLength, LengthAdjust, FontFamily, FontSize, FontWeight, FontStyle, LetterSpacing, WordSpacing, TextDecoration, WritingMode, Rx, Ry, PathLength, FillOpacity, StrokeOpacity, StrokeMiterlimit, PaintOrder, VectorEffect, Color, Visibility, Display, Overflow, PointerEvents, Cursor, ShapeRendering, TextRendering, ImageRendering, ClipPath, Mask, Filter, ClipPathUnits, MaskUnits, MaskContentUnits, FilterUnits, PrimitiveUnits, Offset, StopColor, StopOpacity, GradientUnits, GradientTransform, SpreadMethod, Fx, Fy, Fr, PatternUnits, PatternContentUnits, PatternTransform, MarkerStart, MarkerMid, MarkerEnd, MarkerWidth, MarkerHeight, MarkerUnits, RefX, RefY, Orient, PreserveAspectRatio, Prop, OnCustomEvent, OnMount, OnUnmount, } = Data.taggedEnum();
|
|
103
121
|
export { Prop, OnCustomEvent };
|
|
104
122
|
const setData = (ctx, key, value) => {
|
|
105
123
|
ctx.data[key] = value;
|
|
@@ -342,15 +360,21 @@ const attributeHandlers = {
|
|
|
342
360
|
Popover: ({ value }, ctx) => setDataAttr(ctx, 'popover', value),
|
|
343
361
|
Popovertarget: ({ value }, ctx) => setDataAttr(ctx, 'popovertarget', value),
|
|
344
362
|
Popovertargetaction: ({ value }, ctx) => setDataAttr(ctx, 'popovertargetaction', value),
|
|
345
|
-
OnClick: ({ message }, ctx) => addDataOn(ctx, 'click', () =>
|
|
346
|
-
|
|
347
|
-
|
|
363
|
+
OnClick: ({ message, options }, ctx) => addDataOn(ctx, 'click', (event) => {
|
|
364
|
+
if (options?.defaultAction === 'Prevent') {
|
|
365
|
+
event.preventDefault();
|
|
366
|
+
}
|
|
367
|
+
if (options?.propagation === 'Stop') {
|
|
368
|
+
event.stopPropagation();
|
|
369
|
+
}
|
|
370
|
+
const focusSelector = options?.focusSelector;
|
|
371
|
+
if (focusSelector !== undefined) {
|
|
348
372
|
const focusTarget = document.querySelector(focusSelector);
|
|
349
373
|
if (focusTarget instanceof HTMLElement) {
|
|
350
374
|
focusTarget.focus();
|
|
351
375
|
}
|
|
352
|
-
|
|
353
|
-
|
|
376
|
+
}
|
|
377
|
+
ctx.dispatch(message);
|
|
354
378
|
}),
|
|
355
379
|
OnDoubleClick: ({ message }, ctx) => addDataOn(ctx, 'dblclick', () => ctx.dispatch(message)),
|
|
356
380
|
OnMouseDown: ({ message }, ctx) => addDataOn(ctx, 'mousedown', () => ctx.dispatch(message)),
|
|
@@ -436,13 +460,26 @@ const attributeHandlers = {
|
|
|
436
460
|
OnFocus: ({ message }, ctx) => addDataOn(ctx, 'focus', () => ctx.dispatch(message)),
|
|
437
461
|
OnBlur: ({ message }, ctx) => updateDataOn(ctx, {
|
|
438
462
|
blur: (event) => {
|
|
439
|
-
if (event.relatedTarget
|
|
440
|
-
event.relatedTarget.id === DEVTOOLS_HOST_ID) {
|
|
463
|
+
if (isDevToolsFocusTarget(event.relatedTarget)) {
|
|
441
464
|
return;
|
|
442
465
|
}
|
|
443
466
|
ctx.dispatch(message);
|
|
444
467
|
},
|
|
445
468
|
}),
|
|
469
|
+
OnFocusEnter: ({ message }, ctx) => updateDataOn(ctx, {
|
|
470
|
+
focusin: (event) => {
|
|
471
|
+
if (!isFocusInsideCurrentTarget(event)) {
|
|
472
|
+
ctx.dispatch(message);
|
|
473
|
+
}
|
|
474
|
+
},
|
|
475
|
+
}),
|
|
476
|
+
OnFocusLeave: ({ message }, ctx) => updateDataOn(ctx, {
|
|
477
|
+
focusout: (event) => {
|
|
478
|
+
if (!isFocusInsideCurrentTarget(event)) {
|
|
479
|
+
ctx.dispatch(message);
|
|
480
|
+
}
|
|
481
|
+
},
|
|
482
|
+
}),
|
|
446
483
|
OnInput: ({ f: toMessage }, ctx) => updateDataOn(ctx, {
|
|
447
484
|
input: (event) =>
|
|
448
485
|
/* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */
|
|
@@ -1611,38 +1648,9 @@ const htmlAttributes = () => ({
|
|
|
1611
1648
|
Popover: (value) => Popover({ value }),
|
|
1612
1649
|
Popovertarget: (value) => Popovertarget({ value }),
|
|
1613
1650
|
Popovertargetaction: (value) => Popovertargetaction({ value }),
|
|
1614
|
-
OnClick: (message) =>
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
* `focusSelector`, then dispatches `message`. Both run inside the originating
|
|
1618
|
-
* click event handler, preserving the user-gesture context.
|
|
1619
|
-
*
|
|
1620
|
-
* Use this when tapping the element must open the on-screen keyboard on
|
|
1621
|
-
* iOS Safari. Safari only opens the keyboard if `.focus()` runs synchronously
|
|
1622
|
-
* inside the originating user-gesture handler, which a Command's `Dom.focus`
|
|
1623
|
-
* cannot satisfy (Commands fork through `Effect.forkDetach` +
|
|
1624
|
-
* `requestAnimationFrame` and resolve after the gesture has expired).
|
|
1625
|
-
*
|
|
1626
|
-
* When the real input only mounts later (a search field inside a dialog,
|
|
1627
|
-
* say), focus it in two steps. First, keep a focusable text input that is
|
|
1628
|
-
* always in the DOM (a visually hidden "keyboard warmup") and point
|
|
1629
|
-
* `focusSelector` at it, so the tap focuses the input (which opens the
|
|
1630
|
-
* keyboard) and dispatches a Message. Second, update's branch for that
|
|
1631
|
-
* Message opens the dialog and returns a `Dom.focus` Command pointed at the
|
|
1632
|
-
* real input; by the time it runs the input has mounted, so focus moves to
|
|
1633
|
-
* it. iOS keeps the keyboard up when focus moves between two text inputs,
|
|
1634
|
-
* so it stays open and now targets the real input.
|
|
1635
|
-
*
|
|
1636
|
-
* Like `OnKeyDownPreventDefault`, the side effect (focusing another
|
|
1637
|
-
* element) lives inside the framework's event handler so user code stays
|
|
1638
|
-
* declarative.
|
|
1639
|
-
*
|
|
1640
|
-
* @example
|
|
1641
|
-
* ```typescript
|
|
1642
|
-
* h.OnClickFocus('#search-keyboard-warmup', ClickedSearch())
|
|
1643
|
-
* ```
|
|
1644
|
-
*/
|
|
1645
|
-
OnClickFocus: (focusSelector, message) => OnClickFocus({ focusSelector, message }),
|
|
1651
|
+
OnClick: (message, options) => options === undefined
|
|
1652
|
+
? OnClick({ message })
|
|
1653
|
+
: OnClick({ message, options }),
|
|
1646
1654
|
OnDoubleClick: (message) => OnDoubleClick({ message }),
|
|
1647
1655
|
OnMouseDown: (message) => OnMouseDown({ message }),
|
|
1648
1656
|
OnMouseUp: (message) => OnMouseUp({ message }),
|
|
@@ -1685,6 +1693,8 @@ const htmlAttributes = () => ({
|
|
|
1685
1693
|
OnKeyPress: (toMessage) => OnKeyPress({ f: toMessage }),
|
|
1686
1694
|
OnFocus: (message) => OnFocus({ message }),
|
|
1687
1695
|
OnBlur: (message) => OnBlur({ message }),
|
|
1696
|
+
OnFocusEnter: (message) => OnFocusEnter({ message }),
|
|
1697
|
+
OnFocusLeave: (message) => OnFocusLeave({ message }),
|
|
1688
1698
|
OnInput: (toMessage) => OnInput({ f: toMessage }),
|
|
1689
1699
|
OnChange: (toMessage) => OnChange({ f: toMessage }),
|
|
1690
1700
|
OnFileChange: (toMessage) => OnFileChange({ f: toMessage }),
|
package/dist/html/public.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { childAttributes, createKeyedLazy, createLazy, inertHtml, TextDirection, } from './index.js';
|
|
1
|
+
export { childAttributes, ClickOptions, createKeyedLazy, createLazy, DefaultAction, EventPropagation, inertHtml, TextDirection, } from './index.js';
|
|
2
2
|
export type { Attribute, ChildAttribute, Document, Html, HtmlBuilder, KeyboardModifiers, TagName, } from './index.js';
|
|
3
3
|
//# sourceMappingURL=public.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../src/html/public.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,eAAe,EACf,UAAU,EACV,SAAS,EACT,aAAa,GACd,MAAM,YAAY,CAAA;AAEnB,YAAY,EACV,SAAS,EACT,cAAc,EACd,QAAQ,EACR,IAAI,EACJ,WAAW,EACX,iBAAiB,EACjB,OAAO,GACR,MAAM,YAAY,CAAA"}
|
|
1
|
+
{"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../src/html/public.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,YAAY,EACZ,eAAe,EACf,UAAU,EACV,aAAa,EACb,gBAAgB,EAChB,SAAS,EACT,aAAa,GACd,MAAM,YAAY,CAAA;AAEnB,YAAY,EACV,SAAS,EACT,cAAc,EACd,QAAQ,EACR,IAAI,EACJ,WAAW,EACX,iBAAiB,EACjB,OAAO,GACR,MAAM,YAAY,CAAA"}
|
package/dist/html/public.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { childAttributes, createKeyedLazy, createLazy, inertHtml, TextDirection, } from './index.js';
|
|
1
|
+
export { childAttributes, ClickOptions, createKeyedLazy, createLazy, DefaultAction, EventPropagation, inertHtml, TextDirection, } from './index.js';
|
package/dist/mount/index.d.ts
CHANGED
|
@@ -22,8 +22,8 @@ export type MountDefinitionTypeId = typeof MountDefinitionTypeId;
|
|
|
22
22
|
* the element unmounts, the runtime interrupts the fiber, which closes the
|
|
23
23
|
* Stream's scope and runs any registered `acquireRelease` finalizers.
|
|
24
24
|
*
|
|
25
|
-
* Authors
|
|
26
|
-
* `
|
|
25
|
+
* Authors don't construct this shape directly. `Mount.define` builds it from
|
|
26
|
+
* an `execute` returning `Effect<Message>` for the one-shot case; only
|
|
27
27
|
* `Mount.defineStream` exposes the raw Stream shape for continuous-event
|
|
28
28
|
* cases. */
|
|
29
29
|
export type MountAction<Message, E = never> = Readonly<{
|
|
@@ -54,16 +54,34 @@ export interface MountDefinitionWithArgs<Name extends string, Fields extends Sch
|
|
|
54
54
|
* Union over the no-args and with-args shapes; consumers that only need
|
|
55
55
|
* name/identity can accept this. */
|
|
56
56
|
export type MountDefinition<Name extends string = string, ResultMessage = any> = MountDefinitionNoArgs<Name, ResultMessage> | MountDefinitionWithArgs<Name, any, ResultMessage>;
|
|
57
|
+
/** @internal Rejects an args field named `element`. `execute` receives the live
|
|
58
|
+
* element under that name, so an arg of the same name would shadow it. The
|
|
59
|
+
* literal is the type error a colliding declaration produces. */
|
|
60
|
+
type ElementFieldIsReserved = 'Mount args cannot declare `element`: execute already receives the live element';
|
|
57
61
|
/**
|
|
58
|
-
* Defines a one-shot Mount.
|
|
59
|
-
*
|
|
60
|
-
*
|
|
62
|
+
* Defines a one-shot Mount. Every input is a named field: `args` declares the
|
|
63
|
+
* args Schema, `messages` lists the Messages this Mount can produce, and
|
|
64
|
+
* `execute` holds the work. `execute` receives the live `Element` as `element`
|
|
65
|
+
* alongside the declared args, and returns an `Effect<Message>` that runs once
|
|
66
|
+
* when the element mounts and produces exactly one Message.
|
|
67
|
+
*
|
|
68
|
+
* `args` is optional. Omit it and the Definition is callable as `Definition()`;
|
|
69
|
+
* declare it and the Definition is callable as `Definition(args)`. `execute`
|
|
70
|
+
* keeps the same shape either way, because a Mount always has an element. An
|
|
71
|
+
* args field named `element` is rejected where you declare it, since it would
|
|
72
|
+
* collide with the element `execute` receives.
|
|
73
|
+
*
|
|
74
|
+
* Constructing a MountAction never runs `execute`. The runtime calls it when
|
|
75
|
+
* the element enters the DOM, so nothing the body does happens inside the pure
|
|
76
|
+
* view that built the action.
|
|
77
|
+
*
|
|
78
|
+
* Cleanup composes via `Effect.acquireRelease` inside the Effect: registered
|
|
61
79
|
* finalizers run when the element unmounts. The Mount's scope stays open
|
|
62
80
|
* across the element's full lifetime, even after the Effect completes.
|
|
63
81
|
*
|
|
64
82
|
* At least one result Message schema is required. The Effect's success
|
|
65
|
-
* type is `Schema.Schema.Type<
|
|
66
|
-
* result,
|
|
83
|
+
* type is `Schema.Schema.Type<Messages[number]>`; without a declared
|
|
84
|
+
* result, `execute` would have to return `Effect.never`, leaving
|
|
67
85
|
* `update` with no record of the work and removing DevTools, Scene,
|
|
68
86
|
* and time-travel replay's reference point. Fire-and-forget Mounts
|
|
69
87
|
* follow the same convention as fire-and-forget Commands: declare a
|
|
@@ -71,15 +89,14 @@ export type MountDefinition<Name extends string = string, ResultMessage = any> =
|
|
|
71
89
|
* effect stays observable; `update` simply has nothing meaningful to
|
|
72
90
|
* do with the acknowledgment.
|
|
73
91
|
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
* `
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
* and using `release` only for self-contained teardown.
|
|
92
|
+
* Cleanup is asynchronous with respect to snabbdom's `destroy` hook: the
|
|
93
|
+
* runtime forks `Fiber.interrupt` and returns immediately, so finalizers run
|
|
94
|
+
* on a separate fiber after `destroy` has already completed. For idempotent
|
|
95
|
+
* DOM operations (`element.remove()`, observer `disconnect()`,
|
|
96
|
+
* `removeEventListener`) this is fine; if your cleanup has ordering
|
|
97
|
+
* requirements relative to other DOM removals, prefer doing the imperative
|
|
98
|
+
* work synchronously inside `acquire` and using `release` only for
|
|
99
|
+
* self-contained teardown.
|
|
83
100
|
*
|
|
84
101
|
* **Construct resources INSIDE the acquire body, never before it.**
|
|
85
102
|
* `Effect.acquireRelease` only guarantees atomicity of "acquire body
|
|
@@ -100,20 +117,20 @@ export type MountDefinition<Name extends string = string, ResultMessage = any> =
|
|
|
100
117
|
*
|
|
101
118
|
* @example One-shot, no cleanup (read element geometry on mount)
|
|
102
119
|
* ```ts
|
|
103
|
-
* const MeasurePanelWidth = Mount.define(
|
|
104
|
-
*
|
|
105
|
-
*
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
*
|
|
109
|
-
*
|
|
110
|
-
* )
|
|
120
|
+
* const MeasurePanelWidth = Mount.define('MeasurePanelWidth', {
|
|
121
|
+
* messages: [MeasuredPanelWidth],
|
|
122
|
+
* execute: ({ element }) =>
|
|
123
|
+
* Effect.sync(() =>
|
|
124
|
+
* MeasuredPanelWidth({ width: element.getBoundingClientRect().width }),
|
|
125
|
+
* ),
|
|
126
|
+
* })
|
|
111
127
|
* ```
|
|
112
128
|
*
|
|
113
129
|
* @example One-shot with cleanup (portal-to-body)
|
|
114
130
|
* ```ts
|
|
115
|
-
* const PortalToBody = Mount.define('PortalToBody',
|
|
116
|
-
*
|
|
131
|
+
* const PortalToBody = Mount.define('PortalToBody', {
|
|
132
|
+
* messages: [CompletedPortalToBody],
|
|
133
|
+
* execute: ({ element }) =>
|
|
117
134
|
* Effect.gen(function* () {
|
|
118
135
|
* yield* Effect.acquireRelease(
|
|
119
136
|
* Effect.sync(() => document.body.appendChild(element)),
|
|
@@ -121,27 +138,26 @@ export type MountDefinition<Name extends string = string, ResultMessage = any> =
|
|
|
121
138
|
* )
|
|
122
139
|
* return CompletedPortalToBody()
|
|
123
140
|
* }),
|
|
124
|
-
* )
|
|
141
|
+
* })
|
|
125
142
|
* ```
|
|
126
143
|
*
|
|
127
144
|
* @example With args
|
|
128
145
|
* ```ts
|
|
129
|
-
* const AnchorPopover = Mount.define(
|
|
130
|
-
*
|
|
131
|
-
*
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
*
|
|
135
|
-
*
|
|
136
|
-
*
|
|
137
|
-
*
|
|
138
|
-
*
|
|
139
|
-
*
|
|
140
|
-
*
|
|
141
|
-
* )
|
|
146
|
+
* const AnchorPopover = Mount.define('AnchorPopover', {
|
|
147
|
+
* args: { buttonId: S.String, anchor: AnchorConfig },
|
|
148
|
+
* messages: [CompletedAnchorPopover],
|
|
149
|
+
* execute: ({ element, buttonId, anchor }) =>
|
|
150
|
+
* Effect.gen(function* () {
|
|
151
|
+
* yield* Effect.acquireRelease(
|
|
152
|
+
* Effect.sync(() => anchorSetup(element, { buttonId, anchor })),
|
|
153
|
+
* cleanup => Effect.sync(cleanup),
|
|
154
|
+
* )
|
|
155
|
+
* return CompletedAnchorPopover()
|
|
156
|
+
* }),
|
|
157
|
+
* })
|
|
142
158
|
* ```
|
|
143
159
|
*
|
|
144
|
-
* **Args are captured at mount, not refreshed across renders.**
|
|
160
|
+
* **Args are captured at mount, not refreshed across renders.** `execute`
|
|
145
161
|
* runs once when the element enters the DOM. Subsequent renders construct
|
|
146
162
|
* fresh `MountAction` values with updated arg values, but those values are
|
|
147
163
|
* captured in closures that never execute. `OnMount` only binds to
|
|
@@ -164,19 +180,46 @@ export type MountDefinition<Name extends string = string, ResultMessage = any> =
|
|
|
164
180
|
* applying `user-select: none` to the document while a drag is in progress
|
|
165
181
|
* and undoing it when the drag ends).)
|
|
166
182
|
*/
|
|
167
|
-
export declare function define<const Name extends string,
|
|
168
|
-
|
|
183
|
+
export declare function define<const Name extends string, Fields extends Schema.Struct.Fields, const Messages extends readonly [Schema.Top, ...ReadonlyArray<Schema.Top>]>(name: Name, config: Readonly<{
|
|
184
|
+
args: Fields & Readonly<{
|
|
185
|
+
element?: ElementFieldIsReserved;
|
|
186
|
+
}>;
|
|
187
|
+
messages: Messages;
|
|
188
|
+
execute: (input: Readonly<{
|
|
189
|
+
element: Element;
|
|
190
|
+
}> & Schema.Schema.Type<Schema.Struct<Fields>>) => Effect.Effect<Schema.Schema.Type<Messages[number]>, never, Scope.Scope>;
|
|
191
|
+
}>): MountDefinitionWithArgs<Name, Fields, Schema.Schema.Type<Messages[number]>>;
|
|
192
|
+
export declare function define<const Name extends string, const Messages extends readonly [Schema.Top, ...ReadonlyArray<Schema.Top>]>(name: Name, config: Readonly<{
|
|
193
|
+
args?: never;
|
|
194
|
+
messages: Messages;
|
|
195
|
+
execute: (input: Readonly<{
|
|
196
|
+
element: Element;
|
|
197
|
+
}>) => Effect.Effect<Schema.Schema.Type<Messages[number]>, never, Scope.Scope>;
|
|
198
|
+
}>): MountDefinitionNoArgs<Name, Schema.Schema.Type<Messages[number]>>;
|
|
169
199
|
/**
|
|
170
|
-
* Defines a streaming Mount.
|
|
171
|
-
*
|
|
172
|
-
*
|
|
173
|
-
* `
|
|
174
|
-
*
|
|
175
|
-
*
|
|
200
|
+
* Defines a streaming Mount. Every input is a named field, exactly as in
|
|
201
|
+
* `Mount.define`: `args` declares the args Schema, `messages` lists the
|
|
202
|
+
* Messages this Mount can produce, and `execute` holds the work. `execute`
|
|
203
|
+
* receives the live `Element` as `element` alongside the declared args, and
|
|
204
|
+
* returns a `Stream<Message>` whose lifetime is bound to the element's
|
|
205
|
+
* lifetime: each emitted Message is dispatched, and the Stream's scope is
|
|
206
|
+
* closed (running any registered `Effect.acquireRelease` finalizers) when the
|
|
207
|
+
* element unmounts. Use this form when the Mount emits a continuum of events
|
|
208
|
+
* from observers or listeners attached to the element.
|
|
209
|
+
*
|
|
210
|
+
* `args` is optional. Omit it and the Definition is callable as `Definition()`;
|
|
211
|
+
* declare it and the Definition is callable as `Definition(args)`. `execute`
|
|
212
|
+
* keeps the same shape either way, because a Mount always has an element. An
|
|
213
|
+
* args field named `element` is rejected where you declare it, since it would
|
|
214
|
+
* collide with the element `execute` receives.
|
|
215
|
+
*
|
|
216
|
+
* Constructing a MountAction never runs `execute`. The runtime calls it when
|
|
217
|
+
* the element enters the DOM, so nothing the body does happens inside the pure
|
|
218
|
+
* view that built the action.
|
|
176
219
|
*
|
|
177
220
|
* At least one result Message schema is required. The Stream's emission
|
|
178
|
-
* type is `Schema.Schema.Type<
|
|
179
|
-
* result,
|
|
221
|
+
* type is `Schema.Schema.Type<Messages[number]>`; without a declared
|
|
222
|
+
* result, `execute` would have to return `Stream<never>`, leaving
|
|
180
223
|
* `update` with no record of the work and removing DevTools, Scene,
|
|
181
224
|
* and time-travel replay's reference point. Fire-and-forget Mounts
|
|
182
225
|
* follow the same convention as fire-and-forget Commands: declare a
|
|
@@ -184,10 +227,8 @@ export declare function define<const Name extends string, Fields extends Schema.
|
|
|
184
227
|
* effect stays observable; `update` simply has nothing meaningful to
|
|
185
228
|
* do with the acknowledgment. Re-check the cause.
|
|
186
229
|
*
|
|
187
|
-
*
|
|
188
|
-
*
|
|
189
|
-
* snabbdom's `destroy` hook is the same as `Mount.define` (asynchronous via
|
|
190
|
-
* `Fiber.interrupt`).
|
|
230
|
+
* Cleanup timing relative to snabbdom's `destroy` hook is the same as
|
|
231
|
+
* `Mount.define` (asynchronous via `Fiber.interrupt`).
|
|
191
232
|
*
|
|
192
233
|
* For a Mount that produces exactly one Message at acquire and then holds
|
|
193
234
|
* lifecycle-scoped resources, use `Mount.define` with `Effect<Message>`.
|
|
@@ -196,75 +237,87 @@ export declare function define<const Name extends string, Fields extends Schema.
|
|
|
196
237
|
*
|
|
197
238
|
* @example Continuous scroll events from an element
|
|
198
239
|
* ```ts
|
|
199
|
-
* const SyncSidebarScroll = Mount.defineStream(
|
|
200
|
-
*
|
|
201
|
-
*
|
|
202
|
-
*
|
|
203
|
-
*
|
|
204
|
-
*
|
|
205
|
-
*
|
|
206
|
-
*
|
|
207
|
-
*
|
|
208
|
-
*
|
|
209
|
-
*
|
|
210
|
-
*
|
|
211
|
-
* )
|
|
212
|
-
*
|
|
213
|
-
*
|
|
214
|
-
*
|
|
215
|
-
*
|
|
216
|
-
*
|
|
217
|
-
*
|
|
218
|
-
*
|
|
219
|
-
*
|
|
220
|
-
*
|
|
221
|
-
*
|
|
222
|
-
*
|
|
223
|
-
* )
|
|
240
|
+
* const SyncSidebarScroll = Mount.defineStream('SyncSidebarScroll', {
|
|
241
|
+
* messages: [ScrolledSidebar],
|
|
242
|
+
* execute: ({ element }) =>
|
|
243
|
+
* Stream.callback<typeof ScrolledSidebar.Type>(queue =>
|
|
244
|
+
* Effect.gen(function* () {
|
|
245
|
+
* yield* Effect.acquireRelease(
|
|
246
|
+
* Effect.sync(() => {
|
|
247
|
+
* const handler = () =>
|
|
248
|
+
* Queue.offerUnsafe(
|
|
249
|
+
* queue,
|
|
250
|
+
* ScrolledSidebar({ scroll: element.scrollTop }),
|
|
251
|
+
* )
|
|
252
|
+
* element.addEventListener('scroll', handler, { passive: true })
|
|
253
|
+
* return handler
|
|
254
|
+
* }),
|
|
255
|
+
* handler =>
|
|
256
|
+
* Effect.sync(() =>
|
|
257
|
+
* element.removeEventListener('scroll', handler),
|
|
258
|
+
* ),
|
|
259
|
+
* )
|
|
260
|
+
* return yield* Effect.never
|
|
261
|
+
* }),
|
|
262
|
+
* ),
|
|
263
|
+
* })
|
|
224
264
|
* ```
|
|
225
265
|
*
|
|
226
266
|
* @example IntersectionObserver events
|
|
227
267
|
* ```ts
|
|
228
|
-
* const ObserveHeroVisibility = Mount.defineStream(
|
|
229
|
-
*
|
|
230
|
-
*
|
|
231
|
-
*
|
|
232
|
-
*
|
|
233
|
-
*
|
|
234
|
-
*
|
|
235
|
-
*
|
|
236
|
-
*
|
|
237
|
-
*
|
|
238
|
-
*
|
|
239
|
-
*
|
|
240
|
-
*
|
|
241
|
-
*
|
|
242
|
-
*
|
|
243
|
-
*
|
|
244
|
-
*
|
|
245
|
-
*
|
|
246
|
-
*
|
|
247
|
-
*
|
|
248
|
-
*
|
|
249
|
-
* )
|
|
250
|
-
*
|
|
251
|
-
*
|
|
252
|
-
*
|
|
253
|
-
*
|
|
254
|
-
*
|
|
255
|
-
*
|
|
256
|
-
*
|
|
257
|
-
*
|
|
258
|
-
*
|
|
259
|
-
* )
|
|
268
|
+
* const ObserveHeroVisibility = Mount.defineStream('ObserveHeroVisibility', {
|
|
269
|
+
* messages: [ChangedHeroVisibility],
|
|
270
|
+
* execute: ({ element }) =>
|
|
271
|
+
* Stream.callback<typeof ChangedHeroVisibility.Type>(queue =>
|
|
272
|
+
* Effect.gen(function* () {
|
|
273
|
+
* yield* Effect.acquireRelease(
|
|
274
|
+
* Effect.sync(() => {
|
|
275
|
+
* const observer = new IntersectionObserver(entries => {
|
|
276
|
+
* pipe(
|
|
277
|
+
* Array.head(entries),
|
|
278
|
+
* Option.match({
|
|
279
|
+
* onNone: Function.constVoid,
|
|
280
|
+
* onSome: entry =>
|
|
281
|
+
* Queue.offerUnsafe(
|
|
282
|
+
* queue,
|
|
283
|
+
* ChangedHeroVisibility({
|
|
284
|
+
* isVisible: entry.isIntersecting,
|
|
285
|
+
* }),
|
|
286
|
+
* ),
|
|
287
|
+
* }),
|
|
288
|
+
* )
|
|
289
|
+
* })
|
|
290
|
+
* observer.observe(element)
|
|
291
|
+
* return observer
|
|
292
|
+
* }),
|
|
293
|
+
* observer => Effect.sync(() => observer.disconnect()),
|
|
294
|
+
* )
|
|
295
|
+
* return yield* Effect.never
|
|
296
|
+
* }),
|
|
297
|
+
* ),
|
|
298
|
+
* })
|
|
260
299
|
* ```
|
|
261
300
|
*
|
|
262
301
|
* The args-captured-at-mount and Subscriptions-vs-Mount guidance from
|
|
263
302
|
* `Mount.define` apply identically here. See that constructor's docs for
|
|
264
303
|
* the mental model.
|
|
265
304
|
*/
|
|
266
|
-
export declare function defineStream<const Name extends string,
|
|
267
|
-
|
|
305
|
+
export declare function defineStream<const Name extends string, Fields extends Schema.Struct.Fields, const Messages extends readonly [Schema.Top, ...ReadonlyArray<Schema.Top>]>(name: Name, config: Readonly<{
|
|
306
|
+
args: Fields & Readonly<{
|
|
307
|
+
element?: ElementFieldIsReserved;
|
|
308
|
+
}>;
|
|
309
|
+
messages: Messages;
|
|
310
|
+
execute: (input: Readonly<{
|
|
311
|
+
element: Element;
|
|
312
|
+
}> & Schema.Schema.Type<Schema.Struct<Fields>>) => Stream.Stream<Schema.Schema.Type<Messages[number]>, never, never>;
|
|
313
|
+
}>): MountDefinitionWithArgs<Name, Fields, Schema.Schema.Type<Messages[number]>>;
|
|
314
|
+
export declare function defineStream<const Name extends string, const Messages extends readonly [Schema.Top, ...ReadonlyArray<Schema.Top>]>(name: Name, config: Readonly<{
|
|
315
|
+
args?: never;
|
|
316
|
+
messages: Messages;
|
|
317
|
+
execute: (input: Readonly<{
|
|
318
|
+
element: Element;
|
|
319
|
+
}>) => Stream.Stream<Schema.Schema.Type<Messages[number]>, never, never>;
|
|
320
|
+
}>): MountDefinitionNoArgs<Name, Schema.Schema.Type<Messages[number]>>;
|
|
268
321
|
/** Lifts a `MountAction` from one Message universe to another by mapping its
|
|
269
322
|
* dispatched Messages through a transform. Used by Submodel components to
|
|
270
323
|
* emit lifecycle action results into the parent's Message union via the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/mount/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,OAAO,EACP,MAAM,EAIN,MAAM,EACN,KAAK,EACL,MAAM,EACP,MAAM,QAAQ,CAAA;;sBAWO,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI;oBACxD,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI;;AAV1E;;;;;4CAK4C;AAC5C,qBAAa,YAAa,SAAQ,iBAMN;CAAG;AAE/B,mDAAmD;AAEnD,eAAO,MAAM,qBAAqB,EAAE,OAAO,MAEN,CAAA;AAErC,mDAAmD;AACnD,MAAM,MAAM,qBAAqB,GAAG,OAAO,qBAAqB,CAAA;AAEhE;;;;;;;;;;aAUa;AACb,MAAM,MAAM,WAAW,CAAC,OAAO,EAAE,CAAC,GAAG,KAAK,IAAI,QAAQ,CAAC;IACrD,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC9B,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAA;CACnD,CAAC,CAAA;AAEF,6GAA6G;AAC7G,MAAM,WAAW,qBAAqB,CAAC,IAAI,SAAS,MAAM,EAAE,aAAa;IACvE,QAAQ,CAAC,CAAC,qBAAqB,CAAC,EAAE,qBAAqB,CAAA;IACvD,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IACpB,IAAI,QAAQ,CAAC;QACX,IAAI,EAAE,IAAI,CAAA;QACV,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,CAAA;KACtD,CAAC,CAAA;CACH;AAED,8GAA8G;AAC9G,MAAM,WAAW,uBAAuB,CACtC,IAAI,SAAS,MAAM,EACnB,MAAM,SAAS,MAAM,CAAC,MAAM,CAAC,MAAM,EACnC,aAAa;IAEb,QAAQ,CAAC,CAAC,qBAAqB,CAAC,EAAE,qBAAqB,CAAA;IACvD,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IACpB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,QAAQ,CAAC;QAC1D,IAAI,EAAE,IAAI,CAAA;QACV,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAA;QAC/C,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,CAAA;KACtD,CAAC,CAAA;CACH;AAED;;qCAEqC;AACrC,MAAM,MAAM,eAAe,CACzB,IAAI,SAAS,MAAM,GAAG,MAAM,EAC5B,aAAa,GAAG,GAAG,IAEjB,qBAAqB,CAAC,IAAI,EAAE,aAAa,CAAC,GAC1C,uBAAuB,CAAC,IAAI,EAAE,GAAG,EAAE,aAAa,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/mount/index.ts"],"names":[],"mappings":"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"}
|