@akcelik/strct 0.1.0 → 0.2.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/README.md +2 -0
- package/fesm2022/akcelik-strct.mjs +636 -77
- package/fesm2022/akcelik-strct.mjs.map +1 -1
- package/package.json +1 -1
- package/types/akcelik-strct.d.ts +191 -16
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { inject, DOCUMENT, signal, computed, Injectable, input, ViewEncapsulation, ChangeDetectionStrategy, Component, ElementRef, NgZone, afterNextRender, Directive, booleanAttribute, output, HostListener, model, contentChildren, effect, forwardRef, TemplateRef, contentChild, Renderer2 } from '@angular/core';
|
|
2
|
+
import { inject, DOCUMENT, signal, computed, Injectable, input, ViewEncapsulation, ChangeDetectionStrategy, Component, ElementRef, NgZone, afterNextRender, Directive, booleanAttribute, output, HostListener, model, contentChildren, effect, ApplicationRef, EnvironmentInjector, createComponent, forwardRef, TemplateRef, contentChild, Renderer2 } from '@angular/core';
|
|
3
3
|
import { DomSanitizer } from '@angular/platform-browser';
|
|
4
|
+
import { DOCUMENT as DOCUMENT$1, NgTemplateOutlet } from '@angular/common';
|
|
4
5
|
import { NG_VALUE_ACCESSOR } from '@angular/forms';
|
|
5
|
-
import { NgTemplateOutlet } from '@angular/common';
|
|
6
6
|
|
|
7
7
|
/** All palettes the token system ships with, in display order. */
|
|
8
8
|
const STRCT_PALETTES = [
|
|
@@ -1116,45 +1116,72 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImpo
|
|
|
1116
1116
|
`, host: { class: 'strct-tabs' }, styles: [".strct-tabs{display:block}.strct-tabs__bar{display:flex;gap:2px;border-bottom:1px solid var(--b2)}.strct-tabs__btn{appearance:none;border:0;background:transparent;cursor:pointer;font-family:var(--font);font-size:13px;font-weight:500;color:var(--t2);padding:9px 14px;border-bottom:2px solid transparent;margin-bottom:-1px;transition:color .14s ease,border-color .14s ease}.strct-tabs__btn:hover{color:var(--t1)}.strct-tabs__btn--active{color:var(--acc);border-bottom-color:var(--acc)}.strct-tabs__btn:disabled{color:var(--t4);cursor:not-allowed}.strct-tabs__panels{padding-top:16px}\n"] }]
|
|
1117
1117
|
}], ctorParameters: () => [], propDecorators: { tabs: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => StrctTab), { isSignal: true }] }] } });
|
|
1118
1118
|
|
|
1119
|
-
/** Root container for a tree of `<strct-tree-node>` items. */
|
|
1120
|
-
class StrctTree {
|
|
1121
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: StrctTree, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1122
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.16", type: StrctTree, isStandalone: true, selector: "strct-tree", host: { attributes: { "role": "tree" }, classAttribute: "strct-tree" }, ngImport: i0, template: `<ng-content />`, isInline: true, styles: [".strct-tree{display:block}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
1123
|
-
}
|
|
1124
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: StrctTree, decorators: [{
|
|
1125
|
-
type: Component,
|
|
1126
|
-
args: [{ selector: 'strct-tree', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: `<ng-content />`, host: { class: 'strct-tree', role: 'tree' }, styles: [".strct-tree{display:block}\n"] }]
|
|
1127
|
-
}] });
|
|
1128
1119
|
/**
|
|
1129
|
-
* Tree node.
|
|
1130
|
-
*
|
|
1131
|
-
*
|
|
1120
|
+
* Tree node. Two modes:
|
|
1121
|
+
* - **Content:** nest `<strct-tree-node>` children manually.
|
|
1122
|
+
* - **Data:** pass a `[node]` object that recurses over its `children` —
|
|
1123
|
+
* used internally by `<strct-tree [nodes]>`.
|
|
1124
|
+
*
|
|
1125
|
+
* <strct-tree-node label="Group" icon="layers" badge="ok" [(expanded)]="open">
|
|
1126
|
+
* <strct-tree-node label="Leaf" icon="vm" [active]="true" />
|
|
1132
1127
|
* </strct-tree-node>
|
|
1133
1128
|
*/
|
|
1134
1129
|
class StrctTreeNode {
|
|
1135
|
-
|
|
1130
|
+
/** Data-driven node; when set, label/icon/children come from it. */
|
|
1131
|
+
node = input(null, ...(ngDevMode ? [{ debugName: "node" }] : /* istanbul ignore next */ []));
|
|
1132
|
+
label = input('', ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
1136
1133
|
icon = input(undefined, ...(ngDevMode ? [{ debugName: "icon" }] : /* istanbul ignore next */ []));
|
|
1134
|
+
badge = input('none', ...(ngDevMode ? [{ debugName: "badge" }] : /* istanbul ignore next */ []));
|
|
1137
1135
|
active = input(false, ...(ngDevMode ? [{ debugName: "active" }] : /* istanbul ignore next */ []));
|
|
1138
1136
|
expanded = model(false, ...(ngDevMode ? [{ debugName: "expanded" }] : /* istanbul ignore next */ []));
|
|
1137
|
+
/** Content-mode click. */
|
|
1139
1138
|
activated = output();
|
|
1139
|
+
/** Data-mode click — carries the activated node (bubbles to the tree). */
|
|
1140
|
+
nodeActivated = output();
|
|
1140
1141
|
childNodes = contentChildren(StrctTreeNode, ...(ngDevMode ? [{ debugName: "childNodes" }] : /* istanbul ignore next */ []));
|
|
1141
|
-
|
|
1142
|
+
/** Data-mode expansion (seeded from node.expanded on first toggle). */
|
|
1143
|
+
dataExpanded = signal(null, ...(ngDevMode ? [{ debugName: "dataExpanded" }] : /* istanbul ignore next */ []));
|
|
1144
|
+
displayLabel = computed(() => this.node()?.label ?? this.label(), ...(ngDevMode ? [{ debugName: "displayLabel" }] : /* istanbul ignore next */ []));
|
|
1145
|
+
displayIcon = computed(() => this.node()?.icon ?? this.icon(), ...(ngDevMode ? [{ debugName: "displayIcon" }] : /* istanbul ignore next */ []));
|
|
1146
|
+
displayBadge = computed(() => this.node()?.badge ?? this.badge(), ...(ngDevMode ? [{ debugName: "displayBadge" }] : /* istanbul ignore next */ []));
|
|
1147
|
+
displayActive = computed(() => this.node()?.active ?? this.active(), ...(ngDevMode ? [{ debugName: "displayActive" }] : /* istanbul ignore next */ []));
|
|
1148
|
+
hasChildren = computed(() => {
|
|
1149
|
+
const n = this.node();
|
|
1150
|
+
return n ? (n.children?.length ?? 0) > 0 : this.childNodes().length > 0;
|
|
1151
|
+
}, ...(ngDevMode ? [{ debugName: "hasChildren" }] : /* istanbul ignore next */ []));
|
|
1152
|
+
isOpen = computed(() => {
|
|
1153
|
+
if (this.node())
|
|
1154
|
+
return this.dataExpanded() ?? this.node().expanded ?? false;
|
|
1155
|
+
return this.expanded();
|
|
1156
|
+
}, ...(ngDevMode ? [{ debugName: "isOpen" }] : /* istanbul ignore next */ []));
|
|
1142
1157
|
toggle() {
|
|
1143
|
-
this.
|
|
1158
|
+
if (this.node()) {
|
|
1159
|
+
this.dataExpanded.set(!this.isOpen());
|
|
1160
|
+
}
|
|
1161
|
+
else {
|
|
1162
|
+
this.expanded.update((v) => !v);
|
|
1163
|
+
}
|
|
1164
|
+
}
|
|
1165
|
+
onActivate() {
|
|
1166
|
+
const n = this.node();
|
|
1167
|
+
if (n)
|
|
1168
|
+
this.nodeActivated.emit(n);
|
|
1169
|
+
else
|
|
1170
|
+
this.activated.emit();
|
|
1144
1171
|
}
|
|
1145
1172
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: StrctTreeNode, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1146
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.16", type: StrctTreeNode, isStandalone: true, selector: "strct-tree-node", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired:
|
|
1173
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.16", type: StrctTreeNode, isStandalone: true, selector: "strct-tree-node", inputs: { node: { classPropertyName: "node", publicName: "node", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, badge: { classPropertyName: "badge", publicName: "badge", isSignal: true, isRequired: false, transformFunction: null }, active: { classPropertyName: "active", publicName: "active", isSignal: true, isRequired: false, transformFunction: null }, expanded: { classPropertyName: "expanded", publicName: "expanded", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { expanded: "expandedChange", activated: "activated", nodeActivated: "nodeActivated" }, host: { classAttribute: "strct-tnode" }, queries: [{ propertyName: "childNodes", predicate: StrctTreeNode, isSignal: true }], ngImport: i0, template: `
|
|
1147
1174
|
<div
|
|
1148
1175
|
class="strct-tnode__row"
|
|
1149
|
-
[class.strct-tnode__row--active]="
|
|
1176
|
+
[class.strct-tnode__row--active]="displayActive()"
|
|
1150
1177
|
role="treeitem"
|
|
1151
|
-
[attr.aria-expanded]="hasChildren() ?
|
|
1152
|
-
(click)="
|
|
1178
|
+
[attr.aria-expanded]="hasChildren() ? isOpen() : null"
|
|
1179
|
+
(click)="onActivate()"
|
|
1153
1180
|
>
|
|
1154
1181
|
@if (hasChildren()) {
|
|
1155
1182
|
<span
|
|
1156
1183
|
class="strct-tnode__chevron"
|
|
1157
|
-
[class.strct-tnode__chevron--open]="
|
|
1184
|
+
[class.strct-tnode__chevron--open]="isOpen()"
|
|
1158
1185
|
(click)="$event.stopPropagation(); toggle()"
|
|
1159
1186
|
>
|
|
1160
1187
|
<strct-icon name="chevronRight" [size]="12" [strokeWidth]="1.7" />
|
|
@@ -1162,33 +1189,45 @@ class StrctTreeNode {
|
|
|
1162
1189
|
} @else {
|
|
1163
1190
|
<span class="strct-tnode__spacer"></span>
|
|
1164
1191
|
}
|
|
1165
|
-
@if (
|
|
1166
|
-
<strct-icon
|
|
1192
|
+
@if (displayIcon()) {
|
|
1193
|
+
<strct-icon
|
|
1194
|
+
class="strct-tnode__icon"
|
|
1195
|
+
[name]="displayIcon()!"
|
|
1196
|
+
[size]="14"
|
|
1197
|
+
[strokeWidth]="1.3"
|
|
1198
|
+
[badge]="displayBadge()"
|
|
1199
|
+
/>
|
|
1167
1200
|
}
|
|
1168
|
-
<span class="strct-tnode__label">{{
|
|
1201
|
+
<span class="strct-tnode__label">{{ displayLabel() }}</span>
|
|
1169
1202
|
<ng-content select="[strctTreeTrailing]" />
|
|
1170
1203
|
</div>
|
|
1171
|
-
@if (hasChildren() &&
|
|
1204
|
+
@if (hasChildren() && isOpen()) {
|
|
1172
1205
|
<div class="strct-tnode__children" role="group">
|
|
1173
|
-
|
|
1206
|
+
@if (node()) {
|
|
1207
|
+
@for (child of node()!.children ?? []; track $index) {
|
|
1208
|
+
<strct-tree-node [node]="child" (nodeActivated)="nodeActivated.emit($event)" />
|
|
1209
|
+
}
|
|
1210
|
+
} @else {
|
|
1211
|
+
<ng-content />
|
|
1212
|
+
}
|
|
1174
1213
|
</div>
|
|
1175
1214
|
}
|
|
1176
|
-
`, isInline: true, styles: [".strct-tnode{display:block}.strct-tnode__row{display:flex;align-items:center;gap:7px;padding:7px 10px;border-radius:5px;cursor:pointer;font-size:13px;color:var(--t1);-webkit-user-select:none;user-select:none}.strct-tnode__row:hover{background:var(--bg-3)}.strct-tnode__row--active{background:var(--acc-m);color:var(--acc);font-weight:500}.strct-tnode__row--active .strct-tnode__icon,.strct-tnode__row--active .strct-tnode__chevron{color:var(--acc)}.strct-tnode__chevron{display:inline-flex;color:var(--t3);transition:transform .15s ease;width:14px;justify-content:center}.strct-tnode__chevron--open{transform:rotate(90deg)}.strct-tnode__spacer{width:14px;flex-shrink:0}.strct-tnode__icon{color:var(--t2);flex-shrink:0}.strct-tnode__label{flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.strct-tnode__children{margin-left:16px}\n"], dependencies: [{ kind: "component", type: StrctIcon, selector: "strct-icon", inputs: ["name", "size", "strokeWidth", "badge"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
1215
|
+
`, isInline: true, styles: [".strct-tnode{display:block}.strct-tnode__row{display:flex;align-items:center;gap:7px;padding:7px 10px;border-radius:5px;cursor:pointer;font-size:13px;color:var(--t1);-webkit-user-select:none;user-select:none}.strct-tnode__row:hover{background:var(--bg-3)}.strct-tnode__row--active{background:var(--acc-m);color:var(--acc);font-weight:500}.strct-tnode__row--active .strct-tnode__icon,.strct-tnode__row--active .strct-tnode__chevron{color:var(--acc)}.strct-tnode__chevron{display:inline-flex;color:var(--t3);transition:transform .15s ease;width:14px;justify-content:center}.strct-tnode__chevron--open{transform:rotate(90deg)}.strct-tnode__spacer{width:14px;flex-shrink:0}.strct-tnode__icon{color:var(--t2);flex-shrink:0}.strct-tnode__label{flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.strct-tnode__children{margin-left:16px}\n"], dependencies: [{ kind: "component", type: StrctTreeNode, selector: "strct-tree-node", inputs: ["node", "label", "icon", "badge", "active", "expanded"], outputs: ["expandedChange", "activated", "nodeActivated"] }, { kind: "component", type: StrctIcon, selector: "strct-icon", inputs: ["name", "size", "strokeWidth", "badge"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
1177
1216
|
}
|
|
1178
1217
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: StrctTreeNode, decorators: [{
|
|
1179
1218
|
type: Component,
|
|
1180
1219
|
args: [{ selector: 'strct-tree-node', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [StrctIcon], template: `
|
|
1181
1220
|
<div
|
|
1182
1221
|
class="strct-tnode__row"
|
|
1183
|
-
[class.strct-tnode__row--active]="
|
|
1222
|
+
[class.strct-tnode__row--active]="displayActive()"
|
|
1184
1223
|
role="treeitem"
|
|
1185
|
-
[attr.aria-expanded]="hasChildren() ?
|
|
1186
|
-
(click)="
|
|
1224
|
+
[attr.aria-expanded]="hasChildren() ? isOpen() : null"
|
|
1225
|
+
(click)="onActivate()"
|
|
1187
1226
|
>
|
|
1188
1227
|
@if (hasChildren()) {
|
|
1189
1228
|
<span
|
|
1190
1229
|
class="strct-tnode__chevron"
|
|
1191
|
-
[class.strct-tnode__chevron--open]="
|
|
1230
|
+
[class.strct-tnode__chevron--open]="isOpen()"
|
|
1192
1231
|
(click)="$event.stopPropagation(); toggle()"
|
|
1193
1232
|
>
|
|
1194
1233
|
<strct-icon name="chevronRight" [size]="12" [strokeWidth]="1.7" />
|
|
@@ -1196,19 +1235,64 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImpo
|
|
|
1196
1235
|
} @else {
|
|
1197
1236
|
<span class="strct-tnode__spacer"></span>
|
|
1198
1237
|
}
|
|
1199
|
-
@if (
|
|
1200
|
-
<strct-icon
|
|
1238
|
+
@if (displayIcon()) {
|
|
1239
|
+
<strct-icon
|
|
1240
|
+
class="strct-tnode__icon"
|
|
1241
|
+
[name]="displayIcon()!"
|
|
1242
|
+
[size]="14"
|
|
1243
|
+
[strokeWidth]="1.3"
|
|
1244
|
+
[badge]="displayBadge()"
|
|
1245
|
+
/>
|
|
1201
1246
|
}
|
|
1202
|
-
<span class="strct-tnode__label">{{
|
|
1247
|
+
<span class="strct-tnode__label">{{ displayLabel() }}</span>
|
|
1203
1248
|
<ng-content select="[strctTreeTrailing]" />
|
|
1204
1249
|
</div>
|
|
1205
|
-
@if (hasChildren() &&
|
|
1250
|
+
@if (hasChildren() && isOpen()) {
|
|
1206
1251
|
<div class="strct-tnode__children" role="group">
|
|
1207
|
-
|
|
1252
|
+
@if (node()) {
|
|
1253
|
+
@for (child of node()!.children ?? []; track $index) {
|
|
1254
|
+
<strct-tree-node [node]="child" (nodeActivated)="nodeActivated.emit($event)" />
|
|
1255
|
+
}
|
|
1256
|
+
} @else {
|
|
1257
|
+
<ng-content />
|
|
1258
|
+
}
|
|
1208
1259
|
</div>
|
|
1209
1260
|
}
|
|
1210
1261
|
`, host: { class: 'strct-tnode' }, styles: [".strct-tnode{display:block}.strct-tnode__row{display:flex;align-items:center;gap:7px;padding:7px 10px;border-radius:5px;cursor:pointer;font-size:13px;color:var(--t1);-webkit-user-select:none;user-select:none}.strct-tnode__row:hover{background:var(--bg-3)}.strct-tnode__row--active{background:var(--acc-m);color:var(--acc);font-weight:500}.strct-tnode__row--active .strct-tnode__icon,.strct-tnode__row--active .strct-tnode__chevron{color:var(--acc)}.strct-tnode__chevron{display:inline-flex;color:var(--t3);transition:transform .15s ease;width:14px;justify-content:center}.strct-tnode__chevron--open{transform:rotate(90deg)}.strct-tnode__spacer{width:14px;flex-shrink:0}.strct-tnode__icon{color:var(--t2);flex-shrink:0}.strct-tnode__label{flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.strct-tnode__children{margin-left:16px}\n"] }]
|
|
1211
|
-
}], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required:
|
|
1262
|
+
}], propDecorators: { node: [{ type: i0.Input, args: [{ isSignal: true, alias: "node", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], badge: [{ type: i0.Input, args: [{ isSignal: true, alias: "badge", required: false }] }], active: [{ type: i0.Input, args: [{ isSignal: true, alias: "active", required: false }] }], expanded: [{ type: i0.Input, args: [{ isSignal: true, alias: "expanded", required: false }] }, { type: i0.Output, args: ["expandedChange"] }], activated: [{ type: i0.Output, args: ["activated"] }], nodeActivated: [{ type: i0.Output, args: ["nodeActivated"] }], childNodes: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => StrctTreeNode), { isSignal: true }] }] } });
|
|
1263
|
+
/**
|
|
1264
|
+
* Root container for a tree. Either project `<strct-tree-node>` children, or
|
|
1265
|
+
* pass `[nodes]` for a fully data-driven, self-recursing tree:
|
|
1266
|
+
* <strct-tree [nodes]="roots" (nodeActivated)="select($event)" />
|
|
1267
|
+
*/
|
|
1268
|
+
class StrctTree {
|
|
1269
|
+
/** Data-driven node list; when set, projected content is ignored. */
|
|
1270
|
+
nodes = input(null, ...(ngDevMode ? [{ debugName: "nodes" }] : /* istanbul ignore next */ []));
|
|
1271
|
+
/** Emitted when any data-driven node is clicked. */
|
|
1272
|
+
nodeActivated = output();
|
|
1273
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: StrctTree, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1274
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.16", type: StrctTree, isStandalone: true, selector: "strct-tree", inputs: { nodes: { classPropertyName: "nodes", publicName: "nodes", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { nodeActivated: "nodeActivated" }, host: { attributes: { "role": "tree" }, classAttribute: "strct-tree" }, ngImport: i0, template: `
|
|
1275
|
+
@if (nodes(); as ns) {
|
|
1276
|
+
@for (n of ns; track $index) {
|
|
1277
|
+
<strct-tree-node [node]="n" (nodeActivated)="nodeActivated.emit($event)" />
|
|
1278
|
+
}
|
|
1279
|
+
} @else {
|
|
1280
|
+
<ng-content />
|
|
1281
|
+
}
|
|
1282
|
+
`, isInline: true, styles: [".strct-tree{display:block}\n"], dependencies: [{ kind: "component", type: StrctTreeNode, selector: "strct-tree-node", inputs: ["node", "label", "icon", "badge", "active", "expanded"], outputs: ["expandedChange", "activated", "nodeActivated"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
1283
|
+
}
|
|
1284
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: StrctTree, decorators: [{
|
|
1285
|
+
type: Component,
|
|
1286
|
+
args: [{ selector: 'strct-tree', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [StrctTreeNode], template: `
|
|
1287
|
+
@if (nodes(); as ns) {
|
|
1288
|
+
@for (n of ns; track $index) {
|
|
1289
|
+
<strct-tree-node [node]="n" (nodeActivated)="nodeActivated.emit($event)" />
|
|
1290
|
+
}
|
|
1291
|
+
} @else {
|
|
1292
|
+
<ng-content />
|
|
1293
|
+
}
|
|
1294
|
+
`, host: { class: 'strct-tree', role: 'tree' }, styles: [".strct-tree{display:block}\n"] }]
|
|
1295
|
+
}], propDecorators: { nodes: [{ type: i0.Input, args: [{ isSignal: true, alias: "nodes", required: false }] }], nodeActivated: [{ type: i0.Output, args: ["nodeActivated"] }] } });
|
|
1212
1296
|
|
|
1213
1297
|
let modalCounter = 0;
|
|
1214
1298
|
/**
|
|
@@ -1606,9 +1690,341 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImpo
|
|
|
1606
1690
|
`, host: { class: 'strct-submenu-host' }, styles: [".strct-submenu{position:relative}.strct-submenu__trigger{display:flex;align-items:center;gap:8px;padding:7px 8px 7px 10px;border-radius:5px;cursor:default;font-size:13px;color:var(--t1)}.strct-submenu__trigger:hover{background:var(--bg-3)}.strct-submenu__icon{color:var(--t2);flex-shrink:0}.strct-submenu__icon-spacer{width:14px;flex-shrink:0}.strct-submenu__label{flex:1;display:inline-flex;align-items:center;gap:8px}.strct-submenu__arrow{color:var(--t3)}.strct-submenu__panel{position:absolute;top:-5px;left:100%;z-index:1;min-width:170px;margin-left:2px;padding:4px;background:var(--bg-1);border:1px solid var(--b2);border-radius:7px;box-shadow:var(--shh);animation:strct-submenu-in .1s ease}@keyframes strct-submenu-in{0%{opacity:0;transform:translate(-4px)}}\n"] }]
|
|
1607
1691
|
}], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }] } });
|
|
1608
1692
|
|
|
1693
|
+
/**
|
|
1694
|
+
* Floating menu panel — portaled into `<body>` (so it escapes overflow /
|
|
1695
|
+
* transform clipping), positioned by its real measured size, with full keyboard
|
|
1696
|
+
* navigation and recursive submenus. Usually created by `[strctContextMenu]`,
|
|
1697
|
+
* but can be embedded directly with `submenu`.
|
|
1698
|
+
*/
|
|
1699
|
+
class StrctMenuPanel {
|
|
1700
|
+
host = inject(ElementRef);
|
|
1701
|
+
items = input.required(...(ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []));
|
|
1702
|
+
data = input(undefined, ...(ngDevMode ? [{ debugName: "data" }] : /* istanbul ignore next */ []));
|
|
1703
|
+
x = input(0, ...(ngDevMode ? [{ debugName: "x" }] : /* istanbul ignore next */ []));
|
|
1704
|
+
y = input(0, ...(ngDevMode ? [{ debugName: "y" }] : /* istanbul ignore next */ []));
|
|
1705
|
+
submenu = input(false, { ...(ngDevMode ? { debugName: "submenu" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
1706
|
+
select = output();
|
|
1707
|
+
close = output();
|
|
1708
|
+
/** ArrowLeft inside a submenu — asks the parent to close it. */
|
|
1709
|
+
back = output();
|
|
1710
|
+
posX = signal(0, ...(ngDevMode ? [{ debugName: "posX" }] : /* istanbul ignore next */ []));
|
|
1711
|
+
posY = signal(0, ...(ngDevMode ? [{ debugName: "posY" }] : /* istanbul ignore next */ []));
|
|
1712
|
+
flipLeft = signal(false, ...(ngDevMode ? [{ debugName: "flipLeft" }] : /* istanbul ignore next */ []));
|
|
1713
|
+
activeIndex = signal(0, ...(ngDevMode ? [{ debugName: "activeIndex" }] : /* istanbul ignore next */ []));
|
|
1714
|
+
openSubIndex = signal(null, ...(ngDevMode ? [{ debugName: "openSubIndex" }] : /* istanbul ignore next */ []));
|
|
1715
|
+
navIndices = computed(() => this.items()
|
|
1716
|
+
.map((it, i) => (it.divider ? -1 : i))
|
|
1717
|
+
.filter((i) => i >= 0), ...(ngDevMode ? [{ debugName: "navIndices" }] : /* istanbul ignore next */ []));
|
|
1718
|
+
constructor() {
|
|
1719
|
+
this.posX.set(this.x());
|
|
1720
|
+
this.posY.set(this.y());
|
|
1721
|
+
afterNextRender(() => {
|
|
1722
|
+
this.activeIndex.set(this.navIndices()[0] ?? 0);
|
|
1723
|
+
if (!this.submenu())
|
|
1724
|
+
this.clampToViewport();
|
|
1725
|
+
this.focusItem(this.activeIndex());
|
|
1726
|
+
});
|
|
1727
|
+
}
|
|
1728
|
+
clampToViewport() {
|
|
1729
|
+
const host = this.host.nativeElement;
|
|
1730
|
+
const w = host.offsetWidth;
|
|
1731
|
+
const h = host.offsetHeight;
|
|
1732
|
+
const vw = window.innerWidth;
|
|
1733
|
+
const vh = window.innerHeight;
|
|
1734
|
+
const m = 6;
|
|
1735
|
+
let nx = this.x();
|
|
1736
|
+
let ny = this.y();
|
|
1737
|
+
if (nx + w > vw - m)
|
|
1738
|
+
nx = Math.max(m, Math.min(this.x() - w, vw - w - m));
|
|
1739
|
+
if (ny + h > vh - m)
|
|
1740
|
+
ny = Math.max(m, vh - h - m);
|
|
1741
|
+
this.posX.set(nx);
|
|
1742
|
+
this.posY.set(ny);
|
|
1743
|
+
// Submenus of a panel near the right edge open to the left.
|
|
1744
|
+
this.flipLeft.set(nx + w > vw - 220);
|
|
1745
|
+
}
|
|
1746
|
+
focusItem(i) {
|
|
1747
|
+
this.activeIndex.set(i);
|
|
1748
|
+
this.host.nativeElement
|
|
1749
|
+
.querySelector(`.strct-menu__item[data-idx="${i}"]`)
|
|
1750
|
+
?.focus();
|
|
1751
|
+
}
|
|
1752
|
+
move(dir) {
|
|
1753
|
+
const nav = this.navIndices();
|
|
1754
|
+
if (!nav.length)
|
|
1755
|
+
return;
|
|
1756
|
+
const pos = nav.indexOf(this.activeIndex());
|
|
1757
|
+
const next = nav[(pos + dir + nav.length) % nav.length];
|
|
1758
|
+
this.openSubIndex.set(null);
|
|
1759
|
+
this.focusItem(next);
|
|
1760
|
+
}
|
|
1761
|
+
onHover(i) {
|
|
1762
|
+
this.activeIndex.set(i);
|
|
1763
|
+
const it = this.items()[i];
|
|
1764
|
+
this.openSubIndex.set(it?.children?.length ? i : null);
|
|
1765
|
+
}
|
|
1766
|
+
onLeave(i) {
|
|
1767
|
+
if (this.openSubIndex() === i)
|
|
1768
|
+
this.openSubIndex.set(null);
|
|
1769
|
+
}
|
|
1770
|
+
onItemClick(item, i, event) {
|
|
1771
|
+
event.stopPropagation();
|
|
1772
|
+
if (item.disabled)
|
|
1773
|
+
return;
|
|
1774
|
+
if (item.children?.length) {
|
|
1775
|
+
this.openSubIndex.set(this.openSubIndex() === i ? null : i);
|
|
1776
|
+
this.focusItem(i);
|
|
1777
|
+
}
|
|
1778
|
+
else {
|
|
1779
|
+
this.select.emit(item);
|
|
1780
|
+
}
|
|
1781
|
+
}
|
|
1782
|
+
closeSub() {
|
|
1783
|
+
this.openSubIndex.set(null);
|
|
1784
|
+
}
|
|
1785
|
+
onKeydown(event) {
|
|
1786
|
+
const key = event.key;
|
|
1787
|
+
const item = this.items()[this.activeIndex()];
|
|
1788
|
+
switch (key) {
|
|
1789
|
+
case 'ArrowDown':
|
|
1790
|
+
event.preventDefault();
|
|
1791
|
+
event.stopPropagation();
|
|
1792
|
+
this.move(1);
|
|
1793
|
+
break;
|
|
1794
|
+
case 'ArrowUp':
|
|
1795
|
+
event.preventDefault();
|
|
1796
|
+
event.stopPropagation();
|
|
1797
|
+
this.move(-1);
|
|
1798
|
+
break;
|
|
1799
|
+
case 'Home':
|
|
1800
|
+
event.preventDefault();
|
|
1801
|
+
event.stopPropagation();
|
|
1802
|
+
this.focusItem(this.navIndices()[0] ?? 0);
|
|
1803
|
+
break;
|
|
1804
|
+
case 'End':
|
|
1805
|
+
event.preventDefault();
|
|
1806
|
+
event.stopPropagation();
|
|
1807
|
+
this.focusItem(this.navIndices().at(-1) ?? 0);
|
|
1808
|
+
break;
|
|
1809
|
+
case 'ArrowRight':
|
|
1810
|
+
if (item?.children?.length) {
|
|
1811
|
+
event.preventDefault();
|
|
1812
|
+
event.stopPropagation();
|
|
1813
|
+
this.openSubIndex.set(this.activeIndex());
|
|
1814
|
+
}
|
|
1815
|
+
break;
|
|
1816
|
+
case 'ArrowLeft':
|
|
1817
|
+
event.preventDefault();
|
|
1818
|
+
event.stopPropagation();
|
|
1819
|
+
if (this.openSubIndex() != null)
|
|
1820
|
+
this.closeSub();
|
|
1821
|
+
else if (this.submenu())
|
|
1822
|
+
this.back.emit();
|
|
1823
|
+
break;
|
|
1824
|
+
case 'Enter':
|
|
1825
|
+
case ' ':
|
|
1826
|
+
event.preventDefault();
|
|
1827
|
+
event.stopPropagation();
|
|
1828
|
+
if (item && !item.disabled) {
|
|
1829
|
+
if (item.children?.length)
|
|
1830
|
+
this.openSubIndex.set(this.activeIndex());
|
|
1831
|
+
else
|
|
1832
|
+
this.select.emit(item);
|
|
1833
|
+
}
|
|
1834
|
+
break;
|
|
1835
|
+
case 'Escape':
|
|
1836
|
+
event.preventDefault();
|
|
1837
|
+
event.stopPropagation();
|
|
1838
|
+
this.close.emit();
|
|
1839
|
+
break;
|
|
1840
|
+
}
|
|
1841
|
+
}
|
|
1842
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: StrctMenuPanel, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1843
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.16", type: StrctMenuPanel, isStandalone: true, selector: "strct-menu-panel", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: true, transformFunction: null }, data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, x: { classPropertyName: "x", publicName: "x", isSignal: true, isRequired: false, transformFunction: null }, y: { classPropertyName: "y", publicName: "y", isSignal: true, isRequired: false, transformFunction: null }, submenu: { classPropertyName: "submenu", publicName: "submenu", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { select: "select", close: "close", back: "back" }, host: { properties: { "style.position": "submenu() ? null : 'fixed'", "style.left.px": "submenu() ? null : posX()", "style.top.px": "submenu() ? null : posY()", "style.zIndex": "submenu() ? null : 1100" }, classAttribute: "strct-menu-host" }, ngImport: i0, template: `
|
|
1844
|
+
<div class="strct-menu" role="menu" tabindex="-1" (keydown)="onKeydown($event)">
|
|
1845
|
+
@for (item of items(); track $index; let i = $index) {
|
|
1846
|
+
@if (item.divider) {
|
|
1847
|
+
<div class="strct-menu__sep" role="separator"></div>
|
|
1848
|
+
} @else {
|
|
1849
|
+
<div class="strct-menu__wrap" (mouseenter)="onHover(i)" (mouseleave)="onLeave(i)">
|
|
1850
|
+
<button
|
|
1851
|
+
type="button"
|
|
1852
|
+
class="strct-menu__item"
|
|
1853
|
+
[attr.data-idx]="i"
|
|
1854
|
+
[class.strct-menu__item--danger]="item.danger"
|
|
1855
|
+
[class.strct-menu__item--active]="i === activeIndex()"
|
|
1856
|
+
[disabled]="item.disabled"
|
|
1857
|
+
role="menuitem"
|
|
1858
|
+
[attr.aria-haspopup]="item.children?.length ? 'menu' : null"
|
|
1859
|
+
[attr.aria-expanded]="item.children?.length ? openSubIndex() === i : null"
|
|
1860
|
+
[attr.tabindex]="i === activeIndex() ? 0 : -1"
|
|
1861
|
+
(click)="onItemClick(item, i, $event)"
|
|
1862
|
+
>
|
|
1863
|
+
@if (item.icon) {
|
|
1864
|
+
<strct-icon class="strct-menu__icon" [name]="item.icon" [size]="14" [strokeWidth]="1.3" />
|
|
1865
|
+
} @else {
|
|
1866
|
+
<span class="strct-menu__icon-spacer" aria-hidden="true"></span>
|
|
1867
|
+
}
|
|
1868
|
+
<span class="strct-menu__label">{{ item.label }}</span>
|
|
1869
|
+
@if (item.children?.length) {
|
|
1870
|
+
<strct-icon class="strct-menu__arrow" name="chevronRight" [size]="12" [strokeWidth]="1.6" />
|
|
1871
|
+
}
|
|
1872
|
+
</button>
|
|
1873
|
+
@if (openSubIndex() === i && item.children?.length) {
|
|
1874
|
+
<strct-menu-panel
|
|
1875
|
+
submenu
|
|
1876
|
+
class="strct-menu__subpanel"
|
|
1877
|
+
[class.strct-menu__subpanel--flip]="flipLeft()"
|
|
1878
|
+
[items]="item.children!"
|
|
1879
|
+
[data]="data()"
|
|
1880
|
+
(select)="select.emit($event)"
|
|
1881
|
+
(close)="close.emit()"
|
|
1882
|
+
(back)="closeSub(); focusItem(i)"
|
|
1883
|
+
/>
|
|
1884
|
+
}
|
|
1885
|
+
</div>
|
|
1886
|
+
}
|
|
1887
|
+
}
|
|
1888
|
+
</div>
|
|
1889
|
+
`, isInline: true, styles: [".strct-menu-host{display:block}.strct-menu{min-width:180px;padding:4px;background:var(--bg-1);border:1px solid var(--b2);border-radius:7px;box-shadow:var(--shh);animation:strct-menu-in .1s ease}.strct-menu:focus{outline:none}.strct-menu__wrap{position:relative}.strct-menu__item{display:flex;align-items:center;gap:8px;width:100%;padding:7px 8px 7px 10px;border:0;border-radius:5px;cursor:pointer;background:transparent;color:var(--t1);font-size:13px;font-family:var(--font);text-align:left}.strct-menu__item:hover:not(:disabled),.strct-menu__item--active:not(:disabled){background:var(--bg-3)}.strct-menu__item:focus-visible{outline:none;background:var(--bg-3)}.strct-menu__item--danger{color:var(--crt)}.strct-menu__item--danger:hover:not(:disabled),.strct-menu__item--danger.strct-menu__item--active:not(:disabled){background:var(--crt-bg)}.strct-menu__item:disabled{opacity:.45;cursor:not-allowed}.strct-menu__icon{color:var(--t2);flex-shrink:0}.strct-menu__item--danger .strct-menu__icon{color:var(--crt)}.strct-menu__icon-spacer{width:14px;flex-shrink:0}.strct-menu__label{flex:1;white-space:nowrap}.strct-menu__arrow{color:var(--t3);flex-shrink:0}.strct-menu__sep{height:1px;margin:4px 6px;background:var(--b1)}.strct-menu__subpanel{position:absolute;top:-5px;left:100%;margin-left:2px;z-index:1}.strct-menu__subpanel--flip{left:auto;right:100%;margin-left:0;margin-right:2px}@keyframes strct-menu-in{0%{opacity:0;transform:scale(.97)}}\n"], dependencies: [{ kind: "component", type: StrctMenuPanel, selector: "strct-menu-panel", inputs: ["items", "data", "x", "y", "submenu"], outputs: ["select", "close", "back"] }, { kind: "component", type: StrctIcon, selector: "strct-icon", inputs: ["name", "size", "strokeWidth", "badge"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
1890
|
+
}
|
|
1891
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: StrctMenuPanel, decorators: [{
|
|
1892
|
+
type: Component,
|
|
1893
|
+
args: [{ selector: 'strct-menu-panel', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [StrctIcon], template: `
|
|
1894
|
+
<div class="strct-menu" role="menu" tabindex="-1" (keydown)="onKeydown($event)">
|
|
1895
|
+
@for (item of items(); track $index; let i = $index) {
|
|
1896
|
+
@if (item.divider) {
|
|
1897
|
+
<div class="strct-menu__sep" role="separator"></div>
|
|
1898
|
+
} @else {
|
|
1899
|
+
<div class="strct-menu__wrap" (mouseenter)="onHover(i)" (mouseleave)="onLeave(i)">
|
|
1900
|
+
<button
|
|
1901
|
+
type="button"
|
|
1902
|
+
class="strct-menu__item"
|
|
1903
|
+
[attr.data-idx]="i"
|
|
1904
|
+
[class.strct-menu__item--danger]="item.danger"
|
|
1905
|
+
[class.strct-menu__item--active]="i === activeIndex()"
|
|
1906
|
+
[disabled]="item.disabled"
|
|
1907
|
+
role="menuitem"
|
|
1908
|
+
[attr.aria-haspopup]="item.children?.length ? 'menu' : null"
|
|
1909
|
+
[attr.aria-expanded]="item.children?.length ? openSubIndex() === i : null"
|
|
1910
|
+
[attr.tabindex]="i === activeIndex() ? 0 : -1"
|
|
1911
|
+
(click)="onItemClick(item, i, $event)"
|
|
1912
|
+
>
|
|
1913
|
+
@if (item.icon) {
|
|
1914
|
+
<strct-icon class="strct-menu__icon" [name]="item.icon" [size]="14" [strokeWidth]="1.3" />
|
|
1915
|
+
} @else {
|
|
1916
|
+
<span class="strct-menu__icon-spacer" aria-hidden="true"></span>
|
|
1917
|
+
}
|
|
1918
|
+
<span class="strct-menu__label">{{ item.label }}</span>
|
|
1919
|
+
@if (item.children?.length) {
|
|
1920
|
+
<strct-icon class="strct-menu__arrow" name="chevronRight" [size]="12" [strokeWidth]="1.6" />
|
|
1921
|
+
}
|
|
1922
|
+
</button>
|
|
1923
|
+
@if (openSubIndex() === i && item.children?.length) {
|
|
1924
|
+
<strct-menu-panel
|
|
1925
|
+
submenu
|
|
1926
|
+
class="strct-menu__subpanel"
|
|
1927
|
+
[class.strct-menu__subpanel--flip]="flipLeft()"
|
|
1928
|
+
[items]="item.children!"
|
|
1929
|
+
[data]="data()"
|
|
1930
|
+
(select)="select.emit($event)"
|
|
1931
|
+
(close)="close.emit()"
|
|
1932
|
+
(back)="closeSub(); focusItem(i)"
|
|
1933
|
+
/>
|
|
1934
|
+
}
|
|
1935
|
+
</div>
|
|
1936
|
+
}
|
|
1937
|
+
}
|
|
1938
|
+
</div>
|
|
1939
|
+
`, host: {
|
|
1940
|
+
class: 'strct-menu-host',
|
|
1941
|
+
'[style.position]': "submenu() ? null : 'fixed'",
|
|
1942
|
+
'[style.left.px]': 'submenu() ? null : posX()',
|
|
1943
|
+
'[style.top.px]': 'submenu() ? null : posY()',
|
|
1944
|
+
'[style.zIndex]': 'submenu() ? null : 1100',
|
|
1945
|
+
}, styles: [".strct-menu-host{display:block}.strct-menu{min-width:180px;padding:4px;background:var(--bg-1);border:1px solid var(--b2);border-radius:7px;box-shadow:var(--shh);animation:strct-menu-in .1s ease}.strct-menu:focus{outline:none}.strct-menu__wrap{position:relative}.strct-menu__item{display:flex;align-items:center;gap:8px;width:100%;padding:7px 8px 7px 10px;border:0;border-radius:5px;cursor:pointer;background:transparent;color:var(--t1);font-size:13px;font-family:var(--font);text-align:left}.strct-menu__item:hover:not(:disabled),.strct-menu__item--active:not(:disabled){background:var(--bg-3)}.strct-menu__item:focus-visible{outline:none;background:var(--bg-3)}.strct-menu__item--danger{color:var(--crt)}.strct-menu__item--danger:hover:not(:disabled),.strct-menu__item--danger.strct-menu__item--active:not(:disabled){background:var(--crt-bg)}.strct-menu__item:disabled{opacity:.45;cursor:not-allowed}.strct-menu__icon{color:var(--t2);flex-shrink:0}.strct-menu__item--danger .strct-menu__icon{color:var(--crt)}.strct-menu__icon-spacer{width:14px;flex-shrink:0}.strct-menu__label{flex:1;white-space:nowrap}.strct-menu__arrow{color:var(--t3);flex-shrink:0}.strct-menu__sep{height:1px;margin:4px 6px;background:var(--b1)}.strct-menu__subpanel{position:absolute;top:-5px;left:100%;margin-left:2px;z-index:1}.strct-menu__subpanel--flip{left:auto;right:100%;margin-left:0;margin-right:2px}@keyframes strct-menu-in{0%{opacity:0;transform:scale(.97)}}\n"] }]
|
|
1946
|
+
}], ctorParameters: () => [], propDecorators: { items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: true }] }], data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], x: [{ type: i0.Input, args: [{ isSignal: true, alias: "x", required: false }] }], y: [{ type: i0.Input, args: [{ isSignal: true, alias: "y", required: false }] }], submenu: [{ type: i0.Input, args: [{ isSignal: true, alias: "submenu", required: false }] }], select: [{ type: i0.Output, args: ["select"] }], close: [{ type: i0.Output, args: ["close"] }], back: [{ type: i0.Output, args: ["back"] }] } });
|
|
1947
|
+
/**
|
|
1948
|
+
* Right-click (context) menu driven by a data array. Attach to any trigger; the
|
|
1949
|
+
* menu portals into `<body>` and runs each item's `action` on selection.
|
|
1950
|
+
* <div [strctContextMenu]="menuFor(host)" [strctContextMenuData]="host"
|
|
1951
|
+
* (menuSelect)="onPick($event)">…</div>
|
|
1952
|
+
*/
|
|
1953
|
+
class StrctContextMenuTrigger {
|
|
1954
|
+
appRef = inject(ApplicationRef);
|
|
1955
|
+
envInjector = inject(EnvironmentInjector);
|
|
1956
|
+
zone = inject(NgZone);
|
|
1957
|
+
doc = inject(DOCUMENT$1);
|
|
1958
|
+
items = input.required({ ...(ngDevMode ? { debugName: "items" } : /* istanbul ignore next */ {}), alias: 'strctContextMenu' });
|
|
1959
|
+
data = input(undefined, { ...(ngDevMode ? { debugName: "data" } : /* istanbul ignore next */ {}), alias: 'strctContextMenuData' });
|
|
1960
|
+
menuSelect = output();
|
|
1961
|
+
ref = null;
|
|
1962
|
+
onClose = () => this.zone.run(() => this.closeMenu());
|
|
1963
|
+
onContextMenu(event) {
|
|
1964
|
+
if (!this.items()?.length)
|
|
1965
|
+
return;
|
|
1966
|
+
event.preventDefault();
|
|
1967
|
+
this.openAt(event.clientX, event.clientY);
|
|
1968
|
+
}
|
|
1969
|
+
openAt(x, y) {
|
|
1970
|
+
this.closeMenu();
|
|
1971
|
+
const ref = createComponent(StrctMenuPanel, { environmentInjector: this.envInjector });
|
|
1972
|
+
ref.setInput('items', this.items());
|
|
1973
|
+
ref.setInput('data', this.data());
|
|
1974
|
+
ref.setInput('x', x);
|
|
1975
|
+
ref.setInput('y', y);
|
|
1976
|
+
ref.instance.select.subscribe((item) => {
|
|
1977
|
+
item.action?.(this.data());
|
|
1978
|
+
this.menuSelect.emit(item);
|
|
1979
|
+
this.closeMenu();
|
|
1980
|
+
});
|
|
1981
|
+
ref.instance.close.subscribe(() => this.closeMenu());
|
|
1982
|
+
this.appRef.attachView(ref.hostView);
|
|
1983
|
+
this.doc.body.appendChild(ref.location.nativeElement);
|
|
1984
|
+
this.ref = ref;
|
|
1985
|
+
// Defer global listeners so the opening right-click doesn't immediately close.
|
|
1986
|
+
setTimeout(() => {
|
|
1987
|
+
this.zone.runOutsideAngular(() => {
|
|
1988
|
+
this.doc.addEventListener('mousedown', this.onOutside, true);
|
|
1989
|
+
window.addEventListener('scroll', this.onClose, true);
|
|
1990
|
+
window.addEventListener('resize', this.onClose);
|
|
1991
|
+
});
|
|
1992
|
+
});
|
|
1993
|
+
}
|
|
1994
|
+
onOutside = (event) => {
|
|
1995
|
+
if (this.ref && !this.ref.location.nativeElement.contains(event.target)) {
|
|
1996
|
+
this.onClose();
|
|
1997
|
+
}
|
|
1998
|
+
};
|
|
1999
|
+
closeMenu() {
|
|
2000
|
+
if (!this.ref)
|
|
2001
|
+
return;
|
|
2002
|
+
this.doc.removeEventListener('mousedown', this.onOutside, true);
|
|
2003
|
+
window.removeEventListener('scroll', this.onClose, true);
|
|
2004
|
+
window.removeEventListener('resize', this.onClose);
|
|
2005
|
+
this.appRef.detachView(this.ref.hostView);
|
|
2006
|
+
this.ref.destroy();
|
|
2007
|
+
this.ref = null;
|
|
2008
|
+
}
|
|
2009
|
+
ngOnDestroy() {
|
|
2010
|
+
this.closeMenu();
|
|
2011
|
+
}
|
|
2012
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: StrctContextMenuTrigger, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
2013
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.16", type: StrctContextMenuTrigger, isStandalone: true, selector: "[strctContextMenu]", inputs: { items: { classPropertyName: "items", publicName: "strctContextMenu", isSignal: true, isRequired: true, transformFunction: null }, data: { classPropertyName: "data", publicName: "strctContextMenuData", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { menuSelect: "menuSelect" }, host: { listeners: { "contextmenu": "onContextMenu($event)" } }, ngImport: i0 });
|
|
2014
|
+
}
|
|
2015
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: StrctContextMenuTrigger, decorators: [{
|
|
2016
|
+
type: Directive,
|
|
2017
|
+
args: [{ selector: '[strctContextMenu]' }]
|
|
2018
|
+
}], propDecorators: { items: [{ type: i0.Input, args: [{ isSignal: true, alias: "strctContextMenu", required: true }] }], data: [{ type: i0.Input, args: [{ isSignal: true, alias: "strctContextMenuData", required: false }] }], menuSelect: [{ type: i0.Output, args: ["menuSelect"] }], onContextMenu: [{
|
|
2019
|
+
type: HostListener,
|
|
2020
|
+
args: ['contextmenu', ['$event']]
|
|
2021
|
+
}] } });
|
|
2022
|
+
|
|
1609
2023
|
/** A single wizard step. `label` names it in the step header. */
|
|
1610
2024
|
class StrctStep {
|
|
1611
2025
|
label = input.required(...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
2026
|
+
/** When false, the wizard's Next / Finish is disabled on this step. */
|
|
2027
|
+
canAdvance = input(true, { ...(ngDevMode ? { debugName: "canAdvance" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
1612
2028
|
_active = signal(false, ...(ngDevMode ? [{ debugName: "_active" }] : /* istanbul ignore next */ []));
|
|
1613
2029
|
active = this._active.asReadonly();
|
|
1614
2030
|
/** @internal */
|
|
@@ -1616,7 +2032,7 @@ class StrctStep {
|
|
|
1616
2032
|
this._active.set(value);
|
|
1617
2033
|
}
|
|
1618
2034
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: StrctStep, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1619
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.16", type: StrctStep, isStandalone: true, selector: "strct-step", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null } }, host: { properties: { "hidden": "!active()" }, classAttribute: "strct-step" }, ngImport: i0, template: `@if (active()) {
|
|
2035
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.16", type: StrctStep, isStandalone: true, selector: "strct-step", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, canAdvance: { classPropertyName: "canAdvance", publicName: "canAdvance", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "hidden": "!active()" }, classAttribute: "strct-step" }, ngImport: i0, template: `@if (active()) {
|
|
1620
2036
|
<ng-content />
|
|
1621
2037
|
}`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1622
2038
|
}
|
|
@@ -1630,13 +2046,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImpo
|
|
|
1630
2046
|
}`,
|
|
1631
2047
|
host: { class: 'strct-step', '[hidden]': '!active()' },
|
|
1632
2048
|
}]
|
|
1633
|
-
}], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }] } });
|
|
2049
|
+
}], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }], canAdvance: [{ type: i0.Input, args: [{ isSignal: true, alias: "canAdvance", required: false }] }] } });
|
|
1634
2050
|
/** Multi-step flow with a numbered header and Back / Next / Finish controls. */
|
|
1635
2051
|
class StrctWizard {
|
|
1636
2052
|
steps = contentChildren(StrctStep, ...(ngDevMode ? [{ debugName: "steps" }] : /* istanbul ignore next */ []));
|
|
1637
2053
|
current = signal(0, ...(ngDevMode ? [{ debugName: "current" }] : /* istanbul ignore next */ []));
|
|
2054
|
+
/** Label for the final-step button (default "Finish"). */
|
|
2055
|
+
finishLabel = input('Finish', ...(ngDevMode ? [{ debugName: "finishLabel" }] : /* istanbul ignore next */ []));
|
|
2056
|
+
/** Disable Finish and show a busy label while an async submit is in flight. */
|
|
2057
|
+
submitting = input(false, { ...(ngDevMode ? { debugName: "submitting" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
2058
|
+
/** Show a Cancel button on the left. */
|
|
2059
|
+
cancelable = input(false, { ...(ngDevMode ? { debugName: "cancelable" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
1638
2060
|
finished = output();
|
|
2061
|
+
cancelled = output();
|
|
2062
|
+
/** Emits the new step index after a Back / Next move. */
|
|
2063
|
+
stepChange = output();
|
|
1639
2064
|
isLast = computed(() => this.current() >= this.steps().length - 1, ...(ngDevMode ? [{ debugName: "isLast" }] : /* istanbul ignore next */ []));
|
|
2065
|
+
/** Whether the current step permits advancing (its `canAdvance`). */
|
|
2066
|
+
canAdvance = computed(() => this.steps()[this.current()]?.canAdvance() ?? true, ...(ngDevMode ? [{ debugName: "canAdvance" }] : /* istanbul ignore next */ []));
|
|
1640
2067
|
constructor() {
|
|
1641
2068
|
effect(() => {
|
|
1642
2069
|
const idx = this.current();
|
|
@@ -1644,18 +2071,23 @@ class StrctWizard {
|
|
|
1644
2071
|
});
|
|
1645
2072
|
}
|
|
1646
2073
|
next() {
|
|
1647
|
-
if (!this.isLast())
|
|
2074
|
+
if (!this.isLast() && this.canAdvance()) {
|
|
1648
2075
|
this.current.update((i) => i + 1);
|
|
2076
|
+
this.stepChange.emit(this.current());
|
|
2077
|
+
}
|
|
1649
2078
|
}
|
|
1650
2079
|
back() {
|
|
1651
|
-
if (this.current() > 0)
|
|
2080
|
+
if (this.current() > 0) {
|
|
1652
2081
|
this.current.update((i) => i - 1);
|
|
2082
|
+
this.stepChange.emit(this.current());
|
|
2083
|
+
}
|
|
1653
2084
|
}
|
|
1654
2085
|
finish() {
|
|
1655
|
-
this.
|
|
2086
|
+
if (this.canAdvance() && !this.submitting())
|
|
2087
|
+
this.finished.emit();
|
|
1656
2088
|
}
|
|
1657
2089
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: StrctWizard, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1658
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.16", type: StrctWizard, isStandalone: true, selector: "strct-wizard", outputs: { finished: "finished" }, host: { classAttribute: "strct-wiz" }, queries: [{ propertyName: "steps", predicate: StrctStep, isSignal: true }], ngImport: i0, template: `
|
|
2090
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.16", type: StrctWizard, isStandalone: true, selector: "strct-wizard", inputs: { finishLabel: { classPropertyName: "finishLabel", publicName: "finishLabel", isSignal: true, isRequired: false, transformFunction: null }, submitting: { classPropertyName: "submitting", publicName: "submitting", isSignal: true, isRequired: false, transformFunction: null }, cancelable: { classPropertyName: "cancelable", publicName: "cancelable", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { finished: "finished", cancelled: "cancelled", stepChange: "stepChange" }, host: { classAttribute: "strct-wiz" }, queries: [{ propertyName: "steps", predicate: StrctStep, isSignal: true }], ngImport: i0, template: `
|
|
1659
2091
|
<div class="strct-wiz__steps">
|
|
1660
2092
|
@for (step of steps(); track step; let i = $index; let last = $last) {
|
|
1661
2093
|
<div
|
|
@@ -1675,14 +2107,26 @@ class StrctWizard {
|
|
|
1675
2107
|
<div class="strct-wiz__content"><ng-content /></div>
|
|
1676
2108
|
|
|
1677
2109
|
<div class="strct-wiz__foot">
|
|
2110
|
+
@if (cancelable()) {
|
|
2111
|
+
<button strct-button variant="flat" class="strct-wiz__cancel" (click)="cancelled.emit()">
|
|
2112
|
+
Cancel
|
|
2113
|
+
</button>
|
|
2114
|
+
}
|
|
1678
2115
|
<button strct-button variant="flat" [disabled]="current() === 0" (click)="back()">Back</button>
|
|
1679
2116
|
@if (isLast()) {
|
|
1680
|
-
<button
|
|
2117
|
+
<button
|
|
2118
|
+
strct-button
|
|
2119
|
+
variant="primary"
|
|
2120
|
+
[disabled]="submitting() || !canAdvance()"
|
|
2121
|
+
(click)="finish()"
|
|
2122
|
+
>
|
|
2123
|
+
{{ submitting() ? 'Submitting…' : finishLabel() }}
|
|
2124
|
+
</button>
|
|
1681
2125
|
} @else {
|
|
1682
|
-
<button strct-button variant="primary" (click)="next()">Next</button>
|
|
2126
|
+
<button strct-button variant="primary" [disabled]="!canAdvance()" (click)="next()">Next</button>
|
|
1683
2127
|
}
|
|
1684
2128
|
</div>
|
|
1685
|
-
`, isInline: true, styles: [".strct-wiz{display:block}.strct-wiz__steps{display:flex;align-items:center;gap:6px}.strct-wiz__step{display:flex;align-items:center;gap:8px}.strct-wiz__dot{display:inline-flex;align-items:center;justify-content:center;width:22px;height:22px;border-radius:50%;font-size:11px;font-weight:600;color:var(--t2);background:var(--bg-3);border:1px solid var(--b2)}.strct-wiz__label{font-size:12px;color:var(--t2)}.strct-wiz__step--active .strct-wiz__dot{background:var(--acc-m);color:var(--acc);border-color:var(--acc)}.strct-wiz__step--active .strct-wiz__label{color:var(--t1);font-weight:600}.strct-wiz__step--done .strct-wiz__dot{background:var(--acc-m);color:var(--acc);border-color:var(--acc30)}.strct-wiz__sep{flex:1;height:1px;background:var(--b2);min-width:18px}.strct-wiz__content{margin:18px 0;padding:16px;min-height:80px;background:var(--bg-1);border:1px solid var(--b2);border-radius:8px;color:var(--t2);font-size:13px}.strct-wiz__foot{display:flex;justify-content:flex-end;gap:8px}\n"], dependencies: [{ kind: "component", type: StrctButton, selector: "button[strct-button], a[strct-button]", inputs: ["variant", "size", "solid", "block", "iconOnly"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
2129
|
+
`, isInline: true, styles: [".strct-wiz{display:block}.strct-wiz__steps{display:flex;align-items:center;gap:6px}.strct-wiz__step{display:flex;align-items:center;gap:8px}.strct-wiz__dot{display:inline-flex;align-items:center;justify-content:center;width:22px;height:22px;border-radius:50%;font-size:11px;font-weight:600;color:var(--t2);background:var(--bg-3);border:1px solid var(--b2)}.strct-wiz__label{font-size:12px;color:var(--t2)}.strct-wiz__step--active .strct-wiz__dot{background:var(--acc-m);color:var(--acc);border-color:var(--acc)}.strct-wiz__step--active .strct-wiz__label{color:var(--t1);font-weight:600}.strct-wiz__step--done .strct-wiz__dot{background:var(--acc-m);color:var(--acc);border-color:var(--acc30)}.strct-wiz__sep{flex:1;height:1px;background:var(--b2);min-width:18px}.strct-wiz__content{margin:18px 0;padding:16px;min-height:80px;background:var(--bg-1);border:1px solid var(--b2);border-radius:8px;color:var(--t2);font-size:13px}.strct-wiz__foot{display:flex;justify-content:flex-end;gap:8px}.strct-wiz__cancel{margin-right:auto}\n"], dependencies: [{ kind: "component", type: StrctButton, selector: "button[strct-button], a[strct-button]", inputs: ["variant", "size", "solid", "block", "iconOnly"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
1686
2130
|
}
|
|
1687
2131
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: StrctWizard, decorators: [{
|
|
1688
2132
|
type: Component,
|
|
@@ -1706,15 +2150,27 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImpo
|
|
|
1706
2150
|
<div class="strct-wiz__content"><ng-content /></div>
|
|
1707
2151
|
|
|
1708
2152
|
<div class="strct-wiz__foot">
|
|
2153
|
+
@if (cancelable()) {
|
|
2154
|
+
<button strct-button variant="flat" class="strct-wiz__cancel" (click)="cancelled.emit()">
|
|
2155
|
+
Cancel
|
|
2156
|
+
</button>
|
|
2157
|
+
}
|
|
1709
2158
|
<button strct-button variant="flat" [disabled]="current() === 0" (click)="back()">Back</button>
|
|
1710
2159
|
@if (isLast()) {
|
|
1711
|
-
<button
|
|
2160
|
+
<button
|
|
2161
|
+
strct-button
|
|
2162
|
+
variant="primary"
|
|
2163
|
+
[disabled]="submitting() || !canAdvance()"
|
|
2164
|
+
(click)="finish()"
|
|
2165
|
+
>
|
|
2166
|
+
{{ submitting() ? 'Submitting…' : finishLabel() }}
|
|
2167
|
+
</button>
|
|
1712
2168
|
} @else {
|
|
1713
|
-
<button strct-button variant="primary" (click)="next()">Next</button>
|
|
2169
|
+
<button strct-button variant="primary" [disabled]="!canAdvance()" (click)="next()">Next</button>
|
|
1714
2170
|
}
|
|
1715
2171
|
</div>
|
|
1716
|
-
`, host: { class: 'strct-wiz' }, styles: [".strct-wiz{display:block}.strct-wiz__steps{display:flex;align-items:center;gap:6px}.strct-wiz__step{display:flex;align-items:center;gap:8px}.strct-wiz__dot{display:inline-flex;align-items:center;justify-content:center;width:22px;height:22px;border-radius:50%;font-size:11px;font-weight:600;color:var(--t2);background:var(--bg-3);border:1px solid var(--b2)}.strct-wiz__label{font-size:12px;color:var(--t2)}.strct-wiz__step--active .strct-wiz__dot{background:var(--acc-m);color:var(--acc);border-color:var(--acc)}.strct-wiz__step--active .strct-wiz__label{color:var(--t1);font-weight:600}.strct-wiz__step--done .strct-wiz__dot{background:var(--acc-m);color:var(--acc);border-color:var(--acc30)}.strct-wiz__sep{flex:1;height:1px;background:var(--b2);min-width:18px}.strct-wiz__content{margin:18px 0;padding:16px;min-height:80px;background:var(--bg-1);border:1px solid var(--b2);border-radius:8px;color:var(--t2);font-size:13px}.strct-wiz__foot{display:flex;justify-content:flex-end;gap:8px}\n"] }]
|
|
1717
|
-
}], ctorParameters: () => [], propDecorators: { steps: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => StrctStep), { isSignal: true }] }], finished: [{ type: i0.Output, args: ["finished"] }] } });
|
|
2172
|
+
`, host: { class: 'strct-wiz' }, styles: [".strct-wiz{display:block}.strct-wiz__steps{display:flex;align-items:center;gap:6px}.strct-wiz__step{display:flex;align-items:center;gap:8px}.strct-wiz__dot{display:inline-flex;align-items:center;justify-content:center;width:22px;height:22px;border-radius:50%;font-size:11px;font-weight:600;color:var(--t2);background:var(--bg-3);border:1px solid var(--b2)}.strct-wiz__label{font-size:12px;color:var(--t2)}.strct-wiz__step--active .strct-wiz__dot{background:var(--acc-m);color:var(--acc);border-color:var(--acc)}.strct-wiz__step--active .strct-wiz__label{color:var(--t1);font-weight:600}.strct-wiz__step--done .strct-wiz__dot{background:var(--acc-m);color:var(--acc);border-color:var(--acc30)}.strct-wiz__sep{flex:1;height:1px;background:var(--b2);min-width:18px}.strct-wiz__content{margin:18px 0;padding:16px;min-height:80px;background:var(--bg-1);border:1px solid var(--b2);border-radius:8px;color:var(--t2);font-size:13px}.strct-wiz__foot{display:flex;justify-content:flex-end;gap:8px}.strct-wiz__cancel{margin-right:auto}\n"] }]
|
|
2173
|
+
}], ctorParameters: () => [], propDecorators: { steps: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => StrctStep), { isSignal: true }] }], finishLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "finishLabel", required: false }] }], submitting: [{ type: i0.Input, args: [{ isSignal: true, alias: "submitting", required: false }] }], cancelable: [{ type: i0.Input, args: [{ isSignal: true, alias: "cancelable", required: false }] }], finished: [{ type: i0.Output, args: ["finished"] }], cancelled: [{ type: i0.Output, args: ["cancelled"] }], stepChange: [{ type: i0.Output, args: ["stepChange"] }] } });
|
|
1718
2174
|
|
|
1719
2175
|
/**
|
|
1720
2176
|
* Separator rule. Horizontal by default; pass `vertical` for an inline rule.
|
|
@@ -4014,7 +4470,26 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImpo
|
|
|
4014
4470
|
}] } });
|
|
4015
4471
|
|
|
4016
4472
|
/**
|
|
4017
|
-
*
|
|
4473
|
+
* Per-column cell template for `strct-table` / `strct-datagrid`. The column key
|
|
4474
|
+
* is the directive value; the row, value and column are the template context:
|
|
4475
|
+
*
|
|
4476
|
+
* <ng-template strctCell="status" let-row let-value="value">
|
|
4477
|
+
* <strct-badge [status]="row['ok'] ? 'success' : 'danger'">{{ value }}</strct-badge>
|
|
4478
|
+
* </ng-template>
|
|
4479
|
+
*/
|
|
4480
|
+
class StrctCellDef {
|
|
4481
|
+
key = input.required({ ...(ngDevMode ? { debugName: "key" } : /* istanbul ignore next */ {}), alias: 'strctCell' });
|
|
4482
|
+
template = inject(TemplateRef);
|
|
4483
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: StrctCellDef, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
4484
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.16", type: StrctCellDef, isStandalone: true, selector: "[strctCell]", inputs: { key: { classPropertyName: "key", publicName: "strctCell", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0 });
|
|
4485
|
+
}
|
|
4486
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: StrctCellDef, decorators: [{
|
|
4487
|
+
type: Directive,
|
|
4488
|
+
args: [{ selector: '[strctCell]' }]
|
|
4489
|
+
}], propDecorators: { key: [{ type: i0.Input, args: [{ isSignal: true, alias: "strctCell", required: true }] }] } });
|
|
4490
|
+
/**
|
|
4491
|
+
* Declarative data table. Cells render `row[col.key]` as text by default; supply
|
|
4492
|
+
* a `*strctCell` template per column for custom content.
|
|
4018
4493
|
* <strct-table [columns]="cols" [rows]="data" hover />
|
|
4019
4494
|
*/
|
|
4020
4495
|
class StrctTable {
|
|
@@ -4023,8 +4498,18 @@ class StrctTable {
|
|
|
4023
4498
|
striped = input(false, { ...(ngDevMode ? { debugName: "striped" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
4024
4499
|
hover = input(false, { ...(ngDevMode ? { debugName: "hover" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
4025
4500
|
emptyText = input('No data', ...(ngDevMode ? [{ debugName: "emptyText" }] : /* istanbul ignore next */ []));
|
|
4501
|
+
cellDefs = contentChildren(StrctCellDef, ...(ngDevMode ? [{ debugName: "cellDefs" }] : /* istanbul ignore next */ []));
|
|
4502
|
+
cellMap = computed(() => {
|
|
4503
|
+
const m = new Map();
|
|
4504
|
+
for (const d of this.cellDefs())
|
|
4505
|
+
m.set(d.key(), d.template);
|
|
4506
|
+
return m;
|
|
4507
|
+
}, ...(ngDevMode ? [{ debugName: "cellMap" }] : /* istanbul ignore next */ []));
|
|
4508
|
+
cellTemplate(key) {
|
|
4509
|
+
return this.cellMap().get(key) ?? null;
|
|
4510
|
+
}
|
|
4026
4511
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: StrctTable, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
4027
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.16", type: StrctTable, isStandalone: true, selector: "strct-table", inputs: { columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: true, transformFunction: null }, rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: true, transformFunction: null }, striped: { classPropertyName: "striped", publicName: "striped", isSignal: true, isRequired: false, transformFunction: null }, hover: { classPropertyName: "hover", publicName: "hover", isSignal: true, isRequired: false, transformFunction: null }, emptyText: { classPropertyName: "emptyText", publicName: "emptyText", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.strct-table-host--striped": "striped()", "class.strct-table-host--hover": "hover()" }, classAttribute: "strct-table-host" }, ngImport: i0, template: `
|
|
4512
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.16", type: StrctTable, isStandalone: true, selector: "strct-table", inputs: { columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: true, transformFunction: null }, rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: true, transformFunction: null }, striped: { classPropertyName: "striped", publicName: "striped", isSignal: true, isRequired: false, transformFunction: null }, hover: { classPropertyName: "hover", publicName: "hover", isSignal: true, isRequired: false, transformFunction: null }, emptyText: { classPropertyName: "emptyText", publicName: "emptyText", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.strct-table-host--striped": "striped()", "class.strct-table-host--hover": "hover()" }, classAttribute: "strct-table-host" }, queries: [{ propertyName: "cellDefs", predicate: StrctCellDef, isSignal: true }], ngImport: i0, template: `
|
|
4028
4513
|
<table class="strct-table">
|
|
4029
4514
|
<thead>
|
|
4030
4515
|
<tr>
|
|
@@ -4037,7 +4522,16 @@ class StrctTable {
|
|
|
4037
4522
|
@for (row of rows(); track $index) {
|
|
4038
4523
|
<tr>
|
|
4039
4524
|
@for (col of columns(); track col.key) {
|
|
4040
|
-
<td [style.text-align]="col.align ?? 'start'">
|
|
4525
|
+
<td [style.text-align]="col.align ?? 'start'">
|
|
4526
|
+
@if (cellTemplate(col.key); as tpl) {
|
|
4527
|
+
<ng-container
|
|
4528
|
+
[ngTemplateOutlet]="tpl"
|
|
4529
|
+
[ngTemplateOutletContext]="{ $implicit: row, value: row[col.key], column: col }"
|
|
4530
|
+
/>
|
|
4531
|
+
} @else {
|
|
4532
|
+
{{ row[col.key] }}
|
|
4533
|
+
}
|
|
4534
|
+
</td>
|
|
4041
4535
|
}
|
|
4042
4536
|
</tr>
|
|
4043
4537
|
} @empty {
|
|
@@ -4047,11 +4541,11 @@ class StrctTable {
|
|
|
4047
4541
|
}
|
|
4048
4542
|
</tbody>
|
|
4049
4543
|
</table>
|
|
4050
|
-
`, isInline: true, styles: [".strct-table-host{display:block;overflow-x:auto}.strct-table{width:100%;border-collapse:collapse;font-size:13px;border:1px solid var(--b2);border-radius:8px;overflow:hidden}.strct-table th,.strct-table td{padding:9px 13px;text-align:left;border-bottom:1px solid var(--b1)}.strct-table th{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.4px;color:var(--t2);background:var(--bg-2)}.strct-table td{color:var(--t1)}.strct-table tbody tr:last-child td{border-bottom:0}.strct-table-host--striped tbody tr:nth-child(2n) td{background:var(--bg-2)}.strct-table-host--hover tbody tr:hover td{background:var(--acc-s)}.strct-table__empty{text-align:center;color:var(--t3);padding:22px}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
4544
|
+
`, isInline: true, styles: [".strct-table-host{display:block;overflow-x:auto}.strct-table{width:100%;border-collapse:collapse;font-size:13px;border:1px solid var(--b2);border-radius:8px;overflow:hidden}.strct-table th,.strct-table td{padding:9px 13px;text-align:left;border-bottom:1px solid var(--b1)}.strct-table th{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.4px;color:var(--t2);background:var(--bg-2)}.strct-table td{color:var(--t1)}.strct-table tbody tr:last-child td{border-bottom:0}.strct-table-host--striped tbody tr:nth-child(2n) td{background:var(--bg-2)}.strct-table-host--hover tbody tr:hover td{background:var(--acc-s)}.strct-table__empty{text-align:center;color:var(--t3);padding:22px}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
4051
4545
|
}
|
|
4052
4546
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: StrctTable, decorators: [{
|
|
4053
4547
|
type: Component,
|
|
4054
|
-
args: [{ selector: 'strct-table', changeDetection: ChangeDetectionStrategy.OnPush, template: `
|
|
4548
|
+
args: [{ selector: 'strct-table', changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgTemplateOutlet], template: `
|
|
4055
4549
|
<table class="strct-table">
|
|
4056
4550
|
<thead>
|
|
4057
4551
|
<tr>
|
|
@@ -4064,7 +4558,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImpo
|
|
|
4064
4558
|
@for (row of rows(); track $index) {
|
|
4065
4559
|
<tr>
|
|
4066
4560
|
@for (col of columns(); track col.key) {
|
|
4067
|
-
<td [style.text-align]="col.align ?? 'start'">
|
|
4561
|
+
<td [style.text-align]="col.align ?? 'start'">
|
|
4562
|
+
@if (cellTemplate(col.key); as tpl) {
|
|
4563
|
+
<ng-container
|
|
4564
|
+
[ngTemplateOutlet]="tpl"
|
|
4565
|
+
[ngTemplateOutletContext]="{ $implicit: row, value: row[col.key], column: col }"
|
|
4566
|
+
/>
|
|
4567
|
+
} @else {
|
|
4568
|
+
{{ row[col.key] }}
|
|
4569
|
+
}
|
|
4570
|
+
</td>
|
|
4068
4571
|
}
|
|
4069
4572
|
</tr>
|
|
4070
4573
|
} @empty {
|
|
@@ -4079,7 +4582,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImpo
|
|
|
4079
4582
|
'[class.strct-table-host--striped]': 'striped()',
|
|
4080
4583
|
'[class.strct-table-host--hover]': 'hover()',
|
|
4081
4584
|
}, styles: [".strct-table-host{display:block;overflow-x:auto}.strct-table{width:100%;border-collapse:collapse;font-size:13px;border:1px solid var(--b2);border-radius:8px;overflow:hidden}.strct-table th,.strct-table td{padding:9px 13px;text-align:left;border-bottom:1px solid var(--b1)}.strct-table th{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.4px;color:var(--t2);background:var(--bg-2)}.strct-table td{color:var(--t1)}.strct-table tbody tr:last-child td{border-bottom:0}.strct-table-host--striped tbody tr:nth-child(2n) td{background:var(--bg-2)}.strct-table-host--hover tbody tr:hover td{background:var(--acc-s)}.strct-table__empty{text-align:center;color:var(--t3);padding:22px}\n"] }]
|
|
4082
|
-
}], propDecorators: { columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: true }] }], rows: [{ type: i0.Input, args: [{ isSignal: true, alias: "rows", required: true }] }], striped: [{ type: i0.Input, args: [{ isSignal: true, alias: "striped", required: false }] }], hover: [{ type: i0.Input, args: [{ isSignal: true, alias: "hover", required: false }] }], emptyText: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyText", required: false }] }] } });
|
|
4585
|
+
}], propDecorators: { columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: true }] }], rows: [{ type: i0.Input, args: [{ isSignal: true, alias: "rows", required: true }] }], striped: [{ type: i0.Input, args: [{ isSignal: true, alias: "striped", required: false }] }], hover: [{ type: i0.Input, args: [{ isSignal: true, alias: "hover", required: false }] }], emptyText: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyText", required: false }] }], cellDefs: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => StrctCellDef), { isSignal: true }] }] } });
|
|
4083
4586
|
|
|
4084
4587
|
/**
|
|
4085
4588
|
* Marks the expandable-row detail template. The row is the template's implicit
|
|
@@ -4123,14 +4626,34 @@ class StrctDatagrid {
|
|
|
4123
4626
|
detailPane = input(false, { ...(ngDevMode ? { debugName: "detailPane" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
4124
4627
|
compact = input(false, { ...(ngDevMode ? { debugName: "compact" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
4125
4628
|
emptyText = input('No data', ...(ngDevMode ? [{ debugName: "emptyText" }] : /* istanbul ignore next */ []));
|
|
4629
|
+
/**
|
|
4630
|
+
* Stable row identity (property key or function). Set this for live-refreshing
|
|
4631
|
+
* data so selection, expansion and the active detail row survive re-fetches
|
|
4632
|
+
* that replace the row objects. Defaults to object identity.
|
|
4633
|
+
*/
|
|
4634
|
+
rowId = input(null, ...(ngDevMode ? [{ debugName: "rowId" }] : /* istanbul ignore next */ []));
|
|
4126
4635
|
selectionChange = output();
|
|
4127
4636
|
detailDef = contentChild(StrctRowDetailDef, ...(ngDevMode ? [{ debugName: "detailDef" }] : /* istanbul ignore next */ []));
|
|
4128
4637
|
actionBarDef = contentChild(StrctDatagridActionBar, ...(ngDevMode ? [{ debugName: "actionBarDef" }] : /* istanbul ignore next */ []));
|
|
4638
|
+
cellDefs = contentChildren(StrctCellDef, ...(ngDevMode ? [{ debugName: "cellDefs" }] : /* istanbul ignore next */ []));
|
|
4639
|
+
cellMap = computed(() => {
|
|
4640
|
+
const m = new Map();
|
|
4641
|
+
for (const d of this.cellDefs())
|
|
4642
|
+
m.set(d.key(), d.template);
|
|
4643
|
+
return m;
|
|
4644
|
+
}, ...(ngDevMode ? [{ debugName: "cellMap" }] : /* istanbul ignore next */ []));
|
|
4129
4645
|
page = signal(1, ...(ngDevMode ? [{ debugName: "page" }] : /* istanbul ignore next */ []));
|
|
4130
4646
|
sort = signal({ key: null, dir: 'asc' }, ...(ngDevMode ? [{ debugName: "sort" }] : /* istanbul ignore next */ []));
|
|
4647
|
+
/** Selection / expansion are tracked by row id (see {@link rowId}). */
|
|
4131
4648
|
selected = signal(new Set(), ...(ngDevMode ? [{ debugName: "selected" }] : /* istanbul ignore next */ []));
|
|
4132
4649
|
expandedRows = signal(new Set(), ...(ngDevMode ? [{ debugName: "expandedRows" }] : /* istanbul ignore next */ []));
|
|
4133
|
-
|
|
4650
|
+
activeId = signal(null, ...(ngDevMode ? [{ debugName: "activeId" }] : /* istanbul ignore next */ []));
|
|
4651
|
+
activeRow = computed(() => {
|
|
4652
|
+
const id = this.activeId();
|
|
4653
|
+
if (id == null)
|
|
4654
|
+
return null;
|
|
4655
|
+
return this.rows().find((r) => this.idOf(r) === id) ?? null;
|
|
4656
|
+
}, ...(ngDevMode ? [{ debugName: "activeRow" }] : /* istanbul ignore next */ []));
|
|
4134
4657
|
canExpand = computed(() => this.expandable() && !this.detailPane() && !!this.detailDef(), ...(ngDevMode ? [{ debugName: "canExpand" }] : /* istanbul ignore next */ []));
|
|
4135
4658
|
canDetail = computed(() => this.detailPane() && !!this.detailDef(), ...(ngDevMode ? [{ debugName: "canDetail" }] : /* istanbul ignore next */ []));
|
|
4136
4659
|
paneOpen = computed(() => this.detailPane() && !!this.detailDef() && !!this.activeRow(), ...(ngDevMode ? [{ debugName: "paneOpen" }] : /* istanbul ignore next */ []));
|
|
@@ -4154,9 +4677,22 @@ class StrctDatagrid {
|
|
|
4154
4677
|
selectedCount = computed(() => this.selected().size, ...(ngDevMode ? [{ debugName: "selectedCount" }] : /* istanbul ignore next */ []));
|
|
4155
4678
|
allPageSelected = computed(() => {
|
|
4156
4679
|
const rows = this.paged();
|
|
4157
|
-
return rows.length > 0 && rows.every((r) => this.selected().has(r));
|
|
4680
|
+
return rows.length > 0 && rows.every((r) => this.selected().has(this.idOf(r)));
|
|
4158
4681
|
}, ...(ngDevMode ? [{ debugName: "allPageSelected" }] : /* istanbul ignore next */ []));
|
|
4159
|
-
somePageSelected = computed(() => !this.allPageSelected() && this.paged().some((r) => this.selected().has(r)), ...(ngDevMode ? [{ debugName: "somePageSelected" }] : /* istanbul ignore next */ []));
|
|
4682
|
+
somePageSelected = computed(() => !this.allPageSelected() && this.paged().some((r) => this.selected().has(this.idOf(r))), ...(ngDevMode ? [{ debugName: "somePageSelected" }] : /* istanbul ignore next */ []));
|
|
4683
|
+
/** Resolve a row's stable identity (defaults to the row object itself). */
|
|
4684
|
+
idOf(row) {
|
|
4685
|
+
const id = this.rowId();
|
|
4686
|
+
if (id == null)
|
|
4687
|
+
return row;
|
|
4688
|
+
return typeof id === 'function' ? id(row) : row[id];
|
|
4689
|
+
}
|
|
4690
|
+
rowKey(row) {
|
|
4691
|
+
return this.idOf(row);
|
|
4692
|
+
}
|
|
4693
|
+
cellTemplate(key) {
|
|
4694
|
+
return this.cellMap().get(key) ?? null;
|
|
4695
|
+
}
|
|
4160
4696
|
constructor() {
|
|
4161
4697
|
// Keep the page in range when the data set shrinks.
|
|
4162
4698
|
effect(() => {
|
|
@@ -4177,10 +4713,11 @@ class StrctDatagrid {
|
|
|
4177
4713
|
/** Toggle the detail pane for a row (triggered by its » button, not the row,
|
|
4178
4714
|
* so row cells remain selectable for copy). */
|
|
4179
4715
|
openDetail(row) {
|
|
4180
|
-
this.
|
|
4716
|
+
const id = this.idOf(row);
|
|
4717
|
+
this.activeId.set(this.activeId() === id ? null : id);
|
|
4181
4718
|
}
|
|
4182
4719
|
closePane() {
|
|
4183
|
-
this.
|
|
4720
|
+
this.activeId.set(null);
|
|
4184
4721
|
}
|
|
4185
4722
|
sortBy(key) {
|
|
4186
4723
|
const current = this.sort();
|
|
@@ -4211,38 +4748,42 @@ class StrctDatagrid {
|
|
|
4211
4748
|
this.sortBy(key);
|
|
4212
4749
|
}
|
|
4213
4750
|
isSelected(row) {
|
|
4214
|
-
return this.selected().has(row);
|
|
4751
|
+
return this.selected().has(this.idOf(row));
|
|
4215
4752
|
}
|
|
4216
4753
|
isExpanded(row) {
|
|
4217
|
-
return this.expandedRows().has(row);
|
|
4754
|
+
return this.expandedRows().has(this.idOf(row));
|
|
4218
4755
|
}
|
|
4219
4756
|
toggleExpand(row) {
|
|
4757
|
+
const id = this.idOf(row);
|
|
4220
4758
|
const next = new Set(this.expandedRows());
|
|
4221
|
-
next.has(
|
|
4759
|
+
next.has(id) ? next.delete(id) : next.add(id);
|
|
4222
4760
|
this.expandedRows.set(next);
|
|
4223
4761
|
}
|
|
4224
4762
|
toggleRow(row) {
|
|
4763
|
+
const id = this.idOf(row);
|
|
4225
4764
|
const next = new Set(this.selected());
|
|
4226
|
-
next.has(
|
|
4765
|
+
next.has(id) ? next.delete(id) : next.add(id);
|
|
4227
4766
|
this.commitSelection(next);
|
|
4228
4767
|
}
|
|
4229
4768
|
toggleAll() {
|
|
4230
4769
|
const next = new Set(this.selected());
|
|
4231
4770
|
const rows = this.paged();
|
|
4232
4771
|
if (this.allPageSelected()) {
|
|
4233
|
-
rows.forEach((r) => next.delete(r));
|
|
4772
|
+
rows.forEach((r) => next.delete(this.idOf(r)));
|
|
4234
4773
|
}
|
|
4235
4774
|
else {
|
|
4236
|
-
rows.forEach((r) => next.add(r));
|
|
4775
|
+
rows.forEach((r) => next.add(this.idOf(r)));
|
|
4237
4776
|
}
|
|
4238
4777
|
this.commitSelection(next);
|
|
4239
4778
|
}
|
|
4240
4779
|
clearSelection() {
|
|
4241
4780
|
this.commitSelection(new Set());
|
|
4242
4781
|
}
|
|
4782
|
+
/** Emit the current row objects whose id is selected (resolved against the
|
|
4783
|
+
* latest data, so consumers always get fresh references). */
|
|
4243
4784
|
commitSelection(next) {
|
|
4244
4785
|
this.selected.set(next);
|
|
4245
|
-
this.selectionChange.emit(
|
|
4786
|
+
this.selectionChange.emit(this.rows().filter((r) => next.has(this.idOf(r))));
|
|
4246
4787
|
}
|
|
4247
4788
|
compare(a, b) {
|
|
4248
4789
|
if (typeof a === 'number' && typeof b === 'number')
|
|
@@ -4250,7 +4791,7 @@ class StrctDatagrid {
|
|
|
4250
4791
|
return String(a ?? '').localeCompare(String(b ?? ''), undefined, { numeric: true });
|
|
4251
4792
|
}
|
|
4252
4793
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: StrctDatagrid, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
4253
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.16", type: StrctDatagrid, isStandalone: true, selector: "strct-datagrid", inputs: { columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: true, transformFunction: null }, rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: true, transformFunction: null }, pageSize: { classPropertyName: "pageSize", publicName: "pageSize", isSignal: true, isRequired: false, transformFunction: null }, selectable: { classPropertyName: "selectable", publicName: "selectable", isSignal: true, isRequired: false, transformFunction: null }, expandable: { classPropertyName: "expandable", publicName: "expandable", isSignal: true, isRequired: false, transformFunction: null }, detailPane: { classPropertyName: "detailPane", publicName: "detailPane", isSignal: true, isRequired: false, transformFunction: null }, compact: { classPropertyName: "compact", publicName: "compact", isSignal: true, isRequired: false, transformFunction: null }, emptyText: { classPropertyName: "emptyText", publicName: "emptyText", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectionChange: "selectionChange" }, host: { properties: { "class.strct-dg-host--compact": "compact()" }, classAttribute: "strct-dg-host" }, queries: [{ propertyName: "detailDef", first: true, predicate: StrctRowDetailDef, descendants: true, isSignal: true }, { propertyName: "actionBarDef", first: true, predicate: StrctDatagridActionBar, descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
4794
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.16", type: StrctDatagrid, isStandalone: true, selector: "strct-datagrid", inputs: { columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: true, transformFunction: null }, rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: true, transformFunction: null }, pageSize: { classPropertyName: "pageSize", publicName: "pageSize", isSignal: true, isRequired: false, transformFunction: null }, selectable: { classPropertyName: "selectable", publicName: "selectable", isSignal: true, isRequired: false, transformFunction: null }, expandable: { classPropertyName: "expandable", publicName: "expandable", isSignal: true, isRequired: false, transformFunction: null }, detailPane: { classPropertyName: "detailPane", publicName: "detailPane", isSignal: true, isRequired: false, transformFunction: null }, compact: { classPropertyName: "compact", publicName: "compact", isSignal: true, isRequired: false, transformFunction: null }, emptyText: { classPropertyName: "emptyText", publicName: "emptyText", isSignal: true, isRequired: false, transformFunction: null }, rowId: { classPropertyName: "rowId", publicName: "rowId", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectionChange: "selectionChange" }, host: { properties: { "class.strct-dg-host--compact": "compact()" }, classAttribute: "strct-dg-host" }, queries: [{ propertyName: "detailDef", first: true, predicate: StrctRowDetailDef, descendants: true, isSignal: true }, { propertyName: "actionBarDef", first: true, predicate: StrctDatagridActionBar, descendants: true, isSignal: true }, { propertyName: "cellDefs", predicate: StrctCellDef, isSignal: true }], ngImport: i0, template: `
|
|
4254
4795
|
@if (actionBarDef()) {
|
|
4255
4796
|
<div class="strct-dg__toolbar"><ng-content select="[strctDatagridActionBar]" /></div>
|
|
4256
4797
|
}
|
|
@@ -4306,7 +4847,7 @@ class StrctDatagrid {
|
|
|
4306
4847
|
</tr>
|
|
4307
4848
|
</thead>
|
|
4308
4849
|
<tbody>
|
|
4309
|
-
@for (row of paged(); track
|
|
4850
|
+
@for (row of paged(); track rowKey(row)) {
|
|
4310
4851
|
<tr
|
|
4311
4852
|
[class.strct-dg__row--selected]="isSelected(row)"
|
|
4312
4853
|
[class.strct-dg__row--active]="paneOpen() && row === activeRow()"
|
|
@@ -4350,7 +4891,16 @@ class StrctDatagrid {
|
|
|
4350
4891
|
</td>
|
|
4351
4892
|
}
|
|
4352
4893
|
@for (col of visibleColumns(); track col.key) {
|
|
4353
|
-
<td [style.text-align]="col.align ?? 'start'">
|
|
4894
|
+
<td [style.text-align]="col.align ?? 'start'">
|
|
4895
|
+
@if (cellTemplate(col.key); as tpl) {
|
|
4896
|
+
<ng-container
|
|
4897
|
+
[ngTemplateOutlet]="tpl"
|
|
4898
|
+
[ngTemplateOutletContext]="{ $implicit: row, value: row[col.key], column: col }"
|
|
4899
|
+
/>
|
|
4900
|
+
} @else {
|
|
4901
|
+
{{ row[col.key] }}
|
|
4902
|
+
}
|
|
4903
|
+
</td>
|
|
4354
4904
|
}
|
|
4355
4905
|
</tr>
|
|
4356
4906
|
@if (canExpand() && isExpanded(row)) {
|
|
@@ -4462,7 +5012,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImpo
|
|
|
4462
5012
|
</tr>
|
|
4463
5013
|
</thead>
|
|
4464
5014
|
<tbody>
|
|
4465
|
-
@for (row of paged(); track
|
|
5015
|
+
@for (row of paged(); track rowKey(row)) {
|
|
4466
5016
|
<tr
|
|
4467
5017
|
[class.strct-dg__row--selected]="isSelected(row)"
|
|
4468
5018
|
[class.strct-dg__row--active]="paneOpen() && row === activeRow()"
|
|
@@ -4506,7 +5056,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImpo
|
|
|
4506
5056
|
</td>
|
|
4507
5057
|
}
|
|
4508
5058
|
@for (col of visibleColumns(); track col.key) {
|
|
4509
|
-
<td [style.text-align]="col.align ?? 'start'">
|
|
5059
|
+
<td [style.text-align]="col.align ?? 'start'">
|
|
5060
|
+
@if (cellTemplate(col.key); as tpl) {
|
|
5061
|
+
<ng-container
|
|
5062
|
+
[ngTemplateOutlet]="tpl"
|
|
5063
|
+
[ngTemplateOutletContext]="{ $implicit: row, value: row[col.key], column: col }"
|
|
5064
|
+
/>
|
|
5065
|
+
} @else {
|
|
5066
|
+
{{ row[col.key] }}
|
|
5067
|
+
}
|
|
5068
|
+
</td>
|
|
4510
5069
|
}
|
|
4511
5070
|
</tr>
|
|
4512
5071
|
@if (canExpand() && isExpanded(row)) {
|
|
@@ -4562,7 +5121,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImpo
|
|
|
4562
5121
|
class: 'strct-dg-host',
|
|
4563
5122
|
'[class.strct-dg-host--compact]': 'compact()',
|
|
4564
5123
|
}, styles: [".strct-dg-host{display:block}.strct-dg{width:100%;border-collapse:collapse;font-size:13px;border:1px solid var(--b2);border-radius:8px;overflow:hidden}.strct-dg th,.strct-dg td{padding:9px 13px;text-align:left;border-bottom:1px solid var(--b1)}.strct-dg-host--compact .strct-dg th,.strct-dg-host--compact .strct-dg td{padding:5px 11px}.strct-dg th{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.4px;color:var(--t2);background:var(--bg-2);white-space:nowrap;-webkit-user-select:none;user-select:none}.strct-dg__th--sortable{cursor:pointer}.strct-dg__th--sortable:hover{color:var(--t1)}.strct-dg__th--sortable:focus-visible{outline:2px solid var(--acc50);outline-offset:-2px}.strct-dg__hd{display:inline-flex;align-items:center;gap:5px}.strct-dg__sorticon{color:var(--t3)}.strct-dg__th--sortable:hover .strct-dg__sorticon{color:var(--acc)}.strct-dg td{color:var(--t1)}.strct-dg tbody tr:last-child td{border-bottom:0}.strct-dg tbody tr:not(.strct-dg__detailrow):hover td{background:var(--acc-s)}.strct-dg__row--selected td{background:var(--acc-m)}.strct-dg__sel{width:1%;white-space:nowrap}.strct-dg__sel input{accent-color:var(--acc);width:15px;height:15px;cursor:pointer}.strct-dg__expandcol,.strct-dg__expandcell{width:1%;white-space:nowrap}.strct-dg__expandbtn{display:inline-flex;padding:3px;border:0;border-radius:4px;background:transparent;color:var(--t3);cursor:pointer;transition:transform .15s ease,color .15s ease}.strct-dg__expandbtn:hover{color:var(--t1);background:var(--bg-3)}.strct-dg__expandbtn--open{transform:rotate(90deg);color:var(--acc)}.strct-dg__detailbtn{display:inline-flex;padding:3px;border:0;border-radius:4px;background:transparent;color:var(--t3);cursor:pointer;transition:color .14s ease,background .14s ease}.strct-dg__detailbtn:hover{color:var(--acc);background:var(--bg-3)}.strct-dg__detailbtn--active{color:var(--acc);background:var(--acc-m)}.strct-dg__detailrow td{background:var(--bg-2);padding:0}.strct-dg__detail{padding:14px 16px;font-size:13px;color:var(--t2)}.strct-dg__layout{display:flex;gap:14px;align-items:flex-start}.strct-dg__layout--paned .strct-dg{width:auto;min-width:180px;max-width:260px;flex-shrink:0}.strct-dg__row--clickable{cursor:pointer}.strct-dg__row--active td{background:var(--acc-m)}.strct-dg__layout--paned .strct-dg__row--active td:last-child{position:relative;padding-right:26px}.strct-dg__layout--paned .strct-dg__row--active td:last-child:after{content:\"\";position:absolute;right:11px;top:50%;width:6px;height:6px;border-top:1.6px solid var(--acc);border-right:1.6px solid var(--acc);transform:translateY(-50%) rotate(45deg)}.strct-dg__pane{flex:1;min-width:0;align-self:stretch;background:var(--bg-1);border:1px solid var(--b2);border-left:2px solid var(--acc);border-radius:8px;overflow:hidden;animation:strct-dg-pane-in .14s ease}.strct-dg__pane-head{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:11px 14px;border-bottom:1px solid var(--b1);font-size:13px;font-weight:600;color:var(--t1)}.strct-dg__pane-close{display:inline-flex;padding:3px;border:0;border-radius:4px;background:transparent;color:var(--t3);cursor:pointer}.strct-dg__pane-close:hover{color:var(--t1);background:var(--bg-3)}.strct-dg__pane-body{padding:14px 16px;font-size:13px;color:var(--t2)}@keyframes strct-dg-pane-in{0%{opacity:0;transform:translate(8px)}}.strct-dg__empty{text-align:center;color:var(--t3);padding:22px}.strct-dg__toolbar{display:flex;align-items:center;gap:8px;flex-wrap:wrap;padding:8px 10px;margin-bottom:10px;background:var(--bg-2);border:1px solid var(--b2);border-radius:8px}.strct-dg__actionbar{display:flex;align-items:center;gap:14px;padding:8px 12px;margin-bottom:10px;background:var(--acc-m);border:1px solid var(--acc30);border-radius:7px;font-size:13px;animation:strct-dg-bar-in .12s ease}.strct-dg__actionbar-count{color:var(--acc);font-weight:600}.strct-dg__actionbar-clear{border:0;background:transparent;color:var(--t2);cursor:pointer;font-size:12px;padding:2px 4px}.strct-dg__actionbar-clear:hover{color:var(--t1)}.strct-dg__actionbar-actions{display:flex;gap:8px;margin-left:auto}@keyframes strct-dg-bar-in{0%{opacity:0;transform:translateY(-4px)}}.strct-dg__foot{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-top:12px;flex-wrap:wrap}.strct-dg__count{font-size:12px;color:var(--t2)}\n"] }]
|
|
4565
|
-
}], ctorParameters: () => [], propDecorators: { columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: true }] }], rows: [{ type: i0.Input, args: [{ isSignal: true, alias: "rows", required: true }] }], pageSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSize", required: false }] }], selectable: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectable", required: false }] }], expandable: [{ type: i0.Input, args: [{ isSignal: true, alias: "expandable", required: false }] }], detailPane: [{ type: i0.Input, args: [{ isSignal: true, alias: "detailPane", required: false }] }], compact: [{ type: i0.Input, args: [{ isSignal: true, alias: "compact", required: false }] }], emptyText: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyText", required: false }] }], selectionChange: [{ type: i0.Output, args: ["selectionChange"] }], detailDef: [{ type: i0.ContentChild, args: [i0.forwardRef(() => StrctRowDetailDef), { isSignal: true }] }], actionBarDef: [{ type: i0.ContentChild, args: [i0.forwardRef(() => StrctDatagridActionBar), { isSignal: true }] }] } });
|
|
5124
|
+
}], ctorParameters: () => [], propDecorators: { columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: true }] }], rows: [{ type: i0.Input, args: [{ isSignal: true, alias: "rows", required: true }] }], pageSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSize", required: false }] }], selectable: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectable", required: false }] }], expandable: [{ type: i0.Input, args: [{ isSignal: true, alias: "expandable", required: false }] }], detailPane: [{ type: i0.Input, args: [{ isSignal: true, alias: "detailPane", required: false }] }], compact: [{ type: i0.Input, args: [{ isSignal: true, alias: "compact", required: false }] }], emptyText: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyText", required: false }] }], rowId: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowId", required: false }] }], selectionChange: [{ type: i0.Output, args: ["selectionChange"] }], detailDef: [{ type: i0.ContentChild, args: [i0.forwardRef(() => StrctRowDetailDef), { isSignal: true }] }], actionBarDef: [{ type: i0.ContentChild, args: [i0.forwardRef(() => StrctDatagridActionBar), { isSignal: true }] }], cellDefs: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => StrctCellDef), { isSignal: true }] }] } });
|
|
4566
5125
|
|
|
4567
5126
|
/** Vertical timeline container. Wraps `<strct-timeline-item>` children. */
|
|
4568
5127
|
class StrctTimeline {
|
|
@@ -5371,5 +5930,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImpo
|
|
|
5371
5930
|
* Generated bundle index. Do not edit.
|
|
5372
5931
|
*/
|
|
5373
5932
|
|
|
5374
|
-
export { STRCT_ICONS, STRCT_ICON_GROUPS, STRCT_MASKS, STRCT_PALETTES, STRCT_RAW_ICONS, StrctAccordion, StrctAccordionPanel, StrctAlert, StrctAvatar, StrctBadge, StrctBreadcrumb, StrctBreadcrumbItem, StrctButton, StrctButtonGroup, StrctCard, StrctCardBlock, StrctCardFooter, StrctCardHeader, StrctCascadeHost, StrctCascadeNode, StrctCascadeSelect, StrctChart, StrctCheckbox, StrctChips, StrctColorPicker, StrctCombobox, StrctContextMenu, StrctDatagrid, StrctDatagridActionBar, StrctDatepicker, StrctDivider, StrctDonut, StrctDropdown, StrctDropdownDivider, StrctDropdownItem, StrctFile, StrctFooter, StrctGauge, StrctHeader, StrctIcon, StrctInput, StrctInputMask, StrctInputOtp, StrctKnob, StrctLogin, StrctModal, StrctNav, StrctNavItem, StrctOverlay, StrctPagination, StrctPassword, StrctProgress, StrctRadio, StrctRadioGroup, StrctRange, StrctRating, StrctRowDetailDef, StrctShell, StrctSignpost, StrctSkeleton, StrctSparkline, StrctSpeedDial, StrctSpinner, StrctStack, StrctStackItem, StrctStep, StrctSubmenu, StrctTab, StrctTable, StrctTabs, StrctTag, StrctThemeService, StrctThemeSwitcher, StrctTimeline, StrctTimelineItem, StrctToastOutlet, StrctToastService, StrctToggle, StrctTooltip, StrctTree, StrctTreeNode, StrctVerticalNav, StrctWizard, registerStrctIcon };
|
|
5933
|
+
export { STRCT_ICONS, STRCT_ICON_GROUPS, STRCT_MASKS, STRCT_PALETTES, STRCT_RAW_ICONS, StrctAccordion, StrctAccordionPanel, StrctAlert, StrctAvatar, StrctBadge, StrctBreadcrumb, StrctBreadcrumbItem, StrctButton, StrctButtonGroup, StrctCard, StrctCardBlock, StrctCardFooter, StrctCardHeader, StrctCascadeHost, StrctCascadeNode, StrctCascadeSelect, StrctCellDef, StrctChart, StrctCheckbox, StrctChips, StrctColorPicker, StrctCombobox, StrctContextMenu, StrctContextMenuTrigger, StrctDatagrid, StrctDatagridActionBar, StrctDatepicker, StrctDivider, StrctDonut, StrctDropdown, StrctDropdownDivider, StrctDropdownItem, StrctFile, StrctFooter, StrctGauge, StrctHeader, StrctIcon, StrctInput, StrctInputMask, StrctInputOtp, StrctKnob, StrctLogin, StrctMenuPanel, StrctModal, StrctNav, StrctNavItem, StrctOverlay, StrctPagination, StrctPassword, StrctProgress, StrctRadio, StrctRadioGroup, StrctRange, StrctRating, StrctRowDetailDef, StrctShell, StrctSignpost, StrctSkeleton, StrctSparkline, StrctSpeedDial, StrctSpinner, StrctStack, StrctStackItem, StrctStep, StrctSubmenu, StrctTab, StrctTable, StrctTabs, StrctTag, StrctThemeService, StrctThemeSwitcher, StrctTimeline, StrctTimelineItem, StrctToastOutlet, StrctToastService, StrctToggle, StrctTooltip, StrctTree, StrctTreeNode, StrctVerticalNav, StrctWizard, registerStrctIcon };
|
|
5375
5934
|
//# sourceMappingURL=akcelik-strct.mjs.map
|