@radix-ng/primitives 1.0.0-beta.2 → 1.0.0-beta.4
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 +1 -1
- package/README.md +76 -6
- package/fesm2022/radix-ng-primitives-accordion.mjs +5 -3
- package/fesm2022/radix-ng-primitives-accordion.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-alert-dialog.mjs +31 -24
- package/fesm2022/radix-ng-primitives-alert-dialog.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-autocomplete.mjs +1744 -0
- package/fesm2022/radix-ng-primitives-autocomplete.mjs.map +1 -0
- package/fesm2022/radix-ng-primitives-calendar.mjs +5 -3
- package/fesm2022/radix-ng-primitives-calendar.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-combobox.mjs +1399 -606
- package/fesm2022/radix-ng-primitives-combobox.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-config.mjs +13 -4
- package/fesm2022/radix-ng-primitives-config.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-context-menu.mjs +51 -10
- package/fesm2022/radix-ng-primitives-context-menu.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-core.mjs +1345 -64
- package/fesm2022/radix-ng-primitives-core.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-date-field.mjs +5 -3
- package/fesm2022/radix-ng-primitives-date-field.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-dialog.mjs +271 -145
- package/fesm2022/radix-ng-primitives-dialog.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-direction-provider.mjs +70 -0
- package/fesm2022/radix-ng-primitives-direction-provider.mjs.map +1 -0
- package/fesm2022/radix-ng-primitives-dismissable-layer.mjs +519 -184
- package/fesm2022/radix-ng-primitives-dismissable-layer.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-drawer.mjs +154 -64
- package/fesm2022/radix-ng-primitives-drawer.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-field.mjs +3 -2
- package/fesm2022/radix-ng-primitives-field.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-floating-focus-manager.mjs +517 -0
- package/fesm2022/radix-ng-primitives-floating-focus-manager.mjs.map +1 -0
- package/fesm2022/radix-ng-primitives-focus-scope.mjs +296 -70
- package/fesm2022/radix-ng-primitives-focus-scope.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-menu.mjs +894 -299
- package/fesm2022/radix-ng-primitives-menu.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-menubar.mjs +32 -4
- package/fesm2022/radix-ng-primitives-menubar.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-navigation-menu.mjs +176 -207
- package/fesm2022/radix-ng-primitives-navigation-menu.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-popover.mjs +250 -250
- package/fesm2022/radix-ng-primitives-popover.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-popper.mjs +94 -45
- package/fesm2022/radix-ng-primitives-popper.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-portal.mjs +107 -17
- package/fesm2022/radix-ng-primitives-portal.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-presence.mjs +262 -79
- package/fesm2022/radix-ng-primitives-presence.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-preview-card.mjs +172 -218
- package/fesm2022/radix-ng-primitives-preview-card.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-roving-focus.mjs +4 -2
- package/fesm2022/radix-ng-primitives-roving-focus.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-scroll-area.mjs +5 -4
- package/fesm2022/radix-ng-primitives-scroll-area.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-select.mjs +303 -234
- package/fesm2022/radix-ng-primitives-select.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-slider.mjs +5 -3
- package/fesm2022/radix-ng-primitives-slider.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-stepper.mjs +5 -3
- package/fesm2022/radix-ng-primitives-stepper.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-time-field.mjs +5 -3
- package/fesm2022/radix-ng-primitives-time-field.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-toast.mjs +15 -36
- package/fesm2022/radix-ng-primitives-toast.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-toggle-group.mjs +5 -3
- package/fesm2022/radix-ng-primitives-toggle-group.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-toolbar.mjs +5 -3
- package/fesm2022/radix-ng-primitives-toolbar.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-tooltip.mjs +105 -145
- package/fesm2022/radix-ng-primitives-tooltip.mjs.map +1 -1
- package/package.json +14 -1
- package/types/radix-ng-primitives-accordion.d.ts +4 -3
- package/types/radix-ng-primitives-alert-dialog.d.ts +17 -11
- package/types/radix-ng-primitives-autocomplete.d.ts +661 -0
- package/types/radix-ng-primitives-calendar.d.ts +5 -3
- package/types/radix-ng-primitives-combobox.d.ts +727 -293
- package/types/radix-ng-primitives-config.d.ts +1 -1
- package/types/radix-ng-primitives-context-menu.d.ts +15 -5
- package/types/radix-ng-primitives-core.d.ts +762 -14
- package/types/radix-ng-primitives-date-field.d.ts +3 -2
- package/types/radix-ng-primitives-dialog.d.ts +107 -55
- package/types/radix-ng-primitives-direction-provider.d.ts +41 -0
- package/types/radix-ng-primitives-dismissable-layer.d.ts +147 -99
- package/types/radix-ng-primitives-drawer.d.ts +49 -22
- package/types/radix-ng-primitives-field.d.ts +1 -0
- package/types/radix-ng-primitives-floating-focus-manager.d.ts +175 -0
- package/types/radix-ng-primitives-focus-scope.d.ts +132 -1
- package/types/radix-ng-primitives-menu.d.ts +204 -112
- package/types/radix-ng-primitives-navigation-menu.d.ts +61 -101
- package/types/radix-ng-primitives-popover.d.ts +82 -115
- package/types/radix-ng-primitives-popper.d.ts +46 -10
- package/types/radix-ng-primitives-portal.d.ts +53 -8
- package/types/radix-ng-primitives-presence.d.ts +98 -17
- package/types/radix-ng-primitives-preview-card.d.ts +63 -95
- package/types/radix-ng-primitives-roving-focus.d.ts +7 -6
- package/types/radix-ng-primitives-scroll-area.d.ts +2 -2
- package/types/radix-ng-primitives-select.d.ts +192 -158
- package/types/radix-ng-primitives-slider.d.ts +5 -4
- package/types/radix-ng-primitives-stepper.d.ts +4 -3
- package/types/radix-ng-primitives-time-field.d.ts +3 -2
- package/types/radix-ng-primitives-toast.d.ts +7 -7
- package/types/radix-ng-primitives-toggle-group.d.ts +5 -4
- package/types/radix-ng-primitives-toolbar.d.ts +3 -2
- package/types/radix-ng-primitives-tooltip.d.ts +48 -84
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { Type, Provider, InputSignal, WritableSignal, ModelSignal, Signal, InjectionToken, InputSignalWithTransform, OutputRef,
|
|
2
|
+
import { Type, Provider, InputSignal, WritableSignal, ModelSignal, Signal, InjectionToken, InputSignalWithTransform, OutputRef, Injector, ElementRef, EffectRef, EffectCleanupRegisterFn, CreateEffectOptions } from '@angular/core';
|
|
3
3
|
import { ControlValueAccessor } from '@angular/forms';
|
|
4
4
|
import { DateValue, Time, CalendarDateTime, ZonedDateTime } from '@internationalized/date';
|
|
5
|
+
import * as _radix_ng_primitives_core from '@radix-ng/primitives/core';
|
|
5
6
|
|
|
6
7
|
type DataOrientation = 'vertical' | 'horizontal';
|
|
7
8
|
/** Layout direction for bidirectional text. */
|
|
@@ -548,6 +549,74 @@ declare function handleCalendarInitialFocus(calendar: HTMLElement): void;
|
|
|
548
549
|
declare function normalizeHourCycle(hourCycle: HourCycle): "h11" | "h23" | undefined;
|
|
549
550
|
declare function normalizeHour12(hourCycle: HourCycle): boolean | undefined;
|
|
550
551
|
|
|
552
|
+
/**
|
|
553
|
+
* Base URL of the documentation site. Each primitive's docs are also served as plain
|
|
554
|
+
* Markdown at `/<section>/<slug>.md`, which both humans and AI agents can open.
|
|
555
|
+
*/
|
|
556
|
+
declare const DOCS_BASE_URL = "https://radix-ng.com";
|
|
557
|
+
/**
|
|
558
|
+
* Full URL to a primitive's plain-Markdown docs page.
|
|
559
|
+
* @param docsPath Documentation path for the owning primitive (e.g. `'components/select'`).
|
|
560
|
+
*/
|
|
561
|
+
declare function docsUrl(docsPath: string): string;
|
|
562
|
+
/**
|
|
563
|
+
* Emits a deduplicated dev-mode `console.warn` for a recoverable misuse.
|
|
564
|
+
*
|
|
565
|
+
* No-op outside `isDevMode()`, so production builds stay silent (and the message
|
|
566
|
+
* assembly tree-shakes out). Dedupes per `code` per page load, replacing the
|
|
567
|
+
* hand-rolled `warned` flags individual primitives used to carry.
|
|
568
|
+
*
|
|
569
|
+
* @param code Stable, greppable `<primitive>/<slug>` identifier (e.g. `'select/trigger-element'`).
|
|
570
|
+
* @param message Human-readable explanation of the misuse and how to fix it.
|
|
571
|
+
* @param docsPath Optional docs path appended as a `See <url>` hint (e.g. `'components/select'`).
|
|
572
|
+
*/
|
|
573
|
+
declare function rdxDevWarning(code: string, message: string, docsPath?: string): void;
|
|
574
|
+
/**
|
|
575
|
+
* Throws a dev-mode `Error` for unrecoverable misuse (broken markup that cannot work).
|
|
576
|
+
*
|
|
577
|
+
* Unlike {@link rdxDevWarning} this always throws when reached — callers that want the
|
|
578
|
+
* check to stay dev-only should guard the call with `isDevMode()`.
|
|
579
|
+
*
|
|
580
|
+
* @param code Stable, greppable `<primitive>/<slug>` identifier (e.g. `'popover/portal-on-element'`).
|
|
581
|
+
* @param message Human-readable explanation of the misuse and how to fix it.
|
|
582
|
+
* @param docsPath Optional docs path appended as a `See <url>` hint (e.g. `'components/popover'`).
|
|
583
|
+
*/
|
|
584
|
+
declare function rdxDevError(code: string, message: string, docsPath?: string): never;
|
|
585
|
+
/**
|
|
586
|
+
* Test-only: clears the per-code dedup set so warning specs stay isolated from one another.
|
|
587
|
+
*/
|
|
588
|
+
declare function resetRdxDevWarnings(): void;
|
|
589
|
+
/**
|
|
590
|
+
* Dev-mode check: warns when a trigger part sits on a host element that is neither natively
|
|
591
|
+
* interactive (`<button>`, `<a>`, `<input>`) nor made focusable with `tabindex`.
|
|
592
|
+
*
|
|
593
|
+
* Only meaningful for triggers whose selector accepts arbitrary elements **and** that do not
|
|
594
|
+
* adapt their own ARIA/keyboard handling for non-button hosts — triggers scoped to
|
|
595
|
+
* `button[...]` already enforce this at the selector level, and triggers that auto-apply
|
|
596
|
+
* `role`/`tabindex` (e.g. `rdxMenuTrigger`) handle it themselves.
|
|
597
|
+
*
|
|
598
|
+
* Must be called inside an injection context (a directive constructor), where the host element
|
|
599
|
+
* already exists. No-op outside `isDevMode()` and on synthetic hosts (component / `ng-template`),
|
|
600
|
+
* where `HOST_TAG_NAME` is absent.
|
|
601
|
+
*
|
|
602
|
+
* @param triggerName Selector name used in the message, e.g. `'rdxPreviewCardTrigger'`.
|
|
603
|
+
* @param code Stable diagnostics code, e.g. `'preview-card/trigger-element'`.
|
|
604
|
+
* @param docsPath Docs path for the See-link, e.g. `'components/preview-card'`.
|
|
605
|
+
*/
|
|
606
|
+
declare function rdxCheckTriggerElement(triggerName: string, code: string, docsPath: string): void;
|
|
607
|
+
/**
|
|
608
|
+
* Dev-mode check: warns when a label part sits on a non-`<label>` host. The `for` attribute only
|
|
609
|
+
* associates a `<label>` with a control, so a label part placed on any other element is not
|
|
610
|
+
* programmatically connected to its control.
|
|
611
|
+
*
|
|
612
|
+
* Must be called inside an injection context. No-op outside `isDevMode()` and on synthetic hosts.
|
|
613
|
+
*
|
|
614
|
+
* @param labelName Selector name used in the message, e.g. `'rdxFieldLabel'`.
|
|
615
|
+
* @param code Stable diagnostics code, e.g. `'field/unassociated-label'`.
|
|
616
|
+
* @param docsPath Docs path for the See-link, e.g. `'components/field'`.
|
|
617
|
+
*/
|
|
618
|
+
declare function rdxCheckLabelElement(labelName: string, code: string, docsPath: string): void;
|
|
619
|
+
|
|
551
620
|
declare function handleAndDispatchCustomEvent<E extends CustomEvent, OriginalEvent extends Event>(name: string, handler: ((event: E) => void) | undefined, detail: {
|
|
552
621
|
originalEvent: OriginalEvent;
|
|
553
622
|
} & (E extends CustomEvent<infer D> ? D : never)): void;
|
|
@@ -790,6 +859,658 @@ interface RdxFormCheckboxControl extends RdxFormUiControl {
|
|
|
790
859
|
readonly value?: undefined;
|
|
791
860
|
}
|
|
792
861
|
|
|
862
|
+
interface RdxCancelableChangeEventDetails<Reason extends string = string> {
|
|
863
|
+
reason: Reason;
|
|
864
|
+
event: Event;
|
|
865
|
+
trigger: HTMLElement | undefined;
|
|
866
|
+
cancel: () => void;
|
|
867
|
+
isCanceled: () => boolean;
|
|
868
|
+
preventUnmountOnClose: () => void;
|
|
869
|
+
}
|
|
870
|
+
interface RdxCancelableChangeEventTransaction<Reason extends string = string> {
|
|
871
|
+
eventDetails: RdxCancelableChangeEventDetails<Reason>;
|
|
872
|
+
shouldPreventUnmountOnClose: () => boolean;
|
|
873
|
+
}
|
|
874
|
+
declare function createCancelableChangeEventDetails<Reason extends string>(reason: Reason, event: Event, trigger?: HTMLElement): RdxCancelableChangeEventTransaction<Reason>;
|
|
875
|
+
|
|
876
|
+
/**
|
|
877
|
+
* The typed event map for the **shared tree-level coordination channel** on {@link RdxFloatingTree}.
|
|
878
|
+
* Neutral by design — it ships no events initially. Each capability (hover-close, virtual focus, menu
|
|
879
|
+
* coordination, list navigation) **augments** this interface via module augmentation rather than
|
|
880
|
+
* emitting untyped strings:
|
|
881
|
+
*
|
|
882
|
+
* ```ts
|
|
883
|
+
* declare module '@radix-ng/primitives/core' {
|
|
884
|
+
* interface RdxFloatingEventMap {
|
|
885
|
+
* virtualfocus: { id: string; element: HTMLElement | null };
|
|
886
|
+
* }
|
|
887
|
+
* }
|
|
888
|
+
* ```
|
|
889
|
+
*
|
|
890
|
+
* **`openchange` belongs here only per-popup, not per-tree.** Base UI emits `openchange` on the
|
|
891
|
+
* per-popup `FloatingRootStore.events` (`FloatingRootStore.ts:121`), not on the shared
|
|
892
|
+
* `FloatingTreeStore.events`. For open-state changes, use {@link RdxFloatingRootContextEventMap} on
|
|
893
|
+
* the popup's {@link RdxFloatingRootContext.events}, not this tree-level channel.
|
|
894
|
+
*/
|
|
895
|
+
interface RdxFloatingEventMap {
|
|
896
|
+
}
|
|
897
|
+
/**
|
|
898
|
+
* The typed event map for the **per-popup events channel** on {@link RdxFloatingRootContext} —
|
|
899
|
+
* the Angular counterpart of Base UI's `FloatingRootStore.events` (`FloatingRootStore.ts:121`).
|
|
900
|
+
* Unlike the tree channel (one per coordinating root shared by all nested popups), this channel
|
|
901
|
+
* lives **on the root context** so each popup has its own scoped emitter with no cross-popup bleed.
|
|
902
|
+
*/
|
|
903
|
+
interface RdxFloatingRootContextEventMap {
|
|
904
|
+
/** The popup's open-state changed. `reason` mirrors Base UI open-change reason strings. */
|
|
905
|
+
openchange: {
|
|
906
|
+
open: boolean;
|
|
907
|
+
reason?: string;
|
|
908
|
+
event?: Event;
|
|
909
|
+
};
|
|
910
|
+
}
|
|
911
|
+
/**
|
|
912
|
+
* Neutral typed event channel — the Angular counterpart of Base UI's `createEventEmitter()`, typed
|
|
913
|
+
* over `M` (a {@link RdxFloatingEventMap} sub-type for tree-level or a
|
|
914
|
+
* {@link RdxFloatingRootContextEventMap} sub-type for per-popup).
|
|
915
|
+
*/
|
|
916
|
+
interface RdxFloatingEvents<M extends object = RdxFloatingEventMap> {
|
|
917
|
+
emit<K extends keyof M>(event: K, data: M[K]): void;
|
|
918
|
+
on<K extends keyof M>(event: K, listener: (data: M[K]) => void): void;
|
|
919
|
+
off<K extends keyof M>(event: K, listener: (data: M[K]) => void): void;
|
|
920
|
+
}
|
|
921
|
+
/**
|
|
922
|
+
* Creates an {@link RdxFloatingEvents} emitter backed by `Map<event, Set<listener>>`, mirroring Base
|
|
923
|
+
* UI's implementation: synchronous dispatch, set-deduplicated listeners, no replay.
|
|
924
|
+
*
|
|
925
|
+
* **Snapshot dispatch:** `emit()` snapshots the listener set before iterating so that a listener
|
|
926
|
+
* calling `on()`/`off()` during dispatch does not cause skip/revisit issues.
|
|
927
|
+
*/
|
|
928
|
+
declare function createFloatingEvents<M extends object = RdxFloatingEventMap>(): RdxFloatingEvents<M>;
|
|
929
|
+
|
|
930
|
+
/**
|
|
931
|
+
* The shared **mounted / open** lifecycle contract every floating capability reads (ADR 0015 §1,
|
|
932
|
+
* cross-cutting across ADRs 0015/0016/0017). It separates *presence* from *activeness*, which Base
|
|
933
|
+
* UI keeps distinct (`DialogStore` / `popupStoreUtils`):
|
|
934
|
+
*
|
|
935
|
+
* - **`mounted()`** — the node/popup is rendered. Stays `true` through an animated exit (Base UI's
|
|
936
|
+
* `FloatingFocusManager` is `disabled={!mounted}`, so the focus trap survives the exit).
|
|
937
|
+
* - **`open()`** — the popup is logically open. Flips to `false` **immediately** on close, *before*
|
|
938
|
+
* unmount.
|
|
939
|
+
*
|
|
940
|
+
* The interesting middle state is **closed-but-mounted** (`mounted() && !open()`): an animated exit,
|
|
941
|
+
* or a popup deliberately kept mounted after close. Its effects are **per-effect**, matching Base UI
|
|
942
|
+
* (it is *not* "everything off"):
|
|
943
|
+
*
|
|
944
|
+
* | concern | on `open() === false` (still mounted) |
|
|
945
|
+
* | -------------------------------- | ------------------------------------- |
|
|
946
|
+
* | dismissal (Escape/outside-press) | **inactive** — capability reads `open()` |
|
|
947
|
+
* | `markOthers` marker / aria-hidden| **released** |
|
|
948
|
+
* | internal backdrop | **`inert`** |
|
|
949
|
+
* | scroll lock | **unlocked** (predicate keys off `open()`) |
|
|
950
|
+
* | focus trap + return-focus | **persist until unmount** (read `mounted()`) |
|
|
951
|
+
*
|
|
952
|
+
* So every consumer reads `open()` for behavior and `mounted()` for presence — never conflating them.
|
|
953
|
+
*
|
|
954
|
+
* @remarks
|
|
955
|
+
* `preventUnmountOnClose` (Base UI's per-close one-shot that holds a popup *mounted after close*) is a
|
|
956
|
+
* **close-transaction** concern, not a standing boolean — modeling it as a persistent
|
|
957
|
+
* `signal<boolean>` would pin the popup mounted forever after the first prevented close. Whether Radix
|
|
958
|
+
* exposes it publicly or maps it onto `RdxPortalPresence` (keep-mounted) is pinned in ADR 0015/0017
|
|
959
|
+
* Phase 0; it is intentionally **not** baked into this contract.
|
|
960
|
+
*/
|
|
961
|
+
interface RdxFloatingLifecycle {
|
|
962
|
+
/** Presence: the node/popup is rendered (stays `true` during an animated exit). */
|
|
963
|
+
readonly mounted: () => boolean;
|
|
964
|
+
/** Activeness: the popup is open (flips `false` immediately on close, before unmount). */
|
|
965
|
+
readonly open: () => boolean;
|
|
966
|
+
}
|
|
967
|
+
|
|
968
|
+
/**
|
|
969
|
+
* Per-popup store of active **trigger** elements — the Angular counterpart of Base UI's
|
|
970
|
+
* `triggerElements` (`PopupTriggerMap`) on each `FloatingRootStore`. One registry lives on each
|
|
971
|
+
* {@link RdxFloatingRootContext} (NOT on the shared tree, and NOT on the node — the context can exist
|
|
972
|
+
* without a node, e.g. the node-optional Navigation Menu case). Scoping it per-context is what keeps
|
|
973
|
+
* one independent popup's trigger from counting as inside-content for an unrelated popup.
|
|
974
|
+
*
|
|
975
|
+
* Within its context it is read by **both** the dismissal engine (ADR 0015 — outside-press / focus-out
|
|
976
|
+
* containment) and the focus manager (ADR 0017 — inside-element checks), so the two never drift into
|
|
977
|
+
* different inside-element sets (ADR 0015 §1 pillar 3, §2). A trigger is plain inside-content: it has
|
|
978
|
+
* **no** floating node and **no** parent — only its membership is stored here.
|
|
979
|
+
*
|
|
980
|
+
* Matching mirrors Base UI's `isTargetInsideEnabledTrigger`: a target counts when it is exactly a
|
|
981
|
+
* registered element ({@link hasElement}) **or** a descendant of one ({@link hasMatchingElement}).
|
|
982
|
+
* Membership is by **reference** (`Set.has` / `Node.contains`), so it stays correct **cross-realm** for
|
|
983
|
+
* elements from another `Window` / iframe — where `target instanceof Element` against the local realm
|
|
984
|
+
* would wrongly return `false`.
|
|
985
|
+
*/
|
|
986
|
+
declare class RdxTriggerRegistry {
|
|
987
|
+
private readonly elements;
|
|
988
|
+
/** Registers `element` as a trigger. Idempotent. */
|
|
989
|
+
add(element: Element): void;
|
|
990
|
+
/** Removes `element` from the registry. */
|
|
991
|
+
delete(element: Element): void;
|
|
992
|
+
/**
|
|
993
|
+
* Exact membership — Base UI `triggerElements.hasElement(target)`. Uses reference identity
|
|
994
|
+
* (`Set.has`), **not** `instanceof Element`, so a trigger from another realm/iframe still matches.
|
|
995
|
+
*/
|
|
996
|
+
hasElement(target: EventTarget | Node | null): boolean;
|
|
997
|
+
/**
|
|
998
|
+
* Ancestor match — Base UI `hasMatchingElement((t) => contains(t, target))`: `true` when any
|
|
999
|
+
* registered trigger contains `target`. Catches a press/focus landing on a child of the trigger.
|
|
1000
|
+
*/
|
|
1001
|
+
hasMatchingElement(target: Node | null): boolean;
|
|
1002
|
+
/** `true` when `target` is a registered trigger or lives inside one. */
|
|
1003
|
+
contains(target: EventTarget | Node | null): boolean;
|
|
1004
|
+
}
|
|
1005
|
+
|
|
1006
|
+
/** Initialization for a {@link RdxFloatingRootContext}. */
|
|
1007
|
+
interface RdxFloatingRootContextInit {
|
|
1008
|
+
ownerDocument: Document;
|
|
1009
|
+
/** Popup open-state lifecycle. Defaults to `() => false`. */
|
|
1010
|
+
open?: () => boolean;
|
|
1011
|
+
floatingElement?: HTMLElement | null;
|
|
1012
|
+
referenceElement?: Element | null;
|
|
1013
|
+
}
|
|
1014
|
+
/**
|
|
1015
|
+
* The per-popup **root context / store** — the Angular counterpart of Base UI's `FloatingRootStore`
|
|
1016
|
+
* (`FloatingRootContext`). It is a **separate entity from {@link RdxFloatingNode}** (which is only
|
|
1017
|
+
* `id` + `parent` + a context ref), mirroring Base UI: the node carries tree membership, the root
|
|
1018
|
+
* context carries the popup's `open`, elements, and trigger registry.
|
|
1019
|
+
*
|
|
1020
|
+
* Crucially it can exist **without** a node — the `getEmptyRootContext()` analog ({@link
|
|
1021
|
+
* createFloatingRootContext}) — which is what lets a **node-optional** capability (Navigation Menu,
|
|
1022
|
+
* ADR 0015 §1 / ADR 0017 #12) still read `open()`, `triggers`, and the elements while its tree node is
|
|
1023
|
+
* temporarily absent. A dismissal/focus capability therefore references a root context **mandatorily**
|
|
1024
|
+
* and a node **optionally**.
|
|
1025
|
+
*
|
|
1026
|
+
* `floatingElement` / `referenceElement` are exposed read-only and mutated **only** through the
|
|
1027
|
+
* validated setters, so a consumer cannot bypass the owner-`Document` invariant with a raw assignment.
|
|
1028
|
+
*/
|
|
1029
|
+
declare class RdxFloatingRootContext {
|
|
1030
|
+
readonly ownerDocument: Document;
|
|
1031
|
+
/** Neutral popup open-state lifecycle (singular). Tree traversal's `onlyOpen` filter reads this. */
|
|
1032
|
+
readonly open: () => boolean;
|
|
1033
|
+
/** Per-popup trigger registry (Base UI `triggerElements`), read by both dismissal and focus. */
|
|
1034
|
+
readonly triggers: RdxTriggerRegistry;
|
|
1035
|
+
/**
|
|
1036
|
+
* Per-popup typed event channel (Base UI `FloatingRootStore.events`). Scoped to this popup,
|
|
1037
|
+
* so open-change events carry no cross-popup bleed. Use `events.emit('openchange', …)` when
|
|
1038
|
+
* the popup's `open` state changes; dismissal / focus manager subscribe here, not on the tree.
|
|
1039
|
+
*/
|
|
1040
|
+
readonly events: RdxFloatingEvents<RdxFloatingRootContextEventMap>;
|
|
1041
|
+
private floatingElementRef;
|
|
1042
|
+
private referenceElementRef;
|
|
1043
|
+
private readonly floatingElementsRef;
|
|
1044
|
+
constructor(init: RdxFloatingRootContextInit);
|
|
1045
|
+
/** The floating (popup) element, once it renders. `null` while mounted-but-not-yet-rendered. */
|
|
1046
|
+
get floatingElement(): HTMLElement | null;
|
|
1047
|
+
/** The reference (anchor / trigger) element the popup is positioned against. */
|
|
1048
|
+
get referenceElement(): Element | null;
|
|
1049
|
+
/**
|
|
1050
|
+
* **All** of this layer's own root elements — the popup plus any extra roots a primitive owns (e.g.
|
|
1051
|
+
* a Dialog backdrop relocated as a separate body sibling). This is DOM-footprint bookkeeping for
|
|
1052
|
+
* primitive-specific checks; `markOthers` keep-sets are intentionally narrower and do not include
|
|
1053
|
+
* sibling roots such as backdrops. Distinct from {@link floatingElement} (the single popup, used for
|
|
1054
|
+
* press / focus containment).
|
|
1055
|
+
*/
|
|
1056
|
+
get floatingElements(): ReadonlySet<Element>;
|
|
1057
|
+
/** Assigns the floating (popup) element, validating it shares this context's `ownerDocument`. */
|
|
1058
|
+
setFloatingElement(element: HTMLElement | null): void;
|
|
1059
|
+
/** Registers an additional owned root element (e.g. a backdrop) into {@link floatingElements}. */
|
|
1060
|
+
addFloatingElement(element: Element): void;
|
|
1061
|
+
/** Removes a previously {@link addFloatingElement | added} owned root element. */
|
|
1062
|
+
removeFloatingElement(element: Element): void;
|
|
1063
|
+
/** Assigns the reference element, validating it shares this context's `ownerDocument`. */
|
|
1064
|
+
setReferenceElement(element: Element | null): void;
|
|
1065
|
+
private assertSameDocument;
|
|
1066
|
+
}
|
|
1067
|
+
/**
|
|
1068
|
+
* Creates a standalone {@link RdxFloatingRootContext} **without** a tree node — the Angular counterpart
|
|
1069
|
+
* of Base UI's `getEmptyRootContext()`. Use it for a node-optional capability that needs a root context
|
|
1070
|
+
* before (or without) registering a floating node.
|
|
1071
|
+
*/
|
|
1072
|
+
declare function createFloatingRootContext(init: RdxFloatingRootContextInit): RdxFloatingRootContext;
|
|
1073
|
+
|
|
1074
|
+
/**
|
|
1075
|
+
* Module-private construction key. The {@link RdxFloatingNode} constructor requires it, and its type is
|
|
1076
|
+
* a non-exported `unique symbol`, so consumers can neither name it (compile error) nor produce it
|
|
1077
|
+
* (runtime guard) — a node can only be created through {@link RdxFloatingTree.register}, never a loose
|
|
1078
|
+
* `new RdxFloatingNode(...)` that would exist outside `tree.all`.
|
|
1079
|
+
*/
|
|
1080
|
+
declare const NODE_CONSTRUCT_KEY: unique symbol;
|
|
1081
|
+
/**
|
|
1082
|
+
* A neutral node in the shared floating tree — the Angular counterpart of Base UI's `FloatingNode`
|
|
1083
|
+
* (`{ id, parentId, context? }`). It is deliberately **lightweight**: tree membership only. The
|
|
1084
|
+
* popup's `open` state, trigger registry, and elements live on the separate {@link
|
|
1085
|
+
* RdxFloatingRootContext}, exactly as Base UI splits `FloatingNode` from `FloatingRootStore`.
|
|
1086
|
+
*
|
|
1087
|
+
* `parent` and `context` are exposed **read-only**; they are mutated **only** through {@link
|
|
1088
|
+
* RdxFloatingTree.setParent} / {@link RdxFloatingTree.setContext} (which enforce the cycle and
|
|
1089
|
+
* owner-`Document` invariants). The backing state is held in a module-private `WeakMap`, so a consumer
|
|
1090
|
+
* cannot reach around the tree with `node.parent = …` / `node.context = …`.
|
|
1091
|
+
*
|
|
1092
|
+
* `context` may be `null` (a contextless intermediate node). Open-ness is read from the context — there
|
|
1093
|
+
* is no `open` on the node — and tree traversal's `onlyOpen` filter reads `node.context?.open()`,
|
|
1094
|
+
* mirroring Base UI's `getNodeChildren` filtering on `child.context?.open`. Presence (`mounted`) is
|
|
1095
|
+
* implicit: a node is mounted **iff** it is registered in the tree.
|
|
1096
|
+
*/
|
|
1097
|
+
declare class RdxFloatingNode {
|
|
1098
|
+
readonly id: string;
|
|
1099
|
+
/** Which tree (store) this node belongs to — Base UI's `externalTree`. */
|
|
1100
|
+
readonly tree: RdxFloatingTree;
|
|
1101
|
+
/** @internal — constructed only by {@link RdxFloatingTree.register} (guarded by a module-private key). */
|
|
1102
|
+
constructor(construct: typeof NODE_CONSTRUCT_KEY, id: string, tree: RdxFloatingTree, parent: RdxFloatingNode | null, context: RdxFloatingRootContext | null);
|
|
1103
|
+
/** Resolved **logical** parent (DI-derived). Reassign via {@link RdxFloatingTree.setParent}. */
|
|
1104
|
+
get parent(): RdxFloatingNode | null;
|
|
1105
|
+
/** The per-popup root context/store. `null` for a contextless node. Reassign via `tree.setContext`. */
|
|
1106
|
+
get context(): RdxFloatingRootContext | null;
|
|
1107
|
+
}
|
|
1108
|
+
/**
|
|
1109
|
+
* Discriminated parent-assignment override (ADR 0015 §1). A nullable optional would collapse
|
|
1110
|
+
* `undefined`/`null` in Angular signals, so "no override" (`inherit`) and "explicit independent root"
|
|
1111
|
+
* (`root`) must be **distinct** values — they must not both reduce to `parent == null`.
|
|
1112
|
+
*/
|
|
1113
|
+
type RdxFloatingParentOverride = {
|
|
1114
|
+
kind: 'inherit';
|
|
1115
|
+
} | {
|
|
1116
|
+
kind: 'root';
|
|
1117
|
+
} | {
|
|
1118
|
+
kind: 'node';
|
|
1119
|
+
parent: RdxFloatingNode;
|
|
1120
|
+
};
|
|
1121
|
+
/** Initialization for {@link RdxFloatingTree.register}. The caller resolves `inherit` before calling. */
|
|
1122
|
+
interface RdxFloatingNodeInit {
|
|
1123
|
+
id: string;
|
|
1124
|
+
/** Already-resolved logical parent (`null` for a root). */
|
|
1125
|
+
parent: RdxFloatingNode | null;
|
|
1126
|
+
/** The per-popup root context. `null` for a contextless intermediate node. */
|
|
1127
|
+
context: RdxFloatingRootContext | null;
|
|
1128
|
+
}
|
|
1129
|
+
/**
|
|
1130
|
+
* The shared floating tree (node store) — the Angular counterpart of Base UI's `FloatingTreeStore`.
|
|
1131
|
+
*
|
|
1132
|
+
* It owns a flat set of {@link RdxFloatingNode | nodes} linked by `parent`, an adjacency index for
|
|
1133
|
+
* O(1) child lookup, and a neutral typed {@link RdxFloatingEvents | event channel}. It owns **neither**
|
|
1134
|
+
* trigger registries **nor** `open` state — those live per-popup on each {@link RdxFloatingRootContext}
|
|
1135
|
+
* (Base UI keeps them on the root store, not the tree store). Dismissal (ADR 0015) and the focus
|
|
1136
|
+
* manager (ADR 0017) read the **same** nodes, traversal, and events; neither owns the tree.
|
|
1137
|
+
*
|
|
1138
|
+
* Ancestry is **logical** (DI-derived), not DOM-derived, so portal relocation never changes ownership
|
|
1139
|
+
* (ADR 0015 §1). Independent roots are **not** coordinated against each other (Base UI parity): the
|
|
1140
|
+
* tree only answers questions *within* itself.
|
|
1141
|
+
*
|
|
1142
|
+
* **Performance:** `isRegistered()` is O(1) via `nodeSet`; `directChildren()` is O(1) via the
|
|
1143
|
+
* `childrenOf` adjacency map; `ancestors()` is O(depth); `children()` is O(n) total.
|
|
1144
|
+
*/
|
|
1145
|
+
declare class RdxFloatingTree {
|
|
1146
|
+
/**
|
|
1147
|
+
* Neutral typed event channel (hover-close, virtual focus, menu coordination, list nav). Private to
|
|
1148
|
+
* this tree, which is scoped-by-default (one per coordinating root via `provideFloatingTree()`), so
|
|
1149
|
+
* events never leak across unrelated popups — matching Base UI's per-`FloatingTree` events.
|
|
1150
|
+
*/
|
|
1151
|
+
readonly events: RdxFloatingEvents;
|
|
1152
|
+
/** O(1) membership test and snapshot for `all`. */
|
|
1153
|
+
private readonly nodeSet;
|
|
1154
|
+
/**
|
|
1155
|
+
* Adjacency index: maps each node (or `null` for root nodes) to its direct children in
|
|
1156
|
+
* registration order. Maintained in sync by `register`, `unregister`, and `setParent`.
|
|
1157
|
+
* Eliminates the O(n) `filter` per node in recursive traversal. Invariant: only **non-empty**
|
|
1158
|
+
* arrays are stored — an entry is pruned the moment its last child leaves, so a key never
|
|
1159
|
+
* outlives its node (see `removeFromChildrenOf`).
|
|
1160
|
+
*/
|
|
1161
|
+
private readonly childrenOf;
|
|
1162
|
+
/** Registers a new node. `init.parent` must already be resolved (DI layer handles `inherit`). */
|
|
1163
|
+
register(init: RdxFloatingNodeInit): RdxFloatingNode;
|
|
1164
|
+
/** Removes a node from the tree. Children are **not** removed — they keep their `parent` reference. */
|
|
1165
|
+
unregister(node: RdxFloatingNode): void;
|
|
1166
|
+
/**
|
|
1167
|
+
* Associates / re-associates / clears a node's root context after registration (Base UI attaches
|
|
1168
|
+
* the context once the floating element resolves). Validates the new context's owner-`Document`
|
|
1169
|
+
* against the nearest context-bearing **ancestor** (through contextless intermediates) **and**
|
|
1170
|
+
* every context-bearing **descendant**, so a contextless intermediate can never bridge two
|
|
1171
|
+
* documents. Allows the `null → context → null` lifecycle.
|
|
1172
|
+
*/
|
|
1173
|
+
setContext(node: RdxFloatingNode, context: RdxFloatingRootContext | null): void;
|
|
1174
|
+
/** Reparents an existing node (detached composition / explicit `node` override), with cycle guard. */
|
|
1175
|
+
setParent(node: RdxFloatingNode, parent: RdxFloatingNode | null): void;
|
|
1176
|
+
/**
|
|
1177
|
+
* Direct + transitive children, in registration order. The `onlyOpen` filter (default `true`)
|
|
1178
|
+
* filters the **result** by each node's `context?.open()` lifecycle but **never** aborts recursion
|
|
1179
|
+
* at a closed node, so a keep-mounted/closed parent never hides an open grandchild (Base UI
|
|
1180
|
+
* `getNodeChildren`, ADR 0015 §1 traversal contract).
|
|
1181
|
+
*
|
|
1182
|
+
* Dismissal children queries pass `onlyOpen: true` (the `hasBlockingChild` pattern in the
|
|
1183
|
+
* capability). The focus manager's focus-return check passes `onlyOpen: false` explicitly (Base UI
|
|
1184
|
+
* `FloatingFocusManager.tsx:842`) — so focus inside a closed-but-mounted descendant still counts as
|
|
1185
|
+
* "inside the tree". Always pass `onlyOpen` explicitly for non-dismissal paths; do not inherit the
|
|
1186
|
+
* default.
|
|
1187
|
+
*/
|
|
1188
|
+
children(node: RdxFloatingNode, options?: {
|
|
1189
|
+
onlyOpen?: boolean;
|
|
1190
|
+
}): RdxFloatingNode[];
|
|
1191
|
+
/**
|
|
1192
|
+
* Logical ancestors of `node`, nearest first (Base UI `getNodeAncestors`). The walk **stops at an
|
|
1193
|
+
* unregistered node**: Base UI resolves ancestry by `parentId` lookup in the live nodes array, so
|
|
1194
|
+
* unregistering a parent breaks the chain (a removed middle node truncates ancestry — its children
|
|
1195
|
+
* keep the raw `parent` identity but it no longer appears as an ancestor). This avoids a "ghost"
|
|
1196
|
+
* ancestor lingering in DI-ownership / document / dismissal/focus traversal when Angular destroys a
|
|
1197
|
+
* parent before its child.
|
|
1198
|
+
*/
|
|
1199
|
+
ancestors(node: RdxFloatingNode): RdxFloatingNode[];
|
|
1200
|
+
/** Snapshot of all registered nodes (debugging / diagnostics). Registration order is preserved. */
|
|
1201
|
+
get all(): readonly RdxFloatingNode[];
|
|
1202
|
+
/** Direct children of `parent` in registration order. O(1) via the adjacency map. */
|
|
1203
|
+
private directChildren;
|
|
1204
|
+
private addToChildrenOf;
|
|
1205
|
+
private removeFromChildrenOf;
|
|
1206
|
+
/**
|
|
1207
|
+
* Nearest context-bearing node walking up from `node` (inclusive), skipping contextless ancestors.
|
|
1208
|
+
* Stops at an unregistered node (same ghost-ancestry rule as {@link ancestors}).
|
|
1209
|
+
*/
|
|
1210
|
+
private nearestContext;
|
|
1211
|
+
/** All contexts among `node`'s transitive descendants (skips `node` itself). */
|
|
1212
|
+
private descendantContexts;
|
|
1213
|
+
/**
|
|
1214
|
+
* Dev-only: validates every context in `node`'s subtree (node + transitive descendants) against
|
|
1215
|
+
* the nearest context-bearing ancestor walking up from `newParent`. Shared between `setParent`
|
|
1216
|
+
* (moves a subtree under a new parent) to keep the document-consistency rule in one place.
|
|
1217
|
+
*/
|
|
1218
|
+
private assertSubtreeDocuments;
|
|
1219
|
+
/** Whether `node` is currently registered in this tree. O(1). */
|
|
1220
|
+
private isRegistered;
|
|
1221
|
+
/**
|
|
1222
|
+
* Guards that `node` actually belongs to **this** tree and is still registered — so a tree can
|
|
1223
|
+
* never mutate/traverse a node owned by another tree (which would leave `node.tree` pointing
|
|
1224
|
+
* elsewhere while its ancestry leads here) or one that was already unregistered.
|
|
1225
|
+
*/
|
|
1226
|
+
private assertOwnedNode;
|
|
1227
|
+
/** A parent (when given) must belong to this tree **and** still be registered. */
|
|
1228
|
+
private assertRegisterableParent;
|
|
1229
|
+
/** Owner-`Document` consistency between a node's context and a related (ancestor/descendant) context. */
|
|
1230
|
+
private assertContextDocument;
|
|
1231
|
+
}
|
|
1232
|
+
|
|
1233
|
+
/**
|
|
1234
|
+
* Registers a {@link RdxFloatingNode} into the shared {@link RdxFloatingTree} for its DI subtree and
|
|
1235
|
+
* propagates the registration handle to descendants — the reusable Angular counterpart of mounting a
|
|
1236
|
+
* Base UI `<FloatingNode>` (ADR 0015 §1, Phase 1). It is the **single** place that runs the handle
|
|
1237
|
+
* pattern; the dismissal capability (ADR 0015) and the focus manager (ADR 0017) **consume** the node /
|
|
1238
|
+
* context / tree it registers, they do not re-implement registration.
|
|
1239
|
+
*
|
|
1240
|
+
* **What it owns vs. what it reads.** It provides its own {@link RdxFloatingRegistrationContext} (so
|
|
1241
|
+
* descendants resolve it with `skipSelf`) and registers/unregisters a node reactively. It does **not**
|
|
1242
|
+
* create the tree or the root context — a coordination-boundary primitive root supplies those
|
|
1243
|
+
* (`provideFloatingTree()` inherit-or-create + `provideFloatingRootContext()`); this directive injects
|
|
1244
|
+
* them. With **no** enclosing tree it runs **node-optional** (`status() === 'detached'`, `node() ===
|
|
1245
|
+
* null`), reading its context directly — the standalone `rdxDismissableLayer` case.
|
|
1246
|
+
*
|
|
1247
|
+
* **Resolution (per {@link RdxFloatingParentOverride}).** Only an `inherit` node depends on the DI
|
|
1248
|
+
* parent, so only it waits on a `pending` parent; `root` / `node` overrides are independent and register
|
|
1249
|
+
* immediately. The node carries the injected {@link RDX_FLOATING_ROOT_CONTEXT} (or `null` for a
|
|
1250
|
+
* contextless intermediate). All teardown (re-resolution **and** destroy) unregisters the node and
|
|
1251
|
+
* reverts the handle.
|
|
1252
|
+
*/
|
|
1253
|
+
declare class RdxFloatingNodeRegistration {
|
|
1254
|
+
/** Explicit tree for detached sibling composition — Base UI's `externalTree`. */
|
|
1255
|
+
readonly externalTree: i0.InputSignal<RdxFloatingTree | null>;
|
|
1256
|
+
/** How this node's logical parent is resolved. Defaults to `inherit` (nearest DI ancestor). */
|
|
1257
|
+
readonly parentOverride: i0.InputSignal<RdxFloatingParentOverride>;
|
|
1258
|
+
/** Own handle — the WRITER side (concrete class); this directive is the only writer. */
|
|
1259
|
+
private readonly selfReg;
|
|
1260
|
+
/** Nearest ancestor handle — the READER side (reader-typed token), or `null` at the top. */
|
|
1261
|
+
private readonly parentReg;
|
|
1262
|
+
/** The enclosing tree, if a coordination boundary provided one (else node-optional). */
|
|
1263
|
+
private readonly ambientTree;
|
|
1264
|
+
/** This node's per-popup context, or `null` for a contextless intermediate node. */
|
|
1265
|
+
private readonly rootContext;
|
|
1266
|
+
private readonly nodeId;
|
|
1267
|
+
/** This directive's node once registered (`null` while `pending` / `detached`). */
|
|
1268
|
+
readonly node: Signal<RdxFloatingNode | null>;
|
|
1269
|
+
/** Lifecycle phase of this directive's registration (`pending` | `detached` | `registered`). */
|
|
1270
|
+
readonly status: Signal<_radix_ng_primitives_core.RdxFloatingRegistrationStatus>;
|
|
1271
|
+
/** The tree this node joined (`null` until `registered`). */
|
|
1272
|
+
readonly tree: Signal<RdxFloatingTree | null>;
|
|
1273
|
+
constructor();
|
|
1274
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<RdxFloatingNodeRegistration, never>;
|
|
1275
|
+
static ɵdir: i0.ɵɵDirectiveDeclaration<RdxFloatingNodeRegistration, "[rdxFloatingNode]", ["rdxFloatingNode"], { "externalTree": { "alias": "externalTree"; "required": false; "isSignal": true; }; "parentOverride": { "alias": "parentOverride"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
1276
|
+
}
|
|
1277
|
+
|
|
1278
|
+
/** The three lifecycle phases of a {@link RdxFloatingRegistrationContext} (see {@link RegistrationState}). */
|
|
1279
|
+
type RdxFloatingRegistrationStatus = 'pending' | 'detached' | 'registered';
|
|
1280
|
+
/**
|
|
1281
|
+
* The **read-only projection** of a registration handle — what a **descendant** injects (it reads its
|
|
1282
|
+
* nearest ancestor's handle to resolve its logical parent, ADR 0015 §1). It deliberately exposes only
|
|
1283
|
+
* the reactive reads (`status` / `tree` / `node`) and **not** the writers (`register` / `markDetached` /
|
|
1284
|
+
* `clear`), which belong solely to the directive that owns the handle: a descendant must never be able
|
|
1285
|
+
* to clear or re-point its parent's registration. The {@link RDX_FLOATING_REGISTRATION} token is typed
|
|
1286
|
+
* as this reader, so the ergonomic, cast-free injection path is read-only; the owning directive uses the
|
|
1287
|
+
* concrete {@link RdxFloatingRegistrationContext} type (the writer) for its own handle.
|
|
1288
|
+
*/
|
|
1289
|
+
interface RdxFloatingRegistrationReader {
|
|
1290
|
+
readonly status: Signal<RdxFloatingRegistrationStatus>;
|
|
1291
|
+
readonly tree: Signal<RdxFloatingTree | null>;
|
|
1292
|
+
readonly node: Signal<RdxFloatingNode | null>;
|
|
1293
|
+
}
|
|
1294
|
+
/**
|
|
1295
|
+
* A **stable DI handle** created at injector formation time and filled in at runtime once the
|
|
1296
|
+
* registration directive resolves its `externalTree` / `parentOverride` inputs.
|
|
1297
|
+
*
|
|
1298
|
+
* **Why a handle, not direct token replacement.** Angular injectors are sealed at creation — a
|
|
1299
|
+
* directive that resolves its tree from a runtime `externalTree` input cannot change what
|
|
1300
|
+
* `RDX_FLOATING_TREE` resolves to for its subtree afterwards. The handle is the object that _is_
|
|
1301
|
+
* provided at creation; its internal state signal changes at runtime. Descendants inject the handle
|
|
1302
|
+
* (with `skipSelf: true`) and read `parentReg.tree()` / `parentReg.node()` reactively — they never
|
|
1303
|
+
* depend on tokens being swapped post-construction.
|
|
1304
|
+
*
|
|
1305
|
+
* **Atomicity.** `tree` and `node` are **not** separate `WritableSignal`s — independent `.set()`
|
|
1306
|
+
* calls would create intermediate states where `node.tree !== tree`. Instead there is **one** private
|
|
1307
|
+
* {@link RegistrationState} signal; `register(tree, node)` sets the `registered` payload after asserting
|
|
1308
|
+
* `node.tree === tree`, `markDetached()` records "resolved, no node", and `clear()` reverts to
|
|
1309
|
+
* `pending`. The `tree`/`node`/`status` reads are `computed()` over that one signal, so they can never
|
|
1310
|
+
* disagree.
|
|
1311
|
+
*
|
|
1312
|
+
* **Registration directive usage pattern:**
|
|
1313
|
+
*
|
|
1314
|
+
* ```ts
|
|
1315
|
+
* @Directive({ providers: [provideFloatingRegistration()] })
|
|
1316
|
+
* class SomeFloatingDirective {
|
|
1317
|
+
* // Own handle — the WRITER side. Inject the concrete type so register()/markDetached()/clear() are
|
|
1318
|
+
* // available; this is the only place that writes this handle.
|
|
1319
|
+
* private readonly selfReg = inject(RdxFloatingRegistrationContext);
|
|
1320
|
+
* // Parent handle — the READER side (token is reader-typed). A descendant can read status/tree/node
|
|
1321
|
+
* // but cannot mutate the parent's registration.
|
|
1322
|
+
* private readonly parentReg = inject(RDX_FLOATING_REGISTRATION, { optional: true, skipSelf: true });
|
|
1323
|
+
* private readonly ambientTree = inject(RDX_FLOATING_TREE, { optional: true });
|
|
1324
|
+
*
|
|
1325
|
+
* constructor() {
|
|
1326
|
+
* effect((onCleanup) => {
|
|
1327
|
+
* const override = this.parentOverride(); // { kind: 'inherit' | 'root' | 'node' }
|
|
1328
|
+
*
|
|
1329
|
+
* // ONLY an `inherit` node depends on the DI parent, so only it waits on a `pending` parent (a
|
|
1330
|
+
* // `pending` parent is NOT "no parent"; reading status() subscribes us, so we re-run when it
|
|
1331
|
+
* // flips). `root` / `node` overrides are independent of the DI ancestor and register NOW —
|
|
1332
|
+
* // waiting on the DI parent would wrongly stall them, or strand them if that parent is destroyed.
|
|
1333
|
+
* if (override.kind === 'inherit' && this.parentReg?.status() === 'pending') return;
|
|
1334
|
+
*
|
|
1335
|
+
* // Logical parent from the override (DI parent only for `inherit`; a `detached` parent reads
|
|
1336
|
+
* // null → this node becomes a root in its tree).
|
|
1337
|
+
* const parentNode =
|
|
1338
|
+
* override.kind === 'node' ? override.parent
|
|
1339
|
+
* : override.kind === 'root' ? null
|
|
1340
|
+
* : (this.parentReg?.node() ?? null); // 'inherit'
|
|
1341
|
+
*
|
|
1342
|
+
* // Tree selection (resolveFloatingTree's logic; inject() is illegal inside effect()). A `node`
|
|
1343
|
+
* // override must join its parent's tree.
|
|
1344
|
+
* const externalTree = this.externalTreeInput(); // input() signal
|
|
1345
|
+
* const resolvedTree =
|
|
1346
|
+
* (override.kind === 'node' ? override.parent.tree : undefined) ??
|
|
1347
|
+
* externalTree ?? this.parentReg?.tree() ?? this.ambientTree;
|
|
1348
|
+
* if (!resolvedTree) {
|
|
1349
|
+
* this.selfReg.markDetached(); // node-optional: resolved, but no tree → no node
|
|
1350
|
+
* return;
|
|
1351
|
+
* }
|
|
1352
|
+
*
|
|
1353
|
+
* const node = resolvedTree.register({ id: ..., parent: parentNode, context: ... });
|
|
1354
|
+
* this.selfReg.register(resolvedTree, node);
|
|
1355
|
+
*
|
|
1356
|
+
* onCleanup(() => {
|
|
1357
|
+
* resolvedTree.unregister(node);
|
|
1358
|
+
* this.selfReg.clear(); // transient: back to 'pending' until the effect re-resolves
|
|
1359
|
+
* });
|
|
1360
|
+
* });
|
|
1361
|
+
* }
|
|
1362
|
+
* }
|
|
1363
|
+
* ```
|
|
1364
|
+
*/
|
|
1365
|
+
declare class RdxFloatingRegistrationContext implements RdxFloatingRegistrationReader {
|
|
1366
|
+
private readonly _state;
|
|
1367
|
+
/**
|
|
1368
|
+
* Lifecycle phase: `pending` (resolving — children must wait), `detached` (resolved, node-optional),
|
|
1369
|
+
* or `registered`. A `computed()` over the one internal state signal. See {@link RegistrationState}.
|
|
1370
|
+
*/
|
|
1371
|
+
readonly status: Signal<RdxFloatingRegistrationStatus>;
|
|
1372
|
+
/**
|
|
1373
|
+
* The tree this directive joined, or `null` unless `status() === 'registered'`. A `computed()`
|
|
1374
|
+
* derived from the internal state — always consistent with {@link node} and {@link status}.
|
|
1375
|
+
*/
|
|
1376
|
+
readonly tree: Signal<RdxFloatingTree | null>;
|
|
1377
|
+
/**
|
|
1378
|
+
* The node this directive registered, or `null` unless `status() === 'registered'`. A `computed()`
|
|
1379
|
+
* derived from the internal state — always consistent with {@link tree}
|
|
1380
|
+
* (`node.tree === tree` is invariant in the `registered` state).
|
|
1381
|
+
*/
|
|
1382
|
+
readonly node: Signal<RdxFloatingNode | null>;
|
|
1383
|
+
/**
|
|
1384
|
+
* Atomically records the resolved tree and the registered node (`status → 'registered'`). Asserts
|
|
1385
|
+
* `node.tree === tree` so no state where `tree` and `node` point to different stores can exist.
|
|
1386
|
+
* Called by the directive inside `effect()` after `tree.register(…)` succeeds.
|
|
1387
|
+
*/
|
|
1388
|
+
register(tree: RdxFloatingTree, node: RdxFloatingNode): void;
|
|
1389
|
+
/**
|
|
1390
|
+
* Records that the directive **resolved but has no node** (`status → 'detached'`): node-optional —
|
|
1391
|
+
* no tree was available (e.g. a standalone `rdxDismissableLayer`). Distinct from `pending`: a child
|
|
1392
|
+
* treats a `detached` parent as absent (inherits `null`), whereas it must **wait** on a `pending` one.
|
|
1393
|
+
*/
|
|
1394
|
+
markDetached(): void;
|
|
1395
|
+
/**
|
|
1396
|
+
* Reverts to `pending` (the `onCleanup` counterpart of {@link register} / {@link markDetached}).
|
|
1397
|
+
* Called after `tree.unregister(node)` so the handle re-enters the "resolving" phase until the
|
|
1398
|
+
* directive's effect re-runs; `tree`/`node` read `null` again.
|
|
1399
|
+
*/
|
|
1400
|
+
clear(): void;
|
|
1401
|
+
}
|
|
1402
|
+
/**
|
|
1403
|
+
* DI token for the nearest ancestor's registration handle, **typed as the read-only
|
|
1404
|
+
* {@link RdxFloatingRegistrationReader}**. A descendant injects it with `{ optional: true, skipSelf:
|
|
1405
|
+
* true }` to read its parent's `status` / `tree` / `node` — and, because the token is reader-typed,
|
|
1406
|
+
* **cannot** call the parent's writers (`register` / `markDetached` / `clear`) without a deliberate
|
|
1407
|
+
* cast. The owning directive writes through its own handle, which it injects by the concrete
|
|
1408
|
+
* {@link RdxFloatingRegistrationContext} type instead (see {@link provideFloatingRegistration}).
|
|
1409
|
+
*/
|
|
1410
|
+
declare const RDX_FLOATING_REGISTRATION: InjectionToken<RdxFloatingRegistrationReader>;
|
|
1411
|
+
/**
|
|
1412
|
+
* Seals a fresh registration handle into this directive's injector at creation time. Returns **two**
|
|
1413
|
+
* providers backed by **one** instance: the concrete {@link RdxFloatingRegistrationContext} (the
|
|
1414
|
+
* writer, injected by the owning directive) and a reader-typed {@link RDX_FLOATING_REGISTRATION} alias
|
|
1415
|
+
* (`useExisting`) that descendants inject. Splitting writer from reader is what stops a descendant from
|
|
1416
|
+
* mutating its parent's registration. Call this in a directive's `providers` array; the directive then
|
|
1417
|
+
* calls `selfReg.register(tree, node)` / `markDetached()` / `clear()` on its own (writer) handle.
|
|
1418
|
+
*/
|
|
1419
|
+
declare function provideFloatingRegistration(): Provider[];
|
|
1420
|
+
|
|
1421
|
+
/** Default marker attribute on the imperatively-created internal backdrop element. */
|
|
1422
|
+
declare const RDX_INTERNAL_BACKDROP_ATTR = "data-rdx-internal-backdrop";
|
|
1423
|
+
interface RdxInternalBackdropOptions {
|
|
1424
|
+
/** Whether the backdrop should exist (modal && reason-appropriate). Reactive — read in an effect. */
|
|
1425
|
+
shouldRender: () => boolean;
|
|
1426
|
+
/** Whether the popup is open. Reactive — drives `inert` during the closed-but-mounted exit window. */
|
|
1427
|
+
isOpen: () => boolean;
|
|
1428
|
+
/**
|
|
1429
|
+
* The element to keep interactive through a clip-path "cutout" (e.g. the trigger, so a toggle-close
|
|
1430
|
+
* click still reaches it), or `null` for a full backdrop. Read once when the backdrop is created.
|
|
1431
|
+
*/
|
|
1432
|
+
cutout?: () => Element | null;
|
|
1433
|
+
/** Marker attribute applied to the backdrop. Defaults to {@link RDX_INTERNAL_BACKDROP_ATTR}. */
|
|
1434
|
+
marker?: string;
|
|
1435
|
+
/** Let pointer/wheel events pass through the backdrop while keeping it mounted for lifecycle parity. */
|
|
1436
|
+
passThrough?: () => boolean;
|
|
1437
|
+
}
|
|
1438
|
+
/**
|
|
1439
|
+
* Renders Base UI's **internal backdrop** for a modal floating popup: a full-viewport element that
|
|
1440
|
+
* intercepts background pointer events (so the page behind the popup is non-interactive) **and** is
|
|
1441
|
+
* itself the outside-press target — clicking it lets the dismissal capability close the popup. This is
|
|
1442
|
+
* why a plain `inert` pass on outside elements is not enough: an inert element dispatches no pointer
|
|
1443
|
+
* event, so the popup could never close on an outside click. An optional clip-path cutout keeps the
|
|
1444
|
+
* trigger (or another region) clickable.
|
|
1445
|
+
*
|
|
1446
|
+
* Inserted as a **sibling before the positioner** — a sibling, not a child: a `position: fixed` element
|
|
1447
|
+
* inside a transformed positioner would be clipped to the positioner's box, not the viewport. The
|
|
1448
|
+
* positioner's own stacking (its `z-index`) keeps the popup above the backdrop.
|
|
1449
|
+
*
|
|
1450
|
+
* Call from the positioner directive inside `afterNextRender` (so the structural portal has already
|
|
1451
|
+
* relocated the positioner into its container).
|
|
1452
|
+
*/
|
|
1453
|
+
declare function setupInternalBackdrop(positioner: HTMLElement, injector: Injector, options: RdxInternalBackdropOptions): void;
|
|
1454
|
+
|
|
1455
|
+
/**
|
|
1456
|
+
* The nearest shared {@link RdxFloatingTree}. **Scoped-by-default, sharing explicit** — strict Base UI
|
|
1457
|
+
* parity: Base UI creates a `FloatingTree` only at the **coordination boundary** (e.g. a top-level Menu
|
|
1458
|
+
* renders `<FloatingTree>`, a nested submenu does **not** — it inherits the parent's store,
|
|
1459
|
+
* `MenuRoot.tsx:533`). There is deliberately **no** application-root provider, so the token resolves only
|
|
1460
|
+
* under a root that opts in with {@link provideFloatingTree}; elsewhere injecting it optionally yields
|
|
1461
|
+
* `null` and the primitive is its own independent root (`parent === null`).
|
|
1462
|
+
*/
|
|
1463
|
+
declare const RDX_FLOATING_TREE: InjectionToken<RdxFloatingTree>;
|
|
1464
|
+
/**
|
|
1465
|
+
* Provides a {@link RdxFloatingTree} for a subtree — the Angular `FloatingTree` analogue. **Inherit-or-
|
|
1466
|
+
* create:** it returns the **nearest ancestor tree** if one is already provided above, and creates a new
|
|
1467
|
+
* one **only at the top coordination boundary**. This is what makes it safe for a nesting-capable root
|
|
1468
|
+
* (Menu/Menubar/Context Menu/nested Dialog) to put it in `providers` unconditionally — a **nested**
|
|
1469
|
+
* instance inherits the parent's tree (so its node parents correctly), while the **top** instance starts
|
|
1470
|
+
* the store. (An always-new tree on a nested root would split ancestry / throw `cross-tree-parent`.)
|
|
1471
|
+
*
|
|
1472
|
+
* **Tree selection is separate from parent assignment** (Base UI: `tree = externalTree ?? contextTree`,
|
|
1473
|
+
* `parentId = nearest FloatingNodeContext`). This helper + {@link resolveFloatingTree} own tree
|
|
1474
|
+
* selection. Parent assignment is resolved at runtime via the `RdxFloatingRegistrationContext` handle
|
|
1475
|
+
* (`parentReg.node()` in `effect()`). In particular `{ kind: 'root' }` is **not** tree isolation — it
|
|
1476
|
+
* sets `parent = null` **within the same tree**. A genuinely separate tree is supplied explicitly via
|
|
1477
|
+
* `resolveFloatingTree(externalTree)`.
|
|
1478
|
+
*/
|
|
1479
|
+
declare function provideFloatingTree(): Provider;
|
|
1480
|
+
/**
|
|
1481
|
+
* Resolves **which tree** a node joins — the tree-selection contract, the Angular counterpart of Base
|
|
1482
|
+
* UI's `externalTree ?? contextTree` (`FloatingTree.tsx:25`). An explicit `externalTree` wins,
|
|
1483
|
+
* otherwise the nearest injected {@link RDX_FLOATING_TREE} (or `null` → the capability runs
|
|
1484
|
+
* **node-optional**). Parent assignment is separate — resolved reactively via
|
|
1485
|
+
* `parentReg.node()` from the {@link RDX_FLOATING_REGISTRATION} handle, not via a token.
|
|
1486
|
+
*
|
|
1487
|
+
* For a **detached** node registered with an explicit `{ kind: 'node', parent }` override from a sibling
|
|
1488
|
+
* injector, the nearest injected tree may be absent or a *different* tree than `parent.tree` — so the
|
|
1489
|
+
* caller **must** pass `externalTree = override.parent.tree` here, so the node joins its parent's tree (the
|
|
1490
|
+
* cross-tree invariant then holds). Must be called in an injection context when `externalTree` is omitted.
|
|
1491
|
+
*/
|
|
1492
|
+
declare function resolveFloatingTree(externalTree?: RdxFloatingTree | null): RdxFloatingTree | null;
|
|
1493
|
+
/**
|
|
1494
|
+
* The shared per-popup {@link RdxFloatingRootContext} — the Angular counterpart of Base UI's
|
|
1495
|
+
* `FloatingRootContext`, created by `useFloatingRootContext` at the **primitive root** and **received**
|
|
1496
|
+
* by `useDismiss` / `FloatingFocusManager` (they never create their own). Mirroring that: a primitive
|
|
1497
|
+
* root (Dialog/Popover/Menu/…) creates **one** context and provides it here; the dismissal capability
|
|
1498
|
+
* (ADR 0015) and the focus manager (ADR 0017) read the **same** context, so `open`, `triggers`, and the
|
|
1499
|
+
* elements are never split across mechanisms.
|
|
1500
|
+
*
|
|
1501
|
+
* Optional: a **standalone** `rdxDismissableLayer` (no enclosing primitive root) has none, and
|
|
1502
|
+
* {@link injectFloatingRootContext} creates a fallback for that case only.
|
|
1503
|
+
*/
|
|
1504
|
+
declare const RDX_FLOATING_ROOT_CONTEXT: InjectionToken<RdxFloatingRootContext>;
|
|
1505
|
+
/** Provides the shared {@link RdxFloatingRootContext} for a primitive root's subtree. */
|
|
1506
|
+
declare function provideFloatingRootContext(factory: () => RdxFloatingRootContext): Provider;
|
|
1507
|
+
/**
|
|
1508
|
+
* Returns the shared {@link RdxFloatingRootContext} provided by an enclosing primitive root, or creates
|
|
1509
|
+
* a **standalone fallback** via `fallback()` when none is provided (a bare `rdxDismissableLayer`). Must be
|
|
1510
|
+
* called in an injection context.
|
|
1511
|
+
*/
|
|
1512
|
+
declare function injectFloatingRootContext(fallback: () => RdxFloatingRootContext): RdxFloatingRootContext;
|
|
1513
|
+
|
|
793
1514
|
declare function injectDocument(): Document;
|
|
794
1515
|
|
|
795
1516
|
declare function elementSize({ elementRef, injector }: {
|
|
@@ -800,7 +1521,13 @@ declare function elementSize({ elementRef, injector }: {
|
|
|
800
1521
|
height: number;
|
|
801
1522
|
}>;
|
|
802
1523
|
|
|
803
|
-
|
|
1524
|
+
/**
|
|
1525
|
+
* The deepest active element, descending into open shadow roots. Pass a specific `root`
|
|
1526
|
+
* (`Document` or `ShadowRoot`) to read focus in that document — defaults to the global `document`
|
|
1527
|
+
* (backward compatible). A focus scope passes its host's `ownerDocument` so it stays correct across
|
|
1528
|
+
* iframes / multi-document environments.
|
|
1529
|
+
*/
|
|
1530
|
+
declare function getActiveElement(root?: DocumentOrShadowRoot): Element | null;
|
|
804
1531
|
|
|
805
1532
|
/**
|
|
806
1533
|
* Creates a resize observer effect for element
|
|
@@ -817,19 +1544,40 @@ declare function resizeEffect(options: {
|
|
|
817
1544
|
onResize: ResizeObserverCallback;
|
|
818
1545
|
}): EffectRef;
|
|
819
1546
|
|
|
1547
|
+
/** Marker attribute set on `<html>` while scroll is locked (a strategy-independent test/CSS hook). */
|
|
1548
|
+
declare const RDX_SCROLL_LOCKED_ATTR = "data-rdx-scroll-locked";
|
|
1549
|
+
interface RdxScrollLockOptions {
|
|
1550
|
+
/** Element whose owner document should be locked. Defaults to Angular's injected DOCUMENT. */
|
|
1551
|
+
referenceElement?: () => Element | null;
|
|
1552
|
+
}
|
|
820
1553
|
/**
|
|
821
|
-
* Locks page scrolling while `active()` is `true`,
|
|
822
|
-
*
|
|
823
|
-
*
|
|
824
|
-
* Locks **both** `<body>` and `<html>`: a `body { overflow: hidden }` lock alone does *not* stop the
|
|
825
|
-
* page when `<html>` is the scroller (e.g. a global `overflow-y: scroll`, as Storybook sets), because
|
|
826
|
-
* body-overflow only propagates to the viewport when `<html>`'s overflow is `visible`. The width of
|
|
827
|
-
* the removed scrollbar is added as `padding-right` on `<html>` so the page doesn't shift.
|
|
1554
|
+
* Locks page scrolling while `active()` is `true`, restoring the original state when it becomes `false`
|
|
1555
|
+
* or the calling context is destroyed.
|
|
828
1556
|
*
|
|
829
|
-
*
|
|
830
|
-
*
|
|
1557
|
+
* This is the full Base UI `useScrollLock` behavioral set (ADR 0016 §1): it picks the **overlay** strategy
|
|
1558
|
+
* (plain `overflow: hidden`) for iOS / overlay-scrollbar documents and the **inset** strategy for desktop
|
|
1559
|
+
* scrollbars — the latter preserves the scroll position, reserves the scrollbar gutter (no content shift),
|
|
1560
|
+
* bails out during a Safari pinch-zoom, and re-locks on resize. Locks compose across all callers in the
|
|
1561
|
+
* same document via a shared per-`Document` ref count, and state is isolated per `Document` (iframe-safe).
|
|
1562
|
+
* No-op on the server. Must be called in an injection context.
|
|
1563
|
+
*/
|
|
1564
|
+
declare function useScrollLock(active: Signal<boolean>, options?: RdxScrollLockOptions): void;
|
|
1565
|
+
/** Options for {@link useAnchoredScrollLock}. */
|
|
1566
|
+
interface RdxAnchoredScrollLockOptions {
|
|
1567
|
+
/** Whether the popup was opened by **touch** — the near-fullscreen gate applies only then. */
|
|
1568
|
+
touchOpen: () => boolean;
|
|
1569
|
+
/** The popup / positioner element whose width decides the touch gate (measured vs the viewport). */
|
|
1570
|
+
element: () => HTMLElement | null;
|
|
1571
|
+
}
|
|
1572
|
+
/**
|
|
1573
|
+
* Scroll lock for an **anchored** popup (Base UI `useAnchoredPopupScrollLock`, ADR 0016 §3). For a
|
|
1574
|
+
* non-touch open it behaves exactly like {@link useScrollLock} (locks while `enabled()`). For a **touch**
|
|
1575
|
+
* open it locks **only** when the popup is effectively viewport-width (`popupWidth >= viewportWidth -
|
|
1576
|
+
* 20px`) — otherwise the page stays scrollable so the user can swipe outside to dismiss the popup. The
|
|
1577
|
+
* width is measured off `element()`; reading `offsetWidth` forces layout, so it is accurate even before
|
|
1578
|
+
* the popup is positioned (visibility does not affect layout). Must be called in an injection context.
|
|
831
1579
|
*/
|
|
832
|
-
declare function
|
|
1580
|
+
declare function useAnchoredScrollLock(enabled: Signal<boolean>, options: RdxAnchoredScrollLockOptions): void;
|
|
833
1581
|
|
|
834
1582
|
type ArrowKeyOptions = 'horizontal' | 'vertical' | 'both';
|
|
835
1583
|
interface ArrowNavigationOptions {
|
|
@@ -1100,5 +1848,5 @@ declare enum RdxPositionAlign {
|
|
|
1100
1848
|
End = "end"
|
|
1101
1849
|
}
|
|
1102
1850
|
|
|
1103
|
-
export { A, ALT, ARROW_DOWN, ARROW_LEFT, ARROW_RIGHT, ARROW_UP, ASTERISK, BACKSPACE, CAPS_LOCK, CONTROL, CTRL, DELETE, END, ENTER, ESCAPE, F1, F10, F11, F12, F2, F3, F4, F5, F6, F7, F8, F9, HOME, META, P, PAGE_DOWN, PAGE_UP, RdxControlValueAccessor, RdxIdGenerator, RdxLiveAnnouncer, RdxPositionAlign, RdxPositionSide, SHIFT, SPACE, SPACE_CODE, TAB, TIME_GRANULARITIES, a, areAllDaysBetweenValid, clamp, createContent, createContext, createFormatter, createMonth, createMonths, elementSize, getActiveElement, getDaysBetween, getDaysInMonth, getDefaultDate, getDefaultTime, getLastFirstDayOfWeek, getMaxTransitionDuration, getNextLastDayOfWeek, getOptsByGranularity, getPlaceholder, getSegmentElements, getWeekNumber, handleAndDispatchCustomEvent, handleCalendarInitialFocus, hasTime, initializeSegmentValues, injectControlValueAccessor, injectDocument, injectId, isAcceptableSegmentKey, isAfter, isAfterOrSame, isBefore, isBeforeOrSame, isBetween, isBetweenInclusive, isCalendarDateTime, isEqual, isItemEqualToValue, isNullish, isNumberString, isSegmentNavigationKey, isZonedDateTime, itemToStringLabel, itemToStringValue, j, k, n, normalizeDateStep, normalizeHour12, normalizeHourCycle, p, provideToken, provideValueAccessor, resizeEffect, roundToStepPrecision, segmentBuilders, snapValueToStep, syncSegmentValues, syncTimeSegmentValues, toDate, useArrowNavigation, useDateField, useFilter, useGraceArea, useListHighlight, usePointerDrag, useScrollLock, useTransitionStatus, watch };
|
|
1104
|
-
export type { AcceptableValue, AnyExceptLiteral, AriaLivePoliteness, BooleanInput, CreateMonthProps, DataOrientation, DateAndTimeSegmentObj, DateFormatterOptions, DateMatcher, DateRange, DateSegmentObj, DateSegmentPart, DateStep, DayPeriod, Direction, EditableSegmentPart, FilterPredicates, Formatter, Granularity, HourCycle, InjectContext, ItemValueComparator, ListHighlight, Month, NonEditableSegmentPart, Nullable, NumberInput, PlaceholderMap, RdxFormCheckboxControl, RdxFormStateInput, RdxFormUiControl, RdxFormValueControl, RdxPointerDragHandlers, RdxTransitionStatus, RdxTransitionStatusRef, RdxValidationError, SafeFunction, SegmentContentObj, SegmentPart, SegmentValueObj, TimeGranularity, TimeSegmentObj, TimeSegmentPart, TimeValue, UseDateFieldProps, UseFilterOptions, UseListHighlightOptions };
|
|
1851
|
+
export { A, ALT, ARROW_DOWN, ARROW_LEFT, ARROW_RIGHT, ARROW_UP, ASTERISK, BACKSPACE, CAPS_LOCK, CONTROL, CTRL, DELETE, DOCS_BASE_URL, END, ENTER, ESCAPE, F1, F10, F11, F12, F2, F3, F4, F5, F6, F7, F8, F9, HOME, META, P, PAGE_DOWN, PAGE_UP, RDX_FLOATING_REGISTRATION, RDX_FLOATING_ROOT_CONTEXT, RDX_FLOATING_TREE, RDX_INTERNAL_BACKDROP_ATTR, RDX_SCROLL_LOCKED_ATTR, RdxControlValueAccessor, RdxFloatingNode, RdxFloatingNodeRegistration, RdxFloatingRegistrationContext, RdxFloatingRootContext, RdxFloatingTree, RdxIdGenerator, RdxLiveAnnouncer, RdxPositionAlign, RdxPositionSide, RdxTriggerRegistry, SHIFT, SPACE, SPACE_CODE, TAB, TIME_GRANULARITIES, a, areAllDaysBetweenValid, clamp, createCancelableChangeEventDetails, createContent, createContext, createFloatingEvents, createFloatingRootContext, createFormatter, createMonth, createMonths, docsUrl, elementSize, getActiveElement, getDaysBetween, getDaysInMonth, getDefaultDate, getDefaultTime, getLastFirstDayOfWeek, getMaxTransitionDuration, getNextLastDayOfWeek, getOptsByGranularity, getPlaceholder, getSegmentElements, getWeekNumber, handleAndDispatchCustomEvent, handleCalendarInitialFocus, hasTime, initializeSegmentValues, injectControlValueAccessor, injectDocument, injectFloatingRootContext, injectId, isAcceptableSegmentKey, isAfter, isAfterOrSame, isBefore, isBeforeOrSame, isBetween, isBetweenInclusive, isCalendarDateTime, isEqual, isItemEqualToValue, isNullish, isNumberString, isSegmentNavigationKey, isZonedDateTime, itemToStringLabel, itemToStringValue, j, k, n, normalizeDateStep, normalizeHour12, normalizeHourCycle, p, provideFloatingRegistration, provideFloatingRootContext, provideFloatingTree, provideToken, provideValueAccessor, rdxCheckLabelElement, rdxCheckTriggerElement, rdxDevError, rdxDevWarning, resetRdxDevWarnings, resizeEffect, resolveFloatingTree, roundToStepPrecision, segmentBuilders, setupInternalBackdrop, snapValueToStep, syncSegmentValues, syncTimeSegmentValues, toDate, useAnchoredScrollLock, useArrowNavigation, useDateField, useFilter, useGraceArea, useListHighlight, usePointerDrag, useScrollLock, useTransitionStatus, watch };
|
|
1852
|
+
export type { AcceptableValue, AnyExceptLiteral, AriaLivePoliteness, BooleanInput, CreateMonthProps, DataOrientation, DateAndTimeSegmentObj, DateFormatterOptions, DateMatcher, DateRange, DateSegmentObj, DateSegmentPart, DateStep, DayPeriod, Direction, EditableSegmentPart, FilterPredicates, Formatter, Granularity, HourCycle, InjectContext, ItemValueComparator, ListHighlight, Month, NonEditableSegmentPart, Nullable, NumberInput, PlaceholderMap, RdxAnchoredScrollLockOptions, RdxCancelableChangeEventDetails, RdxCancelableChangeEventTransaction, RdxFloatingEventMap, RdxFloatingEvents, RdxFloatingLifecycle, RdxFloatingNodeInit, RdxFloatingParentOverride, RdxFloatingRegistrationReader, RdxFloatingRegistrationStatus, RdxFloatingRootContextEventMap, RdxFloatingRootContextInit, RdxFormCheckboxControl, RdxFormStateInput, RdxFormUiControl, RdxFormValueControl, RdxInternalBackdropOptions, RdxPointerDragHandlers, RdxScrollLockOptions, RdxTransitionStatus, RdxTransitionStatusRef, RdxValidationError, SafeFunction, SegmentContentObj, SegmentPart, SegmentValueObj, TimeGranularity, TimeSegmentObj, TimeSegmentPart, TimeValue, UseDateFieldProps, UseFilterOptions, UseListHighlightOptions };
|