@foldkit/ui 0.136.0 → 0.137.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/anchor.d.ts +7 -1
- package/dist/anchor.d.ts.map +1 -1
- package/dist/anchor.js +77 -26
- package/dist/animation/index.d.ts +5 -5
- package/dist/animation/index.d.ts.map +1 -1
- package/dist/animation/index.js +4 -4
- package/dist/animation/public.d.ts +1 -1
- package/dist/animation/public.d.ts.map +1 -1
- package/dist/animation/public.js +1 -1
- package/dist/animation/schema.d.ts +2 -2
- package/dist/animation/schema.d.ts.map +1 -1
- package/dist/animation/schema.js +2 -2
- package/dist/animation/update.d.ts +3 -3
- package/dist/animation/update.d.ts.map +1 -1
- package/dist/animation/update.js +8 -8
- package/dist/combobox/multi.d.ts +1 -1
- package/dist/combobox/shared.d.ts +4 -3
- package/dist/combobox/shared.d.ts.map +1 -1
- package/dist/combobox/single.d.ts +1 -1
- package/dist/datePicker/index.d.ts +2 -2
- package/dist/dialog/index.d.ts +2 -2
- package/dist/dragAndDrop/index.d.ts +7 -7
- package/dist/dragAndDrop/index.d.ts.map +1 -1
- package/dist/dragAndDrop/index.js +8 -8
- package/dist/dragAndDrop/public.d.ts +1 -1
- package/dist/dragAndDrop/public.d.ts.map +1 -1
- package/dist/dragAndDrop/public.js +1 -1
- package/dist/listbox/multi.d.ts +2 -2
- package/dist/listbox/public.d.ts +1 -1
- package/dist/listbox/public.d.ts.map +1 -1
- package/dist/listbox/public.js +1 -1
- package/dist/listbox/shared.d.ts +9 -8
- package/dist/listbox/shared.d.ts.map +1 -1
- package/dist/listbox/shared.js +9 -7
- package/dist/listbox/single.d.ts +2 -2
- package/dist/menu/index.d.ts +7 -6
- package/dist/menu/index.d.ts.map +1 -1
- package/dist/menu/index.js +9 -7
- package/dist/menu/public.d.ts +1 -1
- package/dist/menu/public.d.ts.map +1 -1
- package/dist/menu/public.js +1 -1
- package/dist/popover/index.d.ts +4 -3
- package/dist/popover/index.d.ts.map +1 -1
- package/dist/test/apps/disabledButton.d.ts +2 -2
- package/dist/toast/index.d.ts +19 -18
- package/dist/toast/index.d.ts.map +1 -1
- package/dist/toast/index.js +5 -4
- package/dist/toast/public.d.ts +1 -1
- package/dist/toast/public.d.ts.map +1 -1
- package/dist/toast/public.js +1 -1
- package/dist/toast/schema.d.ts +5 -5
- package/dist/toast/schema.d.ts.map +1 -1
- package/dist/toast/schema.js +2 -2
- package/dist/toast/test.d.ts +6 -5
- package/dist/toast/test.d.ts.map +1 -1
- package/dist/toast/test.js +8 -7
- package/dist/toast/update.d.ts +14 -14
- package/dist/toast/update.d.ts.map +1 -1
- package/dist/toast/update.js +7 -7
- package/dist/tooltip/index.d.ts +2 -177
- package/dist/tooltip/index.d.ts.map +1 -1
- package/dist/tooltip/index.js +2 -260
- package/dist/tooltip/message.d.ts +53 -0
- package/dist/tooltip/message.d.ts.map +1 -0
- package/dist/tooltip/message.js +45 -0
- package/dist/tooltip/public.d.ts +1 -1
- package/dist/tooltip/public.d.ts.map +1 -1
- package/dist/tooltip/public.js +1 -1
- package/dist/tooltip/tooltip.d.ts +130 -0
- package/dist/tooltip/tooltip.d.ts.map +1 -0
- package/dist/tooltip/tooltip.js +226 -0
- package/package.json +2 -2
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { Duration, Effect, Option, Schema as S } from 'effect';
|
|
2
|
+
import * as Command from 'foldkit/command';
|
|
3
|
+
import { type ChildAttribute, type Html } from 'foldkit/html';
|
|
4
|
+
import * as Mount from 'foldkit/mount';
|
|
5
|
+
import { type Reflect } from 'foldkit/submodel';
|
|
6
|
+
import { AnchorConfig } from '../anchor.js';
|
|
7
|
+
import { type Message, type OutMessage } from './message.js';
|
|
8
|
+
/** 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. */
|
|
9
|
+
export declare const Model: S.Struct<{
|
|
10
|
+
readonly id: S.String;
|
|
11
|
+
readonly isOpen: S.Boolean;
|
|
12
|
+
readonly isHovered: S.Boolean;
|
|
13
|
+
readonly isFocused: S.Boolean;
|
|
14
|
+
readonly isDismissed: S.Boolean;
|
|
15
|
+
readonly showDelay: S.DurationFromMillis;
|
|
16
|
+
readonly pendingShowVersion: S.Number;
|
|
17
|
+
readonly maybeLastPointerType: S.Option<S.String>;
|
|
18
|
+
}>;
|
|
19
|
+
export type Model = typeof Model.Type;
|
|
20
|
+
/** Returns the bare DOM id of the tooltip trigger button, derived from the
|
|
21
|
+
* tooltip's base id. Use this to associate an external label with the
|
|
22
|
+
* trigger via a native `<label for={Tooltip.triggerId(id)}>` or an
|
|
23
|
+
* `aria-labelledby` reference. */
|
|
24
|
+
export declare const triggerId: (id: string) => string;
|
|
25
|
+
/** Configuration for creating a tooltip model with `init`. */
|
|
26
|
+
export type InitConfig = Readonly<{
|
|
27
|
+
id: string;
|
|
28
|
+
showDelay?: Duration.Input;
|
|
29
|
+
}>;
|
|
30
|
+
/** Creates an initial tooltip model from a config. Defaults to hidden. */
|
|
31
|
+
export declare const init: (config: InitConfig) => Model;
|
|
32
|
+
/** Waits for the tooltip's show delay before emitting
|
|
33
|
+
* `CompletedWaitBeforeShowing`. */
|
|
34
|
+
export declare const WaitBeforeShowing: Command.CommandDefinitionWithArgs<"WaitBeforeShowing", {
|
|
35
|
+
delay: S.DurationFromMillis;
|
|
36
|
+
version: S.Number;
|
|
37
|
+
}, Effect.Effect<{
|
|
38
|
+
readonly _tag: "CompletedWaitBeforeShowing";
|
|
39
|
+
readonly version: number;
|
|
40
|
+
}, never, never>>;
|
|
41
|
+
/** The anchor-positioning Mount this Tooltip renders on its panel. */
|
|
42
|
+
export declare const AnchorTooltip: Mount.MountDefinitionWithArgs<"AnchorTooltip", {
|
|
43
|
+
buttonId: S.String;
|
|
44
|
+
anchor: S.Struct<{
|
|
45
|
+
readonly placement: S.optional<S.Literals<readonly ["top", "right", "bottom", "left", "top-start", "top-end", "right-start", "right-end", "bottom-start", "bottom-end", "left-start", "left-end"]>>;
|
|
46
|
+
readonly gap: S.optional<S.Number>;
|
|
47
|
+
readonly offset: S.optional<S.Number>;
|
|
48
|
+
readonly padding: S.optional<S.Number>;
|
|
49
|
+
readonly portal: S.optional<S.Boolean>;
|
|
50
|
+
readonly isPlacementLocked: S.optional<S.Boolean>;
|
|
51
|
+
}>;
|
|
52
|
+
}, {
|
|
53
|
+
readonly _tag: "CompletedAnchorTooltip";
|
|
54
|
+
}>;
|
|
55
|
+
type UpdateReturn = readonly [
|
|
56
|
+
Model,
|
|
57
|
+
ReadonlyArray<Command.Command<Message>>,
|
|
58
|
+
Option.Option<OutMessage>
|
|
59
|
+
];
|
|
60
|
+
/** Processes a tooltip message and returns the next model, commands, and
|
|
61
|
+
* an optional OutMessage. `Shown`/`Hidden` fire only on `isOpen`
|
|
62
|
+
* transitions, so consumers don't get spurious events for messages that
|
|
63
|
+
* only update hover/focus/delay state without changing visibility. */
|
|
64
|
+
export declare const update: (model: Model, message: Message) => UpdateReturn;
|
|
65
|
+
/** Reflects an externally-sourced hover show-delay onto the model without
|
|
66
|
+
* emitting an OutMessage. Use to mirror an external config value (a user
|
|
67
|
+
* preference, a restored setting) onto the tooltip. */
|
|
68
|
+
export declare const reflectShowDelay: Reflect<Model, Duration.Input>;
|
|
69
|
+
/** Render-time payload published to the consumer's `toView`.
|
|
70
|
+
*
|
|
71
|
+
* - `trigger`: attribute bundle for the trigger element. Carries the
|
|
72
|
+
* hover/focus/keyboard handlers + ARIA `aria-describedby` linking to
|
|
73
|
+
* the panel.
|
|
74
|
+
* - `panel`: attribute bundle for the panel element. Carries the
|
|
75
|
+
* `role="tooltip"`, the anchor Mount that positions the panel via
|
|
76
|
+
* Floating UI, and a `data-open` attribute when visible.
|
|
77
|
+
* - `isVisible`: derived state. The consumer decides whether to render
|
|
78
|
+
* the panel conditionally on this. */
|
|
79
|
+
export type RenderInfo = Readonly<{
|
|
80
|
+
trigger: ReadonlyArray<ChildAttribute>;
|
|
81
|
+
panel: ReadonlyArray<ChildAttribute>;
|
|
82
|
+
isVisible: boolean;
|
|
83
|
+
}>;
|
|
84
|
+
/** Per-render view inputs passed to `view` via `h.submodel`'s `viewInputs` field. */
|
|
85
|
+
export type ViewInputs = Readonly<{
|
|
86
|
+
anchor: AnchorConfig;
|
|
87
|
+
toView: (render: RenderInfo) => Html;
|
|
88
|
+
isDisabled?: boolean;
|
|
89
|
+
ariaLabel?: string;
|
|
90
|
+
ariaLabelledBy?: string;
|
|
91
|
+
}>;
|
|
92
|
+
/** Renders a headless tooltip with an anchored non-interactive panel.
|
|
93
|
+
* Shows on hover (after delay) or focus (from keyboard, touch, or pen;
|
|
94
|
+
* mouse-click focus is excluded). Hides on leave, blur, or Escape. */
|
|
95
|
+
export declare const view: import("foldkit/submodel").View<{
|
|
96
|
+
readonly id: string;
|
|
97
|
+
readonly isOpen: boolean;
|
|
98
|
+
readonly isHovered: boolean;
|
|
99
|
+
readonly isFocused: boolean;
|
|
100
|
+
readonly isDismissed: boolean;
|
|
101
|
+
readonly showDelay: Duration.Duration;
|
|
102
|
+
readonly pendingShowVersion: number;
|
|
103
|
+
readonly maybeLastPointerType: Option.Option<string>;
|
|
104
|
+
}, {
|
|
105
|
+
readonly _tag: "EnteredTrigger";
|
|
106
|
+
} | {
|
|
107
|
+
readonly _tag: "LeftTrigger";
|
|
108
|
+
} | {
|
|
109
|
+
readonly _tag: "FocusedTrigger";
|
|
110
|
+
} | {
|
|
111
|
+
readonly _tag: "BlurredTrigger";
|
|
112
|
+
} | {
|
|
113
|
+
readonly _tag: "PressedEscape";
|
|
114
|
+
} | {
|
|
115
|
+
readonly _tag: "PressedPointerOnTrigger";
|
|
116
|
+
readonly pointerType: string;
|
|
117
|
+
} | {
|
|
118
|
+
readonly _tag: "CompletedWaitBeforeShowing";
|
|
119
|
+
readonly version: number;
|
|
120
|
+
} | {
|
|
121
|
+
readonly _tag: "CompletedAnchorTooltip";
|
|
122
|
+
}, Readonly<{
|
|
123
|
+
anchor: AnchorConfig;
|
|
124
|
+
toView: (render: RenderInfo) => Html;
|
|
125
|
+
isDisabled?: boolean;
|
|
126
|
+
ariaLabel?: string;
|
|
127
|
+
ariaLabelledBy?: string;
|
|
128
|
+
}>>;
|
|
129
|
+
export {};
|
|
130
|
+
//# sourceMappingURL=tooltip.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tooltip.d.ts","sourceRoot":"","sources":["../../src/tooltip/tooltip.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EACR,MAAM,EAKN,MAAM,EAEN,MAAM,IAAI,CAAC,EACZ,MAAM,QAAQ,CAAA;AACf,OAAO,KAAK,OAAO,MAAM,iBAAiB,CAAA;AAC1C,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,IAAI,EAAmB,MAAM,cAAc,CAAA;AAC9E,OAAO,KAAK,KAAK,MAAM,eAAe,CAAA;AAEtC,OAAO,EAAE,KAAK,OAAO,EAAc,MAAM,kBAAkB,CAAA;AAE3D,OAAO,EAAE,YAAY,EAAe,MAAM,cAAc,CAAA;AAExD,OAAO,EAQL,KAAK,OAAO,EACZ,KAAK,UAAU,EAIhB,MAAM,cAAc,CAAA;AAIrB,8pBAA8pB;AAC9pB,eAAO,MAAM,KAAK;;;;;;;;;EAShB,CAAA;AAEF,MAAM,MAAM,KAAK,GAAG,OAAO,KAAK,CAAC,IAAI,CAAA;AAIrC;;;mCAGmC;AACnC,eAAO,MAAM,SAAS,GAAI,IAAI,MAAM,KAAG,MAAyB,CAAA;AAQhE,8DAA8D;AAC9D,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC;IAChC,EAAE,EAAE,MAAM,CAAA;IACV,SAAS,CAAC,EAAE,QAAQ,CAAC,KAAK,CAAA;CAC3B,CAAC,CAAA;AAEF,0EAA0E;AAC1E,eAAO,MAAM,IAAI,GAAI,QAAQ,UAAU,KAAG,KAYxC,CAAA;AAUF;oCACoC;AACpC,eAAO,MAAM,iBAAiB;;;;;;iBAO5B,CAAA;AAEF,sEAAsE;AACtE,eAAO,MAAM,aAAa;;;;;;;;;;;;EAoBzB,CAAA;AA6GD,KAAK,YAAY,GAAG,SAAS;IAC3B,KAAK;IACL,aAAa,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IACvC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC;CAC1B,CAAA;AAeD;;;uEAGuE;AACvE,eAAO,MAAM,MAAM,GAAI,OAAO,KAAK,EAAE,SAAS,OAAO,KAAG,YAOvD,CAAA;AAED;;wDAEwD;AACxD,eAAO,MAAM,gBAAgB,EAAE,OAAO,CAAC,KAAK,EAAE,QAAQ,CAAC,KAAK,CAI3D,CAAA;AAID;;;;;;;;;yCASyC;AACzC,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC;IAChC,OAAO,EAAE,aAAa,CAAC,cAAc,CAAC,CAAA;IACtC,KAAK,EAAE,aAAa,CAAC,cAAc,CAAC,CAAA;IACpC,SAAS,EAAE,OAAO,CAAA;CACnB,CAAC,CAAA;AAEF,qFAAqF;AACrF,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC;IAChC,MAAM,EAAE,YAAY,CAAA;IACpB,MAAM,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,IAAI,CAAA;IACpC,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB,CAAC,CAAA;AAEF;;uEAEuE;AACvE,eAAO,MAAM,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;YAVP,YAAY;YACZ,CAAC,MAAM,EAAE,UAAU,KAAK,IAAI;iBACvB,OAAO;gBACR,MAAM;qBACD,MAAM;GAuExB,CAAA"}
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
import { brandViewResult as __foldkitBrandViewResult } from 'foldkit/brand'
|
|
2
|
+
import { Duration, Effect, Equal, Function, Match as M, Number, Option, Predicate, Schema as S, } from 'effect';
|
|
3
|
+
import * as Command from 'foldkit/command';
|
|
4
|
+
import { childAttributes } from 'foldkit/html';
|
|
5
|
+
import * as Mount from 'foldkit/mount';
|
|
6
|
+
import { evo } from 'foldkit/struct';
|
|
7
|
+
import { defineView } from 'foldkit/submodel';
|
|
8
|
+
import { AnchorConfig, anchorSetup } from '../anchor.js';
|
|
9
|
+
import * as OptionExt from '../internal/optionExtensions.js';
|
|
10
|
+
import { BlurredTrigger, CompletedAnchorTooltip, CompletedWaitBeforeShowing, EnteredTrigger, FocusedTrigger, Hidden, LeftTrigger, PressedEscape, PressedPointerOnTrigger, Shown, } from './message.js';
|
|
11
|
+
// MODEL
|
|
12
|
+
/** 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. */
|
|
13
|
+
export const Model = S.Struct({
|
|
14
|
+
id: S.String,
|
|
15
|
+
isOpen: S.Boolean,
|
|
16
|
+
isHovered: S.Boolean,
|
|
17
|
+
isFocused: S.Boolean,
|
|
18
|
+
isDismissed: S.Boolean,
|
|
19
|
+
showDelay: S.DurationFromMillis,
|
|
20
|
+
pendingShowVersion: S.Number,
|
|
21
|
+
maybeLastPointerType: S.Option(S.String),
|
|
22
|
+
});
|
|
23
|
+
// SELECTORS
|
|
24
|
+
/** Returns the bare DOM id of the tooltip trigger button, derived from the
|
|
25
|
+
* tooltip's base id. Use this to associate an external label with the
|
|
26
|
+
* trigger via a native `<label for={Tooltip.triggerId(id)}>` or an
|
|
27
|
+
* `aria-labelledby` reference. */
|
|
28
|
+
export const triggerId = (id) => __foldkitBrandViewResult((`${id}-trigger`), "@foldkit/ui/tooltip/tooltip.js#triggerId");
|
|
29
|
+
const panelId = (id) => __foldkitBrandViewResult((`${id}-panel`), "@foldkit/ui/tooltip/tooltip.js#panelId");
|
|
30
|
+
// INIT
|
|
31
|
+
const DEFAULT_SHOW_DELAY = Duration.millis(500);
|
|
32
|
+
/** Creates an initial tooltip model from a config. Defaults to hidden. */
|
|
33
|
+
export const init = (config) => (__foldkitBrandViewResult(({
|
|
34
|
+
id: config.id,
|
|
35
|
+
isOpen: false,
|
|
36
|
+
isHovered: false,
|
|
37
|
+
isFocused: false,
|
|
38
|
+
isDismissed: false,
|
|
39
|
+
showDelay: config.showDelay === undefined
|
|
40
|
+
? DEFAULT_SHOW_DELAY
|
|
41
|
+
: Duration.fromInputUnsafe(config.showDelay),
|
|
42
|
+
pendingShowVersion: 0,
|
|
43
|
+
maybeLastPointerType: Option.none(),
|
|
44
|
+
}), "@foldkit/ui/tooltip/tooltip.js#init"));
|
|
45
|
+
const withUpdateReturn = M.withReturnType();
|
|
46
|
+
/** Waits for the tooltip's show delay before emitting
|
|
47
|
+
* `CompletedWaitBeforeShowing`. */
|
|
48
|
+
export const WaitBeforeShowing = Command.define('WaitBeforeShowing', {
|
|
49
|
+
args: { delay: S.DurationFromMillis, version: S.Number },
|
|
50
|
+
messages: [CompletedWaitBeforeShowing],
|
|
51
|
+
execute: ({ delay, version }) => __foldkitBrandViewResult((Effect.sleep(delay).pipe(Effect.as(CompletedWaitBeforeShowing({ version })))), "@foldkit/ui/tooltip/tooltip.js#execute"),
|
|
52
|
+
});
|
|
53
|
+
/** The anchor-positioning Mount this Tooltip renders on its panel. */
|
|
54
|
+
export const AnchorTooltip = Mount.define('AnchorTooltip', { buttonId: S.String, anchor: AnchorConfig }, CompletedAnchorTooltip)(({ buttonId, anchor }) => __foldkitBrandViewResult((element => __foldkitBrandViewResult((Effect.gen(function* () {
|
|
55
|
+
yield* Effect.acquireRelease(Effect.sync(() => __foldkitBrandViewResult((anchorSetup({
|
|
56
|
+
buttonId,
|
|
57
|
+
anchor,
|
|
58
|
+
interceptTab: false,
|
|
59
|
+
})(element)), "@foldkit/ui/tooltip/tooltip.js#anonymous~4")), cleanup => __foldkitBrandViewResult((Effect.sync(cleanup)), "@foldkit/ui/tooltip/tooltip.js#anonymous~5"));
|
|
60
|
+
return __foldkitBrandViewResult((CompletedAnchorTooltip()), "@foldkit/ui/tooltip/tooltip.js#anonymous~3");
|
|
61
|
+
})), "@foldkit/ui/tooltip/tooltip.js#anonymous~2")), "@foldkit/ui/tooltip/tooltip.js#anonymous"));
|
|
62
|
+
const computeUpdate = (model, message) => __foldkitBrandViewResult((M.value(message).pipe(withUpdateReturn, M.tagsExhaustive({
|
|
63
|
+
EnteredTrigger: () => {
|
|
64
|
+
if (model.isOpen || model.isDismissed) {
|
|
65
|
+
return __foldkitBrandViewResult(([evo(model, { isHovered: () => __foldkitBrandViewResult((true), "@foldkit/ui/tooltip/tooltip.js#isHovered") }), []]), "@foldkit/ui/tooltip/tooltip.js#EnteredTrigger");
|
|
66
|
+
}
|
|
67
|
+
const nextVersion = Number.increment(model.pendingShowVersion);
|
|
68
|
+
return __foldkitBrandViewResult(([
|
|
69
|
+
evo(model, {
|
|
70
|
+
isHovered: () => __foldkitBrandViewResult((true), "@foldkit/ui/tooltip/tooltip.js#isHovered~2"),
|
|
71
|
+
pendingShowVersion: () => __foldkitBrandViewResult((nextVersion), "@foldkit/ui/tooltip/tooltip.js#pendingShowVersion"),
|
|
72
|
+
}),
|
|
73
|
+
[WaitBeforeShowing({ delay: model.showDelay, version: nextVersion })],
|
|
74
|
+
]), "@foldkit/ui/tooltip/tooltip.js#EnteredTrigger");
|
|
75
|
+
},
|
|
76
|
+
LeftTrigger: () => __foldkitBrandViewResult(([
|
|
77
|
+
evo(model, {
|
|
78
|
+
isHovered: () => __foldkitBrandViewResult((false), "@foldkit/ui/tooltip/tooltip.js#isHovered~3"),
|
|
79
|
+
isOpen: () => __foldkitBrandViewResult((model.isFocused && model.isOpen), "@foldkit/ui/tooltip/tooltip.js#isOpen"),
|
|
80
|
+
isDismissed: () => __foldkitBrandViewResult((false), "@foldkit/ui/tooltip/tooltip.js#isDismissed"),
|
|
81
|
+
pendingShowVersion: Number.increment,
|
|
82
|
+
}),
|
|
83
|
+
[],
|
|
84
|
+
]), "@foldkit/ui/tooltip/tooltip.js#LeftTrigger"),
|
|
85
|
+
FocusedTrigger: () => {
|
|
86
|
+
const isFromMousePress = Option.exists(model.maybeLastPointerType, Equal.equals('mouse'));
|
|
87
|
+
if (isFromMousePress) {
|
|
88
|
+
return __foldkitBrandViewResult(([
|
|
89
|
+
evo(model, {
|
|
90
|
+
maybeLastPointerType: () => __foldkitBrandViewResult((Option.none()), "@foldkit/ui/tooltip/tooltip.js#maybeLastPointerType"),
|
|
91
|
+
}),
|
|
92
|
+
[],
|
|
93
|
+
]), "@foldkit/ui/tooltip/tooltip.js#FocusedTrigger");
|
|
94
|
+
}
|
|
95
|
+
if (model.isDismissed) {
|
|
96
|
+
return __foldkitBrandViewResult(([
|
|
97
|
+
evo(model, {
|
|
98
|
+
isFocused: () => __foldkitBrandViewResult((true), "@foldkit/ui/tooltip/tooltip.js#isFocused"),
|
|
99
|
+
maybeLastPointerType: () => __foldkitBrandViewResult((Option.none()), "@foldkit/ui/tooltip/tooltip.js#maybeLastPointerType~2"),
|
|
100
|
+
}),
|
|
101
|
+
[],
|
|
102
|
+
]), "@foldkit/ui/tooltip/tooltip.js#FocusedTrigger");
|
|
103
|
+
}
|
|
104
|
+
return __foldkitBrandViewResult(([
|
|
105
|
+
evo(model, {
|
|
106
|
+
isFocused: () => __foldkitBrandViewResult((true), "@foldkit/ui/tooltip/tooltip.js#isFocused~2"),
|
|
107
|
+
isOpen: () => __foldkitBrandViewResult((true), "@foldkit/ui/tooltip/tooltip.js#isOpen~2"),
|
|
108
|
+
pendingShowVersion: Number.increment,
|
|
109
|
+
}),
|
|
110
|
+
[],
|
|
111
|
+
]), "@foldkit/ui/tooltip/tooltip.js#FocusedTrigger");
|
|
112
|
+
},
|
|
113
|
+
BlurredTrigger: () => __foldkitBrandViewResult(([
|
|
114
|
+
evo(model, {
|
|
115
|
+
isFocused: () => __foldkitBrandViewResult((false), "@foldkit/ui/tooltip/tooltip.js#isFocused~3"),
|
|
116
|
+
isOpen: () => __foldkitBrandViewResult((model.isHovered && model.isOpen), "@foldkit/ui/tooltip/tooltip.js#isOpen~3"),
|
|
117
|
+
isDismissed: () => __foldkitBrandViewResult((false), "@foldkit/ui/tooltip/tooltip.js#isDismissed~2"),
|
|
118
|
+
pendingShowVersion: Number.increment,
|
|
119
|
+
maybeLastPointerType: () => __foldkitBrandViewResult((Option.none()), "@foldkit/ui/tooltip/tooltip.js#maybeLastPointerType~3"),
|
|
120
|
+
}),
|
|
121
|
+
[],
|
|
122
|
+
]), "@foldkit/ui/tooltip/tooltip.js#BlurredTrigger"),
|
|
123
|
+
PressedEscape: () => __foldkitBrandViewResult(([
|
|
124
|
+
evo(model, {
|
|
125
|
+
isOpen: () => __foldkitBrandViewResult((false), "@foldkit/ui/tooltip/tooltip.js#isOpen~4"),
|
|
126
|
+
isDismissed: () => __foldkitBrandViewResult((true), "@foldkit/ui/tooltip/tooltip.js#isDismissed~3"),
|
|
127
|
+
pendingShowVersion: Number.increment,
|
|
128
|
+
}),
|
|
129
|
+
[],
|
|
130
|
+
]), "@foldkit/ui/tooltip/tooltip.js#PressedEscape"),
|
|
131
|
+
PressedPointerOnTrigger: ({ pointerType }) => __foldkitBrandViewResult(([
|
|
132
|
+
evo(model, {
|
|
133
|
+
maybeLastPointerType: () => __foldkitBrandViewResult((Option.some(pointerType)), "@foldkit/ui/tooltip/tooltip.js#maybeLastPointerType~4"),
|
|
134
|
+
}),
|
|
135
|
+
[],
|
|
136
|
+
]), "@foldkit/ui/tooltip/tooltip.js#PressedPointerOnTrigger"),
|
|
137
|
+
CompletedWaitBeforeShowing: ({ version }) => {
|
|
138
|
+
if (version !== model.pendingShowVersion) {
|
|
139
|
+
return __foldkitBrandViewResult(([model, []]), "@foldkit/ui/tooltip/tooltip.js#CompletedWaitBeforeShowing");
|
|
140
|
+
}
|
|
141
|
+
if (!model.isHovered) {
|
|
142
|
+
return __foldkitBrandViewResult(([model, []]), "@foldkit/ui/tooltip/tooltip.js#CompletedWaitBeforeShowing");
|
|
143
|
+
}
|
|
144
|
+
return __foldkitBrandViewResult(([evo(model, { isOpen: () => __foldkitBrandViewResult((true), "@foldkit/ui/tooltip/tooltip.js#isOpen~5") }), []]), "@foldkit/ui/tooltip/tooltip.js#CompletedWaitBeforeShowing");
|
|
145
|
+
},
|
|
146
|
+
CompletedAnchorTooltip: () => __foldkitBrandViewResult(([model, []]), "@foldkit/ui/tooltip/tooltip.js#CompletedAnchorTooltip"),
|
|
147
|
+
}))), "@foldkit/ui/tooltip/tooltip.js#computeUpdate");
|
|
148
|
+
const toMaybeVisibilityOutMessage = (isOpen, isNextOpen) => {
|
|
149
|
+
if (!isOpen && isNextOpen) {
|
|
150
|
+
return __foldkitBrandViewResult((Option.some(Shown())), "@foldkit/ui/tooltip/tooltip.js#toMaybeVisibilityOutMessage");
|
|
151
|
+
}
|
|
152
|
+
else if (isOpen && !isNextOpen) {
|
|
153
|
+
return __foldkitBrandViewResult((Option.some(Hidden())), "@foldkit/ui/tooltip/tooltip.js#toMaybeVisibilityOutMessage");
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
return __foldkitBrandViewResult((Option.none()), "@foldkit/ui/tooltip/tooltip.js#toMaybeVisibilityOutMessage");
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
/** Processes a tooltip message and returns the next model, commands, and
|
|
160
|
+
* an optional OutMessage. `Shown`/`Hidden` fire only on `isOpen`
|
|
161
|
+
* transitions, so consumers don't get spurious events for messages that
|
|
162
|
+
* only update hover/focus/delay state without changing visibility. */
|
|
163
|
+
export const update = (model, message) => {
|
|
164
|
+
const [nextModel, commands] = computeUpdate(model, message);
|
|
165
|
+
const maybeOutMessage = toMaybeVisibilityOutMessage(model.isOpen, nextModel.isOpen);
|
|
166
|
+
return __foldkitBrandViewResult(([nextModel, commands, maybeOutMessage]), "@foldkit/ui/tooltip/tooltip.js#update");
|
|
167
|
+
};
|
|
168
|
+
/** Reflects an externally-sourced hover show-delay onto the model without
|
|
169
|
+
* emitting an OutMessage. Use to mirror an external config value (a user
|
|
170
|
+
* preference, a restored setting) onto the tooltip. */
|
|
171
|
+
export const reflectShowDelay = Function.dual(2, (model, showDelay) => __foldkitBrandViewResult((evo(model, { showDelay: () => __foldkitBrandViewResult((Duration.fromInputUnsafe(showDelay)), "@foldkit/ui/tooltip/tooltip.js#showDelay") })), "@foldkit/ui/tooltip/tooltip.js#anonymous~6"));
|
|
172
|
+
/** Renders a headless tooltip with an anchored non-interactive panel.
|
|
173
|
+
* Shows on hover (after delay) or focus (from keyboard, touch, or pen;
|
|
174
|
+
* mouse-click focus is excluded). Hides on leave, blur, or Escape. */
|
|
175
|
+
export const view = defineView((model, viewInputs, h) => {
|
|
176
|
+
const { id, isOpen } = model;
|
|
177
|
+
const { anchor, toView, isDisabled, ariaLabel, ariaLabelledBy } = viewInputs;
|
|
178
|
+
const resolveTriggerLabel = () => {
|
|
179
|
+
if (Predicate.isNotUndefined(ariaLabel)) {
|
|
180
|
+
return __foldkitBrandViewResult(([h.AriaLabel(ariaLabel)]), "@foldkit/ui/tooltip/tooltip.js#resolveTriggerLabel");
|
|
181
|
+
}
|
|
182
|
+
else if (Predicate.isNotUndefined(ariaLabelledBy)) {
|
|
183
|
+
return __foldkitBrandViewResult(([h.AriaLabelledBy(ariaLabelledBy)]), "@foldkit/ui/tooltip/tooltip.js#resolveTriggerLabel");
|
|
184
|
+
}
|
|
185
|
+
else {
|
|
186
|
+
return __foldkitBrandViewResult(([]), "@foldkit/ui/tooltip/tooltip.js#resolveTriggerLabel");
|
|
187
|
+
}
|
|
188
|
+
};
|
|
189
|
+
const triggerLabelAttributes = resolveTriggerLabel();
|
|
190
|
+
const handleTriggerKeyDown = (key) => __foldkitBrandViewResult((M.value(key).pipe(M.when('Escape', () => __foldkitBrandViewResult((OptionExt.when(isOpen, PressedEscape())), "@foldkit/ui/tooltip/tooltip.js#anonymous~8")), M.orElse(() => __foldkitBrandViewResult((Option.none()), "@foldkit/ui/tooltip/tooltip.js#anonymous~9")))), "@foldkit/ui/tooltip/tooltip.js#handleTriggerKeyDown");
|
|
191
|
+
const handleTriggerPointerDown = (pointerType) => __foldkitBrandViewResult((Option.some(PressedPointerOnTrigger({ pointerType }))), "@foldkit/ui/tooltip/tooltip.js#handleTriggerPointerDown");
|
|
192
|
+
const triggerAttributes = [
|
|
193
|
+
h.Id(triggerId(id)),
|
|
194
|
+
h.Type('button'),
|
|
195
|
+
h.AriaDescribedBy(panelId(id)),
|
|
196
|
+
...triggerLabelAttributes,
|
|
197
|
+
...(isOpen ? [h.DataAttribute('open', '')] : []),
|
|
198
|
+
...(isDisabled
|
|
199
|
+
? [h.AriaDisabled(true), h.DataAttribute('disabled', '')]
|
|
200
|
+
: [
|
|
201
|
+
h.OnMouseEnter(EnteredTrigger()),
|
|
202
|
+
h.OnMouseLeave(LeftTrigger()),
|
|
203
|
+
h.OnFocus(FocusedTrigger()),
|
|
204
|
+
h.OnBlur(BlurredTrigger()),
|
|
205
|
+
h.OnKeyDownPreventDefault(handleTriggerKeyDown),
|
|
206
|
+
h.OnPointerDown(handleTriggerPointerDown),
|
|
207
|
+
]),
|
|
208
|
+
];
|
|
209
|
+
const panelAttributes = [
|
|
210
|
+
h.Id(panelId(id)),
|
|
211
|
+
h.Role('tooltip'),
|
|
212
|
+
h.Style({
|
|
213
|
+
position: 'absolute',
|
|
214
|
+
margin: '0',
|
|
215
|
+
visibility: 'hidden',
|
|
216
|
+
pointerEvents: 'none',
|
|
217
|
+
}),
|
|
218
|
+
h.OnMount(AnchorTooltip({ buttonId: triggerId(id), anchor })),
|
|
219
|
+
...(isOpen ? [h.DataAttribute('open', '')] : []),
|
|
220
|
+
];
|
|
221
|
+
return __foldkitBrandViewResult((toView({
|
|
222
|
+
trigger: childAttributes(triggerAttributes),
|
|
223
|
+
panel: childAttributes(panelAttributes),
|
|
224
|
+
isVisible: isOpen,
|
|
225
|
+
})), "@foldkit/ui/tooltip/tooltip.js#anonymous~7");
|
|
226
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@foldkit/ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.137.0",
|
|
4
4
|
"description": "Headless, accessible UI components for Foldkit",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -128,7 +128,7 @@
|
|
|
128
128
|
"typescript": "^6.0.3",
|
|
129
129
|
"vitest": "^4.1.9",
|
|
130
130
|
"@foldkit/vite-plugin": "0.11.3",
|
|
131
|
-
"foldkit": "0.
|
|
131
|
+
"foldkit": "0.137.0"
|
|
132
132
|
},
|
|
133
133
|
"keywords": [
|
|
134
134
|
"foldkit",
|