@radix-ng/primitives 0.51.0 → 1.0.0-beta.1
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/fesm2022/radix-ng-primitives-accordion.mjs +105 -38
- package/fesm2022/radix-ng-primitives-accordion.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-alert-dialog.mjs +221 -129
- package/fesm2022/radix-ng-primitives-alert-dialog.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-arrow.mjs +20 -4
- package/fesm2022/radix-ng-primitives-arrow.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-aspect-ratio.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-avatar.mjs +54 -61
- package/fesm2022/radix-ng-primitives-avatar.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-button.mjs +123 -0
- package/fesm2022/radix-ng-primitives-button.mjs.map +1 -0
- package/fesm2022/radix-ng-primitives-calendar.mjs +95 -83
- package/fesm2022/radix-ng-primitives-calendar.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-checkbox.mjs +378 -54
- package/fesm2022/radix-ng-primitives-checkbox.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-collapsible.mjs +182 -81
- package/fesm2022/radix-ng-primitives-collapsible.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-collection.mjs +40 -57
- package/fesm2022/radix-ng-primitives-collection.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-config.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-context-menu.mjs +140 -424
- package/fesm2022/radix-ng-primitives-context-menu.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-core.mjs +845 -744
- package/fesm2022/radix-ng-primitives-core.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-cropper.mjs +288 -308
- package/fesm2022/radix-ng-primitives-cropper.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-date-field.mjs +104 -58
- package/fesm2022/radix-ng-primitives-date-field.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-dialog.mjs +655 -327
- package/fesm2022/radix-ng-primitives-dialog.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-dismissable-layer.mjs +70 -46
- package/fesm2022/radix-ng-primitives-dismissable-layer.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-drawer.mjs +960 -0
- package/fesm2022/radix-ng-primitives-drawer.mjs.map +1 -0
- package/fesm2022/radix-ng-primitives-editable.mjs +304 -23
- package/fesm2022/radix-ng-primitives-editable.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-field.mjs +363 -0
- package/fesm2022/radix-ng-primitives-field.mjs.map +1 -0
- package/fesm2022/radix-ng-primitives-fieldset.mjs +79 -0
- package/fesm2022/radix-ng-primitives-fieldset.mjs.map +1 -0
- package/fesm2022/radix-ng-primitives-focus-scope.mjs +23 -8
- package/fesm2022/radix-ng-primitives-focus-scope.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-input.mjs +172 -0
- package/fesm2022/radix-ng-primitives-input.mjs.map +1 -0
- package/fesm2022/radix-ng-primitives-label.mjs +6 -6
- package/fesm2022/radix-ng-primitives-label.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-menu.mjs +1907 -363
- package/fesm2022/radix-ng-primitives-menu.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-menubar.mjs +290 -162
- package/fesm2022/radix-ng-primitives-menubar.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-meter.mjs +271 -0
- package/fesm2022/radix-ng-primitives-meter.mjs.map +1 -0
- package/fesm2022/radix-ng-primitives-navigation-menu.mjs +1052 -1553
- package/fesm2022/radix-ng-primitives-navigation-menu.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-number-field.mjs +1102 -367
- package/fesm2022/radix-ng-primitives-number-field.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-pagination.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-popover.mjs +978 -989
- package/fesm2022/radix-ng-primitives-popover.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-popper.mjs +111 -44
- package/fesm2022/radix-ng-primitives-popper.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-portal.mjs +34 -10
- package/fesm2022/radix-ng-primitives-portal.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-presence.mjs +134 -246
- package/fesm2022/radix-ng-primitives-presence.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-preview-card.mjs +997 -0
- package/fesm2022/radix-ng-primitives-preview-card.mjs.map +1 -0
- package/fesm2022/radix-ng-primitives-progress.mjs +223 -84
- package/fesm2022/radix-ng-primitives-progress.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-radio.mjs +191 -51
- package/fesm2022/radix-ng-primitives-radio.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-roving-focus.mjs +96 -50
- package/fesm2022/radix-ng-primitives-roving-focus.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-scroll-area.mjs +923 -0
- package/fesm2022/radix-ng-primitives-scroll-area.mjs.map +1 -0
- package/fesm2022/radix-ng-primitives-select.mjs +791 -509
- package/fesm2022/radix-ng-primitives-select.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-separator.mjs +12 -35
- package/fesm2022/radix-ng-primitives-separator.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-slider.mjs +969 -717
- package/fesm2022/radix-ng-primitives-slider.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-stepper.mjs +15 -19
- package/fesm2022/radix-ng-primitives-stepper.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-switch.mjs +125 -113
- package/fesm2022/radix-ng-primitives-switch.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-tabs.mjs +390 -108
- package/fesm2022/radix-ng-primitives-tabs.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-time-field.mjs +55 -46
- package/fesm2022/radix-ng-primitives-time-field.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-toast.mjs +839 -0
- package/fesm2022/radix-ng-primitives-toast.mjs.map +1 -0
- package/fesm2022/radix-ng-primitives-toggle-group.mjs +121 -247
- package/fesm2022/radix-ng-primitives-toggle-group.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-toggle.mjs +98 -61
- package/fesm2022/radix-ng-primitives-toggle.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-toolbar.mjs +303 -92
- package/fesm2022/radix-ng-primitives-toolbar.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-tooltip.mjs +699 -1072
- package/fesm2022/radix-ng-primitives-tooltip.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-visually-hidden.mjs +25 -66
- package/fesm2022/radix-ng-primitives-visually-hidden.mjs.map +1 -1
- package/meter/README.md +3 -0
- package/navigation-menu/README.md +2 -1
- package/package.json +39 -18
- package/portal/README.md +2 -0
- package/preview-card/README.md +3 -0
- package/schematics/collection.json +1 -0
- package/schematics/ng-add/index.d.ts +3 -2
- package/schematics/ng-add/index.js +62 -31
- package/schematics/ng-add/index.js.map +1 -1
- package/schematics/ng-add/package-config.d.ts +4 -2
- package/schematics/ng-add/package-config.js +10 -2
- package/schematics/ng-add/package-config.js.map +1 -1
- package/schematics/ng-add/schema.d.ts +3 -0
- package/schematics/ng-add/schema.js +3 -0
- package/schematics/ng-add/schema.js.map +1 -0
- package/schematics/ng-add/schema.json +14 -0
- package/select/README.md +2 -0
- package/types/radix-ng-primitives-accordion.d.ts +51 -16
- package/types/radix-ng-primitives-alert-dialog.d.ts +95 -38
- package/types/radix-ng-primitives-arrow.d.ts +1 -1
- package/types/radix-ng-primitives-aspect-ratio.d.ts +1 -1
- package/types/radix-ng-primitives-avatar.d.ts +7 -11
- package/types/radix-ng-primitives-button.d.ts +73 -0
- package/types/radix-ng-primitives-calendar.d.ts +39 -20
- package/types/radix-ng-primitives-checkbox.d.ts +204 -35
- package/types/radix-ng-primitives-collapsible.d.ts +114 -40
- package/types/radix-ng-primitives-collection.d.ts +38 -34
- package/types/radix-ng-primitives-config.d.ts +1 -1
- package/types/radix-ng-primitives-context-menu.d.ts +61 -116
- package/types/radix-ng-primitives-core.d.ts +345 -235
- package/types/radix-ng-primitives-cropper.d.ts +89 -56
- package/types/radix-ng-primitives-date-field.d.ts +49 -28
- package/types/radix-ng-primitives-dialog.d.ts +283 -165
- package/types/radix-ng-primitives-dismissable-layer.d.ts +15 -7
- package/types/radix-ng-primitives-drawer.d.ts +426 -0
- package/types/radix-ng-primitives-editable.d.ts +91 -14
- package/types/radix-ng-primitives-field.d.ts +374 -0
- package/types/radix-ng-primitives-fieldset.d.ts +49 -0
- package/types/radix-ng-primitives-focus-scope.d.ts +15 -6
- package/types/radix-ng-primitives-input.d.ts +87 -0
- package/types/radix-ng-primitives-label.d.ts +0 -1
- package/types/radix-ng-primitives-menu.d.ts +584 -99
- package/types/radix-ng-primitives-menubar.d.ts +61 -50
- package/types/radix-ng-primitives-meter.d.ts +194 -0
- package/types/radix-ng-primitives-navigation-menu.d.ts +422 -340
- package/types/radix-ng-primitives-number-field.d.ts +405 -145
- package/types/radix-ng-primitives-pagination.d.ts +2 -2
- package/types/radix-ng-primitives-popover.d.ts +366 -351
- package/types/radix-ng-primitives-popper.d.ts +68 -11
- package/types/radix-ng-primitives-portal.d.ts +14 -6
- package/types/radix-ng-primitives-presence.d.ts +28 -76
- package/types/radix-ng-primitives-preview-card.d.ts +359 -0
- package/types/radix-ng-primitives-progress.d.ts +175 -48
- package/types/radix-ng-primitives-radio.d.ts +55 -25
- package/types/radix-ng-primitives-roving-focus.d.ts +33 -23
- package/types/radix-ng-primitives-scroll-area.d.ts +253 -0
- package/types/radix-ng-primitives-select.d.ts +475 -177
- package/types/radix-ng-primitives-separator.d.ts +7 -32
- package/types/radix-ng-primitives-slider.d.ts +315 -201
- package/types/radix-ng-primitives-stepper.d.ts +5 -7
- package/types/radix-ng-primitives-switch.d.ts +86 -71
- package/types/radix-ng-primitives-tabs.d.ts +213 -79
- package/types/radix-ng-primitives-time-field.d.ts +42 -27
- package/types/radix-ng-primitives-toast.d.ts +378 -0
- package/types/radix-ng-primitives-toggle-group.d.ts +86 -164
- package/types/radix-ng-primitives-toggle.d.ts +43 -53
- package/types/radix-ng-primitives-toolbar.d.ts +164 -38
- package/types/radix-ng-primitives-tooltip.d.ts +348 -384
- package/types/radix-ng-primitives-visually-hidden.d.ts +19 -19
- package/dropdown-menu/README.md +0 -1
- package/fesm2022/radix-ng-primitives-dropdown-menu.mjs +0 -581
- package/fesm2022/radix-ng-primitives-dropdown-menu.mjs.map +0 -1
- package/fesm2022/radix-ng-primitives-hover-card.mjs +0 -1238
- package/fesm2022/radix-ng-primitives-hover-card.mjs.map +0 -1
- package/fesm2022/radix-ng-primitives-select2.mjs +0 -897
- package/fesm2022/radix-ng-primitives-select2.mjs.map +0 -1
- package/fesm2022/radix-ng-primitives-tooltip2.mjs +0 -735
- package/fesm2022/radix-ng-primitives-tooltip2.mjs.map +0 -1
- package/hover-card/README.md +0 -3
- package/select2/README.md +0 -3
- package/tooltip2/README.md +0 -3
- package/types/radix-ng-primitives-dropdown-menu.d.ts +0 -171
- package/types/radix-ng-primitives-hover-card.d.ts +0 -471
- package/types/radix-ng-primitives-select2.d.ts +0 -511
- package/types/radix-ng-primitives-tooltip2.d.ts +0 -325
|
@@ -1,180 +1,462 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { inject, DestroyRef, signal, effect, afterNextRender, untracked, Directive, ElementRef, input, booleanAttribute, computed, model, output, NgModule } from '@angular/core';
|
|
3
|
+
import { createContext, useTransitionStatus, injectId } from '@radix-ng/primitives/core';
|
|
4
4
|
import * as i1 from '@radix-ng/primitives/roving-focus';
|
|
5
5
|
import { RdxRovingFocusGroupDirective, RdxRovingFocusItemDirective } from '@radix-ng/primitives/roving-focus';
|
|
6
|
+
import * as i1$1 from '@radix-ng/primitives/presence';
|
|
7
|
+
import { provideRdxPresenceContext, RdxPresenceDirective } from '@radix-ng/primitives/presence';
|
|
6
8
|
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
+
const [injectTabsRootContext, provideTabsRootContext] = createContext('RdxTabsRootContext');
|
|
10
|
+
|
|
11
|
+
function makeTabId(baseId, value) {
|
|
12
|
+
return `${baseId}-tab-${value}`;
|
|
13
|
+
}
|
|
14
|
+
function makePanelId(baseId, value) {
|
|
15
|
+
return `${baseId}-panel-${value}`;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* A visual element that tracks the position and size of the active tab. Exposes the active tab
|
|
20
|
+
* geometry as CSS variables (`--active-tab-{top,right,bottom,left,width,height}`) so it can be
|
|
21
|
+
* animated with CSS.
|
|
22
|
+
*
|
|
23
|
+
* @see https://base-ui.com/react/components/tabs
|
|
24
|
+
*/
|
|
25
|
+
class RdxTabsIndicator {
|
|
9
26
|
constructor() {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
this.
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
27
|
+
this.rootContext = injectTabsRootContext();
|
|
28
|
+
this.destroyRef = inject(DestroyRef);
|
|
29
|
+
/** @ignore */
|
|
30
|
+
this.geometry = signal(null, ...(ngDevMode ? [{ debugName: "geometry" }] : /* istanbul ignore next */ []));
|
|
31
|
+
// Re-measure whenever the selection, orientation or the list element changes.
|
|
32
|
+
effect(() => {
|
|
33
|
+
this.rootContext.value();
|
|
34
|
+
this.rootContext.orientation();
|
|
35
|
+
this.rootContext.tabListElement();
|
|
36
|
+
this.scheduleMeasure();
|
|
37
|
+
});
|
|
38
|
+
afterNextRender(() => {
|
|
39
|
+
const list = untracked(this.rootContext.tabListElement);
|
|
40
|
+
if (!list || typeof ResizeObserver === 'undefined') {
|
|
41
|
+
this.measure();
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
const observer = new ResizeObserver(() => this.measure());
|
|
45
|
+
observer.observe(list);
|
|
46
|
+
this.destroyRef.onDestroy(() => observer.disconnect());
|
|
47
|
+
this.measure();
|
|
48
|
+
});
|
|
28
49
|
}
|
|
29
|
-
|
|
30
|
-
if (
|
|
31
|
-
this.
|
|
50
|
+
scheduleMeasure() {
|
|
51
|
+
if (typeof requestAnimationFrame === 'undefined') {
|
|
52
|
+
this.measure();
|
|
53
|
+
return;
|
|
32
54
|
}
|
|
55
|
+
requestAnimationFrame(() => this.measure());
|
|
33
56
|
}
|
|
34
|
-
|
|
35
|
-
this.
|
|
36
|
-
this.
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
57
|
+
measure() {
|
|
58
|
+
const list = untracked(this.rootContext.tabListElement);
|
|
59
|
+
const value = untracked(this.rootContext.value);
|
|
60
|
+
if (!list || value == null || typeof document === 'undefined') {
|
|
61
|
+
this.geometry.set(null);
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
const tab = document.getElementById(makeTabId(this.rootContext.baseId, value));
|
|
65
|
+
if (!tab) {
|
|
66
|
+
this.geometry.set(null);
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
const listRect = list.getBoundingClientRect();
|
|
70
|
+
const tabRect = tab.getBoundingClientRect();
|
|
71
|
+
// Measure `left` / `top` relative to the list's scrollable content origin rather than its
|
|
72
|
+
// visible edge. When the list is a scroll container (e.g. its tabs overflow inside a Scroll
|
|
73
|
+
// Area), the indicator is an absolutely positioned child of that container and scrolls along
|
|
74
|
+
// with the content, so these offsets must be content-relative to stay aligned with the tab.
|
|
75
|
+
// For non-scrolling lists `scrollLeft` / `scrollTop` are `0`, leaving the geometry unchanged.
|
|
76
|
+
// `right` / `bottom` stay visible-edge relative — there is no unambiguous content-relative
|
|
77
|
+
// meaning for them inside a scroll container, and the moving indicator uses `left`/`top`.
|
|
78
|
+
const scrollLeft = list.scrollLeft;
|
|
79
|
+
const scrollTop = list.scrollTop;
|
|
80
|
+
this.geometry.set({
|
|
81
|
+
top: tabRect.top - listRect.top + scrollTop,
|
|
82
|
+
right: listRect.right - tabRect.right,
|
|
83
|
+
bottom: listRect.bottom - tabRect.bottom,
|
|
84
|
+
left: tabRect.left - listRect.left + scrollLeft,
|
|
85
|
+
width: tabRect.width,
|
|
86
|
+
height: tabRect.height
|
|
87
|
+
});
|
|
41
88
|
}
|
|
42
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type:
|
|
43
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "
|
|
89
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxTabsIndicator, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
90
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxTabsIndicator, isStandalone: true, selector: "[rdxTabsIndicator]", host: { properties: { "attr.data-orientation": "rootContext.orientation()", "attr.data-activation-direction": "rootContext.activationDirection()", "style.--active-tab-top.px": "geometry()?.top", "style.--active-tab-right.px": "geometry()?.right", "style.--active-tab-bottom.px": "geometry()?.bottom", "style.--active-tab-left.px": "geometry()?.left", "style.--active-tab-width.px": "geometry()?.width", "style.--active-tab-height.px": "geometry()?.height" } }, exportAs: ["rdxTabsIndicator"], ngImport: i0 }); }
|
|
44
91
|
}
|
|
45
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type:
|
|
92
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxTabsIndicator, decorators: [{
|
|
46
93
|
type: Directive,
|
|
47
94
|
args: [{
|
|
48
|
-
selector: '[
|
|
49
|
-
|
|
95
|
+
selector: '[rdxTabsIndicator]',
|
|
96
|
+
exportAs: 'rdxTabsIndicator',
|
|
50
97
|
host: {
|
|
51
|
-
'[attr.data-orientation]': 'orientation()',
|
|
52
|
-
'[attr.
|
|
98
|
+
'[attr.data-orientation]': 'rootContext.orientation()',
|
|
99
|
+
'[attr.data-activation-direction]': 'rootContext.activationDirection()',
|
|
100
|
+
'[style.--active-tab-top.px]': 'geometry()?.top',
|
|
101
|
+
'[style.--active-tab-right.px]': 'geometry()?.right',
|
|
102
|
+
'[style.--active-tab-bottom.px]': 'geometry()?.bottom',
|
|
103
|
+
'[style.--active-tab-left.px]': 'geometry()?.left',
|
|
104
|
+
'[style.--active-tab-width.px]': 'geometry()?.width',
|
|
105
|
+
'[style.--active-tab-height.px]': 'geometry()?.height'
|
|
53
106
|
}
|
|
54
107
|
}]
|
|
55
|
-
}],
|
|
108
|
+
}], ctorParameters: () => [] });
|
|
56
109
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
110
|
+
/**
|
|
111
|
+
* Groups the individual tab buttons and manages keyboard navigation.
|
|
112
|
+
*
|
|
113
|
+
* @see https://base-ui.com/react/components/tabs
|
|
114
|
+
*/
|
|
115
|
+
class RdxTabsList {
|
|
116
|
+
constructor() {
|
|
117
|
+
this.rootContext = injectTabsRootContext();
|
|
118
|
+
this.elementRef = inject(ElementRef);
|
|
119
|
+
this.rovingFocusGroup = inject(RdxRovingFocusGroupDirective, { self: true });
|
|
120
|
+
/**
|
|
121
|
+
* Whether a tab is activated when it receives focus (automatic activation).
|
|
122
|
+
* When `false`, tabs are only activated on click or Enter/Space.
|
|
123
|
+
*
|
|
124
|
+
* @default false
|
|
125
|
+
*/
|
|
126
|
+
this.activateOnFocus = input(false, { ...(ngDevMode ? { debugName: "activateOnFocus" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
127
|
+
/**
|
|
128
|
+
* Whether keyboard navigation should loop from the last tab back to the first.
|
|
129
|
+
*
|
|
130
|
+
* @default true
|
|
131
|
+
*/
|
|
132
|
+
this.loopFocus = input(true, { ...(ngDevMode ? { debugName: "loopFocus" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
133
|
+
this.rootContext.setTabListElement(this.elementRef.nativeElement);
|
|
134
|
+
effect(() => {
|
|
135
|
+
this.rovingFocusGroup.setOrientation(this.rootContext.orientation());
|
|
136
|
+
this.rovingFocusGroup.setLoop(this.loopFocus());
|
|
137
|
+
});
|
|
138
|
+
effect(() => this.rootContext.setActivateOnFocus(this.activateOnFocus()));
|
|
139
|
+
}
|
|
140
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxTabsList, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
141
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.9", type: RdxTabsList, isStandalone: true, selector: "[rdxTabsList]", inputs: { activateOnFocus: { classPropertyName: "activateOnFocus", publicName: "activateOnFocus", isSignal: true, isRequired: false, transformFunction: null }, loopFocus: { classPropertyName: "loopFocus", publicName: "loopFocus", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "tablist" }, properties: { "attr.aria-orientation": "rootContext.orientation()", "attr.data-orientation": "rootContext.orientation()", "attr.data-activation-direction": "rootContext.activationDirection()" } }, exportAs: ["rdxTabsList"], hostDirectives: [{ directive: i1.RdxRovingFocusGroupDirective }], ngImport: i0 }); }
|
|
62
142
|
}
|
|
143
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxTabsList, decorators: [{
|
|
144
|
+
type: Directive,
|
|
145
|
+
args: [{
|
|
146
|
+
selector: '[rdxTabsList]',
|
|
147
|
+
exportAs: 'rdxTabsList',
|
|
148
|
+
hostDirectives: [RdxRovingFocusGroupDirective],
|
|
149
|
+
host: {
|
|
150
|
+
role: 'tablist',
|
|
151
|
+
'[attr.aria-orientation]': 'rootContext.orientation()',
|
|
152
|
+
'[attr.data-orientation]': 'rootContext.orientation()',
|
|
153
|
+
'[attr.data-activation-direction]': 'rootContext.activationDirection()'
|
|
154
|
+
}
|
|
155
|
+
}]
|
|
156
|
+
}], ctorParameters: () => [], propDecorators: { activateOnFocus: [{ type: i0.Input, args: [{ isSignal: true, alias: "activateOnFocus", required: false }] }], loopFocus: [{ type: i0.Input, args: [{ isSignal: true, alias: "loopFocus", required: false }] }] } });
|
|
63
157
|
|
|
64
|
-
|
|
158
|
+
const panelPresenceContext = () => ({ present: inject(RdxTabsPanel).present });
|
|
159
|
+
/**
|
|
160
|
+
* A panel displayed when its corresponding tab is active.
|
|
161
|
+
*
|
|
162
|
+
* By default the panel stays in the DOM and is toggled with the `hidden` attribute. To unmount the
|
|
163
|
+
* contents while inactive (Base UI's default `keepMounted: false`), nest a `*rdxTabsPanelPresence`
|
|
164
|
+
* structural directive inside it; set `keepMounted` to keep the contents mounted regardless.
|
|
165
|
+
*
|
|
166
|
+
* @see https://base-ui.com/react/components/tabs
|
|
167
|
+
*/
|
|
168
|
+
class RdxTabsPanel {
|
|
65
169
|
constructor() {
|
|
66
|
-
this.
|
|
170
|
+
this.elementRef = inject(ElementRef);
|
|
171
|
+
this.rootContext = injectTabsRootContext();
|
|
67
172
|
/**
|
|
68
|
-
* A unique value that associates the
|
|
173
|
+
* A unique value that associates the panel with a tab.
|
|
69
174
|
*/
|
|
70
175
|
this.value = input.required(...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
176
|
+
/**
|
|
177
|
+
* Keep the panel contents mounted in the DOM while inactive (the contents are still hidden).
|
|
178
|
+
* Only relevant together with `*rdxTabsPanelPresence`, which otherwise unmounts them.
|
|
179
|
+
*
|
|
180
|
+
* @default false
|
|
181
|
+
*/
|
|
182
|
+
this.keepMounted = input(false, { ...(ngDevMode ? { debugName: "keepMounted" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
183
|
+
this.transition = useTransitionStatus(() => { });
|
|
184
|
+
/** Reactive enter/exit transition phase (`'starting'` | `'ending'` | `undefined`). */
|
|
185
|
+
this.transitionStatus = this.transition.status;
|
|
186
|
+
/** @ignore */
|
|
187
|
+
this.panelId = computed(() => makePanelId(this.rootContext.baseId, this.value()), ...(ngDevMode ? [{ debugName: "panelId" }] : /* istanbul ignore next */ []));
|
|
188
|
+
/** @ignore */
|
|
189
|
+
this.tabId = computed(() => makeTabId(this.rootContext.baseId, this.value()), ...(ngDevMode ? [{ debugName: "tabId" }] : /* istanbul ignore next */ []));
|
|
190
|
+
/** Whether this panel's tab is currently selected. */
|
|
191
|
+
this.active = computed(() => this.rootContext.value() === this.value(), ...(ngDevMode ? [{ debugName: "active" }] : /* istanbul ignore next */ []));
|
|
192
|
+
/** `true` once a `*rdxTabsPanelPresence` child takes over mounting. */
|
|
193
|
+
this.hasPresence = signal(false, ...(ngDevMode ? [{ debugName: "hasPresence" }] : /* istanbul ignore next */ []));
|
|
194
|
+
/**
|
|
195
|
+
* Whether the contents should be present for `*rdxTabsPanelPresence`. Flips with `active` so the
|
|
196
|
+
* presence directive owns the exit-animation timing (it keeps the node mounted until its exit
|
|
197
|
+
* `@keyframes` finishes); `keepMounted` keeps them mounted regardless.
|
|
198
|
+
*/
|
|
199
|
+
this.present = computed(() => this.keepMounted() || this.active(), ...(ngDevMode ? [{ debugName: "present" }] : /* istanbul ignore next */ []));
|
|
200
|
+
/**
|
|
201
|
+
* The `hidden` attribute value. The panel is shown while active or while its exit transition
|
|
202
|
+
* runs. When a presence child unmounts the contents we no longer force `hidden` (the empty
|
|
203
|
+
* element renders nothing), unless `keepMounted` keeps the inactive contents around.
|
|
204
|
+
*/
|
|
205
|
+
this.hidden = computed(() => !this.active() && this.transitionStatus() !== 'ending' && (!this.hasPresence() || this.keepMounted()), ...(ngDevMode ? [{ debugName: "hidden" }] : /* istanbul ignore next */ []));
|
|
206
|
+
/** @ignore Index of the panel, derived from the order of its associated tab. */
|
|
207
|
+
this.index = computed(() => {
|
|
208
|
+
const list = this.rootContext.tabListElement();
|
|
209
|
+
if (!list) {
|
|
210
|
+
return null;
|
|
211
|
+
}
|
|
212
|
+
const tabs = Array.from(list.querySelectorAll('[role="tab"]'));
|
|
213
|
+
const position = tabs.findIndex((tab) => tab.id === makeTabId(this.rootContext.baseId, this.value()));
|
|
214
|
+
return position === -1 ? null : position;
|
|
215
|
+
}, ...(ngDevMode ? [{ debugName: "index" }] : /* istanbul ignore next */ []));
|
|
216
|
+
this.previousActive = false;
|
|
217
|
+
this.isFirstRun = true;
|
|
218
|
+
const unregister = this.transition.registerElement(this.elementRef.nativeElement);
|
|
219
|
+
inject(DestroyRef).onDestroy(unregister);
|
|
220
|
+
effect(() => {
|
|
221
|
+
const active = this.active();
|
|
222
|
+
// Settle the initial state without playing an enter transition.
|
|
223
|
+
if (this.isFirstRun) {
|
|
224
|
+
this.isFirstRun = false;
|
|
225
|
+
this.previousActive = active;
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
if (active !== this.previousActive) {
|
|
229
|
+
this.previousActive = active;
|
|
230
|
+
untracked(() => this.transition.start(active));
|
|
231
|
+
}
|
|
232
|
+
});
|
|
74
233
|
}
|
|
75
|
-
|
|
76
|
-
|
|
234
|
+
/** @ignore Called by `RdxTabsPanelPresence` so the panel stops forcing `hidden`. */
|
|
235
|
+
markHasPresence() {
|
|
236
|
+
this.hasPresence.set(true);
|
|
237
|
+
}
|
|
238
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxTabsPanel, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
239
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.9", type: RdxTabsPanel, isStandalone: true, selector: "[rdxTabsPanel]", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null }, keepMounted: { classPropertyName: "keepMounted", publicName: "keepMounted", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "tabpanel" }, properties: { "id": "panelId()", "attr.tabindex": "active() ? 0 : undefined", "attr.aria-labelledby": "tabId()", "attr.data-orientation": "rootContext.orientation()", "attr.data-activation-direction": "rootContext.activationDirection()", "attr.data-index": "index()", "attr.data-hidden": "active() ? undefined : \"\"", "attr.data-starting-style": "transitionStatus() === \"starting\" ? \"\" : undefined", "attr.data-ending-style": "transitionStatus() === \"ending\" ? \"\" : undefined", "hidden": "hidden()" } }, providers: [provideRdxPresenceContext(panelPresenceContext)], exportAs: ["rdxTabsPanel"], ngImport: i0 }); }
|
|
77
240
|
}
|
|
78
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type:
|
|
241
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxTabsPanel, decorators: [{
|
|
79
242
|
type: Directive,
|
|
80
243
|
args: [{
|
|
81
|
-
selector: '[
|
|
244
|
+
selector: '[rdxTabsPanel]',
|
|
245
|
+
exportAs: 'rdxTabsPanel',
|
|
246
|
+
providers: [provideRdxPresenceContext(panelPresenceContext)],
|
|
82
247
|
host: {
|
|
83
248
|
role: 'tabpanel',
|
|
84
|
-
|
|
85
|
-
'[
|
|
86
|
-
'[attr.aria-labelledby]': '
|
|
87
|
-
'[attr.data-
|
|
88
|
-
'[attr.data-
|
|
89
|
-
'[
|
|
249
|
+
'[id]': 'panelId()',
|
|
250
|
+
'[attr.tabindex]': 'active() ? 0 : undefined',
|
|
251
|
+
'[attr.aria-labelledby]': 'tabId()',
|
|
252
|
+
'[attr.data-orientation]': 'rootContext.orientation()',
|
|
253
|
+
'[attr.data-activation-direction]': 'rootContext.activationDirection()',
|
|
254
|
+
'[attr.data-index]': 'index()',
|
|
255
|
+
'[attr.data-hidden]': 'active() ? undefined : ""',
|
|
256
|
+
'[attr.data-starting-style]': 'transitionStatus() === "starting" ? "" : undefined',
|
|
257
|
+
'[attr.data-ending-style]': 'transitionStatus() === "ending" ? "" : undefined',
|
|
258
|
+
'[hidden]': 'hidden()'
|
|
90
259
|
}
|
|
91
260
|
}]
|
|
92
|
-
}], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: true }] }] } });
|
|
261
|
+
}], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: true }] }], keepMounted: [{ type: i0.Input, args: [{ isSignal: true, alias: "keepMounted", required: false }] }] } });
|
|
93
262
|
|
|
94
|
-
|
|
263
|
+
/**
|
|
264
|
+
* Structural directive that mounts the tab panel contents only while the panel is active,
|
|
265
|
+
* unmounting them once the exit animation finishes. Apply it inside an `[rdxTabsPanel]` to get
|
|
266
|
+
* Base UI's default unmounting behavior; combine with `keepMounted` on the panel to keep the
|
|
267
|
+
* contents mounted instead.
|
|
268
|
+
*
|
|
269
|
+
* The presence state is read from the parent panel through {@link RdxPresenceDirective}.
|
|
270
|
+
*/
|
|
271
|
+
class RdxTabsPanelPresence {
|
|
95
272
|
constructor() {
|
|
96
|
-
|
|
273
|
+
inject(RdxTabsPanel).markHasPresence();
|
|
97
274
|
}
|
|
98
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type:
|
|
99
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type:
|
|
275
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxTabsPanelPresence, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
276
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxTabsPanelPresence, isStandalone: true, selector: "ng-template[rdxTabsPanelPresence]", hostDirectives: [{ directive: i1$1.RdxPresenceDirective }], ngImport: i0 }); }
|
|
100
277
|
}
|
|
101
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type:
|
|
278
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxTabsPanelPresence, decorators: [{
|
|
102
279
|
type: Directive,
|
|
103
280
|
args: [{
|
|
104
|
-
selector: '[
|
|
105
|
-
hostDirectives: [
|
|
281
|
+
selector: 'ng-template[rdxTabsPanelPresence]',
|
|
282
|
+
hostDirectives: [RdxPresenceDirective]
|
|
283
|
+
}]
|
|
284
|
+
}], ctorParameters: () => [] });
|
|
285
|
+
|
|
286
|
+
const rootContext = () => {
|
|
287
|
+
const root = inject(RdxTabsRoot);
|
|
288
|
+
return {
|
|
289
|
+
baseId: root.baseId,
|
|
290
|
+
value: root.value,
|
|
291
|
+
orientation: root.orientation,
|
|
292
|
+
activationDirection: root.activationDirection.asReadonly(),
|
|
293
|
+
activateOnFocus: root.activateOnFocus.asReadonly(),
|
|
294
|
+
tabListElement: root.tabListElement.asReadonly(),
|
|
295
|
+
setValue: (value) => root.setValue(value),
|
|
296
|
+
setActivateOnFocus: (value) => root.activateOnFocus.set(value),
|
|
297
|
+
setTabListElement: (element) => root.tabListElement.set(element)
|
|
298
|
+
};
|
|
299
|
+
};
|
|
300
|
+
/**
|
|
301
|
+
* Groups the tabs and the corresponding panels.
|
|
302
|
+
*
|
|
303
|
+
* @see https://base-ui.com/react/components/tabs
|
|
304
|
+
*/
|
|
305
|
+
class RdxTabsRoot {
|
|
306
|
+
constructor() {
|
|
307
|
+
/** @ignore */
|
|
308
|
+
this.baseId = injectId('rdx-tabs-');
|
|
309
|
+
/**
|
|
310
|
+
* The value of the currently selected tab. Use together with `(onValueChange)` for controlled state.
|
|
311
|
+
*/
|
|
312
|
+
this.value = model(...(ngDevMode ? [undefined, { debugName: "value" }] : /* istanbul ignore next */ []));
|
|
313
|
+
/**
|
|
314
|
+
* The value of the tab that should be initially selected when uncontrolled.
|
|
315
|
+
*/
|
|
316
|
+
this.defaultValue = input(...(ngDevMode ? [undefined, { debugName: "defaultValue" }] : /* istanbul ignore next */ []));
|
|
317
|
+
/**
|
|
318
|
+
* The orientation the tabs are laid out. Controls arrow-key navigation
|
|
319
|
+
* (left/right vs. up/down).
|
|
320
|
+
*
|
|
321
|
+
* @default 'horizontal'
|
|
322
|
+
*/
|
|
323
|
+
this.orientation = input('horizontal', ...(ngDevMode ? [{ debugName: "orientation" }] : /* istanbul ignore next */ []));
|
|
324
|
+
/**
|
|
325
|
+
* Event emitted when the selected tab changes.
|
|
326
|
+
*/
|
|
327
|
+
this.onValueChange = output();
|
|
328
|
+
/** @ignore Set by `[rdxTabsList]`. */
|
|
329
|
+
this.activateOnFocus = signal(false, ...(ngDevMode ? [{ debugName: "activateOnFocus" }] : /* istanbul ignore next */ []));
|
|
330
|
+
/** @ignore Set by `[rdxTabsList]`. */
|
|
331
|
+
this.tabListElement = signal(null, ...(ngDevMode ? [{ debugName: "tabListElement" }] : /* istanbul ignore next */ []));
|
|
332
|
+
/** @ignore */
|
|
333
|
+
this.activationDirection = signal('none', ...(ngDevMode ? [{ debugName: "activationDirection" }] : /* istanbul ignore next */ []));
|
|
334
|
+
effect(() => {
|
|
335
|
+
const initial = this.defaultValue();
|
|
336
|
+
if (initial !== undefined && untracked(this.value) === undefined) {
|
|
337
|
+
this.value.set(initial);
|
|
338
|
+
}
|
|
339
|
+
});
|
|
340
|
+
}
|
|
341
|
+
/** @ignore */
|
|
342
|
+
setValue(value) {
|
|
343
|
+
const previous = this.value();
|
|
344
|
+
if (previous === value) {
|
|
345
|
+
return;
|
|
346
|
+
}
|
|
347
|
+
this.activationDirection.set(this.computeDirection(previous, value));
|
|
348
|
+
this.value.set(value);
|
|
349
|
+
this.onValueChange.emit(value);
|
|
350
|
+
}
|
|
351
|
+
computeDirection(previous, next) {
|
|
352
|
+
const list = this.tabListElement();
|
|
353
|
+
if (!list || previous === undefined || previous === null) {
|
|
354
|
+
return 'none';
|
|
355
|
+
}
|
|
356
|
+
const tabs = Array.from(list.querySelectorAll('[role="tab"]'));
|
|
357
|
+
const previousIndex = tabs.findIndex((tab) => tab.id === makeTabId(this.baseId, previous));
|
|
358
|
+
const nextIndex = tabs.findIndex((tab) => tab.id === makeTabId(this.baseId, next));
|
|
359
|
+
if (previousIndex === -1 || nextIndex === -1 || previousIndex === nextIndex) {
|
|
360
|
+
return 'none';
|
|
361
|
+
}
|
|
362
|
+
const horizontal = this.orientation() === 'horizontal';
|
|
363
|
+
if (nextIndex > previousIndex) {
|
|
364
|
+
return horizontal ? 'right' : 'down';
|
|
365
|
+
}
|
|
366
|
+
return horizontal ? 'left' : 'up';
|
|
367
|
+
}
|
|
368
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxTabsRoot, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
369
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.9", type: RdxTabsRoot, isStandalone: true, selector: "[rdxTabsRoot]", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, defaultValue: { classPropertyName: "defaultValue", publicName: "defaultValue", isSignal: true, isRequired: false, transformFunction: null }, orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", onValueChange: "onValueChange" }, host: { properties: { "attr.data-orientation": "orientation()", "attr.data-activation-direction": "activationDirection()" } }, providers: [provideTabsRootContext(rootContext)], exportAs: ["rdxTabsRoot"], ngImport: i0 }); }
|
|
370
|
+
}
|
|
371
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxTabsRoot, decorators: [{
|
|
372
|
+
type: Directive,
|
|
373
|
+
args: [{
|
|
374
|
+
selector: '[rdxTabsRoot]',
|
|
375
|
+
exportAs: 'rdxTabsRoot',
|
|
376
|
+
providers: [provideTabsRootContext(rootContext)],
|
|
106
377
|
host: {
|
|
107
|
-
|
|
108
|
-
'[attr.
|
|
109
|
-
'[attr.data-orientation]': 'tabsContext.orientation()'
|
|
378
|
+
'[attr.data-orientation]': 'orientation()',
|
|
379
|
+
'[attr.data-activation-direction]': 'activationDirection()'
|
|
110
380
|
}
|
|
111
381
|
}]
|
|
112
|
-
}] });
|
|
382
|
+
}], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], defaultValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultValue", required: false }] }], orientation: [{ type: i0.Input, args: [{ isSignal: true, alias: "orientation", required: false }] }], onValueChange: [{ type: i0.Output, args: ["onValueChange"] }] } });
|
|
113
383
|
|
|
114
|
-
|
|
384
|
+
/**
|
|
385
|
+
* An individual interactive tab button that activates its corresponding panel.
|
|
386
|
+
*
|
|
387
|
+
* @see https://base-ui.com/react/components/tabs
|
|
388
|
+
*/
|
|
389
|
+
class RdxTabsTab {
|
|
115
390
|
constructor() {
|
|
116
|
-
this.
|
|
117
|
-
this.
|
|
391
|
+
this.rootContext = injectTabsRootContext();
|
|
392
|
+
this.rovingFocusItem = inject(RdxRovingFocusItemDirective);
|
|
118
393
|
/**
|
|
119
|
-
* A unique value that associates the
|
|
394
|
+
* A unique value that associates the tab with a panel.
|
|
120
395
|
*/
|
|
121
396
|
this.value = input.required(...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
|
|
122
397
|
/**
|
|
123
|
-
* When true
|
|
398
|
+
* When `true`, prevents the user from interacting with the tab.
|
|
124
399
|
*/
|
|
125
400
|
this.disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
126
|
-
|
|
127
|
-
this.
|
|
128
|
-
|
|
129
|
-
|
|
401
|
+
/** @ignore */
|
|
402
|
+
this.tabId = computed(() => makeTabId(this.rootContext.baseId, this.value()), ...(ngDevMode ? [{ debugName: "tabId" }] : /* istanbul ignore next */ []));
|
|
403
|
+
/** @ignore */
|
|
404
|
+
this.panelId = computed(() => makePanelId(this.rootContext.baseId, this.value()), ...(ngDevMode ? [{ debugName: "panelId" }] : /* istanbul ignore next */ []));
|
|
405
|
+
/** @ignore */
|
|
406
|
+
this.active = computed(() => this.rootContext.value() === this.value(), ...(ngDevMode ? [{ debugName: "active" }] : /* istanbul ignore next */ []));
|
|
407
|
+
effect(() => {
|
|
408
|
+
this.rovingFocusItem.setActive(this.active());
|
|
409
|
+
this.rovingFocusItem.setFocusable(!this.disabled());
|
|
410
|
+
});
|
|
130
411
|
}
|
|
412
|
+
/** @ignore */
|
|
131
413
|
onMouseDown(event) {
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
if (!this.disabled() && mouseEvent.button === 0 && !mouseEvent.ctrlKey) {
|
|
136
|
-
this.tabsContext?.select(this.value());
|
|
414
|
+
// Only the primary button selects; ignore Ctrl-click (macOS right-click emulation).
|
|
415
|
+
if (!this.disabled() && event.button === 0 && !event.ctrlKey) {
|
|
416
|
+
this.rootContext.setValue(this.value());
|
|
137
417
|
}
|
|
138
418
|
else {
|
|
139
|
-
//
|
|
419
|
+
// Prevent focus to avoid accidental activation.
|
|
140
420
|
event.preventDefault();
|
|
141
421
|
}
|
|
142
422
|
}
|
|
423
|
+
/** @ignore */
|
|
143
424
|
onKeyDown(event) {
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
this.tabsContext?.select(this.value());
|
|
425
|
+
if (!this.disabled() && (event.key === ' ' || event.key === 'Enter')) {
|
|
426
|
+
this.rootContext.setValue(this.value());
|
|
147
427
|
}
|
|
148
428
|
}
|
|
429
|
+
/** @ignore */
|
|
149
430
|
onFocus() {
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
this.tabsContext?.select(this.value());
|
|
431
|
+
if (!this.active() && !this.disabled() && this.rootContext.activateOnFocus()) {
|
|
432
|
+
this.rootContext.setValue(this.value());
|
|
153
433
|
}
|
|
154
434
|
}
|
|
155
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type:
|
|
156
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.9", type:
|
|
435
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxTabsTab, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
436
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.9", type: RdxTabsTab, isStandalone: true, selector: "[rdxTabsTab]", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "type": "button", "role": "tab" }, listeners: { "mousedown": "onMouseDown($event)", "keydown": "onKeyDown($event)", "focus": "onFocus()" }, properties: { "id": "tabId()", "attr.aria-selected": "active()", "attr.aria-controls": "panelId()", "attr.data-orientation": "rootContext.orientation()", "attr.data-activation-direction": "rootContext.activationDirection()", "attr.data-active": "active() ? \"\" : undefined", "attr.data-disabled": "disabled() ? \"\" : undefined", "attr.disabled": "disabled() ? \"\" : undefined" } }, exportAs: ["rdxTabsTab"], hostDirectives: [{ directive: i1.RdxRovingFocusItemDirective, inputs: ["allowShiftKey", "allowShiftKey"] }], ngImport: i0 }); }
|
|
157
437
|
}
|
|
158
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type:
|
|
438
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxTabsTab, decorators: [{
|
|
159
439
|
type: Directive,
|
|
160
440
|
args: [{
|
|
161
|
-
selector: '[
|
|
441
|
+
selector: '[rdxTabsTab]',
|
|
442
|
+
exportAs: 'rdxTabsTab',
|
|
162
443
|
hostDirectives: [
|
|
163
444
|
{
|
|
164
445
|
directive: RdxRovingFocusItemDirective,
|
|
165
|
-
inputs: ['
|
|
446
|
+
inputs: ['allowShiftKey']
|
|
166
447
|
}
|
|
167
448
|
],
|
|
168
449
|
host: {
|
|
169
450
|
type: 'button',
|
|
170
451
|
role: 'tab',
|
|
171
|
-
'[id]': '
|
|
172
|
-
'[attr.aria-selected]': '
|
|
173
|
-
'[attr.aria-controls]': '
|
|
174
|
-
'[attr.data-
|
|
452
|
+
'[id]': 'tabId()',
|
|
453
|
+
'[attr.aria-selected]': 'active()',
|
|
454
|
+
'[attr.aria-controls]': 'panelId()',
|
|
455
|
+
'[attr.data-orientation]': 'rootContext.orientation()',
|
|
456
|
+
'[attr.data-activation-direction]': 'rootContext.activationDirection()',
|
|
457
|
+
'[attr.data-active]': 'active() ? "" : undefined',
|
|
458
|
+
'[attr.data-disabled]': 'disabled() ? "" : undefined',
|
|
175
459
|
'[attr.disabled]': 'disabled() ? "" : undefined',
|
|
176
|
-
'[attr.data-state]': "isSelected() ? 'active' : 'inactive'",
|
|
177
|
-
'[attr.data-orientation]': 'tabsContext.orientation()',
|
|
178
460
|
'(mousedown)': 'onMouseDown($event)',
|
|
179
461
|
'(keydown)': 'onKeyDown($event)',
|
|
180
462
|
'(focus)': 'onFocus()'
|
|
@@ -182,10 +464,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
182
464
|
}]
|
|
183
465
|
}], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: true }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }] } });
|
|
184
466
|
|
|
185
|
-
const tabsImports = [
|
|
467
|
+
const tabsImports = [RdxTabsRoot, RdxTabsList, RdxTabsTab, RdxTabsPanel, RdxTabsPanelPresence, RdxTabsIndicator];
|
|
186
468
|
class RdxTabsModule {
|
|
187
469
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxTabsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
188
|
-
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.9", ngImport: i0, type: RdxTabsModule, imports: [
|
|
470
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.9", ngImport: i0, type: RdxTabsModule, imports: [RdxTabsRoot, RdxTabsList, RdxTabsTab, RdxTabsPanel, RdxTabsPanelPresence, RdxTabsIndicator], exports: [RdxTabsRoot, RdxTabsList, RdxTabsTab, RdxTabsPanel, RdxTabsPanelPresence, RdxTabsIndicator] }); }
|
|
189
471
|
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxTabsModule }); }
|
|
190
472
|
}
|
|
191
473
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxTabsModule, decorators: [{
|
|
@@ -200,5 +482,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
200
482
|
* Generated bundle index. Do not edit.
|
|
201
483
|
*/
|
|
202
484
|
|
|
203
|
-
export {
|
|
485
|
+
export { RdxTabsIndicator, RdxTabsList, RdxTabsModule, RdxTabsPanel, RdxTabsPanelPresence, RdxTabsRoot, RdxTabsTab, injectTabsRootContext, provideTabsRootContext, tabsImports };
|
|
204
486
|
//# sourceMappingURL=radix-ng-primitives-tabs.mjs.map
|