@ngstarter-ui/components 21.0.19 → 21.0.20

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.
@@ -1748,6 +1748,7 @@
1748
1748
  "appearance",
1749
1749
  "code",
1750
1750
  "diff",
1751
+ "disableOverflow",
1751
1752
  "highlightLines",
1752
1753
  "language",
1753
1754
  "showCopyButton",
@@ -5495,7 +5496,7 @@
5495
5496
  "name": "list-with-sections-example",
5496
5497
  "title": "List with sections",
5497
5498
  "file": "projects/docs/src/app/components/list/_examples/list-with-sections-example/list-with-sections-example.html",
5498
- "source": "<ngs-list>\n <div ngsSubheader>Folders</div>\n @for (folder of folders; track folder) {\n <ngs-list-item>\n <ngs-icon name=\"fluent:folder-24-regular\" ngsListItemIcon/>\n <div ngsListItemTitle>{{ folder.name }}</div>\n <div ngsListItemLine>{{ folder.updated | date }}</div>\n </ngs-list-item>\n }\n <ngs-divider class=\"my-5\"/>\n <div ngsSubheader>Notes</div>\n @for (note of notes; track note) {\n <ngs-list-item>\n <ngs-icon name=\"fluent:note-24-regular\" ngsListItemIcon/>\n <div ngsListItemTitle>{{ note.name }}</div>\n <div ngsListItemLine>{{ note.updated | date }}</div>\n </ngs-list-item>\n }\n</ngs-list>"
5499
+ "source": "<ngs-list>\n <div ngsSubheader>Folders</div>\n @for (folder of folders(); track folder) {\n <ngs-list-item>\n <ngs-icon name=\"fluent:folder-24-regular\" ngsListItemIcon/>\n <div ngsListItemTitle>{{ folder.name }}</div>\n <div ngsListItemLine>{{ folder.updated | date }}</div>\n </ngs-list-item>\n }\n <ngs-divider class=\"my-5\"/>\n <div ngsSubheader>Notes</div>\n @for (note of notes(); track note) {\n <ngs-list-item>\n <ngs-icon name=\"fluent:note-24-regular\" ngsListItemIcon/>\n <div ngsListItemTitle>{{ note.name }}</div>\n <div ngsListItemLine>{{ note.updated | date }}</div>\n </ngs-list-item>\n }\n</ngs-list>"
5499
5500
  }
5500
5501
  ],
5501
5502
  "previewAsset": "projects/components/list/preview.svg",
@@ -52,6 +52,7 @@ class CodeHighlighter {
52
52
  highlightLines = input([], ...(ngDevMode ? [{ debugName: "highlightLines" }] : /* istanbul ignore next */ []));
53
53
  showLanguage = input(false, { ...(ngDevMode ? { debugName: "showLanguage" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
54
54
  showCopyButton = input(false, { ...(ngDevMode ? { debugName: "showCopyButton" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
55
+ disableOverflow = input(false, { ...(ngDevMode ? { debugName: "disableOverflow" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
55
56
  content = signal(null, ...(ngDevMode ? [{ debugName: "content" }] : /* istanbul ignore next */ []));
56
57
  isLoading = signal(false, ...(ngDevMode ? [{ debugName: "isLoading" }] : /* istanbul ignore next */ []));
57
58
  displayedLanguage = computed(() => {
@@ -330,7 +331,7 @@ class CodeHighlighter {
330
331
  }
331
332
  }
332
333
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: CodeHighlighter, deps: [], target: i0.ɵɵFactoryTarget.Component });
333
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: CodeHighlighter, isStandalone: true, selector: "ngs-code-highlighter", inputs: { code: { classPropertyName: "code", publicName: "code", isSignal: true, isRequired: true, transformFunction: null }, language: { classPropertyName: "language", publicName: "language", isSignal: true, isRequired: false, transformFunction: null }, theme: { classPropertyName: "theme", publicName: "theme", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, appearance: { classPropertyName: "appearance", publicName: "appearance", isSignal: true, isRequired: false, transformFunction: null }, diff: { classPropertyName: "diff", publicName: "diff", isSignal: true, isRequired: false, transformFunction: null }, highlightLines: { classPropertyName: "highlightLines", publicName: "highlightLines", isSignal: true, isRequired: false, transformFunction: null }, showLanguage: { classPropertyName: "showLanguage", publicName: "showLanguage", isSignal: true, isRequired: false, transformFunction: null }, showCopyButton: { classPropertyName: "showCopyButton", publicName: "showCopyButton", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.appearance-bordered": "appearance() === \"bordered\"", "class.appearance-none": "appearance() === \"none\"" }, classAttribute: "ngs-code-highlighter not-prose" }, exportAs: ["ngsCodeHighlighter"], usesOnChanges: true, ngImport: i0, template: "<figure class=\"h-full\">\n @if (title()) {\n <figcaption>\n @if (title()) {\n <span class=\"title\">{{ title() }}</span>\n }\n </figcaption>\n }\n\n <div class=\"content relative h-full\">\n @if (showLanguage()) {\n <div class=\"languageName\">{{ displayedLanguage() }}</div>\n }\n\n @if (showCopyButton()) {\n <span class=\"absolute top-2 right-2\">\n <button\n ngsIconButton\n (click)=\"copyCode()\"\n >\n <ngs-icon\n [name]=\"copied() ? 'fluent:checkmark-24-regular' : 'fluent:copy-24-regular'\"\n [class.text-green-500]=\"copied()\"\n />\n </button>\n </span>\n }\n\n <div>\n @if (content()) {\n <div [innerHTML]=\"content()\"></div>\n } @else if (isLoading()) {\n <div class=\"loading\">Loading\u2026</div>\n }\n </div>\n </div>\n</figure>\n", styles: [":host{--ngs-code-highlighter-bg: var(--ngs-color-background);--ngs-code-highlighter-radius: var(--ngs-radius-xl);--ngs-code-highlighter-padding: calc(var(--spacing, .25rem) * 5);--ngs-code-highlighter-margin: calc(var(--spacing, .25rem) * 5);--ngs-code-highlighter-border: 1px solid var(--ngs-color-border);--ngs-code-highlighter-title-padding: calc(var(--spacing, .25rem) * 2) calc(var(--spacing, .25rem) * 3) calc(var(--spacing, .25rem) * 1) calc(var(--spacing, .25rem) * 3);--ngs-code-highlighter-title-color: var(--ngs-color-neutral-500);display:block;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}:host figcaption{font-size:var(--ngs-font-size-xs);font-weight:500;padding:var(--ngs-code-highlighter-title-padding);background:var(--ngs-code-highlighter-bg);color:var(--ngs-code-highlighter-title-color);position:relative;z-index:1}:host figcaption:after{content:\"\";position:absolute;left:0;right:0;bottom:-1px;height:1px;background:var(--ngs-code-highlighter-bg)}:host .languageName{font-size:var(--ngs-font-size-sm);font-weight:600;padding:0 calc(var(--spacing, .25rem) * 6);width:max-content;margin-bottom:calc(var(--spacing, .25rem) * 4);margin-top:calc(calc(var(--spacing, .25rem) * 1) * -1);position:relative}:host ::ng-deep pre{padding:var(--ngs-code-highlighter-padding) 0;line-height:1.75;font-size:var(--ngs-font-size-sm);position:relative}:host ::ng-deep pre code{display:grid}:host ::ng-deep pre .line{padding-left:calc(var(--spacing, .25rem) * 6);padding-right:var(--ngs-code-highlighter-padding);min-height:1.75em}:host ::ng-deep pre .line.diff.remove{background-color:var(--ngs-color-danger);display:inline-block;width:100%}@supports (color: color-mix(in lab,red,red)){:host ::ng-deep pre .line.diff.remove{background-color:color-mix(in srgb,var(--ngs-color-danger),transparent 85%)}}:host ::ng-deep pre .line.diff.remove:before{content:\"-\";color:var(--ngs-color-danger);position:absolute;left:calc(var(--spacing, .25rem) * 2)}:host ::ng-deep pre .line.diff.add{background-color:var(--ngs-color-success);display:inline-block;width:100%}@supports (color: color-mix(in lab,red,red)){:host ::ng-deep pre .line.diff.add{background-color:color-mix(in srgb,var(--ngs-color-success),transparent 85%)}}:host ::ng-deep pre .line.diff.add:before{content:\"+\";color:var(--ngs-color-success);position:absolute;left:calc(var(--spacing, .25rem) * 2)}:host ::ng-deep pre .line.highlighted{background-color:var(--ngs-color-primary);display:inline-block;width:100%}@supports (color: color-mix(in lab,red,red)){:host ::ng-deep pre .line.highlighted{background-color:color-mix(in srgb,var(--ngs-color-primary),transparent 92%)}}:host ::ng-deep code{white-space:pre}:host .content{overflow:auto;background:var(--ngs-code-highlighter-bg)}:host .content button{color:inherit}:host .content button ngs-icon.text-green-500{color:var(--ngs-color-success)!important}:host.appearance-bordered figcaption{border:var(--ngs-code-highlighter-border);border-bottom:none;border-top-left-radius:var(--ngs-radius-xl);border-top-right-radius:var(--ngs-radius-xl);width:max-content}:host.appearance-bordered .content{border:var(--ngs-code-highlighter-border);border-radius:var(--ngs-code-highlighter-radius);z-index:0}:host.appearance-bordered:has(figcaption) .content{border-top-left-radius:0}:host.appearance-none .content{border:none;background-color:transparent!important;border-radius:0}:host.appearance-none ::ng-deep pre{padding-left:0;padding-right:0}:host.loading{opacity:.6}\n/*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "component", type: Button, selector: " button[ngsButton], button[ngsIconButton], a[ngsButton], a[ngsIconButton] ", inputs: ["ngsButton", "ngsIconButton", "loading", "disabled", "disabledInteractive", "disableRipple", "reverse", "fullWidth", "hideTextOnMobile"], exportAs: ["ngsButton"] }, { kind: "component", type: Icon, selector: "ngs-icon", inputs: ["name"], exportAs: ["ngsIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
334
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: CodeHighlighter, isStandalone: true, selector: "ngs-code-highlighter", inputs: { code: { classPropertyName: "code", publicName: "code", isSignal: true, isRequired: true, transformFunction: null }, language: { classPropertyName: "language", publicName: "language", isSignal: true, isRequired: false, transformFunction: null }, theme: { classPropertyName: "theme", publicName: "theme", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, appearance: { classPropertyName: "appearance", publicName: "appearance", isSignal: true, isRequired: false, transformFunction: null }, diff: { classPropertyName: "diff", publicName: "diff", isSignal: true, isRequired: false, transformFunction: null }, highlightLines: { classPropertyName: "highlightLines", publicName: "highlightLines", isSignal: true, isRequired: false, transformFunction: null }, showLanguage: { classPropertyName: "showLanguage", publicName: "showLanguage", isSignal: true, isRequired: false, transformFunction: null }, showCopyButton: { classPropertyName: "showCopyButton", publicName: "showCopyButton", isSignal: true, isRequired: false, transformFunction: null }, disableOverflow: { classPropertyName: "disableOverflow", publicName: "disableOverflow", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.appearance-bordered": "appearance() === \"bordered\"", "class.appearance-none": "appearance() === \"none\"", "class.overflow-disabled": "disableOverflow()" }, classAttribute: "ngs-code-highlighter not-prose" }, exportAs: ["ngsCodeHighlighter"], usesOnChanges: true, ngImport: i0, template: "<figure class=\"h-full\">\n @if (title()) {\n <figcaption>\n @if (title()) {\n <span class=\"title\">{{ title() }}</span>\n }\n </figcaption>\n }\n\n <div class=\"content relative h-full\">\n @if (showLanguage()) {\n <div class=\"languageName\">{{ displayedLanguage() }}</div>\n }\n\n @if (showCopyButton()) {\n <span class=\"absolute top-2 right-2\">\n <button\n ngsIconButton\n (click)=\"copyCode()\"\n >\n <ngs-icon\n [name]=\"copied() ? 'fluent:checkmark-24-regular' : 'fluent:copy-24-regular'\"\n [class.text-green-500]=\"copied()\"\n />\n </button>\n </span>\n }\n\n <div>\n @if (content()) {\n <div [innerHTML]=\"content()\"></div>\n } @else if (isLoading()) {\n <div class=\"loading\">Loading\u2026</div>\n }\n </div>\n </div>\n</figure>\n", styles: [":host{--ngs-code-highlighter-bg: var(--ngs-color-background);--ngs-code-highlighter-radius: var(--ngs-radius-xl);--ngs-code-highlighter-padding: calc(var(--spacing, .25rem) * 5);--ngs-code-highlighter-margin: calc(var(--spacing, .25rem) * 5);--ngs-code-highlighter-border: 1px solid var(--ngs-color-border);--ngs-code-highlighter-title-padding: calc(var(--spacing, .25rem) * 2) calc(var(--spacing, .25rem) * 3) calc(var(--spacing, .25rem) * 1) calc(var(--spacing, .25rem) * 3);--ngs-code-highlighter-title-color: var(--ngs-color-neutral-500);display:block;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}:host figcaption{font-size:var(--ngs-font-size-xs);font-weight:500;padding:var(--ngs-code-highlighter-title-padding);background:var(--ngs-code-highlighter-bg);color:var(--ngs-code-highlighter-title-color);position:relative;z-index:1}:host figcaption:after{content:\"\";position:absolute;left:0;right:0;bottom:-1px;height:1px;background:var(--ngs-code-highlighter-bg)}:host .languageName{font-size:var(--ngs-font-size-sm);font-weight:600;padding:0 calc(var(--spacing, .25rem) * 6);width:max-content;margin-bottom:calc(var(--spacing, .25rem) * 4);margin-top:calc(calc(var(--spacing, .25rem) * 1) * -1);position:relative}:host ::ng-deep pre{padding:var(--ngs-code-highlighter-padding) 0;line-height:1.75;font-size:var(--ngs-font-size-sm);position:relative}:host ::ng-deep pre code{display:grid}:host ::ng-deep pre .line{padding-left:calc(var(--spacing, .25rem) * 6);padding-right:var(--ngs-code-highlighter-padding);min-height:1.75em}:host ::ng-deep pre .line.diff.remove{background-color:var(--ngs-color-danger);display:inline-block;width:100%}@supports (color: color-mix(in lab,red,red)){:host ::ng-deep pre .line.diff.remove{background-color:color-mix(in srgb,var(--ngs-color-danger),transparent 85%)}}:host ::ng-deep pre .line.diff.remove:before{content:\"-\";color:var(--ngs-color-danger);position:absolute;left:calc(var(--spacing, .25rem) * 2)}:host ::ng-deep pre .line.diff.add{background-color:var(--ngs-color-success);display:inline-block;width:100%}@supports (color: color-mix(in lab,red,red)){:host ::ng-deep pre .line.diff.add{background-color:color-mix(in srgb,var(--ngs-color-success),transparent 85%)}}:host ::ng-deep pre .line.diff.add:before{content:\"+\";color:var(--ngs-color-success);position:absolute;left:calc(var(--spacing, .25rem) * 2)}:host ::ng-deep pre .line.highlighted{background-color:var(--ngs-color-primary);display:inline-block;width:100%}@supports (color: color-mix(in lab,red,red)){:host ::ng-deep pre .line.highlighted{background-color:color-mix(in srgb,var(--ngs-color-primary),transparent 92%)}}:host ::ng-deep code{white-space:pre}:host .content{overflow:auto;background:var(--ngs-code-highlighter-bg)}:host .content button{color:inherit}:host .content button ngs-icon.text-green-500{color:var(--ngs-color-success)!important}:host.overflow-disabled .content{overflow:visible}:host.overflow-disabled ::ng-deep pre,:host.overflow-disabled ::ng-deep code{width:max-content;min-width:100%}:host.appearance-bordered figcaption{border:var(--ngs-code-highlighter-border);border-bottom:none;border-top-left-radius:var(--ngs-radius-xl);border-top-right-radius:var(--ngs-radius-xl);width:max-content}:host.appearance-bordered .content{border:var(--ngs-code-highlighter-border);border-radius:var(--ngs-code-highlighter-radius);z-index:0}:host.appearance-bordered:has(figcaption) .content{border-top-left-radius:0}:host.appearance-none .content{border:none;background-color:transparent!important;border-radius:0}:host.appearance-none ::ng-deep pre{padding-left:0;padding-right:0}:host.loading{opacity:.6}\n/*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "component", type: Button, selector: " button[ngsButton], button[ngsIconButton], a[ngsButton], a[ngsIconButton] ", inputs: ["ngsButton", "ngsIconButton", "loading", "disabled", "disabledInteractive", "disableRipple", "reverse", "fullWidth", "hideTextOnMobile"], exportAs: ["ngsButton"] }, { kind: "component", type: Icon, selector: "ngs-icon", inputs: ["name"], exportAs: ["ngsIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
334
335
  }
335
336
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: CodeHighlighter, decorators: [{
336
337
  type: Component,
@@ -338,8 +339,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImpor
338
339
  'class': 'ngs-code-highlighter not-prose',
339
340
  '[class.appearance-bordered]': 'appearance() === "bordered"',
340
341
  '[class.appearance-none]': 'appearance() === "none"',
341
- }, template: "<figure class=\"h-full\">\n @if (title()) {\n <figcaption>\n @if (title()) {\n <span class=\"title\">{{ title() }}</span>\n }\n </figcaption>\n }\n\n <div class=\"content relative h-full\">\n @if (showLanguage()) {\n <div class=\"languageName\">{{ displayedLanguage() }}</div>\n }\n\n @if (showCopyButton()) {\n <span class=\"absolute top-2 right-2\">\n <button\n ngsIconButton\n (click)=\"copyCode()\"\n >\n <ngs-icon\n [name]=\"copied() ? 'fluent:checkmark-24-regular' : 'fluent:copy-24-regular'\"\n [class.text-green-500]=\"copied()\"\n />\n </button>\n </span>\n }\n\n <div>\n @if (content()) {\n <div [innerHTML]=\"content()\"></div>\n } @else if (isLoading()) {\n <div class=\"loading\">Loading\u2026</div>\n }\n </div>\n </div>\n</figure>\n", styles: [":host{--ngs-code-highlighter-bg: var(--ngs-color-background);--ngs-code-highlighter-radius: var(--ngs-radius-xl);--ngs-code-highlighter-padding: calc(var(--spacing, .25rem) * 5);--ngs-code-highlighter-margin: calc(var(--spacing, .25rem) * 5);--ngs-code-highlighter-border: 1px solid var(--ngs-color-border);--ngs-code-highlighter-title-padding: calc(var(--spacing, .25rem) * 2) calc(var(--spacing, .25rem) * 3) calc(var(--spacing, .25rem) * 1) calc(var(--spacing, .25rem) * 3);--ngs-code-highlighter-title-color: var(--ngs-color-neutral-500);display:block;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}:host figcaption{font-size:var(--ngs-font-size-xs);font-weight:500;padding:var(--ngs-code-highlighter-title-padding);background:var(--ngs-code-highlighter-bg);color:var(--ngs-code-highlighter-title-color);position:relative;z-index:1}:host figcaption:after{content:\"\";position:absolute;left:0;right:0;bottom:-1px;height:1px;background:var(--ngs-code-highlighter-bg)}:host .languageName{font-size:var(--ngs-font-size-sm);font-weight:600;padding:0 calc(var(--spacing, .25rem) * 6);width:max-content;margin-bottom:calc(var(--spacing, .25rem) * 4);margin-top:calc(calc(var(--spacing, .25rem) * 1) * -1);position:relative}:host ::ng-deep pre{padding:var(--ngs-code-highlighter-padding) 0;line-height:1.75;font-size:var(--ngs-font-size-sm);position:relative}:host ::ng-deep pre code{display:grid}:host ::ng-deep pre .line{padding-left:calc(var(--spacing, .25rem) * 6);padding-right:var(--ngs-code-highlighter-padding);min-height:1.75em}:host ::ng-deep pre .line.diff.remove{background-color:var(--ngs-color-danger);display:inline-block;width:100%}@supports (color: color-mix(in lab,red,red)){:host ::ng-deep pre .line.diff.remove{background-color:color-mix(in srgb,var(--ngs-color-danger),transparent 85%)}}:host ::ng-deep pre .line.diff.remove:before{content:\"-\";color:var(--ngs-color-danger);position:absolute;left:calc(var(--spacing, .25rem) * 2)}:host ::ng-deep pre .line.diff.add{background-color:var(--ngs-color-success);display:inline-block;width:100%}@supports (color: color-mix(in lab,red,red)){:host ::ng-deep pre .line.diff.add{background-color:color-mix(in srgb,var(--ngs-color-success),transparent 85%)}}:host ::ng-deep pre .line.diff.add:before{content:\"+\";color:var(--ngs-color-success);position:absolute;left:calc(var(--spacing, .25rem) * 2)}:host ::ng-deep pre .line.highlighted{background-color:var(--ngs-color-primary);display:inline-block;width:100%}@supports (color: color-mix(in lab,red,red)){:host ::ng-deep pre .line.highlighted{background-color:color-mix(in srgb,var(--ngs-color-primary),transparent 92%)}}:host ::ng-deep code{white-space:pre}:host .content{overflow:auto;background:var(--ngs-code-highlighter-bg)}:host .content button{color:inherit}:host .content button ngs-icon.text-green-500{color:var(--ngs-color-success)!important}:host.appearance-bordered figcaption{border:var(--ngs-code-highlighter-border);border-bottom:none;border-top-left-radius:var(--ngs-radius-xl);border-top-right-radius:var(--ngs-radius-xl);width:max-content}:host.appearance-bordered .content{border:var(--ngs-code-highlighter-border);border-radius:var(--ngs-code-highlighter-radius);z-index:0}:host.appearance-bordered:has(figcaption) .content{border-top-left-radius:0}:host.appearance-none .content{border:none;background-color:transparent!important;border-radius:0}:host.appearance-none ::ng-deep pre{padding-left:0;padding-right:0}:host.loading{opacity:.6}\n/*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */\n"] }]
342
- }], propDecorators: { code: [{ type: i0.Input, args: [{ isSignal: true, alias: "code", required: true }] }], language: [{ type: i0.Input, args: [{ isSignal: true, alias: "language", required: false }] }], theme: [{ type: i0.Input, args: [{ isSignal: true, alias: "theme", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], appearance: [{ type: i0.Input, args: [{ isSignal: true, alias: "appearance", required: false }] }], diff: [{ type: i0.Input, args: [{ isSignal: true, alias: "diff", required: false }] }], highlightLines: [{ type: i0.Input, args: [{ isSignal: true, alias: "highlightLines", required: false }] }], showLanguage: [{ type: i0.Input, args: [{ isSignal: true, alias: "showLanguage", required: false }] }], showCopyButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "showCopyButton", required: false }] }] } });
342
+ '[class.overflow-disabled]': 'disableOverflow()',
343
+ }, template: "<figure class=\"h-full\">\n @if (title()) {\n <figcaption>\n @if (title()) {\n <span class=\"title\">{{ title() }}</span>\n }\n </figcaption>\n }\n\n <div class=\"content relative h-full\">\n @if (showLanguage()) {\n <div class=\"languageName\">{{ displayedLanguage() }}</div>\n }\n\n @if (showCopyButton()) {\n <span class=\"absolute top-2 right-2\">\n <button\n ngsIconButton\n (click)=\"copyCode()\"\n >\n <ngs-icon\n [name]=\"copied() ? 'fluent:checkmark-24-regular' : 'fluent:copy-24-regular'\"\n [class.text-green-500]=\"copied()\"\n />\n </button>\n </span>\n }\n\n <div>\n @if (content()) {\n <div [innerHTML]=\"content()\"></div>\n } @else if (isLoading()) {\n <div class=\"loading\">Loading\u2026</div>\n }\n </div>\n </div>\n</figure>\n", styles: [":host{--ngs-code-highlighter-bg: var(--ngs-color-background);--ngs-code-highlighter-radius: var(--ngs-radius-xl);--ngs-code-highlighter-padding: calc(var(--spacing, .25rem) * 5);--ngs-code-highlighter-margin: calc(var(--spacing, .25rem) * 5);--ngs-code-highlighter-border: 1px solid var(--ngs-color-border);--ngs-code-highlighter-title-padding: calc(var(--spacing, .25rem) * 2) calc(var(--spacing, .25rem) * 3) calc(var(--spacing, .25rem) * 1) calc(var(--spacing, .25rem) * 3);--ngs-code-highlighter-title-color: var(--ngs-color-neutral-500);display:block;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}:host figcaption{font-size:var(--ngs-font-size-xs);font-weight:500;padding:var(--ngs-code-highlighter-title-padding);background:var(--ngs-code-highlighter-bg);color:var(--ngs-code-highlighter-title-color);position:relative;z-index:1}:host figcaption:after{content:\"\";position:absolute;left:0;right:0;bottom:-1px;height:1px;background:var(--ngs-code-highlighter-bg)}:host .languageName{font-size:var(--ngs-font-size-sm);font-weight:600;padding:0 calc(var(--spacing, .25rem) * 6);width:max-content;margin-bottom:calc(var(--spacing, .25rem) * 4);margin-top:calc(calc(var(--spacing, .25rem) * 1) * -1);position:relative}:host ::ng-deep pre{padding:var(--ngs-code-highlighter-padding) 0;line-height:1.75;font-size:var(--ngs-font-size-sm);position:relative}:host ::ng-deep pre code{display:grid}:host ::ng-deep pre .line{padding-left:calc(var(--spacing, .25rem) * 6);padding-right:var(--ngs-code-highlighter-padding);min-height:1.75em}:host ::ng-deep pre .line.diff.remove{background-color:var(--ngs-color-danger);display:inline-block;width:100%}@supports (color: color-mix(in lab,red,red)){:host ::ng-deep pre .line.diff.remove{background-color:color-mix(in srgb,var(--ngs-color-danger),transparent 85%)}}:host ::ng-deep pre .line.diff.remove:before{content:\"-\";color:var(--ngs-color-danger);position:absolute;left:calc(var(--spacing, .25rem) * 2)}:host ::ng-deep pre .line.diff.add{background-color:var(--ngs-color-success);display:inline-block;width:100%}@supports (color: color-mix(in lab,red,red)){:host ::ng-deep pre .line.diff.add{background-color:color-mix(in srgb,var(--ngs-color-success),transparent 85%)}}:host ::ng-deep pre .line.diff.add:before{content:\"+\";color:var(--ngs-color-success);position:absolute;left:calc(var(--spacing, .25rem) * 2)}:host ::ng-deep pre .line.highlighted{background-color:var(--ngs-color-primary);display:inline-block;width:100%}@supports (color: color-mix(in lab,red,red)){:host ::ng-deep pre .line.highlighted{background-color:color-mix(in srgb,var(--ngs-color-primary),transparent 92%)}}:host ::ng-deep code{white-space:pre}:host .content{overflow:auto;background:var(--ngs-code-highlighter-bg)}:host .content button{color:inherit}:host .content button ngs-icon.text-green-500{color:var(--ngs-color-success)!important}:host.overflow-disabled .content{overflow:visible}:host.overflow-disabled ::ng-deep pre,:host.overflow-disabled ::ng-deep code{width:max-content;min-width:100%}:host.appearance-bordered figcaption{border:var(--ngs-code-highlighter-border);border-bottom:none;border-top-left-radius:var(--ngs-radius-xl);border-top-right-radius:var(--ngs-radius-xl);width:max-content}:host.appearance-bordered .content{border:var(--ngs-code-highlighter-border);border-radius:var(--ngs-code-highlighter-radius);z-index:0}:host.appearance-bordered:has(figcaption) .content{border-top-left-radius:0}:host.appearance-none .content{border:none;background-color:transparent!important;border-radius:0}:host.appearance-none ::ng-deep pre{padding-left:0;padding-right:0}:host.loading{opacity:.6}\n/*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */\n"] }]
344
+ }], propDecorators: { code: [{ type: i0.Input, args: [{ isSignal: true, alias: "code", required: true }] }], language: [{ type: i0.Input, args: [{ isSignal: true, alias: "language", required: false }] }], theme: [{ type: i0.Input, args: [{ isSignal: true, alias: "theme", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], appearance: [{ type: i0.Input, args: [{ isSignal: true, alias: "appearance", required: false }] }], diff: [{ type: i0.Input, args: [{ isSignal: true, alias: "diff", required: false }] }], highlightLines: [{ type: i0.Input, args: [{ isSignal: true, alias: "highlightLines", required: false }] }], showLanguage: [{ type: i0.Input, args: [{ isSignal: true, alias: "showLanguage", required: false }] }], showCopyButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "showCopyButton", required: false }] }], disableOverflow: [{ type: i0.Input, args: [{ isSignal: true, alias: "disableOverflow", required: false }] }] } });
343
345
 
344
346
  /**
345
347
  * Generated bundle index. Do not edit.
@@ -1 +1 @@
1
- {"version":3,"file":"ngstarter-ui-components-code-highlighter.mjs","sources":["../../../projects/components/code-highlighter/src/code-highlighter/code-highlighter.ts","../../../projects/components/code-highlighter/src/code-highlighter/code-highlighter.html","../../../projects/components/code-highlighter/ngstarter-ui-components-code-highlighter.ts"],"sourcesContent":["import { Component, ChangeDetectionStrategy, input, OnChanges, SimpleChanges, signal, computed, inject, booleanAttribute } from '@angular/core';\nimport { DomSanitizer, SafeHtml } from '@angular/platform-browser';\nimport { codeToHtml, ShikiTransformer } from 'shiki';\nimport { Button } from '@ngstarter-ui/components/button';\nimport { Icon } from '@ngstarter-ui/components/icon';\n\nconst removeDiffPrefix = (node: any) => {\n if (!node.children || node.children.length === 0) return;\n\n const firstChild = node.children[0];\n if (firstChild.type === 'element' && firstChild.children && firstChild.children.length > 0) {\n const textNode = firstChild.children[0];\n if (textNode.type === 'text' && (textNode.value.startsWith('+') || textNode.value.startsWith('-'))) {\n textNode.value = textNode.value.slice(1);\n if (textNode.value === '' && firstChild.children.length === 1) {\n node.children.shift();\n }\n }\n } else if (firstChild.type === 'text' && (firstChild.value.startsWith('+') || firstChild.value.startsWith('-'))) {\n firstChild.value = firstChild.value.slice(1);\n if (firstChild.value === '') {\n node.children.shift();\n }\n }\n};\n\nconst diffTransformer: ShikiTransformer = {\n line(node, line) {\n if (this.options.lang === 'diff' || (this.options as any).diff) {\n const lineTokens = this.tokens[line - 1];\n const text = lineTokens.map(token => token.content).join('');\n if (text.startsWith('+')) {\n this.addClassToHast(node, 'diff add');\n removeDiffPrefix(node);\n } else if (text.startsWith('-')) {\n this.addClassToHast(node, 'diff remove');\n removeDiffPrefix(node);\n }\n }\n }\n};\n\n@Component({\n selector: 'ngs-code-highlighter',\n standalone: true,\n imports: [Button, Icon],\n exportAs: 'ngsCodeHighlighter',\n templateUrl: './code-highlighter.html',\n styleUrl: './code-highlighter.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n 'class': 'ngs-code-highlighter not-prose',\n '[class.appearance-bordered]': 'appearance() === \"bordered\"',\n '[class.appearance-none]': 'appearance() === \"none\"',\n }\n})\nexport class CodeHighlighter implements OnChanges {\n private sanitizer = inject(DomSanitizer);\n\n code = input.required<string>();\n language = input<string>('none');\n theme = input<string>('github-light');\n title = input<string | null>(null);\n appearance = input<'none' | 'bordered'>('bordered');\n diff = input<boolean>(false);\n highlightLines = input<number[] | number[][]>([]);\n showLanguage = input(false, { transform: booleanAttribute });\n showCopyButton = input(false, { transform: booleanAttribute });\n\n readonly content = signal<SafeHtml | null>(null);\n readonly isLoading = signal<boolean>(false);\n\n readonly displayedLanguage = computed(() => {\n const lang = this.language();\n if (!lang || lang === 'none') return '';\n\n const langMap: Record<string, string> = {\n '1c': '1C',\n 'abap': 'ABAP',\n 'actionscript-3': 'ActionScript 3',\n 'ada': 'Ada',\n 'apache': 'Apache',\n 'apex': 'Apex',\n 'apl': 'APL',\n 'applescript': 'AppleScript',\n 'ara': 'Ara',\n 'asm': 'Assembly',\n 'astro': 'Astro',\n 'awk': 'AWK',\n 'ballerina': 'Ballerina',\n 'bash': 'Bash',\n 'sh': 'Bash',\n 'batch': 'Batch',\n 'berry': 'Berry',\n 'bibtex': 'BibTeX',\n 'bicep': 'Bicep',\n 'blade': 'Blade',\n 'c': 'C',\n 'cadence': 'Cadence',\n 'clarity': 'Clarity',\n 'clojure': 'Clojure',\n 'clj': 'Clojure',\n 'cmake': 'CMake',\n 'cobol': 'COBOL',\n 'codeql': 'CodeQL',\n 'coffee': 'CoffeeScript',\n 'cpp': 'C++',\n 'csharp': 'C#',\n 'cs': 'C#',\n 'css': 'CSS',\n 'cue': 'CUE',\n 'cypher': 'Cypher',\n 'd': 'D',\n 'dart': 'Dart',\n 'dax': 'DAX',\n 'diff': 'Diff',\n 'docker': 'Docker',\n 'dockerfile': 'Dockerfile',\n 'dream-maker': 'Dream Maker',\n 'elixir': 'Elixir',\n 'elm': 'Elm',\n 'erb': 'ERB',\n 'erlang': 'Erlang',\n 'fish': 'Fish',\n 'fsharp': 'F#',\n 'fs': 'F#',\n 'gdresource': 'GDResource',\n 'gdscript': 'GDScript',\n 'gdshader': 'GDShader',\n 'gherkin': 'Gherkin',\n 'git-commit': 'Git Commit',\n 'git-rebase': 'Git Rebase',\n 'glimmer-js': 'Glimmer JS',\n 'gljs': 'Glimmer JS',\n 'glsl': 'GLSL',\n 'gnuplot': 'Gnuplot',\n 'go': 'Go',\n 'graphql': 'GraphQL',\n 'groovy': 'Groovy',\n 'hack': 'Hack',\n 'haml': 'Haml',\n 'handlebars': 'Handlebars',\n 'hbs': 'Handlebars',\n 'haskell': 'Haskell',\n 'hs': 'Haskell',\n 'hcl': 'HCL',\n 'hjson': 'Hjson',\n 'hlsl': 'HLSL',\n 'html': 'HTML',\n 'http': 'HTTP',\n 'imba': 'Imba',\n 'ini': 'INI',\n 'java': 'Java',\n 'javascript': 'JavaScript',\n 'js': 'JavaScript',\n 'jinja-html': 'Jinja HTML',\n 'jjson': 'JJSON',\n 'json': 'JSON',\n 'json5': 'JSON5',\n 'jsonc': 'JSONC',\n 'jsonnet': 'Jsonnet',\n 'jssm': 'JSSM',\n 'jsx': 'JSX',\n 'julia': 'Julia',\n 'kotlin': 'Kotlin',\n 'kt': 'Kotlin',\n 'kts': 'Kotlin',\n 'kusto': 'Kusto',\n 'latex': 'LaTeX',\n 'lat': 'LaTeX',\n 'tex': 'LaTeX',\n 'lean': 'Lean',\n 'less': 'Less',\n 'liquid': 'Liquid',\n 'lisp': 'Lisp',\n 'logo': 'Logo',\n 'lua': 'Lua',\n 'make': 'Make',\n 'makefile': 'Makefile',\n 'markdown': 'Markdown',\n 'md': 'Markdown',\n 'marko': 'Marko',\n 'matlab': 'MATLAB',\n 'mdx': 'MDX',\n 'mermaid': 'Mermaid',\n 'mipsasm': 'MIPS Assembly',\n 'mips': 'MIPS Assembly',\n 'mojolicious': 'Mojolicious',\n 'move': 'Move',\n 'narrat': 'Narrat',\n 'nextflow': 'Nextflow',\n 'nginx': 'Nginx',\n 'nim': 'Nim',\n 'nix': 'Nix',\n 'objective-c': 'Objective-C',\n 'objc': 'Objective-C',\n 'objective-cpp': 'Objective-C++',\n 'ocaml': 'OCaml',\n 'pascal': 'Pascal',\n 'perl': 'Perl',\n 'pl': 'Perl',\n 'php': 'PHP',\n 'plsql': 'PL/SQL',\n 'postcss': 'PostCSS',\n 'powerquery': 'PowerQuery',\n 'powershell': 'PowerShell',\n 'ps1': 'PowerShell',\n 'prisma': 'Prisma',\n 'prolog': 'Prolog',\n 'proto': 'Protocol Buffers',\n 'pug': 'Pug',\n 'jade': 'Pug',\n 'puppet': 'Puppet',\n 'purescript': 'PureScript',\n 'python': 'Python',\n 'py': 'Python',\n 'r': 'R',\n 'raku': 'Raku',\n 'razor': 'Razor',\n 'reg': 'Registry',\n 'rel': 'Rel',\n 'riscv': 'RISC-V',\n 'rst': 'reStructuredText',\n 'ruby': 'Ruby',\n 'rb': 'Ruby',\n 'rust': 'Rust',\n 'rs': 'Rust',\n 'sas': 'SAS',\n 'sass': 'Sass',\n 'scala': 'Scala',\n 'scheme': 'Scheme',\n 'scss': 'SCSS',\n 'shaderlab': 'ShaderLab',\n 'shader': 'ShaderLab',\n 'shell': 'Shell',\n 'shellscript': 'Shell',\n 'smalltalk': 'Smalltalk',\n 'solidity': 'Solidity',\n 'sparql': 'SPARQL',\n 'sql': 'SQL',\n 'ssh-config': 'SSH Config',\n 'stata': 'Stata',\n 'stylus': 'Stylus',\n 'styl': 'Stylus',\n 'svelte': 'Svelte',\n 'swift': 'Swift',\n 'system-verilog': 'SystemVerilog',\n 'tasl': 'Tasl',\n 'tcl': 'Tcl',\n 'terraform': 'Terraform',\n 'tf': 'Terraform',\n 'toml': 'TOML',\n 'tsx': 'TSX',\n 'turtle': 'Turtle',\n 'twig': 'Twig',\n 'typescript': 'TypeScript',\n 'ts': 'TypeScript',\n 'v': 'V',\n 'vb': 'Visual Basic',\n 'verilog': 'Verilog',\n 'vhdl': 'VHDL',\n 'viml': 'VimL',\n 'vim': 'VimL',\n 'vue': 'Vue',\n 'vyper': 'Vyper',\n 'wasm': 'WebAssembly',\n 'wenyan': 'Wenyan',\n 'wgsl': 'WGSL',\n 'wolfram': 'Wolfram',\n 'xml': 'XML',\n 'xsl': 'XSL',\n 'yaml': 'YAML',\n 'yml': 'YAML',\n 'zenscript': 'ZenScript',\n 'zig': 'Zig',\n 'zsh': 'Zsh',\n };\n\n return langMap[lang.toLowerCase()] || lang;\n });\n\n private getHighlightTransformer(): ShikiTransformer {\n const highlights = this.highlightLines();\n if (!highlights || (Array.isArray(highlights) && highlights.length === 0)) {\n return {};\n }\n\n const isHighlighted = (line: number): boolean => {\n if (Array.isArray(highlights[0])) {\n return (highlights as number[][]).some(([start, end]) => line >= start && line <= end);\n } else {\n const [start, end] = highlights as number[];\n return line >= start && line <= end;\n }\n };\n\n return {\n line(node, line) {\n if (isHighlighted(line)) {\n this.addClassToHast(node, 'highlighted');\n }\n }\n };\n }\n\n async ngOnChanges(changes: SimpleChanges) {\n const code = this.code() ?? '';\n\n if (code.length === 0) {\n this.isLoading.set(false);\n this.content.set(this.sanitizer.bypassSecurityTrustHtml('<pre class=\"shiki\"><code></code></pre>'));\n return;\n }\n\n this.isLoading.set(true);\n try {\n const highlighted = await codeToHtml(\n code,\n {\n lang: this.language(),\n theme: this.theme(),\n transformers: [diffTransformer, this.getHighlightTransformer()],\n diff: this.diff()\n } as any\n );\n this.content.set(this.sanitizer.bypassSecurityTrustHtml(highlighted));\n } catch (e) {\n // Fallback: raw code escaped inside pre\n const escaped = code\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;');\n const fallback = `<pre class=\"shiki\"><code>${escaped}</code></pre>`;\n this.content.set(this.sanitizer.bypassSecurityTrustHtml(fallback));\n console.error('CodeHighlighter error:', e);\n } finally {\n this.isLoading.set(false);\n }\n }\n\n copied = signal(false);\n private copyTimeout?: any;\n\n copyCode() {\n if (this.code()) {\n navigator.clipboard.writeText(this.code());\n this.copied.set(true);\n\n if (this.copyTimeout) {\n clearTimeout(this.copyTimeout);\n }\n\n this.copyTimeout = setTimeout(() => {\n this.copied.set(false);\n this.copyTimeout = undefined;\n }, 2000);\n }\n }\n}\n","<figure class=\"h-full\">\n @if (title()) {\n <figcaption>\n @if (title()) {\n <span class=\"title\">{{ title() }}</span>\n }\n </figcaption>\n }\n\n <div class=\"content relative h-full\">\n @if (showLanguage()) {\n <div class=\"languageName\">{{ displayedLanguage() }}</div>\n }\n\n @if (showCopyButton()) {\n <span class=\"absolute top-2 right-2\">\n <button\n ngsIconButton\n (click)=\"copyCode()\"\n >\n <ngs-icon\n [name]=\"copied() ? 'fluent:checkmark-24-regular' : 'fluent:copy-24-regular'\"\n [class.text-green-500]=\"copied()\"\n />\n </button>\n </span>\n }\n\n <div>\n @if (content()) {\n <div [innerHTML]=\"content()\"></div>\n } @else if (isLoading()) {\n <div class=\"loading\">Loading…</div>\n }\n </div>\n </div>\n</figure>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ngstarter-ui-components-code-highlighter.mjs","sources":["../../../projects/components/code-highlighter/src/code-highlighter/code-highlighter.ts","../../../projects/components/code-highlighter/src/code-highlighter/code-highlighter.html","../../../projects/components/code-highlighter/ngstarter-ui-components-code-highlighter.ts"],"sourcesContent":["import { Component, ChangeDetectionStrategy, input, OnChanges, SimpleChanges, signal, computed, inject, booleanAttribute } from '@angular/core';\nimport { DomSanitizer, SafeHtml } from '@angular/platform-browser';\nimport { codeToHtml, ShikiTransformer } from 'shiki';\nimport { Button } from '@ngstarter-ui/components/button';\nimport { Icon } from '@ngstarter-ui/components/icon';\n\nconst removeDiffPrefix = (node: any) => {\n if (!node.children || node.children.length === 0) return;\n\n const firstChild = node.children[0];\n if (firstChild.type === 'element' && firstChild.children && firstChild.children.length > 0) {\n const textNode = firstChild.children[0];\n if (textNode.type === 'text' && (textNode.value.startsWith('+') || textNode.value.startsWith('-'))) {\n textNode.value = textNode.value.slice(1);\n if (textNode.value === '' && firstChild.children.length === 1) {\n node.children.shift();\n }\n }\n } else if (firstChild.type === 'text' && (firstChild.value.startsWith('+') || firstChild.value.startsWith('-'))) {\n firstChild.value = firstChild.value.slice(1);\n if (firstChild.value === '') {\n node.children.shift();\n }\n }\n};\n\nconst diffTransformer: ShikiTransformer = {\n line(node, line) {\n if (this.options.lang === 'diff' || (this.options as any).diff) {\n const lineTokens = this.tokens[line - 1];\n const text = lineTokens.map(token => token.content).join('');\n if (text.startsWith('+')) {\n this.addClassToHast(node, 'diff add');\n removeDiffPrefix(node);\n } else if (text.startsWith('-')) {\n this.addClassToHast(node, 'diff remove');\n removeDiffPrefix(node);\n }\n }\n }\n};\n\n@Component({\n selector: 'ngs-code-highlighter',\n standalone: true,\n imports: [Button, Icon],\n exportAs: 'ngsCodeHighlighter',\n templateUrl: './code-highlighter.html',\n styleUrl: './code-highlighter.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n 'class': 'ngs-code-highlighter not-prose',\n '[class.appearance-bordered]': 'appearance() === \"bordered\"',\n '[class.appearance-none]': 'appearance() === \"none\"',\n '[class.overflow-disabled]': 'disableOverflow()',\n }\n})\nexport class CodeHighlighter implements OnChanges {\n private sanitizer = inject(DomSanitizer);\n\n code = input.required<string>();\n language = input<string>('none');\n theme = input<string>('github-light');\n title = input<string | null>(null);\n appearance = input<'none' | 'bordered'>('bordered');\n diff = input<boolean>(false);\n highlightLines = input<number[] | number[][]>([]);\n showLanguage = input(false, { transform: booleanAttribute });\n showCopyButton = input(false, { transform: booleanAttribute });\n disableOverflow = input(false, { transform: booleanAttribute });\n\n readonly content = signal<SafeHtml | null>(null);\n readonly isLoading = signal<boolean>(false);\n\n readonly displayedLanguage = computed(() => {\n const lang = this.language();\n if (!lang || lang === 'none') return '';\n\n const langMap: Record<string, string> = {\n '1c': '1C',\n 'abap': 'ABAP',\n 'actionscript-3': 'ActionScript 3',\n 'ada': 'Ada',\n 'apache': 'Apache',\n 'apex': 'Apex',\n 'apl': 'APL',\n 'applescript': 'AppleScript',\n 'ara': 'Ara',\n 'asm': 'Assembly',\n 'astro': 'Astro',\n 'awk': 'AWK',\n 'ballerina': 'Ballerina',\n 'bash': 'Bash',\n 'sh': 'Bash',\n 'batch': 'Batch',\n 'berry': 'Berry',\n 'bibtex': 'BibTeX',\n 'bicep': 'Bicep',\n 'blade': 'Blade',\n 'c': 'C',\n 'cadence': 'Cadence',\n 'clarity': 'Clarity',\n 'clojure': 'Clojure',\n 'clj': 'Clojure',\n 'cmake': 'CMake',\n 'cobol': 'COBOL',\n 'codeql': 'CodeQL',\n 'coffee': 'CoffeeScript',\n 'cpp': 'C++',\n 'csharp': 'C#',\n 'cs': 'C#',\n 'css': 'CSS',\n 'cue': 'CUE',\n 'cypher': 'Cypher',\n 'd': 'D',\n 'dart': 'Dart',\n 'dax': 'DAX',\n 'diff': 'Diff',\n 'docker': 'Docker',\n 'dockerfile': 'Dockerfile',\n 'dream-maker': 'Dream Maker',\n 'elixir': 'Elixir',\n 'elm': 'Elm',\n 'erb': 'ERB',\n 'erlang': 'Erlang',\n 'fish': 'Fish',\n 'fsharp': 'F#',\n 'fs': 'F#',\n 'gdresource': 'GDResource',\n 'gdscript': 'GDScript',\n 'gdshader': 'GDShader',\n 'gherkin': 'Gherkin',\n 'git-commit': 'Git Commit',\n 'git-rebase': 'Git Rebase',\n 'glimmer-js': 'Glimmer JS',\n 'gljs': 'Glimmer JS',\n 'glsl': 'GLSL',\n 'gnuplot': 'Gnuplot',\n 'go': 'Go',\n 'graphql': 'GraphQL',\n 'groovy': 'Groovy',\n 'hack': 'Hack',\n 'haml': 'Haml',\n 'handlebars': 'Handlebars',\n 'hbs': 'Handlebars',\n 'haskell': 'Haskell',\n 'hs': 'Haskell',\n 'hcl': 'HCL',\n 'hjson': 'Hjson',\n 'hlsl': 'HLSL',\n 'html': 'HTML',\n 'http': 'HTTP',\n 'imba': 'Imba',\n 'ini': 'INI',\n 'java': 'Java',\n 'javascript': 'JavaScript',\n 'js': 'JavaScript',\n 'jinja-html': 'Jinja HTML',\n 'jjson': 'JJSON',\n 'json': 'JSON',\n 'json5': 'JSON5',\n 'jsonc': 'JSONC',\n 'jsonnet': 'Jsonnet',\n 'jssm': 'JSSM',\n 'jsx': 'JSX',\n 'julia': 'Julia',\n 'kotlin': 'Kotlin',\n 'kt': 'Kotlin',\n 'kts': 'Kotlin',\n 'kusto': 'Kusto',\n 'latex': 'LaTeX',\n 'lat': 'LaTeX',\n 'tex': 'LaTeX',\n 'lean': 'Lean',\n 'less': 'Less',\n 'liquid': 'Liquid',\n 'lisp': 'Lisp',\n 'logo': 'Logo',\n 'lua': 'Lua',\n 'make': 'Make',\n 'makefile': 'Makefile',\n 'markdown': 'Markdown',\n 'md': 'Markdown',\n 'marko': 'Marko',\n 'matlab': 'MATLAB',\n 'mdx': 'MDX',\n 'mermaid': 'Mermaid',\n 'mipsasm': 'MIPS Assembly',\n 'mips': 'MIPS Assembly',\n 'mojolicious': 'Mojolicious',\n 'move': 'Move',\n 'narrat': 'Narrat',\n 'nextflow': 'Nextflow',\n 'nginx': 'Nginx',\n 'nim': 'Nim',\n 'nix': 'Nix',\n 'objective-c': 'Objective-C',\n 'objc': 'Objective-C',\n 'objective-cpp': 'Objective-C++',\n 'ocaml': 'OCaml',\n 'pascal': 'Pascal',\n 'perl': 'Perl',\n 'pl': 'Perl',\n 'php': 'PHP',\n 'plsql': 'PL/SQL',\n 'postcss': 'PostCSS',\n 'powerquery': 'PowerQuery',\n 'powershell': 'PowerShell',\n 'ps1': 'PowerShell',\n 'prisma': 'Prisma',\n 'prolog': 'Prolog',\n 'proto': 'Protocol Buffers',\n 'pug': 'Pug',\n 'jade': 'Pug',\n 'puppet': 'Puppet',\n 'purescript': 'PureScript',\n 'python': 'Python',\n 'py': 'Python',\n 'r': 'R',\n 'raku': 'Raku',\n 'razor': 'Razor',\n 'reg': 'Registry',\n 'rel': 'Rel',\n 'riscv': 'RISC-V',\n 'rst': 'reStructuredText',\n 'ruby': 'Ruby',\n 'rb': 'Ruby',\n 'rust': 'Rust',\n 'rs': 'Rust',\n 'sas': 'SAS',\n 'sass': 'Sass',\n 'scala': 'Scala',\n 'scheme': 'Scheme',\n 'scss': 'SCSS',\n 'shaderlab': 'ShaderLab',\n 'shader': 'ShaderLab',\n 'shell': 'Shell',\n 'shellscript': 'Shell',\n 'smalltalk': 'Smalltalk',\n 'solidity': 'Solidity',\n 'sparql': 'SPARQL',\n 'sql': 'SQL',\n 'ssh-config': 'SSH Config',\n 'stata': 'Stata',\n 'stylus': 'Stylus',\n 'styl': 'Stylus',\n 'svelte': 'Svelte',\n 'swift': 'Swift',\n 'system-verilog': 'SystemVerilog',\n 'tasl': 'Tasl',\n 'tcl': 'Tcl',\n 'terraform': 'Terraform',\n 'tf': 'Terraform',\n 'toml': 'TOML',\n 'tsx': 'TSX',\n 'turtle': 'Turtle',\n 'twig': 'Twig',\n 'typescript': 'TypeScript',\n 'ts': 'TypeScript',\n 'v': 'V',\n 'vb': 'Visual Basic',\n 'verilog': 'Verilog',\n 'vhdl': 'VHDL',\n 'viml': 'VimL',\n 'vim': 'VimL',\n 'vue': 'Vue',\n 'vyper': 'Vyper',\n 'wasm': 'WebAssembly',\n 'wenyan': 'Wenyan',\n 'wgsl': 'WGSL',\n 'wolfram': 'Wolfram',\n 'xml': 'XML',\n 'xsl': 'XSL',\n 'yaml': 'YAML',\n 'yml': 'YAML',\n 'zenscript': 'ZenScript',\n 'zig': 'Zig',\n 'zsh': 'Zsh',\n };\n\n return langMap[lang.toLowerCase()] || lang;\n });\n\n private getHighlightTransformer(): ShikiTransformer {\n const highlights = this.highlightLines();\n if (!highlights || (Array.isArray(highlights) && highlights.length === 0)) {\n return {};\n }\n\n const isHighlighted = (line: number): boolean => {\n if (Array.isArray(highlights[0])) {\n return (highlights as number[][]).some(([start, end]) => line >= start && line <= end);\n } else {\n const [start, end] = highlights as number[];\n return line >= start && line <= end;\n }\n };\n\n return {\n line(node, line) {\n if (isHighlighted(line)) {\n this.addClassToHast(node, 'highlighted');\n }\n }\n };\n }\n\n async ngOnChanges(changes: SimpleChanges) {\n const code = this.code() ?? '';\n\n if (code.length === 0) {\n this.isLoading.set(false);\n this.content.set(this.sanitizer.bypassSecurityTrustHtml('<pre class=\"shiki\"><code></code></pre>'));\n return;\n }\n\n this.isLoading.set(true);\n try {\n const highlighted = await codeToHtml(\n code,\n {\n lang: this.language(),\n theme: this.theme(),\n transformers: [diffTransformer, this.getHighlightTransformer()],\n diff: this.diff()\n } as any\n );\n this.content.set(this.sanitizer.bypassSecurityTrustHtml(highlighted));\n } catch (e) {\n // Fallback: raw code escaped inside pre\n const escaped = code\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;');\n const fallback = `<pre class=\"shiki\"><code>${escaped}</code></pre>`;\n this.content.set(this.sanitizer.bypassSecurityTrustHtml(fallback));\n console.error('CodeHighlighter error:', e);\n } finally {\n this.isLoading.set(false);\n }\n }\n\n copied = signal(false);\n private copyTimeout?: any;\n\n copyCode() {\n if (this.code()) {\n navigator.clipboard.writeText(this.code());\n this.copied.set(true);\n\n if (this.copyTimeout) {\n clearTimeout(this.copyTimeout);\n }\n\n this.copyTimeout = setTimeout(() => {\n this.copied.set(false);\n this.copyTimeout = undefined;\n }, 2000);\n }\n }\n}\n","<figure class=\"h-full\">\n @if (title()) {\n <figcaption>\n @if (title()) {\n <span class=\"title\">{{ title() }}</span>\n }\n </figcaption>\n }\n\n <div class=\"content relative h-full\">\n @if (showLanguage()) {\n <div class=\"languageName\">{{ displayedLanguage() }}</div>\n }\n\n @if (showCopyButton()) {\n <span class=\"absolute top-2 right-2\">\n <button\n ngsIconButton\n (click)=\"copyCode()\"\n >\n <ngs-icon\n [name]=\"copied() ? 'fluent:checkmark-24-regular' : 'fluent:copy-24-regular'\"\n [class.text-green-500]=\"copied()\"\n />\n </button>\n </span>\n }\n\n <div>\n @if (content()) {\n <div [innerHTML]=\"content()\"></div>\n } @else if (isLoading()) {\n <div class=\"loading\">Loading…</div>\n }\n </div>\n </div>\n</figure>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -3038,7 +3038,7 @@ class Settings {
3038
3038
  this.imageDesigner?.openEffects();
3039
3039
  }
3040
3040
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: Settings, deps: [], target: i0.ɵɵFactoryTarget.Component });
3041
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: Settings, isStandalone: true, selector: "ngs-settings", ngImport: i0, template: "@let layer = selectedLayer();\n\n@if (layer) {\n <ngs-toolbar\n class=\"h-14 z-10 bg-surface-container-lowest border-b border-border px-5 absolute top-0 left-0 right-0\">\n <!-- Color -->\n @if (showColorPicker()) {\n <ngs-toolbar-item>\n <button [ngsPopoverTriggerFor]=\"colorPopover\"\n position=\"below-center\"\n class=\"size-7 cursor-pointer hover:ring-2 hover:ring-primary rounded-full border border-border\"\n ngsRipple\n [style.backgroundColor]=\"layer['fill'] || '#000000'\">\n </button>\n <ngs-popover #colorPopover>\n <ng-template ngsPopoverContent>\n <div class=\"p-4 w-72\">\n <div class=\"text-xs font-medium uppercase text-muted-foreground mb-4\">\n {{ layer.type === 'text' ? 'Text Color' : 'Fill Color' }}\n </div>\n <ngs-color-switcher [colors]=\"presetColors()\"\n [selectedColor]=\"layer['fill'] || '#000000'\"\n (colorChange)=\"updateColor($event)\"/>\n </div>\n </ng-template>\n </ngs-popover>\n </ngs-toolbar-item>\n <ngs-divider vertical/>\n }\n\n <!-- Opacity -->\n <ngs-toolbar-item>\n <button ngsIconButton\n [ngsPopoverTriggerFor]=\"opacityPopover\"\n position=\"below-center\">\n <ngs-icon name=\"fluent:blur-24-regular\"/>\n </button>\n <ngs-popover #opacityPopover>\n <ng-template ngsPopoverContent>\n <div class=\"p-4 w-60 space-y-3\">\n <div class=\"flex justify-between items-center\">\n <label class=\"text-xs font-medium uppercase text-muted-foreground\">Opacity</label>\n <span class=\"text-xs text-muted-foreground\">{{ (layer['opacity'] ?? 1) * 100 | number:'1.0-0' }}%</span>\n </div>\n <ngs-slider [min]=\"0\" [max]=\"1\" [step]=\"0.01\">\n <input ngsSliderThumb\n [value]=\"layer['opacity'] ?? 1\"\n (valueChange)=\"updateOpacity($event)\"/>\n </ngs-slider>\n </div>\n </ng-template>\n </ngs-popover>\n </ngs-toolbar-item>\n\n <!-- Font Selection for text layers -->\n @if (layer.type === 'text') {\n <ngs-toolbar-item>\n <button ngsButton reverse [ngsMenuTriggerFor]=\"fontMenu\">\n <span class=\"truncate max-w-[100px]\">{{ layer['fontFamily'] }}</span>\n <ngs-icon name=\"fluent:chevron-down-20-regular\" class=\"size-5\"/>\n </button>\n\n <ngs-menu #fontMenu=\"ngsMenu\">\n <div class=\"min-w-[200px]\">\n @for (font of fonts(); track font) {\n <button ngs-menu-item\n [selected]=\"layer['fontFamily'] === font\"\n (click)=\"updateFont(font)\">\n {{ font }}\n </button>\n }\n </div>\n </ngs-menu>\n </ngs-toolbar-item>\n\n <!-- Text Styles -->\n <ngs-toolbar-item>\n <button ngsIconButton\n [ngsPopoverTriggerFor]=\"boldPopover\"\n position=\"below-center\"\n [class.text-primary]=\"layer['fontWeight'] && layer['fontWeight'] !== 'normal' && layer['fontWeight'] !== 400\"\n title=\"Bold\">\n <ngs-icon name=\"fluent:text-bold-24-regular\"/>\n </button>\n <ngs-popover #boldPopover>\n <ng-template ngsPopoverContent>\n <div class=\"p-4 w-60 space-y-3\">\n <div class=\"flex justify-between items-center\">\n <label class=\"text-xs font-medium uppercase text-muted-foreground\">Font Weight</label>\n <span class=\"text-xs text-muted-foreground\">{{ getFontWeightName(layer['fontWeight']) }}</span>\n </div>\n <ngs-slider [min]=\"300\" [max]=\"900\" [step]=\"100\">\n <input ngsSliderThumb\n [value]=\"layer['fontWeight'] === 'bold' ? 700 : (layer['fontWeight'] === 'normal' ? 400 : (layer['fontWeight'] || 400))\"\n (valueChange)=\"updateFontWeight($event)\"/>\n </ngs-slider>\n </div>\n </ng-template>\n </ngs-popover>\n </ngs-toolbar-item>\n\n <!-- Uppercase -->\n <ngs-toolbar-item>\n <button ngsIconButton\n (click)=\"toggleUppercase()\"\n [class.text-primary]=\"layer['textCase'] === 'upper'\"\n title=\"Uppercase\">\n <ngs-icon name=\"fluent:text-case-uppercase-24-regular\"/>\n </button>\n </ngs-toolbar-item>\n\n <ngs-toolbar-item>\n <ngs-button-toggle-group multiple\n hideSelectionIndicator\n [value]=\"getTextStyle()\"\n (valueChange)=\"updateTextStyle($event)\">\n <ngs-button-toggle value=\"italic\" title=\"Italic\">\n <ngs-icon name=\"fluent:text-italic-24-regular\"/>\n </ngs-button-toggle>\n <ngs-button-toggle value=\"underline\" title=\"Underline\">\n <ngs-icon name=\"fluent:text-underline-24-regular\"/>\n </ngs-button-toggle>\n <ngs-button-toggle value=\"line-through\" title=\"Strikethrough\">\n <ngs-icon name=\"fluent:text-strikethrough-24-regular\"/>\n </ngs-button-toggle>\n </ngs-button-toggle-group>\n </ngs-toolbar-item>\n\n <!-- Text Alignment -->\n <ngs-toolbar-item>\n <button ngsIconButton\n [ngsPopoverTriggerFor]=\"alignPopover\"\n position=\"below-center\"\n title=\"Alignment\">\n <ngs-icon [name]=\"'fluent:text-align-' + (layer['align'] || 'left') + '-24-regular'\"/>\n </button>\n <ngs-popover #alignPopover>\n <ng-template ngsPopoverContent>\n <div class=\"p-2 flex gap-1\">\n <button ngsIconButton (click)=\"updateTextAlign('left')\" [class.text-primary]=\"layer['align'] === 'left'\">\n <ngs-icon name=\"fluent:text-align-left-24-regular\"/>\n </button>\n <button ngsIconButton (click)=\"updateTextAlign('center')\" [class.text-primary]=\"layer['align'] === 'center'\">\n <ngs-icon name=\"fluent:text-align-center-24-regular\"/>\n </button>\n <button ngsIconButton (click)=\"updateTextAlign('right')\" [class.text-primary]=\"layer['align'] === 'right'\">\n <ngs-icon name=\"fluent:text-align-right-24-regular\"/>\n </button>\n <button ngsIconButton (click)=\"updateTextAlign('justify')\" [class.text-primary]=\"layer['align'] === 'justify'\">\n <ngs-icon name=\"fluent:text-align-justify-24-regular\"/>\n </button>\n </div>\n </ng-template>\n </ngs-popover>\n </ngs-toolbar-item>\n\n <!-- Spacing (Line Height & Letter Spacing) -->\n <ngs-toolbar-item>\n <button ngsIconButton\n [ngsPopoverTriggerFor]=\"spacingPopover\"\n position=\"below-center\"\n title=\"Spacing\">\n <ngs-icon name=\"fluent:text-line-spacing-24-regular\"/>\n </button>\n <ngs-popover #spacingPopover>\n <ng-template ngsPopoverContent>\n <div class=\"p-4 w-60 space-y-6\">\n <div class=\"space-y-3\">\n <div class=\"flex justify-between items-center\">\n <label class=\"text-xs font-medium uppercase text-muted-foreground\">Line Height</label>\n <span class=\"text-xs text-muted-foreground\">{{ layer['lineHeight'] || 1.2 | number:'1.1-1' }}</span>\n </div>\n <ngs-slider [min]=\"0.5\" [max]=\"3\" [step]=\"0.1\">\n <input ngsSliderThumb\n [value]=\"layer['lineHeight'] || 1.2\"\n (valueChange)=\"updateLineHeight($event)\"/>\n </ngs-slider>\n </div>\n <div class=\"space-y-3\">\n <div class=\"flex justify-between items-center\">\n <label class=\"text-xs font-medium uppercase text-muted-foreground\">Letter Spacing</label>\n <span class=\"text-xs text-muted-foreground\">{{ layer['letterSpacing'] || 0 }}</span>\n </div>\n <ngs-slider [min]=\"-5\" [max]=\"50\" [step]=\"1\">\n <input ngsSliderThumb\n [value]=\"layer['letterSpacing'] || 0\"\n (valueChange)=\"updateLetterSpacing($event)\"/>\n </ngs-slider>\n </div>\n </div>\n </ng-template>\n </ngs-popover>\n </ngs-toolbar-item>\n }\n\n @if (layer.type === 'image') {\n <ngs-toolbar-item>\n <button ngsButton reverse [ngsMenuTriggerFor]=\"flipMenu\">\n <span>Flip</span>\n <ngs-icon name=\"fluent:chevron-down-20-regular\" class=\"size-5\"/>\n </button>\n\n <ngs-menu #flipMenu=\"ngsMenu\">\n <div class=\"min-w-[150px]\">\n <button ngs-menu-item (click)=\"flipHorizontal()\">\n <ngs-icon name=\"fluent:flip-horizontal-24-regular\" class=\"mr-2\"/>\n <span>Flip horizontally</span>\n </button>\n <button ngs-menu-item (click)=\"flipVertical()\">\n <ngs-icon name=\"fluent:flip-vertical-24-regular\" class=\"mr-2\"/>\n <span>Flip vertically</span>\n </button>\n </div>\n </ngs-menu>\n </ngs-toolbar-item>\n\n <ngs-toolbar-item>\n <button ngsButton reverse [ngsMenuTriggerFor]=\"fitMenu\">\n <span>Fit to</span>\n <ngs-icon name=\"fluent:chevron-down-20-regular\" class=\"size-5\"/>\n </button>\n\n <ngs-menu #fitMenu=\"ngsMenu\">\n <div class=\"min-w-[150px]\">\n <button ngs-menu-item (click)=\"fitToPage()\">\n <span>Fit to page</span>\n </button>\n <button ngs-menu-item (click)=\"fillPage()\">\n <span>Fill page</span>\n </button>\n </div>\n </ngs-menu>\n </ngs-toolbar-item>\n }\n\n <ngs-toolbar-item>\n <button ngsButton reverse (click)=\"openEffects()\">\n <span>Effects</span>\n </button>\n </ngs-toolbar-item>\n\n <ngs-toolbar-spacer/>\n\n <!-- <ngs-divider vertical/>-->\n\n <ngs-toolbar-item>\n <button ngsIconButton (click)=\"toggleLock()\">\n <ngs-icon [name]=\"layer['locked'] ? 'fluent:lock-closed-24-regular' : 'fluent:lock-open-24-regular'\"/>\n </button>\n </ngs-toolbar-item>\n\n </ngs-toolbar>\n}\n", styles: [":host{display:contents}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: ColorSwitcher, selector: "ngs-color-switcher", inputs: ["colors", "selectedColor", "disabled"], outputs: ["colorChange"], exportAs: ["ngsColorSwitcher"] }, { kind: "component", type: Slider, selector: "ngs-slider", inputs: ["disabled", "discrete", "showTickMarks", "min", "max", "step", "displayWith"], exportAs: ["ngsSlider"] }, { kind: "directive", type: SliderThumb, selector: "input[ngsSliderThumb]", inputs: ["value"], outputs: ["valueChange"], exportAs: ["ngsSliderThumb"] }, { kind: "component", type: Toolbar, selector: "ngs-toolbar", exportAs: ["ngsToolbar"] }, { kind: "component", type: ToolbarItem, selector: "ngs-toolbar-item", inputs: ["hidden"], outputs: ["hiddenChange"] }, { kind: "component", type: Popover, selector: "ngs-popover", exportAs: ["ngsPopover"] }, { kind: "directive", type: PopoverContent, selector: "[ngsPopoverContent]" }, { kind: "directive", type: PopoverTriggerForDirective, selector: "[ngsPopoverTriggerFor]", inputs: ["ngsPopoverTriggerFor", "ngsPopoverContext", "trigger", "position", "delay", "origin", "closeOnOriginClick", "closeOnOriginMouseLeave", "hasBackdrop"], outputs: ["opened", "closed"], exportAs: ["ngsPopoverTriggerFor"] }, { kind: "component", type: Button, selector: " button[ngsButton], button[ngsIconButton], a[ngsButton], a[ngsIconButton] ", inputs: ["ngsButton", "ngsIconButton", "loading", "disabled", "disabledInteractive", "disableRipple", "reverse", "fullWidth", "hideTextOnMobile"], exportAs: ["ngsButton"] }, { kind: "component", type: Icon, selector: "ngs-icon", inputs: ["name"], exportAs: ["ngsIcon"] }, { kind: "component", type: Divider, selector: "ngs-divider", inputs: ["vertical", "inset", "fixedHeight"], exportAs: ["ngsDivider"] }, { kind: "component", type: Menu, selector: "ngs-menu", inputs: ["role", "classList", "xPosition", "yPosition"], outputs: ["closed"], exportAs: ["ngsMenu"] }, { kind: "component", type: MenuItem, selector: "ngs-menu-item, [ngs-menu-item]", inputs: ["disabled", "role", "selected"], outputs: ["_triggered"], exportAs: ["ngsMenuItem"] }, { kind: "directive", type: MenuTrigger, selector: "[ngsMenuTriggerFor]", inputs: ["ngsMenuTriggerFor", "ngsMenuTriggerData", "ngsMenuDisabled", "xPosition", "yPosition", "ngsMenuTriggerRestoreFocus"], outputs: ["menuOpened", "menuClosed"], exportAs: ["ngsMenuTrigger"] }, { kind: "directive", type: Ripple, selector: "[ngsRipple]", inputs: ["ngsRippleColor", "ngsRippleUnbounded", "ngsRippleCentered", "ngsRippleRadius", "ngsRippleAnimation", "ngsRippleDisabled", "ngsRippleTrigger"], outputs: ["ngsRippleCenteredChange", "ngsRippleDisabledChange", "ngsRippleTriggerChange"], exportAs: ["ngsRipple"] }, { kind: "component", type: ToolbarSpacer, selector: "ngs-toolbar-spacer" }, { kind: "component", type: ButtonToggle, selector: "ngs-button-toggle", inputs: ["id", "value", "name", "checked", "disabled", "onlyIcon"], outputs: ["change"], exportAs: ["ngsButtonToggle"] }, { kind: "component", type: ButtonToggleGroup, selector: "ngs-button-toggle-group", inputs: ["appearance", "disabled", "multiple", "hideSelectionIndicator", "vertical", "value", "onlyIcon"], outputs: ["valueChange", "change"], exportAs: ["ngsButtonToggleGroup"] }, { kind: "ngmodule", type: FormsModule }, { kind: "pipe", type: i1.DecimalPipe, name: "number" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3041
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: Settings, isStandalone: true, selector: "ngs-settings", ngImport: i0, template: "@let layer = selectedLayer();\n\n@if (layer) {\n <ngs-toolbar\n class=\"h-14 z-10 bg-surface-container-lowest border-b border-border px-5 absolute top-0 left-0 right-0\">\n <!-- Color -->\n @if (showColorPicker()) {\n <ngs-toolbar-item>\n <button [ngsPopoverTriggerFor]=\"colorPopover\"\n position=\"below-center\"\n class=\"size-7 cursor-pointer hover:ring-2 hover:ring-primary rounded-full border border-border\"\n ngsRipple\n [style.backgroundColor]=\"layer['fill'] || '#000000'\">\n </button>\n <ngs-popover #colorPopover>\n <ng-template ngsPopoverContent>\n <div class=\"p-4 w-72\">\n <div class=\"text-xs font-medium uppercase text-muted-foreground mb-4\">\n {{ layer.type === 'text' ? 'Text Color' : 'Fill Color' }}\n </div>\n <ngs-color-switcher [colors]=\"presetColors()\"\n [selectedColor]=\"layer['fill'] || '#000000'\"\n (colorChange)=\"updateColor($event)\"/>\n </div>\n </ng-template>\n </ngs-popover>\n </ngs-toolbar-item>\n <ngs-divider vertical/>\n }\n\n <!-- Opacity -->\n <ngs-toolbar-item>\n <button ngsIconButton\n [ngsPopoverTriggerFor]=\"opacityPopover\"\n position=\"below-center\">\n <ngs-icon name=\"fluent:blur-24-regular\"/>\n </button>\n <ngs-popover #opacityPopover>\n <ng-template ngsPopoverContent>\n <div class=\"p-4 w-60 space-y-3\">\n <div class=\"flex justify-between items-center\">\n <label class=\"text-xs font-medium uppercase text-muted-foreground\">Opacity</label>\n <span class=\"text-xs text-muted-foreground\">{{ (layer['opacity'] ?? 1) * 100 | number:'1.0-0' }}%</span>\n </div>\n <ngs-slider [min]=\"0\" [max]=\"1\" [step]=\"0.01\">\n <input ngsSliderThumb\n [value]=\"layer['opacity'] ?? 1\"\n (valueChange)=\"updateOpacity($event)\"/>\n </ngs-slider>\n </div>\n </ng-template>\n </ngs-popover>\n </ngs-toolbar-item>\n\n <!-- Font Selection for text layers -->\n @if (layer.type === 'text') {\n <ngs-toolbar-item>\n <button ngsButton reverse [ngsMenuTriggerFor]=\"fontMenu\">\n <span class=\"truncate max-w-[100px]\">{{ layer['fontFamily'] }}</span>\n <ngs-icon name=\"fluent:chevron-down-20-regular\" class=\"size-5\"/>\n </button>\n\n <ngs-menu #fontMenu=\"ngsMenu\">\n <div class=\"min-w-[200px]\">\n @for (font of fonts(); track font) {\n <button ngs-menu-item\n [selected]=\"layer['fontFamily'] === font\"\n (click)=\"updateFont(font)\">\n {{ font }}\n </button>\n }\n </div>\n </ngs-menu>\n </ngs-toolbar-item>\n\n <!-- Text Styles -->\n <ngs-toolbar-item>\n <button ngsIconButton\n [ngsPopoverTriggerFor]=\"boldPopover\"\n position=\"below-center\"\n [class.text-primary]=\"layer['fontWeight'] && layer['fontWeight'] !== 'normal' && layer['fontWeight'] !== 400\"\n title=\"Bold\">\n <ngs-icon name=\"fluent:text-bold-24-regular\"/>\n </button>\n <ngs-popover #boldPopover>\n <ng-template ngsPopoverContent>\n <div class=\"p-4 w-60 space-y-3\">\n <div class=\"flex justify-between items-center\">\n <label class=\"text-xs font-medium uppercase text-muted-foreground\">Font Weight</label>\n <span class=\"text-xs text-muted-foreground\">{{ getFontWeightName(layer['fontWeight']) }}</span>\n </div>\n <ngs-slider [min]=\"300\" [max]=\"900\" [step]=\"100\">\n <input ngsSliderThumb\n [value]=\"layer['fontWeight'] === 'bold' ? 700 : (layer['fontWeight'] === 'normal' ? 400 : (layer['fontWeight'] || 400))\"\n (valueChange)=\"updateFontWeight($event)\"/>\n </ngs-slider>\n </div>\n </ng-template>\n </ngs-popover>\n </ngs-toolbar-item>\n\n <!-- Uppercase -->\n <ngs-toolbar-item>\n <button ngsIconButton\n (click)=\"toggleUppercase()\"\n [class.text-primary]=\"layer['textCase'] === 'upper'\"\n title=\"Uppercase\">\n <ngs-icon name=\"fluent:text-case-uppercase-24-regular\"/>\n </button>\n </ngs-toolbar-item>\n\n <ngs-toolbar-item>\n <ngs-button-toggle-group multiple\n hideSelectionIndicator\n onlyIcon\n [value]=\"getTextStyle()\"\n (valueChange)=\"updateTextStyle($event)\">\n <ngs-button-toggle value=\"italic\" title=\"Italic\">\n <ngs-icon name=\"fluent:text-italic-24-regular\"/>\n </ngs-button-toggle>\n <ngs-button-toggle value=\"underline\" title=\"Underline\">\n <ngs-icon name=\"fluent:text-underline-24-regular\"/>\n </ngs-button-toggle>\n <ngs-button-toggle value=\"line-through\" title=\"Strikethrough\">\n <ngs-icon name=\"fluent:text-strikethrough-24-regular\"/>\n </ngs-button-toggle>\n </ngs-button-toggle-group>\n </ngs-toolbar-item>\n\n <!-- Text Alignment -->\n <ngs-toolbar-item>\n <button ngsIconButton\n [ngsPopoverTriggerFor]=\"alignPopover\"\n position=\"below-center\"\n title=\"Alignment\">\n <ngs-icon [name]=\"'fluent:text-align-' + (layer['align'] || 'left') + '-24-regular'\"/>\n </button>\n <ngs-popover #alignPopover>\n <ng-template ngsPopoverContent>\n <div class=\"p-2 flex gap-1\">\n <button ngsIconButton (click)=\"updateTextAlign('left')\" [class.text-primary]=\"layer['align'] === 'left'\">\n <ngs-icon name=\"fluent:text-align-left-24-regular\"/>\n </button>\n <button ngsIconButton (click)=\"updateTextAlign('center')\" [class.text-primary]=\"layer['align'] === 'center'\">\n <ngs-icon name=\"fluent:text-align-center-24-regular\"/>\n </button>\n <button ngsIconButton (click)=\"updateTextAlign('right')\" [class.text-primary]=\"layer['align'] === 'right'\">\n <ngs-icon name=\"fluent:text-align-right-24-regular\"/>\n </button>\n <button ngsIconButton (click)=\"updateTextAlign('justify')\" [class.text-primary]=\"layer['align'] === 'justify'\">\n <ngs-icon name=\"fluent:text-align-justify-24-regular\"/>\n </button>\n </div>\n </ng-template>\n </ngs-popover>\n </ngs-toolbar-item>\n\n <!-- Spacing (Line Height & Letter Spacing) -->\n <ngs-toolbar-item>\n <button ngsIconButton\n [ngsPopoverTriggerFor]=\"spacingPopover\"\n position=\"below-center\"\n title=\"Spacing\">\n <ngs-icon name=\"fluent:text-line-spacing-24-regular\"/>\n </button>\n <ngs-popover #spacingPopover>\n <ng-template ngsPopoverContent>\n <div class=\"p-4 w-60 space-y-6\">\n <div class=\"space-y-3\">\n <div class=\"flex justify-between items-center\">\n <label class=\"text-xs font-medium uppercase text-muted-foreground\">Line Height</label>\n <span class=\"text-xs text-muted-foreground\">{{ layer['lineHeight'] || 1.2 | number:'1.1-1' }}</span>\n </div>\n <ngs-slider [min]=\"0.5\" [max]=\"3\" [step]=\"0.1\">\n <input ngsSliderThumb\n [value]=\"layer['lineHeight'] || 1.2\"\n (valueChange)=\"updateLineHeight($event)\"/>\n </ngs-slider>\n </div>\n <div class=\"space-y-3\">\n <div class=\"flex justify-between items-center\">\n <label class=\"text-xs font-medium uppercase text-muted-foreground\">Letter Spacing</label>\n <span class=\"text-xs text-muted-foreground\">{{ layer['letterSpacing'] || 0 }}</span>\n </div>\n <ngs-slider [min]=\"-5\" [max]=\"50\" [step]=\"1\">\n <input ngsSliderThumb\n [value]=\"layer['letterSpacing'] || 0\"\n (valueChange)=\"updateLetterSpacing($event)\"/>\n </ngs-slider>\n </div>\n </div>\n </ng-template>\n </ngs-popover>\n </ngs-toolbar-item>\n }\n\n @if (layer.type === 'image') {\n <ngs-toolbar-item>\n <button ngsButton reverse [ngsMenuTriggerFor]=\"flipMenu\">\n <span>Flip</span>\n <ngs-icon name=\"fluent:chevron-down-20-regular\" class=\"size-5\"/>\n </button>\n\n <ngs-menu #flipMenu=\"ngsMenu\">\n <div class=\"min-w-[150px]\">\n <button ngs-menu-item (click)=\"flipHorizontal()\">\n <ngs-icon name=\"fluent:flip-horizontal-24-regular\" class=\"mr-2\"/>\n <span>Flip horizontally</span>\n </button>\n <button ngs-menu-item (click)=\"flipVertical()\">\n <ngs-icon name=\"fluent:flip-vertical-24-regular\" class=\"mr-2\"/>\n <span>Flip vertically</span>\n </button>\n </div>\n </ngs-menu>\n </ngs-toolbar-item>\n\n <ngs-toolbar-item>\n <button ngsButton reverse [ngsMenuTriggerFor]=\"fitMenu\">\n <span>Fit to</span>\n <ngs-icon name=\"fluent:chevron-down-20-regular\" class=\"size-5\"/>\n </button>\n\n <ngs-menu #fitMenu=\"ngsMenu\">\n <div class=\"min-w-[150px]\">\n <button ngs-menu-item (click)=\"fitToPage()\">\n <span>Fit to page</span>\n </button>\n <button ngs-menu-item (click)=\"fillPage()\">\n <span>Fill page</span>\n </button>\n </div>\n </ngs-menu>\n </ngs-toolbar-item>\n }\n\n <ngs-toolbar-item>\n <button ngsButton reverse (click)=\"openEffects()\">\n <span>Effects</span>\n </button>\n </ngs-toolbar-item>\n\n <ngs-toolbar-spacer/>\n\n <!-- <ngs-divider vertical/>-->\n\n <ngs-toolbar-item>\n <button ngsIconButton (click)=\"toggleLock()\">\n <ngs-icon [name]=\"layer['locked'] ? 'fluent:lock-closed-24-regular' : 'fluent:lock-open-24-regular'\"/>\n </button>\n </ngs-toolbar-item>\n\n </ngs-toolbar>\n}\n", styles: [":host{display:contents}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: ColorSwitcher, selector: "ngs-color-switcher", inputs: ["colors", "selectedColor", "disabled"], outputs: ["colorChange"], exportAs: ["ngsColorSwitcher"] }, { kind: "component", type: Slider, selector: "ngs-slider", inputs: ["disabled", "discrete", "showTickMarks", "min", "max", "step", "displayWith"], exportAs: ["ngsSlider"] }, { kind: "directive", type: SliderThumb, selector: "input[ngsSliderThumb]", inputs: ["value"], outputs: ["valueChange"], exportAs: ["ngsSliderThumb"] }, { kind: "component", type: Toolbar, selector: "ngs-toolbar", exportAs: ["ngsToolbar"] }, { kind: "component", type: ToolbarItem, selector: "ngs-toolbar-item", inputs: ["hidden"], outputs: ["hiddenChange"] }, { kind: "component", type: Popover, selector: "ngs-popover", exportAs: ["ngsPopover"] }, { kind: "directive", type: PopoverContent, selector: "[ngsPopoverContent]" }, { kind: "directive", type: PopoverTriggerForDirective, selector: "[ngsPopoverTriggerFor]", inputs: ["ngsPopoverTriggerFor", "ngsPopoverContext", "trigger", "position", "delay", "origin", "closeOnOriginClick", "closeOnOriginMouseLeave", "hasBackdrop"], outputs: ["opened", "closed"], exportAs: ["ngsPopoverTriggerFor"] }, { kind: "component", type: Button, selector: " button[ngsButton], button[ngsIconButton], a[ngsButton], a[ngsIconButton] ", inputs: ["ngsButton", "ngsIconButton", "loading", "disabled", "disabledInteractive", "disableRipple", "reverse", "fullWidth", "hideTextOnMobile"], exportAs: ["ngsButton"] }, { kind: "component", type: Icon, selector: "ngs-icon", inputs: ["name"], exportAs: ["ngsIcon"] }, { kind: "component", type: Divider, selector: "ngs-divider", inputs: ["vertical", "inset", "fixedHeight"], exportAs: ["ngsDivider"] }, { kind: "component", type: Menu, selector: "ngs-menu", inputs: ["role", "classList", "xPosition", "yPosition"], outputs: ["closed"], exportAs: ["ngsMenu"] }, { kind: "component", type: MenuItem, selector: "ngs-menu-item, [ngs-menu-item]", inputs: ["disabled", "role", "selected"], outputs: ["_triggered"], exportAs: ["ngsMenuItem"] }, { kind: "directive", type: MenuTrigger, selector: "[ngsMenuTriggerFor]", inputs: ["ngsMenuTriggerFor", "ngsMenuTriggerData", "ngsMenuDisabled", "xPosition", "yPosition", "ngsMenuTriggerRestoreFocus"], outputs: ["menuOpened", "menuClosed"], exportAs: ["ngsMenuTrigger"] }, { kind: "directive", type: Ripple, selector: "[ngsRipple]", inputs: ["ngsRippleColor", "ngsRippleUnbounded", "ngsRippleCentered", "ngsRippleRadius", "ngsRippleAnimation", "ngsRippleDisabled", "ngsRippleTrigger"], outputs: ["ngsRippleCenteredChange", "ngsRippleDisabledChange", "ngsRippleTriggerChange"], exportAs: ["ngsRipple"] }, { kind: "component", type: ToolbarSpacer, selector: "ngs-toolbar-spacer" }, { kind: "component", type: ButtonToggle, selector: "ngs-button-toggle", inputs: ["id", "value", "name", "checked", "disabled", "onlyIcon"], outputs: ["change"], exportAs: ["ngsButtonToggle"] }, { kind: "component", type: ButtonToggleGroup, selector: "ngs-button-toggle-group", inputs: ["appearance", "disabled", "multiple", "hideSelectionIndicator", "vertical", "value", "onlyIcon"], outputs: ["valueChange", "change"], exportAs: ["ngsButtonToggleGroup"] }, { kind: "ngmodule", type: FormsModule }, { kind: "pipe", type: i1.DecimalPipe, name: "number" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3042
3042
  }
3043
3043
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: Settings, decorators: [{
3044
3044
  type: Component,
@@ -3064,7 +3064,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImpor
3064
3064
  ButtonToggle,
3065
3065
  ButtonToggleGroup,
3066
3066
  FormsModule
3067
- ], changeDetection: ChangeDetectionStrategy.OnPush, template: "@let layer = selectedLayer();\n\n@if (layer) {\n <ngs-toolbar\n class=\"h-14 z-10 bg-surface-container-lowest border-b border-border px-5 absolute top-0 left-0 right-0\">\n <!-- Color -->\n @if (showColorPicker()) {\n <ngs-toolbar-item>\n <button [ngsPopoverTriggerFor]=\"colorPopover\"\n position=\"below-center\"\n class=\"size-7 cursor-pointer hover:ring-2 hover:ring-primary rounded-full border border-border\"\n ngsRipple\n [style.backgroundColor]=\"layer['fill'] || '#000000'\">\n </button>\n <ngs-popover #colorPopover>\n <ng-template ngsPopoverContent>\n <div class=\"p-4 w-72\">\n <div class=\"text-xs font-medium uppercase text-muted-foreground mb-4\">\n {{ layer.type === 'text' ? 'Text Color' : 'Fill Color' }}\n </div>\n <ngs-color-switcher [colors]=\"presetColors()\"\n [selectedColor]=\"layer['fill'] || '#000000'\"\n (colorChange)=\"updateColor($event)\"/>\n </div>\n </ng-template>\n </ngs-popover>\n </ngs-toolbar-item>\n <ngs-divider vertical/>\n }\n\n <!-- Opacity -->\n <ngs-toolbar-item>\n <button ngsIconButton\n [ngsPopoverTriggerFor]=\"opacityPopover\"\n position=\"below-center\">\n <ngs-icon name=\"fluent:blur-24-regular\"/>\n </button>\n <ngs-popover #opacityPopover>\n <ng-template ngsPopoverContent>\n <div class=\"p-4 w-60 space-y-3\">\n <div class=\"flex justify-between items-center\">\n <label class=\"text-xs font-medium uppercase text-muted-foreground\">Opacity</label>\n <span class=\"text-xs text-muted-foreground\">{{ (layer['opacity'] ?? 1) * 100 | number:'1.0-0' }}%</span>\n </div>\n <ngs-slider [min]=\"0\" [max]=\"1\" [step]=\"0.01\">\n <input ngsSliderThumb\n [value]=\"layer['opacity'] ?? 1\"\n (valueChange)=\"updateOpacity($event)\"/>\n </ngs-slider>\n </div>\n </ng-template>\n </ngs-popover>\n </ngs-toolbar-item>\n\n <!-- Font Selection for text layers -->\n @if (layer.type === 'text') {\n <ngs-toolbar-item>\n <button ngsButton reverse [ngsMenuTriggerFor]=\"fontMenu\">\n <span class=\"truncate max-w-[100px]\">{{ layer['fontFamily'] }}</span>\n <ngs-icon name=\"fluent:chevron-down-20-regular\" class=\"size-5\"/>\n </button>\n\n <ngs-menu #fontMenu=\"ngsMenu\">\n <div class=\"min-w-[200px]\">\n @for (font of fonts(); track font) {\n <button ngs-menu-item\n [selected]=\"layer['fontFamily'] === font\"\n (click)=\"updateFont(font)\">\n {{ font }}\n </button>\n }\n </div>\n </ngs-menu>\n </ngs-toolbar-item>\n\n <!-- Text Styles -->\n <ngs-toolbar-item>\n <button ngsIconButton\n [ngsPopoverTriggerFor]=\"boldPopover\"\n position=\"below-center\"\n [class.text-primary]=\"layer['fontWeight'] && layer['fontWeight'] !== 'normal' && layer['fontWeight'] !== 400\"\n title=\"Bold\">\n <ngs-icon name=\"fluent:text-bold-24-regular\"/>\n </button>\n <ngs-popover #boldPopover>\n <ng-template ngsPopoverContent>\n <div class=\"p-4 w-60 space-y-3\">\n <div class=\"flex justify-between items-center\">\n <label class=\"text-xs font-medium uppercase text-muted-foreground\">Font Weight</label>\n <span class=\"text-xs text-muted-foreground\">{{ getFontWeightName(layer['fontWeight']) }}</span>\n </div>\n <ngs-slider [min]=\"300\" [max]=\"900\" [step]=\"100\">\n <input ngsSliderThumb\n [value]=\"layer['fontWeight'] === 'bold' ? 700 : (layer['fontWeight'] === 'normal' ? 400 : (layer['fontWeight'] || 400))\"\n (valueChange)=\"updateFontWeight($event)\"/>\n </ngs-slider>\n </div>\n </ng-template>\n </ngs-popover>\n </ngs-toolbar-item>\n\n <!-- Uppercase -->\n <ngs-toolbar-item>\n <button ngsIconButton\n (click)=\"toggleUppercase()\"\n [class.text-primary]=\"layer['textCase'] === 'upper'\"\n title=\"Uppercase\">\n <ngs-icon name=\"fluent:text-case-uppercase-24-regular\"/>\n </button>\n </ngs-toolbar-item>\n\n <ngs-toolbar-item>\n <ngs-button-toggle-group multiple\n hideSelectionIndicator\n [value]=\"getTextStyle()\"\n (valueChange)=\"updateTextStyle($event)\">\n <ngs-button-toggle value=\"italic\" title=\"Italic\">\n <ngs-icon name=\"fluent:text-italic-24-regular\"/>\n </ngs-button-toggle>\n <ngs-button-toggle value=\"underline\" title=\"Underline\">\n <ngs-icon name=\"fluent:text-underline-24-regular\"/>\n </ngs-button-toggle>\n <ngs-button-toggle value=\"line-through\" title=\"Strikethrough\">\n <ngs-icon name=\"fluent:text-strikethrough-24-regular\"/>\n </ngs-button-toggle>\n </ngs-button-toggle-group>\n </ngs-toolbar-item>\n\n <!-- Text Alignment -->\n <ngs-toolbar-item>\n <button ngsIconButton\n [ngsPopoverTriggerFor]=\"alignPopover\"\n position=\"below-center\"\n title=\"Alignment\">\n <ngs-icon [name]=\"'fluent:text-align-' + (layer['align'] || 'left') + '-24-regular'\"/>\n </button>\n <ngs-popover #alignPopover>\n <ng-template ngsPopoverContent>\n <div class=\"p-2 flex gap-1\">\n <button ngsIconButton (click)=\"updateTextAlign('left')\" [class.text-primary]=\"layer['align'] === 'left'\">\n <ngs-icon name=\"fluent:text-align-left-24-regular\"/>\n </button>\n <button ngsIconButton (click)=\"updateTextAlign('center')\" [class.text-primary]=\"layer['align'] === 'center'\">\n <ngs-icon name=\"fluent:text-align-center-24-regular\"/>\n </button>\n <button ngsIconButton (click)=\"updateTextAlign('right')\" [class.text-primary]=\"layer['align'] === 'right'\">\n <ngs-icon name=\"fluent:text-align-right-24-regular\"/>\n </button>\n <button ngsIconButton (click)=\"updateTextAlign('justify')\" [class.text-primary]=\"layer['align'] === 'justify'\">\n <ngs-icon name=\"fluent:text-align-justify-24-regular\"/>\n </button>\n </div>\n </ng-template>\n </ngs-popover>\n </ngs-toolbar-item>\n\n <!-- Spacing (Line Height & Letter Spacing) -->\n <ngs-toolbar-item>\n <button ngsIconButton\n [ngsPopoverTriggerFor]=\"spacingPopover\"\n position=\"below-center\"\n title=\"Spacing\">\n <ngs-icon name=\"fluent:text-line-spacing-24-regular\"/>\n </button>\n <ngs-popover #spacingPopover>\n <ng-template ngsPopoverContent>\n <div class=\"p-4 w-60 space-y-6\">\n <div class=\"space-y-3\">\n <div class=\"flex justify-between items-center\">\n <label class=\"text-xs font-medium uppercase text-muted-foreground\">Line Height</label>\n <span class=\"text-xs text-muted-foreground\">{{ layer['lineHeight'] || 1.2 | number:'1.1-1' }}</span>\n </div>\n <ngs-slider [min]=\"0.5\" [max]=\"3\" [step]=\"0.1\">\n <input ngsSliderThumb\n [value]=\"layer['lineHeight'] || 1.2\"\n (valueChange)=\"updateLineHeight($event)\"/>\n </ngs-slider>\n </div>\n <div class=\"space-y-3\">\n <div class=\"flex justify-between items-center\">\n <label class=\"text-xs font-medium uppercase text-muted-foreground\">Letter Spacing</label>\n <span class=\"text-xs text-muted-foreground\">{{ layer['letterSpacing'] || 0 }}</span>\n </div>\n <ngs-slider [min]=\"-5\" [max]=\"50\" [step]=\"1\">\n <input ngsSliderThumb\n [value]=\"layer['letterSpacing'] || 0\"\n (valueChange)=\"updateLetterSpacing($event)\"/>\n </ngs-slider>\n </div>\n </div>\n </ng-template>\n </ngs-popover>\n </ngs-toolbar-item>\n }\n\n @if (layer.type === 'image') {\n <ngs-toolbar-item>\n <button ngsButton reverse [ngsMenuTriggerFor]=\"flipMenu\">\n <span>Flip</span>\n <ngs-icon name=\"fluent:chevron-down-20-regular\" class=\"size-5\"/>\n </button>\n\n <ngs-menu #flipMenu=\"ngsMenu\">\n <div class=\"min-w-[150px]\">\n <button ngs-menu-item (click)=\"flipHorizontal()\">\n <ngs-icon name=\"fluent:flip-horizontal-24-regular\" class=\"mr-2\"/>\n <span>Flip horizontally</span>\n </button>\n <button ngs-menu-item (click)=\"flipVertical()\">\n <ngs-icon name=\"fluent:flip-vertical-24-regular\" class=\"mr-2\"/>\n <span>Flip vertically</span>\n </button>\n </div>\n </ngs-menu>\n </ngs-toolbar-item>\n\n <ngs-toolbar-item>\n <button ngsButton reverse [ngsMenuTriggerFor]=\"fitMenu\">\n <span>Fit to</span>\n <ngs-icon name=\"fluent:chevron-down-20-regular\" class=\"size-5\"/>\n </button>\n\n <ngs-menu #fitMenu=\"ngsMenu\">\n <div class=\"min-w-[150px]\">\n <button ngs-menu-item (click)=\"fitToPage()\">\n <span>Fit to page</span>\n </button>\n <button ngs-menu-item (click)=\"fillPage()\">\n <span>Fill page</span>\n </button>\n </div>\n </ngs-menu>\n </ngs-toolbar-item>\n }\n\n <ngs-toolbar-item>\n <button ngsButton reverse (click)=\"openEffects()\">\n <span>Effects</span>\n </button>\n </ngs-toolbar-item>\n\n <ngs-toolbar-spacer/>\n\n <!-- <ngs-divider vertical/>-->\n\n <ngs-toolbar-item>\n <button ngsIconButton (click)=\"toggleLock()\">\n <ngs-icon [name]=\"layer['locked'] ? 'fluent:lock-closed-24-regular' : 'fluent:lock-open-24-regular'\"/>\n </button>\n </ngs-toolbar-item>\n\n </ngs-toolbar>\n}\n", styles: [":host{display:contents}\n"] }]
3067
+ ], changeDetection: ChangeDetectionStrategy.OnPush, template: "@let layer = selectedLayer();\n\n@if (layer) {\n <ngs-toolbar\n class=\"h-14 z-10 bg-surface-container-lowest border-b border-border px-5 absolute top-0 left-0 right-0\">\n <!-- Color -->\n @if (showColorPicker()) {\n <ngs-toolbar-item>\n <button [ngsPopoverTriggerFor]=\"colorPopover\"\n position=\"below-center\"\n class=\"size-7 cursor-pointer hover:ring-2 hover:ring-primary rounded-full border border-border\"\n ngsRipple\n [style.backgroundColor]=\"layer['fill'] || '#000000'\">\n </button>\n <ngs-popover #colorPopover>\n <ng-template ngsPopoverContent>\n <div class=\"p-4 w-72\">\n <div class=\"text-xs font-medium uppercase text-muted-foreground mb-4\">\n {{ layer.type === 'text' ? 'Text Color' : 'Fill Color' }}\n </div>\n <ngs-color-switcher [colors]=\"presetColors()\"\n [selectedColor]=\"layer['fill'] || '#000000'\"\n (colorChange)=\"updateColor($event)\"/>\n </div>\n </ng-template>\n </ngs-popover>\n </ngs-toolbar-item>\n <ngs-divider vertical/>\n }\n\n <!-- Opacity -->\n <ngs-toolbar-item>\n <button ngsIconButton\n [ngsPopoverTriggerFor]=\"opacityPopover\"\n position=\"below-center\">\n <ngs-icon name=\"fluent:blur-24-regular\"/>\n </button>\n <ngs-popover #opacityPopover>\n <ng-template ngsPopoverContent>\n <div class=\"p-4 w-60 space-y-3\">\n <div class=\"flex justify-between items-center\">\n <label class=\"text-xs font-medium uppercase text-muted-foreground\">Opacity</label>\n <span class=\"text-xs text-muted-foreground\">{{ (layer['opacity'] ?? 1) * 100 | number:'1.0-0' }}%</span>\n </div>\n <ngs-slider [min]=\"0\" [max]=\"1\" [step]=\"0.01\">\n <input ngsSliderThumb\n [value]=\"layer['opacity'] ?? 1\"\n (valueChange)=\"updateOpacity($event)\"/>\n </ngs-slider>\n </div>\n </ng-template>\n </ngs-popover>\n </ngs-toolbar-item>\n\n <!-- Font Selection for text layers -->\n @if (layer.type === 'text') {\n <ngs-toolbar-item>\n <button ngsButton reverse [ngsMenuTriggerFor]=\"fontMenu\">\n <span class=\"truncate max-w-[100px]\">{{ layer['fontFamily'] }}</span>\n <ngs-icon name=\"fluent:chevron-down-20-regular\" class=\"size-5\"/>\n </button>\n\n <ngs-menu #fontMenu=\"ngsMenu\">\n <div class=\"min-w-[200px]\">\n @for (font of fonts(); track font) {\n <button ngs-menu-item\n [selected]=\"layer['fontFamily'] === font\"\n (click)=\"updateFont(font)\">\n {{ font }}\n </button>\n }\n </div>\n </ngs-menu>\n </ngs-toolbar-item>\n\n <!-- Text Styles -->\n <ngs-toolbar-item>\n <button ngsIconButton\n [ngsPopoverTriggerFor]=\"boldPopover\"\n position=\"below-center\"\n [class.text-primary]=\"layer['fontWeight'] && layer['fontWeight'] !== 'normal' && layer['fontWeight'] !== 400\"\n title=\"Bold\">\n <ngs-icon name=\"fluent:text-bold-24-regular\"/>\n </button>\n <ngs-popover #boldPopover>\n <ng-template ngsPopoverContent>\n <div class=\"p-4 w-60 space-y-3\">\n <div class=\"flex justify-between items-center\">\n <label class=\"text-xs font-medium uppercase text-muted-foreground\">Font Weight</label>\n <span class=\"text-xs text-muted-foreground\">{{ getFontWeightName(layer['fontWeight']) }}</span>\n </div>\n <ngs-slider [min]=\"300\" [max]=\"900\" [step]=\"100\">\n <input ngsSliderThumb\n [value]=\"layer['fontWeight'] === 'bold' ? 700 : (layer['fontWeight'] === 'normal' ? 400 : (layer['fontWeight'] || 400))\"\n (valueChange)=\"updateFontWeight($event)\"/>\n </ngs-slider>\n </div>\n </ng-template>\n </ngs-popover>\n </ngs-toolbar-item>\n\n <!-- Uppercase -->\n <ngs-toolbar-item>\n <button ngsIconButton\n (click)=\"toggleUppercase()\"\n [class.text-primary]=\"layer['textCase'] === 'upper'\"\n title=\"Uppercase\">\n <ngs-icon name=\"fluent:text-case-uppercase-24-regular\"/>\n </button>\n </ngs-toolbar-item>\n\n <ngs-toolbar-item>\n <ngs-button-toggle-group multiple\n hideSelectionIndicator\n onlyIcon\n [value]=\"getTextStyle()\"\n (valueChange)=\"updateTextStyle($event)\">\n <ngs-button-toggle value=\"italic\" title=\"Italic\">\n <ngs-icon name=\"fluent:text-italic-24-regular\"/>\n </ngs-button-toggle>\n <ngs-button-toggle value=\"underline\" title=\"Underline\">\n <ngs-icon name=\"fluent:text-underline-24-regular\"/>\n </ngs-button-toggle>\n <ngs-button-toggle value=\"line-through\" title=\"Strikethrough\">\n <ngs-icon name=\"fluent:text-strikethrough-24-regular\"/>\n </ngs-button-toggle>\n </ngs-button-toggle-group>\n </ngs-toolbar-item>\n\n <!-- Text Alignment -->\n <ngs-toolbar-item>\n <button ngsIconButton\n [ngsPopoverTriggerFor]=\"alignPopover\"\n position=\"below-center\"\n title=\"Alignment\">\n <ngs-icon [name]=\"'fluent:text-align-' + (layer['align'] || 'left') + '-24-regular'\"/>\n </button>\n <ngs-popover #alignPopover>\n <ng-template ngsPopoverContent>\n <div class=\"p-2 flex gap-1\">\n <button ngsIconButton (click)=\"updateTextAlign('left')\" [class.text-primary]=\"layer['align'] === 'left'\">\n <ngs-icon name=\"fluent:text-align-left-24-regular\"/>\n </button>\n <button ngsIconButton (click)=\"updateTextAlign('center')\" [class.text-primary]=\"layer['align'] === 'center'\">\n <ngs-icon name=\"fluent:text-align-center-24-regular\"/>\n </button>\n <button ngsIconButton (click)=\"updateTextAlign('right')\" [class.text-primary]=\"layer['align'] === 'right'\">\n <ngs-icon name=\"fluent:text-align-right-24-regular\"/>\n </button>\n <button ngsIconButton (click)=\"updateTextAlign('justify')\" [class.text-primary]=\"layer['align'] === 'justify'\">\n <ngs-icon name=\"fluent:text-align-justify-24-regular\"/>\n </button>\n </div>\n </ng-template>\n </ngs-popover>\n </ngs-toolbar-item>\n\n <!-- Spacing (Line Height & Letter Spacing) -->\n <ngs-toolbar-item>\n <button ngsIconButton\n [ngsPopoverTriggerFor]=\"spacingPopover\"\n position=\"below-center\"\n title=\"Spacing\">\n <ngs-icon name=\"fluent:text-line-spacing-24-regular\"/>\n </button>\n <ngs-popover #spacingPopover>\n <ng-template ngsPopoverContent>\n <div class=\"p-4 w-60 space-y-6\">\n <div class=\"space-y-3\">\n <div class=\"flex justify-between items-center\">\n <label class=\"text-xs font-medium uppercase text-muted-foreground\">Line Height</label>\n <span class=\"text-xs text-muted-foreground\">{{ layer['lineHeight'] || 1.2 | number:'1.1-1' }}</span>\n </div>\n <ngs-slider [min]=\"0.5\" [max]=\"3\" [step]=\"0.1\">\n <input ngsSliderThumb\n [value]=\"layer['lineHeight'] || 1.2\"\n (valueChange)=\"updateLineHeight($event)\"/>\n </ngs-slider>\n </div>\n <div class=\"space-y-3\">\n <div class=\"flex justify-between items-center\">\n <label class=\"text-xs font-medium uppercase text-muted-foreground\">Letter Spacing</label>\n <span class=\"text-xs text-muted-foreground\">{{ layer['letterSpacing'] || 0 }}</span>\n </div>\n <ngs-slider [min]=\"-5\" [max]=\"50\" [step]=\"1\">\n <input ngsSliderThumb\n [value]=\"layer['letterSpacing'] || 0\"\n (valueChange)=\"updateLetterSpacing($event)\"/>\n </ngs-slider>\n </div>\n </div>\n </ng-template>\n </ngs-popover>\n </ngs-toolbar-item>\n }\n\n @if (layer.type === 'image') {\n <ngs-toolbar-item>\n <button ngsButton reverse [ngsMenuTriggerFor]=\"flipMenu\">\n <span>Flip</span>\n <ngs-icon name=\"fluent:chevron-down-20-regular\" class=\"size-5\"/>\n </button>\n\n <ngs-menu #flipMenu=\"ngsMenu\">\n <div class=\"min-w-[150px]\">\n <button ngs-menu-item (click)=\"flipHorizontal()\">\n <ngs-icon name=\"fluent:flip-horizontal-24-regular\" class=\"mr-2\"/>\n <span>Flip horizontally</span>\n </button>\n <button ngs-menu-item (click)=\"flipVertical()\">\n <ngs-icon name=\"fluent:flip-vertical-24-regular\" class=\"mr-2\"/>\n <span>Flip vertically</span>\n </button>\n </div>\n </ngs-menu>\n </ngs-toolbar-item>\n\n <ngs-toolbar-item>\n <button ngsButton reverse [ngsMenuTriggerFor]=\"fitMenu\">\n <span>Fit to</span>\n <ngs-icon name=\"fluent:chevron-down-20-regular\" class=\"size-5\"/>\n </button>\n\n <ngs-menu #fitMenu=\"ngsMenu\">\n <div class=\"min-w-[150px]\">\n <button ngs-menu-item (click)=\"fitToPage()\">\n <span>Fit to page</span>\n </button>\n <button ngs-menu-item (click)=\"fillPage()\">\n <span>Fill page</span>\n </button>\n </div>\n </ngs-menu>\n </ngs-toolbar-item>\n }\n\n <ngs-toolbar-item>\n <button ngsButton reverse (click)=\"openEffects()\">\n <span>Effects</span>\n </button>\n </ngs-toolbar-item>\n\n <ngs-toolbar-spacer/>\n\n <!-- <ngs-divider vertical/>-->\n\n <ngs-toolbar-item>\n <button ngsIconButton (click)=\"toggleLock()\">\n <ngs-icon [name]=\"layer['locked'] ? 'fluent:lock-closed-24-regular' : 'fluent:lock-open-24-regular'\"/>\n </button>\n </ngs-toolbar-item>\n\n </ngs-toolbar>\n}\n", styles: [":host{display:contents}\n"] }]
3068
3068
  }] });
3069
3069
 
3070
3070
  class Effects {