@typed/ui 1.0.0-beta.0 → 1.0.0-beta.10
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/LICENSE +21 -0
- package/README.md +78 -26
- package/dist/Alert.d.ts +72 -0
- package/dist/Alert.d.ts.map +1 -0
- package/dist/Alert.js +40 -0
- package/dist/Button.d.ts +100 -0
- package/dist/Button.d.ts.map +1 -0
- package/dist/Button.js +42 -0
- package/dist/Carousel.d.ts +346 -0
- package/dist/Carousel.d.ts.map +1 -0
- package/dist/Carousel.js +264 -0
- package/dist/Checkbox.d.ts +168 -0
- package/dist/Checkbox.d.ts.map +1 -0
- package/dist/Checkbox.js +146 -0
- package/dist/Collection.d.ts +254 -0
- package/dist/Collection.d.ts.map +1 -0
- package/dist/Collection.js +218 -0
- package/dist/Combobox.d.ts +367 -0
- package/dist/Combobox.d.ts.map +1 -0
- package/dist/Combobox.js +300 -0
- package/dist/Composite.d.ts +823 -0
- package/dist/Composite.d.ts.map +1 -0
- package/dist/Composite.js +615 -0
- package/dist/Dialog.d.ts +544 -0
- package/dist/Dialog.d.ts.map +1 -0
- package/dist/Dialog.js +357 -0
- package/dist/Disclosure.d.ts +219 -0
- package/dist/Disclosure.d.ts.map +1 -0
- package/dist/Disclosure.js +128 -0
- package/dist/Dom/Events.d.ts +122 -0
- package/dist/Dom/Events.d.ts.map +1 -0
- package/dist/Dom/Events.js +192 -0
- package/dist/Dom/Props.d.ts +161 -0
- package/dist/Dom/Props.d.ts.map +1 -0
- package/dist/Dom/Props.js +110 -0
- package/dist/Dom/Refs.d.ts +58 -0
- package/dist/Dom/Refs.d.ts.map +1 -0
- package/dist/Dom/Refs.js +61 -0
- package/dist/Dom/Render.d.ts +59 -0
- package/dist/Dom/Render.d.ts.map +1 -0
- package/dist/Dom/Render.js +71 -0
- package/dist/Dom/Types.d.ts +570 -0
- package/dist/Dom/Types.d.ts.map +1 -0
- package/dist/Dom/Types.js +1 -0
- package/dist/Dom/index.d.ts +20 -0
- package/dist/Dom/index.d.ts.map +1 -0
- package/dist/Dom/index.js +8 -0
- package/dist/Dom.d.ts +14 -0
- package/dist/Dom.d.ts.map +1 -0
- package/dist/Dom.js +13 -0
- package/dist/Focusable.d.ts +85 -0
- package/dist/Focusable.d.ts.map +1 -0
- package/dist/Focusable.js +35 -0
- package/dist/Form.d.ts +1727 -0
- package/dist/Form.d.ts.map +1 -0
- package/dist/Form.js +1142 -0
- package/dist/Grid.d.ts +388 -0
- package/dist/Grid.d.ts.map +1 -0
- package/dist/Grid.js +284 -0
- package/dist/Group.d.ts +128 -0
- package/dist/Group.d.ts.map +1 -0
- package/dist/Group.js +71 -0
- package/dist/Heading.d.ts +87 -0
- package/dist/Heading.d.ts.map +1 -0
- package/dist/Heading.js +58 -0
- package/dist/Hovercard.d.ts +297 -0
- package/dist/Hovercard.d.ts.map +1 -0
- package/dist/Hovercard.js +188 -0
- package/dist/HttpRouter.d.ts +129 -6
- package/dist/HttpRouter.d.ts.map +1 -1
- package/dist/HttpRouter.js +199 -56
- package/dist/Link.d.ts +63 -28
- package/dist/Link.d.ts.map +1 -1
- package/dist/Link.js +84 -37
- package/dist/Listbox.d.ts +305 -0
- package/dist/Listbox.d.ts.map +1 -0
- package/dist/Listbox.js +245 -0
- package/dist/Menu.d.ts +663 -0
- package/dist/Menu.d.ts.map +1 -0
- package/dist/Menu.js +569 -0
- package/dist/Menubar.d.ts +249 -0
- package/dist/Menubar.d.ts.map +1 -0
- package/dist/Menubar.js +207 -0
- package/dist/Meter.d.ts +157 -0
- package/dist/Meter.d.ts.map +1 -0
- package/dist/Meter.js +87 -0
- package/dist/NativeDetails.d.ts +41 -0
- package/dist/NativeDetails.d.ts.map +1 -0
- package/dist/NativeDetails.js +40 -0
- package/dist/NativeDialog.d.ts +66 -0
- package/dist/NativeDialog.d.ts.map +1 -0
- package/dist/NativeDialog.js +88 -0
- package/dist/NativePopover.d.ts +43 -0
- package/dist/NativePopover.d.ts.map +1 -0
- package/dist/NativePopover.js +84 -0
- package/dist/Popover.d.ts +240 -0
- package/dist/Popover.d.ts.map +1 -0
- package/dist/Popover.js +140 -0
- package/dist/RadioGroup.d.ts +330 -0
- package/dist/RadioGroup.d.ts.map +1 -0
- package/dist/RadioGroup.js +241 -0
- package/dist/Role.d.ts +64 -0
- package/dist/Role.d.ts.map +1 -0
- package/dist/Role.js +27 -0
- package/dist/Select.d.ts +418 -0
- package/dist/Select.d.ts.map +1 -0
- package/dist/Select.js +357 -0
- package/dist/Separator.d.ts +58 -0
- package/dist/Separator.d.ts.map +1 -0
- package/dist/Separator.js +32 -0
- package/dist/Slider.d.ts +141 -0
- package/dist/Slider.d.ts.map +1 -0
- package/dist/Slider.js +101 -0
- package/dist/SpinButton.d.ts +141 -0
- package/dist/SpinButton.d.ts.map +1 -0
- package/dist/SpinButton.js +101 -0
- package/dist/Storybook.d.ts +76 -0
- package/dist/Storybook.d.ts.map +1 -0
- package/dist/Storybook.js +102 -0
- package/dist/Switch.d.ts +148 -0
- package/dist/Switch.d.ts.map +1 -0
- package/dist/Switch.js +110 -0
- package/dist/Tab.d.ts +26 -0
- package/dist/Tab.d.ts.map +1 -0
- package/dist/Tab.js +25 -0
- package/dist/Tabs.d.ts +411 -0
- package/dist/Tabs.d.ts.map +1 -0
- package/dist/Tabs.js +262 -0
- package/dist/Toolbar.d.ts +248 -0
- package/dist/Toolbar.d.ts.map +1 -0
- package/dist/Toolbar.js +187 -0
- package/dist/Tooltip.d.ts +296 -0
- package/dist/Tooltip.d.ts.map +1 -0
- package/dist/Tooltip.js +172 -0
- package/dist/Tree.d.ts +405 -0
- package/dist/Tree.d.ts.map +1 -0
- package/dist/Tree.js +333 -0
- package/dist/TreeGrid.d.ts +426 -0
- package/dist/TreeGrid.d.ts.map +1 -0
- package/dist/TreeGrid.js +308 -0
- package/dist/VisuallyHidden.d.ts +68 -0
- package/dist/VisuallyHidden.d.ts.map +1 -0
- package/dist/VisuallyHidden.js +44 -0
- package/dist/WindowSplitter.d.ts +336 -0
- package/dist/WindowSplitter.d.ts.map +1 -0
- package/dist/WindowSplitter.js +305 -0
- package/dist/index.d.ts +48 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +48 -0
- package/package.json +47 -14
- package/src/HttpRouter.test.ts +0 -294
- package/src/HttpRouter.ts +0 -168
- package/src/Link.test.ts +0 -85
- package/src/Link.ts +0 -107
- package/src/index.ts +0 -2
- package/tsconfig.json +0 -6
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Carousel state keeps the active slide and rotation pause policy outside the renderer. Root
|
|
3
|
+
* pauses rotation on focus and pointer entry; slides retain DOM identity while hidden; controls
|
|
4
|
+
* use native button clicks.
|
|
5
|
+
*
|
|
6
|
+
* @remarks
|
|
7
|
+
* The module keeps policy, state transitions, and DOM rendering separable so applications can use
|
|
8
|
+
* the state and pure operations without mounting UI, or supply custom hosts without replacing native
|
|
9
|
+
* events and browser-owned focus.
|
|
10
|
+
*
|
|
11
|
+
* Learn the interaction in the [Carousel guide](/explore/ui-carousel).
|
|
12
|
+
*
|
|
13
|
+
* @since 1.0.0
|
|
14
|
+
* @category modules
|
|
15
|
+
* @packageDocumentation
|
|
16
|
+
*/
|
|
17
|
+
import * as Effect from "effect/Effect";
|
|
18
|
+
import type * as Scope from "effect/Scope";
|
|
19
|
+
import * as Schema from "effect/Schema";
|
|
20
|
+
import type { Fx } from "@typed/fx/Fx";
|
|
21
|
+
import { RefSubject } from "@typed/fx";
|
|
22
|
+
import { type Renderable, type RenderEvent, type RenderTemplate } from "@typed/template";
|
|
23
|
+
import * as Collection from "./Collection.js";
|
|
24
|
+
import * as Dom from "./Dom.js";
|
|
25
|
+
import type { HostResult } from "./Dom/Types.js";
|
|
26
|
+
/**
|
|
27
|
+
* The visible slide identity and explicit paused flag.
|
|
28
|
+
* Changing `paused` does not start a timer; an application scheduler must honor the flag.
|
|
29
|
+
*
|
|
30
|
+
* @since 1.0.0
|
|
31
|
+
* @category Slide and rotation state
|
|
32
|
+
*/
|
|
33
|
+
export interface State {
|
|
34
|
+
/**
|
|
35
|
+
* Id currently active for keyboard navigation; null means no active item.
|
|
36
|
+
* @since 1.0.0
|
|
37
|
+
* @category Keyboard focus
|
|
38
|
+
*/
|
|
39
|
+
readonly activeId: string;
|
|
40
|
+
/**
|
|
41
|
+
* Whether automatic carousel rotation is suspended.
|
|
42
|
+
* @since 1.0.0
|
|
43
|
+
* @category Rotation policy
|
|
44
|
+
*/
|
|
45
|
+
readonly paused: boolean;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Initial Carousel values. activeId is required and paused defaults to true.
|
|
49
|
+
*
|
|
50
|
+
* @since 1.0.0
|
|
51
|
+
* @category Slide and rotation state
|
|
52
|
+
*/
|
|
53
|
+
export interface InitialState {
|
|
54
|
+
/**
|
|
55
|
+
* Id currently active for keyboard navigation; null means no active item.
|
|
56
|
+
* @since 1.0.0
|
|
57
|
+
* @category Keyboard focus
|
|
58
|
+
*/
|
|
59
|
+
readonly activeId: string;
|
|
60
|
+
/**
|
|
61
|
+
* Whether automatic carousel rotation is suspended.
|
|
62
|
+
* @since 1.0.0
|
|
63
|
+
* @category Rotation policy
|
|
64
|
+
*/
|
|
65
|
+
readonly paused?: boolean;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Effect Schema used by makeState to encode, decode, and hydrate Carousel state.
|
|
69
|
+
*
|
|
70
|
+
* @remarks
|
|
71
|
+
* @example
|
|
72
|
+
* ```ts
|
|
73
|
+
* import * as Schema from "effect/Schema";
|
|
74
|
+
* import * as Carousel from "@typed/ui/Carousel";
|
|
75
|
+
*
|
|
76
|
+
* const decodeState = Schema.decodeUnknownEffect(Carousel.StateSchema);
|
|
77
|
+
* ```
|
|
78
|
+
* @since 1.0.0
|
|
79
|
+
* @category Slide and rotation state
|
|
80
|
+
*/
|
|
81
|
+
export declare const StateSchema: Schema.Struct<{
|
|
82
|
+
readonly activeId: Schema.String;
|
|
83
|
+
readonly paused: Schema.Boolean;
|
|
84
|
+
}>;
|
|
85
|
+
/**
|
|
86
|
+
* Creates hydrated Carousel state. activeId is required and paused defaults to true.
|
|
87
|
+
*
|
|
88
|
+
* @remarks
|
|
89
|
+
* The returned Effect creates the RefSubject when run. That state is renderer-independent;
|
|
90
|
+
* collection registrations belong to the separate Scope that runs register or ref, not to state
|
|
91
|
+
* creation.
|
|
92
|
+
*
|
|
93
|
+
* @example
|
|
94
|
+
* ```ts
|
|
95
|
+
* import * as Effect from "effect/Effect";
|
|
96
|
+
* import * as Carousel from "@typed/ui/Carousel";
|
|
97
|
+
*
|
|
98
|
+
* const program = Effect.scoped(
|
|
99
|
+
* Effect.gen(function* () {
|
|
100
|
+
* const state = yield* Carousel.makeState({ activeId: "slide-1" });
|
|
101
|
+
* const collection = yield* Carousel.makeCollection();
|
|
102
|
+
* return { state: yield* state, collection: yield* collection };
|
|
103
|
+
* }),
|
|
104
|
+
* );
|
|
105
|
+
* ```
|
|
106
|
+
* @since 1.0.0
|
|
107
|
+
* @category Slide and rotation state
|
|
108
|
+
*/
|
|
109
|
+
export declare function makeState(initial: InitialState): Effect.Effect<RefSubject.HydratedRefSubject<{
|
|
110
|
+
readonly activeId: string;
|
|
111
|
+
readonly paused: boolean;
|
|
112
|
+
}, Schema.SchemaError, never, never>, never, Scope.Scope>;
|
|
113
|
+
/**
|
|
114
|
+
* Creates a scoped Collection for Carousel items.
|
|
115
|
+
*
|
|
116
|
+
* @remarks
|
|
117
|
+
* The returned Effect allocates the RefSubject in the caller's Scope. Each later registration is
|
|
118
|
+
* owned by the Scope that runs register, independently of this construction Effect.
|
|
119
|
+
*
|
|
120
|
+
* @example
|
|
121
|
+
* ```ts
|
|
122
|
+
* import * as Effect from "effect/Effect";
|
|
123
|
+
* import * as Carousel from "@typed/ui/Carousel";
|
|
124
|
+
*
|
|
125
|
+
* const program = Effect.scoped(
|
|
126
|
+
* Effect.gen(function* () {
|
|
127
|
+
* const collection = yield* Carousel.makeCollection();
|
|
128
|
+
* return yield* collection;
|
|
129
|
+
* }),
|
|
130
|
+
* );
|
|
131
|
+
* ```
|
|
132
|
+
* @since 1.0.0
|
|
133
|
+
* @category Slide registration
|
|
134
|
+
*/
|
|
135
|
+
export declare const makeCollection: (initial?: Collection.State<string, Element>) => Effect.Effect<RefSubject.RefSubject<Collection.State<string, Element>, never, never>, never, Scope.Scope>;
|
|
136
|
+
/**
|
|
137
|
+
* Sets activeId without changing paused state.
|
|
138
|
+
*
|
|
139
|
+
* @remarks
|
|
140
|
+
* The operation exposes Carousel's transition directly so callers can compose it in Effect
|
|
141
|
+
* programs and native event handlers.
|
|
142
|
+
*
|
|
143
|
+
* @since 1.0.0
|
|
144
|
+
* @category Slide navigation
|
|
145
|
+
*/
|
|
146
|
+
export declare function select<E, R>(state: RefSubject.RefSubject<State, E, R>, activeId: string): Effect.Effect<State, E, R>;
|
|
147
|
+
/**
|
|
148
|
+
* Selects the previous or next enabled registered slide; movement wraps and leaves state unchanged
|
|
149
|
+
* for an empty collection.
|
|
150
|
+
*
|
|
151
|
+
* @remarks
|
|
152
|
+
* The operation exposes Carousel's transition directly so callers can compose it in Effect
|
|
153
|
+
* programs and native event handlers.
|
|
154
|
+
*
|
|
155
|
+
* @since 1.0.0
|
|
156
|
+
* @category Slide navigation
|
|
157
|
+
*/
|
|
158
|
+
export declare function move<E, R, E2, R2>(state: RefSubject.RefSubject<State, E, R>, collection: RefSubject.RefSubject<Collection.State<string>, E2, R2>, direction: "next" | "previous"): Effect.Effect<State, E | E2, R | R2>;
|
|
159
|
+
/**
|
|
160
|
+
* Flips paused and preserves activeId.
|
|
161
|
+
*
|
|
162
|
+
* @remarks
|
|
163
|
+
* The operation exposes Carousel's transition directly so callers can compose it in Effect
|
|
164
|
+
* programs and native event handlers.
|
|
165
|
+
*
|
|
166
|
+
* @since 1.0.0
|
|
167
|
+
* @category Rotation policy
|
|
168
|
+
*/
|
|
169
|
+
export declare function toggleRotation<E, R>(state: RefSubject.RefSubject<State, E, R>): Effect.Effect<State, E, R>;
|
|
170
|
+
/**
|
|
171
|
+
* Inputs accepted by Carousel.Root in addition to the shared DOM host options.
|
|
172
|
+
*
|
|
173
|
+
* @since 1.0.0
|
|
174
|
+
* @category Carousel region
|
|
175
|
+
*/
|
|
176
|
+
export interface RootOptions extends Dom.HostOptions<HTMLDivElement> {
|
|
177
|
+
/**
|
|
178
|
+
* Renderer-independent RefSubject state consumed by this component or operation.
|
|
179
|
+
* @since 1.0.0
|
|
180
|
+
* @category State connection
|
|
181
|
+
*/
|
|
182
|
+
readonly state: RefSubject.HydratedRefSubject<State, Schema.SchemaError>;
|
|
183
|
+
/**
|
|
184
|
+
* Renderable child content for the component host.
|
|
185
|
+
* @since 1.0.0
|
|
186
|
+
* @category Rendered content
|
|
187
|
+
*/
|
|
188
|
+
readonly content: Renderable.Any;
|
|
189
|
+
/**
|
|
190
|
+
* Accessible label rendered through aria-label.
|
|
191
|
+
* @since 1.0.0
|
|
192
|
+
* @category Accessible naming
|
|
193
|
+
*/
|
|
194
|
+
readonly label: Renderable.Any<string | null | undefined>;
|
|
195
|
+
}
|
|
196
|
+
declare function rootInternalProps<const Options extends RootOptions>(options: Options): ({ property }: Dom.InternalPropsHelpers<Options>) => {
|
|
197
|
+
readonly role: "region";
|
|
198
|
+
readonly "aria-roledescription": "carousel";
|
|
199
|
+
readonly "aria-label": Exclude<Dom.Property<Options, "label">, Dom.Nullish> | undefined;
|
|
200
|
+
readonly onfocusin: Effect.Effect<State, Schema.SchemaError, never>;
|
|
201
|
+
readonly onmouseenter: Effect.Effect<State, Schema.SchemaError, never>;
|
|
202
|
+
readonly onmouseleave: Effect.Effect<void, Schema.SchemaError, never>;
|
|
203
|
+
readonly ref: RefSubject.HydratedRefSubject<State, Schema.SchemaError, never, never>;
|
|
204
|
+
};
|
|
205
|
+
type RootInternalProps<Options extends RootOptions> = ReturnType<ReturnType<typeof rootInternalProps<Options>>>;
|
|
206
|
+
/**
|
|
207
|
+
* Renders the carousel region and pauses automatic rotation on focus or pointer entry without
|
|
208
|
+
* replacing its child nodes.
|
|
209
|
+
*
|
|
210
|
+
* @remarks
|
|
211
|
+
* The returned Fx installs DOM refs, native listeners, state subscriptions, and optional
|
|
212
|
+
* collection registrations only when rendered. The rendering Scope removes those resources;
|
|
213
|
+
* unrelated nodes and attributes remain caller-owned.
|
|
214
|
+
*
|
|
215
|
+
* @since 1.0.0
|
|
216
|
+
* @category Carousel region
|
|
217
|
+
*/
|
|
218
|
+
export declare function Root<const Options extends RootOptions, const Host extends HostResult = never>(options: Options, host?: Dom.HostOverride<Dom.RenderHostProps<Options, RootInternalProps<Options>>, Options["content"], Host>): Fx<RenderEvent, Renderable.Error<Options | Host>, Renderable.Services<Options | Host> | Scope.Scope | RenderTemplate>;
|
|
219
|
+
/**
|
|
220
|
+
* Inputs accepted by Carousel.Slide in addition to the shared DOM host options.
|
|
221
|
+
*
|
|
222
|
+
* @since 1.0.0
|
|
223
|
+
* @category Slide content
|
|
224
|
+
*/
|
|
225
|
+
export interface SlideOptions extends Dom.HostOptions<HTMLDivElement> {
|
|
226
|
+
/**
|
|
227
|
+
* Renderer-independent RefSubject state consumed by this component or operation.
|
|
228
|
+
* @since 1.0.0
|
|
229
|
+
* @category State connection
|
|
230
|
+
*/
|
|
231
|
+
readonly state: RefSubject.HydratedRefSubject<State, Schema.SchemaError>;
|
|
232
|
+
/**
|
|
233
|
+
* Item registry used for collection-driven keyboard behavior and mounted ordering.
|
|
234
|
+
* @since 1.0.0
|
|
235
|
+
* @category Item registration
|
|
236
|
+
*/
|
|
237
|
+
readonly collection?: RefSubject.RefSubject<Collection.State<string>>;
|
|
238
|
+
/**
|
|
239
|
+
* Stable id used for collection identity and ARIA relationships.
|
|
240
|
+
* @since 1.0.0
|
|
241
|
+
* @category Identity and relationships
|
|
242
|
+
*/
|
|
243
|
+
readonly id: string;
|
|
244
|
+
/**
|
|
245
|
+
* Accessible label rendered through aria-label.
|
|
246
|
+
* @since 1.0.0
|
|
247
|
+
* @category Accessible naming
|
|
248
|
+
*/
|
|
249
|
+
readonly label: Renderable.Any<string | null | undefined>;
|
|
250
|
+
/**
|
|
251
|
+
* Renderable child content for the component host.
|
|
252
|
+
* @since 1.0.0
|
|
253
|
+
* @category Rendered content
|
|
254
|
+
*/
|
|
255
|
+
readonly content: Renderable.Any;
|
|
256
|
+
}
|
|
257
|
+
declare function slideInternalProps<const Options extends SlideOptions>(options: Options): ({ property }: Dom.InternalPropsHelpers<Options>) => {
|
|
258
|
+
readonly id: string;
|
|
259
|
+
readonly role: "group";
|
|
260
|
+
readonly "aria-roledescription": "slide";
|
|
261
|
+
readonly "aria-label": Exclude<Dom.Property<Options, "label">, Dom.Nullish> | undefined;
|
|
262
|
+
readonly "?hidden": RefSubject.Computed<boolean, Schema.SchemaError, never>;
|
|
263
|
+
readonly ref: ((element: Element) => Effect.Effect<void, never, Scope.Scope>) | undefined;
|
|
264
|
+
};
|
|
265
|
+
type SlideInternalProps<Options extends SlideOptions> = ReturnType<ReturnType<typeof slideInternalProps<Options>>>;
|
|
266
|
+
/**
|
|
267
|
+
* Renders one labelled slide, registers it when a collection is supplied, and toggles hidden from
|
|
268
|
+
* activeId.
|
|
269
|
+
*
|
|
270
|
+
* @remarks
|
|
271
|
+
* The returned Fx installs DOM refs, native listeners, state subscriptions, and optional
|
|
272
|
+
* collection registrations only when rendered. The rendering Scope removes those resources;
|
|
273
|
+
* unrelated nodes and attributes remain caller-owned.
|
|
274
|
+
*
|
|
275
|
+
* @since 1.0.0
|
|
276
|
+
* @category Slide content
|
|
277
|
+
*/
|
|
278
|
+
export declare function Slide<const Options extends SlideOptions, const Host extends HostResult = never>(options: Options, host?: Dom.HostOverride<Dom.RenderHostProps<Options, SlideInternalProps<Options>>, Options["content"], Host>): Fx<RenderEvent, Renderable.Error<Options | Host>, Renderable.Services<Options | Host> | Scope.Scope | RenderTemplate>;
|
|
279
|
+
/**
|
|
280
|
+
* Inputs accepted by Carousel.Control in addition to the shared DOM host options.
|
|
281
|
+
*
|
|
282
|
+
* @since 1.0.0
|
|
283
|
+
* @category Slide controls
|
|
284
|
+
*/
|
|
285
|
+
export interface ControlOptions extends Dom.HostOptions<HTMLButtonElement> {
|
|
286
|
+
/**
|
|
287
|
+
* Renderer-independent RefSubject state consumed by this component or operation.
|
|
288
|
+
* @since 1.0.0
|
|
289
|
+
* @category State connection
|
|
290
|
+
*/
|
|
291
|
+
readonly state: RefSubject.HydratedRefSubject<State, Schema.SchemaError>;
|
|
292
|
+
/**
|
|
293
|
+
* Item registry used for collection-driven keyboard behavior and mounted ordering.
|
|
294
|
+
* @since 1.0.0
|
|
295
|
+
* @category Item registration
|
|
296
|
+
*/
|
|
297
|
+
readonly collection?: RefSubject.RefSubject<Collection.State<string>>;
|
|
298
|
+
/**
|
|
299
|
+
* Renderable child content for the component host.
|
|
300
|
+
* @since 1.0.0
|
|
301
|
+
* @category Rendered content
|
|
302
|
+
*/
|
|
303
|
+
readonly content: Renderable.Any;
|
|
304
|
+
}
|
|
305
|
+
declare function controlInternalProps<const Options extends ControlOptions>(options: Options, action: Effect.Effect<unknown, Schema.SchemaError>): () => {
|
|
306
|
+
readonly type: "button";
|
|
307
|
+
readonly onclick: Effect.Effect<unknown, Schema.SchemaError, never>;
|
|
308
|
+
};
|
|
309
|
+
/**
|
|
310
|
+
* Renders a button whose native click selects the previous registered slide with wrapping enabled.
|
|
311
|
+
*
|
|
312
|
+
* @remarks
|
|
313
|
+
* The returned Fx installs DOM refs, native listeners, state subscriptions, and optional
|
|
314
|
+
* collection registrations only when rendered. The rendering Scope removes those resources;
|
|
315
|
+
* unrelated nodes and attributes remain caller-owned.
|
|
316
|
+
*
|
|
317
|
+
* @since 1.0.0
|
|
318
|
+
* @category Slide controls
|
|
319
|
+
*/
|
|
320
|
+
export declare function Previous<const Options extends ControlOptions, const Host extends HostResult = never>(options: Options, host?: Dom.HostOverride<Dom.RenderHostProps<Options, ReturnType<ReturnType<typeof controlInternalProps<Options>>>>, Options["content"], Host>): import("./Dom/Types.js").HostComponent<Host | Options>;
|
|
321
|
+
/**
|
|
322
|
+
* Renders a button whose native click selects the next registered slide with wrapping enabled.
|
|
323
|
+
*
|
|
324
|
+
* @remarks
|
|
325
|
+
* The returned Fx installs DOM refs, native listeners, state subscriptions, and optional
|
|
326
|
+
* collection registrations only when rendered. The rendering Scope removes those resources;
|
|
327
|
+
* unrelated nodes and attributes remain caller-owned.
|
|
328
|
+
*
|
|
329
|
+
* @since 1.0.0
|
|
330
|
+
* @category Slide controls
|
|
331
|
+
*/
|
|
332
|
+
export declare function Next<const Options extends ControlOptions, const Host extends HostResult = never>(options: Options, host?: Dom.HostOverride<Dom.RenderHostProps<Options, ReturnType<ReturnType<typeof controlInternalProps<Options>>>>, Options["content"], Host>): import("./Dom/Types.js").HostComponent<Host | Options>;
|
|
333
|
+
/**
|
|
334
|
+
* Renders a button whose native click toggles the explicit paused state.
|
|
335
|
+
*
|
|
336
|
+
* @remarks
|
|
337
|
+
* The returned Fx installs DOM refs, native listeners, state subscriptions, and optional
|
|
338
|
+
* collection registrations only when rendered. The rendering Scope removes those resources;
|
|
339
|
+
* unrelated nodes and attributes remain caller-owned.
|
|
340
|
+
*
|
|
341
|
+
* @since 1.0.0
|
|
342
|
+
* @category Rotation policy
|
|
343
|
+
*/
|
|
344
|
+
export declare function RotationControl<const Options extends Omit<ControlOptions, "collection">, const Host extends HostResult = never>(options: Options, host?: Dom.HostOverride<Dom.RenderHostProps<Options, ReturnType<ReturnType<typeof controlInternalProps<Options>>>>, Options["content"], Host>): import("./Dom/Types.js").HostComponent<Host | Options>;
|
|
345
|
+
export {};
|
|
346
|
+
//# sourceMappingURL=Carousel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Carousel.d.ts","sourceRoot":"","sources":["../src/Carousel.ts"],"names":[],"mappings":"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"}
|
package/dist/Carousel.js
ADDED
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Carousel state keeps the active slide and rotation pause policy outside the renderer. Root
|
|
3
|
+
* pauses rotation on focus and pointer entry; slides retain DOM identity while hidden; controls
|
|
4
|
+
* use native button clicks.
|
|
5
|
+
*
|
|
6
|
+
* @remarks
|
|
7
|
+
* The module keeps policy, state transitions, and DOM rendering separable so applications can use
|
|
8
|
+
* the state and pure operations without mounting UI, or supply custom hosts without replacing native
|
|
9
|
+
* events and browser-owned focus.
|
|
10
|
+
*
|
|
11
|
+
* Learn the interaction in the [Carousel guide](/explore/ui-carousel).
|
|
12
|
+
*
|
|
13
|
+
* @since 1.0.0
|
|
14
|
+
* @category modules
|
|
15
|
+
* @packageDocumentation
|
|
16
|
+
*/
|
|
17
|
+
import * as Effect from "effect/Effect";
|
|
18
|
+
import * as Schema from "effect/Schema";
|
|
19
|
+
import { RefSubject } from "@typed/fx";
|
|
20
|
+
import { html } from "@typed/template";
|
|
21
|
+
import * as Collection from "./Collection.js";
|
|
22
|
+
import * as Composite from "./Composite.js";
|
|
23
|
+
import * as Dom from "./Dom.js";
|
|
24
|
+
/**
|
|
25
|
+
* Effect Schema used by makeState to encode, decode, and hydrate Carousel state.
|
|
26
|
+
*
|
|
27
|
+
* @remarks
|
|
28
|
+
* @example
|
|
29
|
+
* ```ts
|
|
30
|
+
* import * as Schema from "effect/Schema";
|
|
31
|
+
* import * as Carousel from "@typed/ui/Carousel";
|
|
32
|
+
*
|
|
33
|
+
* const decodeState = Schema.decodeUnknownEffect(Carousel.StateSchema);
|
|
34
|
+
* ```
|
|
35
|
+
* @since 1.0.0
|
|
36
|
+
* @category Slide and rotation state
|
|
37
|
+
*/
|
|
38
|
+
export const StateSchema = Schema.Struct({ activeId: Schema.String, paused: Schema.Boolean });
|
|
39
|
+
/**
|
|
40
|
+
* Creates hydrated Carousel state. activeId is required and paused defaults to true.
|
|
41
|
+
*
|
|
42
|
+
* @remarks
|
|
43
|
+
* The returned Effect creates the RefSubject when run. That state is renderer-independent;
|
|
44
|
+
* collection registrations belong to the separate Scope that runs register or ref, not to state
|
|
45
|
+
* creation.
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* ```ts
|
|
49
|
+
* import * as Effect from "effect/Effect";
|
|
50
|
+
* import * as Carousel from "@typed/ui/Carousel";
|
|
51
|
+
*
|
|
52
|
+
* const program = Effect.scoped(
|
|
53
|
+
* Effect.gen(function* () {
|
|
54
|
+
* const state = yield* Carousel.makeState({ activeId: "slide-1" });
|
|
55
|
+
* const collection = yield* Carousel.makeCollection();
|
|
56
|
+
* return { state: yield* state, collection: yield* collection };
|
|
57
|
+
* }),
|
|
58
|
+
* );
|
|
59
|
+
* ```
|
|
60
|
+
* @since 1.0.0
|
|
61
|
+
* @category Slide and rotation state
|
|
62
|
+
*/
|
|
63
|
+
export function makeState(initial) {
|
|
64
|
+
return RefSubject.hydrate(StateSchema, {
|
|
65
|
+
activeId: initial.activeId,
|
|
66
|
+
paused: initial.paused ?? true,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Creates a scoped Collection for Carousel items.
|
|
71
|
+
*
|
|
72
|
+
* @remarks
|
|
73
|
+
* The returned Effect allocates the RefSubject in the caller's Scope. Each later registration is
|
|
74
|
+
* owned by the Scope that runs register, independently of this construction Effect.
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* ```ts
|
|
78
|
+
* import * as Effect from "effect/Effect";
|
|
79
|
+
* import * as Carousel from "@typed/ui/Carousel";
|
|
80
|
+
*
|
|
81
|
+
* const program = Effect.scoped(
|
|
82
|
+
* Effect.gen(function* () {
|
|
83
|
+
* const collection = yield* Carousel.makeCollection();
|
|
84
|
+
* return yield* collection;
|
|
85
|
+
* }),
|
|
86
|
+
* );
|
|
87
|
+
* ```
|
|
88
|
+
* @since 1.0.0
|
|
89
|
+
* @category Slide registration
|
|
90
|
+
*/
|
|
91
|
+
export const makeCollection = Collection.makeState;
|
|
92
|
+
/**
|
|
93
|
+
* Sets activeId without changing paused state.
|
|
94
|
+
*
|
|
95
|
+
* @remarks
|
|
96
|
+
* The operation exposes Carousel's transition directly so callers can compose it in Effect
|
|
97
|
+
* programs and native event handlers.
|
|
98
|
+
*
|
|
99
|
+
* @since 1.0.0
|
|
100
|
+
* @category Slide navigation
|
|
101
|
+
*/
|
|
102
|
+
export function select(state, activeId) {
|
|
103
|
+
return RefSubject.update(state, (current) => ({ ...current, activeId }));
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Selects the previous or next enabled registered slide; movement wraps and leaves state unchanged
|
|
107
|
+
* for an empty collection.
|
|
108
|
+
*
|
|
109
|
+
* @remarks
|
|
110
|
+
* The operation exposes Carousel's transition directly so callers can compose it in Effect
|
|
111
|
+
* programs and native event handlers.
|
|
112
|
+
*
|
|
113
|
+
* @since 1.0.0
|
|
114
|
+
* @category Slide navigation
|
|
115
|
+
*/
|
|
116
|
+
export function move(state, collection, direction) {
|
|
117
|
+
return Effect.gen(function* () {
|
|
118
|
+
const next = Composite.moveActiveId(yield* collection, { activeId: (yield* state).activeId, loop: true }, direction);
|
|
119
|
+
return next === null ? yield* state : yield* select(state, next);
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Flips paused and preserves activeId.
|
|
124
|
+
*
|
|
125
|
+
* @remarks
|
|
126
|
+
* The operation exposes Carousel's transition directly so callers can compose it in Effect
|
|
127
|
+
* programs and native event handlers.
|
|
128
|
+
*
|
|
129
|
+
* @since 1.0.0
|
|
130
|
+
* @category Rotation policy
|
|
131
|
+
*/
|
|
132
|
+
export function toggleRotation(state) {
|
|
133
|
+
return RefSubject.update(state, (current) => ({ ...current, paused: !current.paused }));
|
|
134
|
+
}
|
|
135
|
+
function rootInternalProps(options) {
|
|
136
|
+
const pause = RefSubject.update(options.state, (current) => current.paused ? current : { ...current, paused: true });
|
|
137
|
+
let resumeOnPointerLeave = false;
|
|
138
|
+
const pauseForFocus = Effect.andThen(Effect.sync(() => {
|
|
139
|
+
resumeOnPointerLeave = false;
|
|
140
|
+
}), pause);
|
|
141
|
+
const pauseForPointer = Effect.flatMap(options.state, (current) => {
|
|
142
|
+
resumeOnPointerLeave = !current.paused;
|
|
143
|
+
return pause;
|
|
144
|
+
});
|
|
145
|
+
const resumeAfterPointer = Effect.suspend(() => {
|
|
146
|
+
if (!resumeOnPointerLeave)
|
|
147
|
+
return Effect.void;
|
|
148
|
+
resumeOnPointerLeave = false;
|
|
149
|
+
return RefSubject.update(options.state, (current) => current.paused ? { ...current, paused: false } : current);
|
|
150
|
+
});
|
|
151
|
+
return ({ property }) => ({
|
|
152
|
+
role: "region",
|
|
153
|
+
"aria-roledescription": "carousel",
|
|
154
|
+
"aria-label": property("label", undefined),
|
|
155
|
+
onfocusin: pauseForFocus,
|
|
156
|
+
onmouseenter: pauseForPointer,
|
|
157
|
+
onmouseleave: resumeAfterPointer,
|
|
158
|
+
ref: options.state,
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Renders the carousel region and pauses automatic rotation on focus or pointer entry without
|
|
163
|
+
* replacing its child nodes.
|
|
164
|
+
*
|
|
165
|
+
* @remarks
|
|
166
|
+
* The returned Fx installs DOM refs, native listeners, state subscriptions, and optional
|
|
167
|
+
* collection registrations only when rendered. The rendering Scope removes those resources;
|
|
168
|
+
* unrelated nodes and attributes remain caller-owned.
|
|
169
|
+
*
|
|
170
|
+
* @since 1.0.0
|
|
171
|
+
* @category Carousel region
|
|
172
|
+
*/
|
|
173
|
+
export function Root(options, host) {
|
|
174
|
+
return Dom.renderHost()(options, host, rootInternalProps(options), options.content, (props, content) => {
|
|
175
|
+
return html `<div ...${props}>${content}</div>`;
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
function slideInternalProps(options) {
|
|
179
|
+
const register = options.collection === undefined
|
|
180
|
+
? undefined
|
|
181
|
+
: Collection.ref(options.collection, {
|
|
182
|
+
id: options.id,
|
|
183
|
+
value: options.id,
|
|
184
|
+
textValue: options.id,
|
|
185
|
+
});
|
|
186
|
+
return ({ property }) => ({
|
|
187
|
+
id: options.id,
|
|
188
|
+
role: "group",
|
|
189
|
+
"aria-roledescription": "slide",
|
|
190
|
+
"aria-label": property("label", undefined),
|
|
191
|
+
"?hidden": RefSubject.map(options.state, (state) => state.activeId !== options.id),
|
|
192
|
+
ref: register,
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Renders one labelled slide, registers it when a collection is supplied, and toggles hidden from
|
|
197
|
+
* activeId.
|
|
198
|
+
*
|
|
199
|
+
* @remarks
|
|
200
|
+
* The returned Fx installs DOM refs, native listeners, state subscriptions, and optional
|
|
201
|
+
* collection registrations only when rendered. The rendering Scope removes those resources;
|
|
202
|
+
* unrelated nodes and attributes remain caller-owned.
|
|
203
|
+
*
|
|
204
|
+
* @since 1.0.0
|
|
205
|
+
* @category Slide content
|
|
206
|
+
*/
|
|
207
|
+
export function Slide(options, host) {
|
|
208
|
+
return Dom.renderHost()(options, host, slideInternalProps(options), options.content, (props, content) => {
|
|
209
|
+
return html `<div ...${props}>${content}</div>`;
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
function controlInternalProps(options, action) {
|
|
213
|
+
return () => ({ type: "button", onclick: action });
|
|
214
|
+
}
|
|
215
|
+
function control(options, host, action) {
|
|
216
|
+
const internal = controlInternalProps(options, action);
|
|
217
|
+
return Dom.renderHost()(options, host, internal, options.content, (props, content) => html `<button ...${props}>${content}</button>`);
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Renders a button whose native click selects the previous registered slide with wrapping enabled.
|
|
221
|
+
*
|
|
222
|
+
* @remarks
|
|
223
|
+
* The returned Fx installs DOM refs, native listeners, state subscriptions, and optional
|
|
224
|
+
* collection registrations only when rendered. The rendering Scope removes those resources;
|
|
225
|
+
* unrelated nodes and attributes remain caller-owned.
|
|
226
|
+
*
|
|
227
|
+
* @since 1.0.0
|
|
228
|
+
* @category Slide controls
|
|
229
|
+
*/
|
|
230
|
+
export function Previous(options, host) {
|
|
231
|
+
return control(options, host, options.collection === undefined
|
|
232
|
+
? Effect.void
|
|
233
|
+
: move(options.state, options.collection, "previous"));
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Renders a button whose native click selects the next registered slide with wrapping enabled.
|
|
237
|
+
*
|
|
238
|
+
* @remarks
|
|
239
|
+
* The returned Fx installs DOM refs, native listeners, state subscriptions, and optional
|
|
240
|
+
* collection registrations only when rendered. The rendering Scope removes those resources;
|
|
241
|
+
* unrelated nodes and attributes remain caller-owned.
|
|
242
|
+
*
|
|
243
|
+
* @since 1.0.0
|
|
244
|
+
* @category Slide controls
|
|
245
|
+
*/
|
|
246
|
+
export function Next(options, host) {
|
|
247
|
+
return control(options, host, options.collection === undefined
|
|
248
|
+
? Effect.void
|
|
249
|
+
: move(options.state, options.collection, "next"));
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Renders a button whose native click toggles the explicit paused state.
|
|
253
|
+
*
|
|
254
|
+
* @remarks
|
|
255
|
+
* The returned Fx installs DOM refs, native listeners, state subscriptions, and optional
|
|
256
|
+
* collection registrations only when rendered. The rendering Scope removes those resources;
|
|
257
|
+
* unrelated nodes and attributes remain caller-owned.
|
|
258
|
+
*
|
|
259
|
+
* @since 1.0.0
|
|
260
|
+
* @category Rotation policy
|
|
261
|
+
*/
|
|
262
|
+
export function RotationControl(options, host) {
|
|
263
|
+
return control(options, host, toggleRotation(options.state));
|
|
264
|
+
}
|