@ship-ui/core 0.22.14 → 0.22.15
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 +46 -0
- package/assets/mcp/components.json +578 -1
- package/bin/src/scanner.zig +9 -18
- package/fesm2022/ship-ui-core-sh-form-field-experimental.mjs +17 -2
- package/fesm2022/ship-ui-core-sh-form-field-experimental.mjs.map +1 -1
- package/fesm2022/ship-ui-core-ship-a11y-keybindings.mjs +433 -0
- package/fesm2022/ship-ui-core-ship-a11y-keybindings.mjs.map +1 -0
- package/fesm2022/ship-ui-core-ship-accordion.mjs +1 -0
- package/fesm2022/ship-ui-core-ship-accordion.mjs.map +1 -1
- package/fesm2022/ship-ui-core-ship-alert.mjs +3 -2
- package/fesm2022/ship-ui-core-ship-alert.mjs.map +1 -1
- package/fesm2022/ship-ui-core-ship-blueprint.mjs +14 -9
- package/fesm2022/ship-ui-core-ship-blueprint.mjs.map +1 -1
- package/fesm2022/ship-ui-core-ship-checkbox.mjs +16 -14
- package/fesm2022/ship-ui-core-ship-checkbox.mjs.map +1 -1
- package/fesm2022/ship-ui-core-ship-color-picker.mjs +3 -1
- package/fesm2022/ship-ui-core-ship-color-picker.mjs.map +1 -1
- package/fesm2022/ship-ui-core-ship-datepicker.mjs +51 -29
- package/fesm2022/ship-ui-core-ship-datepicker.mjs.map +1 -1
- package/fesm2022/ship-ui-core-ship-dialog.mjs +10 -5
- package/fesm2022/ship-ui-core-ship-dialog.mjs.map +1 -1
- package/fesm2022/ship-ui-core-ship-divider.mjs +4 -2
- package/fesm2022/ship-ui-core-ship-divider.mjs.map +1 -1
- package/fesm2022/ship-ui-core-ship-editor.mjs +2673 -0
- package/fesm2022/ship-ui-core-ship-editor.mjs.map +1 -0
- package/fesm2022/ship-ui-core-ship-icon.mjs +2 -2
- package/fesm2022/ship-ui-core-ship-icon.mjs.map +1 -1
- package/fesm2022/ship-ui-core-ship-list.mjs +4 -2
- package/fesm2022/ship-ui-core-ship-list.mjs.map +1 -1
- package/fesm2022/ship-ui-core-ship-menu.mjs +8 -5
- package/fesm2022/ship-ui-core-ship-menu.mjs.map +1 -1
- package/fesm2022/ship-ui-core-ship-popover.mjs +10 -5
- package/fesm2022/ship-ui-core-ship-popover.mjs.map +1 -1
- package/fesm2022/ship-ui-core-ship-progress-bar.mjs +5 -1
- package/fesm2022/ship-ui-core-ship-progress-bar.mjs.map +1 -1
- package/fesm2022/ship-ui-core-ship-radio.mjs +16 -14
- package/fesm2022/ship-ui-core-ship-radio.mjs.map +1 -1
- package/fesm2022/ship-ui-core-ship-select.mjs +9 -9
- package/fesm2022/ship-ui-core-ship-select.mjs.map +1 -1
- package/fesm2022/ship-ui-core-ship-sidenav.mjs +2 -2
- package/fesm2022/ship-ui-core-ship-sidenav.mjs.map +1 -1
- package/fesm2022/ship-ui-core-ship-spinner.mjs +3 -1
- package/fesm2022/ship-ui-core-ship-spinner.mjs.map +1 -1
- package/fesm2022/ship-ui-core-ship-spotlight.mjs +77 -24
- package/fesm2022/ship-ui-core-ship-spotlight.mjs.map +1 -1
- package/fesm2022/ship-ui-core-ship-table.mjs +94 -119
- package/fesm2022/ship-ui-core-ship-table.mjs.map +1 -1
- package/fesm2022/ship-ui-core-ship-theme-toggle.mjs +2 -2
- package/fesm2022/ship-ui-core-ship-theme-toggle.mjs.map +1 -1
- package/fesm2022/ship-ui-core-ship-toggle-card.mjs +24 -3
- package/fesm2022/ship-ui-core-ship-toggle-card.mjs.map +1 -1
- package/fesm2022/ship-ui-core-ship-toggle.mjs +16 -14
- package/fesm2022/ship-ui-core-ship-toggle.mjs.map +1 -1
- package/fesm2022/ship-ui-core-ship-tree.mjs +2 -2
- package/fesm2022/ship-ui-core-ship-tree.mjs.map +1 -1
- package/fesm2022/ship-ui-core-ship-virtual-scroll.mjs +2 -2
- package/fesm2022/ship-ui-core-ship-virtual-scroll.mjs.map +1 -1
- package/fesm2022/ship-ui-core.mjs +36 -23
- package/fesm2022/ship-ui-core.mjs.map +1 -1
- package/package.json +33 -2
- package/types/ship-ui-core-sh-form-field-experimental.d.ts +2 -0
- package/types/ship-ui-core-ship-a11y-keybindings.d.ts +102 -0
- package/types/ship-ui-core-ship-blueprint.d.ts +1 -1
- package/types/ship-ui-core-ship-checkbox.d.ts +2 -1
- package/types/ship-ui-core-ship-editor.d.ts +168 -0
- package/types/ship-ui-core-ship-radio.d.ts +2 -1
- package/types/ship-ui-core-ship-spotlight.d.ts +1 -1
- package/types/ship-ui-core-ship-table.d.ts +1 -0
- package/types/ship-ui-core-ship-toggle-card.d.ts +1 -0
- package/types/ship-ui-core-ship-toggle.d.ts +2 -1
- package/types/ship-ui-core.d.ts +3 -0
- package/bin/ship-fg-scanner +0 -0
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { input, model, effect, ChangeDetectionStrategy, ViewEncapsulation, Component } from '@angular/core';
|
|
2
|
+
import { inject, input, model, effect, ChangeDetectionStrategy, ViewEncapsulation, Component } from '@angular/core';
|
|
3
3
|
import { ShipIcon } from '@ship-ui/core/ship-icon';
|
|
4
|
+
import { ShipA11yKeybindingsService } from '@ship-ui/core/ship-a11y-keybindings';
|
|
4
5
|
import { shipComponentClasses } from '@ship-ui/core';
|
|
5
6
|
|
|
6
7
|
class ShipToggleCard {
|
|
7
8
|
constructor() {
|
|
9
|
+
this.#keybindings = inject(ShipA11yKeybindingsService);
|
|
8
10
|
this.disableToggle = input(false, /* @ts-ignore */
|
|
9
11
|
...(ngDevMode ? [{ debugName: "disableToggle" }] : /* istanbul ignore next */ []));
|
|
10
12
|
this.isActive = model(false, /* @ts-ignore */
|
|
@@ -24,13 +26,26 @@ class ShipToggleCard {
|
|
|
24
26
|
variant: this.variant,
|
|
25
27
|
});
|
|
26
28
|
}
|
|
29
|
+
#keybindings;
|
|
27
30
|
#disabledEffect;
|
|
28
31
|
toggle() {
|
|
29
32
|
this.isActive.set(!this.isActive());
|
|
30
33
|
}
|
|
34
|
+
handleKeyDown(event) {
|
|
35
|
+
if (this.#keybindings.matches(event, 'toggle-card.toggle')) {
|
|
36
|
+
event.preventDefault();
|
|
37
|
+
this.toggle();
|
|
38
|
+
}
|
|
39
|
+
}
|
|
31
40
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.0", ngImport: i0, type: ShipToggleCard, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
32
41
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.0", type: ShipToggleCard, isStandalone: true, selector: "sh-toggle-card", inputs: { disableToggle: { classPropertyName: "disableToggle", publicName: "disableToggle", isSignal: true, isRequired: false, transformFunction: null }, isActive: { classPropertyName: "isActive", publicName: "isActive", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { isActive: "isActiveChange" }, host: { properties: { "class.active": "isActive()", "class": "hostClasses()" } }, ngImport: i0, template: `
|
|
33
|
-
<h3
|
|
42
|
+
<h3
|
|
43
|
+
role="button"
|
|
44
|
+
[attr.tabindex]="disableToggle() ? null : '0'"
|
|
45
|
+
[attr.aria-expanded]="disableToggle() ? null : (isActive() ? 'true' : 'false')"
|
|
46
|
+
[attr.aria-disabled]="disableToggle() ? 'true' : null"
|
|
47
|
+
(click)="!disableToggle() && toggle()"
|
|
48
|
+
(keydown)="!disableToggle() && handleKeyDown($event)">
|
|
34
49
|
<ng-content select="[title]">Title</ng-content>
|
|
35
50
|
|
|
36
51
|
@if (!disableToggle()) {
|
|
@@ -48,7 +63,13 @@ class ShipToggleCard {
|
|
|
48
63
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.0", ngImport: i0, type: ShipToggleCard, decorators: [{
|
|
49
64
|
type: Component,
|
|
50
65
|
args: [{ selector: 'sh-toggle-card', encapsulation: ViewEncapsulation.None, imports: [ShipIcon], template: `
|
|
51
|
-
<h3
|
|
66
|
+
<h3
|
|
67
|
+
role="button"
|
|
68
|
+
[attr.tabindex]="disableToggle() ? null : '0'"
|
|
69
|
+
[attr.aria-expanded]="disableToggle() ? null : (isActive() ? 'true' : 'false')"
|
|
70
|
+
[attr.aria-disabled]="disableToggle() ? 'true' : null"
|
|
71
|
+
(click)="!disableToggle() && toggle()"
|
|
72
|
+
(keydown)="!disableToggle() && handleKeyDown($event)">
|
|
52
73
|
<ng-content select="[title]">Title</ng-content>
|
|
53
74
|
|
|
54
75
|
@if (!disableToggle()) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ship-ui-core-ship-toggle-card.mjs","sources":["../../../projects/ship-ui/ship-toggle-card/ship-toggle-card.ts","../../../projects/ship-ui/ship-toggle-card/ship-ui-core-ship-toggle-card.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, effect, input, model, ViewEncapsulation } from '@angular/core';\nimport { ShipIcon } from '@ship-ui/core/ship-icon';\nimport { shipComponentClasses } from '@ship-ui/core';\nimport { ShipCardVariant, ShipColor } from '@ship-ui/core';\n\n@Component({\n selector: 'sh-toggle-card',\n styleUrl: './ship-toggle-card.scss',\n encapsulation: ViewEncapsulation.None,\n imports: [ShipIcon],\n template: `\n <h3 (click)=\"!disableToggle() && toggle()\">\n <ng-content select=\"[title]\">Title</ng-content>\n\n @if (!disableToggle()) {\n <sh-icon class=\"toggle-icon\">caret-down</sh-icon>\n }\n </h3>\n\n <div class=\"collapsable\">\n <div class=\"content\">\n <ng-content />\n </div>\n </div>\n `,\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '[class.active]': 'isActive()',\n '[class]': 'hostClasses()',\n },\n})\nexport class ShipToggleCard {\n disableToggle = input(false);\n isActive = model<boolean>(false);\n\n #disabledEffect = effect(() => {\n if (this.disableToggle()) {\n this.isActive.set(true);\n }\n });\n\n color = input<ShipColor | null>(null);\n variant = input<ShipCardVariant | null>(null);\n hostClasses = shipComponentClasses('card', {\n color: this.color,\n variant: this.variant,\n });\n\n toggle() {\n this.isActive.set(!this.isActive());\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ship-ui-core-ship-toggle-card.mjs","sources":["../../../projects/ship-ui/ship-toggle-card/ship-toggle-card.ts","../../../projects/ship-ui/ship-toggle-card/ship-ui-core-ship-toggle-card.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, effect, inject, input, model, ViewEncapsulation } from '@angular/core';\nimport { ShipIcon } from '@ship-ui/core/ship-icon';\nimport { ShipA11yKeybindingsService } from '@ship-ui/core/ship-a11y-keybindings';\nimport { shipComponentClasses } from '@ship-ui/core';\nimport { ShipCardVariant, ShipColor } from '@ship-ui/core';\n\n@Component({\n selector: 'sh-toggle-card',\n styleUrl: './ship-toggle-card.scss',\n encapsulation: ViewEncapsulation.None,\n imports: [ShipIcon],\n template: `\n <h3\n role=\"button\"\n [attr.tabindex]=\"disableToggle() ? null : '0'\"\n [attr.aria-expanded]=\"disableToggle() ? null : (isActive() ? 'true' : 'false')\"\n [attr.aria-disabled]=\"disableToggle() ? 'true' : null\"\n (click)=\"!disableToggle() && toggle()\"\n (keydown)=\"!disableToggle() && handleKeyDown($event)\">\n <ng-content select=\"[title]\">Title</ng-content>\n\n @if (!disableToggle()) {\n <sh-icon class=\"toggle-icon\">caret-down</sh-icon>\n }\n </h3>\n\n <div class=\"collapsable\">\n <div class=\"content\">\n <ng-content />\n </div>\n </div>\n `,\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '[class.active]': 'isActive()',\n '[class]': 'hostClasses()',\n },\n})\nexport class ShipToggleCard {\n #keybindings = inject(ShipA11yKeybindingsService);\n\n disableToggle = input(false);\n isActive = model<boolean>(false);\n\n #disabledEffect = effect(() => {\n if (this.disableToggle()) {\n this.isActive.set(true);\n }\n });\n\n color = input<ShipColor | null>(null);\n variant = input<ShipCardVariant | null>(null);\n hostClasses = shipComponentClasses('card', {\n color: this.color,\n variant: this.variant,\n });\n\n toggle() {\n this.isActive.set(!this.isActive());\n }\n\n handleKeyDown(event: KeyboardEvent) {\n if (this.#keybindings.matches(event, 'toggle-card.toggle')) {\n event.preventDefault();\n this.toggle();\n }\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;;;;MAsCa,cAAc,CAAA;AAhC3B,IAAA,WAAA,GAAA;AAiCE,QAAA,IAAA,CAAA,YAAY,GAAG,MAAM,CAAC,0BAA0B,CAAC;QAEjD,IAAA,CAAA,aAAa,GAAG,KAAK,CAAC,KAAK;0FAAC;QAC5B,IAAA,CAAA,QAAQ,GAAG,KAAK,CAAU,KAAK;qFAAC;AAEhC,QAAA,IAAA,CAAA,eAAe,GAAG,MAAM,CAAC,MAAK;AAC5B,YAAA,IAAI,IAAI,CAAC,aAAa,EAAE,EAAE;AACxB,gBAAA,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC;YACzB;QACF,CAAC;4FAAC;QAEF,IAAA,CAAA,KAAK,GAAG,KAAK,CAAmB,IAAI;kFAAC;QACrC,IAAA,CAAA,OAAO,GAAG,KAAK,CAAyB,IAAI;oFAAC;AAC7C,QAAA,IAAA,CAAA,WAAW,GAAG,oBAAoB,CAAC,MAAM,EAAE;YACzC,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,OAAO,EAAE,IAAI,CAAC,OAAO;AACtB,SAAA,CAAC;AAYH,IAAA;AA5BC,IAAA,YAAY;AAKZ,IAAA,eAAe;IAaf,MAAM,GAAA;QACJ,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;IACrC;AAEA,IAAA,aAAa,CAAC,KAAoB,EAAA;QAChC,IAAI,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,KAAK,EAAE,oBAAoB,CAAC,EAAE;YAC1D,KAAK,CAAC,cAAc,EAAE;YACtB,IAAI,CAAC,MAAM,EAAE;QACf;IACF;8GA5BW,cAAc,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAAd,IAAA,SAAA,IAAA,CAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,cAAc,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,gBAAA,EAAA,MAAA,EAAA,EAAA,aAAA,EAAA,EAAA,iBAAA,EAAA,eAAA,EAAA,UAAA,EAAA,eAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,OAAA,EAAA,EAAA,iBAAA,EAAA,SAAA,EAAA,UAAA,EAAA,SAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,QAAA,EAAA,gBAAA,EAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,cAAA,EAAA,YAAA,EAAA,OAAA,EAAA,eAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EA3Bf;;;;;;;;;;;;;;;;;;;;AAoBT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,q7BAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EArBS,QAAQ,EAAA,QAAA,EAAA,SAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,MAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,aAAA,EAAA,EAAA,CAAA,iBAAA,CAAA,IAAA,EAAA,CAAA,CAAA;;2FA4BP,cAAc,EAAA,UAAA,EAAA,CAAA;kBAhC1B,SAAS;+BACE,gBAAgB,EAAA,aAAA,EAEX,iBAAiB,CAAC,IAAI,WAC5B,CAAC,QAAQ,CAAC,EAAA,QAAA,EACT;;;;;;;;;;;;;;;;;;;;GAoBT,EAAA,eAAA,EACgB,uBAAuB,CAAC,MAAM,EAAA,IAAA,EACzC;AACJ,wBAAA,gBAAgB,EAAE,YAAY;AAC9B,wBAAA,SAAS,EAAE,eAAe;AAC3B,qBAAA,EAAA,MAAA,EAAA,CAAA,q7BAAA,CAAA,EAAA;;;ACpCH;;AAEG;;;;"}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
2
|
import { inject, ElementRef, viewChild, model, input, HostListener, ChangeDetectionStrategy, ViewEncapsulation, Component } from '@angular/core';
|
|
3
3
|
import { contentProjectionSignal, shipComponentClasses } from '@ship-ui/core';
|
|
4
|
+
import { ShipA11yKeybindingsService } from '@ship-ui/core/ship-a11y-keybindings';
|
|
4
5
|
|
|
5
6
|
class ShipToggle {
|
|
6
7
|
constructor() {
|
|
7
8
|
this._elementRef = inject(ElementRef);
|
|
9
|
+
this.#keybindings = inject(ShipA11yKeybindingsService);
|
|
8
10
|
this.internalInput = viewChild('internalInput', /* @ts-ignore */
|
|
9
11
|
...(ngDevMode ? [{ debugName: "internalInput" }] : /* istanbul ignore next */ []));
|
|
10
12
|
this.projectedInputs = contentProjectionSignal('input:not(.internal-input)', {
|
|
@@ -29,24 +31,27 @@ class ShipToggle {
|
|
|
29
31
|
readonly: this.readonly,
|
|
30
32
|
});
|
|
31
33
|
}
|
|
34
|
+
#keybindings;
|
|
32
35
|
onInternalInputChange(event) {
|
|
33
36
|
if (this.disabled())
|
|
34
37
|
return;
|
|
35
38
|
const input = event.target;
|
|
36
39
|
this.checked.set(input.checked);
|
|
37
40
|
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
inputEl
|
|
41
|
+
onKeyDown(event) {
|
|
42
|
+
if (this.#keybindings.matches(event, 'toggle.toggle')) {
|
|
43
|
+
const inputEl = this.internalInput()?.nativeElement;
|
|
44
|
+
if (inputEl && getComputedStyle(inputEl).display !== 'none') {
|
|
45
|
+
inputEl.click();
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
this._elementRef.nativeElement.click();
|
|
49
|
+
}
|
|
50
|
+
event.preventDefault();
|
|
42
51
|
}
|
|
43
|
-
else {
|
|
44
|
-
this._elementRef.nativeElement.click();
|
|
45
|
-
}
|
|
46
|
-
event.preventDefault();
|
|
47
52
|
}
|
|
48
53
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.0", ngImport: i0, type: ShipToggle, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
49
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.0", type: ShipToggle, isStandalone: true, selector: "sh-toggle", inputs: { checked: { classPropertyName: "checked", publicName: "checked", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, noInternalInput: { classPropertyName: "noInternalInput", publicName: "noInternalInput", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { checked: "checkedChange" }, host: { listeners: { "keydown
|
|
54
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.0", type: ShipToggle, isStandalone: true, selector: "sh-toggle", inputs: { checked: { classPropertyName: "checked", publicName: "checked", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, noInternalInput: { classPropertyName: "noInternalInput", publicName: "noInternalInput", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { checked: "checkedChange" }, host: { listeners: { "keydown": "onKeyDown($event)" }, properties: { "class": "hostClasses()", "attr.disabled": "disabled() ? \"\" : null", "attr.role": "noInternalInput() ? \"switch\" : null", "attr.aria-checked": "noInternalInput() ? checked() : null", "attr.tabindex": "noInternalInput() ? (disabled() ? \"-1\" : \"0\") : null" } }, viewQueries: [{ propertyName: "internalInput", first: true, predicate: ["internalInput"], descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
50
55
|
<div class="box">
|
|
51
56
|
<div class="knob"></div>
|
|
52
57
|
</div>
|
|
@@ -89,12 +94,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.0", ngImpor
|
|
|
89
94
|
'[attr.aria-checked]': 'noInternalInput() ? checked() : null',
|
|
90
95
|
'[attr.tabindex]': 'noInternalInput() ? (disabled() ? "-1" : "0") : null',
|
|
91
96
|
}, styles: ["sh-toggle{--toggle-bg: var(--base-4);--toggle-b: 0;--togglek-bg: var(--base-2);--togglek-bs: var(--box-shadow-20);display:flex;align-items:center;gap:.5rem;cursor:pointer;-webkit-user-select:none;user-select:none;position:relative}sh-toggle:focus-visible>.box,sh-toggle:has(input:focus-visible)>.box{outline:2px solid var(--primary-8);outline-offset:2px}sh-toggle label{display:flex;align-items:center;gap:.5rem;position:relative;z-index:1}sh-toggle .box{display:block;width:2.125rem;min-width:2.125rem;height:1.25rem;cursor:pointer;position:relative;border-radius:999px;background:var(--toggle-bg);border:var(--toggle-b);transition:background .15s linear}sh-toggle>input[type=checkbox]{appearance:none;position:absolute;inset:0;cursor:pointer;z-index:0;margin:0}sh-toggle>input[type=checkbox]:focus,sh-toggle>input[type=checkbox]:focus-visible{outline:none}sh-toggle:has(>input:not(.internal-input))>input.internal-input{display:none}sh-toggle:has(input[disabled]),sh-toggle[disabled]:not([disabled=false]){opacity:.5;pointer-events:none;-webkit-user-select:none;user-select:none;cursor:initial}sh-toggle .knob{position:absolute;top:.125rem;left:.125rem;width:1rem;height:1rem;border-radius:50%;background:var(--togglek-bg);box-shadow:var(--togglek-bs);box-sizing:border-box;transition:left 125ms ease-in-out}sh-toggle:has(input[type=checkbox]:checked),sh-toggle.active{--togglek-bg: var(--base-8)}sh-toggle:has(input[type=checkbox]:checked) .knob,sh-toggle.active .knob{left:1rem}sh-toggle:has(input[type=checkbox]:checked).primary,sh-toggle.active.primary{--toggle-bg: var(--primary-3);--togglek-bg: var(--primary-8)}sh-toggle:has(input[type=checkbox]:checked).accent,sh-toggle.active.accent{--toggle-bg: var(--accent-3);--togglek-bg: var(--accent-8)}sh-toggle:has(input[type=checkbox]:checked).warn,sh-toggle.active.warn{--toggle-bg: var(--warn-3);--togglek-bg: var(--warn-8)}sh-toggle:has(input[type=checkbox]:checked).error,sh-toggle.active.error{--toggle-bg: var(--error-3);--togglek-bg: var(--error-8)}sh-toggle:has(input[type=checkbox]:checked).success,sh-toggle.active.success{--toggle-bg: var(--success-3);--togglek-bg: var(--success-8)}sh-toggle.outlined{--toggle-bg: var(--base-1);--togglek-bg: var(--base-5);--togglek-bs: none;--toggle-b: 1px solid var(--base-5)}sh-toggle.outlined .knob{width:.875rem;height:.875rem}sh-toggle.outlined.active{--togglek-bg: var(--base-8);--toggle-b: 1px solid var(--base-8)}sh-toggle.outlined.active.primary{--togglek-bg: var(--primary-8);--toggle-b: 1px solid var(--primary-8)}sh-toggle.outlined.active.accent{--togglek-bg: var(--accent-8);--toggle-b: 1px solid var(--accent-8)}sh-toggle.outlined.active.warn{--togglek-bg: var(--warn-8);--toggle-b: 1px solid var(--warn-8)}sh-toggle.outlined.active.error{--togglek-bg: var(--error-8);--toggle-b: 1px solid var(--error-8)}sh-toggle.outlined.active.success{--togglek-bg: var(--success-8);--toggle-b: 1px solid var(--success-8)}sh-toggle.simple{--togglek-bg: #fff}sh-toggle.simple:has(input[type=checkbox]:checked),sh-toggle.simple.active{--togglek-bg: var(--base-8)}sh-toggle.simple:has(input[type=checkbox]:checked).primary,sh-toggle.simple.active.primary{--togglek-bg: var(--primary-8);--toggle-bg: var(--primary-3)}sh-toggle.simple:has(input[type=checkbox]:checked).accent,sh-toggle.simple.active.accent{--togglek-bg: var(--accent-8);--toggle-bg: var(--accent-3)}sh-toggle.simple:has(input[type=checkbox]:checked).warn,sh-toggle.simple.active.warn{--togglek-bg: var(--warn-8);--toggle-bg: var(--warn-3)}sh-toggle.simple:has(input[type=checkbox]:checked).error,sh-toggle.simple.active.error{--togglek-bg: var(--error-8);--toggle-bg: var(--error-3)}sh-toggle.simple:has(input[type=checkbox]:checked).success,sh-toggle.simple.active.success{--togglek-bg: var(--success-8);--toggle-bg: var(--success-3)}sh-toggle.flat{--togglek-bg: #fff}sh-toggle.flat:has(input[type=checkbox]:checked),sh-toggle.flat.active{--togglek-bg: #fff;--toggle-bg: var(--base-8)}sh-toggle.flat:has(input[type=checkbox]:checked).primary,sh-toggle.flat.active.primary{--toggle-bg: var(--primary-8)}sh-toggle.flat:has(input[type=checkbox]:checked).accent,sh-toggle.flat.active.accent{--toggle-bg: var(--accent-8)}sh-toggle.flat:has(input[type=checkbox]:checked).warn,sh-toggle.flat.active.warn{--toggle-bg: var(--warn-8)}sh-toggle.flat:has(input[type=checkbox]:checked).error,sh-toggle.flat.active.error{--toggle-bg: var(--error-8)}sh-toggle.flat:has(input[type=checkbox]:checked).success,sh-toggle.flat.active.success{--toggle-bg: var(--success-8)}sh-toggle.raised{--togglek-bg: #fff}sh-toggle.raised:has(input[type=checkbox]:checked),sh-toggle.raised.active{--toggle-bg: var(--base-g2);--togglek-bg: #fff}sh-toggle.raised:has(input[type=checkbox]:checked).primary,sh-toggle.raised.active.primary{--toggle-bg: var(--primary-g2)}sh-toggle.raised:has(input[type=checkbox]:checked).accent,sh-toggle.raised.active.accent{--toggle-bg: var(--accent-g2)}sh-toggle.raised:has(input[type=checkbox]:checked).warn,sh-toggle.raised.active.warn{--toggle-bg: var(--warn-g2)}sh-toggle.raised:has(input[type=checkbox]:checked).error,sh-toggle.raised.active.error{--toggle-bg: var(--error-g2)}sh-toggle.raised:has(input[type=checkbox]:checked).success,sh-toggle.raised.active.success{--toggle-bg: var(--success-g2)}\n"] }]
|
|
92
|
-
}], propDecorators: { internalInput: [{ type: i0.ViewChild, args: ['internalInput', { isSignal: true }] }], checked: [{ type: i0.Input, args: [{ isSignal: true, alias: "checked", required: false }] }, { type: i0.Output, args: ["checkedChange"] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], noInternalInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "noInternalInput", required: false }] }],
|
|
93
|
-
type: HostListener,
|
|
94
|
-
args: ['keydown.enter', ['$event']]
|
|
95
|
-
}, {
|
|
97
|
+
}], propDecorators: { internalInput: [{ type: i0.ViewChild, args: ['internalInput', { isSignal: true }] }], checked: [{ type: i0.Input, args: [{ isSignal: true, alias: "checked", required: false }] }, { type: i0.Output, args: ["checkedChange"] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], noInternalInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "noInternalInput", required: false }] }], onKeyDown: [{
|
|
96
98
|
type: HostListener,
|
|
97
|
-
args: ['keydown
|
|
99
|
+
args: ['keydown', ['$event']]
|
|
98
100
|
}] } });
|
|
99
101
|
|
|
100
102
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ship-ui-core-ship-toggle.mjs","sources":["../../../projects/ship-ui/ship-toggle/ship-toggle.ts","../../../projects/ship-ui/ship-toggle/ship-ui-core-ship-toggle.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, ElementRef, HostListener, inject, input, model, viewChild, ViewEncapsulation } from '@angular/core';\nimport { contentProjectionSignal } from '@ship-ui/core';\nimport { shipComponentClasses } from '@ship-ui/core';\nimport { ShipColor, ShipSheetVariant } from '@ship-ui/core';\n\n@Component({\n selector: 'sh-toggle',\n styleUrl: './ship-toggle.scss',\n encapsulation: ViewEncapsulation.None,\n imports: [],\n template: `\n <div class=\"box\">\n <div class=\"knob\"></div>\n </div>\n\n <ng-content />\n\n @if (projectedInputs().length === 0 && !noInternalInput()) {\n <input\n #internalInput\n type=\"checkbox\"\n class=\"internal-input\"\n [attr.disabled]=\"disabled() ? '' : null\"\n [checked]=\"checked()\"\n (change)=\"onInternalInputChange($event)\" />\n }\n `,\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '[class]': 'hostClasses()',\n '[attr.disabled]': 'disabled() ? \"\" : null',\n '[attr.role]': 'noInternalInput() ? \"switch\" : null',\n '[attr.aria-checked]': 'noInternalInput() ? checked() : null',\n '[attr.tabindex]': 'noInternalInput() ? (disabled() ? \"-1\" : \"0\") : null',\n },\n})\nexport class ShipToggle {\n private readonly _elementRef = inject(ElementRef);\n\n internalInput = viewChild<ElementRef<HTMLInputElement>>('internalInput');\n projectedInputs = contentProjectionSignal<HTMLInputElement>('input:not(.internal-input)', {\n childList: true,\n attributes: true,\n });\n\n checked = model<boolean>(false);\n color = input<ShipColor | null>(null);\n variant = input<ShipSheetVariant | null>(null);\n readonly = input<boolean>(false);\n disabled = input<boolean>(false);\n noInternalInput = input<boolean>(false);\n\n protected onInternalInputChange(event: Event) {\n if (this.disabled()) return;\n\n const input = event.target as HTMLInputElement;\n this.checked.set(input.checked);\n }\n\n hostClasses = shipComponentClasses('toggle', {\n color: this.color,\n variant: this.variant,\n readonly: this.readonly,\n });\n\n @HostListener('keydown
|
|
1
|
+
{"version":3,"file":"ship-ui-core-ship-toggle.mjs","sources":["../../../projects/ship-ui/ship-toggle/ship-toggle.ts","../../../projects/ship-ui/ship-toggle/ship-ui-core-ship-toggle.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, ElementRef, HostListener, inject, input, model, viewChild, ViewEncapsulation } from '@angular/core';\nimport { contentProjectionSignal } from '@ship-ui/core';\nimport { ShipA11yKeybindingsService } from '@ship-ui/core/ship-a11y-keybindings';\nimport { shipComponentClasses } from '@ship-ui/core';\nimport { ShipColor, ShipSheetVariant } from '@ship-ui/core';\n\n@Component({\n selector: 'sh-toggle',\n styleUrl: './ship-toggle.scss',\n encapsulation: ViewEncapsulation.None,\n imports: [],\n template: `\n <div class=\"box\">\n <div class=\"knob\"></div>\n </div>\n\n <ng-content />\n\n @if (projectedInputs().length === 0 && !noInternalInput()) {\n <input\n #internalInput\n type=\"checkbox\"\n class=\"internal-input\"\n [attr.disabled]=\"disabled() ? '' : null\"\n [checked]=\"checked()\"\n (change)=\"onInternalInputChange($event)\" />\n }\n `,\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '[class]': 'hostClasses()',\n '[attr.disabled]': 'disabled() ? \"\" : null',\n '[attr.role]': 'noInternalInput() ? \"switch\" : null',\n '[attr.aria-checked]': 'noInternalInput() ? checked() : null',\n '[attr.tabindex]': 'noInternalInput() ? (disabled() ? \"-1\" : \"0\") : null',\n },\n})\nexport class ShipToggle {\n private readonly _elementRef = inject(ElementRef);\n #keybindings = inject(ShipA11yKeybindingsService);\n\n internalInput = viewChild<ElementRef<HTMLInputElement>>('internalInput');\n projectedInputs = contentProjectionSignal<HTMLInputElement>('input:not(.internal-input)', {\n childList: true,\n attributes: true,\n });\n\n checked = model<boolean>(false);\n color = input<ShipColor | null>(null);\n variant = input<ShipSheetVariant | null>(null);\n readonly = input<boolean>(false);\n disabled = input<boolean>(false);\n noInternalInput = input<boolean>(false);\n\n protected onInternalInputChange(event: Event) {\n if (this.disabled()) return;\n\n const input = event.target as HTMLInputElement;\n this.checked.set(input.checked);\n }\n\n hostClasses = shipComponentClasses('toggle', {\n color: this.color,\n variant: this.variant,\n readonly: this.readonly,\n });\n\n @HostListener('keydown', ['$event'])\n protected onKeyDown(event: KeyboardEvent) {\n if (this.#keybindings.matches(event, 'toggle.toggle')) {\n const inputEl = this.internalInput()?.nativeElement;\n if (inputEl && getComputedStyle(inputEl).display !== 'none') {\n inputEl.click();\n } else {\n this._elementRef.nativeElement.click();\n }\n event.preventDefault();\n }\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
@@ -169,13 +169,13 @@ class ShipTree {
|
|
|
169
169
|
return this.itemIconName() || 'file';
|
|
170
170
|
}
|
|
171
171
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.0", ngImport: i0, type: ShipTree, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
172
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.0", type: ShipTree, isStandalone: true, selector: "sh-tree", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, sortableManager: { classPropertyName: "sortableManager", publicName: "sortableManager", isSignal: true, isRequired: false, transformFunction: null }, selectedId: { classPropertyName: "selectedId", publicName: "selectedId", isSignal: true, isRequired: false, transformFunction: null }, getId: { classPropertyName: "getId", publicName: "getId", isSignal: true, isRequired: false, transformFunction: null }, getName: { classPropertyName: "getName", publicName: "getName", isSignal: true, isRequired: false, transformFunction: null }, getParentId: { classPropertyName: "getParentId", publicName: "getParentId", isSignal: true, isRequired: false, transformFunction: null }, isFolder: { classPropertyName: "isFolder", publicName: "isFolder", isSignal: true, isRequired: false, transformFunction: null }, getIsOpen: { classPropertyName: "getIsOpen", publicName: "getIsOpen", isSignal: true, isRequired: false, transformFunction: null }, setIsOpen: { classPropertyName: "setIsOpen", publicName: "setIsOpen", isSignal: true, isRequired: false, transformFunction: null }, getIcon: { classPropertyName: "getIcon", publicName: "getIcon", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { items: "itemsChange", selectedId: "selectedIdChange", nodeClick: "nodeClick", nodeToggle: "nodeToggle" }, host: { properties: { "class.sh-tree": "true" } }, queries: [{ propertyName: "openIconDir", first: true, predicate: ShipTreeOpenIcon, descendants: true, isSignal: true }, { propertyName: "closedIconDir", first: true, predicate: ShipTreeClosedIcon, descendants: true, isSignal: true }, { propertyName: "itemIconDir", first: true, predicate: ShipTreeItemIcon, descendants: true, isSignal: true }, { propertyName: "nodeTemplate", first: true, predicate: ["nodeTemplate"], descendants: true, isSignal: true }, { propertyName: "dirTemplate", first: true, predicate: ["dirTemplate"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (sortableManager()) {\n <div\n class=\"sh-tree-container\"\n [shSortable]=\"sortableManager()\"\n [treeItems]=\"visibleNodes()\"\n sortingMode=\"tree\"\n >\n @for (node of visibleNodes(); track getId()(node)) {\n <div\n class=\"sh-tree-node\"\n [class.is-folder]=\"isFolder()(node)\"\n [class.is-expanded]=\"getIsOpen()(node)\"\n [class.is-selected]=\"selectedId() === getId()(node)\"\n draggable=\"true\"\n [attr.sortable-dir]=\"isFolder()(node) ? 'true' : null\"\n [style.--tree-depth]=\"getNodeDepth(node)\"\n (click)=\"handleNodeClick(node, $event)\"\n >\n <!-- Indent guides -->\n @for (i of getDepthArray(getNodeDepth(node)); track i) {\n <div class=\"indent-guide\" [style.--guide-index]=\"i\"></div>\n }\n\n <!-- Folder Caret -->\n @if (isFolder()(node) && !dirTemplate()) {\n <span class=\"caret-container\">\n <button class=\"caret-btn\" (click)=\"toggleNode(node, $event)\" type=\"button\">\n @if (getIsOpen()(node)) {\n <sh-icon size=\"small\">caret-down</sh-icon>\n } @else {\n <sh-icon size=\"small\">caret-right</sh-icon>\n }\n </button>\n </span>\n }\n\n <!-- Node Icon -->\n @if (getNodeIcon(node)) {\n @if (getNodeIcon(node) === 'file') {\n <sh-icon class=\"node-icon\" [class.folder]=\"isFolder()(node)\" size=\"small\">file</sh-icon>\n } @else if (getNodeIcon(node) === 'folder') {\n <sh-icon class=\"node-icon\" [class.folder]=\"isFolder()(node)\" size=\"small\">folder</sh-icon>\n } @else if (getNodeIcon(node) === 'folder-open') {\n <sh-icon class=\"node-icon\" [class.folder]=\"isFolder()(node)\" size=\"small\">folder-open</sh-icon>\n } @else {\n <sh-icon class=\"node-icon\" [class.folder]=\"isFolder()(node)\" size=\"small\">\n {{ getNodeIcon(node) }}\n </sh-icon>\n }\n }\n\n <!-- Node Content -->\n <div class=\"node-content\">\n <ng-container *ngTemplateOutlet=\"isFolder()(node) && dirTemplate() ? dirTemplate() : (nodeTemplate() || defaultTemplate); context: { $implicit: node }\"></ng-container>\n </div>\n </div>\n } @empty {\n <div class=\"empty-state\">\n <ng-content select=\"[emptyState]\">\n No items in tree\n </ng-content>\n </div>\n }\n </div>\n} @else {\n <div class=\"sh-tree-container\">\n @for (node of visibleNodes(); track getId()(node)) {\n <div\n class=\"sh-tree-node\"\n [class.is-folder]=\"isFolder()(node)\"\n [class.is-expanded]=\"getIsOpen()(node)\"\n [class.is-selected]=\"selectedId() === getId()(node)\"\n [style.--tree-depth]=\"getNodeDepth(node)\"\n (click)=\"handleNodeClick(node, $event)\"\n >\n <!-- Indent guides -->\n @for (i of getDepthArray(getNodeDepth(node)); track i) {\n <div class=\"indent-guide\" [style.--guide-index]=\"i\"></div>\n }\n\n <!-- Folder Caret -->\n @if (isFolder()(node) && !dirTemplate()) {\n <span class=\"caret-container\">\n <button class=\"caret-btn\" (click)=\"toggleNode(node, $event)\" type=\"button\">\n @if (getIsOpen()(node)) {\n <sh-icon size=\"small\">caret-down</sh-icon>\n } @else {\n <sh-icon size=\"small\">caret-right</sh-icon>\n }\n </button>\n </span>\n }\n\n <!-- Node Icon -->\n @if (getNodeIcon(node)) {\n @if (getNodeIcon(node) === 'file') {\n <sh-icon class=\"node-icon\" [class.folder]=\"isFolder()(node)\" size=\"small\">file</sh-icon>\n } @else if (getNodeIcon(node) === 'folder') {\n <sh-icon class=\"node-icon\" [class.folder]=\"isFolder()(node)\" size=\"small\">folder</sh-icon>\n } @else if (getNodeIcon(node) === 'folder-open') {\n <sh-icon class=\"node-icon\" [class.folder]=\"isFolder()(node)\" size=\"small\">folder-open</sh-icon>\n } @else {\n <sh-icon class=\"node-icon\" [class.folder]=\"isFolder()(node)\" size=\"small\">\n {{ getNodeIcon(node) }}\n </sh-icon>\n }\n }\n\n <!-- Node Content -->\n <div class=\"node-content\">\n <ng-container *ngTemplateOutlet=\"isFolder()(node) && dirTemplate() ? dirTemplate() : (nodeTemplate() || defaultTemplate); context: { $implicit: node }\"></ng-container>\n </div>\n </div>\n } @empty {\n <div class=\"empty-state\">\n <ng-content select=\"[emptyState]\">\n No items in tree\n </ng-content>\n </div>\n }\n </div>\n}\n\n<ng-template #defaultTemplate let-node>\n <span class=\"node-name\">{{ getName()(node) }}</span>\n</ng-template>\n", styles: [".sh-sortable{position:relative}.sh-sortable.dragging [draggable],.sh-sortable.dragging .sortable-ghost{cursor:grabbing;transition:transform 40ms linear}.sh-sortable [draggable]{transform:translate(0);transition:none;z-index:2;-webkit-user-select:none;user-select:none}.sh-sortable:not(.sh-sortable-tree) [draggable]{background:var(--base-1)}.sh-sortable:not(.sh-sortable-tree) [draggable]:not(:has([sort-handle])){cursor:grab}.sh-sortable .sortable-ghost{opacity:.5;z-index:10}.sh-sortable.item-dragged-out .sortable-ghost{display:none}.sh-sortable [sort-handle]{cursor:grab}.sh-sortable.sh-sortable-tree [draggable]{transform:none!important;transition:none!important;z-index:auto}.sh-sortable.sh-sortable-tree .sortable-ghost{z-index:0!important}.sh-sortable.sh-sortable-tree .sortable-ghost.drop-before:before,.sh-sortable.sh-sortable-tree .sortable-ghost.drop-after:after{display:none!important}.sh-sortable.sh-sortable-tree .sortable-ghost.drop-inside{outline:none!important;background:inherit!important}.sh-sortable.sh-sortable-tree .drop-inside{background:var(--primary-3)!important;outline:2px solid var(--primary-8)!important;outline-offset:-.125rem;border-radius:var(--shape-1, 4px)}.sh-sortable.sh-sortable-tree .drop-inside .node-icon,.sh-sortable.sh-sortable-tree .drop-inside sh-tree-node .sh-tree-node-left sh-icon{color:var(--primary-8)!important}.sh-sortable.sh-sortable-tree .drop-before{position:relative;z-index:20}.sh-sortable.sh-sortable-tree .drop-before:before{content:\"\";position:absolute;top:-.1875rem;left:calc(var(--tree-padding-left, 12px) + var(--tree-depth, 0) * var(--tree-indent-step, 12px) + .375rem);right:var(--tree-padding-right, 6px);height:.375rem;background-image:radial-gradient(circle at 3px 3px,var(--primary-8) 3px,transparent 3px),linear-gradient(to right,var(--primary-8),var(--primary-8));background-repeat:no-repeat,no-repeat;background-position:left center,6px center;background-size:6px 6px,100% 2px;z-index:10;pointer-events:none}.sh-sortable.sh-sortable-tree .drop-after{position:relative;z-index:20}.sh-sortable.sh-sortable-tree .drop-after:after{content:\"\";position:absolute;bottom:-.1875rem;left:calc(var(--tree-padding-left, 12px) + var(--tree-depth, 0) * var(--tree-indent-step, 12px) + .375rem);right:var(--tree-padding-right, 6px);height:.375rem;background-image:radial-gradient(circle at 3px 3px,var(--primary-8) 3px,transparent 3px),linear-gradient(to right,var(--primary-8),var(--primary-8));background-repeat:no-repeat,no-repeat;background-position:left center,6px center;background-size:6px 6px,100% 2px;z-index:10;pointer-events:none}sh-tree{--tree-bg: var(--base-2);--tree-bc: var(--base-3);--tree-color: var(--base-12);--tree-hover-bg: var(--base-3);--tree-active-bg: var(--base-4);--tree-selected-bg: var(--base-4);--tree-guide-color: var(--base-4);--tree-caret-color: var(--base-9);--tree-caret-hover-color: var(--base-12);--tree-icon-color: var(--base-9);--tree-icon-folder-color: var(--primary-8);--tree-indent-step: .75rem;--tree-padding-left: .75rem;--tree-padding-right: .375rem;display:flex;flex-direction:column;width:100%;background:var(--tree-bg);border:1px solid var(--tree-bc);border-radius:var(--shape-2, .5rem);overflow:hidden;font-family:var(--font-family, sans-serif);box-shadow:var(--box-shadow-10)}sh-tree .sh-tree-container{flex:1;padding:.5rem 0;overflow-y:auto;position:relative}sh-tree .sh-tree-node{display:flex;align-items:center;height:2rem;position:relative;cursor:pointer;-webkit-user-select:none;user-select:none;color:var(--tree-color);font:var(--paragraph-20, 14px sans-serif);gap:.375rem;transition:background .12s ease;padding-left:calc(var(--tree-padding-left) + var(--tree-depth, 0) * var(--tree-indent-step));padding-right:var(--tree-padding-right);background:var(--tree-bg)}sh-tree .sh-tree-node:hover{background:var(--tree-hover-bg)}sh-tree .sh-tree-node.is-selected{background:var(--tree-selected-bg)}sh-tree .sh-tree-node.sortable-ghost{opacity:.4;background:var(--tree-active-bg)}sh-tree .sh-tree-node .indent-guide{position:absolute;top:0;bottom:0;width:1px;border-left:1px solid var(--tree-guide-color);opacity:.5;left:calc(var(--tree-padding-left) + var(--tree-indent-step) / 2 + var(--guide-index, 0) * var(--tree-indent-step))}sh-tree .sh-tree-node .caret-container{display:flex;align-items:center;justify-content:center;width:var(--tree-indent-step);height:1rem;z-index:2}sh-tree .sh-tree-node .caret-container:has(+.node-icon){position:absolute;opacity:0;z-index:3;width:var(--tree-indent-step)}sh-tree .sh-tree-node .caret-container .caret-btn{background:none;border:none;padding:0;cursor:pointer;display:flex;align-items:center;justify-content:center;color:var(--tree-caret-color);border-radius:var(--shape-1, 4px);width:100%;height:100%;position:relative;transition:background .15s ease,color .15s ease}sh-tree .sh-tree-node .caret-container .caret-btn:after{content:\"\";position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:1.5rem;height:1.5rem;z-index:1}sh-tree .sh-tree-node .caret-container .caret-btn:hover{color:var(--tree-caret-hover-color)}sh-tree .sh-tree-node .node-icon{color:var(--tree-icon-color);display:inline-flex;align-items:center;justify-content:center;width:var(--tree-indent-step)}sh-tree .sh-tree-node .node-icon.folder{color:var(--tree-icon-folder-color)}sh-tree .sh-tree-node .node-icon:has(~.node-content sh-tree-node sh-icon){display:none}sh-tree .sh-tree-node.is-folder sh-tree-node .sh-tree-node-left sh-icon{color:var(--tree-icon-folder-color)}sh-tree .sh-tree-node:not(.is-folder) sh-tree-node .sh-tree-node-left sh-icon{color:var(--tree-icon-color)}sh-tree .sh-tree-node .node-content{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;z-index:2;display:flex;align-items:center}sh-tree .sh-tree-node .node-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}sh-tree sh-tree-node{display:flex;align-items:center;width:100%;gap:.5rem;justify-content:space-between;min-width:0}sh-tree sh-tree-node .sh-tree-node-left{display:flex;align-items:center;gap:.25rem;padding-left:.25rem;overflow:hidden;min-width:0;flex:1}sh-tree sh-tree-node .sh-tree-node-left sh-icon{display:inline-flex;align-items:center;justify-content:center;width:var(--tree-indent-step)}sh-tree sh-tree-node .sh-tree-node-label{display:inline-block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}sh-tree sh-tree-node .sh-tree-node-label span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}sh-tree sh-tree-node .sh-tree-node-actions,sh-tree sh-tree-node sh-tree-node-actions{display:flex;align-items:center;gap:.5rem}sh-tree sh-tree-node .status-badge{font-size:.625rem;padding:.125rem .375rem;border-radius:var(--shape-1, 4px);text-transform:uppercase;font-weight:600}sh-tree sh-tree-node .status-badge.success{background:var(--success-3, #e6f4ea);color:var(--success-8, #137333)}sh-tree sh-tree-node .status-badge.warning{background:var(--warning-3, #fef7e0);color:var(--warning-8, #b06000)}sh-tree sh-tree-node .status-badge.error{background:var(--error-3, #fce8e6);color:var(--error-8, #c5221f)}sh-tree sh-tree-node .delete-btn{background:none;border:none;padding:.125rem;cursor:pointer;color:var(--base-9);border-radius:var(--shape-1, 4px);display:flex;opacity:0;transition:opacity .15s ease;align-items:center;justify-content:center}sh-tree sh-tree-node .delete-btn:hover{background:var(--base-4);color:var(--error-8, #c5221f)}sh-tree .sh-tree-node:hover .delete-btn{opacity:1}sh-tree .empty-state{padding:2rem;text-align:center;color:var(--tree-caret-color);font:var(--paragraph-20, 14px sans-serif)}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: ShipIcon, selector: "sh-icon", inputs: ["color", "size"] }, { kind: "directive", type: ShipSortable, selector: "[shSortable]", inputs: ["shSortable", "sortableGroup", "sortingMode", "treeItems"], outputs: ["treeItemsChange", "sortDrop", "afterDrop", "crossDrop", "treeDrop"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
172
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.0", type: ShipTree, isStandalone: true, selector: "sh-tree", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, sortableManager: { classPropertyName: "sortableManager", publicName: "sortableManager", isSignal: true, isRequired: false, transformFunction: null }, selectedId: { classPropertyName: "selectedId", publicName: "selectedId", isSignal: true, isRequired: false, transformFunction: null }, getId: { classPropertyName: "getId", publicName: "getId", isSignal: true, isRequired: false, transformFunction: null }, getName: { classPropertyName: "getName", publicName: "getName", isSignal: true, isRequired: false, transformFunction: null }, getParentId: { classPropertyName: "getParentId", publicName: "getParentId", isSignal: true, isRequired: false, transformFunction: null }, isFolder: { classPropertyName: "isFolder", publicName: "isFolder", isSignal: true, isRequired: false, transformFunction: null }, getIsOpen: { classPropertyName: "getIsOpen", publicName: "getIsOpen", isSignal: true, isRequired: false, transformFunction: null }, setIsOpen: { classPropertyName: "setIsOpen", publicName: "setIsOpen", isSignal: true, isRequired: false, transformFunction: null }, getIcon: { classPropertyName: "getIcon", publicName: "getIcon", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { items: "itemsChange", selectedId: "selectedIdChange", nodeClick: "nodeClick", nodeToggle: "nodeToggle" }, host: { properties: { "class.sh-tree": "true" } }, queries: [{ propertyName: "openIconDir", first: true, predicate: ShipTreeOpenIcon, descendants: true, isSignal: true }, { propertyName: "closedIconDir", first: true, predicate: ShipTreeClosedIcon, descendants: true, isSignal: true }, { propertyName: "itemIconDir", first: true, predicate: ShipTreeItemIcon, descendants: true, isSignal: true }, { propertyName: "nodeTemplate", first: true, predicate: ["nodeTemplate"], descendants: true, isSignal: true }, { propertyName: "dirTemplate", first: true, predicate: ["dirTemplate"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (sortableManager()) {\n <div\n class=\"sh-tree-container\"\n [shSortable]=\"sortableManager()\"\n [treeItems]=\"visibleNodes()\"\n sortingMode=\"tree\"\n role=\"tree\"\n >\n @for (node of visibleNodes(); track getId()(node)) {\n <div\n class=\"sh-tree-node\"\n [class.is-folder]=\"isFolder()(node)\"\n [class.is-expanded]=\"getIsOpen()(node)\"\n [class.is-selected]=\"selectedId() === getId()(node)\"\n draggable=\"true\"\n [attr.sortable-dir]=\"isFolder()(node) ? 'true' : null\"\n [style.--tree-depth]=\"getNodeDepth(node)\"\n (click)=\"handleNodeClick(node, $event)\"\n role=\"treeitem\"\n [attr.aria-expanded]=\"isFolder()(node) ? getIsOpen()(node) : null\"\n >\n <!-- Indent guides -->\n @for (i of getDepthArray(getNodeDepth(node)); track i) {\n <div class=\"indent-guide\" [style.--guide-index]=\"i\"></div>\n }\n\n <!-- Folder Caret -->\n @if (isFolder()(node) && !dirTemplate()) {\n <span class=\"caret-container\">\n <button class=\"caret-btn\" (click)=\"toggleNode(node, $event)\" type=\"button\">\n @if (getIsOpen()(node)) {\n <sh-icon size=\"small\">caret-down</sh-icon>\n } @else {\n <sh-icon size=\"small\">caret-right</sh-icon>\n }\n </button>\n </span>\n }\n\n <!-- Node Icon -->\n @if (getNodeIcon(node)) {\n @if (getNodeIcon(node) === 'file') {\n <sh-icon class=\"node-icon\" [class.folder]=\"isFolder()(node)\" size=\"small\">file</sh-icon>\n } @else if (getNodeIcon(node) === 'folder') {\n <sh-icon class=\"node-icon\" [class.folder]=\"isFolder()(node)\" size=\"small\">folder</sh-icon>\n } @else if (getNodeIcon(node) === 'folder-open') {\n <sh-icon class=\"node-icon\" [class.folder]=\"isFolder()(node)\" size=\"small\">folder-open</sh-icon>\n } @else {\n <sh-icon class=\"node-icon\" [class.folder]=\"isFolder()(node)\" size=\"small\">\n {{ getNodeIcon(node) }}\n </sh-icon>\n }\n }\n\n <!-- Node Content -->\n <div class=\"node-content\">\n <ng-container *ngTemplateOutlet=\"isFolder()(node) && dirTemplate() ? dirTemplate() : (nodeTemplate() || defaultTemplate); context: { $implicit: node }\"></ng-container>\n </div>\n </div>\n } @empty {\n <div class=\"empty-state\">\n <ng-content select=\"[emptyState]\">\n No items in tree\n </ng-content>\n </div>\n }\n </div>\n} @else {\n <div class=\"sh-tree-container\" role=\"tree\">\n @for (node of visibleNodes(); track getId()(node)) {\n <div\n class=\"sh-tree-node\"\n [class.is-folder]=\"isFolder()(node)\"\n [class.is-expanded]=\"getIsOpen()(node)\"\n [class.is-selected]=\"selectedId() === getId()(node)\"\n [style.--tree-depth]=\"getNodeDepth(node)\"\n (click)=\"handleNodeClick(node, $event)\"\n role=\"treeitem\"\n [attr.aria-expanded]=\"isFolder()(node) ? getIsOpen()(node) : null\"\n >\n <!-- Indent guides -->\n @for (i of getDepthArray(getNodeDepth(node)); track i) {\n <div class=\"indent-guide\" [style.--guide-index]=\"i\"></div>\n }\n\n <!-- Folder Caret -->\n @if (isFolder()(node) && !dirTemplate()) {\n <span class=\"caret-container\">\n <button class=\"caret-btn\" (click)=\"toggleNode(node, $event)\" type=\"button\">\n @if (getIsOpen()(node)) {\n <sh-icon size=\"small\">caret-down</sh-icon>\n } @else {\n <sh-icon size=\"small\">caret-right</sh-icon>\n }\n </button>\n </span>\n }\n\n <!-- Node Icon -->\n @if (getNodeIcon(node)) {\n @if (getNodeIcon(node) === 'file') {\n <sh-icon class=\"node-icon\" [class.folder]=\"isFolder()(node)\" size=\"small\">file</sh-icon>\n } @else if (getNodeIcon(node) === 'folder') {\n <sh-icon class=\"node-icon\" [class.folder]=\"isFolder()(node)\" size=\"small\">folder</sh-icon>\n } @else if (getNodeIcon(node) === 'folder-open') {\n <sh-icon class=\"node-icon\" [class.folder]=\"isFolder()(node)\" size=\"small\">folder-open</sh-icon>\n } @else {\n <sh-icon class=\"node-icon\" [class.folder]=\"isFolder()(node)\" size=\"small\">\n {{ getNodeIcon(node) }}\n </sh-icon>\n }\n }\n\n <!-- Node Content -->\n <div class=\"node-content\">\n <ng-container *ngTemplateOutlet=\"isFolder()(node) && dirTemplate() ? dirTemplate() : (nodeTemplate() || defaultTemplate); context: { $implicit: node }\"></ng-container>\n </div>\n </div>\n } @empty {\n <div class=\"empty-state\">\n <ng-content select=\"[emptyState]\">\n No items in tree\n </ng-content>\n </div>\n }\n </div>\n}\n\n<ng-template #defaultTemplate let-node>\n <span class=\"node-name\">{{ getName()(node) }}</span>\n</ng-template>\n", styles: [".sh-sortable{position:relative}.sh-sortable.dragging [draggable],.sh-sortable.dragging .sortable-ghost{cursor:grabbing;transition:transform 40ms linear}.sh-sortable [draggable]{transform:translate(0);transition:none;z-index:2;-webkit-user-select:none;user-select:none}.sh-sortable:not(.sh-sortable-tree) [draggable]{background:var(--base-1)}.sh-sortable:not(.sh-sortable-tree) [draggable]:not(:has([sort-handle])){cursor:grab}.sh-sortable .sortable-ghost{opacity:.5;z-index:10}.sh-sortable.item-dragged-out .sortable-ghost{display:none}.sh-sortable [sort-handle]{cursor:grab}.sh-sortable.sh-sortable-tree [draggable]{transform:none!important;transition:none!important;z-index:auto}.sh-sortable.sh-sortable-tree .sortable-ghost{z-index:0!important}.sh-sortable.sh-sortable-tree .sortable-ghost.drop-before:before,.sh-sortable.sh-sortable-tree .sortable-ghost.drop-after:after{display:none!important}.sh-sortable.sh-sortable-tree .sortable-ghost.drop-inside{outline:none!important;background:inherit!important}.sh-sortable.sh-sortable-tree .drop-inside{background:var(--primary-3)!important;outline:2px solid var(--primary-8)!important;outline-offset:-.125rem;border-radius:var(--shape-1, 4px)}.sh-sortable.sh-sortable-tree .drop-inside .node-icon,.sh-sortable.sh-sortable-tree .drop-inside sh-tree-node .sh-tree-node-left sh-icon{color:var(--primary-8)!important}.sh-sortable.sh-sortable-tree .drop-before{position:relative;z-index:20}.sh-sortable.sh-sortable-tree .drop-before:before{content:\"\";position:absolute;top:-.1875rem;left:calc(var(--tree-padding-left, 12px) + var(--tree-depth, 0) * var(--tree-indent-step, 12px) + .375rem);right:var(--tree-padding-right, 6px);height:.375rem;background-image:radial-gradient(circle at 3px 3px,var(--primary-8) 3px,transparent 3px),linear-gradient(to right,var(--primary-8),var(--primary-8));background-repeat:no-repeat,no-repeat;background-position:left center,6px center;background-size:6px 6px,100% 2px;z-index:10;pointer-events:none}.sh-sortable.sh-sortable-tree .drop-after{position:relative;z-index:20}.sh-sortable.sh-sortable-tree .drop-after:after{content:\"\";position:absolute;bottom:-.1875rem;left:calc(var(--tree-padding-left, 12px) + var(--tree-depth, 0) * var(--tree-indent-step, 12px) + .375rem);right:var(--tree-padding-right, 6px);height:.375rem;background-image:radial-gradient(circle at 3px 3px,var(--primary-8) 3px,transparent 3px),linear-gradient(to right,var(--primary-8),var(--primary-8));background-repeat:no-repeat,no-repeat;background-position:left center,6px center;background-size:6px 6px,100% 2px;z-index:10;pointer-events:none}sh-tree{--tree-bg: var(--base-2);--tree-bc: var(--base-3);--tree-color: var(--base-12);--tree-hover-bg: var(--base-3);--tree-active-bg: var(--base-4);--tree-selected-bg: var(--base-4);--tree-guide-color: var(--base-4);--tree-caret-color: var(--base-9);--tree-caret-hover-color: var(--base-12);--tree-icon-color: var(--base-9);--tree-icon-folder-color: var(--primary-8);--tree-indent-step: .75rem;--tree-padding-left: .75rem;--tree-padding-right: .375rem;display:flex;flex-direction:column;width:100%;background:var(--tree-bg);border:1px solid var(--tree-bc);border-radius:var(--shape-2, .5rem);overflow:hidden;font-family:var(--font-family, sans-serif);box-shadow:var(--box-shadow-10)}sh-tree .sh-tree-container{flex:1;padding:.5rem 0;overflow-y:auto;position:relative}sh-tree .sh-tree-node{display:flex;align-items:center;height:2rem;position:relative;cursor:pointer;-webkit-user-select:none;user-select:none;color:var(--tree-color);font:var(--paragraph-20, 14px sans-serif);gap:.375rem;transition:background .12s ease;padding-left:calc(var(--tree-padding-left) + var(--tree-depth, 0) * var(--tree-indent-step));padding-right:var(--tree-padding-right);background:var(--tree-bg)}sh-tree .sh-tree-node:hover{background:var(--tree-hover-bg)}sh-tree .sh-tree-node.is-selected{background:var(--tree-selected-bg)}sh-tree .sh-tree-node.sortable-ghost{opacity:.4;background:var(--tree-active-bg)}sh-tree .sh-tree-node .indent-guide{position:absolute;top:0;bottom:0;width:1px;border-left:1px solid var(--tree-guide-color);opacity:.5;left:calc(var(--tree-padding-left) + var(--tree-indent-step) / 2 + var(--guide-index, 0) * var(--tree-indent-step))}sh-tree .sh-tree-node .caret-container{display:flex;align-items:center;justify-content:center;width:var(--tree-indent-step);height:1rem;z-index:2}sh-tree .sh-tree-node .caret-container:has(+.node-icon){position:absolute;opacity:0;z-index:3;width:var(--tree-indent-step)}sh-tree .sh-tree-node .caret-container .caret-btn{background:none;border:none;padding:0;cursor:pointer;display:flex;align-items:center;justify-content:center;color:var(--tree-caret-color);border-radius:var(--shape-1, 4px);width:100%;height:100%;position:relative;transition:background .15s ease,color .15s ease}sh-tree .sh-tree-node .caret-container .caret-btn:after{content:\"\";position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:1.5rem;height:1.5rem;z-index:1}sh-tree .sh-tree-node .caret-container .caret-btn:hover{color:var(--tree-caret-hover-color)}sh-tree .sh-tree-node .node-icon{color:var(--tree-icon-color);display:inline-flex;align-items:center;justify-content:center;width:var(--tree-indent-step)}sh-tree .sh-tree-node .node-icon.folder{color:var(--tree-icon-folder-color)}sh-tree .sh-tree-node .node-icon:has(~.node-content sh-tree-node sh-icon){display:none}sh-tree .sh-tree-node.is-folder sh-tree-node .sh-tree-node-left sh-icon{color:var(--tree-icon-folder-color)}sh-tree .sh-tree-node:not(.is-folder) sh-tree-node .sh-tree-node-left sh-icon{color:var(--tree-icon-color)}sh-tree .sh-tree-node .node-content{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;z-index:2;display:flex;align-items:center}sh-tree .sh-tree-node .node-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}sh-tree sh-tree-node{display:flex;align-items:center;width:100%;gap:.5rem;justify-content:space-between;min-width:0}sh-tree sh-tree-node .sh-tree-node-left{display:flex;align-items:center;gap:.25rem;padding-left:.25rem;overflow:hidden;min-width:0;flex:1}sh-tree sh-tree-node .sh-tree-node-left sh-icon{display:inline-flex;align-items:center;justify-content:center;width:var(--tree-indent-step)}sh-tree sh-tree-node .sh-tree-node-label{display:inline-block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}sh-tree sh-tree-node .sh-tree-node-label span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}sh-tree sh-tree-node .sh-tree-node-actions,sh-tree sh-tree-node sh-tree-node-actions{display:flex;align-items:center;gap:.5rem}sh-tree sh-tree-node .status-badge{font-size:.625rem;padding:.125rem .375rem;border-radius:var(--shape-1, 4px);text-transform:uppercase;font-weight:600}sh-tree sh-tree-node .status-badge.success{background:var(--success-3, #e6f4ea);color:var(--success-8, #137333)}sh-tree sh-tree-node .status-badge.warning{background:var(--warning-3, #fef7e0);color:var(--warning-8, #b06000)}sh-tree sh-tree-node .status-badge.error{background:var(--error-3, #fce8e6);color:var(--error-8, #c5221f)}sh-tree sh-tree-node .delete-btn{background:none;border:none;padding:.125rem;cursor:pointer;color:var(--base-9);border-radius:var(--shape-1, 4px);display:flex;opacity:0;transition:opacity .15s ease;align-items:center;justify-content:center}sh-tree sh-tree-node .delete-btn:hover{background:var(--base-4);color:var(--error-8, #c5221f)}sh-tree .sh-tree-node:hover .delete-btn{opacity:1}sh-tree .empty-state{padding:2rem;text-align:center;color:var(--tree-caret-color);font:var(--paragraph-20, 14px sans-serif)}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: ShipIcon, selector: "sh-icon", inputs: ["color", "size"] }, { kind: "directive", type: ShipSortable, selector: "[shSortable]", inputs: ["shSortable", "sortableGroup", "sortingMode", "treeItems"], outputs: ["treeItemsChange", "sortDrop", "afterDrop", "crossDrop", "treeDrop"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
173
173
|
}
|
|
174
174
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.0", ngImport: i0, type: ShipTree, decorators: [{
|
|
175
175
|
type: Component,
|
|
176
176
|
args: [{ selector: 'sh-tree', standalone: true, imports: [NgTemplateOutlet, ShipIcon, ShipSortable], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, host: {
|
|
177
177
|
'[class.sh-tree]': 'true',
|
|
178
|
-
}, template: "@if (sortableManager()) {\n <div\n class=\"sh-tree-container\"\n [shSortable]=\"sortableManager()\"\n [treeItems]=\"visibleNodes()\"\n sortingMode=\"tree\"\n >\n @for (node of visibleNodes(); track getId()(node)) {\n <div\n class=\"sh-tree-node\"\n [class.is-folder]=\"isFolder()(node)\"\n [class.is-expanded]=\"getIsOpen()(node)\"\n [class.is-selected]=\"selectedId() === getId()(node)\"\n draggable=\"true\"\n [attr.sortable-dir]=\"isFolder()(node) ? 'true' : null\"\n [style.--tree-depth]=\"getNodeDepth(node)\"\n (click)=\"handleNodeClick(node, $event)\"\n >\n <!-- Indent guides -->\n @for (i of getDepthArray(getNodeDepth(node)); track i) {\n <div class=\"indent-guide\" [style.--guide-index]=\"i\"></div>\n }\n\n <!-- Folder Caret -->\n @if (isFolder()(node) && !dirTemplate()) {\n <span class=\"caret-container\">\n <button class=\"caret-btn\" (click)=\"toggleNode(node, $event)\" type=\"button\">\n @if (getIsOpen()(node)) {\n <sh-icon size=\"small\">caret-down</sh-icon>\n } @else {\n <sh-icon size=\"small\">caret-right</sh-icon>\n }\n </button>\n </span>\n }\n\n <!-- Node Icon -->\n @if (getNodeIcon(node)) {\n @if (getNodeIcon(node) === 'file') {\n <sh-icon class=\"node-icon\" [class.folder]=\"isFolder()(node)\" size=\"small\">file</sh-icon>\n } @else if (getNodeIcon(node) === 'folder') {\n <sh-icon class=\"node-icon\" [class.folder]=\"isFolder()(node)\" size=\"small\">folder</sh-icon>\n } @else if (getNodeIcon(node) === 'folder-open') {\n <sh-icon class=\"node-icon\" [class.folder]=\"isFolder()(node)\" size=\"small\">folder-open</sh-icon>\n } @else {\n <sh-icon class=\"node-icon\" [class.folder]=\"isFolder()(node)\" size=\"small\">\n {{ getNodeIcon(node) }}\n </sh-icon>\n }\n }\n\n <!-- Node Content -->\n <div class=\"node-content\">\n <ng-container *ngTemplateOutlet=\"isFolder()(node) && dirTemplate() ? dirTemplate() : (nodeTemplate() || defaultTemplate); context: { $implicit: node }\"></ng-container>\n </div>\n </div>\n } @empty {\n <div class=\"empty-state\">\n <ng-content select=\"[emptyState]\">\n No items in tree\n </ng-content>\n </div>\n }\n </div>\n} @else {\n <div class=\"sh-tree-container\">\n @for (node of visibleNodes(); track getId()(node)) {\n <div\n class=\"sh-tree-node\"\n [class.is-folder]=\"isFolder()(node)\"\n [class.is-expanded]=\"getIsOpen()(node)\"\n [class.is-selected]=\"selectedId() === getId()(node)\"\n [style.--tree-depth]=\"getNodeDepth(node)\"\n (click)=\"handleNodeClick(node, $event)\"\n >\n <!-- Indent guides -->\n @for (i of getDepthArray(getNodeDepth(node)); track i) {\n <div class=\"indent-guide\" [style.--guide-index]=\"i\"></div>\n }\n\n <!-- Folder Caret -->\n @if (isFolder()(node) && !dirTemplate()) {\n <span class=\"caret-container\">\n <button class=\"caret-btn\" (click)=\"toggleNode(node, $event)\" type=\"button\">\n @if (getIsOpen()(node)) {\n <sh-icon size=\"small\">caret-down</sh-icon>\n } @else {\n <sh-icon size=\"small\">caret-right</sh-icon>\n }\n </button>\n </span>\n }\n\n <!-- Node Icon -->\n @if (getNodeIcon(node)) {\n @if (getNodeIcon(node) === 'file') {\n <sh-icon class=\"node-icon\" [class.folder]=\"isFolder()(node)\" size=\"small\">file</sh-icon>\n } @else if (getNodeIcon(node) === 'folder') {\n <sh-icon class=\"node-icon\" [class.folder]=\"isFolder()(node)\" size=\"small\">folder</sh-icon>\n } @else if (getNodeIcon(node) === 'folder-open') {\n <sh-icon class=\"node-icon\" [class.folder]=\"isFolder()(node)\" size=\"small\">folder-open</sh-icon>\n } @else {\n <sh-icon class=\"node-icon\" [class.folder]=\"isFolder()(node)\" size=\"small\">\n {{ getNodeIcon(node) }}\n </sh-icon>\n }\n }\n\n <!-- Node Content -->\n <div class=\"node-content\">\n <ng-container *ngTemplateOutlet=\"isFolder()(node) && dirTemplate() ? dirTemplate() : (nodeTemplate() || defaultTemplate); context: { $implicit: node }\"></ng-container>\n </div>\n </div>\n } @empty {\n <div class=\"empty-state\">\n <ng-content select=\"[emptyState]\">\n No items in tree\n </ng-content>\n </div>\n }\n </div>\n}\n\n<ng-template #defaultTemplate let-node>\n <span class=\"node-name\">{{ getName()(node) }}</span>\n</ng-template>\n", styles: [".sh-sortable{position:relative}.sh-sortable.dragging [draggable],.sh-sortable.dragging .sortable-ghost{cursor:grabbing;transition:transform 40ms linear}.sh-sortable [draggable]{transform:translate(0);transition:none;z-index:2;-webkit-user-select:none;user-select:none}.sh-sortable:not(.sh-sortable-tree) [draggable]{background:var(--base-1)}.sh-sortable:not(.sh-sortable-tree) [draggable]:not(:has([sort-handle])){cursor:grab}.sh-sortable .sortable-ghost{opacity:.5;z-index:10}.sh-sortable.item-dragged-out .sortable-ghost{display:none}.sh-sortable [sort-handle]{cursor:grab}.sh-sortable.sh-sortable-tree [draggable]{transform:none!important;transition:none!important;z-index:auto}.sh-sortable.sh-sortable-tree .sortable-ghost{z-index:0!important}.sh-sortable.sh-sortable-tree .sortable-ghost.drop-before:before,.sh-sortable.sh-sortable-tree .sortable-ghost.drop-after:after{display:none!important}.sh-sortable.sh-sortable-tree .sortable-ghost.drop-inside{outline:none!important;background:inherit!important}.sh-sortable.sh-sortable-tree .drop-inside{background:var(--primary-3)!important;outline:2px solid var(--primary-8)!important;outline-offset:-.125rem;border-radius:var(--shape-1, 4px)}.sh-sortable.sh-sortable-tree .drop-inside .node-icon,.sh-sortable.sh-sortable-tree .drop-inside sh-tree-node .sh-tree-node-left sh-icon{color:var(--primary-8)!important}.sh-sortable.sh-sortable-tree .drop-before{position:relative;z-index:20}.sh-sortable.sh-sortable-tree .drop-before:before{content:\"\";position:absolute;top:-.1875rem;left:calc(var(--tree-padding-left, 12px) + var(--tree-depth, 0) * var(--tree-indent-step, 12px) + .375rem);right:var(--tree-padding-right, 6px);height:.375rem;background-image:radial-gradient(circle at 3px 3px,var(--primary-8) 3px,transparent 3px),linear-gradient(to right,var(--primary-8),var(--primary-8));background-repeat:no-repeat,no-repeat;background-position:left center,6px center;background-size:6px 6px,100% 2px;z-index:10;pointer-events:none}.sh-sortable.sh-sortable-tree .drop-after{position:relative;z-index:20}.sh-sortable.sh-sortable-tree .drop-after:after{content:\"\";position:absolute;bottom:-.1875rem;left:calc(var(--tree-padding-left, 12px) + var(--tree-depth, 0) * var(--tree-indent-step, 12px) + .375rem);right:var(--tree-padding-right, 6px);height:.375rem;background-image:radial-gradient(circle at 3px 3px,var(--primary-8) 3px,transparent 3px),linear-gradient(to right,var(--primary-8),var(--primary-8));background-repeat:no-repeat,no-repeat;background-position:left center,6px center;background-size:6px 6px,100% 2px;z-index:10;pointer-events:none}sh-tree{--tree-bg: var(--base-2);--tree-bc: var(--base-3);--tree-color: var(--base-12);--tree-hover-bg: var(--base-3);--tree-active-bg: var(--base-4);--tree-selected-bg: var(--base-4);--tree-guide-color: var(--base-4);--tree-caret-color: var(--base-9);--tree-caret-hover-color: var(--base-12);--tree-icon-color: var(--base-9);--tree-icon-folder-color: var(--primary-8);--tree-indent-step: .75rem;--tree-padding-left: .75rem;--tree-padding-right: .375rem;display:flex;flex-direction:column;width:100%;background:var(--tree-bg);border:1px solid var(--tree-bc);border-radius:var(--shape-2, .5rem);overflow:hidden;font-family:var(--font-family, sans-serif);box-shadow:var(--box-shadow-10)}sh-tree .sh-tree-container{flex:1;padding:.5rem 0;overflow-y:auto;position:relative}sh-tree .sh-tree-node{display:flex;align-items:center;height:2rem;position:relative;cursor:pointer;-webkit-user-select:none;user-select:none;color:var(--tree-color);font:var(--paragraph-20, 14px sans-serif);gap:.375rem;transition:background .12s ease;padding-left:calc(var(--tree-padding-left) + var(--tree-depth, 0) * var(--tree-indent-step));padding-right:var(--tree-padding-right);background:var(--tree-bg)}sh-tree .sh-tree-node:hover{background:var(--tree-hover-bg)}sh-tree .sh-tree-node.is-selected{background:var(--tree-selected-bg)}sh-tree .sh-tree-node.sortable-ghost{opacity:.4;background:var(--tree-active-bg)}sh-tree .sh-tree-node .indent-guide{position:absolute;top:0;bottom:0;width:1px;border-left:1px solid var(--tree-guide-color);opacity:.5;left:calc(var(--tree-padding-left) + var(--tree-indent-step) / 2 + var(--guide-index, 0) * var(--tree-indent-step))}sh-tree .sh-tree-node .caret-container{display:flex;align-items:center;justify-content:center;width:var(--tree-indent-step);height:1rem;z-index:2}sh-tree .sh-tree-node .caret-container:has(+.node-icon){position:absolute;opacity:0;z-index:3;width:var(--tree-indent-step)}sh-tree .sh-tree-node .caret-container .caret-btn{background:none;border:none;padding:0;cursor:pointer;display:flex;align-items:center;justify-content:center;color:var(--tree-caret-color);border-radius:var(--shape-1, 4px);width:100%;height:100%;position:relative;transition:background .15s ease,color .15s ease}sh-tree .sh-tree-node .caret-container .caret-btn:after{content:\"\";position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:1.5rem;height:1.5rem;z-index:1}sh-tree .sh-tree-node .caret-container .caret-btn:hover{color:var(--tree-caret-hover-color)}sh-tree .sh-tree-node .node-icon{color:var(--tree-icon-color);display:inline-flex;align-items:center;justify-content:center;width:var(--tree-indent-step)}sh-tree .sh-tree-node .node-icon.folder{color:var(--tree-icon-folder-color)}sh-tree .sh-tree-node .node-icon:has(~.node-content sh-tree-node sh-icon){display:none}sh-tree .sh-tree-node.is-folder sh-tree-node .sh-tree-node-left sh-icon{color:var(--tree-icon-folder-color)}sh-tree .sh-tree-node:not(.is-folder) sh-tree-node .sh-tree-node-left sh-icon{color:var(--tree-icon-color)}sh-tree .sh-tree-node .node-content{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;z-index:2;display:flex;align-items:center}sh-tree .sh-tree-node .node-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}sh-tree sh-tree-node{display:flex;align-items:center;width:100%;gap:.5rem;justify-content:space-between;min-width:0}sh-tree sh-tree-node .sh-tree-node-left{display:flex;align-items:center;gap:.25rem;padding-left:.25rem;overflow:hidden;min-width:0;flex:1}sh-tree sh-tree-node .sh-tree-node-left sh-icon{display:inline-flex;align-items:center;justify-content:center;width:var(--tree-indent-step)}sh-tree sh-tree-node .sh-tree-node-label{display:inline-block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}sh-tree sh-tree-node .sh-tree-node-label span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}sh-tree sh-tree-node .sh-tree-node-actions,sh-tree sh-tree-node sh-tree-node-actions{display:flex;align-items:center;gap:.5rem}sh-tree sh-tree-node .status-badge{font-size:.625rem;padding:.125rem .375rem;border-radius:var(--shape-1, 4px);text-transform:uppercase;font-weight:600}sh-tree sh-tree-node .status-badge.success{background:var(--success-3, #e6f4ea);color:var(--success-8, #137333)}sh-tree sh-tree-node .status-badge.warning{background:var(--warning-3, #fef7e0);color:var(--warning-8, #b06000)}sh-tree sh-tree-node .status-badge.error{background:var(--error-3, #fce8e6);color:var(--error-8, #c5221f)}sh-tree sh-tree-node .delete-btn{background:none;border:none;padding:.125rem;cursor:pointer;color:var(--base-9);border-radius:var(--shape-1, 4px);display:flex;opacity:0;transition:opacity .15s ease;align-items:center;justify-content:center}sh-tree sh-tree-node .delete-btn:hover{background:var(--base-4);color:var(--error-8, #c5221f)}sh-tree .sh-tree-node:hover .delete-btn{opacity:1}sh-tree .empty-state{padding:2rem;text-align:center;color:var(--tree-caret-color);font:var(--paragraph-20, 14px sans-serif)}\n"] }]
|
|
178
|
+
}, template: "@if (sortableManager()) {\n <div\n class=\"sh-tree-container\"\n [shSortable]=\"sortableManager()\"\n [treeItems]=\"visibleNodes()\"\n sortingMode=\"tree\"\n role=\"tree\"\n >\n @for (node of visibleNodes(); track getId()(node)) {\n <div\n class=\"sh-tree-node\"\n [class.is-folder]=\"isFolder()(node)\"\n [class.is-expanded]=\"getIsOpen()(node)\"\n [class.is-selected]=\"selectedId() === getId()(node)\"\n draggable=\"true\"\n [attr.sortable-dir]=\"isFolder()(node) ? 'true' : null\"\n [style.--tree-depth]=\"getNodeDepth(node)\"\n (click)=\"handleNodeClick(node, $event)\"\n role=\"treeitem\"\n [attr.aria-expanded]=\"isFolder()(node) ? getIsOpen()(node) : null\"\n >\n <!-- Indent guides -->\n @for (i of getDepthArray(getNodeDepth(node)); track i) {\n <div class=\"indent-guide\" [style.--guide-index]=\"i\"></div>\n }\n\n <!-- Folder Caret -->\n @if (isFolder()(node) && !dirTemplate()) {\n <span class=\"caret-container\">\n <button class=\"caret-btn\" (click)=\"toggleNode(node, $event)\" type=\"button\">\n @if (getIsOpen()(node)) {\n <sh-icon size=\"small\">caret-down</sh-icon>\n } @else {\n <sh-icon size=\"small\">caret-right</sh-icon>\n }\n </button>\n </span>\n }\n\n <!-- Node Icon -->\n @if (getNodeIcon(node)) {\n @if (getNodeIcon(node) === 'file') {\n <sh-icon class=\"node-icon\" [class.folder]=\"isFolder()(node)\" size=\"small\">file</sh-icon>\n } @else if (getNodeIcon(node) === 'folder') {\n <sh-icon class=\"node-icon\" [class.folder]=\"isFolder()(node)\" size=\"small\">folder</sh-icon>\n } @else if (getNodeIcon(node) === 'folder-open') {\n <sh-icon class=\"node-icon\" [class.folder]=\"isFolder()(node)\" size=\"small\">folder-open</sh-icon>\n } @else {\n <sh-icon class=\"node-icon\" [class.folder]=\"isFolder()(node)\" size=\"small\">\n {{ getNodeIcon(node) }}\n </sh-icon>\n }\n }\n\n <!-- Node Content -->\n <div class=\"node-content\">\n <ng-container *ngTemplateOutlet=\"isFolder()(node) && dirTemplate() ? dirTemplate() : (nodeTemplate() || defaultTemplate); context: { $implicit: node }\"></ng-container>\n </div>\n </div>\n } @empty {\n <div class=\"empty-state\">\n <ng-content select=\"[emptyState]\">\n No items in tree\n </ng-content>\n </div>\n }\n </div>\n} @else {\n <div class=\"sh-tree-container\" role=\"tree\">\n @for (node of visibleNodes(); track getId()(node)) {\n <div\n class=\"sh-tree-node\"\n [class.is-folder]=\"isFolder()(node)\"\n [class.is-expanded]=\"getIsOpen()(node)\"\n [class.is-selected]=\"selectedId() === getId()(node)\"\n [style.--tree-depth]=\"getNodeDepth(node)\"\n (click)=\"handleNodeClick(node, $event)\"\n role=\"treeitem\"\n [attr.aria-expanded]=\"isFolder()(node) ? getIsOpen()(node) : null\"\n >\n <!-- Indent guides -->\n @for (i of getDepthArray(getNodeDepth(node)); track i) {\n <div class=\"indent-guide\" [style.--guide-index]=\"i\"></div>\n }\n\n <!-- Folder Caret -->\n @if (isFolder()(node) && !dirTemplate()) {\n <span class=\"caret-container\">\n <button class=\"caret-btn\" (click)=\"toggleNode(node, $event)\" type=\"button\">\n @if (getIsOpen()(node)) {\n <sh-icon size=\"small\">caret-down</sh-icon>\n } @else {\n <sh-icon size=\"small\">caret-right</sh-icon>\n }\n </button>\n </span>\n }\n\n <!-- Node Icon -->\n @if (getNodeIcon(node)) {\n @if (getNodeIcon(node) === 'file') {\n <sh-icon class=\"node-icon\" [class.folder]=\"isFolder()(node)\" size=\"small\">file</sh-icon>\n } @else if (getNodeIcon(node) === 'folder') {\n <sh-icon class=\"node-icon\" [class.folder]=\"isFolder()(node)\" size=\"small\">folder</sh-icon>\n } @else if (getNodeIcon(node) === 'folder-open') {\n <sh-icon class=\"node-icon\" [class.folder]=\"isFolder()(node)\" size=\"small\">folder-open</sh-icon>\n } @else {\n <sh-icon class=\"node-icon\" [class.folder]=\"isFolder()(node)\" size=\"small\">\n {{ getNodeIcon(node) }}\n </sh-icon>\n }\n }\n\n <!-- Node Content -->\n <div class=\"node-content\">\n <ng-container *ngTemplateOutlet=\"isFolder()(node) && dirTemplate() ? dirTemplate() : (nodeTemplate() || defaultTemplate); context: { $implicit: node }\"></ng-container>\n </div>\n </div>\n } @empty {\n <div class=\"empty-state\">\n <ng-content select=\"[emptyState]\">\n No items in tree\n </ng-content>\n </div>\n }\n </div>\n}\n\n<ng-template #defaultTemplate let-node>\n <span class=\"node-name\">{{ getName()(node) }}</span>\n</ng-template>\n", styles: [".sh-sortable{position:relative}.sh-sortable.dragging [draggable],.sh-sortable.dragging .sortable-ghost{cursor:grabbing;transition:transform 40ms linear}.sh-sortable [draggable]{transform:translate(0);transition:none;z-index:2;-webkit-user-select:none;user-select:none}.sh-sortable:not(.sh-sortable-tree) [draggable]{background:var(--base-1)}.sh-sortable:not(.sh-sortable-tree) [draggable]:not(:has([sort-handle])){cursor:grab}.sh-sortable .sortable-ghost{opacity:.5;z-index:10}.sh-sortable.item-dragged-out .sortable-ghost{display:none}.sh-sortable [sort-handle]{cursor:grab}.sh-sortable.sh-sortable-tree [draggable]{transform:none!important;transition:none!important;z-index:auto}.sh-sortable.sh-sortable-tree .sortable-ghost{z-index:0!important}.sh-sortable.sh-sortable-tree .sortable-ghost.drop-before:before,.sh-sortable.sh-sortable-tree .sortable-ghost.drop-after:after{display:none!important}.sh-sortable.sh-sortable-tree .sortable-ghost.drop-inside{outline:none!important;background:inherit!important}.sh-sortable.sh-sortable-tree .drop-inside{background:var(--primary-3)!important;outline:2px solid var(--primary-8)!important;outline-offset:-.125rem;border-radius:var(--shape-1, 4px)}.sh-sortable.sh-sortable-tree .drop-inside .node-icon,.sh-sortable.sh-sortable-tree .drop-inside sh-tree-node .sh-tree-node-left sh-icon{color:var(--primary-8)!important}.sh-sortable.sh-sortable-tree .drop-before{position:relative;z-index:20}.sh-sortable.sh-sortable-tree .drop-before:before{content:\"\";position:absolute;top:-.1875rem;left:calc(var(--tree-padding-left, 12px) + var(--tree-depth, 0) * var(--tree-indent-step, 12px) + .375rem);right:var(--tree-padding-right, 6px);height:.375rem;background-image:radial-gradient(circle at 3px 3px,var(--primary-8) 3px,transparent 3px),linear-gradient(to right,var(--primary-8),var(--primary-8));background-repeat:no-repeat,no-repeat;background-position:left center,6px center;background-size:6px 6px,100% 2px;z-index:10;pointer-events:none}.sh-sortable.sh-sortable-tree .drop-after{position:relative;z-index:20}.sh-sortable.sh-sortable-tree .drop-after:after{content:\"\";position:absolute;bottom:-.1875rem;left:calc(var(--tree-padding-left, 12px) + var(--tree-depth, 0) * var(--tree-indent-step, 12px) + .375rem);right:var(--tree-padding-right, 6px);height:.375rem;background-image:radial-gradient(circle at 3px 3px,var(--primary-8) 3px,transparent 3px),linear-gradient(to right,var(--primary-8),var(--primary-8));background-repeat:no-repeat,no-repeat;background-position:left center,6px center;background-size:6px 6px,100% 2px;z-index:10;pointer-events:none}sh-tree{--tree-bg: var(--base-2);--tree-bc: var(--base-3);--tree-color: var(--base-12);--tree-hover-bg: var(--base-3);--tree-active-bg: var(--base-4);--tree-selected-bg: var(--base-4);--tree-guide-color: var(--base-4);--tree-caret-color: var(--base-9);--tree-caret-hover-color: var(--base-12);--tree-icon-color: var(--base-9);--tree-icon-folder-color: var(--primary-8);--tree-indent-step: .75rem;--tree-padding-left: .75rem;--tree-padding-right: .375rem;display:flex;flex-direction:column;width:100%;background:var(--tree-bg);border:1px solid var(--tree-bc);border-radius:var(--shape-2, .5rem);overflow:hidden;font-family:var(--font-family, sans-serif);box-shadow:var(--box-shadow-10)}sh-tree .sh-tree-container{flex:1;padding:.5rem 0;overflow-y:auto;position:relative}sh-tree .sh-tree-node{display:flex;align-items:center;height:2rem;position:relative;cursor:pointer;-webkit-user-select:none;user-select:none;color:var(--tree-color);font:var(--paragraph-20, 14px sans-serif);gap:.375rem;transition:background .12s ease;padding-left:calc(var(--tree-padding-left) + var(--tree-depth, 0) * var(--tree-indent-step));padding-right:var(--tree-padding-right);background:var(--tree-bg)}sh-tree .sh-tree-node:hover{background:var(--tree-hover-bg)}sh-tree .sh-tree-node.is-selected{background:var(--tree-selected-bg)}sh-tree .sh-tree-node.sortable-ghost{opacity:.4;background:var(--tree-active-bg)}sh-tree .sh-tree-node .indent-guide{position:absolute;top:0;bottom:0;width:1px;border-left:1px solid var(--tree-guide-color);opacity:.5;left:calc(var(--tree-padding-left) + var(--tree-indent-step) / 2 + var(--guide-index, 0) * var(--tree-indent-step))}sh-tree .sh-tree-node .caret-container{display:flex;align-items:center;justify-content:center;width:var(--tree-indent-step);height:1rem;z-index:2}sh-tree .sh-tree-node .caret-container:has(+.node-icon){position:absolute;opacity:0;z-index:3;width:var(--tree-indent-step)}sh-tree .sh-tree-node .caret-container .caret-btn{background:none;border:none;padding:0;cursor:pointer;display:flex;align-items:center;justify-content:center;color:var(--tree-caret-color);border-radius:var(--shape-1, 4px);width:100%;height:100%;position:relative;transition:background .15s ease,color .15s ease}sh-tree .sh-tree-node .caret-container .caret-btn:after{content:\"\";position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:1.5rem;height:1.5rem;z-index:1}sh-tree .sh-tree-node .caret-container .caret-btn:hover{color:var(--tree-caret-hover-color)}sh-tree .sh-tree-node .node-icon{color:var(--tree-icon-color);display:inline-flex;align-items:center;justify-content:center;width:var(--tree-indent-step)}sh-tree .sh-tree-node .node-icon.folder{color:var(--tree-icon-folder-color)}sh-tree .sh-tree-node .node-icon:has(~.node-content sh-tree-node sh-icon){display:none}sh-tree .sh-tree-node.is-folder sh-tree-node .sh-tree-node-left sh-icon{color:var(--tree-icon-folder-color)}sh-tree .sh-tree-node:not(.is-folder) sh-tree-node .sh-tree-node-left sh-icon{color:var(--tree-icon-color)}sh-tree .sh-tree-node .node-content{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;z-index:2;display:flex;align-items:center}sh-tree .sh-tree-node .node-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}sh-tree sh-tree-node{display:flex;align-items:center;width:100%;gap:.5rem;justify-content:space-between;min-width:0}sh-tree sh-tree-node .sh-tree-node-left{display:flex;align-items:center;gap:.25rem;padding-left:.25rem;overflow:hidden;min-width:0;flex:1}sh-tree sh-tree-node .sh-tree-node-left sh-icon{display:inline-flex;align-items:center;justify-content:center;width:var(--tree-indent-step)}sh-tree sh-tree-node .sh-tree-node-label{display:inline-block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}sh-tree sh-tree-node .sh-tree-node-label span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}sh-tree sh-tree-node .sh-tree-node-actions,sh-tree sh-tree-node sh-tree-node-actions{display:flex;align-items:center;gap:.5rem}sh-tree sh-tree-node .status-badge{font-size:.625rem;padding:.125rem .375rem;border-radius:var(--shape-1, 4px);text-transform:uppercase;font-weight:600}sh-tree sh-tree-node .status-badge.success{background:var(--success-3, #e6f4ea);color:var(--success-8, #137333)}sh-tree sh-tree-node .status-badge.warning{background:var(--warning-3, #fef7e0);color:var(--warning-8, #b06000)}sh-tree sh-tree-node .status-badge.error{background:var(--error-3, #fce8e6);color:var(--error-8, #c5221f)}sh-tree sh-tree-node .delete-btn{background:none;border:none;padding:.125rem;cursor:pointer;color:var(--base-9);border-radius:var(--shape-1, 4px);display:flex;opacity:0;transition:opacity .15s ease;align-items:center;justify-content:center}sh-tree sh-tree-node .delete-btn:hover{background:var(--base-4);color:var(--error-8, #c5221f)}sh-tree .sh-tree-node:hover .delete-btn{opacity:1}sh-tree .empty-state{padding:2rem;text-align:center;color:var(--tree-caret-color);font:var(--paragraph-20, 14px sans-serif)}\n"] }]
|
|
179
179
|
}], propDecorators: { items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: false }] }, { type: i0.Output, args: ["itemsChange"] }], sortableManager: [{ type: i0.Input, args: [{ isSignal: true, alias: "sortableManager", required: false }] }], selectedId: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedId", required: false }] }, { type: i0.Output, args: ["selectedIdChange"] }], getId: [{ type: i0.Input, args: [{ isSignal: true, alias: "getId", required: false }] }], getName: [{ type: i0.Input, args: [{ isSignal: true, alias: "getName", required: false }] }], getParentId: [{ type: i0.Input, args: [{ isSignal: true, alias: "getParentId", required: false }] }], isFolder: [{ type: i0.Input, args: [{ isSignal: true, alias: "isFolder", required: false }] }], getIsOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "getIsOpen", required: false }] }], setIsOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "setIsOpen", required: false }] }], getIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "getIcon", required: false }] }], openIconDir: [{ type: i0.ContentChild, args: [i0.forwardRef(() => ShipTreeOpenIcon), { isSignal: true }] }], closedIconDir: [{ type: i0.ContentChild, args: [i0.forwardRef(() => ShipTreeClosedIcon), { isSignal: true }] }], itemIconDir: [{ type: i0.ContentChild, args: [i0.forwardRef(() => ShipTreeItemIcon), { isSignal: true }] }], nodeClick: [{ type: i0.Output, args: ["nodeClick"] }], nodeToggle: [{ type: i0.Output, args: ["nodeToggle"] }], nodeTemplate: [{ type: i0.ContentChild, args: ['nodeTemplate', { isSignal: true }] }], dirTemplate: [{ type: i0.ContentChild, args: ['dirTemplate', { isSignal: true }] }] } });
|
|
180
180
|
class ShipTreeNode {
|
|
181
181
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.0", ngImport: i0, type: ShipTreeNode, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ship-ui-core-ship-tree.mjs","sources":["../../../projects/ship-ui/ship-tree/ship-tree.ts","../../../projects/ship-ui/ship-tree/ship-tree.html","../../../projects/ship-ui/ship-tree/ship-ui-core-ship-tree.ts"],"sourcesContent":["import { NgTemplateOutlet } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n computed,\n contentChild,\n Directive,\n ElementRef,\n inject,\n input,\n model,\n output,\n TemplateRef,\n ViewEncapsulation,\n} from '@angular/core';\nimport { ShipIcon } from '@ship-ui/core/ship-icon';\nimport { ShipSortable } from '@ship-ui/core/ship-sortable';\n\n@Directive({ selector: 'sh-icon[openIcon]', standalone: true })\nexport class ShipTreeOpenIcon {\n readonly el = inject(ElementRef<HTMLElement>);\n}\n\n@Directive({ selector: 'sh-icon[closedIcon]', standalone: true })\nexport class ShipTreeClosedIcon {\n readonly el = inject(ElementRef<HTMLElement>);\n}\n\n@Directive({ selector: 'sh-icon[itemIcon]', standalone: true })\nexport class ShipTreeItemIcon {\n readonly el = inject(ElementRef<HTMLElement>);\n}\n\n@Component({\n selector: 'sh-tree',\n standalone: true,\n imports: [NgTemplateOutlet, ShipIcon, ShipSortable],\n templateUrl: './ship-tree.html',\n styleUrl: './ship-tree.scss',\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '[class.sh-tree]': 'true',\n },\n})\nexport class ShipTree {\n /** The flat list of all tree nodes. */\n readonly items = model<any[]>([]);\n\n /** Optional Writable/Readable WritableSignal manager created by createTreeSortableManager. */\n readonly sortableManager = input<any>(null);\n\n /** Currently selected node ID. */\n readonly selectedId = model<string | null>(null);\n\n // Mappings\n readonly getId = input<(item: any) => string>((item) => item.id);\n readonly getName = input<(item: any) => string>((item) => item.name);\n readonly getParentId = input<(item: any) => string | null>((item) => item.parentId);\n readonly isFolder = input<(item: any) => boolean>((item) => item.type === 'dir');\n readonly getIsOpen = input<(item: any) => boolean>((item) => !!item.isOpen);\n readonly setIsOpen = input<(item: any, isOpen: boolean) => void>((item, open) => {\n item.isOpen = open;\n });\n\n /** Function returning a custom icon name for a node. */\n readonly getIcon = input<(item: any) => string | null>(() => null);\n\n // Read projected icons via lightweight directives\n readonly openIconDir = contentChild(ShipTreeOpenIcon);\n readonly closedIconDir = contentChild(ShipTreeClosedIcon);\n readonly itemIconDir = contentChild(ShipTreeItemIcon);\n\n openIconName = computed(() => this.openIconDir()?.el.nativeElement.textContent?.trim() || null);\n closedIconName = computed(() => this.closedIconDir()?.el.nativeElement.textContent?.trim() || null);\n itemIconName = computed(() => this.itemIconDir()?.el.nativeElement.textContent?.trim() || null);\n\n // Outputs\n readonly nodeClick = output<any>();\n readonly nodeToggle = output<{ node: any; isOpen: boolean }>();\n\n readonly nodeTemplate = contentChild<TemplateRef<any>>('nodeTemplate');\n readonly dirTemplate = contentChild<TemplateRef<any>>('dirTemplate');\n\n /** Filter the full flat array down to only visible nodes (whose parents are all expanded). */\n visibleNodes = computed(() => {\n const manager = this.sortableManager();\n if (manager && typeof manager.visibleNodes === 'function') {\n return manager.visibleNodes();\n }\n\n const list = this.items();\n const visible: any[] = [];\n\n const isNodeVisible = (node: any): boolean => {\n let currentParentId = this.getParentId()(node);\n while (currentParentId !== null && currentParentId !== undefined) {\n const parent = list.find((n) => this.getId()(n) === currentParentId);\n if (!parent || !this.getIsOpen()(parent)) {\n return false;\n }\n currentParentId = this.getParentId()(parent);\n }\n return true;\n };\n\n for (const node of list) {\n const parentId = this.getParentId()(node);\n if (parentId === null || parentId === undefined || isNodeVisible(node)) {\n visible.push(node);\n }\n }\n return visible;\n });\n\n toggleNode(node: any, event: MouseEvent) {\n event.stopPropagation();\n const open = !this.getIsOpen()(node);\n\n this.items.update((list) =>\n list.map((item) => {\n if (this.getId()(item) === this.getId()(node)) {\n const updated = { ...item };\n this.setIsOpen()(updated, open);\n return updated;\n }\n return item;\n })\n );\n\n this.nodeToggle.emit({ node, isOpen: open });\n }\n\n handleNodeClick(node: any, event: MouseEvent) {\n const target = event.target as HTMLElement;\n const isIconClick = !!target.closest('sh-icon') && !target.closest('.sh-tree-node-actions') && !target.closest('sh-tree-node-actions') && !target.closest('.caret-container');\n\n if (isIconClick && this.isFolder()(node)) {\n this.toggleNode(node, event);\n } else {\n this.selectNode(node);\n }\n }\n\n selectNode(node: any) {\n this.selectedId.set(this.getId()(node));\n this.nodeClick.emit(node);\n }\n\n getDepthArray(depth: number): number[] {\n return Array.from({ length: depth }, (_, i) => i);\n }\n\n getNodeDepth(node: any): number {\n const list = this.items();\n let depth = 0;\n let currentParentId = this.getParentId()(node);\n while (currentParentId !== null && currentParentId !== undefined) {\n const parent = list.find((n) => this.getId()(n) === currentParentId);\n if (!parent) break;\n depth++;\n currentParentId = this.getParentId()(parent);\n }\n return depth;\n }\n\n getNodeIcon(node: any): string | null {\n const customIcon = this.getIcon()(node);\n if (customIcon) return customIcon;\n\n if (this.isFolder()(node)) {\n const open = this.getIsOpen()(node);\n return open ? this.openIconName() : this.closedIconName();\n }\n return this.itemIconName() || 'file';\n }\n}\n\n@Component({\n selector: 'sh-tree-node',\n template: `\n <div class=\"sh-tree-node-left\">\n <ng-content select=\"sh-icon\" />\n <span class=\"sh-tree-node-label\">\n <ng-content />\n </span>\n </div>\n <div class=\"sh-tree-node-actions\">\n <ng-content select=\"[actions], sh-tree-node-actions\" />\n </div>\n `,\n host: {\n '[class.sh-tree-node-layout]': 'true',\n },\n})\nexport class ShipTreeNode {}\n\n@Component({\n selector: 'sh-tree-node-actions',\n template: `\n <ng-content />\n `,\n host: {\n '[class.sh-tree-node-actions]': 'true',\n },\n})\nexport class ShipTreeNodeActions {}\n","@if (sortableManager()) {\n <div\n class=\"sh-tree-container\"\n [shSortable]=\"sortableManager()\"\n [treeItems]=\"visibleNodes()\"\n sortingMode=\"tree\"\n >\n @for (node of visibleNodes(); track getId()(node)) {\n <div\n class=\"sh-tree-node\"\n [class.is-folder]=\"isFolder()(node)\"\n [class.is-expanded]=\"getIsOpen()(node)\"\n [class.is-selected]=\"selectedId() === getId()(node)\"\n draggable=\"true\"\n [attr.sortable-dir]=\"isFolder()(node) ? 'true' : null\"\n [style.--tree-depth]=\"getNodeDepth(node)\"\n (click)=\"handleNodeClick(node, $event)\"\n >\n <!-- Indent guides -->\n @for (i of getDepthArray(getNodeDepth(node)); track i) {\n <div class=\"indent-guide\" [style.--guide-index]=\"i\"></div>\n }\n\n <!-- Folder Caret -->\n @if (isFolder()(node) && !dirTemplate()) {\n <span class=\"caret-container\">\n <button class=\"caret-btn\" (click)=\"toggleNode(node, $event)\" type=\"button\">\n @if (getIsOpen()(node)) {\n <sh-icon size=\"small\">caret-down</sh-icon>\n } @else {\n <sh-icon size=\"small\">caret-right</sh-icon>\n }\n </button>\n </span>\n }\n\n <!-- Node Icon -->\n @if (getNodeIcon(node)) {\n @if (getNodeIcon(node) === 'file') {\n <sh-icon class=\"node-icon\" [class.folder]=\"isFolder()(node)\" size=\"small\">file</sh-icon>\n } @else if (getNodeIcon(node) === 'folder') {\n <sh-icon class=\"node-icon\" [class.folder]=\"isFolder()(node)\" size=\"small\">folder</sh-icon>\n } @else if (getNodeIcon(node) === 'folder-open') {\n <sh-icon class=\"node-icon\" [class.folder]=\"isFolder()(node)\" size=\"small\">folder-open</sh-icon>\n } @else {\n <sh-icon class=\"node-icon\" [class.folder]=\"isFolder()(node)\" size=\"small\">\n {{ getNodeIcon(node) }}\n </sh-icon>\n }\n }\n\n <!-- Node Content -->\n <div class=\"node-content\">\n <ng-container *ngTemplateOutlet=\"isFolder()(node) && dirTemplate() ? dirTemplate() : (nodeTemplate() || defaultTemplate); context: { $implicit: node }\"></ng-container>\n </div>\n </div>\n } @empty {\n <div class=\"empty-state\">\n <ng-content select=\"[emptyState]\">\n No items in tree\n </ng-content>\n </div>\n }\n </div>\n} @else {\n <div class=\"sh-tree-container\">\n @for (node of visibleNodes(); track getId()(node)) {\n <div\n class=\"sh-tree-node\"\n [class.is-folder]=\"isFolder()(node)\"\n [class.is-expanded]=\"getIsOpen()(node)\"\n [class.is-selected]=\"selectedId() === getId()(node)\"\n [style.--tree-depth]=\"getNodeDepth(node)\"\n (click)=\"handleNodeClick(node, $event)\"\n >\n <!-- Indent guides -->\n @for (i of getDepthArray(getNodeDepth(node)); track i) {\n <div class=\"indent-guide\" [style.--guide-index]=\"i\"></div>\n }\n\n <!-- Folder Caret -->\n @if (isFolder()(node) && !dirTemplate()) {\n <span class=\"caret-container\">\n <button class=\"caret-btn\" (click)=\"toggleNode(node, $event)\" type=\"button\">\n @if (getIsOpen()(node)) {\n <sh-icon size=\"small\">caret-down</sh-icon>\n } @else {\n <sh-icon size=\"small\">caret-right</sh-icon>\n }\n </button>\n </span>\n }\n\n <!-- Node Icon -->\n @if (getNodeIcon(node)) {\n @if (getNodeIcon(node) === 'file') {\n <sh-icon class=\"node-icon\" [class.folder]=\"isFolder()(node)\" size=\"small\">file</sh-icon>\n } @else if (getNodeIcon(node) === 'folder') {\n <sh-icon class=\"node-icon\" [class.folder]=\"isFolder()(node)\" size=\"small\">folder</sh-icon>\n } @else if (getNodeIcon(node) === 'folder-open') {\n <sh-icon class=\"node-icon\" [class.folder]=\"isFolder()(node)\" size=\"small\">folder-open</sh-icon>\n } @else {\n <sh-icon class=\"node-icon\" [class.folder]=\"isFolder()(node)\" size=\"small\">\n {{ getNodeIcon(node) }}\n </sh-icon>\n }\n }\n\n <!-- Node Content -->\n <div class=\"node-content\">\n <ng-container *ngTemplateOutlet=\"isFolder()(node) && dirTemplate() ? dirTemplate() : (nodeTemplate() || defaultTemplate); context: { $implicit: node }\"></ng-container>\n </div>\n </div>\n } @empty {\n <div class=\"empty-state\">\n <ng-content select=\"[emptyState]\">\n No items in tree\n </ng-content>\n </div>\n }\n </div>\n}\n\n<ng-template #defaultTemplate let-node>\n <span class=\"node-name\">{{ getName()(node) }}</span>\n</ng-template>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ship-ui-core-ship-tree.mjs","sources":["../../../projects/ship-ui/ship-tree/ship-tree.ts","../../../projects/ship-ui/ship-tree/ship-tree.html","../../../projects/ship-ui/ship-tree/ship-ui-core-ship-tree.ts"],"sourcesContent":["import { NgTemplateOutlet } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n computed,\n contentChild,\n Directive,\n ElementRef,\n inject,\n input,\n model,\n output,\n TemplateRef,\n ViewEncapsulation,\n} from '@angular/core';\nimport { ShipIcon } from '@ship-ui/core/ship-icon';\nimport { ShipSortable } from '@ship-ui/core/ship-sortable';\n\n@Directive({ selector: 'sh-icon[openIcon]', standalone: true })\nexport class ShipTreeOpenIcon {\n readonly el = inject(ElementRef<HTMLElement>);\n}\n\n@Directive({ selector: 'sh-icon[closedIcon]', standalone: true })\nexport class ShipTreeClosedIcon {\n readonly el = inject(ElementRef<HTMLElement>);\n}\n\n@Directive({ selector: 'sh-icon[itemIcon]', standalone: true })\nexport class ShipTreeItemIcon {\n readonly el = inject(ElementRef<HTMLElement>);\n}\n\n@Component({\n selector: 'sh-tree',\n standalone: true,\n imports: [NgTemplateOutlet, ShipIcon, ShipSortable],\n templateUrl: './ship-tree.html',\n styleUrl: './ship-tree.scss',\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '[class.sh-tree]': 'true',\n },\n})\nexport class ShipTree {\n /** The flat list of all tree nodes. */\n readonly items = model<any[]>([]);\n\n /** Optional Writable/Readable WritableSignal manager created by createTreeSortableManager. */\n readonly sortableManager = input<any>(null);\n\n /** Currently selected node ID. */\n readonly selectedId = model<string | null>(null);\n\n // Mappings\n readonly getId = input<(item: any) => string>((item) => item.id);\n readonly getName = input<(item: any) => string>((item) => item.name);\n readonly getParentId = input<(item: any) => string | null>((item) => item.parentId);\n readonly isFolder = input<(item: any) => boolean>((item) => item.type === 'dir');\n readonly getIsOpen = input<(item: any) => boolean>((item) => !!item.isOpen);\n readonly setIsOpen = input<(item: any, isOpen: boolean) => void>((item, open) => {\n item.isOpen = open;\n });\n\n /** Function returning a custom icon name for a node. */\n readonly getIcon = input<(item: any) => string | null>(() => null);\n\n // Read projected icons via lightweight directives\n readonly openIconDir = contentChild(ShipTreeOpenIcon);\n readonly closedIconDir = contentChild(ShipTreeClosedIcon);\n readonly itemIconDir = contentChild(ShipTreeItemIcon);\n\n openIconName = computed(() => this.openIconDir()?.el.nativeElement.textContent?.trim() || null);\n closedIconName = computed(() => this.closedIconDir()?.el.nativeElement.textContent?.trim() || null);\n itemIconName = computed(() => this.itemIconDir()?.el.nativeElement.textContent?.trim() || null);\n\n // Outputs\n readonly nodeClick = output<any>();\n readonly nodeToggle = output<{ node: any; isOpen: boolean }>();\n\n readonly nodeTemplate = contentChild<TemplateRef<any>>('nodeTemplate');\n readonly dirTemplate = contentChild<TemplateRef<any>>('dirTemplate');\n\n /** Filter the full flat array down to only visible nodes (whose parents are all expanded). */\n visibleNodes = computed(() => {\n const manager = this.sortableManager();\n if (manager && typeof manager.visibleNodes === 'function') {\n return manager.visibleNodes();\n }\n\n const list = this.items();\n const visible: any[] = [];\n\n const isNodeVisible = (node: any): boolean => {\n let currentParentId = this.getParentId()(node);\n while (currentParentId !== null && currentParentId !== undefined) {\n const parent = list.find((n) => this.getId()(n) === currentParentId);\n if (!parent || !this.getIsOpen()(parent)) {\n return false;\n }\n currentParentId = this.getParentId()(parent);\n }\n return true;\n };\n\n for (const node of list) {\n const parentId = this.getParentId()(node);\n if (parentId === null || parentId === undefined || isNodeVisible(node)) {\n visible.push(node);\n }\n }\n return visible;\n });\n\n toggleNode(node: any, event: MouseEvent) {\n event.stopPropagation();\n const open = !this.getIsOpen()(node);\n\n this.items.update((list) =>\n list.map((item) => {\n if (this.getId()(item) === this.getId()(node)) {\n const updated = { ...item };\n this.setIsOpen()(updated, open);\n return updated;\n }\n return item;\n })\n );\n\n this.nodeToggle.emit({ node, isOpen: open });\n }\n\n handleNodeClick(node: any, event: MouseEvent) {\n const target = event.target as HTMLElement;\n const isIconClick = !!target.closest('sh-icon') && !target.closest('.sh-tree-node-actions') && !target.closest('sh-tree-node-actions') && !target.closest('.caret-container');\n\n if (isIconClick && this.isFolder()(node)) {\n this.toggleNode(node, event);\n } else {\n this.selectNode(node);\n }\n }\n\n selectNode(node: any) {\n this.selectedId.set(this.getId()(node));\n this.nodeClick.emit(node);\n }\n\n getDepthArray(depth: number): number[] {\n return Array.from({ length: depth }, (_, i) => i);\n }\n\n getNodeDepth(node: any): number {\n const list = this.items();\n let depth = 0;\n let currentParentId = this.getParentId()(node);\n while (currentParentId !== null && currentParentId !== undefined) {\n const parent = list.find((n) => this.getId()(n) === currentParentId);\n if (!parent) break;\n depth++;\n currentParentId = this.getParentId()(parent);\n }\n return depth;\n }\n\n getNodeIcon(node: any): string | null {\n const customIcon = this.getIcon()(node);\n if (customIcon) return customIcon;\n\n if (this.isFolder()(node)) {\n const open = this.getIsOpen()(node);\n return open ? this.openIconName() : this.closedIconName();\n }\n return this.itemIconName() || 'file';\n }\n}\n\n@Component({\n selector: 'sh-tree-node',\n template: `\n <div class=\"sh-tree-node-left\">\n <ng-content select=\"sh-icon\" />\n <span class=\"sh-tree-node-label\">\n <ng-content />\n </span>\n </div>\n <div class=\"sh-tree-node-actions\">\n <ng-content select=\"[actions], sh-tree-node-actions\" />\n </div>\n `,\n host: {\n '[class.sh-tree-node-layout]': 'true',\n },\n})\nexport class ShipTreeNode {}\n\n@Component({\n selector: 'sh-tree-node-actions',\n template: `\n <ng-content />\n `,\n host: {\n '[class.sh-tree-node-actions]': 'true',\n },\n})\nexport class ShipTreeNodeActions {}\n","@if (sortableManager()) {\n <div\n class=\"sh-tree-container\"\n [shSortable]=\"sortableManager()\"\n [treeItems]=\"visibleNodes()\"\n sortingMode=\"tree\"\n role=\"tree\"\n >\n @for (node of visibleNodes(); track getId()(node)) {\n <div\n class=\"sh-tree-node\"\n [class.is-folder]=\"isFolder()(node)\"\n [class.is-expanded]=\"getIsOpen()(node)\"\n [class.is-selected]=\"selectedId() === getId()(node)\"\n draggable=\"true\"\n [attr.sortable-dir]=\"isFolder()(node) ? 'true' : null\"\n [style.--tree-depth]=\"getNodeDepth(node)\"\n (click)=\"handleNodeClick(node, $event)\"\n role=\"treeitem\"\n [attr.aria-expanded]=\"isFolder()(node) ? getIsOpen()(node) : null\"\n >\n <!-- Indent guides -->\n @for (i of getDepthArray(getNodeDepth(node)); track i) {\n <div class=\"indent-guide\" [style.--guide-index]=\"i\"></div>\n }\n\n <!-- Folder Caret -->\n @if (isFolder()(node) && !dirTemplate()) {\n <span class=\"caret-container\">\n <button class=\"caret-btn\" (click)=\"toggleNode(node, $event)\" type=\"button\">\n @if (getIsOpen()(node)) {\n <sh-icon size=\"small\">caret-down</sh-icon>\n } @else {\n <sh-icon size=\"small\">caret-right</sh-icon>\n }\n </button>\n </span>\n }\n\n <!-- Node Icon -->\n @if (getNodeIcon(node)) {\n @if (getNodeIcon(node) === 'file') {\n <sh-icon class=\"node-icon\" [class.folder]=\"isFolder()(node)\" size=\"small\">file</sh-icon>\n } @else if (getNodeIcon(node) === 'folder') {\n <sh-icon class=\"node-icon\" [class.folder]=\"isFolder()(node)\" size=\"small\">folder</sh-icon>\n } @else if (getNodeIcon(node) === 'folder-open') {\n <sh-icon class=\"node-icon\" [class.folder]=\"isFolder()(node)\" size=\"small\">folder-open</sh-icon>\n } @else {\n <sh-icon class=\"node-icon\" [class.folder]=\"isFolder()(node)\" size=\"small\">\n {{ getNodeIcon(node) }}\n </sh-icon>\n }\n }\n\n <!-- Node Content -->\n <div class=\"node-content\">\n <ng-container *ngTemplateOutlet=\"isFolder()(node) && dirTemplate() ? dirTemplate() : (nodeTemplate() || defaultTemplate); context: { $implicit: node }\"></ng-container>\n </div>\n </div>\n } @empty {\n <div class=\"empty-state\">\n <ng-content select=\"[emptyState]\">\n No items in tree\n </ng-content>\n </div>\n }\n </div>\n} @else {\n <div class=\"sh-tree-container\" role=\"tree\">\n @for (node of visibleNodes(); track getId()(node)) {\n <div\n class=\"sh-tree-node\"\n [class.is-folder]=\"isFolder()(node)\"\n [class.is-expanded]=\"getIsOpen()(node)\"\n [class.is-selected]=\"selectedId() === getId()(node)\"\n [style.--tree-depth]=\"getNodeDepth(node)\"\n (click)=\"handleNodeClick(node, $event)\"\n role=\"treeitem\"\n [attr.aria-expanded]=\"isFolder()(node) ? getIsOpen()(node) : null\"\n >\n <!-- Indent guides -->\n @for (i of getDepthArray(getNodeDepth(node)); track i) {\n <div class=\"indent-guide\" [style.--guide-index]=\"i\"></div>\n }\n\n <!-- Folder Caret -->\n @if (isFolder()(node) && !dirTemplate()) {\n <span class=\"caret-container\">\n <button class=\"caret-btn\" (click)=\"toggleNode(node, $event)\" type=\"button\">\n @if (getIsOpen()(node)) {\n <sh-icon size=\"small\">caret-down</sh-icon>\n } @else {\n <sh-icon size=\"small\">caret-right</sh-icon>\n }\n </button>\n </span>\n }\n\n <!-- Node Icon -->\n @if (getNodeIcon(node)) {\n @if (getNodeIcon(node) === 'file') {\n <sh-icon class=\"node-icon\" [class.folder]=\"isFolder()(node)\" size=\"small\">file</sh-icon>\n } @else if (getNodeIcon(node) === 'folder') {\n <sh-icon class=\"node-icon\" [class.folder]=\"isFolder()(node)\" size=\"small\">folder</sh-icon>\n } @else if (getNodeIcon(node) === 'folder-open') {\n <sh-icon class=\"node-icon\" [class.folder]=\"isFolder()(node)\" size=\"small\">folder-open</sh-icon>\n } @else {\n <sh-icon class=\"node-icon\" [class.folder]=\"isFolder()(node)\" size=\"small\">\n {{ getNodeIcon(node) }}\n </sh-icon>\n }\n }\n\n <!-- Node Content -->\n <div class=\"node-content\">\n <ng-container *ngTemplateOutlet=\"isFolder()(node) && dirTemplate() ? dirTemplate() : (nodeTemplate() || defaultTemplate); context: { $implicit: node }\"></ng-container>\n </div>\n </div>\n } @empty {\n <div class=\"empty-state\">\n <ng-content select=\"[emptyState]\">\n No items in tree\n </ng-content>\n </div>\n }\n </div>\n}\n\n<ng-template #defaultTemplate let-node>\n <span class=\"node-name\">{{ getName()(node) }}</span>\n</ng-template>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
@@ -158,7 +158,7 @@ class ShipVirtualScroll {
|
|
|
158
158
|
}
|
|
159
159
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.0", ngImport: i0, type: ShipVirtualScroll, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
160
160
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.0.0", type: ShipVirtualScroll, isStandalone: true, selector: "sh-virtual-scroll", viewQueries: [{ propertyName: "viewportRef", first: true, predicate: ["viewport"], descendants: true, isSignal: true }, { propertyName: "itemElements", predicate: ["item"], descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
161
|
-
<div class="viewport" #viewport (scroll)="onScroll()">
|
|
161
|
+
<div class="viewport" #viewport tabindex="0" role="region" aria-label="Virtualized list" (scroll)="onScroll()">
|
|
162
162
|
<div class="total-height" [style.height]="totalHeight() + 'px'"></div>
|
|
163
163
|
<div class="items-container" [style.transform]="'translateY(' + translateY() + 'px)'">
|
|
164
164
|
<ng-content />
|
|
@@ -169,7 +169,7 @@ class ShipVirtualScroll {
|
|
|
169
169
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.0", ngImport: i0, type: ShipVirtualScroll, decorators: [{
|
|
170
170
|
type: Component,
|
|
171
171
|
args: [{ selector: 'sh-virtual-scroll', encapsulation: ViewEncapsulation.None, imports: [], template: `
|
|
172
|
-
<div class="viewport" #viewport (scroll)="onScroll()">
|
|
172
|
+
<div class="viewport" #viewport tabindex="0" role="region" aria-label="Virtualized list" (scroll)="onScroll()">
|
|
173
173
|
<div class="total-height" [style.height]="totalHeight() + 'px'"></div>
|
|
174
174
|
<div class="items-container" [style.transform]="'translateY(' + translateY() + 'px)'">
|
|
175
175
|
<ng-content />
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ship-ui-core-ship-virtual-scroll.mjs","sources":["../../../projects/ship-ui/ship-virtual-scroll/ship-virtual-scroll.component.ts","../../../projects/ship-ui/ship-virtual-scroll/ship-ui-core-ship-virtual-scroll.ts"],"sourcesContent":["import { ChangeDetectionStrategy, ChangeDetectorRef, Component, computed, effect, ElementRef, inject, Renderer2, signal, viewChild, viewChildren, ViewEncapsulation } from '@angular/core';\n\n@Component({\n selector: 'sh-virtual-scroll',\n styleUrl: './ship-virtual-scroll.scss',\n encapsulation: ViewEncapsulation.None,\n imports: [],\n template: `\n <div class=\"viewport\" #viewport (scroll)=\"onScroll()\">\n <div class=\"total-height\" [style.height]=\"totalHeight() + 'px'\"></div>\n <div class=\"items-container\" [style.transform]=\"'translateY(' + translateY() + 'px)'\">\n <ng-content />\n </div>\n </div>\n `,\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class ShipVirtualScroll {\n #changeRef = inject(ChangeDetectorRef);\n #renderer = inject(Renderer2);\n #hostElement = inject(ElementRef);\n\n viewportRef = viewChild.required<ElementRef<HTMLDivElement>>('viewport');\n itemElements = viewChildren<ElementRef>('item');\n\n bufferSize = signal(10);\n\n itemHeights = signal<number[]>([]);\n startIndex = signal(0);\n endIndex = signal(0);\n translateY = signal(0);\n totalHeight = computed(() => this.itemHeights().reduce((sum, height) => sum + height, 0));\n numberOfRenderedItems = signal(0);\n\n #resizeObserver: ResizeObserver | null = null;\n #hostResizeObserver: ResizeObserver | null = null;\n\n #itemHeightsEffect = effect(() => {\n const startIndex = this.startIndex();\n const endIndex = this.endIndex();\n const itemHeights = this.itemHeights();\n\n if (startIndex > 0 && endIndex > 0 && itemHeights.length > 0) {\n let newTranslateY = 0;\n for (let i = 0; i < startIndex; i++) {\n newTranslateY += itemHeights[i];\n }\n this.translateY.set(newTranslateY);\n }\n });\n\n #totalHeightEffect = effect(() => {\n const _ = this.totalHeight();\n this.#changeRef.detectChanges();\n });\n\n #itemElementsEffect = effect(() => {\n const itemElements = this.itemElements();\n\n if (this.#resizeObserver && itemElements) {\n this.#resizeObserver.disconnect();\n const heights = new Array(itemElements.length).fill(0);\n this.numberOfRenderedItems.set(itemElements.length);\n this.itemHeights.set(heights);\n\n for (let i = 0; i < itemElements.length; i++) {\n this.#resizeObserver.observe(itemElements[i].nativeElement);\n heights[i] = itemElements[i].nativeElement.offsetHeight;\n }\n\n this.itemHeights.set(heights);\n this.#calculateVisibleItems();\n }\n });\n\n ngAfterViewInit() {\n this.#setupHostResizeObserver();\n this.#setupResizeObserver();\n this.#changeRef.detectChanges();\n }\n\n onScroll() {\n this.#calculateVisibleItems();\n }\n\n #setupHostResizeObserver() {\n if (typeof ResizeObserver === 'undefined') return;\n this.#hostResizeObserver = new ResizeObserver((entries) => {\n const hostElement = entries[0];\n if (hostElement) {\n const newHeight = hostElement.contentRect.height;\n this.#renderer.setStyle(this.viewportRef().nativeElement, 'height', `${newHeight}px`);\n }\n });\n\n this.#hostResizeObserver.observe(this.#hostElement.nativeElement);\n }\n\n #setupResizeObserver() {\n if (typeof ResizeObserver === 'undefined') return;\n this.#resizeObserver = new ResizeObserver((entries) => {\n const newHeights = [...this.itemHeights()];\n\n let didUpdate = false;\n\n for (const entry of entries) {\n const index = this.itemElements().findIndex((el) => el.nativeElement === entry.target);\n\n if (index !== undefined && index !== -1) {\n const newHeight = entry.contentRect.height;\n if (newHeights[index] !== newHeight) {\n newHeights[index] = newHeight;\n didUpdate = true;\n }\n }\n }\n\n if (didUpdate) {\n this.itemHeights.set(newHeights);\n this.#calculateVisibleItems();\n }\n });\n }\n\n #cleanupResizeObserver() {\n if (this.#resizeObserver) {\n this.#resizeObserver.disconnect();\n this.#resizeObserver = null;\n }\n }\n\n #cleanupHostResizeObserver() {\n if (this.#hostResizeObserver) {\n this.#hostResizeObserver.disconnect();\n this.#hostResizeObserver = null;\n }\n }\n\n #calculateVisibleItems() {\n const nativeElement = this.viewportRef();\n if (!nativeElement) return;\n\n const scrollTop = nativeElement.nativeElement.scrollTop;\n const viewportHeight = nativeElement.nativeElement.clientHeight;\n\n let accumulatedHeight = 0;\n let startIndex = -1;\n let endIndex = -1;\n\n for (let i = 0; i < this.itemHeights().length; i++) {\n const itemHeight = this.itemHeights()[i];\n\n if (startIndex === -1 && accumulatedHeight + itemHeight >= scrollTop - this.bufferSize()) {\n startIndex = i;\n }\n\n if (endIndex === -1 && accumulatedHeight >= scrollTop + viewportHeight + this.bufferSize()) {\n endIndex = i;\n break;\n }\n\n accumulatedHeight += itemHeight;\n }\n\n if (endIndex === -1) {\n endIndex = this.itemHeights().length - 1;\n }\n\n if (this.startIndex() !== startIndex) {\n this.startIndex.set(startIndex);\n }\n if (this.endIndex() !== endIndex) {\n this.endIndex.set(endIndex);\n }\n }\n\n ngOnDestroy() {\n this.#cleanupResizeObserver();\n this.#cleanupHostResizeObserver();\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ship-ui-core-ship-virtual-scroll.mjs","sources":["../../../projects/ship-ui/ship-virtual-scroll/ship-virtual-scroll.component.ts","../../../projects/ship-ui/ship-virtual-scroll/ship-ui-core-ship-virtual-scroll.ts"],"sourcesContent":["import { ChangeDetectionStrategy, ChangeDetectorRef, Component, computed, effect, ElementRef, inject, Renderer2, signal, viewChild, viewChildren, ViewEncapsulation } from '@angular/core';\n\n@Component({\n selector: 'sh-virtual-scroll',\n styleUrl: './ship-virtual-scroll.scss',\n encapsulation: ViewEncapsulation.None,\n imports: [],\n template: `\n <div class=\"viewport\" #viewport tabindex=\"0\" role=\"region\" aria-label=\"Virtualized list\" (scroll)=\"onScroll()\">\n <div class=\"total-height\" [style.height]=\"totalHeight() + 'px'\"></div>\n <div class=\"items-container\" [style.transform]=\"'translateY(' + translateY() + 'px)'\">\n <ng-content />\n </div>\n </div>\n `,\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class ShipVirtualScroll {\n #changeRef = inject(ChangeDetectorRef);\n #renderer = inject(Renderer2);\n #hostElement = inject(ElementRef);\n\n viewportRef = viewChild.required<ElementRef<HTMLDivElement>>('viewport');\n itemElements = viewChildren<ElementRef>('item');\n\n bufferSize = signal(10);\n\n itemHeights = signal<number[]>([]);\n startIndex = signal(0);\n endIndex = signal(0);\n translateY = signal(0);\n totalHeight = computed(() => this.itemHeights().reduce((sum, height) => sum + height, 0));\n numberOfRenderedItems = signal(0);\n\n #resizeObserver: ResizeObserver | null = null;\n #hostResizeObserver: ResizeObserver | null = null;\n\n #itemHeightsEffect = effect(() => {\n const startIndex = this.startIndex();\n const endIndex = this.endIndex();\n const itemHeights = this.itemHeights();\n\n if (startIndex > 0 && endIndex > 0 && itemHeights.length > 0) {\n let newTranslateY = 0;\n for (let i = 0; i < startIndex; i++) {\n newTranslateY += itemHeights[i];\n }\n this.translateY.set(newTranslateY);\n }\n });\n\n #totalHeightEffect = effect(() => {\n const _ = this.totalHeight();\n this.#changeRef.detectChanges();\n });\n\n #itemElementsEffect = effect(() => {\n const itemElements = this.itemElements();\n\n if (this.#resizeObserver && itemElements) {\n this.#resizeObserver.disconnect();\n const heights = new Array(itemElements.length).fill(0);\n this.numberOfRenderedItems.set(itemElements.length);\n this.itemHeights.set(heights);\n\n for (let i = 0; i < itemElements.length; i++) {\n this.#resizeObserver.observe(itemElements[i].nativeElement);\n heights[i] = itemElements[i].nativeElement.offsetHeight;\n }\n\n this.itemHeights.set(heights);\n this.#calculateVisibleItems();\n }\n });\n\n ngAfterViewInit() {\n this.#setupHostResizeObserver();\n this.#setupResizeObserver();\n this.#changeRef.detectChanges();\n }\n\n onScroll() {\n this.#calculateVisibleItems();\n }\n\n #setupHostResizeObserver() {\n if (typeof ResizeObserver === 'undefined') return;\n this.#hostResizeObserver = new ResizeObserver((entries) => {\n const hostElement = entries[0];\n if (hostElement) {\n const newHeight = hostElement.contentRect.height;\n this.#renderer.setStyle(this.viewportRef().nativeElement, 'height', `${newHeight}px`);\n }\n });\n\n this.#hostResizeObserver.observe(this.#hostElement.nativeElement);\n }\n\n #setupResizeObserver() {\n if (typeof ResizeObserver === 'undefined') return;\n this.#resizeObserver = new ResizeObserver((entries) => {\n const newHeights = [...this.itemHeights()];\n\n let didUpdate = false;\n\n for (const entry of entries) {\n const index = this.itemElements().findIndex((el) => el.nativeElement === entry.target);\n\n if (index !== undefined && index !== -1) {\n const newHeight = entry.contentRect.height;\n if (newHeights[index] !== newHeight) {\n newHeights[index] = newHeight;\n didUpdate = true;\n }\n }\n }\n\n if (didUpdate) {\n this.itemHeights.set(newHeights);\n this.#calculateVisibleItems();\n }\n });\n }\n\n #cleanupResizeObserver() {\n if (this.#resizeObserver) {\n this.#resizeObserver.disconnect();\n this.#resizeObserver = null;\n }\n }\n\n #cleanupHostResizeObserver() {\n if (this.#hostResizeObserver) {\n this.#hostResizeObserver.disconnect();\n this.#hostResizeObserver = null;\n }\n }\n\n #calculateVisibleItems() {\n const nativeElement = this.viewportRef();\n if (!nativeElement) return;\n\n const scrollTop = nativeElement.nativeElement.scrollTop;\n const viewportHeight = nativeElement.nativeElement.clientHeight;\n\n let accumulatedHeight = 0;\n let startIndex = -1;\n let endIndex = -1;\n\n for (let i = 0; i < this.itemHeights().length; i++) {\n const itemHeight = this.itemHeights()[i];\n\n if (startIndex === -1 && accumulatedHeight + itemHeight >= scrollTop - this.bufferSize()) {\n startIndex = i;\n }\n\n if (endIndex === -1 && accumulatedHeight >= scrollTop + viewportHeight + this.bufferSize()) {\n endIndex = i;\n break;\n }\n\n accumulatedHeight += itemHeight;\n }\n\n if (endIndex === -1) {\n endIndex = this.itemHeights().length - 1;\n }\n\n if (this.startIndex() !== startIndex) {\n this.startIndex.set(startIndex);\n }\n if (this.endIndex() !== endIndex) {\n this.endIndex.set(endIndex);\n }\n }\n\n ngOnDestroy() {\n this.#cleanupResizeObserver();\n this.#cleanupHostResizeObserver();\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|