@fxi/zartigl 0.5.0 → 0.6.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.
@@ -0,0 +1,12 @@
1
+ function e(r) {
2
+ if (r == null)
3
+ return null;
4
+ if (!Number.isFinite(r[0]) || !Number.isFinite(r[1]) || r[0] >= r[1])
5
+ throw new RangeError(
6
+ "colorDomain must contain two finite, increasing values"
7
+ );
8
+ return [r[0], r[1]];
9
+ }
10
+ export {
11
+ e as v
12
+ };
@@ -0,0 +1,398 @@
1
+ /** `rootMargin` that shrinks the root to a band at `line`. */
2
+ export declare function activationMargin(line: number): string;
3
+
4
+ export declare function advanceStorySequence(index: number, direction: 1 | -1, length: number, mode: "loop" | "ping-pong"): {
5
+ index: number;
6
+ direction: 1 | -1;
7
+ };
8
+
9
+ /** Layouts of the original story demo, accepted when an app names none. */
10
+ export declare const DEFAULT_STORY_LAYOUTS: readonly string[];
11
+
12
+ /**
13
+ * Define `<story-pager>`: ‹ 1 2 … n › ⏯ in light DOM, styled by the app.
14
+ * Emits `story-pager-navigate` ({@link StoryPagerNavigateDetail}) and
15
+ * `story-pager-toggle`; the app owns the state and sets it back. The active
16
+ * step has `aria-current="step"` and its `--progress` drives a fill.
17
+ */
18
+ export declare function defineStoryPager(registry?: CustomElementRegistry, name?: string): void;
19
+
20
+ export declare function initializeAfterStaticRender<T>(renderStatic: () => void, initialize: () => Promise<T>): Promise<T>;
21
+
22
+ export declare class LoadingIndicator {
23
+ private readonly update;
24
+ private readonly revealDelayMs;
25
+ private readonly minimumVisibleMs;
26
+ private revealTimer;
27
+ private hideTimer;
28
+ private shownAt;
29
+ private visible;
30
+ constructor(update: (visible: boolean) => void, options?: LoadingIndicatorOptions);
31
+ show(): void;
32
+ hide(immediate?: boolean): void;
33
+ private setVisible;
34
+ private clearRevealTimer;
35
+ private clearHideTimer;
36
+ }
37
+
38
+ export declare interface LoadingIndicatorOptions {
39
+ revealDelayMs?: number;
40
+ minimumVisibleMs?: number;
41
+ }
42
+
43
+ export declare type LocalizedText = Record<string, string>;
44
+
45
+ export declare function nextStoryIndex(current: number, delta: number, sceneCount: number): number;
46
+
47
+ export declare function parseStoryDocuments(story: unknown, views: unknown, options?: StoryValidationOptions): {
48
+ story: StoryDocument;
49
+ views: StoryViewsDocument;
50
+ };
51
+
52
+ /** Read `#s=<scene id>&paused=1`; unknown or missing fields stay undefined. */
53
+ export declare function parseStoryHash(hash: string): StoryHashState;
54
+
55
+ export declare function resolveLocalizedText(text: LocalizedText, locale: string, defaultLocale: string, fallbacks?: readonly string[]): string;
56
+
57
+ export declare function sceneShowsTime(scene: StoryScene): boolean;
58
+
59
+ export declare function sceneViewId(scene: StoryScene): string | undefined;
60
+
61
+ export declare function sequenceIndexAtOrBefore(times: readonly string[], time: number): number;
62
+
63
+ export declare type StoryAnchor = "center" | "top-left" | "top-right" | "bottom-left" | "bottom-right";
64
+
65
+ export declare type StoryBlock = StoryCopyBlock | StoryViewBlock | StoryWidgetBlock | StoryTextBlock;
66
+
67
+ declare interface StoryBlockBase {
68
+ id: string;
69
+ slot: StorySlot;
70
+ anchor?: StoryAnchor;
71
+ }
72
+
73
+ export declare interface StoryCopyBlock extends StoryBlockBase {
74
+ type: "copy";
75
+ label?: LocalizedText;
76
+ heading: LocalizedText;
77
+ text?: LocalizedText;
78
+ references?: StoryReference[];
79
+ showTime?: boolean;
80
+ backdrop?: "none" | "dark-gradient";
81
+ orientation?: "horizontal" | "vertical-rl";
82
+ variant?: "hero" | "standard";
83
+ }
84
+
85
+ export declare interface StoryDocument {
86
+ schemaVersion: 1;
87
+ defaultLocale: string;
88
+ fallbackLocales?: string[];
89
+ title: LocalizedText;
90
+ themes: Record<string, StoryTheme>;
91
+ scenes: StoryScene[];
92
+ }
93
+
94
+ export declare interface StoryExternalLinkAttributes {
95
+ href: string;
96
+ target: "_blank";
97
+ rel: "noopener noreferrer";
98
+ textContent: string;
99
+ }
100
+
101
+ export declare function storyExternalLinkAttributes(reference: StoryReference, label: string): StoryExternalLinkAttributes;
102
+
103
+ export declare interface StoryFrameScheduler {
104
+ request(callback: FrameRequestCallback): number;
105
+ cancel(handle: number): void;
106
+ }
107
+
108
+ /** Url hash, without the leading "#", for a scene and its play state. */
109
+ export declare function storyHash(scene: string, paused: boolean): string;
110
+
111
+ /** Shareable position in a story: the scene and whether playback holds. */
112
+ export declare interface StoryHashState {
113
+ scene?: string;
114
+ paused?: boolean;
115
+ }
116
+
117
+ export declare interface StoryPagerElement extends HTMLElement {
118
+ /** Rebuild for `count` steps with the given labels. */
119
+ configure(count: number, labels: StoryPagerLabels): void;
120
+ /** Active step, 0-based. */
121
+ index: number;
122
+ playing: boolean;
123
+ /** Progress of the active step while playing, 0–1. */
124
+ progress: number;
125
+ disabled: boolean;
126
+ }
127
+
128
+ /** A step button, or a gap standing for hidden steps. */
129
+ export declare type StoryPagerItem = number | "gap";
130
+
131
+ /**
132
+ * Step buttons to show: all of them when they fit in `slots`, else the first,
133
+ * the last and the steps around `current`, with a gap for each hidden run.
134
+ * A gap takes one slot and always hides at least two steps.
135
+ */
136
+ export declare function storyPagerItems(count: number, current: number, slots?: number): StoryPagerItem[];
137
+
138
+ /** Accessible names of the pager controls, in the story locale. */
139
+ export declare interface StoryPagerLabels {
140
+ navigation: string;
141
+ previous: string;
142
+ next: string;
143
+ play: string;
144
+ pause: string;
145
+ /** Name of step `index` (0-based), e.g. "3 — Arctic". */
146
+ step(index: number): string;
147
+ }
148
+
149
+ /** Detail of the `story-pager-navigate` event: the requested step. */
150
+ export declare interface StoryPagerNavigateDetail {
151
+ index: number;
152
+ }
153
+
154
+ export declare type StoryPlayback = {
155
+ mode: "none";
156
+ } | {
157
+ mode: "autoplay";
158
+ } | {
159
+ mode: "sequence";
160
+ times: string[];
161
+ intervalMs: number;
162
+ direction?: "loop" | "ping-pong";
163
+ };
164
+
165
+ export declare interface StoryReference {
166
+ label: LocalizedText;
167
+ url: string;
168
+ }
169
+
170
+ export declare class StoryRegistry {
171
+ private readonly viewFactories;
172
+ private readonly viewAdapters;
173
+ private readonly widgets;
174
+ registerViewType(type: string, factory: StoryViewAdapterFactory): this;
175
+ registerWidgetType(type: string, renderer: StoryWidgetRenderer): this;
176
+ getViewAdapter(type: string): StoryViewAdapter;
177
+ getWidget(type: string): StoryWidgetRenderer;
178
+ destroy(): void;
179
+ }
180
+
181
+ export declare interface StoryScene {
182
+ id: string;
183
+ name: LocalizedText;
184
+ chapter?: string;
185
+ theme: string;
186
+ /** A layout id the app renders; see `StoryValidationOptions.layouts`. */
187
+ layout: string;
188
+ blocks: StoryBlock[];
189
+ playback?: StoryPlayback;
190
+ /** Auto-advance: time on this scene before the next, when the story plays. */
191
+ durationMs?: number;
192
+ }
193
+
194
+ /**
195
+ * Auto-advance clock of one scene: runs for a duration, pauses and resumes
196
+ * keeping the elapsed time, and calls `onDone` once when it runs out.
197
+ */
198
+ export declare class StorySceneTimer {
199
+ private readonly onDone;
200
+ private readonly now;
201
+ private durationMs;
202
+ private elapsedMs;
203
+ private startedAt;
204
+ private timer;
205
+ constructor(onDone: () => void, now?: () => number);
206
+ /** Restart from zero; runs at once unless `paused`. */
207
+ start(durationMs: number, paused?: boolean): void;
208
+ get running(): boolean;
209
+ /** Elapsed share of the duration, 0–1. */
210
+ get progress(): number;
211
+ pause(): void;
212
+ resume(): void;
213
+ /** Stop without firing; the progress drops to zero. */
214
+ stop(): void;
215
+ private clear;
216
+ }
217
+
218
+ /** The part of IntersectionObserverEntry the scroller reads. */
219
+ export declare interface StoryScrollEntry {
220
+ target: Element;
221
+ isIntersecting: boolean;
222
+ }
223
+
224
+ /**
225
+ * Scroll-driven scene activation: watches a list of sections and reports the
226
+ * one crossing the activation line. Between sections, the last one stays
227
+ * active, so a gap or a section taller than the viewport never blanks the
228
+ * view. No scroll listener: one IntersectionObserver.
229
+ */
230
+ export declare class StoryScroller {
231
+ private readonly sections;
232
+ private readonly onActivate;
233
+ private readonly observer;
234
+ private readonly crossing;
235
+ private activeIndex;
236
+ /**
237
+ * @param sections Scene sections in document order.
238
+ * @param onActivate Called once each time another section becomes active.
239
+ */
240
+ constructor(sections: readonly Element[], onActivate: (index: number, section: Element) => void, options?: StoryScrollerOptions);
241
+ /** Index of the active section, -1 before the first one is reached. */
242
+ get active(): number;
243
+ destroy(): void;
244
+ private update;
245
+ }
246
+
247
+ export declare interface StoryScrollerOptions {
248
+ /**
249
+ * Activation line, as a share of the viewport height from the top: the
250
+ * section that crosses it is the active one. Defaults to 0.5.
251
+ */
252
+ line?: number;
253
+ /** Scroll container; the viewport when omitted. */
254
+ root?: Element | null;
255
+ createObserver?: StoryScrollObserverFactory;
256
+ }
257
+
258
+ /** The part of IntersectionObserver the scroller uses; injectable for tests. */
259
+ export declare type StoryScrollObserverFactory = (callback: (entries: readonly StoryScrollEntry[]) => void, init: IntersectionObserverInit) => {
260
+ observe(target: Element): void;
261
+ disconnect(): void;
262
+ };
263
+
264
+ export declare type StorySlot = "copy" | "stage" | "analysis" | "edge";
265
+
266
+ export declare interface StoryTextBlock extends StoryBlockBase {
267
+ type: "text" | "credit" | "label";
268
+ text: LocalizedText;
269
+ orientation?: "horizontal" | "vertical-rl";
270
+ variant?: "standard" | "small";
271
+ }
272
+
273
+ export declare interface StoryTheme {
274
+ background: string;
275
+ foreground: string;
276
+ muted: string;
277
+ accent: string;
278
+ accentSoft: string;
279
+ surface: string;
280
+ glowAnchor?: StoryAnchor;
281
+ }
282
+
283
+ /** Coordinates an immediate cursor update with at most one layer seek per frame. */
284
+ export declare class StoryTimeInteraction {
285
+ private readonly callbacks;
286
+ private readonly frames;
287
+ private active;
288
+ private resumeAfterInteraction;
289
+ private latestTime;
290
+ private appliedTime;
291
+ private frame;
292
+ constructor(callbacks: StoryTimeInteractionCallbacks, frames?: StoryFrameScheduler);
293
+ get interacting(): boolean;
294
+ begin(): void;
295
+ request(time: number): void;
296
+ end(): void;
297
+ /** Abandons pending work without resuming playback (for navigation/cleanup). */
298
+ cancel(): void;
299
+ private applyLatest;
300
+ private cancelFrame;
301
+ }
302
+
303
+ export declare interface StoryTimeInteractionCallbacks {
304
+ isPlaying(): boolean;
305
+ pause(): void;
306
+ apply(time: number): void;
307
+ present(time: number): void;
308
+ finish(time: number | null, resume: boolean): void;
309
+ }
310
+
311
+ export declare class StoryTimePresentation {
312
+ private enabled;
313
+ get visible(): boolean;
314
+ setScene(scene: StoryScene): void;
315
+ accept(time: number): number | null;
316
+ }
317
+
318
+ export declare interface StoryValidationOptions {
319
+ /** Scene layout ids the app renders. */
320
+ layouts?: readonly string[];
321
+ }
322
+
323
+ export declare interface StoryViewAdapter {
324
+ activate(view: StoryViewDefinition, scene: StoryScene): Promise<void> | void;
325
+ play?(): Promise<void> | void;
326
+ pause?(): void;
327
+ setTime?(time: number): void;
328
+ deactivate?(): void;
329
+ destroy(): void;
330
+ }
331
+
332
+ export declare type StoryViewAdapterFactory = () => StoryViewAdapter;
333
+
334
+ export declare interface StoryViewBlock extends StoryBlockBase {
335
+ type: "view";
336
+ view: string;
337
+ presentation?: "background" | "panel";
338
+ }
339
+
340
+ export declare interface StoryViewDefinition {
341
+ id: string;
342
+ type: string;
343
+ config: Record<string, unknown>;
344
+ }
345
+
346
+ export declare interface StoryViewsDocument {
347
+ schemaVersion: 1;
348
+ views: StoryViewDefinition[];
349
+ }
350
+
351
+ export declare interface StoryWidgetBlock extends StoryBlockBase {
352
+ type: "widget";
353
+ widget: string;
354
+ config?: Record<string, unknown>;
355
+ caption?: LocalizedText;
356
+ }
357
+
358
+ export declare type StoryWidgetCleanup = () => void;
359
+
360
+ export declare interface StoryWidgetContext {
361
+ scene: StoryScene;
362
+ block: StoryWidgetBlock;
363
+ locale: string;
364
+ signal: AbortSignal;
365
+ getViewAdapter(viewId: string): StoryViewAdapter | undefined;
366
+ setTimeCursor(cursor: (time: number) => void): void;
367
+ beginTimeInteraction(): void;
368
+ requestTime(time: number): void;
369
+ endTimeInteraction(): void;
370
+ }
371
+
372
+ export declare class StoryWidgetLifecycle {
373
+ private readonly onCleanupError;
374
+ private generation;
375
+ private controller;
376
+ private cleanup;
377
+ constructor(onCleanupError?: (error: unknown) => void);
378
+ begin(): StoryWidgetRun;
379
+ cancel(): void;
380
+ private invoke;
381
+ }
382
+
383
+ export declare type StoryWidgetRenderer = (host: HTMLElement, config: Record<string, unknown>, context: StoryWidgetContext) => Promise<(() => void) | void> | (() => void) | void;
384
+
385
+ export declare interface StoryWidgetRun {
386
+ readonly signal: AbortSignal;
387
+ isCurrent(): boolean;
388
+ runIfCurrent(effect: () => void): boolean;
389
+ settle(cleanup: StoryWidgetCleanup | void): void;
390
+ }
391
+
392
+ export declare function validateStoryDocument(value: unknown, options?: StoryValidationOptions): asserts value is StoryDocument;
393
+
394
+ export declare function validateStoryReferences(story: StoryDocument, views: StoryViewsDocument): void;
395
+
396
+ export declare function validateViewsDocument(value: unknown): asserts value is StoryViewsDocument;
397
+
398
+ export { }