@rt-tools/ui-kit-v2 0.42.0 → 0.43.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/rt-tools-ui-kit-v2-core.mjs +22 -0
- package/fesm2022/rt-tools-ui-kit-v2-core.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-page-header.mjs +1778 -18
- package/fesm2022/rt-tools-ui-kit-v2-page-header.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-rich-editor.mjs +19 -5
- package/fesm2022/rt-tools-ui-kit-v2-rich-editor.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-stepper.mjs +34 -11
- package/fesm2022/rt-tools-ui-kit-v2-stepper.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-tabs.mjs +725 -47
- package/fesm2022/rt-tools-ui-kit-v2-tabs.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-workspace-details.mjs +6 -0
- package/fesm2022/rt-tools-ui-kit-v2-workspace-details.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-workspace.mjs +217 -6
- package/fesm2022/rt-tools-ui-kit-v2-workspace.mjs.map +1 -1
- package/package.json +1 -1
- package/src/lib/components/page-header/CONTEXT.md +35 -1
- package/src/lib/components/page-header/bar/rt-page-bar.component.scss +161 -0
- package/src/lib/components/page-header/rail/rt-page-actions.component.scss +115 -0
- package/src/lib/components/page-header/rail/rt-page-phone-menu.component.scss +129 -0
- package/src/lib/components/page-header/rail/rt-page-rail.component.scss +281 -0
- package/src/lib/components/page-header/rail/rt-page-user.component.scss +76 -0
- package/src/lib/components/page-header/rt-page-header.component.scss +5 -0
- package/src/lib/components/page-header/stories/component/test-page-header-vertical.component.scss +72 -0
- package/src/lib/components/page-header/stories/component/test-page-table.component.scss +81 -0
- package/src/lib/components/page-header/user/rt-page-header-user.component.scss +6 -0
- package/src/lib/components/stepper/CONTEXT.md +34 -2
- package/src/lib/components/stepper/rt-stepper.component.scss +62 -43
- package/src/lib/components/tabs/CONTEXT.md +30 -1
- package/src/lib/components/tabs/rt-tabs-arrows.scss +140 -0
- package/src/lib/components/tabs/rt-tabs-more-menu.scss +126 -0
- package/src/lib/components/tabs/rt-tabs-more.component.scss +29 -0
- package/src/lib/components/tabs/rt-tabs.component.scss +18 -61
- package/src/lib/components/workspace/CONTEXT.md +11 -1
- package/src/lib/components/workspace/rt-workspace.component.scss +51 -3
- package/src/rich-editor/lib/components/chat/CONTEXT.md +11 -1
- package/src/rich-editor/lib/components/chat/rt-chat-messenger.scss +9 -3
- package/src/rich-editor/lib/components/chat/rt-chat-translation.scss +92 -0
- package/types/rt-tools-ui-kit-v2-core.d.ts +9 -1
- package/types/rt-tools-ui-kit-v2-page-header.d.ts +202 -2
- package/types/rt-tools-ui-kit-v2-rich-editor.d.ts +23 -0
- package/types/rt-tools-ui-kit-v2-stepper.d.ts +20 -6
- package/types/rt-tools-ui-kit-v2-tabs.d.ts +120 -1
- package/types/rt-tools-ui-kit-v2-workspace.d.ts +33 -1
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
import { DOCUMENT, NgTemplateOutlet } from "@angular/common";
|
|
2
2
|
import * as i0 from "@angular/core";
|
|
3
|
-
import { ChangeDetectionStrategy, Component, DestroyRef, Directive, ElementRef, Injector, TemplateRef, ViewEncapsulation, afterNextRender, afterRenderEffect, booleanAttribute, computed, contentChildren, inject, input, linkedSignal, output, signal, untracked, viewChild } from "@angular/core";
|
|
3
|
+
import { ChangeDetectionStrategy, Component, DestroyRef, Directive, ElementRef, Injector, TemplateRef, ViewEncapsulation, afterNextRender, afterRenderEffect, booleanAttribute, computed, contentChildren, effect, inject, input, linkedSignal, numberAttribute, output, signal, untracked, viewChild } from "@angular/core";
|
|
4
4
|
import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
|
|
5
5
|
import { debounceTime, fromEvent } from "rxjs";
|
|
6
6
|
import { BlockDirective, ElemDirective, ModDirective } from "@rt-tools/core";
|
|
7
7
|
import { RtIconComponent } from "@rt-tools/ui-kit-v2/icon";
|
|
8
8
|
import { RtTooltipDirective } from "@rt-tools/ui-kit-v2/tooltip";
|
|
9
|
-
import { rtKitLabel } from "@rt-tools/ui-kit-v2/core";
|
|
9
|
+
import { RT_KIT_LABELS, rtKitLabel } from "@rt-tools/ui-kit-v2/core";
|
|
10
|
+
import { CdkConnectedOverlay } from "@angular/cdk/overlay";
|
|
11
|
+
import { FocusKeyManager } from "@angular/cdk/a11y";
|
|
12
|
+
import { RtPopoverDirective } from "@rt-tools/ui-kit-v2/popover";
|
|
10
13
|
var RtTabDirective = class RtTabDirective {
|
|
11
14
|
constructor() {
|
|
12
15
|
this.#t_uiTabInvalid = rtKitLabel("uiTabInvalid");
|
|
@@ -47,6 +50,11 @@ var RtTabDirective = class RtTabDirective {
|
|
|
47
50
|
...ngDevMode ? { debugName: "closable" } : /* istanbul ignore next */ {},
|
|
48
51
|
transform: booleanAttribute
|
|
49
52
|
});
|
|
53
|
+
this.pinned = input(false, {
|
|
54
|
+
...ngDevMode ? { debugName: "pinned" } : /* istanbul ignore next */ {},
|
|
55
|
+
transform: booleanAttribute
|
|
56
|
+
});
|
|
57
|
+
this.contextMenu = input(null, ...ngDevMode ? [{ debugName: "contextMenu" }] : /* istanbul ignore next */ []);
|
|
50
58
|
this.closeTooltip = input("", ...ngDevMode ? [{ debugName: "closeTooltip" }] : /* istanbul ignore next */ []);
|
|
51
59
|
this.closeTooltipPlacement = input(null, ...ngDevMode ? [{ debugName: "closeTooltipPlacement" }] : /* istanbul ignore next */ []);
|
|
52
60
|
this.closeHovered = signal(false, ...ngDevMode ? [{ debugName: "closeHovered" }] : /* istanbul ignore next */ []);
|
|
@@ -57,7 +65,8 @@ var RtTabDirective = class RtTabDirective {
|
|
|
57
65
|
}, ...ngDevMode ? [{ debugName: "buttonTooltip" }] : /* istanbul ignore next */ []);
|
|
58
66
|
this.ariaLabel = computed(() => this.label() || this.titleTemplate() ? null : this.tooltip() || null, ...ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []);
|
|
59
67
|
this.closeLabel = computed(() => this.closeTooltip() || this.#t_uiClose(), ...ngDevMode ? [{ debugName: "closeLabel" }] : /* istanbul ignore next */ []);
|
|
60
|
-
this.
|
|
68
|
+
this.shownIcon = computed(() => this.icon() ?? (this.pinned() && !this.glyph() ? "pin" : null), ...ngDevMode ? [{ debugName: "shownIcon" }] : /* istanbul ignore next */ []);
|
|
69
|
+
this.hasIcon = computed(() => Boolean(this.shownIcon() || this.glyph()), ...ngDevMode ? [{ debugName: "hasIcon" }] : /* istanbul ignore next */ []);
|
|
61
70
|
this.badgeOverlay = computed(() => this.badgePosition() === "overlay" && this.badge() !== null && this.hasIcon(), ...ngDevMode ? [{ debugName: "badgeOverlay" }] : /* istanbul ignore next */ []);
|
|
62
71
|
this.showClose = computed(() => this.closable() && !this.disabled(), ...ngDevMode ? [{ debugName: "showClose" }] : /* istanbul ignore next */ []);
|
|
63
72
|
}
|
|
@@ -200,6 +209,20 @@ var RtTabDirective = class RtTabDirective {
|
|
|
200
209
|
isRequired: false,
|
|
201
210
|
transformFunction: null
|
|
202
211
|
},
|
|
212
|
+
pinned: {
|
|
213
|
+
classPropertyName: "pinned",
|
|
214
|
+
publicName: "pinned",
|
|
215
|
+
isSignal: true,
|
|
216
|
+
isRequired: false,
|
|
217
|
+
transformFunction: null
|
|
218
|
+
},
|
|
219
|
+
contextMenu: {
|
|
220
|
+
classPropertyName: "contextMenu",
|
|
221
|
+
publicName: "contextMenu",
|
|
222
|
+
isSignal: true,
|
|
223
|
+
isRequired: false,
|
|
224
|
+
transformFunction: null
|
|
225
|
+
},
|
|
203
226
|
closeTooltip: {
|
|
204
227
|
classPropertyName: "closeTooltip",
|
|
205
228
|
publicName: "closeTooltip",
|
|
@@ -365,6 +388,22 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
365
388
|
required: false
|
|
366
389
|
}]
|
|
367
390
|
}],
|
|
391
|
+
pinned: [{
|
|
392
|
+
type: i0.Input,
|
|
393
|
+
args: [{
|
|
394
|
+
isSignal: true,
|
|
395
|
+
alias: "pinned",
|
|
396
|
+
required: false
|
|
397
|
+
}]
|
|
398
|
+
}],
|
|
399
|
+
contextMenu: [{
|
|
400
|
+
type: i0.Input,
|
|
401
|
+
args: [{
|
|
402
|
+
isSignal: true,
|
|
403
|
+
alias: "contextMenu",
|
|
404
|
+
required: false
|
|
405
|
+
}]
|
|
406
|
+
}],
|
|
368
407
|
closeTooltip: [{
|
|
369
408
|
type: i0.Input,
|
|
370
409
|
args: [{
|
|
@@ -597,6 +636,12 @@ function rtTabsEasing(value) {
|
|
|
597
636
|
return bezierAt((low + high) / 2, y1, y2);
|
|
598
637
|
};
|
|
599
638
|
}
|
|
639
|
+
function rtTabsRestShown(list) {
|
|
640
|
+
return {
|
|
641
|
+
before: list.scrollLeft > 0,
|
|
642
|
+
after: list.scrollWidth - list.scrollLeft - list.clientWidth > 1
|
|
643
|
+
};
|
|
644
|
+
}
|
|
600
645
|
function rtTabsPageTarget(list, from, back, step) {
|
|
601
646
|
const max = Math.max(0, list.scrollWidth - list.clientWidth);
|
|
602
647
|
const shift = step === "fixed" ? FIXED_STEP : list.clientWidth * STEP_SHARE[step];
|
|
@@ -625,6 +670,16 @@ var RtTabsScroller = class {
|
|
|
625
670
|
from() {
|
|
626
671
|
return this.#target ?? this.#list()?.nativeElement.scrollLeft ?? 0;
|
|
627
672
|
}
|
|
673
|
+
place(target, instant) {
|
|
674
|
+
const list = this.#list()?.nativeElement;
|
|
675
|
+
if (target === null || !list) return;
|
|
676
|
+
if (instant) {
|
|
677
|
+
this.stop();
|
|
678
|
+
list.scrollLeft = target;
|
|
679
|
+
return;
|
|
680
|
+
}
|
|
681
|
+
this.to(target);
|
|
682
|
+
}
|
|
628
683
|
to(left) {
|
|
629
684
|
const list = this.#list()?.nativeElement;
|
|
630
685
|
const win = this.#win;
|
|
@@ -754,6 +809,23 @@ var RtTabsFollow = class {
|
|
|
754
809
|
this.#list = null;
|
|
755
810
|
}
|
|
756
811
|
};
|
|
812
|
+
function rtTabsKeyTarget(key, direction, index, count) {
|
|
813
|
+
const isVertical = direction === "vertical";
|
|
814
|
+
return (/* @__PURE__ */ new Map([
|
|
815
|
+
[isVertical ? "ArrowDown" : "ArrowRight", (index + 1) % count],
|
|
816
|
+
[isVertical ? "ArrowUp" : "ArrowLeft", (index - 1 + count) % count],
|
|
817
|
+
["Home", 0],
|
|
818
|
+
["End", count - 1]
|
|
819
|
+
])).get(key);
|
|
820
|
+
}
|
|
821
|
+
function rtTabsKeyTargetId(enabled, currentId, key, direction) {
|
|
822
|
+
if (!enabled.length) return;
|
|
823
|
+
const index = rtTabsKeyTarget(key, direction, enabled.indexOf(currentId), enabled.length);
|
|
824
|
+
return index === void 0 ? void 0 : enabled[index];
|
|
825
|
+
}
|
|
826
|
+
function rtTabsSelectedId(enabled, candidate) {
|
|
827
|
+
return candidate !== null && enabled.includes(candidate) ? candidate : enabled[0] ?? null;
|
|
828
|
+
}
|
|
757
829
|
var RtTabsControlDirective = class RtTabsControlDirective {
|
|
758
830
|
constructor() {
|
|
759
831
|
this.templateRef = inject(TemplateRef);
|
|
@@ -809,6 +881,539 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
809
881
|
}]
|
|
810
882
|
}] }
|
|
811
883
|
});
|
|
884
|
+
var RtTabsMenuKeysDirective = class RtTabsMenuKeysDirective {
|
|
885
|
+
#host = inject(ElementRef).nativeElement;
|
|
886
|
+
#doc = inject(DOCUMENT);
|
|
887
|
+
#returnTo = this.#doc.activeElement;
|
|
888
|
+
#keys = null;
|
|
889
|
+
constructor() {
|
|
890
|
+
afterNextRender(() => {
|
|
891
|
+
const items = this.#items().map((node) => ({
|
|
892
|
+
disabled: node.getAttribute("aria-disabled") === "true" || node.hasAttribute("disabled"),
|
|
893
|
+
focus: () => node.focus()
|
|
894
|
+
}));
|
|
895
|
+
this.#keys = new FocusKeyManager(items).withWrap().withHomeAndEnd();
|
|
896
|
+
this.#keys.setFirstItemActive();
|
|
897
|
+
});
|
|
898
|
+
inject(DestroyRef).onDestroy(() => {
|
|
899
|
+
this.#keys?.destroy();
|
|
900
|
+
const active = this.#doc.activeElement;
|
|
901
|
+
if ((active === null || active === this.#doc.body || this.#host.contains(active)) && this.#returnTo instanceof HTMLElement && this.#returnTo.isConnected) this.#returnTo.focus();
|
|
902
|
+
});
|
|
903
|
+
}
|
|
904
|
+
onKeydown(event) {
|
|
905
|
+
if (event.key !== "Tab" && event.key !== "Escape") this.#keys?.onKeydown(event);
|
|
906
|
+
}
|
|
907
|
+
#items() {
|
|
908
|
+
const items = Array.from(this.#host.querySelectorAll("[role=\"menuitem\"]"));
|
|
909
|
+
return items.length > 0 ? items : Array.from(this.#host.querySelectorAll("button"));
|
|
910
|
+
}
|
|
911
|
+
static {
|
|
912
|
+
this.ɵfac = i0.ɵɵngDeclareFactory({
|
|
913
|
+
minVersion: "12.0.0",
|
|
914
|
+
version: "22.2.2",
|
|
915
|
+
ngImport: i0,
|
|
916
|
+
type: RtTabsMenuKeysDirective,
|
|
917
|
+
deps: [],
|
|
918
|
+
target: i0.ɵɵFactoryTarget.Directive
|
|
919
|
+
});
|
|
920
|
+
}
|
|
921
|
+
static {
|
|
922
|
+
this.ɵdir = i0.ɵɵngDeclareDirective({
|
|
923
|
+
minVersion: "14.0.0",
|
|
924
|
+
version: "22.2.2",
|
|
925
|
+
type: RtTabsMenuKeysDirective,
|
|
926
|
+
isStandalone: true,
|
|
927
|
+
selector: "[rtTabsMenuKeys]",
|
|
928
|
+
host: { listeners: { "keydown": "onKeydown($event)" } },
|
|
929
|
+
ngImport: i0
|
|
930
|
+
});
|
|
931
|
+
}
|
|
932
|
+
};
|
|
933
|
+
i0.ɵɵngDeclareClassMetadata({
|
|
934
|
+
minVersion: "12.0.0",
|
|
935
|
+
version: "22.2.2",
|
|
936
|
+
ngImport: i0,
|
|
937
|
+
type: RtTabsMenuKeysDirective,
|
|
938
|
+
decorators: [{
|
|
939
|
+
type: Directive,
|
|
940
|
+
args: [{
|
|
941
|
+
selector: "[rtTabsMenuKeys]",
|
|
942
|
+
host: { "(keydown)": "onKeydown($event)" }
|
|
943
|
+
}]
|
|
944
|
+
}],
|
|
945
|
+
ctorParameters: () => []
|
|
946
|
+
});
|
|
947
|
+
const BEM_BLOCK$2 = "rt-tabs-context-menu";
|
|
948
|
+
var RtTabsContextMenuComponent = class RtTabsContextMenuComponent {
|
|
949
|
+
constructor() {
|
|
950
|
+
this.state = signal(null, ...ngDevMode ? [{ debugName: "state" }] : /* istanbul ignore next */ []);
|
|
951
|
+
}
|
|
952
|
+
open(event, tab) {
|
|
953
|
+
const template = tab.contextMenu();
|
|
954
|
+
if (template === null) return;
|
|
955
|
+
event.preventDefault();
|
|
956
|
+
this.state.set({
|
|
957
|
+
template,
|
|
958
|
+
point: RtTabsContextMenuComponent.pointOf(event),
|
|
959
|
+
context: { $implicit: tab.id() }
|
|
960
|
+
});
|
|
961
|
+
}
|
|
962
|
+
static pointOf(event) {
|
|
963
|
+
if (event.clientX === 0 && event.clientY === 0 && event.target instanceof Element) {
|
|
964
|
+
const box = event.target.getBoundingClientRect();
|
|
965
|
+
return {
|
|
966
|
+
x: box.left,
|
|
967
|
+
y: box.bottom
|
|
968
|
+
};
|
|
969
|
+
}
|
|
970
|
+
return {
|
|
971
|
+
x: event.clientX,
|
|
972
|
+
y: event.clientY
|
|
973
|
+
};
|
|
974
|
+
}
|
|
975
|
+
close() {
|
|
976
|
+
this.state.set(null);
|
|
977
|
+
}
|
|
978
|
+
onKeydown(event) {
|
|
979
|
+
if (event.key === "Escape") this.close();
|
|
980
|
+
}
|
|
981
|
+
static {
|
|
982
|
+
this.ɵfac = i0.ɵɵngDeclareFactory({
|
|
983
|
+
minVersion: "12.0.0",
|
|
984
|
+
version: "22.2.2",
|
|
985
|
+
ngImport: i0,
|
|
986
|
+
type: RtTabsContextMenuComponent,
|
|
987
|
+
deps: [],
|
|
988
|
+
target: i0.ɵɵFactoryTarget.Component
|
|
989
|
+
});
|
|
990
|
+
}
|
|
991
|
+
static {
|
|
992
|
+
this.ɵcmp = i0.ɵɵngDeclareComponent({
|
|
993
|
+
minVersion: "17.0.0",
|
|
994
|
+
version: "22.2.2",
|
|
995
|
+
type: RtTabsContextMenuComponent,
|
|
996
|
+
isStandalone: true,
|
|
997
|
+
selector: "rt-tabs-context-menu",
|
|
998
|
+
host: { classAttribute: "rt-tabs-context-menu" },
|
|
999
|
+
ngImport: i0,
|
|
1000
|
+
template: "@if (state(); as menu) {\n <ng-template\n cdkConnectedOverlay\n cdkConnectedOverlayHasBackdrop\n cdkConnectedOverlayBackdropClass=\"cdk-overlay-transparent-backdrop\"\n [cdkConnectedOverlayOpen]=\"true\"\n [cdkConnectedOverlayOrigin]=\"menu.point\"\n (backdropClick)=\"close()\"\n (detach)=\"close()\"\n (overlayKeydown)=\"onKeydown($event)\">\n <div\n rtBlock=\"rt-tabs-more-menu\"\n rtTabsMenuKeys\n role=\"menu\"\n tabindex=\"-1\"\n qa-dataid=\"tabs-context-menu\"\n (click)=\"close()\"\n (keydown.enter)=\"close()\">\n <ng-container [ngTemplateOutlet]=\"menu.template\" [ngTemplateOutletContext]=\"menu.context\" />\n </div>\n </ng-template>\n}\n",
|
|
1001
|
+
dependencies: [
|
|
1002
|
+
{
|
|
1003
|
+
kind: "directive",
|
|
1004
|
+
type: CdkConnectedOverlay,
|
|
1005
|
+
selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]",
|
|
1006
|
+
inputs: [
|
|
1007
|
+
"cdkConnectedOverlayOrigin",
|
|
1008
|
+
"cdkConnectedOverlayPositions",
|
|
1009
|
+
"cdkConnectedOverlayPositionStrategy",
|
|
1010
|
+
"cdkConnectedOverlayOffsetX",
|
|
1011
|
+
"cdkConnectedOverlayOffsetY",
|
|
1012
|
+
"cdkConnectedOverlayWidth",
|
|
1013
|
+
"cdkConnectedOverlayHeight",
|
|
1014
|
+
"cdkConnectedOverlayMinWidth",
|
|
1015
|
+
"cdkConnectedOverlayMinHeight",
|
|
1016
|
+
"cdkConnectedOverlayBackdropClass",
|
|
1017
|
+
"cdkConnectedOverlayPanelClass",
|
|
1018
|
+
"cdkConnectedOverlayViewportMargin",
|
|
1019
|
+
"cdkConnectedOverlayScrollStrategy",
|
|
1020
|
+
"cdkConnectedOverlayOpen",
|
|
1021
|
+
"cdkConnectedOverlayDisableClose",
|
|
1022
|
+
"cdkConnectedOverlayTransformOriginOn",
|
|
1023
|
+
"cdkConnectedOverlayHasBackdrop",
|
|
1024
|
+
"cdkConnectedOverlayLockPosition",
|
|
1025
|
+
"cdkConnectedOverlayFlexibleDimensions",
|
|
1026
|
+
"cdkConnectedOverlayGrowAfterOpen",
|
|
1027
|
+
"cdkConnectedOverlayPush",
|
|
1028
|
+
"cdkConnectedOverlayDisposeOnNavigation",
|
|
1029
|
+
"cdkConnectedOverlayUsePopover",
|
|
1030
|
+
"cdkConnectedOverlayMatchWidth",
|
|
1031
|
+
"cdkConnectedOverlay"
|
|
1032
|
+
],
|
|
1033
|
+
outputs: [
|
|
1034
|
+
"backdropClick",
|
|
1035
|
+
"positionChange",
|
|
1036
|
+
"attach",
|
|
1037
|
+
"detach",
|
|
1038
|
+
"overlayKeydown",
|
|
1039
|
+
"overlayOutsideClick"
|
|
1040
|
+
],
|
|
1041
|
+
exportAs: ["cdkConnectedOverlay"]
|
|
1042
|
+
},
|
|
1043
|
+
{
|
|
1044
|
+
kind: "directive",
|
|
1045
|
+
type: NgTemplateOutlet,
|
|
1046
|
+
selector: "[ngTemplateOutlet]",
|
|
1047
|
+
inputs: [
|
|
1048
|
+
"ngTemplateOutletContext",
|
|
1049
|
+
"ngTemplateOutlet",
|
|
1050
|
+
"ngTemplateOutletInjector"
|
|
1051
|
+
]
|
|
1052
|
+
},
|
|
1053
|
+
{
|
|
1054
|
+
kind: "directive",
|
|
1055
|
+
type: RtTabsMenuKeysDirective,
|
|
1056
|
+
selector: "[rtTabsMenuKeys]"
|
|
1057
|
+
},
|
|
1058
|
+
{
|
|
1059
|
+
kind: "directive",
|
|
1060
|
+
type: BlockDirective,
|
|
1061
|
+
selector: "[rtBlock]",
|
|
1062
|
+
inputs: ["rtMod"]
|
|
1063
|
+
}
|
|
1064
|
+
],
|
|
1065
|
+
changeDetection: i0.ChangeDetectionStrategy.OnPush,
|
|
1066
|
+
encapsulation: i0.ViewEncapsulation.None
|
|
1067
|
+
});
|
|
1068
|
+
}
|
|
1069
|
+
};
|
|
1070
|
+
i0.ɵɵngDeclareClassMetadata({
|
|
1071
|
+
minVersion: "12.0.0",
|
|
1072
|
+
version: "22.2.2",
|
|
1073
|
+
ngImport: i0,
|
|
1074
|
+
type: RtTabsContextMenuComponent,
|
|
1075
|
+
decorators: [{
|
|
1076
|
+
type: Component,
|
|
1077
|
+
args: [{
|
|
1078
|
+
selector: "rt-tabs-context-menu",
|
|
1079
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
1080
|
+
encapsulation: ViewEncapsulation.None,
|
|
1081
|
+
imports: [
|
|
1082
|
+
CdkConnectedOverlay,
|
|
1083
|
+
NgTemplateOutlet,
|
|
1084
|
+
RtTabsMenuKeysDirective,
|
|
1085
|
+
BlockDirective
|
|
1086
|
+
],
|
|
1087
|
+
host: { class: BEM_BLOCK$2 },
|
|
1088
|
+
template: "@if (state(); as menu) {\n <ng-template\n cdkConnectedOverlay\n cdkConnectedOverlayHasBackdrop\n cdkConnectedOverlayBackdropClass=\"cdk-overlay-transparent-backdrop\"\n [cdkConnectedOverlayOpen]=\"true\"\n [cdkConnectedOverlayOrigin]=\"menu.point\"\n (backdropClick)=\"close()\"\n (detach)=\"close()\"\n (overlayKeydown)=\"onKeydown($event)\">\n <div\n rtBlock=\"rt-tabs-more-menu\"\n rtTabsMenuKeys\n role=\"menu\"\n tabindex=\"-1\"\n qa-dataid=\"tabs-context-menu\"\n (click)=\"close()\"\n (keydown.enter)=\"close()\">\n <ng-container [ngTemplateOutlet]=\"menu.template\" [ngTemplateOutletContext]=\"menu.context\" />\n </div>\n </ng-template>\n}\n"
|
|
1089
|
+
}]
|
|
1090
|
+
}]
|
|
1091
|
+
});
|
|
1092
|
+
const BEM_BLOCK$1 = "rt-tabs-more";
|
|
1093
|
+
var RtTabsMoreComponent = class RtTabsMoreComponent {
|
|
1094
|
+
constructor() {
|
|
1095
|
+
this.t = inject(RT_KIT_LABELS);
|
|
1096
|
+
this.popover = viewChild(RtPopoverDirective, ...ngDevMode ? [{ debugName: "popover" }] : /* istanbul ignore next */ []);
|
|
1097
|
+
this.hasError = computed(() => this.tabs().some((tab) => tab.invalid()), ...ngDevMode ? [{ debugName: "hasError" }] : /* istanbul ignore next */ []);
|
|
1098
|
+
this.tabs = input([], ...ngDevMode ? [{ debugName: "tabs" }] : /* istanbul ignore next */ []);
|
|
1099
|
+
this.pick = output();
|
|
1100
|
+
this.closeTab = output();
|
|
1101
|
+
effect(() => {
|
|
1102
|
+
const popover = this.popover();
|
|
1103
|
+
if (this.tabs().length === 0 && popover?.isOpen()) popover.close();
|
|
1104
|
+
});
|
|
1105
|
+
}
|
|
1106
|
+
onPick(tab, popover) {
|
|
1107
|
+
if (tab.disabled()) return;
|
|
1108
|
+
this.pick.emit(tab.id());
|
|
1109
|
+
popover.close();
|
|
1110
|
+
}
|
|
1111
|
+
static {
|
|
1112
|
+
this.ɵfac = i0.ɵɵngDeclareFactory({
|
|
1113
|
+
minVersion: "12.0.0",
|
|
1114
|
+
version: "22.2.2",
|
|
1115
|
+
ngImport: i0,
|
|
1116
|
+
type: RtTabsMoreComponent,
|
|
1117
|
+
deps: [],
|
|
1118
|
+
target: i0.ɵɵFactoryTarget.Component
|
|
1119
|
+
});
|
|
1120
|
+
}
|
|
1121
|
+
static {
|
|
1122
|
+
this.ɵcmp = i0.ɵɵngDeclareComponent({
|
|
1123
|
+
minVersion: "17.0.0",
|
|
1124
|
+
version: "22.2.2",
|
|
1125
|
+
type: RtTabsMoreComponent,
|
|
1126
|
+
isStandalone: true,
|
|
1127
|
+
selector: "rt-tabs-more",
|
|
1128
|
+
inputs: { tabs: {
|
|
1129
|
+
classPropertyName: "tabs",
|
|
1130
|
+
publicName: "tabs",
|
|
1131
|
+
isSignal: true,
|
|
1132
|
+
isRequired: false,
|
|
1133
|
+
transformFunction: null
|
|
1134
|
+
} },
|
|
1135
|
+
outputs: {
|
|
1136
|
+
pick: "pick",
|
|
1137
|
+
closeTab: "closeTab"
|
|
1138
|
+
},
|
|
1139
|
+
host: {
|
|
1140
|
+
attributes: { "role": "presentation" },
|
|
1141
|
+
properties: { "class.rt-tabs-more--idle": "!tabs().length" },
|
|
1142
|
+
classAttribute: "rt-tabs-more"
|
|
1143
|
+
},
|
|
1144
|
+
viewQueries: [{
|
|
1145
|
+
propertyName: "popover",
|
|
1146
|
+
first: true,
|
|
1147
|
+
predicate: RtPopoverDirective,
|
|
1148
|
+
descendants: true,
|
|
1149
|
+
isSignal: true
|
|
1150
|
+
}],
|
|
1151
|
+
ngImport: i0,
|
|
1152
|
+
template: "<!-- Пункт выглядит как вкладка и берёт её блок: второй набор тех же правил разошёлся бы с первым. -->\n<div rtBlock=\"rt-tab-item\" role=\"presentation\">\n <button\n rtElem=\"trigger\"\n qa-dataid=\"tabs-more\"\n type=\"button\"\n role=\"tab\"\n aria-haspopup=\"menu\"\n aria-selected=\"false\"\n #morePopover=\"rtPopover\"\n rtPopoverAlign=\"end\"\n rtPopoverFitViewport\n rtPopoverOffsetY=\"6\"\n [attr.aria-expanded]=\"morePopover.isOpen()\"\n [attr.tabindex]=\"tabs().length ? 0 : -1\"\n [rtMod]=\"{ open: morePopover.isOpen() }\"\n [rtPopover]=\"moreTpl\">\n <span rtElem=\"title\">{{ t().uiNavMore }}</span>\n @if (hasError()) {\n <span rtElem=\"more-dot\" role=\"img\" qa-dataid=\"tabs-more-dot\" [attr.aria-label]=\"t().uiTabInvalid\"></span>\n }\n <rt-icon color=\"current\" size=\"xs\" [name]=\"morePopover.isOpen() ? 'chevron-up' : 'chevron-down'\" />\n </button>\n</div>\n\n<ng-template #moreTpl>\n <div rtBlock=\"rt-tabs-more-menu\" rtTabsMenuKeys role=\"menu\" qa-dataid=\"tabs-more-menu\">\n @for (tab of tabs(); track tab.id()) {\n <div rtElem=\"row\" role=\"none\" [rtMod]=\"{ disabled: tab.disabled(), invalid: tab.invalid() }\">\n <button\n rtElem=\"pick\"\n qa-dataid=\"tabs-more-item\"\n type=\"button\"\n role=\"menuitem\"\n [attr.aria-disabled]=\"tab.disabled() || null\"\n [attr.data-id]=\"tab.id()\"\n [rtTooltip]=\"tab.buttonTooltip()\"\n (click)=\"onPick(tab, morePopover)\">\n @if (tab.hasIcon()) {\n <rt-icon\n rtElem=\"icon\"\n size=\"sm\"\n [name]=\"tab.icon()\"\n [glyph]=\"tab.glyph()\"\n [color]=\"tab.iconColor()\"\n [fill]=\"tab.iconFill()\" />\n }\n <span rtElem=\"label\">\n @if (tab.titleTemplate(); as titleTpl) {\n <ng-container [ngTemplateOutlet]=\"titleTpl\" />\n } @else {\n {{ tab.label() }}\n }\n </span>\n @if (tab.badge() !== null) {\n <span rtElem=\"badge\">{{ tab.badge() }}</span>\n }\n </button>\n @if (tab.showClose()) {\n <button\n rtElem=\"close\"\n qa-dataid=\"tabs-more-close\"\n type=\"button\"\n [attr.aria-label]=\"tab.closeLabel()\"\n [attr.data-id]=\"tab.id()\"\n (click)=\"closeTab.emit(tab)\">\n <rt-icon name=\"close\" color=\"current\" size=\"xs\" />\n </button>\n }\n </div>\n }\n </div>\n</ng-template>\n",
|
|
1153
|
+
styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-tabs-more{--rt-tabs-more-dot-radius: var(--rt-radius-full);display:inline-flex;order:9999}.rt-tabs-more--idle{position:absolute;top:0;left:0;pointer-events:none;visibility:hidden}.rt-tabs-more .rt-tab-item__trigger--open{background-color:var(--rt-color-bg-hover);color:var(--rt-color-text-primary)}.rt-tabs-more .rt-tab-item__more-dot{width:var(--rt-size-2);height:var(--rt-size-2);border-radius:var(--rt-tabs-more-dot-radius);background-color:var(--rt-color-state-danger)}}\n"],
|
|
1154
|
+
dependencies: [
|
|
1155
|
+
{
|
|
1156
|
+
kind: "directive",
|
|
1157
|
+
type: NgTemplateOutlet,
|
|
1158
|
+
selector: "[ngTemplateOutlet]",
|
|
1159
|
+
inputs: [
|
|
1160
|
+
"ngTemplateOutletContext",
|
|
1161
|
+
"ngTemplateOutlet",
|
|
1162
|
+
"ngTemplateOutletInjector"
|
|
1163
|
+
]
|
|
1164
|
+
},
|
|
1165
|
+
{
|
|
1166
|
+
kind: "component",
|
|
1167
|
+
type: RtIconComponent,
|
|
1168
|
+
selector: "rt-icon",
|
|
1169
|
+
inputs: [
|
|
1170
|
+
"name",
|
|
1171
|
+
"glyph",
|
|
1172
|
+
"glyphStrategy",
|
|
1173
|
+
"size",
|
|
1174
|
+
"color",
|
|
1175
|
+
"fill",
|
|
1176
|
+
"spin",
|
|
1177
|
+
"rotate"
|
|
1178
|
+
]
|
|
1179
|
+
},
|
|
1180
|
+
{
|
|
1181
|
+
kind: "directive",
|
|
1182
|
+
type: RtPopoverDirective,
|
|
1183
|
+
selector: "[rtPopover]",
|
|
1184
|
+
inputs: [
|
|
1185
|
+
"rtPopover",
|
|
1186
|
+
"rtPopoverTrigger",
|
|
1187
|
+
"rtPopoverWidth",
|
|
1188
|
+
"rtPopoverAlign",
|
|
1189
|
+
"rtPopoverFitViewport",
|
|
1190
|
+
"rtPopoverContext",
|
|
1191
|
+
"rtPopoverPanelClass",
|
|
1192
|
+
"rtPopoverBackdropClass",
|
|
1193
|
+
"rtPopoverDisabled",
|
|
1194
|
+
"rtPopoverOffsetY",
|
|
1195
|
+
"rtPopoverOffsetX",
|
|
1196
|
+
"rtPopoverPositions"
|
|
1197
|
+
],
|
|
1198
|
+
outputs: ["rtPopoverOpened", "rtPopoverClosed"],
|
|
1199
|
+
exportAs: ["rtPopover"]
|
|
1200
|
+
},
|
|
1201
|
+
{
|
|
1202
|
+
kind: "directive",
|
|
1203
|
+
type: RtTooltipDirective,
|
|
1204
|
+
selector: "[rtTooltip]",
|
|
1205
|
+
inputs: [
|
|
1206
|
+
"rtTooltip",
|
|
1207
|
+
"rtTooltipPlacement",
|
|
1208
|
+
"rtTooltipShowDelay",
|
|
1209
|
+
"rtTooltipWhenTruncated",
|
|
1210
|
+
"rtTooltipHideOnClick",
|
|
1211
|
+
"rtTooltipShowOnTap"
|
|
1212
|
+
],
|
|
1213
|
+
exportAs: ["rtTooltip"]
|
|
1214
|
+
},
|
|
1215
|
+
{
|
|
1216
|
+
kind: "directive",
|
|
1217
|
+
type: RtTabsMenuKeysDirective,
|
|
1218
|
+
selector: "[rtTabsMenuKeys]"
|
|
1219
|
+
},
|
|
1220
|
+
{
|
|
1221
|
+
kind: "directive",
|
|
1222
|
+
type: BlockDirective,
|
|
1223
|
+
selector: "[rtBlock]",
|
|
1224
|
+
inputs: ["rtMod"]
|
|
1225
|
+
},
|
|
1226
|
+
{
|
|
1227
|
+
kind: "directive",
|
|
1228
|
+
type: ElemDirective,
|
|
1229
|
+
selector: "[rtElem]",
|
|
1230
|
+
inputs: ["rtMod"]
|
|
1231
|
+
},
|
|
1232
|
+
{
|
|
1233
|
+
kind: "directive",
|
|
1234
|
+
type: ModDirective,
|
|
1235
|
+
selector: "[rtMod]"
|
|
1236
|
+
}
|
|
1237
|
+
],
|
|
1238
|
+
changeDetection: i0.ChangeDetectionStrategy.OnPush,
|
|
1239
|
+
encapsulation: i0.ViewEncapsulation.None
|
|
1240
|
+
});
|
|
1241
|
+
}
|
|
1242
|
+
};
|
|
1243
|
+
i0.ɵɵngDeclareClassMetadata({
|
|
1244
|
+
minVersion: "12.0.0",
|
|
1245
|
+
version: "22.2.2",
|
|
1246
|
+
ngImport: i0,
|
|
1247
|
+
type: RtTabsMoreComponent,
|
|
1248
|
+
decorators: [{
|
|
1249
|
+
type: Component,
|
|
1250
|
+
args: [{
|
|
1251
|
+
selector: "rt-tabs-more",
|
|
1252
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
1253
|
+
encapsulation: ViewEncapsulation.None,
|
|
1254
|
+
imports: [
|
|
1255
|
+
NgTemplateOutlet,
|
|
1256
|
+
RtIconComponent,
|
|
1257
|
+
RtPopoverDirective,
|
|
1258
|
+
RtTooltipDirective,
|
|
1259
|
+
RtTabsMenuKeysDirective,
|
|
1260
|
+
BlockDirective,
|
|
1261
|
+
ElemDirective,
|
|
1262
|
+
ModDirective
|
|
1263
|
+
],
|
|
1264
|
+
host: {
|
|
1265
|
+
class: BEM_BLOCK$1,
|
|
1266
|
+
role: "presentation",
|
|
1267
|
+
"[class.rt-tabs-more--idle]": "!tabs().length"
|
|
1268
|
+
},
|
|
1269
|
+
template: "<!-- Пункт выглядит как вкладка и берёт её блок: второй набор тех же правил разошёлся бы с первым. -->\n<div rtBlock=\"rt-tab-item\" role=\"presentation\">\n <button\n rtElem=\"trigger\"\n qa-dataid=\"tabs-more\"\n type=\"button\"\n role=\"tab\"\n aria-haspopup=\"menu\"\n aria-selected=\"false\"\n #morePopover=\"rtPopover\"\n rtPopoverAlign=\"end\"\n rtPopoverFitViewport\n rtPopoverOffsetY=\"6\"\n [attr.aria-expanded]=\"morePopover.isOpen()\"\n [attr.tabindex]=\"tabs().length ? 0 : -1\"\n [rtMod]=\"{ open: morePopover.isOpen() }\"\n [rtPopover]=\"moreTpl\">\n <span rtElem=\"title\">{{ t().uiNavMore }}</span>\n @if (hasError()) {\n <span rtElem=\"more-dot\" role=\"img\" qa-dataid=\"tabs-more-dot\" [attr.aria-label]=\"t().uiTabInvalid\"></span>\n }\n <rt-icon color=\"current\" size=\"xs\" [name]=\"morePopover.isOpen() ? 'chevron-up' : 'chevron-down'\" />\n </button>\n</div>\n\n<ng-template #moreTpl>\n <div rtBlock=\"rt-tabs-more-menu\" rtTabsMenuKeys role=\"menu\" qa-dataid=\"tabs-more-menu\">\n @for (tab of tabs(); track tab.id()) {\n <div rtElem=\"row\" role=\"none\" [rtMod]=\"{ disabled: tab.disabled(), invalid: tab.invalid() }\">\n <button\n rtElem=\"pick\"\n qa-dataid=\"tabs-more-item\"\n type=\"button\"\n role=\"menuitem\"\n [attr.aria-disabled]=\"tab.disabled() || null\"\n [attr.data-id]=\"tab.id()\"\n [rtTooltip]=\"tab.buttonTooltip()\"\n (click)=\"onPick(tab, morePopover)\">\n @if (tab.hasIcon()) {\n <rt-icon\n rtElem=\"icon\"\n size=\"sm\"\n [name]=\"tab.icon()\"\n [glyph]=\"tab.glyph()\"\n [color]=\"tab.iconColor()\"\n [fill]=\"tab.iconFill()\" />\n }\n <span rtElem=\"label\">\n @if (tab.titleTemplate(); as titleTpl) {\n <ng-container [ngTemplateOutlet]=\"titleTpl\" />\n } @else {\n {{ tab.label() }}\n }\n </span>\n @if (tab.badge() !== null) {\n <span rtElem=\"badge\">{{ tab.badge() }}</span>\n }\n </button>\n @if (tab.showClose()) {\n <button\n rtElem=\"close\"\n qa-dataid=\"tabs-more-close\"\n type=\"button\"\n [attr.aria-label]=\"tab.closeLabel()\"\n [attr.data-id]=\"tab.id()\"\n (click)=\"closeTab.emit(tab)\">\n <rt-icon name=\"close\" color=\"current\" size=\"xs\" />\n </button>\n }\n </div>\n }\n </div>\n</ng-template>\n",
|
|
1270
|
+
styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-tabs-more{--rt-tabs-more-dot-radius: var(--rt-radius-full);display:inline-flex;order:9999}.rt-tabs-more--idle{position:absolute;top:0;left:0;pointer-events:none;visibility:hidden}.rt-tabs-more .rt-tab-item__trigger--open{background-color:var(--rt-color-bg-hover);color:var(--rt-color-text-primary)}.rt-tabs-more .rt-tab-item__more-dot{width:var(--rt-size-2);height:var(--rt-size-2);border-radius:var(--rt-tabs-more-dot-radius);background-color:var(--rt-color-state-danger)}}\n"]
|
|
1271
|
+
}]
|
|
1272
|
+
}],
|
|
1273
|
+
ctorParameters: () => [],
|
|
1274
|
+
propDecorators: {
|
|
1275
|
+
popover: [{
|
|
1276
|
+
type: i0.ViewChild,
|
|
1277
|
+
args: [i0.forwardRef(() => RtPopoverDirective), { isSignal: true }]
|
|
1278
|
+
}],
|
|
1279
|
+
tabs: [{
|
|
1280
|
+
type: i0.Input,
|
|
1281
|
+
args: [{
|
|
1282
|
+
isSignal: true,
|
|
1283
|
+
alias: "tabs",
|
|
1284
|
+
required: false
|
|
1285
|
+
}]
|
|
1286
|
+
}],
|
|
1287
|
+
pick: [{
|
|
1288
|
+
type: i0.Output,
|
|
1289
|
+
args: ["pick"]
|
|
1290
|
+
}],
|
|
1291
|
+
closeTab: [{
|
|
1292
|
+
type: i0.Output,
|
|
1293
|
+
args: ["closeTab"]
|
|
1294
|
+
}]
|
|
1295
|
+
}
|
|
1296
|
+
});
|
|
1297
|
+
const FIT_TOLERANCE = .5;
|
|
1298
|
+
function widthOf(tabs) {
|
|
1299
|
+
return tabs.reduce((sum, tab) => sum + tab.width, 0);
|
|
1300
|
+
}
|
|
1301
|
+
function idOf(tab) {
|
|
1302
|
+
return tab.id;
|
|
1303
|
+
}
|
|
1304
|
+
function leadingFit(free, budget, limit) {
|
|
1305
|
+
const prefix = [];
|
|
1306
|
+
let used = 0;
|
|
1307
|
+
for (const tab of free) {
|
|
1308
|
+
if (prefix.length >= limit || used + tab.width > budget) break;
|
|
1309
|
+
prefix.push(tab);
|
|
1310
|
+
used += tab.width;
|
|
1311
|
+
}
|
|
1312
|
+
return prefix;
|
|
1313
|
+
}
|
|
1314
|
+
function makeRoom(prefix, selected, budget, limit) {
|
|
1315
|
+
while (prefix.length > 0 && (widthOf(prefix) + selected.width > budget || prefix.length >= limit)) prefix.pop();
|
|
1316
|
+
prefix.push(selected);
|
|
1317
|
+
}
|
|
1318
|
+
function rtTabsFitRow(input) {
|
|
1319
|
+
const { slots, selectedId, moreWidth, available, limit = Infinity } = input;
|
|
1320
|
+
const pinned = slots.filter((tab) => tab.pinned);
|
|
1321
|
+
const free = slots.filter((tab) => !tab.pinned);
|
|
1322
|
+
const freeLimit = Math.max(0, limit - pinned.length);
|
|
1323
|
+
if (widthOf(slots) <= available + FIT_TOLERANCE && free.length <= freeLimit) return {
|
|
1324
|
+
row: [...pinned, ...free].map(idOf),
|
|
1325
|
+
more: []
|
|
1326
|
+
};
|
|
1327
|
+
const selected = free.find((tab) => tab.id === selectedId);
|
|
1328
|
+
const budget = available - moreWidth - widthOf(pinned) + FIT_TOLERANCE;
|
|
1329
|
+
const prefix = leadingFit(free, budget, freeLimit);
|
|
1330
|
+
if (selected !== void 0 && !prefix.includes(selected)) makeRoom(prefix, selected, budget, freeLimit);
|
|
1331
|
+
const inRow = new Set(prefix);
|
|
1332
|
+
return {
|
|
1333
|
+
row: [...pinned, ...prefix].map(idOf),
|
|
1334
|
+
more: free.filter((tab) => !inRow.has(tab)).map(idOf)
|
|
1335
|
+
};
|
|
1336
|
+
}
|
|
1337
|
+
const EMPTY_LAYOUT = {
|
|
1338
|
+
row: [],
|
|
1339
|
+
more: []
|
|
1340
|
+
};
|
|
1341
|
+
const RT_TABS_MEASURE_CLASS = "rt-tabs__tab-list--measure";
|
|
1342
|
+
function sameLayout(a, b) {
|
|
1343
|
+
return a.row.join() === b.row.join() && a.more.join() === b.more.join();
|
|
1344
|
+
}
|
|
1345
|
+
var RtTabsMoreRow = class {
|
|
1346
|
+
#win;
|
|
1347
|
+
#list;
|
|
1348
|
+
#deps;
|
|
1349
|
+
#layout;
|
|
1350
|
+
#watch;
|
|
1351
|
+
constructor(win, list, deps) {
|
|
1352
|
+
this.#layout = signal(EMPTY_LAYOUT, {
|
|
1353
|
+
...ngDevMode ? { debugName: "#layout" } : /* istanbul ignore next */ {},
|
|
1354
|
+
equal: sameLayout
|
|
1355
|
+
});
|
|
1356
|
+
this.#watch = null;
|
|
1357
|
+
this.ids = computed(() => new Set(this.#layout().more), ...ngDevMode ? [{ debugName: "ids" }] : /* istanbul ignore next */ []);
|
|
1358
|
+
this.order = computed(() => new Map(this.#layout().row.map((id, index) => [id, index])), ...ngDevMode ? [{ debugName: "order" }] : /* istanbul ignore next */ []);
|
|
1359
|
+
this.moreTabs = computed(() => this.#deps.visible().filter((tab) => this.ids().has(tab.id())), ...ngDevMode ? [{ debugName: "moreTabs" }] : /* istanbul ignore next */ []);
|
|
1360
|
+
this.rowTabs = computed(() => {
|
|
1361
|
+
const order = this.order();
|
|
1362
|
+
return this.#deps.visible().filter((tab) => !this.ids().has(tab.id())).sort((a, b) => (order.get(a.id()) ?? 0) - (order.get(b.id()) ?? 0));
|
|
1363
|
+
}, ...ngDevMode ? [{ debugName: "rowTabs" }] : /* istanbul ignore next */ []);
|
|
1364
|
+
this.#win = win;
|
|
1365
|
+
this.#list = list;
|
|
1366
|
+
this.#deps = deps;
|
|
1367
|
+
afterRenderEffect(() => {
|
|
1368
|
+
deps.visible();
|
|
1369
|
+
deps.enabled();
|
|
1370
|
+
this.#watchSizes();
|
|
1371
|
+
});
|
|
1372
|
+
afterRenderEffect(() => {
|
|
1373
|
+
deps.visible();
|
|
1374
|
+
deps.selectedId();
|
|
1375
|
+
deps.enabled();
|
|
1376
|
+
deps.limit();
|
|
1377
|
+
this.#measure();
|
|
1378
|
+
});
|
|
1379
|
+
inject(DestroyRef).onDestroy(() => this.#watch?.disconnect());
|
|
1380
|
+
}
|
|
1381
|
+
#watchSizes() {
|
|
1382
|
+
const list = this.#list()?.nativeElement;
|
|
1383
|
+
this.#watch?.disconnect();
|
|
1384
|
+
this.#watch = null;
|
|
1385
|
+
if (!this.#deps.enabled() || !list || !this.#win || !("ResizeObserver" in this.#win)) return;
|
|
1386
|
+
const watch = new ResizeObserver(() => this.#measure());
|
|
1387
|
+
watch.observe(list);
|
|
1388
|
+
Array.from(list.children).forEach((node) => watch.observe(node));
|
|
1389
|
+
this.#watch = watch;
|
|
1390
|
+
}
|
|
1391
|
+
#measure() {
|
|
1392
|
+
const list = this.#list()?.nativeElement;
|
|
1393
|
+
if (!this.#deps.enabled() || !list || !this.#win) {
|
|
1394
|
+
this.#layout.set(EMPTY_LAYOUT);
|
|
1395
|
+
return;
|
|
1396
|
+
}
|
|
1397
|
+
const style = this.#win.getComputedStyle(list);
|
|
1398
|
+
const padding = (parseFloat(style.paddingInlineStart) || 0) + (parseFloat(style.paddingInlineEnd) || 0);
|
|
1399
|
+
const available = list.getBoundingClientRect().width - padding;
|
|
1400
|
+
if (available <= 0) return;
|
|
1401
|
+
list.classList.add(RT_TABS_MEASURE_CLASS);
|
|
1402
|
+
const slots = this.#deps.visible().map((tab) => ({
|
|
1403
|
+
id: tab.id(),
|
|
1404
|
+
pinned: tab.pinned(),
|
|
1405
|
+
width: list.querySelector(`[data-tabitem="${tab.id()}"]`)?.getBoundingClientRect().width ?? 0
|
|
1406
|
+
}));
|
|
1407
|
+
list.classList.remove(RT_TABS_MEASURE_CLASS);
|
|
1408
|
+
this.#layout.set(rtTabsFitRow({
|
|
1409
|
+
slots,
|
|
1410
|
+
available,
|
|
1411
|
+
selectedId: this.#deps.selectedId(),
|
|
1412
|
+
limit: this.#deps.limit(),
|
|
1413
|
+
moreWidth: list.querySelector(".rt-tabs-more")?.getBoundingClientRect().width ?? 0
|
|
1414
|
+
}));
|
|
1415
|
+
}
|
|
1416
|
+
};
|
|
812
1417
|
const REST_DEBOUNCE_MS = 50;
|
|
813
1418
|
const BEM_BLOCK = "rt-tabs";
|
|
814
1419
|
var RtTabsComponent = class RtTabsComponent {
|
|
@@ -829,20 +1434,12 @@ var RtTabsComponent = class RtTabsComponent {
|
|
|
829
1434
|
this.visibleTabs = computed(() => this.tabs().filter((tab) => !tab.hidden()), ...ngDevMode ? [{ debugName: "visibleTabs" }] : /* istanbul ignore next */ []);
|
|
830
1435
|
this.leftControls = computed(() => this.controls().filter((c) => c.side() === "left"), ...ngDevMode ? [{ debugName: "leftControls" }] : /* istanbul ignore next */ []);
|
|
831
1436
|
this.rightControls = computed(() => this.controls().filter((c) => c.side() === "right"), ...ngDevMode ? [{ debugName: "rightControls" }] : /* istanbul ignore next */ []);
|
|
832
|
-
this.selectedId = computed(() => {
|
|
833
|
-
|
|
834
|
-
const candidate = this.activeId() ?? this.#internalId();
|
|
835
|
-
const candidateValid = candidate !== null && enabled.some((tab) => tab.id() === candidate);
|
|
836
|
-
let result;
|
|
837
|
-
if (candidateValid) result = candidate;
|
|
838
|
-
else if (enabled.length) result = enabled[0].id();
|
|
839
|
-
else result = null;
|
|
840
|
-
return result;
|
|
841
|
-
}, ...ngDevMode ? [{ debugName: "selectedId" }] : /* istanbul ignore next */ []);
|
|
1437
|
+
this.selectedId = computed(() => rtTabsSelectedId(this.visibleTabs().filter((tab) => !tab.disabled()).map((tab) => tab.id()), this.activeId() ?? this.#internalId()), ...ngDevMode ? [{ debugName: "selectedId" }] : /* istanbul ignore next */ []);
|
|
1438
|
+
this.moreMode = computed(() => this.overflow() === "more" && this.direction() === "horizontal", ...ngDevMode ? [{ debugName: "moreMode" }] : /* istanbul ignore next */ []);
|
|
842
1439
|
this.activeTab = computed(() => this.visibleTabs().find((tab) => tab.id() === this.selectedId()) ?? null, ...ngDevMode ? [{ debugName: "activeTab" }] : /* istanbul ignore next */ []);
|
|
843
1440
|
this.focusId = computed(() => {
|
|
844
1441
|
const focused = this.#focusedId();
|
|
845
|
-
return focused !== null && this.
|
|
1442
|
+
return focused !== null && this.more.rowTabs().some((tab) => tab.id() === focused && !tab.disabled()) ? focused : this.selectedId();
|
|
846
1443
|
}, ...ngDevMode ? [{ debugName: "focusId" }] : /* istanbul ignore next */ []);
|
|
847
1444
|
this.restBeforeVisible = signal(false, ...ngDevMode ? [{ debugName: "restBeforeVisible" }] : /* istanbul ignore next */ []);
|
|
848
1445
|
this.restAfterVisible = signal(false, ...ngDevMode ? [{ debugName: "restAfterVisible" }] : /* istanbul ignore next */ []);
|
|
@@ -857,8 +1454,14 @@ var RtTabsComponent = class RtTabsComponent {
|
|
|
857
1454
|
duration: () => this.animationDuration(),
|
|
858
1455
|
preserve: () => this.preserveContent()
|
|
859
1456
|
});
|
|
860
|
-
this.
|
|
1457
|
+
this.more = new RtTabsMoreRow(this.#win, this.tabListRef, {
|
|
1458
|
+
enabled: this.moreMode,
|
|
861
1459
|
visible: this.visibleTabs,
|
|
1460
|
+
selectedId: this.selectedId,
|
|
1461
|
+
limit: computed(() => this.moreLimit())
|
|
1462
|
+
});
|
|
1463
|
+
this.ink = new RtTabsInk(this.#win, this.tabListRef, {
|
|
1464
|
+
visible: this.more.rowTabs,
|
|
862
1465
|
active: this.activeTab
|
|
863
1466
|
});
|
|
864
1467
|
this.activeId = input(null, ...ngDevMode ? [{ debugName: "activeId" }] : /* istanbul ignore next */ []);
|
|
@@ -871,6 +1474,7 @@ var RtTabsComponent = class RtTabsComponent {
|
|
|
871
1474
|
...ngDevMode ? { debugName: "dense" } : /* istanbul ignore next */ {},
|
|
872
1475
|
transform: booleanAttribute
|
|
873
1476
|
});
|
|
1477
|
+
this.closeOn = input("all", ...ngDevMode ? [{ debugName: "closeOn" }] : /* istanbul ignore next */ []);
|
|
874
1478
|
this.contentScrollable = input(true, {
|
|
875
1479
|
...ngDevMode ? { debugName: "contentScrollable" } : /* istanbul ignore next */ {},
|
|
876
1480
|
transform: booleanAttribute
|
|
@@ -884,7 +1488,13 @@ var RtTabsComponent = class RtTabsComponent {
|
|
|
884
1488
|
transform: booleanAttribute
|
|
885
1489
|
});
|
|
886
1490
|
this.activation = input("auto", ...ngDevMode ? [{ debugName: "activation" }] : /* istanbul ignore next */ []);
|
|
1491
|
+
this.overflow = input("scroll", ...ngDevMode ? [{ debugName: "overflow" }] : /* istanbul ignore next */ []);
|
|
1492
|
+
this.moreLimit = input(10, {
|
|
1493
|
+
...ngDevMode ? { debugName: "moreLimit" } : /* istanbul ignore next */ {},
|
|
1494
|
+
transform: (value) => numberAttribute(value, 10)
|
|
1495
|
+
});
|
|
887
1496
|
this.scrollArrows = input("overlay", ...ngDevMode ? [{ debugName: "scrollArrows" }] : /* istanbul ignore next */ []);
|
|
1497
|
+
this.arrowLook = input("block", ...ngDevMode ? [{ debugName: "arrowLook" }] : /* istanbul ignore next */ []);
|
|
888
1498
|
this.scrollStep = input("fixed", ...ngDevMode ? [{ debugName: "scrollStep" }] : /* istanbul ignore next */ []);
|
|
889
1499
|
this.animationDuration = input(null, ...ngDevMode ? [{ debugName: "animationDuration" }] : /* istanbul ignore next */ []);
|
|
890
1500
|
this.contentTabIndex = input(0, ...ngDevMode ? [{ debugName: "contentTabIndex" }] : /* istanbul ignore next */ []);
|
|
@@ -923,26 +1533,17 @@ var RtTabsComponent = class RtTabsComponent {
|
|
|
923
1533
|
event.stopPropagation();
|
|
924
1534
|
this.#close(tab, event.currentTarget instanceof HTMLElement && event.currentTarget.matches(":focus"));
|
|
925
1535
|
}
|
|
1536
|
+
onMoreClose(tab) {
|
|
1537
|
+
this.#close(tab, false);
|
|
1538
|
+
}
|
|
926
1539
|
onTabKeydown(event, tab) {
|
|
927
1540
|
if (event.key === "Delete") {
|
|
928
1541
|
this.#closeByKey(event, tab);
|
|
929
1542
|
return;
|
|
930
1543
|
}
|
|
931
|
-
const
|
|
932
|
-
if (
|
|
933
|
-
const isVertical = this.direction() === "vertical";
|
|
934
|
-
const nextKey = isVertical ? "ArrowDown" : "ArrowRight";
|
|
935
|
-
const prevKey = isVertical ? "ArrowUp" : "ArrowLeft";
|
|
936
|
-
const currentIndex = enabled.findIndex((item) => item.id() === tab.id());
|
|
937
|
-
const targetIndex = (/* @__PURE__ */ new Map([
|
|
938
|
-
[nextKey, (currentIndex + 1) % enabled.length],
|
|
939
|
-
[prevKey, (currentIndex - 1 + enabled.length) % enabled.length],
|
|
940
|
-
["Home", 0],
|
|
941
|
-
["End", enabled.length - 1]
|
|
942
|
-
])).get(event.key);
|
|
943
|
-
if (targetIndex === void 0) return;
|
|
1544
|
+
const targetId = rtTabsKeyTargetId(this.more.rowTabs().filter((item) => !item.disabled()).map((item) => item.id()), tab.id(), event.key, this.direction());
|
|
1545
|
+
if (targetId === void 0) return;
|
|
944
1546
|
event.preventDefault();
|
|
945
|
-
const targetId = enabled[targetIndex].id();
|
|
946
1547
|
if (this.activation() === "manual") {
|
|
947
1548
|
this.#focusedId.set(targetId);
|
|
948
1549
|
this.#scrollTabIntoView(targetId);
|
|
@@ -965,7 +1566,7 @@ var RtTabsComponent = class RtTabsComponent {
|
|
|
965
1566
|
this.#updateRestVisibility();
|
|
966
1567
|
}
|
|
967
1568
|
#closeByKey(event, tab) {
|
|
968
|
-
if (!tab.showClose()) return;
|
|
1569
|
+
if (!tab.showClose() || this.closeOn() === "selected" && tab.id() !== this.selectedId()) return;
|
|
969
1570
|
event.preventDefault();
|
|
970
1571
|
this.#close(tab, true);
|
|
971
1572
|
}
|
|
@@ -985,14 +1586,12 @@ var RtTabsComponent = class RtTabsComponent {
|
|
|
985
1586
|
}
|
|
986
1587
|
#updateRestVisibility() {
|
|
987
1588
|
const list = this.tabListRef()?.nativeElement;
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
this.restBeforeVisible.set(list.scrollLeft > 0);
|
|
995
|
-
this.restAfterVisible.set(scrolledRight > 1);
|
|
1589
|
+
const shown = list && this.direction() === "horizontal" && !this.moreMode() ? rtTabsRestShown(list) : {
|
|
1590
|
+
before: false,
|
|
1591
|
+
after: false
|
|
1592
|
+
};
|
|
1593
|
+
this.restBeforeVisible.set(shown.before);
|
|
1594
|
+
this.restAfterVisible.set(shown.after);
|
|
996
1595
|
}
|
|
997
1596
|
#scrollToSelected(again = false) {
|
|
998
1597
|
const id = this.selectedId();
|
|
@@ -1004,15 +1603,12 @@ var RtTabsComponent = class RtTabsComponent {
|
|
|
1004
1603
|
#scrollTabIntoView(id) {
|
|
1005
1604
|
const list = this.tabListRef()?.nativeElement;
|
|
1006
1605
|
const tab = list?.querySelector(`[data-tabitem="${id}"]`);
|
|
1007
|
-
if (!list || !tab) return;
|
|
1606
|
+
if (!list || !tab || this.moreMode()) return;
|
|
1008
1607
|
const first = this.#scrolledId === null;
|
|
1009
1608
|
const rest = list.parentElement?.querySelector(".rt-tabs__rest");
|
|
1010
1609
|
const target = rtTabsIntoViewTarget(list, tab, this.scrollArrows() === "overlay" ? rest?.offsetWidth ?? 0 : 0);
|
|
1011
1610
|
this.#scrolledId = id;
|
|
1012
|
-
|
|
1013
|
-
this.#scroller.stop();
|
|
1014
|
-
list.scrollLeft = target;
|
|
1015
|
-
} else if (target !== null) this.#scroller.to(target);
|
|
1611
|
+
this.#scroller.place(target, first);
|
|
1016
1612
|
this.#updateRestVisibility();
|
|
1017
1613
|
}
|
|
1018
1614
|
#focusTab(id) {
|
|
@@ -1064,6 +1660,13 @@ var RtTabsComponent = class RtTabsComponent {
|
|
|
1064
1660
|
isRequired: false,
|
|
1065
1661
|
transformFunction: null
|
|
1066
1662
|
},
|
|
1663
|
+
closeOn: {
|
|
1664
|
+
classPropertyName: "closeOn",
|
|
1665
|
+
publicName: "closeOn",
|
|
1666
|
+
isSignal: true,
|
|
1667
|
+
isRequired: false,
|
|
1668
|
+
transformFunction: null
|
|
1669
|
+
},
|
|
1067
1670
|
contentScrollable: {
|
|
1068
1671
|
classPropertyName: "contentScrollable",
|
|
1069
1672
|
publicName: "contentScrollable",
|
|
@@ -1092,6 +1695,20 @@ var RtTabsComponent = class RtTabsComponent {
|
|
|
1092
1695
|
isRequired: false,
|
|
1093
1696
|
transformFunction: null
|
|
1094
1697
|
},
|
|
1698
|
+
overflow: {
|
|
1699
|
+
classPropertyName: "overflow",
|
|
1700
|
+
publicName: "overflow",
|
|
1701
|
+
isSignal: true,
|
|
1702
|
+
isRequired: false,
|
|
1703
|
+
transformFunction: null
|
|
1704
|
+
},
|
|
1705
|
+
moreLimit: {
|
|
1706
|
+
classPropertyName: "moreLimit",
|
|
1707
|
+
publicName: "moreLimit",
|
|
1708
|
+
isSignal: true,
|
|
1709
|
+
isRequired: false,
|
|
1710
|
+
transformFunction: null
|
|
1711
|
+
},
|
|
1095
1712
|
scrollArrows: {
|
|
1096
1713
|
classPropertyName: "scrollArrows",
|
|
1097
1714
|
publicName: "scrollArrows",
|
|
@@ -1099,6 +1716,13 @@ var RtTabsComponent = class RtTabsComponent {
|
|
|
1099
1716
|
isRequired: false,
|
|
1100
1717
|
transformFunction: null
|
|
1101
1718
|
},
|
|
1719
|
+
arrowLook: {
|
|
1720
|
+
classPropertyName: "arrowLook",
|
|
1721
|
+
publicName: "arrowLook",
|
|
1722
|
+
isSignal: true,
|
|
1723
|
+
isRequired: false,
|
|
1724
|
+
transformFunction: null
|
|
1725
|
+
},
|
|
1102
1726
|
scrollStep: {
|
|
1103
1727
|
classPropertyName: "scrollStep",
|
|
1104
1728
|
publicName: "scrollStep",
|
|
@@ -1152,8 +1776,12 @@ var RtTabsComponent = class RtTabsComponent {
|
|
|
1152
1776
|
isSignal: true
|
|
1153
1777
|
}],
|
|
1154
1778
|
ngImport: i0,
|
|
1155
|
-
template: "<ng-container rtBlock=\"rt-tabs\">\n <div rtElem=\"header\">\n @if (leftControls().length) {\n <div rtElem=\"controls\" [rtMod]=\"{ before: true }\">\n @for (control of leftControls(); track $index) {\n <ng-container [ngTemplateOutlet]=\"control.templateRef\" />\n }\n </div>\n }\n\n <div
|
|
1156
|
-
styles: [
|
|
1779
|
+
template: "<ng-container rtBlock=\"rt-tabs\">\n <div rtElem=\"header\">\n @if (leftControls().length) {\n <div rtElem=\"controls\" [rtMod]=\"{ before: true }\">\n @for (control of leftControls(); track $index) {\n <ng-container [ngTemplateOutlet]=\"control.templateRef\" />\n }\n </div>\n }\n\n <div\n rtElem=\"tab-list-wrapper\"\n [rtMod]=\"{ inline: scrollArrows() === 'inline', overflowing: overflowing(), compact: arrowLook() === 'compact' }\">\n @if (!moreMode()) {\n <div\n rtElem=\"rest\"\n qa-dataid=\"tabs-scroll-prev\"\n [rtMod]=\"{ before: true, visible: restBeforeVisible(), inactive: !restBeforeVisible() }\"\n (mousedown)=\"onRestPointerDown('before', $event)\"\n (mouseup)=\"onRestPointerUp()\"\n (mouseleave)=\"onRestPointerLeave()\">\n <span rtElem=\"arrow\"><rt-icon name=\"chevron-left\" color=\"current\" size=\"sm\" /></span>\n </div>\n }\n\n <div\n #tabList\n rtElem=\"tab-list\"\n qa-dataid=\"tabs-tab-list\"\n role=\"tablist\"\n [rtMod]=\"{ stretch: stretch(), direction: direction(), ink: ink.box() !== null, more: moreMode() }\"\n [attr.aria-orientation]=\"direction()\"\n (scroll)=\"onTabListScroll()\">\n @for (tab of visibleTabs(); track tab.id()) {\n @let focusable = tab.id() === focusId();\n @let closeShown = tab.showClose() && (closeOn() === 'all' || tab.id() === selectedId());\n <!-- Вкладка — обёртка из двух кнопок: самой вкладки и крестика рядом с ней, не внутри,\n потому что кнопка в кнопке недопустима. Нажатие в любом месте обёртки выбирает\n вкладку; крестик своё нажатие дальше не пускает. -->\n <div\n rtBlock=\"rt-tab-item\"\n role=\"presentation\"\n [rtMod]=\"{\n selected: tab.id() === selectedId(),\n disabled: tab.disabled(),\n invalid: tab.invalid(),\n stretch: stretch(),\n inMore: more.ids().has(tab.id()),\n }\"\n [style.order]=\"more.order().get(tab.id())\"\n [attr.inert]=\"more.ids().has(tab.id()) || null\"\n [attr.data-tabitem]=\"tab.id()\"\n (click)=\"selectTab(tab.id())\"\n (contextmenu)=\"contextMenu.open($event, tab)\">\n <button\n rtElem=\"trigger\"\n qa-dataid=\"tabs-tab\"\n type=\"button\"\n role=\"tab\"\n [rtMod]=\"{ closable: closeShown }\"\n [id]=\"'rt-tab-' + tab.id()\"\n [attr.aria-disabled]=\"tab.disabled() || null\"\n [attr.aria-label]=\"tab.ariaLabel()\"\n [attr.aria-keyshortcuts]=\"closeShown ? 'Delete' : null\"\n [attr.data-tabid]=\"tab.id()\"\n [attr.aria-selected]=\"tab.id() === selectedId()\"\n [attr.aria-controls]=\"headerOnly() ? null : 'rt-tabpanel-' + tab.id()\"\n [attr.tabindex]=\"focusable ? 0 : -1\"\n [rtTooltip]=\"tab.buttonTooltip()\"\n (keydown)=\"onTabKeydown($event, tab)\">\n @if (tab.hasIcon()) {\n <span rtElem=\"icon-box\">\n <rt-icon\n rtElem=\"icon\"\n size=\"sm\"\n [name]=\"tab.shownIcon()\"\n [glyph]=\"tab.glyph()\"\n [color]=\"tab.iconColor()\"\n [fill]=\"tab.iconFill()\" />\n @if (tab.badgeOverlay()) {\n <!-- prettier-ignore -->\n <span rtElem=\"badge\" [rtMod]=\"{ overlay: true }\" [rtTooltip]=\"tab.badgeTitle()\" [attr.aria-label]=\"tab.badgeAriaLabel() || null\">{{ tab.badge() }}</span>\n }\n </span>\n }\n\n @if (tab.titleTemplate(); as titleTpl) {\n <ng-container [ngTemplateOutlet]=\"titleTpl\" />\n } @else if (tab.label()) {\n <!-- Пустая подпись не рисуется: её зазор сдвигал значок вкладки без подписи с середины. -->\n <span rtElem=\"title\">{{ tab.label() }}</span>\n }\n\n @if (tab.badge() !== null && !tab.badgeOverlay()) {\n <!-- В одну строку: перенос внутри добавил бы пробел в текст кнопки. -->\n <!-- prettier-ignore -->\n <span rtElem=\"badge\" [rtTooltip]=\"tab.badgeTitle()\" [attr.aria-label]=\"tab.badgeAriaLabel() || null\">{{ tab.badge() }}</span>\n }\n </button>\n\n @if (closeShown) {\n <!-- В таб-порядке только у вкладки в фокусе: Tab с неё идёт на её крестик, дальше — из полосы. -->\n <button\n rtElem=\"close\"\n qa-dataid=\"tabs-tab-close\"\n type=\"button\"\n [attr.aria-label]=\"tab.closeLabel()\"\n [attr.tabindex]=\"focusable ? 0 : -1\"\n [rtTooltip]=\"tab.closeTooltip()\"\n [rtTooltipPlacement]=\"tab.closeTooltipPlacement()\"\n (mouseenter)=\"tab.closeHovered.set(true)\"\n (mouseleave)=\"tab.closeHovered.set(false)\"\n (click)=\"onCloseClick($event, tab)\">\n <rt-icon name=\"close\" color=\"current\" size=\"xs\" />\n </button>\n }\n </div>\n }\n\n @if (moreMode()) {\n <rt-tabs-more [tabs]=\"more.moreTabs()\" (pick)=\"selectTab($event)\" (closeTab)=\"onMoreClose($event)\" />\n }\n\n <!-- Полоса выбранной вкладки — одна на всю полосу: так она переезжает между вкладками. -->\n <span\n rtElem=\"ink\"\n aria-hidden=\"true\"\n [rtMod]=\"{ placed: ink.box() !== null, animated: ink.animated(), invalid: ink.invalid() }\"\n [style.width.px]=\"ink.box()?.width\"\n [style.translate]=\"ink.translate()\"></span>\n </div>\n\n @if (!moreMode()) {\n <div\n rtElem=\"rest\"\n qa-dataid=\"tabs-scroll-next\"\n [rtMod]=\"{ after: true, visible: restAfterVisible(), inactive: !restAfterVisible() }\"\n (mousedown)=\"onRestPointerDown('after', $event)\"\n (mouseup)=\"onRestPointerUp()\"\n (mouseleave)=\"onRestPointerLeave()\">\n <span rtElem=\"arrow\"><rt-icon name=\"chevron-right\" color=\"current\" size=\"sm\" /></span>\n </div>\n }\n </div>\n\n @if (rightControls().length) {\n <div rtElem=\"controls\" [rtMod]=\"{ after: true }\">\n @for (control of rightControls(); track $index) {\n <ng-container [ngTemplateOutlet]=\"control.templateRef\" />\n }\n </div>\n }\n </div>\n\n <rt-tabs-context-menu #contextMenu />\n\n <!-- Уходящая панель стоит поверх: место ей задаёт замер, сделанный до смены. Сохранённые\n тела посещённых вкладок скрыты и вне таб-порядка. -->\n @for (panel of panels.list(); track panel.tab.id()) {\n @let current = panel.leaving === null && !panel.idle;\n <div\n rtElem=\"content\"\n role=\"tabpanel\"\n [attr.qa-dataid]=\"current ? 'tabs-panel' : panel.idle ? 'tabs-panel-idle' : 'tabs-panel-leaving'\"\n [attr.tabindex]=\"current ? contentTabIndex() : -1\"\n [attr.aria-hidden]=\"current ? null : 'true'\"\n [attr.inert]=\"current ? null : ''\"\n [hidden]=\"panel.idle\"\n [rtMod]=\"{\n scrollable: contentScrollable(),\n idle: panel.idle,\n leaving: panel.leaving !== null,\n entering: current && panels.shift() !== null,\n shift: panels.shift(),\n }\"\n [style.top.px]=\"panel.leaving?.top\"\n [style.left.px]=\"panel.leaving?.left\"\n [id]=\"'rt-tabpanel-' + panel.tab.id()\"\n [attr.aria-labelledby]=\"'rt-tab-' + panel.tab.id()\"\n (animationend)=\"panels.animationEnd($event)\"\n (animationcancel)=\"panels.animationEnd($event)\">\n <ng-container [ngTemplateOutlet]=\"panel.tab.templateRef\" />\n </div>\n }\n</ng-container>\n",
|
|
1780
|
+
styles: [
|
|
1781
|
+
"@charset \"UTF-8\";@layer rt-kit.components{.rt-tabs{--rt-tabs-border-width: var(--rt-border-width-thin);--rt-tabs-transition-duration: var(--rt-duration-fast);--rt-tabs-list-align: stretch;--rt-tabs-list-border-color: var(--rt-color-border-default);--rt-tabs-list-min-height: auto;--rt-tabs-list-padding-inline: 0;--rt-tabs-content-padding-top: var(--rt-space-md);display:flex;-webkit-tap-highlight-color:transparent}.rt-tabs--direction--horizontal{flex-direction:column}.rt-tabs--direction--vertical{flex-direction:row}.rt-tabs--animating{position:relative;overflow-x:clip}.rt-tabs__header{display:flex;align-items:center}.rt-tabs__tab-list-wrapper{position:relative;display:flex;overflow:hidden;flex:1 1 auto;align-items:center}.rt-tabs__tab-list{position:relative;display:flex;box-sizing:border-box;align-items:var(--rt-tabs-list-align);border-bottom:var(--rt-tabs-border-width) solid var(--rt-tabs-list-border-color);margin:0;min-block-size:var(--rt-tabs-list-min-height);-ms-overflow-style:none;overflow-x:auto;padding-inline:var(--rt-tabs-list-padding-inline);scrollbar-width:none;white-space:nowrap}.rt-tabs__tab-list::-webkit-scrollbar{display:none}.rt-tabs__tab-list--direction--horizontal{width:100%;flex-direction:row}.rt-tabs__tab-list--direction--vertical{flex-direction:column;border-right:var(--rt-tabs-border-width) solid var(--rt-color-border-default);border-bottom:0}.rt-tabs__tab-list--stretch{justify-content:space-between}.rt-tabs__tab-list--more{overflow-x:clip}.rt-tabs__tab-list--ink .rt-tab-item--selected:not(.rt-tab-item--invalid):after{background-color:transparent}.rt-tabs__ink{position:absolute;top:0;left:0;display:none;height:2px;margin-top:var(--rt-tabs-border-width);background-color:var(--rt-color-action-primary);pointer-events:none;transform:translateY(-100%)}.rt-tabs__ink--placed{display:block}.rt-tabs__ink--animated{transition:translate var(--rt-tabs-indicator-duration) var(--rt-tabs-indicator-easing),width var(--rt-tabs-indicator-duration) var(--rt-tabs-indicator-easing)}.rt-tabs__ink--invalid{background-color:var(--rt-color-state-danger)}.rt-tabs__controls{display:flex;flex-shrink:0;align-items:center}.rt-tabs__controls--before{padding-right:var(--rt-space-md)}.rt-tabs__controls--after{padding-left:var(--rt-space-md)}.rt-tabs__content{display:flex;min-height:0;flex:1 1 auto;flex-direction:column;padding-top:var(--rt-tabs-content-padding-top);gap:var(--rt-space-md);line-height:var(--rt-leading-relaxed)}.rt-tabs__content--scrollable{overflow:auto}.rt-tabs__content--idle{display:none}.rt-tabs__content--leaving{position:absolute;right:0;bottom:0;animation:rt-tabs-panel-leave var(--rt-tabs-panel-duration) var(--rt-tabs-panel-easing) forwards;pointer-events:none}.rt-tabs__content--entering{animation:rt-tabs-panel-enter var(--rt-tabs-panel-duration) var(--rt-tabs-panel-easing)}.rt-tabs__content--shift--forward{--rt-tabs-panel-leave-to: -100%;--rt-tabs-panel-enter-from: 100%}.rt-tabs__content--shift--backward{--rt-tabs-panel-leave-to: 100%;--rt-tabs-panel-enter-from: -100%}@keyframes rt-tabs-panel-leave{to{translate:var(--rt-tabs-panel-leave-to) 0}}@keyframes rt-tabs-panel-enter{0%{translate:var(--rt-tabs-panel-enter-from) 0}}@media(prefers-reduced-motion:reduce){.rt-tabs__ink--animated{transition:none}.rt-tabs__content--leaving,.rt-tabs__content--entering{animation:none}}.rt-tab-item{--rt-tab-item-border-width: var(--rt-border-width-thin);--rt-tab-item-badge-radius: var(--rt-radius-full);--rt-tab-item-transition-duration: var(--rt-duration-fast);--rt-tab-item-close-size: var(--rt-size-5);--rt-tab-item-close-radius: var(--rt-radius-full);--rt-tab-item-close-bg: transparent;--rt-tab-item-close-bg-hover: var(--rt-color-bg-hover);--rt-tab-item-close-color: var(--rt-color-text-muted);--rt-tab-item-close-color-hover: var(--rt-color-text-primary);--rt-tab-item-close-icon-size: var(--rt-icon-step-xs);--rt-tab-item-close-margin-inline-start: 0;--rt-tab-item-close-margin-inline-end: calc(-1 * var(--rt-space-2));position:relative;display:inline-flex;align-items:center;justify-content:center;margin:0;background-color:transparent;color:var(--rt-color-text-muted);cursor:pointer;font-family:inherit;font-size:var(--rt-text-sm);font-weight:var(--rt-font-weight-semibold);gap:var(--rt-space-sm);line-height:var(--rt-leading-none);transition:color var(--rt-tab-item-transition-duration) linear,background-color var(--rt-tab-item-transition-duration) linear;white-space:nowrap}.rt-tab-item:after{position:absolute;bottom:0;height:2px;background-color:transparent;content:\"\";inset-inline:0;pointer-events:none;translate:0 var(--rt-tab-item-border-width)}.rt-tab-item--in-more{position:absolute;top:0;left:0;visibility:hidden}.rt-tab-item:hover:not(.rt-tab-item--disabled,.rt-tab-item--selected){background-color:var(--rt-color-bg-hover);color:var(--rt-color-text-primary)}.rt-tab-item:has(>.rt-tab-item__trigger:focus-visible){outline:2px solid var(--rt-color-action-primary);outline-offset:-3px}.rt-tab-item__trigger{display:inline-flex;min-width:0;align-items:center;justify-content:center;padding:var(--rt-space-2) var(--rt-space-4);border:0;margin:0;background:none;color:inherit;cursor:inherit;font:inherit;gap:inherit;line-height:inherit;outline:none}.rt-tab-item__trigger--closable{padding-inline-end:0}.rt-tabs--dense .rt-tab-item__trigger{padding-inline:var(--rt-space-2)}.rt-tab-item__title{overflow:hidden;max-width:200px;text-overflow:ellipsis}.rt-tab-item__icon{flex-shrink:0}.rt-tab-item__icon-box{position:relative;display:inline-flex;flex-shrink:0}.rt-tab-item__badge{display:inline-flex;min-width:18px;height:18px;align-items:center;justify-content:center;padding:0 var(--rt-space-2);border-radius:var(--rt-tab-item-badge-radius);background-color:var(--rt-color-bg-surface-subtle);color:var(--rt-color-text-muted);font-size:var(--rt-text-xs);font-weight:var(--rt-font-weight-medium);line-height:var(--rt-leading-none)}.rt-tab-item__badge--overlay{position:absolute;top:calc(-1 * var(--rt-space-2));right:calc(-1 * (var(--rt-space-1) + var(--rt-space-0-5)));min-width:var(--rt-size-4);height:var(--rt-size-4);box-sizing:border-box;padding:0 var(--rt-space-1);background-color:var(--rt-color-action-primary);color:var(--rt-color-action-on-primary);font-size:var(--rt-text-2xs)}.rt-tab-item__close{--rt-icon-step-xs: var(--rt-tab-item-close-icon-size);display:inline-flex;width:var(--rt-tab-item-close-size);height:var(--rt-tab-item-close-size);flex-shrink:0;align-items:center;justify-content:center;padding:0;border:0;border-radius:var(--rt-tab-item-close-radius);background-color:var(--rt-tab-item-close-bg);color:var(--rt-tab-item-close-color);cursor:pointer;font:inherit;margin-block:calc(-1 * var(--rt-space-1));margin-inline:var(--rt-tab-item-close-margin-inline-start) calc(var(--rt-space-4) + var(--rt-tab-item-close-margin-inline-end));transition:color var(--rt-tab-item-transition-duration) linear,background-color var(--rt-tab-item-transition-duration) linear}.rt-tab-item__close:hover{background-color:var(--rt-tab-item-close-bg-hover);color:var(--rt-tab-item-close-color-hover)}.rt-tab-item__close:focus-visible{outline:2px solid var(--rt-color-action-primary);outline-offset:0}.rt-tab-item--selected{color:var(--rt-color-action-primary);cursor:default}.rt-tab-item--selected .rt-tab-item__trigger{padding-block-end:calc(var(--rt-space-2) + 2px)}.rt-tab-item--selected:after{background-color:var(--rt-color-action-primary)}.rt-tab-item--selected .rt-tab-item__badge:not(.rt-tab-item__badge--overlay){background-color:var(--rt-color-action-primary-soft);color:var(--rt-color-action-primary)}.rt-tab-item--invalid{color:var(--rt-color-state-danger)}.rt-tab-item--invalid:after{background-color:var(--rt-color-state-danger)}.rt-tab-item--disabled{color:var(--rt-color-text-disabled);cursor:not-allowed}.rt-tab-item--stretch{max-width:100%;flex:1 1 auto}.rt-tabs__tab-list--measure>.rt-tab-item--stretch{flex-grow:0}}\n",
|
|
1782
|
+
"@charset \"UTF-8\";@layer rt-kit.components{.rt-tabs{--rt-tabs-arrow-size: var(--rt-size-6);--rt-tabs-arrow-inset: var(--rt-space-1);--rt-tabs-arrow-radius: var(--rt-radius-sm);--rt-tabs-arrow-shadow: var(--rt-shadow-sm);--rt-tabs-arrow-bg: var(--rt-color-bg-surface);--rt-tabs-arrow-bg-hover: var(--rt-color-bg-hover);--rt-tabs-arrow-color: var(--rt-color-text-muted);--rt-tabs-arrow-color-hover: var(--rt-color-text-primary);--rt-tabs-arrow-fade: var(--rt-color-bg-surface)}.rt-tabs__rest{position:absolute;z-index:1;top:0;bottom:0;display:flex;width:var(--rt-control-height-lg);align-items:center;justify-content:center;background-color:var(--rt-color-bg-surface);color:var(--rt-color-text-muted);cursor:pointer;transition:color var(--rt-tabs-transition-duration) linear;visibility:hidden}.rt-tabs__rest:hover{color:var(--rt-color-text-primary)}.rt-tabs__rest--before{left:0;border-right:var(--rt-tabs-border-width) solid var(--rt-color-border-default)}.rt-tabs__rest--after{right:0;border-left:var(--rt-tabs-border-width) solid var(--rt-color-border-default)}.rt-tabs__rest--visible{visibility:visible}.rt-tabs__arrow{display:contents}.rt-tabs__tab-list-wrapper--inline{align-items:stretch}.rt-tabs__tab-list-wrapper--inline .rt-tabs__rest{position:static;display:none;flex-shrink:0;border:0;border-bottom:var(--rt-tabs-border-width) solid var(--rt-color-border-default);background-color:transparent}.rt-tabs__tab-list-wrapper--inline.rt-tabs__tab-list-wrapper--overflowing .rt-tabs__rest{display:flex;visibility:visible}.rt-tabs__tab-list-wrapper--inline .rt-tabs__rest--inactive{color:var(--rt-color-text-disabled);cursor:default;pointer-events:none}.rt-tabs__tab-list-wrapper--compact .rt-tabs__rest{width:auto;border:0;padding-inline:var(--rt-tabs-arrow-inset)}.rt-tabs__tab-list-wrapper--compact .rt-tabs__rest--before{background:linear-gradient(to right,var(--rt-tabs-arrow-fade) 70%,transparent)}.rt-tabs__tab-list-wrapper--compact .rt-tabs__rest--after{background:linear-gradient(to left,var(--rt-tabs-arrow-fade) 70%,transparent)}.rt-tabs__tab-list-wrapper--compact .rt-tabs__arrow{display:flex;width:var(--rt-tabs-arrow-size);height:var(--rt-tabs-arrow-size);flex:none;align-items:center;justify-content:center;border-radius:var(--rt-tabs-arrow-radius);background-color:var(--rt-tabs-arrow-bg);box-shadow:var(--rt-tabs-arrow-shadow);color:var(--rt-tabs-arrow-color);transition:color var(--rt-tabs-transition-duration) linear,background-color var(--rt-tabs-transition-duration) linear}.rt-tabs__tab-list-wrapper--compact .rt-tabs__rest:hover .rt-tabs__arrow{background-color:var(--rt-tabs-arrow-bg-hover);color:var(--rt-tabs-arrow-color-hover)}.rt-tabs__tab-list-wrapper--compact.rt-tabs__tab-list-wrapper--inline .rt-tabs__rest{border-bottom:var(--rt-tabs-border-width) solid var(--rt-tabs-list-border-color);background:none}.rt-tabs__tab-list-wrapper--compact.rt-tabs__tab-list-wrapper--inline .rt-tabs__arrow{box-shadow:none}.rt-tabs__tab-list-wrapper--compact.rt-tabs__tab-list-wrapper--inline .rt-tabs__rest--inactive .rt-tabs__arrow{color:var(--rt-color-text-disabled)}}\n",
|
|
1783
|
+
"@charset \"UTF-8\";@layer rt-kit.components{.rt-tabs-more-menu{--rt-tabs-more-menu-radius: var(--rt-overlay-menu-radius);--rt-tabs-more-menu-border-width: var(--rt-border-width-thin);--rt-tabs-more-menu-shadow: var(--rt-overlay-menu-shadow);--rt-tabs-more-menu-row-radius: var(--rt-radius-sm);--rt-tabs-more-menu-close-radius: var(--rt-radius-full);--rt-tabs-more-menu-max-height: 282px;display:flex;overflow:hidden auto;width:var(--rt-size-60);max-height:var(--rt-tabs-more-menu-max-height);box-sizing:border-box;flex-direction:column;padding:var(--rt-overlay-menu-padding-y) var(--rt-space-xs);border:var(--rt-tabs-more-menu-border-width) solid var(--rt-color-border-subtle);border-radius:var(--rt-tabs-more-menu-radius);background:var(--rt-overlay-menu-bg);box-shadow:var(--rt-tabs-more-menu-shadow)}.rt-tabs-more-menu__row{display:flex;min-height:var(--rt-overlay-menu-item-min-height);flex:none;align-items:center;border-radius:var(--rt-tabs-more-menu-row-radius);padding-inline-end:var(--rt-space-2)}.rt-tabs-more-menu__row:hover:not(.rt-tabs-more-menu__row--disabled){background:var(--rt-color-bg-hover)}.rt-tabs-more-menu__row--disabled{opacity:var(--rt-opacity-disabled)}.rt-tabs-more-menu__row--invalid{color:var(--rt-color-state-danger)}.rt-tabs-more-menu__pick{display:flex;min-width:0;flex:1 1 auto;align-items:center;padding:var(--rt-overlay-menu-item-padding-y) var(--rt-overlay-menu-item-padding-x);border:0;background:none;color:var(--rt-color-text-primary);cursor:pointer;font-family:inherit;font-size:var(--rt-text-sm);font-weight:var(--rt-overlay-menu-item-weight);gap:var(--rt-space-sm);outline:none;text-align:start}.rt-tabs-more-menu__pick:focus-visible{background:var(--rt-color-bg-hover)}.rt-tabs-more-menu__pick[aria-disabled=true]{cursor:default}.rt-tabs-more-menu__row--invalid .rt-tabs-more-menu__pick{color:inherit}.rt-tabs-more-menu__icon{flex:none}.rt-tabs-more-menu__label{overflow:hidden;min-width:0;flex:1 1 auto;text-overflow:ellipsis;white-space:nowrap}.rt-tabs-more-menu__badge{flex:none;color:var(--rt-color-text-muted)}.rt-tabs-more-menu__close{display:inline-flex;width:var(--rt-size-5);height:var(--rt-size-5);flex:none;align-items:center;justify-content:center;padding:0;border:0;border-radius:var(--rt-tabs-more-menu-close-radius);background:transparent;color:var(--rt-color-text-muted);cursor:pointer;opacity:0}.rt-tabs-more-menu__row:hover .rt-tabs-more-menu__close,.rt-tabs-more-menu__row:focus-within .rt-tabs-more-menu__close{opacity:1}@media(hover:none){.rt-tabs-more-menu__close{opacity:1}}.rt-tabs-more-menu__close:hover{background:var(--rt-color-bg-hover);color:var(--rt-color-text-primary)}}\n"
|
|
1784
|
+
],
|
|
1157
1785
|
dependencies: [
|
|
1158
1786
|
{
|
|
1159
1787
|
kind: "directive",
|
|
@@ -1180,6 +1808,18 @@ var RtTabsComponent = class RtTabsComponent {
|
|
|
1180
1808
|
"rotate"
|
|
1181
1809
|
]
|
|
1182
1810
|
},
|
|
1811
|
+
{
|
|
1812
|
+
kind: "component",
|
|
1813
|
+
type: RtTabsContextMenuComponent,
|
|
1814
|
+
selector: "rt-tabs-context-menu"
|
|
1815
|
+
},
|
|
1816
|
+
{
|
|
1817
|
+
kind: "component",
|
|
1818
|
+
type: RtTabsMoreComponent,
|
|
1819
|
+
selector: "rt-tabs-more",
|
|
1820
|
+
inputs: ["tabs"],
|
|
1821
|
+
outputs: ["pick", "closeTab"]
|
|
1822
|
+
},
|
|
1183
1823
|
{
|
|
1184
1824
|
kind: "directive",
|
|
1185
1825
|
type: RtTooltipDirective,
|
|
@@ -1231,6 +1871,8 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
1231
1871
|
imports: [
|
|
1232
1872
|
NgTemplateOutlet,
|
|
1233
1873
|
RtIconComponent,
|
|
1874
|
+
RtTabsContextMenuComponent,
|
|
1875
|
+
RtTabsMoreComponent,
|
|
1234
1876
|
RtTooltipDirective,
|
|
1235
1877
|
BlockDirective,
|
|
1236
1878
|
ElemDirective,
|
|
@@ -1244,8 +1886,12 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
1244
1886
|
"[class.rt-tabs--dense]": "dense()",
|
|
1245
1887
|
"[style]": "panels.durations()"
|
|
1246
1888
|
},
|
|
1247
|
-
template: "<ng-container rtBlock=\"rt-tabs\">\n <div rtElem=\"header\">\n @if (leftControls().length) {\n <div rtElem=\"controls\" [rtMod]=\"{ before: true }\">\n @for (control of leftControls(); track $index) {\n <ng-container [ngTemplateOutlet]=\"control.templateRef\" />\n }\n </div>\n }\n\n <div
|
|
1248
|
-
styles: [
|
|
1889
|
+
template: "<ng-container rtBlock=\"rt-tabs\">\n <div rtElem=\"header\">\n @if (leftControls().length) {\n <div rtElem=\"controls\" [rtMod]=\"{ before: true }\">\n @for (control of leftControls(); track $index) {\n <ng-container [ngTemplateOutlet]=\"control.templateRef\" />\n }\n </div>\n }\n\n <div\n rtElem=\"tab-list-wrapper\"\n [rtMod]=\"{ inline: scrollArrows() === 'inline', overflowing: overflowing(), compact: arrowLook() === 'compact' }\">\n @if (!moreMode()) {\n <div\n rtElem=\"rest\"\n qa-dataid=\"tabs-scroll-prev\"\n [rtMod]=\"{ before: true, visible: restBeforeVisible(), inactive: !restBeforeVisible() }\"\n (mousedown)=\"onRestPointerDown('before', $event)\"\n (mouseup)=\"onRestPointerUp()\"\n (mouseleave)=\"onRestPointerLeave()\">\n <span rtElem=\"arrow\"><rt-icon name=\"chevron-left\" color=\"current\" size=\"sm\" /></span>\n </div>\n }\n\n <div\n #tabList\n rtElem=\"tab-list\"\n qa-dataid=\"tabs-tab-list\"\n role=\"tablist\"\n [rtMod]=\"{ stretch: stretch(), direction: direction(), ink: ink.box() !== null, more: moreMode() }\"\n [attr.aria-orientation]=\"direction()\"\n (scroll)=\"onTabListScroll()\">\n @for (tab of visibleTabs(); track tab.id()) {\n @let focusable = tab.id() === focusId();\n @let closeShown = tab.showClose() && (closeOn() === 'all' || tab.id() === selectedId());\n <!-- Вкладка — обёртка из двух кнопок: самой вкладки и крестика рядом с ней, не внутри,\n потому что кнопка в кнопке недопустима. Нажатие в любом месте обёртки выбирает\n вкладку; крестик своё нажатие дальше не пускает. -->\n <div\n rtBlock=\"rt-tab-item\"\n role=\"presentation\"\n [rtMod]=\"{\n selected: tab.id() === selectedId(),\n disabled: tab.disabled(),\n invalid: tab.invalid(),\n stretch: stretch(),\n inMore: more.ids().has(tab.id()),\n }\"\n [style.order]=\"more.order().get(tab.id())\"\n [attr.inert]=\"more.ids().has(tab.id()) || null\"\n [attr.data-tabitem]=\"tab.id()\"\n (click)=\"selectTab(tab.id())\"\n (contextmenu)=\"contextMenu.open($event, tab)\">\n <button\n rtElem=\"trigger\"\n qa-dataid=\"tabs-tab\"\n type=\"button\"\n role=\"tab\"\n [rtMod]=\"{ closable: closeShown }\"\n [id]=\"'rt-tab-' + tab.id()\"\n [attr.aria-disabled]=\"tab.disabled() || null\"\n [attr.aria-label]=\"tab.ariaLabel()\"\n [attr.aria-keyshortcuts]=\"closeShown ? 'Delete' : null\"\n [attr.data-tabid]=\"tab.id()\"\n [attr.aria-selected]=\"tab.id() === selectedId()\"\n [attr.aria-controls]=\"headerOnly() ? null : 'rt-tabpanel-' + tab.id()\"\n [attr.tabindex]=\"focusable ? 0 : -1\"\n [rtTooltip]=\"tab.buttonTooltip()\"\n (keydown)=\"onTabKeydown($event, tab)\">\n @if (tab.hasIcon()) {\n <span rtElem=\"icon-box\">\n <rt-icon\n rtElem=\"icon\"\n size=\"sm\"\n [name]=\"tab.shownIcon()\"\n [glyph]=\"tab.glyph()\"\n [color]=\"tab.iconColor()\"\n [fill]=\"tab.iconFill()\" />\n @if (tab.badgeOverlay()) {\n <!-- prettier-ignore -->\n <span rtElem=\"badge\" [rtMod]=\"{ overlay: true }\" [rtTooltip]=\"tab.badgeTitle()\" [attr.aria-label]=\"tab.badgeAriaLabel() || null\">{{ tab.badge() }}</span>\n }\n </span>\n }\n\n @if (tab.titleTemplate(); as titleTpl) {\n <ng-container [ngTemplateOutlet]=\"titleTpl\" />\n } @else if (tab.label()) {\n <!-- Пустая подпись не рисуется: её зазор сдвигал значок вкладки без подписи с середины. -->\n <span rtElem=\"title\">{{ tab.label() }}</span>\n }\n\n @if (tab.badge() !== null && !tab.badgeOverlay()) {\n <!-- В одну строку: перенос внутри добавил бы пробел в текст кнопки. -->\n <!-- prettier-ignore -->\n <span rtElem=\"badge\" [rtTooltip]=\"tab.badgeTitle()\" [attr.aria-label]=\"tab.badgeAriaLabel() || null\">{{ tab.badge() }}</span>\n }\n </button>\n\n @if (closeShown) {\n <!-- В таб-порядке только у вкладки в фокусе: Tab с неё идёт на её крестик, дальше — из полосы. -->\n <button\n rtElem=\"close\"\n qa-dataid=\"tabs-tab-close\"\n type=\"button\"\n [attr.aria-label]=\"tab.closeLabel()\"\n [attr.tabindex]=\"focusable ? 0 : -1\"\n [rtTooltip]=\"tab.closeTooltip()\"\n [rtTooltipPlacement]=\"tab.closeTooltipPlacement()\"\n (mouseenter)=\"tab.closeHovered.set(true)\"\n (mouseleave)=\"tab.closeHovered.set(false)\"\n (click)=\"onCloseClick($event, tab)\">\n <rt-icon name=\"close\" color=\"current\" size=\"xs\" />\n </button>\n }\n </div>\n }\n\n @if (moreMode()) {\n <rt-tabs-more [tabs]=\"more.moreTabs()\" (pick)=\"selectTab($event)\" (closeTab)=\"onMoreClose($event)\" />\n }\n\n <!-- Полоса выбранной вкладки — одна на всю полосу: так она переезжает между вкладками. -->\n <span\n rtElem=\"ink\"\n aria-hidden=\"true\"\n [rtMod]=\"{ placed: ink.box() !== null, animated: ink.animated(), invalid: ink.invalid() }\"\n [style.width.px]=\"ink.box()?.width\"\n [style.translate]=\"ink.translate()\"></span>\n </div>\n\n @if (!moreMode()) {\n <div\n rtElem=\"rest\"\n qa-dataid=\"tabs-scroll-next\"\n [rtMod]=\"{ after: true, visible: restAfterVisible(), inactive: !restAfterVisible() }\"\n (mousedown)=\"onRestPointerDown('after', $event)\"\n (mouseup)=\"onRestPointerUp()\"\n (mouseleave)=\"onRestPointerLeave()\">\n <span rtElem=\"arrow\"><rt-icon name=\"chevron-right\" color=\"current\" size=\"sm\" /></span>\n </div>\n }\n </div>\n\n @if (rightControls().length) {\n <div rtElem=\"controls\" [rtMod]=\"{ after: true }\">\n @for (control of rightControls(); track $index) {\n <ng-container [ngTemplateOutlet]=\"control.templateRef\" />\n }\n </div>\n }\n </div>\n\n <rt-tabs-context-menu #contextMenu />\n\n <!-- Уходящая панель стоит поверх: место ей задаёт замер, сделанный до смены. Сохранённые\n тела посещённых вкладок скрыты и вне таб-порядка. -->\n @for (panel of panels.list(); track panel.tab.id()) {\n @let current = panel.leaving === null && !panel.idle;\n <div\n rtElem=\"content\"\n role=\"tabpanel\"\n [attr.qa-dataid]=\"current ? 'tabs-panel' : panel.idle ? 'tabs-panel-idle' : 'tabs-panel-leaving'\"\n [attr.tabindex]=\"current ? contentTabIndex() : -1\"\n [attr.aria-hidden]=\"current ? null : 'true'\"\n [attr.inert]=\"current ? null : ''\"\n [hidden]=\"panel.idle\"\n [rtMod]=\"{\n scrollable: contentScrollable(),\n idle: panel.idle,\n leaving: panel.leaving !== null,\n entering: current && panels.shift() !== null,\n shift: panels.shift(),\n }\"\n [style.top.px]=\"panel.leaving?.top\"\n [style.left.px]=\"panel.leaving?.left\"\n [id]=\"'rt-tabpanel-' + panel.tab.id()\"\n [attr.aria-labelledby]=\"'rt-tab-' + panel.tab.id()\"\n (animationend)=\"panels.animationEnd($event)\"\n (animationcancel)=\"panels.animationEnd($event)\">\n <ng-container [ngTemplateOutlet]=\"panel.tab.templateRef\" />\n </div>\n }\n</ng-container>\n",
|
|
1890
|
+
styles: [
|
|
1891
|
+
"@charset \"UTF-8\";@layer rt-kit.components{.rt-tabs{--rt-tabs-border-width: var(--rt-border-width-thin);--rt-tabs-transition-duration: var(--rt-duration-fast);--rt-tabs-list-align: stretch;--rt-tabs-list-border-color: var(--rt-color-border-default);--rt-tabs-list-min-height: auto;--rt-tabs-list-padding-inline: 0;--rt-tabs-content-padding-top: var(--rt-space-md);display:flex;-webkit-tap-highlight-color:transparent}.rt-tabs--direction--horizontal{flex-direction:column}.rt-tabs--direction--vertical{flex-direction:row}.rt-tabs--animating{position:relative;overflow-x:clip}.rt-tabs__header{display:flex;align-items:center}.rt-tabs__tab-list-wrapper{position:relative;display:flex;overflow:hidden;flex:1 1 auto;align-items:center}.rt-tabs__tab-list{position:relative;display:flex;box-sizing:border-box;align-items:var(--rt-tabs-list-align);border-bottom:var(--rt-tabs-border-width) solid var(--rt-tabs-list-border-color);margin:0;min-block-size:var(--rt-tabs-list-min-height);-ms-overflow-style:none;overflow-x:auto;padding-inline:var(--rt-tabs-list-padding-inline);scrollbar-width:none;white-space:nowrap}.rt-tabs__tab-list::-webkit-scrollbar{display:none}.rt-tabs__tab-list--direction--horizontal{width:100%;flex-direction:row}.rt-tabs__tab-list--direction--vertical{flex-direction:column;border-right:var(--rt-tabs-border-width) solid var(--rt-color-border-default);border-bottom:0}.rt-tabs__tab-list--stretch{justify-content:space-between}.rt-tabs__tab-list--more{overflow-x:clip}.rt-tabs__tab-list--ink .rt-tab-item--selected:not(.rt-tab-item--invalid):after{background-color:transparent}.rt-tabs__ink{position:absolute;top:0;left:0;display:none;height:2px;margin-top:var(--rt-tabs-border-width);background-color:var(--rt-color-action-primary);pointer-events:none;transform:translateY(-100%)}.rt-tabs__ink--placed{display:block}.rt-tabs__ink--animated{transition:translate var(--rt-tabs-indicator-duration) var(--rt-tabs-indicator-easing),width var(--rt-tabs-indicator-duration) var(--rt-tabs-indicator-easing)}.rt-tabs__ink--invalid{background-color:var(--rt-color-state-danger)}.rt-tabs__controls{display:flex;flex-shrink:0;align-items:center}.rt-tabs__controls--before{padding-right:var(--rt-space-md)}.rt-tabs__controls--after{padding-left:var(--rt-space-md)}.rt-tabs__content{display:flex;min-height:0;flex:1 1 auto;flex-direction:column;padding-top:var(--rt-tabs-content-padding-top);gap:var(--rt-space-md);line-height:var(--rt-leading-relaxed)}.rt-tabs__content--scrollable{overflow:auto}.rt-tabs__content--idle{display:none}.rt-tabs__content--leaving{position:absolute;right:0;bottom:0;animation:rt-tabs-panel-leave var(--rt-tabs-panel-duration) var(--rt-tabs-panel-easing) forwards;pointer-events:none}.rt-tabs__content--entering{animation:rt-tabs-panel-enter var(--rt-tabs-panel-duration) var(--rt-tabs-panel-easing)}.rt-tabs__content--shift--forward{--rt-tabs-panel-leave-to: -100%;--rt-tabs-panel-enter-from: 100%}.rt-tabs__content--shift--backward{--rt-tabs-panel-leave-to: 100%;--rt-tabs-panel-enter-from: -100%}@keyframes rt-tabs-panel-leave{to{translate:var(--rt-tabs-panel-leave-to) 0}}@keyframes rt-tabs-panel-enter{0%{translate:var(--rt-tabs-panel-enter-from) 0}}@media(prefers-reduced-motion:reduce){.rt-tabs__ink--animated{transition:none}.rt-tabs__content--leaving,.rt-tabs__content--entering{animation:none}}.rt-tab-item{--rt-tab-item-border-width: var(--rt-border-width-thin);--rt-tab-item-badge-radius: var(--rt-radius-full);--rt-tab-item-transition-duration: var(--rt-duration-fast);--rt-tab-item-close-size: var(--rt-size-5);--rt-tab-item-close-radius: var(--rt-radius-full);--rt-tab-item-close-bg: transparent;--rt-tab-item-close-bg-hover: var(--rt-color-bg-hover);--rt-tab-item-close-color: var(--rt-color-text-muted);--rt-tab-item-close-color-hover: var(--rt-color-text-primary);--rt-tab-item-close-icon-size: var(--rt-icon-step-xs);--rt-tab-item-close-margin-inline-start: 0;--rt-tab-item-close-margin-inline-end: calc(-1 * var(--rt-space-2));position:relative;display:inline-flex;align-items:center;justify-content:center;margin:0;background-color:transparent;color:var(--rt-color-text-muted);cursor:pointer;font-family:inherit;font-size:var(--rt-text-sm);font-weight:var(--rt-font-weight-semibold);gap:var(--rt-space-sm);line-height:var(--rt-leading-none);transition:color var(--rt-tab-item-transition-duration) linear,background-color var(--rt-tab-item-transition-duration) linear;white-space:nowrap}.rt-tab-item:after{position:absolute;bottom:0;height:2px;background-color:transparent;content:\"\";inset-inline:0;pointer-events:none;translate:0 var(--rt-tab-item-border-width)}.rt-tab-item--in-more{position:absolute;top:0;left:0;visibility:hidden}.rt-tab-item:hover:not(.rt-tab-item--disabled,.rt-tab-item--selected){background-color:var(--rt-color-bg-hover);color:var(--rt-color-text-primary)}.rt-tab-item:has(>.rt-tab-item__trigger:focus-visible){outline:2px solid var(--rt-color-action-primary);outline-offset:-3px}.rt-tab-item__trigger{display:inline-flex;min-width:0;align-items:center;justify-content:center;padding:var(--rt-space-2) var(--rt-space-4);border:0;margin:0;background:none;color:inherit;cursor:inherit;font:inherit;gap:inherit;line-height:inherit;outline:none}.rt-tab-item__trigger--closable{padding-inline-end:0}.rt-tabs--dense .rt-tab-item__trigger{padding-inline:var(--rt-space-2)}.rt-tab-item__title{overflow:hidden;max-width:200px;text-overflow:ellipsis}.rt-tab-item__icon{flex-shrink:0}.rt-tab-item__icon-box{position:relative;display:inline-flex;flex-shrink:0}.rt-tab-item__badge{display:inline-flex;min-width:18px;height:18px;align-items:center;justify-content:center;padding:0 var(--rt-space-2);border-radius:var(--rt-tab-item-badge-radius);background-color:var(--rt-color-bg-surface-subtle);color:var(--rt-color-text-muted);font-size:var(--rt-text-xs);font-weight:var(--rt-font-weight-medium);line-height:var(--rt-leading-none)}.rt-tab-item__badge--overlay{position:absolute;top:calc(-1 * var(--rt-space-2));right:calc(-1 * (var(--rt-space-1) + var(--rt-space-0-5)));min-width:var(--rt-size-4);height:var(--rt-size-4);box-sizing:border-box;padding:0 var(--rt-space-1);background-color:var(--rt-color-action-primary);color:var(--rt-color-action-on-primary);font-size:var(--rt-text-2xs)}.rt-tab-item__close{--rt-icon-step-xs: var(--rt-tab-item-close-icon-size);display:inline-flex;width:var(--rt-tab-item-close-size);height:var(--rt-tab-item-close-size);flex-shrink:0;align-items:center;justify-content:center;padding:0;border:0;border-radius:var(--rt-tab-item-close-radius);background-color:var(--rt-tab-item-close-bg);color:var(--rt-tab-item-close-color);cursor:pointer;font:inherit;margin-block:calc(-1 * var(--rt-space-1));margin-inline:var(--rt-tab-item-close-margin-inline-start) calc(var(--rt-space-4) + var(--rt-tab-item-close-margin-inline-end));transition:color var(--rt-tab-item-transition-duration) linear,background-color var(--rt-tab-item-transition-duration) linear}.rt-tab-item__close:hover{background-color:var(--rt-tab-item-close-bg-hover);color:var(--rt-tab-item-close-color-hover)}.rt-tab-item__close:focus-visible{outline:2px solid var(--rt-color-action-primary);outline-offset:0}.rt-tab-item--selected{color:var(--rt-color-action-primary);cursor:default}.rt-tab-item--selected .rt-tab-item__trigger{padding-block-end:calc(var(--rt-space-2) + 2px)}.rt-tab-item--selected:after{background-color:var(--rt-color-action-primary)}.rt-tab-item--selected .rt-tab-item__badge:not(.rt-tab-item__badge--overlay){background-color:var(--rt-color-action-primary-soft);color:var(--rt-color-action-primary)}.rt-tab-item--invalid{color:var(--rt-color-state-danger)}.rt-tab-item--invalid:after{background-color:var(--rt-color-state-danger)}.rt-tab-item--disabled{color:var(--rt-color-text-disabled);cursor:not-allowed}.rt-tab-item--stretch{max-width:100%;flex:1 1 auto}.rt-tabs__tab-list--measure>.rt-tab-item--stretch{flex-grow:0}}\n",
|
|
1892
|
+
"@charset \"UTF-8\";@layer rt-kit.components{.rt-tabs{--rt-tabs-arrow-size: var(--rt-size-6);--rt-tabs-arrow-inset: var(--rt-space-1);--rt-tabs-arrow-radius: var(--rt-radius-sm);--rt-tabs-arrow-shadow: var(--rt-shadow-sm);--rt-tabs-arrow-bg: var(--rt-color-bg-surface);--rt-tabs-arrow-bg-hover: var(--rt-color-bg-hover);--rt-tabs-arrow-color: var(--rt-color-text-muted);--rt-tabs-arrow-color-hover: var(--rt-color-text-primary);--rt-tabs-arrow-fade: var(--rt-color-bg-surface)}.rt-tabs__rest{position:absolute;z-index:1;top:0;bottom:0;display:flex;width:var(--rt-control-height-lg);align-items:center;justify-content:center;background-color:var(--rt-color-bg-surface);color:var(--rt-color-text-muted);cursor:pointer;transition:color var(--rt-tabs-transition-duration) linear;visibility:hidden}.rt-tabs__rest:hover{color:var(--rt-color-text-primary)}.rt-tabs__rest--before{left:0;border-right:var(--rt-tabs-border-width) solid var(--rt-color-border-default)}.rt-tabs__rest--after{right:0;border-left:var(--rt-tabs-border-width) solid var(--rt-color-border-default)}.rt-tabs__rest--visible{visibility:visible}.rt-tabs__arrow{display:contents}.rt-tabs__tab-list-wrapper--inline{align-items:stretch}.rt-tabs__tab-list-wrapper--inline .rt-tabs__rest{position:static;display:none;flex-shrink:0;border:0;border-bottom:var(--rt-tabs-border-width) solid var(--rt-color-border-default);background-color:transparent}.rt-tabs__tab-list-wrapper--inline.rt-tabs__tab-list-wrapper--overflowing .rt-tabs__rest{display:flex;visibility:visible}.rt-tabs__tab-list-wrapper--inline .rt-tabs__rest--inactive{color:var(--rt-color-text-disabled);cursor:default;pointer-events:none}.rt-tabs__tab-list-wrapper--compact .rt-tabs__rest{width:auto;border:0;padding-inline:var(--rt-tabs-arrow-inset)}.rt-tabs__tab-list-wrapper--compact .rt-tabs__rest--before{background:linear-gradient(to right,var(--rt-tabs-arrow-fade) 70%,transparent)}.rt-tabs__tab-list-wrapper--compact .rt-tabs__rest--after{background:linear-gradient(to left,var(--rt-tabs-arrow-fade) 70%,transparent)}.rt-tabs__tab-list-wrapper--compact .rt-tabs__arrow{display:flex;width:var(--rt-tabs-arrow-size);height:var(--rt-tabs-arrow-size);flex:none;align-items:center;justify-content:center;border-radius:var(--rt-tabs-arrow-radius);background-color:var(--rt-tabs-arrow-bg);box-shadow:var(--rt-tabs-arrow-shadow);color:var(--rt-tabs-arrow-color);transition:color var(--rt-tabs-transition-duration) linear,background-color var(--rt-tabs-transition-duration) linear}.rt-tabs__tab-list-wrapper--compact .rt-tabs__rest:hover .rt-tabs__arrow{background-color:var(--rt-tabs-arrow-bg-hover);color:var(--rt-tabs-arrow-color-hover)}.rt-tabs__tab-list-wrapper--compact.rt-tabs__tab-list-wrapper--inline .rt-tabs__rest{border-bottom:var(--rt-tabs-border-width) solid var(--rt-tabs-list-border-color);background:none}.rt-tabs__tab-list-wrapper--compact.rt-tabs__tab-list-wrapper--inline .rt-tabs__arrow{box-shadow:none}.rt-tabs__tab-list-wrapper--compact.rt-tabs__tab-list-wrapper--inline .rt-tabs__rest--inactive .rt-tabs__arrow{color:var(--rt-color-text-disabled)}}\n",
|
|
1893
|
+
"@charset \"UTF-8\";@layer rt-kit.components{.rt-tabs-more-menu{--rt-tabs-more-menu-radius: var(--rt-overlay-menu-radius);--rt-tabs-more-menu-border-width: var(--rt-border-width-thin);--rt-tabs-more-menu-shadow: var(--rt-overlay-menu-shadow);--rt-tabs-more-menu-row-radius: var(--rt-radius-sm);--rt-tabs-more-menu-close-radius: var(--rt-radius-full);--rt-tabs-more-menu-max-height: 282px;display:flex;overflow:hidden auto;width:var(--rt-size-60);max-height:var(--rt-tabs-more-menu-max-height);box-sizing:border-box;flex-direction:column;padding:var(--rt-overlay-menu-padding-y) var(--rt-space-xs);border:var(--rt-tabs-more-menu-border-width) solid var(--rt-color-border-subtle);border-radius:var(--rt-tabs-more-menu-radius);background:var(--rt-overlay-menu-bg);box-shadow:var(--rt-tabs-more-menu-shadow)}.rt-tabs-more-menu__row{display:flex;min-height:var(--rt-overlay-menu-item-min-height);flex:none;align-items:center;border-radius:var(--rt-tabs-more-menu-row-radius);padding-inline-end:var(--rt-space-2)}.rt-tabs-more-menu__row:hover:not(.rt-tabs-more-menu__row--disabled){background:var(--rt-color-bg-hover)}.rt-tabs-more-menu__row--disabled{opacity:var(--rt-opacity-disabled)}.rt-tabs-more-menu__row--invalid{color:var(--rt-color-state-danger)}.rt-tabs-more-menu__pick{display:flex;min-width:0;flex:1 1 auto;align-items:center;padding:var(--rt-overlay-menu-item-padding-y) var(--rt-overlay-menu-item-padding-x);border:0;background:none;color:var(--rt-color-text-primary);cursor:pointer;font-family:inherit;font-size:var(--rt-text-sm);font-weight:var(--rt-overlay-menu-item-weight);gap:var(--rt-space-sm);outline:none;text-align:start}.rt-tabs-more-menu__pick:focus-visible{background:var(--rt-color-bg-hover)}.rt-tabs-more-menu__pick[aria-disabled=true]{cursor:default}.rt-tabs-more-menu__row--invalid .rt-tabs-more-menu__pick{color:inherit}.rt-tabs-more-menu__icon{flex:none}.rt-tabs-more-menu__label{overflow:hidden;min-width:0;flex:1 1 auto;text-overflow:ellipsis;white-space:nowrap}.rt-tabs-more-menu__badge{flex:none;color:var(--rt-color-text-muted)}.rt-tabs-more-menu__close{display:inline-flex;width:var(--rt-size-5);height:var(--rt-size-5);flex:none;align-items:center;justify-content:center;padding:0;border:0;border-radius:var(--rt-tabs-more-menu-close-radius);background:transparent;color:var(--rt-color-text-muted);cursor:pointer;opacity:0}.rt-tabs-more-menu__row:hover .rt-tabs-more-menu__close,.rt-tabs-more-menu__row:focus-within .rt-tabs-more-menu__close{opacity:1}@media(hover:none){.rt-tabs-more-menu__close{opacity:1}}.rt-tabs-more-menu__close:hover{background:var(--rt-color-bg-hover);color:var(--rt-color-text-primary)}}\n"
|
|
1894
|
+
]
|
|
1249
1895
|
}]
|
|
1250
1896
|
}],
|
|
1251
1897
|
ctorParameters: () => [],
|
|
@@ -1294,6 +1940,14 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
1294
1940
|
required: false
|
|
1295
1941
|
}]
|
|
1296
1942
|
}],
|
|
1943
|
+
closeOn: [{
|
|
1944
|
+
type: i0.Input,
|
|
1945
|
+
args: [{
|
|
1946
|
+
isSignal: true,
|
|
1947
|
+
alias: "closeOn",
|
|
1948
|
+
required: false
|
|
1949
|
+
}]
|
|
1950
|
+
}],
|
|
1297
1951
|
contentScrollable: [{
|
|
1298
1952
|
type: i0.Input,
|
|
1299
1953
|
args: [{
|
|
@@ -1326,6 +1980,22 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
1326
1980
|
required: false
|
|
1327
1981
|
}]
|
|
1328
1982
|
}],
|
|
1983
|
+
overflow: [{
|
|
1984
|
+
type: i0.Input,
|
|
1985
|
+
args: [{
|
|
1986
|
+
isSignal: true,
|
|
1987
|
+
alias: "overflow",
|
|
1988
|
+
required: false
|
|
1989
|
+
}]
|
|
1990
|
+
}],
|
|
1991
|
+
moreLimit: [{
|
|
1992
|
+
type: i0.Input,
|
|
1993
|
+
args: [{
|
|
1994
|
+
isSignal: true,
|
|
1995
|
+
alias: "moreLimit",
|
|
1996
|
+
required: false
|
|
1997
|
+
}]
|
|
1998
|
+
}],
|
|
1329
1999
|
scrollArrows: [{
|
|
1330
2000
|
type: i0.Input,
|
|
1331
2001
|
args: [{
|
|
@@ -1334,6 +2004,14 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
1334
2004
|
required: false
|
|
1335
2005
|
}]
|
|
1336
2006
|
}],
|
|
2007
|
+
arrowLook: [{
|
|
2008
|
+
type: i0.Input,
|
|
2009
|
+
args: [{
|
|
2010
|
+
isSignal: true,
|
|
2011
|
+
alias: "arrowLook",
|
|
2012
|
+
required: false
|
|
2013
|
+
}]
|
|
2014
|
+
}],
|
|
1337
2015
|
scrollStep: [{
|
|
1338
2016
|
type: i0.Input,
|
|
1339
2017
|
args: [{
|