@foldkit/ui 0.125.0 → 0.127.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.
@@ -80,10 +80,21 @@ export type InitConfig = Readonly<{
80
80
  id: string;
81
81
  isOpen?: boolean;
82
82
  isAnimated?: boolean;
83
+ /** CSS selector for the element that receives focus when the dialog opens.
84
+ * A selector-based override of the `initialFocus` RenderInfo marker, for the
85
+ * cases a spread-on marker cannot express: an element whose id you do not
86
+ * own, or a descendant selector. Takes precedence over `initialFocus`. With
87
+ * neither set, focus falls to the first focusable element. */
83
88
  focusSelector?: string;
84
89
  }>;
85
90
  /** Creates an initial dialog model from a config. Defaults to closed and non-animated. */
86
91
  export declare const init: (config: InitConfig) => Model;
92
+ /** Data attribute the dialog places on the `initialFocus` RenderInfo group and
93
+ * focuses on open. */
94
+ export declare const initialFocusMarkerAttribute = "foldkit-dialog-initial-focus";
95
+ /** Selector for {@link initialFocusMarkerAttribute}, focused against the open
96
+ * dialog when no `focusSelector` is configured. */
97
+ export declare const initialFocusMarkerSelector = "[data-foldkit-dialog-initial-focus]";
87
98
  type UpdateReturn = readonly [
88
99
  Model,
89
100
  ReadonlyArray<Command.Command<Message>>,
@@ -96,7 +107,7 @@ type UpdateReturn = readonly [
96
107
  * component supplies its own backdrop. */
97
108
  export declare const ShowDialog: Command.CommandDefinitionWithArgs<"ShowDialog", {
98
109
  id: S.String;
99
- maybeFocusSelector: S.Option<S.String>;
110
+ focusSelector: S.String;
100
111
  }, Effect.Effect<{
101
112
  readonly _tag: "CompletedShowDialog";
102
113
  }, never, never>>;
@@ -162,6 +173,10 @@ export declare const descriptionId: (model: Model) => string;
162
173
  * - `description`: attributes for the description element. Carries the
163
174
  * framework-managed id the dialog's `aria-describedby` points at. Spread
164
175
  * onto your description element (`h.p([...description], [...])`).
176
+ * - `initialFocus`: attributes for the element that should receive focus when
177
+ * the dialog opens. Spread onto that element (`h.input([...initialFocus])`).
178
+ * A configured `focusSelector` (see `init`) takes precedence, and focus
179
+ * falls back to the default when no element carries the group.
165
180
  * - `closeButton`: attributes for an in-panel close control such as a Cancel
166
181
  * or dismiss button. Carries the `OnClick` handler that closes the
167
182
  * dialog (suppressed while a leave animation is in progress). Spread
@@ -175,6 +190,7 @@ export type RenderInfo = Readonly<{
175
190
  panel: ReadonlyArray<ChildAttribute>;
176
191
  title: ReadonlyArray<ChildAttribute>;
177
192
  description: ReadonlyArray<ChildAttribute>;
193
+ initialFocus: ReadonlyArray<ChildAttribute>;
178
194
  closeButton: ReadonlyArray<ChildAttribute>;
179
195
  isVisible: boolean;
180
196
  }>;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/dialog/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/dialog/index.ts"],"names":[],"mappings":"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"}
@@ -78,16 +78,19 @@ export const init = (config) => ({
78
78
  });
79
79
  // UPDATE
80
80
  const dialogSelector = (id) => idSelector(id);
81
+ /** Data attribute the dialog places on the `initialFocus` RenderInfo group and
82
+ * focuses on open. */
83
+ export const initialFocusMarkerAttribute = 'foldkit-dialog-initial-focus';
84
+ /** Selector for {@link initialFocusMarkerAttribute}, focused against the open
85
+ * dialog when no `focusSelector` is configured. */
86
+ export const initialFocusMarkerSelector = `[data-${initialFocusMarkerAttribute}]`;
81
87
  const withUpdateReturn = M.withReturnType();
82
88
  /** Locks page scroll and opens the native dialog element through
83
89
  * `Dom.showDialog`, which calls `show()` (not native `showModal()`) so other
84
90
  * high-z-index overlays stay interactive. It layers the dialog with a high
85
91
  * z-index, traps focus, and dispatches a `cancel` event on Esc. The Dialog
86
92
  * component supplies its own backdrop. */
87
- export const ShowDialog = Command.define('ShowDialog', { id: S.String, maybeFocusSelector: S.Option(S.String) }, CompletedShowDialog)(({ id, maybeFocusSelector }) => Dom.lockScroll.pipe(Effect.andThen(() => Dom.showDialog(dialogSelector(id), Option.match(maybeFocusSelector, {
88
- onNone: () => undefined,
89
- onSome: focusSelector => ({ focusSelector }),
90
- }))), Effect.ignore, Effect.as(CompletedShowDialog())));
93
+ export const ShowDialog = Command.define('ShowDialog', { id: S.String, focusSelector: S.String }, CompletedShowDialog)(({ id, focusSelector }) => Dom.lockScroll.pipe(Effect.andThen(() => Dom.showDialog(dialogSelector(id), { focusSelector })), Effect.ignore, Effect.as(CompletedShowDialog())));
91
94
  /** Calls `close()` on the native dialog element and unlocks page scroll. */
92
95
  export const CloseDialog = Command.define('CloseDialog', { id: S.String }, CompletedCloseDialog)(({ id }) => Dom.closeDialog(dialogSelector(id)).pipe(Effect.andThen(() => Dom.unlockScroll), Effect.ignore, Effect.as(CompletedCloseDialog())));
93
96
  /** Releases the framework hygiene the dialog holds while open (scroll lock,
@@ -120,7 +123,7 @@ export const update = (model, message) => M.value(message).pipe(withUpdateReturn
120
123
  const wasClosed = !model.isOpen;
121
124
  const maybeShow = Option.liftPredicate(ShowDialog({
122
125
  id: model.id,
123
- maybeFocusSelector: model.maybeFocusSelector,
126
+ focusSelector: Option.getOrElse(model.maybeFocusSelector, () => initialFocusMarkerSelector),
124
127
  }), () => wasClosed);
125
128
  const maybeOutMessage = wasClosed
126
129
  ? Option.some(Opened())
@@ -259,6 +262,9 @@ export const view = defineView((model, viewInputs) => {
259
262
  const panelAttributes = [h.Id(`${id}-panel`), ...animationAttributes];
260
263
  const titleAttributes = [h.Id(titleId(model))];
261
264
  const descriptionAttributes = [h.Id(descriptionId(model))];
265
+ const initialFocusAttributes = [
266
+ h.DataAttribute(initialFocusMarkerAttribute, ''),
267
+ ];
262
268
  const closeButtonAttributes = isLeaving ? [] : [h.OnClick(RequestedClose())];
263
269
  return toView({
264
270
  dialog: childAttributes(dialogAttributes),
@@ -266,6 +272,7 @@ export const view = defineView((model, viewInputs) => {
266
272
  panel: childAttributes(panelAttributes),
267
273
  title: childAttributes(titleAttributes),
268
274
  description: childAttributes(descriptionAttributes),
275
+ initialFocus: childAttributes(initialFocusAttributes),
269
276
  closeButton: childAttributes(closeButtonAttributes),
270
277
  isVisible,
271
278
  });
@@ -4,7 +4,7 @@ import { type ChildAttribute, type Html } from 'foldkit/html';
4
4
  import * as Mount from 'foldkit/mount';
5
5
  import { type Reflect } from 'foldkit/submodel';
6
6
  import { AnchorConfig } from '../anchor.js';
7
- /** Schema for the tooltip component's state. `isOpen` is visibility; `isHovered` tracks pointer on trigger; `isFocused` tracks tooltip-affirming focus on the trigger (focus arriving without a preceding mouse press, like keyboard, touch, or pen; mouse-click-induced focus is excluded since it doesn't affirm the user wants the tooltip visible); `isDismissed` suppresses re-opening after the user dismissed the tooltip (via Escape or left-click) until they disengage (leave or blur). `showDelay` is the hover-to-show duration. `maybeLastPointerType` records the most recent pointer type that pressed the trigger, so a mouse-click-induced focus can be distinguished from other focus. */
7
+ /** Schema for the tooltip component's state. `isOpen` is visibility; `isHovered` tracks pointer on trigger; `isFocused` tracks tooltip-affirming focus on the trigger (focus arriving without a preceding mouse press, like keyboard, touch, or pen; mouse-click-induced focus is excluded since it doesn't affirm the user wants the tooltip visible); `isDismissed` suppresses re-opening after the user dismissed the tooltip (via Escape) until they disengage (leave or blur). `showDelay` is the hover-to-show duration. `maybeLastPointerType` records the most recent pointer type that pressed the trigger, so a mouse-click-induced focus can be distinguished from other focus. */
8
8
  export declare const Model: S.Struct<{
9
9
  readonly id: S.String;
10
10
  readonly isOpen: S.Boolean;
@@ -26,10 +26,11 @@ export declare const FocusedTrigger: import("foldkit/schema").CallableTaggedStru
26
26
  export declare const BlurredTrigger: import("foldkit/schema").CallableTaggedStruct<"BlurredTrigger", {}>;
27
27
  /** Sent when Escape is pressed while the tooltip is visible. */
28
28
  export declare const PressedEscape: import("foldkit/schema").CallableTaggedStruct<"PressedEscape", {}>;
29
- /** Sent when a pointer presses the trigger. */
29
+ /** Sent when a pointer presses the trigger. Recorded so the focus that
30
+ * follows a mouse press can be told apart from focus that affirms the
31
+ * tooltip (keyboard, touch, or pen). */
30
32
  export declare const PressedPointerOnTrigger: import("foldkit/schema").CallableTaggedStruct<"PressedPointerOnTrigger", {
31
33
  pointerType: S.String;
32
- button: S.Number;
33
34
  }>;
34
35
  /** Sent when the show-delay timer fires. */
35
36
  export declare const ElapsedShowDelay: import("foldkit/schema").CallableTaggedStruct<"ElapsedShowDelay", {
@@ -138,8 +139,7 @@ export type ViewInputs = Readonly<{
138
139
  }>;
139
140
  /** Renders a headless tooltip with an anchored non-interactive panel.
140
141
  * Shows on hover (after delay) or focus (from keyboard, touch, or pen;
141
- * mouse-click focus is excluded); hides on leave, blur, Escape, or
142
- * left-click of the trigger. */
142
+ * mouse-click focus is excluded). Hides on leave, blur, or Escape. */
143
143
  export declare const view: import("foldkit/submodel").View<S.Struct.ReadonlySide<{
144
144
  readonly id: S.String;
145
145
  readonly isOpen: S.Boolean;
@@ -162,7 +162,6 @@ export declare const view: import("foldkit/submodel").View<S.Struct.ReadonlySide
162
162
  }, "Type"> | S.Struct.ReadonlySide<{
163
163
  readonly _tag: S.tag<"PressedPointerOnTrigger">;
164
164
  pointerType: S.String;
165
- button: S.Number;
166
165
  }, "Type"> | S.Struct.ReadonlySide<{
167
166
  readonly _tag: S.tag<"ElapsedShowDelay">;
168
167
  version: S.Number;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tooltip/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tooltip/index.ts"],"names":[],"mappings":"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"}
@@ -8,7 +8,7 @@ import { defineView } from 'foldkit/submodel';
8
8
  import { AnchorConfig, anchorSetup } from '../anchor.js';
9
9
  import * as OptionExt from '../internal/optionExtensions.js';
10
10
  // MODEL
11
- /** Schema for the tooltip component's state. `isOpen` is visibility; `isHovered` tracks pointer on trigger; `isFocused` tracks tooltip-affirming focus on the trigger (focus arriving without a preceding mouse press, like keyboard, touch, or pen; mouse-click-induced focus is excluded since it doesn't affirm the user wants the tooltip visible); `isDismissed` suppresses re-opening after the user dismissed the tooltip (via Escape or left-click) until they disengage (leave or blur). `showDelay` is the hover-to-show duration. `maybeLastPointerType` records the most recent pointer type that pressed the trigger, so a mouse-click-induced focus can be distinguished from other focus. */
11
+ /** Schema for the tooltip component's state. `isOpen` is visibility; `isHovered` tracks pointer on trigger; `isFocused` tracks tooltip-affirming focus on the trigger (focus arriving without a preceding mouse press, like keyboard, touch, or pen; mouse-click-induced focus is excluded since it doesn't affirm the user wants the tooltip visible); `isDismissed` suppresses re-opening after the user dismissed the tooltip (via Escape) until they disengage (leave or blur). `showDelay` is the hover-to-show duration. `maybeLastPointerType` records the most recent pointer type that pressed the trigger, so a mouse-click-induced focus can be distinguished from other focus. */
12
12
  export const Model = S.Struct({
13
13
  id: S.String,
14
14
  isOpen: S.Boolean,
@@ -30,10 +30,11 @@ export const FocusedTrigger = m('FocusedTrigger');
30
30
  export const BlurredTrigger = m('BlurredTrigger');
31
31
  /** Sent when Escape is pressed while the tooltip is visible. */
32
32
  export const PressedEscape = m('PressedEscape');
33
- /** Sent when a pointer presses the trigger. */
33
+ /** Sent when a pointer presses the trigger. Recorded so the focus that
34
+ * follows a mouse press can be told apart from focus that affirms the
35
+ * tooltip (keyboard, touch, or pen). */
34
36
  export const PressedPointerOnTrigger = m('PressedPointerOnTrigger', {
35
37
  pointerType: S.String,
36
- button: S.Number,
37
38
  });
38
39
  /** Sent when the show-delay timer fires. */
39
40
  export const ElapsedShowDelay = m('ElapsedShowDelay', {
@@ -69,7 +70,6 @@ export const OutMessage = S.Union([Shown, Hidden]);
69
70
  export const triggerId = (id) => `${id}-trigger`;
70
71
  // INIT
71
72
  const DEFAULT_SHOW_DELAY = Duration.millis(500);
72
- const LEFT_MOUSE_BUTTON = 0;
73
73
  /** Creates an initial tooltip model from a config. Defaults to hidden. */
74
74
  export const init = (config) => ({
75
75
  id: config.id,
@@ -164,27 +164,12 @@ const computeUpdate = (model, message) => M.value(message).pipe(withUpdateReturn
164
164
  }),
165
165
  [],
166
166
  ],
167
- PressedPointerOnTrigger: ({ pointerType, button }) => {
168
- const isLeftClickOnOpen = button === LEFT_MOUSE_BUTTON && model.isOpen;
169
- if (isLeftClickOnOpen) {
170
- return [
171
- evo(model, {
172
- maybeLastPointerType: () => Option.some(pointerType),
173
- isOpen: () => false,
174
- isFocused: () => false,
175
- isDismissed: () => true,
176
- pendingShowVersion: Number.increment,
177
- }),
178
- [],
179
- ];
180
- }
181
- return [
182
- evo(model, {
183
- maybeLastPointerType: () => Option.some(pointerType),
184
- }),
185
- [],
186
- ];
187
- },
167
+ PressedPointerOnTrigger: ({ pointerType }) => [
168
+ evo(model, {
169
+ maybeLastPointerType: () => Option.some(pointerType),
170
+ }),
171
+ [],
172
+ ],
188
173
  ElapsedShowDelay: ({ version }) => {
189
174
  if (version !== model.pendingShowVersion) {
190
175
  return [model, []];
@@ -215,8 +200,7 @@ export const update = (model, message) => {
215
200
  export const reflectShowDelay = Function.dual(2, (model, showDelay) => evo(model, { showDelay: () => Duration.fromInputUnsafe(showDelay) }));
216
201
  /** Renders a headless tooltip with an anchored non-interactive panel.
217
202
  * Shows on hover (after delay) or focus (from keyboard, touch, or pen;
218
- * mouse-click focus is excluded); hides on leave, blur, Escape, or
219
- * left-click of the trigger. */
203
+ * mouse-click focus is excluded). Hides on leave, blur, or Escape. */
220
204
  export const view = defineView((model, viewInputs) => {
221
205
  const h = html();
222
206
  const { id, isOpen } = model;
@@ -234,7 +218,7 @@ export const view = defineView((model, viewInputs) => {
234
218
  };
235
219
  const triggerLabelAttributes = resolveTriggerLabel();
236
220
  const handleTriggerKeyDown = (key) => M.value(key).pipe(M.when('Escape', () => OptionExt.when(isOpen, PressedEscape())), M.orElse(() => Option.none()));
237
- const handleTriggerPointerDown = (pointerType, button) => Option.some(PressedPointerOnTrigger({ pointerType, button }));
221
+ const handleTriggerPointerDown = (pointerType) => Option.some(PressedPointerOnTrigger({ pointerType }));
238
222
  const triggerAttributes = [
239
223
  h.Id(`${id}-trigger`),
240
224
  h.Type('button'),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@foldkit/ui",
3
- "version": "0.125.0",
3
+ "version": "0.127.0",
4
4
  "description": "Headless, accessible UI components for Foldkit",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -127,7 +127,7 @@
127
127
  "typedoc": "^0.28.19",
128
128
  "typescript": "^6.0.3",
129
129
  "vitest": "^4.1.9",
130
- "foldkit": "0.125.0"
130
+ "foldkit": "0.127.0"
131
131
  },
132
132
  "keywords": [
133
133
  "foldkit",