@brytdesigns/web-component-core 1.1.7 → 3.1.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.
Files changed (84) hide show
  1. package/dist/main/animation/awaitAllAnimations.js +28 -32
  2. package/dist/main/animation/awaitAllAnimations.js.map +1 -1
  3. package/dist/main/animation/content.js +156 -0
  4. package/dist/main/animation/content.js.map +1 -0
  5. package/dist/main/animation/controlsToPromise.js +6 -5
  6. package/dist/main/animation/controlsToPromise.js.map +1 -1
  7. package/dist/main/animation/getTransitionConfig.js +52 -51
  8. package/dist/main/animation/getTransitionConfig.js.map +1 -1
  9. package/dist/main/animation/index.d.ts +61 -1
  10. package/dist/main/animation/index.js +5 -5
  11. package/dist/main/focusTrap/index.d.ts +1 -1
  12. package/dist/main/focusTrap/index.js +10 -14
  13. package/dist/main/focusTrap/index.js.map +1 -1
  14. package/dist/main/hooks/index.d.ts +14 -9
  15. package/dist/main/hooks/index.js +5 -6
  16. package/dist/main/hooks/internal/getValueFromPath.js +9 -10
  17. package/dist/main/hooks/internal/getValueFromPath.js.map +1 -1
  18. package/dist/main/hooks/makePathContextHooks.js +58 -68
  19. package/dist/main/hooks/makePathContextHooks.js.map +1 -1
  20. package/dist/main/hooks/makePathDataArrayComponent.js +61 -67
  21. package/dist/main/hooks/makePathDataArrayComponent.js.map +1 -1
  22. package/dist/main/hooks/makePathDataArrayItemComponent.js +17 -21
  23. package/dist/main/hooks/makePathDataArrayItemComponent.js.map +1 -1
  24. package/dist/main/hooks/makePathDataComponent.js +31 -33
  25. package/dist/main/hooks/makePathDataComponent.js.map +1 -1
  26. package/dist/main/index.d.ts +304 -27
  27. package/dist/main/index.js +28 -7
  28. package/dist/main/promise/abortablePromise.js +10 -15
  29. package/dist/main/promise/abortablePromise.js.map +1 -1
  30. package/dist/main/promise/index.js +2 -3
  31. package/dist/main/utils/a11y.js +133 -0
  32. package/dist/main/utils/a11y.js.map +1 -0
  33. package/dist/main/utils/body-scroll-lock.js +40 -18
  34. package/dist/main/utils/body-scroll-lock.js.map +1 -1
  35. package/dist/main/utils/checkLoaded.js +4 -4
  36. package/dist/main/utils/checkLoaded.js.map +1 -1
  37. package/dist/main/utils/createRemoteContext.js +85 -0
  38. package/dist/main/utils/createRemoteContext.js.map +1 -0
  39. package/dist/main/utils/disclosure.js +52 -0
  40. package/dist/main/utils/disclosure.js.map +1 -0
  41. package/dist/main/utils/formatValue.js +14 -18
  42. package/dist/main/utils/formatValue.js.map +1 -1
  43. package/dist/main/utils/getContextFromProvider.js +15 -10
  44. package/dist/main/utils/getContextFromProvider.js.map +1 -1
  45. package/dist/main/utils/getTemplateContent.js +6 -7
  46. package/dist/main/utils/getTemplateContent.js.map +1 -1
  47. package/dist/main/utils/guarded-effect.js +72 -0
  48. package/dist/main/utils/guarded-effect.js.map +1 -0
  49. package/dist/main/utils/index.d.ts +237 -20
  50. package/dist/main/utils/index.js +15 -12
  51. package/dist/main/utils/invokeOnLoaded.js +13 -13
  52. package/dist/main/utils/invokeOnLoaded.js.map +1 -1
  53. package/dist/main/utils/isCustomElement.js +4 -3
  54. package/dist/main/utils/isCustomElement.js.map +1 -1
  55. package/dist/main/utils/nested-overlays.js +36 -0
  56. package/dist/main/utils/nested-overlays.js.map +1 -0
  57. package/dist/main/utils/solid-element.js +48 -88
  58. package/dist/main/utils/solid-element.js.map +1 -1
  59. package/dist/main/utils/toHyphenated.js +4 -3
  60. package/dist/main/utils/toHyphenated.js.map +1 -1
  61. package/package.json +16 -15
  62. package/dist/esm/animation/index.js +0 -97
  63. package/dist/esm/animation/index.js.map +0 -1
  64. package/dist/esm/focusTrap/index.js +0 -18
  65. package/dist/esm/focusTrap/index.js.map +0 -1
  66. package/dist/esm/hooks/index.js +0 -235
  67. package/dist/esm/hooks/index.js.map +0 -1
  68. package/dist/esm/index.js +0 -547
  69. package/dist/esm/index.js.map +0 -1
  70. package/dist/esm/promise/index.js +0 -20
  71. package/dist/esm/promise/index.js.map +0 -1
  72. package/dist/esm/utils/index.js +0 -236
  73. package/dist/esm/utils/index.js.map +0 -1
  74. package/dist/main/animation/index.js.map +0 -1
  75. package/dist/main/hooks/index.js.map +0 -1
  76. package/dist/main/hooks/internal/index.js +0 -3
  77. package/dist/main/hooks/internal/index.js.map +0 -1
  78. package/dist/main/hooks/internal/types.js +0 -3
  79. package/dist/main/hooks/internal/types.js.map +0 -1
  80. package/dist/main/index.js.map +0 -1
  81. package/dist/main/promise/index.js.map +0 -1
  82. package/dist/main/utils/createWithElementContext.js +0 -64
  83. package/dist/main/utils/createWithElementContext.js.map +0 -1
  84. package/dist/main/utils/index.js.map +0 -1
@@ -1,15 +1,73 @@
1
1
  // Generated by dts-bundle-generator v9.5.1
2
2
 
3
3
  import { BodyScrollOptions } from 'body-scroll-lock-upgrade';
4
- import { ComponentType as mComponentType, ICustomElement, createContext, provide as _provide } from 'component-register';
4
+ import { ComponentType as ComponentRegisterComponentType, ICustomElement, createContext, provide as _provide } from 'component-register';
5
5
  import { FocusTrap, Options } from 'focus-trap';
6
6
  import { AnimationGeneratorType, AnimationPlaybackControlsWithThen, Easing, RepeatType } from 'motion';
7
- import { Accessor } from 'solid-js';
7
+ import { Accessor, EffectFunction, EffectOptions } from 'solid-js';
8
8
 
9
- export declare const createFocusTrap: (element: HTMLElement, options?: Accessor<Options>) => Accessor<FocusTrap>;
10
- export declare function abortablePromise(promise: Promise<any>, signal: AbortSignal): Promise<unknown>;
11
- export declare function controlsToPromise(controls: AnimationPlaybackControlsWithThen): Promise<unknown>;
12
9
  export declare function awaitAllAnimations(promises: AnimationPlaybackControlsWithThen[]): Promise<unknown>;
10
+ /**
11
+ * Whether the visitor has asked their device to reduce motion. Read on every
12
+ * open and close, so changing the setting applies without a reload.
13
+ */
14
+ export declare function shouldReduceMotion(): boolean;
15
+ /**
16
+ * Whether the direction this animation was started for has since been left.
17
+ *
18
+ * Toggling mid-animation re-runs the caller's effect, whose cleanup calls
19
+ * `animation.complete()` — which resolves the promise, so the `.then` below
20
+ * fires as a microtask *after* the new direction has already applied its
21
+ * styles, and would undo them. Callers flip their own flag in that cleanup;
22
+ * the default is for callers that never re-enter.
23
+ */
24
+ export type IsStale = () => boolean;
25
+ /**
26
+ * Whether the browser supports `hidden="until-found"`, which keeps a closed
27
+ * content's text reachable by find-in-page and text-fragment links.
28
+ */
29
+ export declare function supportsHiddenUntilFound(): boolean;
30
+ /**
31
+ * Puts the content in its open end state, without animating.
32
+ *
33
+ * `flow-root` rather than `block`, so the panel is always a block formatting
34
+ * context and always contains its children's margins.
35
+ *
36
+ * Without it the box model changed underneath the animation. The measurement
37
+ * runs before `overflow: hidden` is applied, so a child margin collapsed out
38
+ * of the panel and the target came back short; the animation then set
39
+ * `overflow: hidden`, which *makes* the panel a BFC, so the same content
40
+ * suddenly needed more room than the target allowed and stayed clipped — and
41
+ * snapped into place when `overflow` was removed at the end. A `<p>` with
42
+ * default margins inside a plain `<div>` measured 24px and rendered 56px.
43
+ *
44
+ * `flow-root` is the modern way to ask for a BFC without clipping, which is
45
+ * exactly what is wanted here: `overflow: hidden` during the animation now
46
+ * changes nothing about the box, only what is painted outside it.
47
+ */
48
+ export declare function showContent(element: HTMLElement): void;
49
+ /**
50
+ * Puts the content in its closed end state, without animating.
51
+ *
52
+ * Where supported, the content is closed with `hidden="until-found"` rather
53
+ * than `display: none`, so find-in-page can still match its text. The inline
54
+ * styles zero the box, which `until-found` alone leaves its padding, and keep
55
+ * it a block: `until-found` hides content through `content-visibility`, which
56
+ * does not apply to an inline box, and custom elements are inline by default.
57
+ */
58
+ export declare function hideContent(element: HTMLElement): void;
59
+ /**
60
+ * Calls `callback` when find-in-page or a text-fragment link matches text
61
+ * inside the closed content. It fires before the browser removes `hidden` and
62
+ * scrolls to the match, so layout changes made synchronously in `callback`
63
+ * are settled by the time the browser scrolls. Returns a cleanup function.
64
+ */
65
+ export declare function onContentRevealed(element: HTMLElement, callback: () => void): () => void;
66
+ /** Animates the content open from zero height. */
67
+ export declare function expandContent(element: HTMLElement, isStale?: IsStale): import("motion").AnimationPlaybackControlsWithThen;
68
+ /** Animates the content closed to zero height. */
69
+ export declare function collapseContent(element: HTMLElement, isStale?: IsStale): import("motion").AnimationPlaybackControlsWithThen;
70
+ export declare function controlsToPromise(controls: AnimationPlaybackControlsWithThen): Promise<unknown>;
13
71
  export declare function getTransitionConfig(style: CSSStyleDeclaration): {
14
72
  bounce: number | undefined;
15
73
  bounceDamping: number | undefined;
@@ -34,30 +92,248 @@ export declare function getTransitionConfig(style: CSSStyleDeclaration): {
34
92
  velocity: number | undefined;
35
93
  visualDuration: number | undefined;
36
94
  };
37
- export declare function toHyphenated(str: string): string;
38
- export type ComponentType<T> = mComponentType<T>;
39
- export type CorrectComponentOptions = {
40
- element: HTMLElement & ICustomElement;
95
+ export declare const createFocusTrap: (element: HTMLElement, options?: Accessor<Options>) => import("solid-js").SourceAccessor<FocusTrap>;
96
+ /**
97
+ * Shared accessibility helpers.
98
+ *
99
+ * Everything here was either duplicated across leaf packages or missing
100
+ * entirely while each overlay reimplemented a piece of it.
101
+ */
102
+ /**
103
+ * Visually hidden, still in the accessibility tree.
104
+ *
105
+ * Byte-identical to the copies that lived in `keen-slider-scrollbar`,
106
+ * `keen-slider-navigation-arrows` and `keen-slider-navigation-dots` — three
107
+ * copies of the same clip-rect incantation, none of which could be fixed
108
+ * without finding the other two.
109
+ */
110
+ export declare const srOnly = "border-width:0 !important;clip:rect(1px, 1px, 1px, 1px) !important;-webkit-clip-path:inset(50%) !important;clip-path:inset(50%) !important;height:1px !important;margin-top:-1px !important;margin-bottom:-1px !important;margin-right:-1px !important;margin-left:-1px !important;overflow:hidden !important;padding-top:0 !important;padding-bottom:0 !important;padding-right:0 !important;padding-left:0 !important;position:absolute !important;width:1px !important;white-space:nowrap !important;";
111
+ /**
112
+ * The panel belonging to this overlay — `dialog-content`, `drawer-content` or
113
+ * `modal-panel` — skipping the panels of overlays nested inside it.
114
+ *
115
+ * Same shape as `findDisclosureContent`, and for the same reason: a plain
116
+ * `querySelector` finds a nested overlay's panel first whenever the nested one
117
+ * is authored above its parent's own content.
118
+ */
119
+ export declare function findOverlayPanel(context: HTMLElement, panelTag: string, selector?: string): HTMLElement | null;
120
+ export type FocusReturn = {
121
+ /** Remembers what holds focus now, to restore later. */
122
+ record: () => void;
123
+ /** Restores it. Returns whether focus was actually moved. */
124
+ restore: () => boolean;
41
125
  };
42
- export type CorrectComponentType<T> = (props: T, options: CorrectComponentOptions) => unknown;
43
- export declare function customElement<T extends object>(tagName: string, props: T, Component?: ComponentType<T>, ...rest: ((C: ComponentType<T>) => ComponentType<T>)[]): import("component-register/types/utils").ComponentType<any>;
44
- export declare function customShadowlessElement<T extends object>(tagName: string, props: T, Component?: ComponentType<T>, ...rest: ((C: ComponentType<T>) => ComponentType<T>)[]): import("component-register/types/utils").ComponentType<any>;
45
- export declare const correctElementType: <T>(component: CorrectComponentType<T>) => ComponentType<T>;
46
- export declare function isCustomElement(element: any): element is ICustomElement & HTMLElement;
47
- export declare function getContextFromProvider<T>(context: ReturnType<typeof createContext>, element: Element): T;
126
+ /**
127
+ * Remembers where focus came from when an overlay opens, and puts it back when
128
+ * the overlay closes.
129
+ *
130
+ * `focus-trap` already does this, but only while a trap is active — so an
131
+ * overlay with `should-trap-focus="false"` dropped focus on the floor, and a
132
+ * keyboard user was returned to the top of the document. Keeping it separate
133
+ * means focus return is a property of opening and closing rather than a
134
+ * side effect of trapping.
135
+ *
136
+ * Focus already inside the overlay is not recorded: that is where focus is
137
+ * going, not where it came from, and restoring to it would strand the user in
138
+ * a hidden subtree.
139
+ */
140
+ export declare function createFocusReturn(element: HTMLElement): FocusReturn;
141
+ export type EscapeHandlerOptions = {
142
+ /** The overlay root — the element carrying `is-open`. */
143
+ element: HTMLElement;
144
+ /** Called when Escape should close this overlay. */
145
+ onEscape: () => void;
146
+ /** Checked at key time, so toggling the attribute takes effect at once. */
147
+ isEnabled?: () => boolean;
148
+ /** Overridable for tests; defaults to the three overlay context tags. */
149
+ selector?: string;
150
+ };
151
+ /**
152
+ * Closes the topmost overlay on Escape. Returns its own teardown.
153
+ *
154
+ * This exists because Escape was previously `focus-trap`'s `escapeDeactivates`
155
+ * option, which has two consequences nobody wanted: Escape did nothing at all
156
+ * unless focus trapping was *also* on, and the two settings could not be
157
+ * configured independently even though they are different promises to the
158
+ * user.
159
+ *
160
+ * Only the innermost open overlay responds, so Escape inside a nested dialog
161
+ * closes that dialog rather than collapsing the whole stack.
162
+ */
163
+ export declare function createEscapeHandler({ element, onEscape, isEnabled, selector, }: EscapeHandlerOptions): () => void;
164
+ export type Politeness = "polite" | "assertive";
165
+ /**
166
+ * Announces a message to assistive tech through a single shared live region.
167
+ *
168
+ * One region for the whole page, not one per component: a live region has to
169
+ * be in the DOM *before* its content changes for the change to be announced,
170
+ * so a component that creates one and fills it in the same tick announces
171
+ * nothing. Creating it once, on first use, sidesteps that.
172
+ *
173
+ * The text is cleared and set on a later tick for the same reason in reverse —
174
+ * writing identical text is not a change, so a screen reader stays silent when
175
+ * the same message is announced twice in a row.
176
+ */
177
+ export declare function announce(message: string, politeness?: Politeness): void;
178
+ export declare const disableBodyScroll: (element: ICustomElement & HTMLElement, options?: BodyScrollOptions) => void;
179
+ export declare const enableBodyScroll: (element: ICustomElement & HTMLElement) => void;
48
180
  export declare function checkLoaded(): boolean;
49
- export declare function invokeOnLoaded(fn: () => void, { signal }: {
50
- signal?: AbortSignal;
51
- }): void;
181
+ export type ContextRef = {
182
+ id: symbol;
183
+ };
184
+ export declare class RemoteContextError extends Error {
185
+ readonly target: unknown;
186
+ constructor(message: string, target: unknown);
187
+ }
188
+ export type RemoteContextOptions = {
189
+ /**
190
+ * Map a `target` to the element that actually provides the context.
191
+ *
192
+ * Synchronous by design — it answers "which element, given the DOM as it is
193
+ * now". Waiting for the element to appear is the helper's job, and it
194
+ * re-runs `resolve` on each mutation, so a strategy never has to implement
195
+ * retrying itself.
196
+ *
197
+ * Defaults to `document.querySelector(target)`, falling back to the host
198
+ * element when `target` is empty.
199
+ */
200
+ resolve?: (target: string | undefined, host: HTMLElement) => Element | null;
201
+ /** Label used in warnings and errors. Defaults to the context's symbol. */
202
+ name?: string;
203
+ };
204
+ /**
205
+ * Build a hook that resolves one context from a *lateral* element.
206
+ *
207
+ * ```ts
208
+ * export const useDrawerAt = createRemoteContext<DrawerContext>(DrawerContextState);
209
+ * ```
210
+ */
211
+ export declare function createRemoteContext<T>(context: ContextRef, { resolve, name }?: RemoteContextOptions): (target: () => string | undefined, host: HTMLElement) => import("solid-js").SourceAccessor<T & ({} | null)>;
52
212
  /**
53
- * Creates a HOF to ensure that a given callback is invoked only after the context for the element is ready.
54
- * */
55
- export declare function createWithElementContext<Context extends ReturnType<typeof createContext>, ContextState = null>(context: Context): <D extends any>(target: string | Accessor<string> | Accessor<() => Element>, dependencies: Accessor<D> | undefined, cb: (context: ContextState, dependencies: D) => void | (() => void)) => void;
213
+ * ARIA wiring for disclosure widgets (accordion and collapsible): the
214
+ * trigger's button reports whether its content is open and which content it
215
+ * controls.
216
+ */
217
+ /**
218
+ * The element a trigger exposes to assistive tech: the trigger itself when it
219
+ * has `role="button"`, otherwise the first button inside it.
220
+ */
221
+ export declare function findDisclosureControl(trigger: HTMLElement): HTMLElement | null;
222
+ /**
223
+ * The content belonging to the same item as `trigger`, skipping the content of items
224
+ * nested inside it.
225
+ */
226
+ export declare function findDisclosureContent(trigger: HTMLElement, itemTag: string, contentTag: string): HTMLElement | null;
227
+ /** Returns the element's id, assigning a unique `${prefix}-N` if it has none. */
228
+ export declare function ensureId(element: HTMLElement, prefix: string): string;
229
+ /**
230
+ * Points the control's `aria-controls` at the content, unless the markup already
231
+ * set one. Returns whether the control is linked.
232
+ */
233
+ export declare function linkDisclosureControl(control: HTMLElement, content: HTMLElement | null, idPrefix: string): boolean;
56
234
  export type Format = "currency" | "number" | "boolean" | "invert_boolean" | string;
57
235
  export declare function formatValue(format: Format, value: unknown): any;
236
+ /**
237
+ * Read a `component-register` context off an element, synchronously.
238
+ *
239
+ * The imperative counterpart to `createRemoteContext`: no waiting, no effect,
240
+ * callable from a plain `<script>` in a Liquid template when you already know
241
+ * the element is there. Deliberately kept separate — forcing an async,
242
+ * effect-shaped API on this use case would break theme scripts for no gain.
243
+ */
244
+ export declare function getContextFromProvider<T>(context: ReturnType<typeof createContext>, element: Element): T & ({} | null);
58
245
  export declare function getTemplateContent(element: HTMLElement, state: string): DocumentFragment | null;
59
- export declare const disableBodyScroll: (element: ICustomElement & HTMLElement, options?: BodyScrollOptions) => void;
60
- export declare const enableBodyScroll: (element: ICustomElement & HTMLElement) => void;
246
+ /**
247
+ * `createEffect` whose **apply phase cannot take the page down**.
248
+ *
249
+ * ## Why this exists
250
+ *
251
+ * Solid 2 treats the two phases of an effect very differently, and only one
252
+ * of them is dangerous. Measured against the installed `2.0.0-rc.14`, in
253
+ * `tests/component/reactivity-halt.test.ts`:
254
+ *
255
+ * | throw site | rest of the page |
256
+ * | ----------------- | --------------------------- |
257
+ * | component setup | unaffected |
258
+ * | compute phase | unaffected — the run is skipped and logged |
259
+ * | **apply phase** | **every computation on the page stops, permanently** |
260
+ *
261
+ * An uncaught apply-phase throw calls the runtime's `haltReactivity`, which
262
+ * is module-level global state. On a Shopify page every Bryt element shares
263
+ * one `solid-js` singleton, so one bad attribute on one element freezes every
264
+ * drawer, modal, slider and the cart until the shopper reloads.
265
+ *
266
+ * ## Why not an error boundary
267
+ *
268
+ * Because it does not work. `createErrorBoundary` is documented as catching
269
+ * this, and it does not in rc.14: the characterization test drives a
270
+ * subscribed boundary around the throwing effect and the fallback never runs
271
+ * while the rest of the page still freezes. Upstream's own guidance in
272
+ * `@solidjs/signals`' `createEffect` docblock is the half that holds —
273
+ *
274
+ * > The **effect phase is different**: it is your own imperative code, so
275
+ * > handle failures with `try/catch` where they occur.
276
+ *
277
+ * — which is all this function is. If a later release makes boundaries catch
278
+ * it, the characterization test starts failing and says so.
279
+ *
280
+ * The compute phase is deliberately NOT guarded. It is already non-fatal, and
281
+ * swallowing a compute error would hide a genuine reactivity bug behind an
282
+ * effect that silently stops updating.
283
+ *
284
+ * @param compute the tracking phase — reads signals, returns the value
285
+ * @param apply the imperative phase, may return a cleanup function
286
+ * @param options forwarded to `createEffect`; `name` is used in the report
287
+ */
288
+ export declare function createGuardedEffect<const T>(compute: (prev: T | undefined) => T, apply: EffectFunction<NoInfer<T>, T>, options?: EffectOptions): void;
289
+ export declare function invokeOnLoaded(fn: () => void, { signal }: {
290
+ signal?: AbortSignal;
291
+ }): void;
292
+ export declare function isCustomElement(element: any): element is ICustomElement & HTMLElement;
293
+ /**
294
+ * Closing an overlay has to close the overlays inside it.
295
+ *
296
+ * A dialog nested in another is hidden along with its parent, but
297
+ * nothing changes its own `isOpen`. It keeps reporting `is-open="true"` while
298
+ * invisible, never fires `drawer:close`, never releases what it holds, and
299
+ * reappears still open when the parent is opened again.
300
+ *
301
+ * These components have no concept of a parent — no containment check anywhere
302
+ * in either package — so the relationship is established here, at the point
303
+ * where it is needed, rather than threaded through context.
304
+ *
305
+ * Writing a *descendant's* attribute is allowed in Solid 2. Writing the
306
+ * component's own prop is what `REACTIVE_WRITE_IN_OWNED_SCOPE` forbids, which
307
+ * is why this takes the element rather than a setter.
308
+ */
309
+ /**
310
+ * Both kinds, not just the caller's own. A modal inside a drawer is hidden by
311
+ * the drawer closing exactly as another drawer would be, and is left in the
312
+ * same wrong state.
313
+ */
314
+ export declare const OVERLAY_SELECTOR = "dialog-context, drawer-context, modal-context";
315
+ export declare function closeNestedOverlays(root: HTMLElement, selector?: string): HTMLElement[];
316
+ export type ComponentType<T> = ComponentRegisterComponentType<T>;
317
+ /**
318
+ * `component-register` types `options.element` as a bare `ICustomElement`, but
319
+ * at runtime it is always also an `HTMLElement`. Every component in this repo
320
+ * needs the DOM half.
321
+ */
322
+ export type CorrectComponentOptions = {
323
+ element: HTMLElement & ICustomElement;
324
+ };
325
+ export type CorrectComponentType<T> = (props: T, options: CorrectComponentOptions) => unknown;
326
+ export type Middleware<T> = (Component: ComponentType<T>) => ComponentType<T>;
327
+ export declare function customElement<T extends object>(tagName: string, props: T, Component: CorrectComponentType<T>, ...rest: Middleware<T>[]): import("component-register/types/utils").ComponentType<any>;
328
+ export declare function customShadowlessElement<T extends object>(tagName: string, props: T, Component: CorrectComponentType<T>, ...rest: Middleware<T>[]): import("component-register/types/utils").ComponentType<any>;
329
+ /**
330
+ * @deprecated The narrowing is built into `customElement` and
331
+ * `customShadowlessElement` now, so this is a type-level identity. It is kept
332
+ * only so packages still on Solid 1 keep compiling during the migration;
333
+ * delete the call rather than porting it.
334
+ */
335
+ export declare const correctElementType: <T>(component: CorrectComponentType<T>) => CorrectComponentType<T>;
336
+ export declare function toHyphenated(str: string): string;
61
337
  export type Path<T> = T extends readonly (infer U)[] ? `${number}` | `${number}.${Path<U>}` : T extends object ? {
62
338
  [K in keyof T & (string | number)]: T[K] extends object | any[] ? `${K}` | `${K}.${Path<T[K]>}` : `${K}`;
63
339
  }[keyof T & (string | number)] : never;
@@ -89,10 +365,6 @@ export type BaseOptions<RootData = any, Props = any> = {
89
365
  name: string;
90
366
  Component?: CorrectComponentType<Props>;
91
367
  };
92
- export declare const makePathDataComponent: <RootData = any, Props = any>({ useRootData, hooks, name, }: BaseOptions<RootData>) => CorrectComponentType<{
93
- propertyName: Path<RootData>;
94
- format?: Format;
95
- } & Props>;
96
368
  export declare const makePathDataArrayComponent: <RootData = any, Props = any>({ useRootData, hooks, name, arrayItemName, }: BaseOptions<RootData> & {
97
369
  arrayItemName: string;
98
370
  }) => CorrectComponentType<{
@@ -102,5 +374,10 @@ export declare const makePathDataArrayComponent: <RootData = any, Props = any>({
102
374
  export declare const makePathDataArrayItemComponent: <RootData = any, Props extends {
103
375
  itemIndex: Path<RootData>;
104
376
  } = any>({ hooks, name, }: BaseOptions<RootData, Props>) => CorrectComponentType<Props>;
377
+ export declare const makePathDataComponent: <RootData = any, Props = any>({ useRootData, hooks, name, }: BaseOptions<RootData>) => CorrectComponentType<{
378
+ propertyName: Path<RootData>;
379
+ format?: Format;
380
+ } & Props>;
381
+ export declare function abortablePromise(promise: Promise<any>, signal: AbortSignal): Promise<unknown>;
105
382
 
106
383
  export {};
@@ -1,7 +1,28 @@
1
- export * from './focusTrap/index.js';
2
- export * from './promise/index.js';
3
- export * from './animation/index.js';
4
- export * from './utils/index.js';
5
- export * from './hooks/index.js';
6
- //# sourceMappingURL=index.js.map
7
- //# sourceMappingURL=index.js.map
1
+ import { awaitAllAnimations } from "./animation/awaitAllAnimations.js";
2
+ import { collapseContent, expandContent, hideContent, onContentRevealed, shouldReduceMotion, showContent, supportsHiddenUntilFound } from "./animation/content.js";
3
+ import { controlsToPromise } from "./animation/controlsToPromise.js";
4
+ import { getTransitionConfig } from "./animation/getTransitionConfig.js";
5
+ import "./animation/index.js";
6
+ import { createFocusTrap } from "./focusTrap/index.js";
7
+ import { OVERLAY_SELECTOR, closeNestedOverlays } from "./utils/nested-overlays.js";
8
+ import { announce, createEscapeHandler, createFocusReturn, findOverlayPanel, srOnly } from "./utils/a11y.js";
9
+ import { createGuardedEffect } from "./utils/guarded-effect.js";
10
+ import { disableBodyScroll, enableBodyScroll } from "./utils/body-scroll-lock.js";
11
+ import { checkLoaded } from "./utils/checkLoaded.js";
12
+ import { RemoteContextError, createRemoteContext } from "./utils/createRemoteContext.js";
13
+ import { ensureId, findDisclosureContent, findDisclosureControl, linkDisclosureControl } from "./utils/disclosure.js";
14
+ import { formatValue } from "./utils/formatValue.js";
15
+ import { getContextFromProvider } from "./utils/getContextFromProvider.js";
16
+ import { getTemplateContent } from "./utils/getTemplateContent.js";
17
+ import { invokeOnLoaded } from "./utils/invokeOnLoaded.js";
18
+ import { isCustomElement } from "./utils/isCustomElement.js";
19
+ import { correctElementType, customElement, customShadowlessElement } from "./utils/solid-element.js";
20
+ import { toHyphenated } from "./utils/toHyphenated.js";
21
+ import "./utils/index.js";
22
+ import { makeFullPropertyPathContext } from "./hooks/makePathContextHooks.js";
23
+ import { makePathDataArrayComponent } from "./hooks/makePathDataArrayComponent.js";
24
+ import { makePathDataArrayItemComponent } from "./hooks/makePathDataArrayItemComponent.js";
25
+ import { makePathDataComponent } from "./hooks/makePathDataComponent.js";
26
+ import "./hooks/index.js";
27
+ import { abortablePromise } from "./promise/abortablePromise.js";
28
+ export { OVERLAY_SELECTOR, RemoteContextError, abortablePromise, announce, awaitAllAnimations, checkLoaded, closeNestedOverlays, collapseContent, controlsToPromise, correctElementType, createEscapeHandler, createFocusReturn, createFocusTrap, createGuardedEffect, createRemoteContext, customElement, customShadowlessElement, disableBodyScroll, enableBodyScroll, ensureId, expandContent, findDisclosureContent, findDisclosureControl, findOverlayPanel, formatValue, getContextFromProvider, getTemplateContent, getTransitionConfig, hideContent, invokeOnLoaded, isCustomElement, linkDisclosureControl, makeFullPropertyPathContext, makePathDataArrayComponent, makePathDataArrayItemComponent, makePathDataComponent, onContentRevealed, shouldReduceMotion, showContent, srOnly, supportsHiddenUntilFound, toHyphenated };
@@ -1,19 +1,14 @@
1
+ //#region src/promise/abortablePromise.ts
1
2
  function abortablePromise(promise, signal) {
2
- if (signal.aborted) {
3
- return new Promise((_, rej) => rej(signal.reason));
4
- }
5
- return new Promise(async (res, rej) => {
6
- signal.addEventListener(
7
- "abort",
8
- () => {
9
- rej(signal.reason);
10
- },
11
- { once: true }
12
- );
13
- promise.then(res);
14
- });
3
+ if (signal.aborted) return new Promise((_, rej) => rej(signal.reason));
4
+ return new Promise((res, rej) => {
5
+ signal.addEventListener("abort", () => {
6
+ rej(signal.reason);
7
+ }, { once: true });
8
+ promise.then(res, rej);
9
+ });
15
10
  }
16
-
11
+ //#endregion
17
12
  export { abortablePromise };
18
- //# sourceMappingURL=abortablePromise.js.map
13
+
19
14
  //# sourceMappingURL=abortablePromise.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/promise/abortablePromise.ts"],"names":[],"mappings":"AAAO,SAAS,gBAAA,CAAiB,SAAuB,MAAqB,EAAA;AAC3E,EAAA,IAAI,OAAO,OAAS,EAAA;AAClB,IAAO,OAAA,IAAI,QAAQ,CAAC,CAAA,EAAG,QAAQ,GAAI,CAAA,MAAA,CAAO,MAAM,CAAC,CAAA;AAAA;AAGnD,EAAA,OAAO,IAAI,OAAA,CAAQ,OAAO,GAAA,EAAK,GAAQ,KAAA;AACrC,IAAO,MAAA,CAAA,gBAAA;AAAA,MACL,OAAA;AAAA,MACA,MAAM;AACJ,QAAA,GAAA,CAAI,OAAO,MAAM,CAAA;AAAA,OACnB;AAAA,MACA,EAAE,MAAM,IAAK;AAAA,KACf;AACA,IAAA,OAAA,CAAQ,KAAK,GAAG,CAAA;AAAA,GACjB,CAAA;AACH","file":"abortablePromise.js","sourcesContent":["export function abortablePromise(promise: Promise<any>, signal: AbortSignal) {\n if (signal.aborted) {\n return new Promise((_, rej) => rej(signal.reason));\n }\n\n return new Promise(async (res, rej) => {\n signal.addEventListener(\n \"abort\",\n () => {\n rej(signal.reason);\n },\n { once: true },\n );\n promise.then(res);\n });\n}\n"]}
1
+ {"version":3,"file":"abortablePromise.js","names":[],"sources":["../../../src/promise/abortablePromise.ts"],"sourcesContent":["export function abortablePromise(promise: Promise<any>, signal: AbortSignal) {\n\tif (signal.aborted) {\n\t\treturn new Promise((_, rej) => rej(signal.reason));\n\t}\n\n\treturn new Promise((res, rej) => {\n\t\tsignal.addEventListener(\n\t\t\t\"abort\",\n\t\t\t() => {\n\t\t\t\trej(signal.reason);\n\t\t\t},\n\t\t\t{ once: true },\n\t\t);\n\t\t// Both settlement paths are forwarded. The previous `promise.then(res)`\n\t\t// dropped rejection, so a rejected input left the returned promise pending\n\t\t// forever unless the signal happened to abort. The `async` executor it sat\n\t\t// in compounded that: a throw inside an async executor rejects the\n\t\t// executor's own discarded promise, never the one being constructed.\n\t\tpromise.then(res, rej);\n\t});\n}\n"],"mappings":";AAAA,SAAgB,iBAAiB,SAAuB,QAAqB;CAC5E,IAAI,OAAO,SACV,OAAO,IAAI,SAAS,GAAG,QAAQ,IAAI,OAAO,MAAM,CAAC;CAGlD,OAAO,IAAI,SAAS,KAAK,QAAQ;EAChC,OAAO,iBACN,eACM;GACL,IAAI,OAAO,MAAM;EAClB,GACA,EAAE,MAAM,KAAK,CACd;EAMA,QAAQ,KAAK,KAAK,GAAG;CACtB,CAAC;AACF"}
@@ -1,3 +1,2 @@
1
- export * from './abortablePromise.js';
2
- //# sourceMappingURL=index.js.map
3
- //# sourceMappingURL=index.js.map
1
+ import { abortablePromise } from "./abortablePromise.js";
2
+ export { abortablePromise };
@@ -0,0 +1,133 @@
1
+ import { OVERLAY_SELECTOR } from "./nested-overlays.js";
2
+ //#region src/utils/a11y.ts
3
+ /**
4
+ * Shared accessibility helpers.
5
+ *
6
+ * Everything here was either duplicated across leaf packages or missing
7
+ * entirely while each overlay reimplemented a piece of it.
8
+ */
9
+ /**
10
+ * Visually hidden, still in the accessibility tree.
11
+ *
12
+ * Byte-identical to the copies that lived in `keen-slider-scrollbar`,
13
+ * `keen-slider-navigation-arrows` and `keen-slider-navigation-dots` — three
14
+ * copies of the same clip-rect incantation, none of which could be fixed
15
+ * without finding the other two.
16
+ */
17
+ var srOnly = `border-width:0 !important;clip:rect(1px, 1px, 1px, 1px) !important;-webkit-clip-path:inset(50%) !important;clip-path:inset(50%) !important;height:1px !important;margin-top:-1px !important;margin-bottom:-1px !important;margin-right:-1px !important;margin-left:-1px !important;overflow:hidden !important;padding-top:0 !important;padding-bottom:0 !important;padding-right:0 !important;padding-left:0 !important;position:absolute !important;width:1px !important;white-space:nowrap !important;`;
18
+ /**
19
+ * The panel belonging to this overlay — `dialog-content`, `drawer-content` or
20
+ * `modal-panel` — skipping the panels of overlays nested inside it.
21
+ *
22
+ * Same shape as `findDisclosureContent`, and for the same reason: a plain
23
+ * `querySelector` finds a nested overlay's panel first whenever the nested one
24
+ * is authored above its parent's own content.
25
+ */
26
+ function findOverlayPanel(context, panelTag, selector = OVERLAY_SELECTOR) {
27
+ for (const panel of Array.from(context.querySelectorAll(panelTag))) if (panel.closest(selector) === context) return panel;
28
+ return null;
29
+ }
30
+ /**
31
+ * Remembers where focus came from when an overlay opens, and puts it back when
32
+ * the overlay closes.
33
+ *
34
+ * `focus-trap` already does this, but only while a trap is active — so an
35
+ * overlay with `should-trap-focus="false"` dropped focus on the floor, and a
36
+ * keyboard user was returned to the top of the document. Keeping it separate
37
+ * means focus return is a property of opening and closing rather than a
38
+ * side effect of trapping.
39
+ *
40
+ * Focus already inside the overlay is not recorded: that is where focus is
41
+ * going, not where it came from, and restoring to it would strand the user in
42
+ * a hidden subtree.
43
+ */
44
+ function createFocusReturn(element) {
45
+ let previous = null;
46
+ return {
47
+ record() {
48
+ const active = document.activeElement;
49
+ if (!(active instanceof HTMLElement) || active === document.body || element.contains(active)) {
50
+ previous = null;
51
+ return;
52
+ }
53
+ previous = active;
54
+ },
55
+ restore() {
56
+ const target = previous;
57
+ previous = null;
58
+ if (!target || !target.isConnected) return false;
59
+ target.focus();
60
+ return true;
61
+ }
62
+ };
63
+ }
64
+ /**
65
+ * Whether this overlay is the innermost open one.
66
+ *
67
+ * Nesting is established by containment rather than a registry, matching
68
+ * `closeNestedOverlays` — these components have no concept of a parent.
69
+ */
70
+ function isTopmostOpenOverlay(element, selector) {
71
+ if (element.getAttribute("is-open") !== "true") return false;
72
+ for (const nested of Array.from(element.querySelectorAll(selector))) if (nested.getAttribute("is-open") === "true") return false;
73
+ return true;
74
+ }
75
+ /**
76
+ * Closes the topmost overlay on Escape. Returns its own teardown.
77
+ *
78
+ * This exists because Escape was previously `focus-trap`'s `escapeDeactivates`
79
+ * option, which has two consequences nobody wanted: Escape did nothing at all
80
+ * unless focus trapping was *also* on, and the two settings could not be
81
+ * configured independently even though they are different promises to the
82
+ * user.
83
+ *
84
+ * Only the innermost open overlay responds, so Escape inside a nested dialog
85
+ * closes that dialog rather than collapsing the whole stack.
86
+ */
87
+ function createEscapeHandler({ element, onEscape, isEnabled, selector = OVERLAY_SELECTOR }) {
88
+ const controller = new AbortController();
89
+ document.addEventListener("keydown", (event) => {
90
+ if (event.key !== "Escape") return;
91
+ if (isEnabled && !isEnabled()) return;
92
+ if (!isTopmostOpenOverlay(element, selector)) return;
93
+ event.stopPropagation();
94
+ onEscape();
95
+ }, { signal: controller.signal });
96
+ return () => controller.abort();
97
+ }
98
+ var liveRegion = null;
99
+ /** The one shared live region, created on first use. */
100
+ function getLiveRegion() {
101
+ if (liveRegion?.isConnected) return liveRegion;
102
+ liveRegion = document.createElement("div");
103
+ liveRegion.setAttribute("data-bryt-announcer", "");
104
+ liveRegion.setAttribute("aria-atomic", "true");
105
+ liveRegion.setAttribute("style", srOnly);
106
+ document.body.appendChild(liveRegion);
107
+ return liveRegion;
108
+ }
109
+ /**
110
+ * Announces a message to assistive tech through a single shared live region.
111
+ *
112
+ * One region for the whole page, not one per component: a live region has to
113
+ * be in the DOM *before* its content changes for the change to be announced,
114
+ * so a component that creates one and fills it in the same tick announces
115
+ * nothing. Creating it once, on first use, sidesteps that.
116
+ *
117
+ * The text is cleared and set on a later tick for the same reason in reverse —
118
+ * writing identical text is not a change, so a screen reader stays silent when
119
+ * the same message is announced twice in a row.
120
+ */
121
+ function announce(message, politeness = "polite") {
122
+ if (!message) return;
123
+ const region = getLiveRegion();
124
+ region.setAttribute("aria-live", politeness);
125
+ region.textContent = "";
126
+ window.setTimeout(() => {
127
+ if (region.isConnected) region.textContent = message;
128
+ }, 50);
129
+ }
130
+ //#endregion
131
+ export { announce, createEscapeHandler, createFocusReturn, findOverlayPanel, srOnly };
132
+
133
+ //# sourceMappingURL=a11y.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"a11y.js","names":[],"sources":["../../../src/utils/a11y.ts"],"sourcesContent":["import { OVERLAY_SELECTOR } from \"./nested-overlays.js\";\n\n/**\n * Shared accessibility helpers.\n *\n * Everything here was either duplicated across leaf packages or missing\n * entirely while each overlay reimplemented a piece of it.\n */\n\n/**\n * Visually hidden, still in the accessibility tree.\n *\n * Byte-identical to the copies that lived in `keen-slider-scrollbar`,\n * `keen-slider-navigation-arrows` and `keen-slider-navigation-dots` — three\n * copies of the same clip-rect incantation, none of which could be fixed\n * without finding the other two.\n */\nexport const srOnly = `border-width:0 !important;clip:rect(1px, 1px, 1px, 1px) !important;-webkit-clip-path:inset(50%) !important;clip-path:inset(50%) !important;height:1px !important;margin-top:-1px !important;margin-bottom:-1px !important;margin-right:-1px !important;margin-left:-1px !important;overflow:hidden !important;padding-top:0 !important;padding-bottom:0 !important;padding-right:0 !important;padding-left:0 !important;position:absolute !important;width:1px !important;white-space:nowrap !important;`;\n\n/**\n * The panel belonging to this overlay — `dialog-content`, `drawer-content` or\n * `modal-panel` — skipping the panels of overlays nested inside it.\n *\n * Same shape as `findDisclosureContent`, and for the same reason: a plain\n * `querySelector` finds a nested overlay's panel first whenever the nested one\n * is authored above its parent's own content.\n */\nexport function findOverlayPanel(\n\tcontext: HTMLElement,\n\tpanelTag: string,\n\tselector: string = OVERLAY_SELECTOR,\n): HTMLElement | null {\n\tfor (const panel of Array.from(\n\t\tcontext.querySelectorAll<HTMLElement>(panelTag),\n\t)) {\n\t\tif (panel.closest(selector) === context) return panel;\n\t}\n\treturn null;\n}\n\nexport type FocusReturn = {\n\t/** Remembers what holds focus now, to restore later. */\n\trecord: () => void;\n\t/** Restores it. Returns whether focus was actually moved. */\n\trestore: () => boolean;\n};\n\n/**\n * Remembers where focus came from when an overlay opens, and puts it back when\n * the overlay closes.\n *\n * `focus-trap` already does this, but only while a trap is active — so an\n * overlay with `should-trap-focus=\"false\"` dropped focus on the floor, and a\n * keyboard user was returned to the top of the document. Keeping it separate\n * means focus return is a property of opening and closing rather than a\n * side effect of trapping.\n *\n * Focus already inside the overlay is not recorded: that is where focus is\n * going, not where it came from, and restoring to it would strand the user in\n * a hidden subtree.\n */\nexport function createFocusReturn(element: HTMLElement): FocusReturn {\n\tlet previous: HTMLElement | null = null;\n\n\treturn {\n\t\trecord() {\n\t\t\tconst active = document.activeElement;\n\t\t\tif (\n\t\t\t\t!(active instanceof HTMLElement) ||\n\t\t\t\tactive === document.body ||\n\t\t\t\telement.contains(active)\n\t\t\t) {\n\t\t\t\tprevious = null;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tprevious = active;\n\t\t},\n\n\t\trestore() {\n\t\t\tconst target = previous;\n\t\t\tprevious = null;\n\t\t\t// A trigger rendered by a section that re-rendered while the overlay\n\t\t\t// was open is gone; focusing it throws nothing but moves nothing\n\t\t\t// either, and the browser would leave focus on <body>.\n\t\t\tif (!target || !target.isConnected) return false;\n\t\t\ttarget.focus();\n\t\t\treturn true;\n\t\t},\n\t};\n}\n\nexport type EscapeHandlerOptions = {\n\t/** The overlay root — the element carrying `is-open`. */\n\telement: HTMLElement;\n\t/** Called when Escape should close this overlay. */\n\tonEscape: () => void;\n\t/** Checked at key time, so toggling the attribute takes effect at once. */\n\tisEnabled?: () => boolean;\n\t/** Overridable for tests; defaults to the three overlay context tags. */\n\tselector?: string;\n};\n\n/**\n * Whether this overlay is the innermost open one.\n *\n * Nesting is established by containment rather than a registry, matching\n * `closeNestedOverlays` — these components have no concept of a parent.\n */\nfunction isTopmostOpenOverlay(element: HTMLElement, selector: string) {\n\tif (element.getAttribute(\"is-open\") !== \"true\") return false;\n\n\tfor (const nested of Array.from(\n\t\telement.querySelectorAll<HTMLElement>(selector),\n\t)) {\n\t\tif (nested.getAttribute(\"is-open\") === \"true\") return false;\n\t}\n\n\treturn true;\n}\n\n/**\n * Closes the topmost overlay on Escape. Returns its own teardown.\n *\n * This exists because Escape was previously `focus-trap`'s `escapeDeactivates`\n * option, which has two consequences nobody wanted: Escape did nothing at all\n * unless focus trapping was *also* on, and the two settings could not be\n * configured independently even though they are different promises to the\n * user.\n *\n * Only the innermost open overlay responds, so Escape inside a nested dialog\n * closes that dialog rather than collapsing the whole stack.\n */\nexport function createEscapeHandler({\n\telement,\n\tonEscape,\n\tisEnabled,\n\tselector = OVERLAY_SELECTOR,\n}: EscapeHandlerOptions): () => void {\n\tconst controller = new AbortController();\n\n\tdocument.addEventListener(\n\t\t\"keydown\",\n\t\t(event: KeyboardEvent) => {\n\t\t\tif (event.key !== \"Escape\") return;\n\t\t\tif (isEnabled && !isEnabled()) return;\n\t\t\tif (!isTopmostOpenOverlay(element, selector)) return;\n\n\t\t\t// Stops an ancestor overlay's handler seeing the same key, in case one\n\t\t\t// is bound on a container rather than the document.\n\t\t\tevent.stopPropagation();\n\t\t\tonEscape();\n\t\t},\n\t\t{ signal: controller.signal },\n\t);\n\n\treturn () => controller.abort();\n}\n\nexport type Politeness = \"polite\" | \"assertive\";\n\nlet liveRegion: HTMLElement | null = null;\n\n/** The one shared live region, created on first use. */\nfunction getLiveRegion(): HTMLElement {\n\tif (liveRegion?.isConnected) return liveRegion;\n\n\tliveRegion = document.createElement(\"div\");\n\t// A stable hook, so a test can find the region without guessing at which\n\t// `[aria-live]` on the page belongs to it.\n\tliveRegion.setAttribute(\"data-bryt-announcer\", \"\");\n\tliveRegion.setAttribute(\"aria-atomic\", \"true\");\n\tliveRegion.setAttribute(\"style\", srOnly);\n\tdocument.body.appendChild(liveRegion);\n\n\treturn liveRegion;\n}\n\n/**\n * Announces a message to assistive tech through a single shared live region.\n *\n * One region for the whole page, not one per component: a live region has to\n * be in the DOM *before* its content changes for the change to be announced,\n * so a component that creates one and fills it in the same tick announces\n * nothing. Creating it once, on first use, sidesteps that.\n *\n * The text is cleared and set on a later tick for the same reason in reverse —\n * writing identical text is not a change, so a screen reader stays silent when\n * the same message is announced twice in a row.\n */\nexport function announce(message: string, politeness: Politeness = \"polite\") {\n\tif (!message) return;\n\n\tconst region = getLiveRegion();\n\tregion.setAttribute(\"aria-live\", politeness);\n\tregion.textContent = \"\";\n\n\twindow.setTimeout(() => {\n\t\t// Another announcement may have replaced the region in the meantime.\n\t\tif (region.isConnected) region.textContent = message;\n\t}, 50);\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAiBA,IAAa,SAAS;;;;;;;;;AAUtB,SAAgB,iBACf,SACA,UACA,WAAmB,kBACE;CACrB,KAAK,MAAM,SAAS,MAAM,KACzB,QAAQ,iBAA8B,QAAQ,CAC/C,GACC,IAAI,MAAM,QAAQ,QAAQ,MAAM,SAAS,OAAO;CAEjD,OAAO;AACR;;;;;;;;;;;;;;;AAuBA,SAAgB,kBAAkB,SAAmC;CACpE,IAAI,WAA+B;CAEnC,OAAO;EACN,SAAS;GACR,MAAM,SAAS,SAAS;GACxB,IACC,EAAE,kBAAkB,gBACpB,WAAW,SAAS,QACpB,QAAQ,SAAS,MAAM,GACtB;IACD,WAAW;IACX;GACD;GACA,WAAW;EACZ;EAEA,UAAU;GACT,MAAM,SAAS;GACf,WAAW;GAIX,IAAI,CAAC,UAAU,CAAC,OAAO,aAAa,OAAO;GAC3C,OAAO,MAAM;GACb,OAAO;EACR;CACD;AACD;;;;;;;AAmBA,SAAS,qBAAqB,SAAsB,UAAkB;CACrE,IAAI,QAAQ,aAAa,SAAS,MAAM,QAAQ,OAAO;CAEvD,KAAK,MAAM,UAAU,MAAM,KAC1B,QAAQ,iBAA8B,QAAQ,CAC/C,GACC,IAAI,OAAO,aAAa,SAAS,MAAM,QAAQ,OAAO;CAGvD,OAAO;AACR;;;;;;;;;;;;;AAcA,SAAgB,oBAAoB,EACnC,SACA,UACA,WACA,WAAW,oBACyB;CACpC,MAAM,aAAa,IAAI,gBAAgB;CAEvC,SAAS,iBACR,YACC,UAAyB;EACzB,IAAI,MAAM,QAAQ,UAAU;EAC5B,IAAI,aAAa,CAAC,UAAU,GAAG;EAC/B,IAAI,CAAC,qBAAqB,SAAS,QAAQ,GAAG;EAI9C,MAAM,gBAAgB;EACtB,SAAS;CACV,GACA,EAAE,QAAQ,WAAW,OAAO,CAC7B;CAEA,aAAa,WAAW,MAAM;AAC/B;AAIA,IAAI,aAAiC;;AAGrC,SAAS,gBAA6B;CACrC,IAAI,YAAY,aAAa,OAAO;CAEpC,aAAa,SAAS,cAAc,KAAK;CAGzC,WAAW,aAAa,uBAAuB,EAAE;CACjD,WAAW,aAAa,eAAe,MAAM;CAC7C,WAAW,aAAa,SAAS,MAAM;CACvC,SAAS,KAAK,YAAY,UAAU;CAEpC,OAAO;AACR;;;;;;;;;;;;;AAcA,SAAgB,SAAS,SAAiB,aAAyB,UAAU;CAC5E,IAAI,CAAC,SAAS;CAEd,MAAM,SAAS,cAAc;CAC7B,OAAO,aAAa,aAAa,UAAU;CAC3C,OAAO,cAAc;CAErB,OAAO,iBAAiB;EAEvB,IAAI,OAAO,aAAa,OAAO,cAAc;CAC9C,GAAG,EAAE;AACN"}