@radix-ng/primitives 1.0.0-beta.5 → 1.0.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.
- package/composite/README.md +3 -0
- package/fesm2022/radix-ng-primitives-accordion.mjs +20 -44
- package/fesm2022/radix-ng-primitives-accordion.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-checkbox.mjs +134 -58
- package/fesm2022/radix-ng-primitives-checkbox.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-composite.mjs +599 -0
- package/fesm2022/radix-ng-primitives-composite.mjs.map +1 -0
- package/fesm2022/radix-ng-primitives-drawer.mjs +442 -2
- package/fesm2022/radix-ng-primitives-drawer.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-menu.mjs +315 -68
- package/fesm2022/radix-ng-primitives-menu.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-menubar.mjs +91 -36
- package/fesm2022/radix-ng-primitives-menubar.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-navigation-menu.mjs +281 -88
- package/fesm2022/radix-ng-primitives-navigation-menu.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-popover.mjs +40 -15
- package/fesm2022/radix-ng-primitives-popover.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-popper.mjs +73 -65
- package/fesm2022/radix-ng-primitives-popper.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-radio.mjs +63 -27
- package/fesm2022/radix-ng-primitives-radio.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-scroll-area.mjs +56 -25
- package/fesm2022/radix-ng-primitives-scroll-area.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-select.mjs +59 -29
- package/fesm2022/radix-ng-primitives-select.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-slider.mjs +57 -13
- package/fesm2022/radix-ng-primitives-slider.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-tabs.mjs +335 -73
- package/fesm2022/radix-ng-primitives-tabs.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-toggle-group.mjs +66 -21
- package/fesm2022/radix-ng-primitives-toggle-group.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-toggle.mjs +29 -11
- package/fesm2022/radix-ng-primitives-toggle.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-toolbar.mjs +68 -36
- package/fesm2022/radix-ng-primitives-toolbar.mjs.map +1 -1
- package/navigation-menu/README.md +5 -2
- package/package.json +6 -10
- package/types/radix-ng-primitives-accordion.d.ts +12 -16
- package/types/radix-ng-primitives-checkbox.d.ts +98 -70
- package/types/radix-ng-primitives-composite.d.ts +195 -0
- package/types/radix-ng-primitives-drawer.d.ts +40 -2
- package/types/radix-ng-primitives-menu.d.ts +46 -16
- package/types/radix-ng-primitives-menubar.d.ts +12 -5
- package/types/radix-ng-primitives-navigation-menu.d.ts +65 -33
- package/types/radix-ng-primitives-popover.d.ts +9 -5
- package/types/radix-ng-primitives-popper.d.ts +1 -0
- package/types/radix-ng-primitives-radio.d.ts +11 -9
- package/types/radix-ng-primitives-scroll-area.d.ts +4 -1
- package/types/radix-ng-primitives-select.d.ts +46 -32
- package/types/radix-ng-primitives-slider.d.ts +19 -4
- package/types/radix-ng-primitives-tabs.d.ts +69 -14
- package/types/radix-ng-primitives-toggle-group.d.ts +27 -16
- package/types/radix-ng-primitives-toggle.d.ts +5 -5
- package/types/radix-ng-primitives-toolbar.d.ts +84 -69
- package/collection/README.md +0 -1
- package/fesm2022/radix-ng-primitives-collection.mjs +0 -72
- package/fesm2022/radix-ng-primitives-collection.mjs.map +0 -1
- package/fesm2022/radix-ng-primitives-roving-focus.mjs +0 -388
- package/fesm2022/radix-ng-primitives-roving-focus.mjs.map +0 -1
- package/roving-focus/README.md +0 -3
- package/types/radix-ng-primitives-collection.d.ts +0 -44
- package/types/radix-ng-primitives-roving-focus.d.ts +0 -187
|
@@ -7,8 +7,8 @@ import * as i2 from '@radix-ng/primitives/floating-focus-manager';
|
|
|
7
7
|
import { getInteractionTypeFromEvent, provideFloatingFocusManagerConfig, RdxFloatingFocusManager, createRdxTriggerInteraction } from '@radix-ng/primitives/floating-focus-manager';
|
|
8
8
|
import * as i1 from '@radix-ng/primitives/popper';
|
|
9
9
|
import { RdxPopper, RdxPopperContent, RdxPopperContentWrapper, legacyPopperVars, provideRdxPopperContentWrapper, provideRdxPopperContentConfig, RdxPopperAnchor } from '@radix-ng/primitives/popper';
|
|
10
|
-
import * as i4 from '@radix-ng/primitives/
|
|
11
|
-
import {
|
|
10
|
+
import * as i4 from '@radix-ng/primitives/composite';
|
|
11
|
+
import { RdxCompositeList, RdxCompositeListItem } from '@radix-ng/primitives/composite';
|
|
12
12
|
import { RdxDismiss } from '@radix-ng/primitives/dismissable-layer';
|
|
13
13
|
import * as i1$1 from '@radix-ng/primitives/portal';
|
|
14
14
|
import { RdxPortalPresence } from '@radix-ng/primitives/portal';
|
|
@@ -341,9 +341,15 @@ const context$1 = () => {
|
|
|
341
341
|
isPositioned: context.isPositioned,
|
|
342
342
|
selectedItem: context.selectedItem,
|
|
343
343
|
selectedItemText: context.selectedItemText,
|
|
344
|
+
items: context.items,
|
|
344
345
|
highlightedItem: context.highlight.highlightedItem,
|
|
345
|
-
isHighlighted: (
|
|
346
|
-
highlightItem: (
|
|
346
|
+
isHighlighted: (element) => context.highlight.highlightedItem()?.element === element,
|
|
347
|
+
highlightItem: (element) => {
|
|
348
|
+
const item = context.items().find((item) => item.element === element);
|
|
349
|
+
if (item) {
|
|
350
|
+
context.highlight.set(item);
|
|
351
|
+
}
|
|
352
|
+
},
|
|
347
353
|
isKeyboardActive: () => context.isKeyboardActive(),
|
|
348
354
|
setKeyboardActive: (value) => context.setKeyboardActive(value),
|
|
349
355
|
onViewportChange: (node) => {
|
|
@@ -391,23 +397,23 @@ class RdxSelectPopup {
|
|
|
391
397
|
this.floatingContext = inject(RDX_FLOATING_ROOT_CONTEXT);
|
|
392
398
|
this.registration = inject(RDX_FLOATING_REGISTRATION, { optional: true });
|
|
393
399
|
this.currentElement = inject(ElementRef);
|
|
394
|
-
this.
|
|
400
|
+
this.compositeList = inject(RdxCompositeList, { self: true });
|
|
395
401
|
this.injector = inject(Injector);
|
|
396
402
|
this.rootContext = injectSelectRootContext();
|
|
397
403
|
/**
|
|
398
404
|
* The collected items (DOM order). Exposed so the `item-aligned` positioner — now the popup's
|
|
399
|
-
* **ancestor** — can read them without injecting
|
|
400
|
-
*
|
|
405
|
+
* **ancestor** — can read them without injecting the composite list (which the popup provides as
|
|
406
|
+
* a descendant, so an upward `inject` would not find it).
|
|
401
407
|
*/
|
|
402
|
-
this.items = this.
|
|
408
|
+
this.items = computed(() => this.compositeList.items(), ...(ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []));
|
|
403
409
|
/**
|
|
404
410
|
* Highlight-model navigation over the collected items (DOM order). `loop` is disabled so arrow
|
|
405
411
|
* navigation stops at the first / last item instead of wrapping around — matching native
|
|
406
412
|
* `<select>` behavior.
|
|
407
413
|
*/
|
|
408
414
|
this.highlight = useListHighlight({
|
|
409
|
-
items: this.
|
|
410
|
-
isNavigable: (item) => !item.
|
|
415
|
+
items: this.items,
|
|
416
|
+
isNavigable: (item) => !item.metadata()?.disabled,
|
|
411
417
|
getId: (item) => item.element.id,
|
|
412
418
|
loop: signal(false),
|
|
413
419
|
injector: this.injector
|
|
@@ -420,6 +426,7 @@ class RdxSelectPopup {
|
|
|
420
426
|
// Tracks whether the last interaction was the keyboard, so the highlight doesn't jump to an item
|
|
421
427
|
// the cursor happens to rest on when arrow-key navigation scrolls the list.
|
|
422
428
|
this.keyboardActive = false;
|
|
429
|
+
this.hasHighlightedOpen = false;
|
|
423
430
|
/**
|
|
424
431
|
* Event handler called when the escape key is down.
|
|
425
432
|
* Can be prevented.
|
|
@@ -438,9 +445,8 @@ class RdxSelectPopup {
|
|
|
438
445
|
*/
|
|
439
446
|
this.positioner = inject(RDX_SELECT_POSITIONER_TOKEN, { optional: true });
|
|
440
447
|
this.positioner?.placed.subscribe(() => {
|
|
441
|
-
this.highlightSelectedItem();
|
|
442
|
-
this.scrollSelectedIntoView();
|
|
443
448
|
this.isPositioned.set(true);
|
|
449
|
+
this.highlightSelectedItemAfterPositioned();
|
|
444
450
|
// In Popper mode the popup lives inside the positioner, which stays `visibility: hidden`
|
|
445
451
|
// until it is placed — so the mount-time `mountAutoFocus` call no-ops on the hidden
|
|
446
452
|
// listbox and keyboard navigation never starts. Focus it now that it is visible (skip if
|
|
@@ -450,6 +456,16 @@ class RdxSelectPopup {
|
|
|
450
456
|
popup.focus({ preventScroll: true });
|
|
451
457
|
}
|
|
452
458
|
});
|
|
459
|
+
effect(() => {
|
|
460
|
+
if (!this.rootContext.open()) {
|
|
461
|
+
this.hasHighlightedOpen = false;
|
|
462
|
+
return;
|
|
463
|
+
}
|
|
464
|
+
if (!this.isPositioned() || this.hasHighlightedOpen) {
|
|
465
|
+
return;
|
|
466
|
+
}
|
|
467
|
+
this.highlightSelectedItemAfterPositioned();
|
|
468
|
+
});
|
|
453
469
|
// Keep the highlighted item in view during keyboard navigation. The highlight model is pure
|
|
454
470
|
// state (it never moves DOM focus or scrolls), so without this the highlight can move past the
|
|
455
471
|
// visible viewport — behind the scroll buttons. Only keyboard moves scroll; hover highlights
|
|
@@ -550,8 +566,8 @@ class RdxSelectPopup {
|
|
|
550
566
|
}
|
|
551
567
|
/** Highlights the selected item (or the first enabled one) when the popup opens. */
|
|
552
568
|
highlightSelectedItem() {
|
|
553
|
-
const items = this.
|
|
554
|
-
const selected = items.find((item) => valueComparator(this.rootContext.value(), item.
|
|
569
|
+
const items = this.items();
|
|
570
|
+
const selected = items.find((item) => valueComparator(this.rootContext.value(), item.metadata()?.value, this.rootContext.isItemEqualToValue()));
|
|
555
571
|
if (selected) {
|
|
556
572
|
this.highlight.set(selected);
|
|
557
573
|
}
|
|
@@ -559,6 +575,14 @@ class RdxSelectPopup {
|
|
|
559
575
|
this.highlight.first();
|
|
560
576
|
}
|
|
561
577
|
}
|
|
578
|
+
highlightSelectedItemAfterPositioned() {
|
|
579
|
+
if (this.items().length === 0) {
|
|
580
|
+
return;
|
|
581
|
+
}
|
|
582
|
+
this.highlightSelectedItem();
|
|
583
|
+
this.scrollSelectedIntoView();
|
|
584
|
+
this.hasHighlightedOpen = true;
|
|
585
|
+
}
|
|
562
586
|
scrollSelectedIntoView() {
|
|
563
587
|
this.selectedItem()?.scrollIntoView?.({ block: 'nearest' });
|
|
564
588
|
}
|
|
@@ -580,8 +604,9 @@ class RdxSelectPopup {
|
|
|
580
604
|
if (SELECTION_KEYS.includes(keyEvent.key)) {
|
|
581
605
|
event.preventDefault();
|
|
582
606
|
const item = this.highlight.highlightedItem();
|
|
583
|
-
|
|
584
|
-
|
|
607
|
+
const metadata = item?.metadata();
|
|
608
|
+
if (item && metadata && !metadata.disabled) {
|
|
609
|
+
this.rootContext.onValueChange(metadata.value, 'item-press', event);
|
|
585
610
|
if (!this.rootContext.multiple()) {
|
|
586
611
|
this.rootContext.onOpenChange(false, 'item-press', event);
|
|
587
612
|
}
|
|
@@ -624,7 +649,7 @@ class RdxSelectPopup {
|
|
|
624
649
|
closeInteractionType: () => rootContext.closeInteractionType()
|
|
625
650
|
};
|
|
626
651
|
})
|
|
627
|
-
], hostDirectives: [{ directive: i1.RdxPopperContent }, { directive: i2.RdxFloatingFocusManager, inputs: ["returnFocus", "finalFocus"] }, { directive: i3.RdxFloatingNodeRegistration }, { directive: i4.
|
|
652
|
+
], hostDirectives: [{ directive: i1.RdxPopperContent }, { directive: i2.RdxFloatingFocusManager, inputs: ["returnFocus", "finalFocus"] }, { directive: i3.RdxFloatingNodeRegistration }, { directive: i4.RdxCompositeList }], ngImport: i0 }); }
|
|
628
653
|
}
|
|
629
654
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxSelectPopup, decorators: [{
|
|
630
655
|
type: Directive,
|
|
@@ -634,7 +659,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
634
659
|
RdxPopperContent,
|
|
635
660
|
{ directive: RdxFloatingFocusManager, inputs: ['returnFocus: finalFocus'] },
|
|
636
661
|
RdxFloatingNodeRegistration,
|
|
637
|
-
|
|
662
|
+
RdxCompositeList
|
|
638
663
|
],
|
|
639
664
|
providers: [
|
|
640
665
|
provideSelectPopupContext(context$1),
|
|
@@ -692,7 +717,7 @@ class RdxSelectItem {
|
|
|
692
717
|
constructor() {
|
|
693
718
|
this.rootContext = injectSelectRootContext();
|
|
694
719
|
this.contentContext = injectSelectPopupContext();
|
|
695
|
-
this.
|
|
720
|
+
this.listItem = inject(RdxCompositeListItem, { self: true });
|
|
696
721
|
this.currentElement = inject(ElementRef);
|
|
697
722
|
this.value = input(...(ngDevMode ? [undefined, { debugName: "value" }] : /* istanbul ignore next */ []));
|
|
698
723
|
this.textValue = input('', ...(ngDevMode ? [{ debugName: "textValue" }] : /* istanbul ignore next */ []));
|
|
@@ -700,7 +725,7 @@ class RdxSelectItem {
|
|
|
700
725
|
this.textValue$ = linkedSignal(this.textValue, ...(ngDevMode ? [{ debugName: "textValue$" }] : /* istanbul ignore next */ []));
|
|
701
726
|
this.isSelected = computed(() => valueComparator(this.rootContext.value(), this.value(), this.rootContext.isItemEqualToValue()), ...(ngDevMode ? [{ debugName: "isSelected" }] : /* istanbul ignore next */ []));
|
|
702
727
|
/** Highlighted via the highlight model (keyboard / hover), not DOM focus. */
|
|
703
|
-
this.isHighlighted = computed(() => this.contentContext.isHighlighted(this.
|
|
728
|
+
this.isHighlighted = computed(() => this.contentContext.isHighlighted(this.currentElement.nativeElement), ...(ngDevMode ? [{ debugName: "isHighlighted" }] : /* istanbul ignore next */ []));
|
|
704
729
|
/** Item id, referenced by the popup's `aria-activedescendant`. */
|
|
705
730
|
this.id = injectId('rdx-select-item-');
|
|
706
731
|
this.textId = injectId('rdx-select-item-text-');
|
|
@@ -708,6 +733,13 @@ class RdxSelectItem {
|
|
|
708
733
|
this.contentContext.itemRefCallback(this.currentElement.nativeElement, this.value(), this.disabled());
|
|
709
734
|
});
|
|
710
735
|
this.SELECT_SELECT = 'select.select';
|
|
736
|
+
effect(() => {
|
|
737
|
+
this.listItem.setMetadata({
|
|
738
|
+
value: this.value(),
|
|
739
|
+
disabled: this.disabled(),
|
|
740
|
+
textValue: this.textValue$()
|
|
741
|
+
});
|
|
742
|
+
});
|
|
711
743
|
}
|
|
712
744
|
onPointerUp(event) {
|
|
713
745
|
if (event.defaultPrevented)
|
|
@@ -738,7 +770,7 @@ class RdxSelectItem {
|
|
|
738
770
|
return;
|
|
739
771
|
}
|
|
740
772
|
if (!this.disabled()) {
|
|
741
|
-
this.contentContext.highlightItem(this.
|
|
773
|
+
this.contentContext.highlightItem(this.currentElement.nativeElement);
|
|
742
774
|
}
|
|
743
775
|
}
|
|
744
776
|
handleKeyDown(event) {
|
|
@@ -749,7 +781,7 @@ class RdxSelectItem {
|
|
|
749
781
|
this.onPointerUp(keyEvent);
|
|
750
782
|
}
|
|
751
783
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxSelectItem, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
752
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.9", type: RdxSelectItem, isStandalone: true, selector: "[rdxSelectItem]", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, textValue: { classPropertyName: "textValue", publicName: "textValue", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "option" }, listeners: { "pointerup": "onPointerUp($event)", "pointerleave": "onPointerLeave($event)", "pointermove": "onPointerMove($event)" }, properties: { "attr.id": "id", "attr.aria-selected": "isSelected()", "attr.aria-disabled": "disabled() ? \"true\" : undefined", "attr.data-state": "isSelected() ? \"checked\" : \"unchecked\"", "attr.data-selected": "isSelected() ? \"\" : undefined", "attr.data-highlighted": "isHighlighted() ? \"\" : undefined", "attr.data-disabled": "disabled() ? \"\" : undefined" } }, providers: [provideSelectItemContext(context)], exportAs: ["rdxSelectItem"], hostDirectives: [{ directive: i4.
|
|
784
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.9", type: RdxSelectItem, isStandalone: true, selector: "[rdxSelectItem]", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, textValue: { classPropertyName: "textValue", publicName: "textValue", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "option" }, listeners: { "pointerup": "onPointerUp($event)", "pointerleave": "onPointerLeave($event)", "pointermove": "onPointerMove($event)" }, properties: { "attr.id": "id", "attr.aria-selected": "isSelected()", "attr.aria-disabled": "disabled() ? \"true\" : undefined", "attr.data-state": "isSelected() ? \"checked\" : \"unchecked\"", "attr.data-selected": "isSelected() ? \"\" : undefined", "attr.data-highlighted": "isHighlighted() ? \"\" : undefined", "attr.data-disabled": "disabled() ? \"\" : undefined" } }, providers: [provideSelectItemContext(context)], exportAs: ["rdxSelectItem"], hostDirectives: [{ directive: i4.RdxCompositeListItem }], ngImport: i0 }); }
|
|
753
785
|
}
|
|
754
786
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxSelectItem, decorators: [{
|
|
755
787
|
type: Directive,
|
|
@@ -757,12 +789,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
757
789
|
selector: '[rdxSelectItem]',
|
|
758
790
|
exportAs: 'rdxSelectItem',
|
|
759
791
|
providers: [provideSelectItemContext(context)],
|
|
760
|
-
hostDirectives: [
|
|
761
|
-
{
|
|
762
|
-
directive: RdxCollectionItem,
|
|
763
|
-
inputs: ['value', 'disabled']
|
|
764
|
-
}
|
|
765
|
-
],
|
|
792
|
+
hostDirectives: [RdxCompositeListItem],
|
|
766
793
|
host: {
|
|
767
794
|
role: 'option',
|
|
768
795
|
'[attr.id]': 'id',
|
|
@@ -777,7 +804,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
777
804
|
'(pointermove)': 'onPointerMove($event)'
|
|
778
805
|
}
|
|
779
806
|
}]
|
|
780
|
-
}], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], textValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "textValue", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }] } });
|
|
807
|
+
}], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], textValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "textValue", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }] } });
|
|
781
808
|
|
|
782
809
|
class RdxSelectItemIndicator {
|
|
783
810
|
constructor() {
|
|
@@ -1040,6 +1067,9 @@ class RdxSelectTrigger {
|
|
|
1040
1067
|
// We force `focus` in this case. Note: this doesn't create any other side-effect
|
|
1041
1068
|
// because we are preventing default in `onPointerDown` so effectively
|
|
1042
1069
|
// this only runs for a label 'click'
|
|
1070
|
+
if (this.rootContext.open()) {
|
|
1071
|
+
return;
|
|
1072
|
+
}
|
|
1043
1073
|
event?.currentTarget?.focus();
|
|
1044
1074
|
}
|
|
1045
1075
|
onPointerDown(event) {
|