@radix-ng/primitives 1.0.0-beta.0 → 1.0.0-beta.2

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 (117) hide show
  1. package/fesm2022/radix-ng-primitives-accordion.mjs +2 -2
  2. package/fesm2022/radix-ng-primitives-accordion.mjs.map +1 -1
  3. package/fesm2022/radix-ng-primitives-calendar.mjs +109 -84
  4. package/fesm2022/radix-ng-primitives-calendar.mjs.map +1 -1
  5. package/fesm2022/radix-ng-primitives-checkbox.mjs +2 -2
  6. package/fesm2022/radix-ng-primitives-checkbox.mjs.map +1 -1
  7. package/fesm2022/radix-ng-primitives-collapsible.mjs +1 -1
  8. package/fesm2022/radix-ng-primitives-collapsible.mjs.map +1 -1
  9. package/fesm2022/radix-ng-primitives-combobox.mjs +1923 -0
  10. package/fesm2022/radix-ng-primitives-combobox.mjs.map +1 -0
  11. package/fesm2022/radix-ng-primitives-context-menu.mjs +1 -1
  12. package/fesm2022/radix-ng-primitives-context-menu.mjs.map +1 -1
  13. package/fesm2022/radix-ng-primitives-core.mjs +591 -470
  14. package/fesm2022/radix-ng-primitives-core.mjs.map +1 -1
  15. package/fesm2022/radix-ng-primitives-cropper.mjs +287 -308
  16. package/fesm2022/radix-ng-primitives-cropper.mjs.map +1 -1
  17. package/fesm2022/radix-ng-primitives-date-field.mjs +66 -15
  18. package/fesm2022/radix-ng-primitives-date-field.mjs.map +1 -1
  19. package/fesm2022/radix-ng-primitives-dialog.mjs +1 -1
  20. package/fesm2022/radix-ng-primitives-dialog.mjs.map +1 -1
  21. package/fesm2022/radix-ng-primitives-drawer.mjs +7 -106
  22. package/fesm2022/radix-ng-primitives-drawer.mjs.map +1 -1
  23. package/fesm2022/radix-ng-primitives-editable.mjs +305 -24
  24. package/fesm2022/radix-ng-primitives-editable.mjs.map +1 -1
  25. package/fesm2022/radix-ng-primitives-field.mjs +86 -6
  26. package/fesm2022/radix-ng-primitives-field.mjs.map +1 -1
  27. package/fesm2022/radix-ng-primitives-fieldset.mjs +1 -1
  28. package/fesm2022/radix-ng-primitives-fieldset.mjs.map +1 -1
  29. package/fesm2022/radix-ng-primitives-focus-scope.mjs +1 -1
  30. package/fesm2022/radix-ng-primitives-focus-scope.mjs.map +1 -1
  31. package/fesm2022/radix-ng-primitives-form.mjs +207 -0
  32. package/fesm2022/radix-ng-primitives-form.mjs.map +1 -0
  33. package/fesm2022/radix-ng-primitives-input.mjs +85 -4
  34. package/fesm2022/radix-ng-primitives-input.mjs.map +1 -1
  35. package/fesm2022/radix-ng-primitives-menu.mjs +413 -5
  36. package/fesm2022/radix-ng-primitives-menu.mjs.map +1 -1
  37. package/fesm2022/radix-ng-primitives-menubar.mjs +1 -1
  38. package/fesm2022/radix-ng-primitives-menubar.mjs.map +1 -1
  39. package/fesm2022/radix-ng-primitives-meter.mjs +1 -1
  40. package/fesm2022/radix-ng-primitives-meter.mjs.map +1 -1
  41. package/fesm2022/radix-ng-primitives-navigation-menu.mjs +1 -1
  42. package/fesm2022/radix-ng-primitives-navigation-menu.mjs.map +1 -1
  43. package/fesm2022/radix-ng-primitives-number-field.mjs +2 -2
  44. package/fesm2022/radix-ng-primitives-number-field.mjs.map +1 -1
  45. package/fesm2022/radix-ng-primitives-popover.mjs +1 -1
  46. package/fesm2022/radix-ng-primitives-popover.mjs.map +1 -1
  47. package/fesm2022/radix-ng-primitives-popper.mjs +22 -5
  48. package/fesm2022/radix-ng-primitives-popper.mjs.map +1 -1
  49. package/fesm2022/radix-ng-primitives-portal.mjs.map +1 -1
  50. package/fesm2022/radix-ng-primitives-preview-card.mjs +1 -1
  51. package/fesm2022/radix-ng-primitives-preview-card.mjs.map +1 -1
  52. package/fesm2022/radix-ng-primitives-progress.mjs +1 -1
  53. package/fesm2022/radix-ng-primitives-progress.mjs.map +1 -1
  54. package/fesm2022/radix-ng-primitives-roving-focus.mjs +1 -1
  55. package/fesm2022/radix-ng-primitives-roving-focus.mjs.map +1 -1
  56. package/fesm2022/radix-ng-primitives-scroll-area.mjs +923 -0
  57. package/fesm2022/radix-ng-primitives-scroll-area.mjs.map +1 -0
  58. package/fesm2022/radix-ng-primitives-select.mjs +421 -224
  59. package/fesm2022/radix-ng-primitives-select.mjs.map +1 -1
  60. package/fesm2022/radix-ng-primitives-slider.mjs +1 -1
  61. package/fesm2022/radix-ng-primitives-slider.mjs.map +1 -1
  62. package/fesm2022/radix-ng-primitives-stepper.mjs.map +1 -1
  63. package/fesm2022/radix-ng-primitives-switch.mjs +3 -2
  64. package/fesm2022/radix-ng-primitives-switch.mjs.map +1 -1
  65. package/fesm2022/radix-ng-primitives-tabs.mjs +12 -3
  66. package/fesm2022/radix-ng-primitives-tabs.mjs.map +1 -1
  67. package/fesm2022/radix-ng-primitives-time-field.mjs +27 -3
  68. package/fesm2022/radix-ng-primitives-time-field.mjs.map +1 -1
  69. package/fesm2022/radix-ng-primitives-toast.mjs +839 -0
  70. package/fesm2022/radix-ng-primitives-toast.mjs.map +1 -0
  71. package/fesm2022/radix-ng-primitives-toggle-group.mjs +1 -1
  72. package/fesm2022/radix-ng-primitives-toggle-group.mjs.map +1 -1
  73. package/fesm2022/radix-ng-primitives-toolbar.mjs +2 -2
  74. package/fesm2022/radix-ng-primitives-toolbar.mjs.map +1 -1
  75. package/fesm2022/radix-ng-primitives-tooltip.mjs +11 -3
  76. package/fesm2022/radix-ng-primitives-tooltip.mjs.map +1 -1
  77. package/package.json +18 -2
  78. package/schematics/ng-add/index.js +57 -0
  79. package/schematics/ng-add/index.js.map +1 -1
  80. package/schematics/ng-add/schema.d.ts +1 -0
  81. package/schematics/ng-add/schema.json +6 -0
  82. package/types/radix-ng-primitives-accordion.d.ts +3 -2
  83. package/types/radix-ng-primitives-calendar.d.ts +38 -18
  84. package/types/radix-ng-primitives-checkbox.d.ts +5 -5
  85. package/types/radix-ng-primitives-collapsible.d.ts +2 -1
  86. package/types/radix-ng-primitives-combobox.d.ts +1265 -0
  87. package/types/radix-ng-primitives-context-menu.d.ts +3 -2
  88. package/types/radix-ng-primitives-core.d.ts +187 -56
  89. package/types/radix-ng-primitives-cropper.d.ts +89 -56
  90. package/types/radix-ng-primitives-date-field.d.ts +11 -5
  91. package/types/radix-ng-primitives-dialog.d.ts +2 -1
  92. package/types/radix-ng-primitives-drawer.d.ts +5 -27
  93. package/types/radix-ng-primitives-editable.d.ts +90 -13
  94. package/types/radix-ng-primitives-field.d.ts +74 -4
  95. package/types/radix-ng-primitives-fieldset.d.ts +3 -2
  96. package/types/radix-ng-primitives-focus-scope.d.ts +2 -1
  97. package/types/radix-ng-primitives-form.d.ts +124 -0
  98. package/types/radix-ng-primitives-input.d.ts +75 -5
  99. package/types/radix-ng-primitives-menu.d.ts +16 -4
  100. package/types/radix-ng-primitives-menubar.d.ts +2 -1
  101. package/types/radix-ng-primitives-meter.d.ts +3 -2
  102. package/types/radix-ng-primitives-navigation-menu.d.ts +1 -1
  103. package/types/radix-ng-primitives-number-field.d.ts +6 -6
  104. package/types/radix-ng-primitives-popover.d.ts +2 -1
  105. package/types/radix-ng-primitives-popper.d.ts +19 -2
  106. package/types/radix-ng-primitives-preview-card.d.ts +1 -1
  107. package/types/radix-ng-primitives-progress.d.ts +3 -2
  108. package/types/radix-ng-primitives-roving-focus.d.ts +4 -3
  109. package/types/radix-ng-primitives-scroll-area.d.ts +253 -0
  110. package/types/radix-ng-primitives-select.d.ts +296 -136
  111. package/types/radix-ng-primitives-slider.d.ts +1 -1
  112. package/types/radix-ng-primitives-switch.d.ts +1 -1
  113. package/types/radix-ng-primitives-tabs.d.ts +1 -1
  114. package/types/radix-ng-primitives-toast.d.ts +378 -0
  115. package/types/radix-ng-primitives-toggle-group.d.ts +2 -1
  116. package/types/radix-ng-primitives-toolbar.d.ts +3 -2
  117. package/types/radix-ng-primitives-tooltip.d.ts +3 -2
@@ -1,9 +1,10 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { Signal } from '@angular/core';
3
+ import * as _radix_ng_primitives_core from '@radix-ng/primitives/core';
4
+ import { BooleanInput, NumberInput } from '@radix-ng/primitives/core';
3
5
  import * as i1 from '@radix-ng/primitives/menu';
4
6
  import { RdxMenuRoot, RdxMenuAutoFocusInput } from '@radix-ng/primitives/menu';
5
7
  import * as _radix_ng_primitives_context_menu from '@radix-ng/primitives/context-menu';
6
- import { BooleanInput, NumberInput } from '@radix-ng/primitives/core';
7
8
 
8
9
  interface RdxContextMenuRootContext {
9
10
  /** Whether the context menu is currently open. */
@@ -15,7 +16,7 @@ interface RdxContextMenuRootContext {
15
16
  /** Close the menu. */
16
17
  close: () => void;
17
18
  }
18
- declare const injectRdxContextMenuRootContext: (optional?: boolean) => RdxContextMenuRootContext | null;
19
+ declare const injectRdxContextMenuRootContext: _radix_ng_primitives_core.InjectContext<RdxContextMenuRootContext>;
19
20
  declare const provideRdxContextMenuRootContext: (useFactory: () => RdxContextMenuRootContext) => i0.Provider;
20
21
  /**
21
22
  * Groups all parts of a context menu. Composes the Menu primitive but, instead of anchoring the
@@ -151,15 +151,28 @@ declare function roundToStepPrecision(value: number, step: number): number;
151
151
  */
152
152
  declare function snapValueToStep(value: number, min: number | undefined, max: number | undefined, step: number): number;
153
153
 
154
+ /**
155
+ * Retrieves the context value from Angular's dependency injection.
156
+ * Overloaded so the non-optional call returns a non-nullable `T` (no `!` needed),
157
+ * while the optional call may return `null`.
158
+ */
159
+ interface InjectContext<T> {
160
+ (): T;
161
+ (optional: false): T;
162
+ (optional: true): T | null;
163
+ (optional?: boolean): T | null;
164
+ }
154
165
  /**
155
166
  * Creates a context with injector and provider functions for a given type
156
167
  * @template T The type of the context value
157
168
  * @param description Descriptive string for the context (used in token creation)
169
+ * @param docs Documentation path for the owning primitive (e.g. `'components/accordion'`),
170
+ * appended to the missing-context error as a link to the required anatomy
158
171
  * @returns A tuple containing:
159
172
  * - injectContext: Function to retrieve the context value
160
173
  * - provideContext: Function to create a provider for the context
161
174
  */
162
- declare function createContext<T>(description: string): readonly [injectContext: (optional?: boolean) => T | null, provideContext: (useFactory: () => T) => Provider];
175
+ declare function createContext<T>(description: string, docs?: string): readonly [injectContext: InjectContext<T>, provideContext: (useFactory: () => T) => Provider];
163
176
 
164
177
  declare const DATE_SEGMENT_PARTS: readonly ["day", "month", "year"];
165
178
  declare const TIME_SEGMENT_PARTS: readonly ["hour", "minute", "second", "dayPeriod"];
@@ -332,6 +345,12 @@ declare function areAllDaysBetweenValid(start: DateValue, end: DateValue, isUnav
332
345
  type TimeValue = Time | CalendarDateTime | ZonedDateTime;
333
346
  type Granularity = 'day' | 'hour' | 'minute' | 'second';
334
347
  type TimeGranularity = 'hour' | 'minute' | 'second';
348
+ /**
349
+ * The granularities that require a time component (and therefore a `CalendarDateTime`
350
+ * rather than a `CalendarDate`). Single source of truth — used by both the default-date
351
+ * builder and the segment-value initializer.
352
+ */
353
+ declare const TIME_GRANULARITIES: readonly Granularity[];
335
354
  type GetDefaultDateProps = {
336
355
  defaultValue?: DateValue | DateValue[] | undefined;
337
356
  defaultPlaceholder?: DateValue | undefined;
@@ -394,7 +413,7 @@ type SyncTimeSegmentValuesProps = {
394
413
  formatter: Formatter;
395
414
  };
396
415
  declare function syncTimeSegmentValues(props: SyncTimeSegmentValuesProps): SegmentValueObj;
397
- declare function initializeSegmentValues(granularity: Granularity): SegmentValueObj;
416
+ declare function initializeSegmentValues(granularity: Granularity, isTimeValue?: boolean): SegmentValueObj;
398
417
  type SharedContentProps = {
399
418
  granularity: Granularity;
400
419
  dateRef: DateValue;
@@ -451,54 +470,9 @@ type SegmentAttrProps = {
451
470
  placeholder: DateValue;
452
471
  formatter: Formatter;
453
472
  };
454
- declare function daySegmentAttrs(props: SegmentAttrProps): {
455
- 'aria-label': string;
456
- 'aria-valuemin': number;
457
- 'aria-valuemax': number;
458
- 'aria-valuenow': number;
459
- 'aria-valuetext': string;
460
- 'data-placeholder': string | undefined;
461
- role: string;
462
- contenteditable: boolean;
463
- tabindex: number | undefined;
464
- spellcheck: boolean;
465
- inputmode: string;
466
- autocorrect: string;
467
- enterkeyhint: string;
468
- style: string;
469
- };
470
- declare function monthSegmentAttrs(props: SegmentAttrProps): {
471
- 'aria-label': string;
472
- contenteditable: boolean;
473
- 'aria-valuemin': number;
474
- 'aria-valuemax': number;
475
- 'aria-valuenow': number;
476
- 'aria-valuetext': string;
477
- 'data-placeholder': string | undefined;
478
- role: string;
479
- tabindex: number | undefined;
480
- spellcheck: boolean;
481
- inputmode: string;
482
- autocorrect: string;
483
- enterkeyhint: string;
484
- style: string;
485
- };
486
- declare function yearSegmentAttrs(props: SegmentAttrProps): {
487
- 'aria-label': string;
488
- 'aria-valuemin': number;
489
- 'aria-valuemax': number;
490
- 'aria-valuenow': number;
491
- 'aria-valuetext': string;
492
- 'data-placeholder': string | undefined;
493
- role: string;
494
- contenteditable: boolean;
495
- tabindex: number | undefined;
496
- spellcheck: boolean;
497
- inputmode: string;
498
- autocorrect: string;
499
- enterkeyhint: string;
500
- style: string;
501
- };
473
+ declare function daySegmentAttrs(props: SegmentAttrProps): {};
474
+ declare function monthSegmentAttrs(props: SegmentAttrProps): {};
475
+ declare function yearSegmentAttrs(props: SegmentAttrProps): {};
502
476
  declare function hourSegmentAttrs(props: SegmentAttrProps): {};
503
477
  declare function minuteSegmentAttrs(props: SegmentAttrProps): {};
504
478
  declare function secondSegmentAttrs(props: SegmentAttrProps): {};
@@ -605,6 +579,36 @@ declare class RdxIdGenerator {
605
579
  */
606
580
  declare function injectId(prefix: string): string;
607
581
 
582
+ /**
583
+ * A comparator for list-item values, aligned with Base UI's `isItemEqualToValue` naming.
584
+ *
585
+ * - a **function** `(a, b) => boolean` — full control over equality;
586
+ * - a **string** — an object key whose values are compared with {@link isEqual} (Reka-style `by`);
587
+ * - omitted — structural deep equality via {@link isEqual}.
588
+ */
589
+ type ItemValueComparator<T = unknown> = ((a: T, b: T) => boolean) | string;
590
+ /**
591
+ * Converts an item value to the string shown to the user.
592
+ *
593
+ * Strings pass through unchanged; `null`/`undefined` become an empty string; everything else is
594
+ * coerced with `String()`. Primitives that hold object values (e.g. combobox) typically pass their
595
+ * own `itemToStringLabel` to render a field off the object instead.
596
+ */
597
+ declare function itemToStringLabel(value: unknown): string;
598
+ /**
599
+ * Converts an item value to the string used for form serialization. Defaults to the same rules as
600
+ * {@link itemToStringLabel}; kept as a separate export so a primitive can diverge label vs. value.
601
+ */
602
+ declare function itemToStringValue(value: unknown): string;
603
+ /**
604
+ * Compares two item values for equality using an optional {@link ItemValueComparator}.
605
+ *
606
+ * @example
607
+ * isItemEqualToValue({ id: 1 }, { id: 1 }, 'id'); // true — compares the `id` key
608
+ * isItemEqualToValue({ id: 1 }, { id: 1 }); // true — deep equality fallback
609
+ */
610
+ declare function isItemEqualToValue<T>(a: T, b: T, comparator?: ItemValueComparator<T>): boolean;
611
+
608
612
  declare const ALT = "Alt";
609
613
  declare const ARROW_DOWN = "ArrowDown";
610
614
  declare const ARROW_LEFT = "ArrowLeft";
@@ -745,15 +749,27 @@ interface RdxFormUiControl {
745
749
  readonly invalid?: RdxFormStateInput<boolean>;
746
750
  readonly hidden?: RdxFormStateInput<boolean>;
747
751
  readonly pending?: RdxFormStateInput<boolean>;
748
- readonly touched?: RdxFormStateInput<boolean>;
752
+ /**
753
+ * Touched status the form writes into the control.
754
+ *
755
+ * The two API generations disagree on the notification half: the 21.x
756
+ * experimental implementation listens to a `touched` **model**'s
757
+ * `touchedChange` output, while stable Angular 22 reverted to a plain
758
+ * `touched` input plus a separate {@link touch} output. A `model()` set on
759
+ * blur **plus** an emitted `touch` output satisfies both (`ModelSignal`
760
+ * extends `InputSignalWithTransform`, so it type-checks as the 22 input).
761
+ */
762
+ readonly touched?: ModelSignal<boolean> | RdxFormStateInput<boolean> | OutputRef<boolean>;
749
763
  readonly dirty?: RdxFormStateInput<boolean>;
750
764
  readonly name?: RdxFormStateInput<string | undefined>;
751
765
  readonly errors?: RdxFormStateInput<readonly RdxValidationError[]>;
752
766
  readonly minLength?: RdxFormStateInput<number | undefined>;
753
767
  readonly maxLength?: RdxFormStateInput<number | undefined>;
754
768
  readonly pattern?: RdxFormStateInput<readonly RegExp[]>;
755
- /** Notifies the form that the control was touched (mirror of Angular's `touch` output). */
769
+ /** Notifies the form the control was touched (stable Angular 22 contract; ignored by 21.x). */
756
770
  readonly touch?: OutputRef<void>;
771
+ /** Resets the control's UI state (optional method added in stable Angular 22). */
772
+ reset?(): void;
757
773
  }
758
774
  /**
759
775
  * Mirror of `FormValueControl<TValue>` — a control that edits a single value via
@@ -802,8 +818,13 @@ declare function resizeEffect(options: {
802
818
  }): EffectRef;
803
819
 
804
820
  /**
805
- * Locks `document.body` scrolling while `active()` is `true`, and restores the original overflow
806
- * when it becomes `false` or the calling context is destroyed.
821
+ * Locks page scrolling while `active()` is `true`, and restores the original state when it becomes
822
+ * `false` or the calling context is destroyed.
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.
807
828
  *
808
829
  * Lock ownership is shared across all callers via a single module-level counter, so nested or
809
830
  * concurrent overlays compose correctly. Must be called in an injection context.
@@ -874,6 +895,39 @@ interface ArrowNavigationOptions {
874
895
  */
875
896
  declare function useArrowNavigation(e: KeyboardEvent, currentElement: HTMLElement, parentElement: HTMLElement | undefined, options?: ArrowNavigationOptions): HTMLElement | null;
876
897
 
898
+ /**
899
+ * Locale-aware string matching backed by `Intl.Collator`, mirroring Base UI's `useFilter`.
900
+ *
901
+ * The collator defaults to `sensitivity: 'base'`, so matching is both case-insensitive and
902
+ * diacritic-insensitive (`"Äpfel"` matches `"ap"`, `"résumé"` matches `"resume"`). Pass `locale`
903
+ * and/or any `Intl.Collator` options to override.
904
+ */
905
+ interface UseFilterOptions extends Intl.CollatorOptions {
906
+ /** Locale(s) for the collator. Defaults to the runtime's default locale. */
907
+ locale?: Intl.LocalesArgument;
908
+ }
909
+ /** Predicates returned by {@link useFilter}. An empty `query` always matches. */
910
+ interface FilterPredicates {
911
+ /** Whether `text` contains `query`. */
912
+ contains: (text: string, query: string) => boolean;
913
+ /** Whether `text` starts with `query`. */
914
+ startsWith: (text: string, query: string) => boolean;
915
+ /** Whether `text` ends with `query`. */
916
+ endsWith: (text: string, query: string) => boolean;
917
+ }
918
+ /**
919
+ * Creates locale-aware `contains` / `startsWith` / `endsWith` predicates.
920
+ *
921
+ * Matching uses `Intl.Collator` with `sensitivity: 'base'` and `usage: 'search'` by default, so
922
+ * comparisons ignore case and diacritics. An empty (or whitespace-only) `query` matches everything,
923
+ * which is the natural "no filter applied" state for a combobox.
924
+ *
925
+ * @example
926
+ * const { contains } = useFilter();
927
+ * contains('Äpfel', 'ap'); // true
928
+ */
929
+ declare function useFilter(options?: UseFilterOptions): FilterPredicates;
930
+
877
931
  /**
878
932
  * Keeps hover content open while the pointer crosses the gap between a trigger and a popup.
879
933
  */
@@ -882,6 +936,83 @@ declare function useGraceArea(triggerEl: Signal<HTMLElement | null | undefined>,
882
936
  onPointerExit: (callback: (value: void) => void) => () => void;
883
937
  };
884
938
 
939
+ /** Options for {@link useListHighlight}. */
940
+ interface UseListHighlightOptions<T> {
941
+ /** All items in DOM order (e.g. a collection provider's `items()`). */
942
+ items: Signal<readonly T[]>;
943
+ /**
944
+ * Whether an item can be highlighted — must return `false` for hidden (filtered-out) and
945
+ * disabled items. Navigation and self-healing both consult this.
946
+ */
947
+ isNavigable: (item: T) => boolean;
948
+ /** Resolves the item's element id, exposed as {@link ListHighlight.activeId} for `aria-activedescendant`. */
949
+ getId: (item: T) => string | undefined;
950
+ /** Whether navigation wraps at the boundaries. Defaults to `true`. */
951
+ loop?: Signal<boolean>;
952
+ /** Injector to bind the self-healing effect to when not called in an injection context. */
953
+ injector?: Injector;
954
+ }
955
+ /** Highlight-model navigation API returned by {@link useListHighlight}. */
956
+ interface ListHighlight<T> {
957
+ /** The currently highlighted item, or `null`. DOM focus is never moved by this state. */
958
+ readonly highlightedItem: Signal<T | null>;
959
+ /** The highlighted item's element id, or `undefined`. Bind to `aria-activedescendant`. */
960
+ readonly activeId: Signal<string | undefined>;
961
+ /** Highlight the first navigable item. */
962
+ first(): void;
963
+ /** Highlight the last navigable item. */
964
+ last(): void;
965
+ /** Highlight the next navigable item (wraps when `loop`). */
966
+ next(): void;
967
+ /** Highlight the previous navigable item (wraps when `loop`). */
968
+ previous(): void;
969
+ /** Highlight a specific item (ignored if not navigable); pass `null` to clear. */
970
+ set(item: T | null): void;
971
+ /** Clear the highlight. */
972
+ clear(): void;
973
+ }
974
+ /**
975
+ * Highlight-model list navigation over a set of items, decoupled from DOM focus.
976
+ *
977
+ * Unlike roving `tabindex`, the highlight is pure state: callers move it with the keyboard while DOM
978
+ * focus stays on a single controlling element (e.g. a combobox `<input>`), which exposes
979
+ * {@link ListHighlight.activeId} as `aria-activedescendant`. Navigation only ever lands on items for
980
+ * which `isNavigable` returns `true`, so hidden (filtered-out) and disabled items are skipped. A
981
+ * self-healing effect clears the highlight if its item stops being navigable or leaves the list, so
982
+ * `activeId` never references a detached or hidden element.
983
+ *
984
+ * Must be called in an injection context, or given an `injector`.
985
+ */
986
+ declare function useListHighlight<T>(options: UseListHighlightOptions<T>): ListHighlight<T>;
987
+
988
+ interface RdxPointerDragHandlers {
989
+ /** Whether a press may begin a drag (e.g. enabled, not on an opt-out element, at a scroll edge). */
990
+ canStart: (event: PointerEvent) => boolean;
991
+ /** A drag actually began (the pointer moved past the start threshold). */
992
+ onStart: (event: PointerEvent) => void;
993
+ /** Pointer moved during a drag. Return `false` to end the gesture early (treated as not committed). */
994
+ onMove: (event: PointerEvent) => void | boolean;
995
+ /** The drag ended. `committed` is true only for a normal `pointerup`, false for cancel/lost-capture/early-stop. */
996
+ onEnd: (event: PointerEvent, committed: boolean) => void;
997
+ }
998
+ /**
999
+ * Shared pointer-drag lifecycle for gesture primitives (drawer swipe, toast swipe, etc.).
1000
+ *
1001
+ * A press only becomes a drag once the pointer moves past {@link DRAG_THRESHOLD}; until then it is a
1002
+ * plain tap, so clicks on buttons inside the element keep working (the gesture never captures the
1003
+ * pointer for a tap). Once dragging, the pointer is captured so a drag that leaves the element still
1004
+ * completes, and `lostpointercapture` / `pointercancel` count as a non-committed end — a swallowed
1005
+ * `pointerup` (native context menu, OS gesture, tab switch) can never wedge the gesture. Only the
1006
+ * primary pointer is tracked, so a second finger can't start a parallel gesture. No-op outside the
1007
+ * browser, keeping SSR safe.
1008
+ *
1009
+ * `onEnd` is NOT called if the host is destroyed mid-drag — callers that pair `onStart`/`onEnd`
1010
+ * (e.g. to pause/resume timers) should balance that case in their own `DestroyRef` cleanup.
1011
+ *
1012
+ * Must be called from an injection context (a directive/component constructor).
1013
+ */
1014
+ declare function usePointerDrag(handlers: RdxPointerDragHandlers): void;
1015
+
885
1016
  /**
886
1017
  * Lifecycle phase of an open/close transition.
887
1018
  *
@@ -969,5 +1100,5 @@ declare enum RdxPositionAlign {
969
1100
  End = "end"
970
1101
  }
971
1102
 
972
- 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, 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, isNullish, isNumberString, isSegmentNavigationKey, isZonedDateTime, j, k, n, normalizeDateStep, normalizeHour12, normalizeHourCycle, p, provideToken, provideValueAccessor, resizeEffect, roundToStepPrecision, segmentBuilders, snapValueToStep, syncSegmentValues, syncTimeSegmentValues, toDate, useArrowNavigation, useDateField, useGraceArea, useScrollLock, useTransitionStatus, watch };
973
- export type { AcceptableValue, AnyExceptLiteral, AriaLivePoliteness, BooleanInput, CreateMonthProps, DataOrientation, DateAndTimeSegmentObj, DateFormatterOptions, DateMatcher, DateRange, DateSegmentObj, DateSegmentPart, DateStep, DayPeriod, Direction, EditableSegmentPart, Formatter, Granularity, HourCycle, Month, NonEditableSegmentPart, Nullable, NumberInput, PlaceholderMap, RdxFormCheckboxControl, RdxFormStateInput, RdxFormUiControl, RdxFormValueControl, RdxTransitionStatus, RdxTransitionStatusRef, RdxValidationError, SafeFunction, SegmentContentObj, SegmentPart, SegmentValueObj, TimeGranularity, TimeSegmentObj, TimeSegmentPart, TimeValue, UseDateFieldProps };
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 };
@@ -1,28 +1,21 @@
1
1
  import * as _angular_core from '@angular/core';
2
- import { InjectionToken, InputSignal, WritableSignal } from '@angular/core';
3
- import { NumberInput } from '@radix-ng/primitives/core';
2
+ import { InputSignal, Signal } from '@angular/core';
3
+ import * as _radix_ng_primitives_core from '@radix-ng/primitives/core';
4
+ import { NumberInput, BooleanInput } from '@radix-ng/primitives/core';
4
5
  import * as _radix_ng_primitives_cropper from '@radix-ng/primitives/cropper';
5
6
 
6
- interface CropperContextToken {
7
- image: InputSignal<string>;
8
- getImageProps: () => {
9
- [key: string]: any;
10
- };
11
- getImageWrapperStyle: () => Record<string, string>;
12
- getCropAreaStyle: () => Record<string, string>;
13
- descriptionId: WritableSignal<string>;
14
- }
15
- declare const CROPPER_ROOT_CONTEXT: InjectionToken<CropperContextToken>;
16
- declare function injectCropperRootContext(): CropperContextToken;
17
-
7
+ /** A crop rectangle in the source image's natural-pixel coordinate space. */
18
8
  type Area = {
19
9
  x: number;
20
10
  y: number;
21
11
  width: number;
22
12
  height: number;
23
13
  };
24
- declare class RdxCropperRootDirective implements CropperContextToken {
14
+
15
+ declare class RdxCropperRootDirective {
25
16
  private readonly elementRef;
17
+ private readonly injector;
18
+ private readonly isBrowser;
26
19
  private readonly CROPPER_DESC_WARN_MESSAGE;
27
20
  readonly image: _angular_core.InputSignal<string>;
28
21
  readonly cropPadding: _angular_core.InputSignalWithTransform<number, unknown>;
@@ -30,29 +23,55 @@ declare class RdxCropperRootDirective implements CropperContextToken {
30
23
  readonly minZoom: _angular_core.InputSignalWithTransform<number, unknown>;
31
24
  readonly maxZoom: _angular_core.InputSignalWithTransform<number, unknown>;
32
25
  readonly zoomSensitivity: _angular_core.InputSignalWithTransform<number, unknown>;
26
+ /** Pan distance (px) per arrow-key press. */
33
27
  readonly keyboardStep: _angular_core.InputSignalWithTransform<number, unknown>;
28
+ /** Zoom delta per `+` / `-` / `PageUp` / `PageDown` press. */
29
+ readonly zoomKeyboardStep: _angular_core.InputSignalWithTransform<number, unknown>;
34
30
  readonly zoom: _angular_core.InputSignalWithTransform<number | undefined, NumberInput>;
31
+ /** Accessible name for the cropper widget. */
32
+ readonly ariaLabel: _angular_core.InputSignal<string>;
33
+ /** Disables all interaction (drag, wheel/pinch zoom, keyboard); exposed as `data-disabled`. */
34
+ readonly disabled: _angular_core.InputSignalWithTransform<boolean, BooleanInput>;
35
35
  readonly onCropChange: _angular_core.OutputEmitterRef<Area | null>;
36
36
  readonly onZoomChange: _angular_core.OutputEmitterRef<number>;
37
37
  private readonly imgWidth;
38
38
  private readonly imgHeight;
39
+ /** Raw content-box size (px) of the root, fed by the ResizeObserver / initial measure. */
40
+ private readonly containerSize;
41
+ /**
42
+ * Crop-area size derived from the container minus padding, fitted to `aspectRatio`. A `computed`
43
+ * (not a written signal) so it stays reactive to `aspectRatio` / `cropPadding` changes, not only
44
+ * to container resizes — previously these inputs were read inside the ResizeObserver closure and
45
+ * never recomputed until the next resize.
46
+ */
47
+ private readonly cropAreaSize;
39
48
  private readonly cropAreaWidth;
40
49
  private readonly cropAreaHeight;
41
50
  private readonly imageWrapperWidth;
42
51
  private readonly imageWrapperHeight;
43
- private readonly offsetX;
44
- private readonly offsetY;
52
+ /** Raw (unclamped) pan-offset intent (px) written by gestures; clamping lives in `clampedOffset`. */
53
+ private readonly offset;
45
54
  private readonly internalZoom;
46
- private readonly isDragging;
47
- readonly descriptionId: _angular_core.WritableSignal<string>;
55
+ protected readonly isDragging: _angular_core.WritableSignal<boolean>;
56
+ readonly descriptionId: string;
48
57
  private readonly isZoomControlled;
49
58
  protected readonly effectiveZoom: _angular_core.Signal<number>;
50
- protected readonly zoomValueText: _angular_core.Signal<string>;
59
+ /**
60
+ * The applied pan offset (px): the raw intent clamped to keep the image covering the crop window
61
+ * at the current geometry/zoom. Derived (not an effect) so it self-corrects when the container
62
+ * resizes or the zoom/aspect-ratio changes — no write-back, no `untracked` re-entrancy. This is the
63
+ * value the view renders and the crop math reads.
64
+ */
65
+ private readonly clampedOffset;
66
+ /**
67
+ * Crop rectangle derived from the rendered pan/zoom — the single source of truth for emission.
68
+ * `onCropChange` fires from one effect watching this, so interactions/handlers never emit directly
69
+ * (which previously double-emitted). Value equality keeps it from notifying on equal results.
70
+ */
71
+ private readonly cropData;
51
72
  private readonly dragStartPoint;
52
73
  private readonly dragStartOffset;
53
- private readonly latestRestrictedOffset;
54
74
  private readonly latestZoom;
55
- private readonly isInitialSetupDone;
56
75
  private readonly initialPinchDistance;
57
76
  private readonly initialPinchZoom;
58
77
  private readonly isPinching;
@@ -62,75 +81,89 @@ declare class RdxCropperRootDirective implements CropperContextToken {
62
81
  private initializeContainerDimensions;
63
82
  private setupImageLoadEffect;
64
83
  private setupDimensionsEffects;
84
+ /** Current rendered geometry the crop math operates on, read from the state signals. */
85
+ private geometry;
65
86
  private restrictOffset;
66
- private calculateCropData;
67
- private setupCropCalculationEffect;
68
87
  private setupAccessibilityWarningEffect;
88
+ /**
89
+ * Single attachment point for every interaction listener. Re-runs on `disabled()`, so a disabled
90
+ * cropper has NO interaction listeners bound at all — there is no per-handler `disabled` check to
91
+ * forget, and a new gesture path can't accidentally bypass the gate. Uses `{ passive: false }` so
92
+ * the handlers can `preventDefault()` (wheel/touch scrolling, arrow-key page scroll).
93
+ */
69
94
  private setupEventListenersEffect;
70
- private handleInteractionEnd;
95
+ private onMouseDown;
71
96
  /**
72
- * @ignore
97
+ * Zoom toward an anchor point (coordinates relative to the root's center). `fromZoom`/`fromOffset`
98
+ * are the zoom/offset the anchor is measured against — the live state for wheel/keyboard, the
99
+ * gesture-start baseline for pinch. Emits the zoom request via {@link updateZoom}, then re-anchors
100
+ * the pan offset **only when the zoom is uncontrolled**: in controlled mode the rendered zoom does
101
+ * not change until the parent writes `zoom` back, so writing an offset for a not-yet-applied zoom
102
+ * would pan the image without rescaling it (`clampedOffset` re-derives once the new zoom applies).
73
103
  */
74
- onMouseDown(e: MouseEvent): void;
104
+ private zoomToPoint;
75
105
  private handleWheel;
76
106
  private getPinchDistance;
77
107
  private getPinchCenter;
78
108
  private handleTouchStart;
79
109
  private handleTouchMove;
80
110
  private handleTouchEnd;
111
+ private onKeyDown;
112
+ /** Zoom by `delta` keeping the crop center fixed (the keyboard counterpart of wheel/pinch zoom). */
113
+ private zoomFromCenter;
81
114
  /**
82
- * @ignore
115
+ * Inline style for the image wrapper: measured size, centered in the root, then translated and
116
+ * scaled by the current pan offset and zoom. A `computed` (not a method) so the `[style]` binding
117
+ * only re-applies when an input actually changes — a per-change-detection method call would
118
+ * allocate a new object every tick and force a constant re-bind.
83
119
  */
84
- onKeyDown(e: KeyboardEvent): void;
85
- /**
86
- * @ignore
87
- */
88
- onKeyUp(e: KeyboardEvent): void;
89
- /**
90
- * @ignore
91
- */
92
- getImageProps(): {
93
- [key: string]: any;
94
- };
95
- /**
96
- * @ignore
97
- */
98
- getImageWrapperStyle(): Record<string, string>;
99
- /**
100
- * @ignore
101
- */
102
- getCropAreaStyle(): Record<string, string>;
120
+ readonly imageWrapperStyle: _angular_core.Signal<Record<string, string>>;
121
+ /** Inline style for the crop-area overlay (its measured width/height). */
122
+ readonly cropAreaStyle: _angular_core.Signal<Record<string, string>>;
103
123
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<RdxCropperRootDirective, never>;
104
- static ɵdir: _angular_core.ɵɵDirectiveDeclaration<RdxCropperRootDirective, "[rdxCropperRoot]", never, { "image": { "alias": "image"; "required": true; "isSignal": true; }; "cropPadding": { "alias": "cropPadding"; "required": false; "isSignal": true; }; "aspectRatio": { "alias": "aspectRatio"; "required": false; "isSignal": true; }; "minZoom": { "alias": "minZoom"; "required": false; "isSignal": true; }; "maxZoom": { "alias": "maxZoom"; "required": false; "isSignal": true; }; "zoomSensitivity": { "alias": "zoomSensitivity"; "required": false; "isSignal": true; }; "keyboardStep": { "alias": "keyboardStep"; "required": false; "isSignal": true; }; "zoom": { "alias": "zoom"; "required": false; "isSignal": true; }; }, { "onCropChange": "onCropChange"; "onZoomChange": "onZoomChange"; }, never, never, true, never>;
124
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<RdxCropperRootDirective, "[rdxCropperRoot]", never, { "image": { "alias": "image"; "required": true; "isSignal": true; }; "cropPadding": { "alias": "cropPadding"; "required": false; "isSignal": true; }; "aspectRatio": { "alias": "aspectRatio"; "required": false; "isSignal": true; }; "minZoom": { "alias": "minZoom"; "required": false; "isSignal": true; }; "maxZoom": { "alias": "maxZoom"; "required": false; "isSignal": true; }; "zoomSensitivity": { "alias": "zoomSensitivity"; "required": false; "isSignal": true; }; "keyboardStep": { "alias": "keyboardStep"; "required": false; "isSignal": true; }; "zoomKeyboardStep": { "alias": "zoomKeyboardStep"; "required": false; "isSignal": true; }; "zoom": { "alias": "zoom"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; }, { "onCropChange": "onCropChange"; "onZoomChange": "onZoomChange"; }, never, never, true, never>;
105
125
  }
106
126
 
107
127
  declare class RdxCropperImageComponent {
108
- protected readonly rootContext: _radix_ng_primitives_cropper.CropperContextToken;
128
+ protected readonly rootContext: _radix_ng_primitives_cropper.CropperRootContext;
109
129
  readonly imgClass: _angular_core.InputSignal<string | undefined>;
110
130
  readonly imgStyles: _angular_core.InputSignal<string | undefined>;
111
- protected readonly imgClasses: _angular_core.Signal<string | undefined>;
112
- protected readonly imgStyless: _angular_core.Signal<string | undefined>;
131
+ /**
132
+ * `alt` text for the rendered image. Defaults to `''` (decorative — screen readers skip it, since
133
+ * the cropper widget describes itself via the root's label/description). Set a non-empty value to
134
+ * give the image a meaningful accessible name.
135
+ */
136
+ readonly imgAlt: _angular_core.InputSignal<string>;
113
137
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<RdxCropperImageComponent, never>;
114
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<RdxCropperImageComponent, "[rdxCropperImage]", never, { "imgClass": { "alias": "imgClass"; "required": false; "isSignal": true; }; "imgStyles": { "alias": "imgStyles"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
138
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<RdxCropperImageComponent, "[rdxCropperImage]", never, { "imgClass": { "alias": "imgClass"; "required": false; "isSignal": true; }; "imgStyles": { "alias": "imgStyles"; "required": false; "isSignal": true; }; "imgAlt": { "alias": "imgAlt"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
115
139
  }
116
140
 
117
141
  declare class RdxCropperCropAreaDirective {
118
- readonly rootContext: _radix_ng_primitives_cropper.CropperContextToken;
142
+ readonly rootContext: _radix_ng_primitives_cropper.CropperRootContext;
119
143
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<RdxCropperCropAreaDirective, never>;
120
144
  static ɵdir: _angular_core.ɵɵDirectiveDeclaration<RdxCropperCropAreaDirective, "[rdxCropperCropArea]", never, {}, {}, never, never, true, never>;
121
145
  }
122
146
 
123
147
  declare class RdxCropperDescriptionDirective {
124
- readonly rootContext: _radix_ng_primitives_cropper.CropperContextToken;
148
+ readonly rootContext: _radix_ng_primitives_cropper.CropperRootContext;
125
149
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<RdxCropperDescriptionDirective, never>;
126
150
  static ɵdir: _angular_core.ɵɵDirectiveDeclaration<RdxCropperDescriptionDirective, "[rdxCropperDescription]", never, {}, {}, never, never, true, never>;
127
151
  }
128
152
 
153
+ interface CropperRootContext {
154
+ image: InputSignal<string>;
155
+ imageWrapperStyle: Signal<Record<string, string>>;
156
+ cropAreaStyle: Signal<Record<string, string>>;
157
+ descriptionId: string;
158
+ }
159
+ declare const injectCropperRootContext: _radix_ng_primitives_core.InjectContext<CropperRootContext>;
160
+ declare const provideCropperRootContext: (useFactory: () => CropperRootContext) => _angular_core.Provider;
161
+
129
162
  declare class RdxCropperModule {
130
163
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<RdxCropperModule, never>;
131
164
  static ɵmod: _angular_core.ɵɵNgModuleDeclaration<RdxCropperModule, never, [typeof RdxCropperRootDirective, typeof RdxCropperImageComponent, typeof RdxCropperCropAreaDirective, typeof RdxCropperDescriptionDirective], [typeof RdxCropperRootDirective, typeof RdxCropperImageComponent, typeof RdxCropperCropAreaDirective, typeof RdxCropperDescriptionDirective]>;
132
165
  static ɵinj: _angular_core.ɵɵInjectorDeclaration<RdxCropperModule>;
133
166
  }
134
167
 
135
- export { CROPPER_ROOT_CONTEXT, RdxCropperCropAreaDirective, RdxCropperDescriptionDirective, RdxCropperImageComponent, RdxCropperModule, RdxCropperRootDirective, injectCropperRootContext };
136
- export type { Area, CropperContextToken };
168
+ export { RdxCropperCropAreaDirective, RdxCropperDescriptionDirective, RdxCropperImageComponent, RdxCropperModule, RdxCropperRootDirective, injectCropperRootContext, provideCropperRootContext };
169
+ export type { Area, CropperRootContext };
@@ -6,11 +6,11 @@ import { DateValue } from '@internationalized/date';
6
6
 
7
7
  declare class RdxDateFieldRootDirective {
8
8
  /**
9
- * The controlled checked state of the calendar.
9
+ * The controlled value of the date field.
10
10
  */
11
11
  readonly value: _angular_core.ModelSignal<DateValue | undefined>;
12
12
  /**
13
- * A callback fired when the date field's value is invalid.
13
+ * A matcher that marks specific dates as unavailable; a matched value makes the field invalid.
14
14
  */
15
15
  readonly isDateUnavailable: _angular_core.InputSignal<DateMatcher | undefined>;
16
16
  /**
@@ -178,14 +178,20 @@ declare class RdxDateFieldInputDirective {
178
178
  private readonly fieldData;
179
179
  private readonly attributes;
180
180
  /**
181
+ * Attribute keys applied imperatively on the previous effect run, so keys that
182
+ * disappear from `attributes()` are removed instead of lingering as stale state.
181
183
  * @ignore
182
184
  */
183
- handleSegmentClick: (e: Event) => void;
185
+ private appliedAttrs;
186
+ constructor();
184
187
  /**
185
188
  * @ignore
186
189
  */
187
- handleSegmentKeydown: (e: Event) => void;
188
- constructor();
190
+ handleSegmentClick(event: Event): void;
191
+ /**
192
+ * @ignore
193
+ */
194
+ handleSegmentKeydown(event: Event): void;
189
195
  /**
190
196
  * @ignore
191
197
  */
@@ -1,6 +1,7 @@
1
1
  import * as _angular_core from '@angular/core';
2
2
  import { InjectionToken, Provider, Signal, ElementRef } from '@angular/core';
3
3
  import * as i1 from '@radix-ng/primitives/presence';
4
+ import * as _radix_ng_primitives_core from '@radix-ng/primitives/core';
4
5
  import { RdxTransitionStatus, BooleanInput } from '@radix-ng/primitives/core';
5
6
  import * as _radix_ng_primitives_dialog from '@radix-ng/primitives/dialog';
6
7
  import * as i1$1 from '@radix-ng/primitives/portal';
@@ -93,7 +94,7 @@ interface RdxDialogRootContext {
93
94
  close: (reason?: RdxDialogOpenChangeReason, event?: Event) => void;
94
95
  toggle: (triggerId: string, trigger: HTMLElement, payload?: unknown, event?: Event) => void;
95
96
  }
96
- declare const injectRdxDialogRootContext: (optional?: boolean) => RdxDialogRootContext | null;
97
+ declare const injectRdxDialogRootContext: _radix_ng_primitives_core.InjectContext<RdxDialogRootContext>;
97
98
  declare const provideRdxDialogRootContext: (useFactory: () => RdxDialogRootContext) => _angular_core.Provider;
98
99
  /**
99
100
  * Groups all parts of the dialog.