@spartan-ng/cli 1.7.0 → 1.8.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/package.json +1 -1
  2. package/src/generators/healthcheck/healthchecks/brn-collapsible.js +3 -4
  3. package/src/generators/healthcheck/healthchecks/brn-collapsible.js.map +1 -1
  4. package/src/generators/migrate-collapsible/generator.js +3 -4
  5. package/src/generators/migrate-collapsible/generator.js.map +1 -1
  6. package/src/generators/migrate-collapsible/helm-collapsible-files.d.ts +6 -0
  7. package/src/generators/migrate-collapsible/helm-collapsible-files.js +17 -0
  8. package/src/generators/migrate-collapsible/helm-collapsible-files.js.map +1 -0
  9. package/src/generators/ui/libs/code-block/files/index.ts.template +28 -0
  10. package/src/generators/ui/libs/code-block/files/lib/hlm-code-block-actions.ts.template +16 -0
  11. package/src/generators/ui/libs/code-block/files/lib/hlm-code-block-content.ts.template +85 -0
  12. package/src/generators/ui/libs/code-block/files/lib/hlm-code-block-copy-button.ts.template +62 -0
  13. package/src/generators/ui/libs/code-block/files/lib/hlm-code-block-footer.ts.template +13 -0
  14. package/src/generators/ui/libs/code-block/files/lib/hlm-code-block-header.ts.template +16 -0
  15. package/src/generators/ui/libs/code-block/files/lib/hlm-code-block-line.ts.template +42 -0
  16. package/src/generators/ui/libs/code-block/files/lib/hlm-code-block-title.ts.template +16 -0
  17. package/src/generators/ui/libs/code-block/files/lib/hlm-code-block.ts.template +34 -0
  18. package/src/generators/ui/libs/code-block/generator.d.ts +3 -0
  19. package/src/generators/ui/libs/code-block/generator.js +9 -0
  20. package/src/generators/ui/libs/code-block/generator.js.map +1 -0
  21. package/src/generators/ui/libs/trace/files/index.ts.template +28 -0
  22. package/src/generators/ui/libs/trace/files/lib/hlm-trace-collapsible-content.ts.template +34 -0
  23. package/src/generators/ui/libs/trace/files/lib/hlm-trace-collapsible-trigger.ts.template +31 -0
  24. package/src/generators/ui/libs/trace/files/lib/hlm-trace-collapsible.ts.template +21 -0
  25. package/src/generators/ui/libs/trace/files/lib/hlm-trace-description.ts.template +13 -0
  26. package/src/generators/ui/libs/trace/files/lib/hlm-trace-icon.ts.template +13 -0
  27. package/src/generators/ui/libs/trace/files/lib/hlm-trace-line.ts.template +18 -0
  28. package/src/generators/ui/libs/trace/files/lib/hlm-trace-title.ts.template +13 -0
  29. package/src/generators/ui/libs/trace/files/lib/hlm-trace.ts.template +16 -0
  30. package/src/generators/ui/libs/trace/generator.d.ts +3 -0
  31. package/src/generators/ui/libs/trace/generator.js +9 -0
  32. package/src/generators/ui/libs/trace/generator.js.map +1 -0
  33. package/src/generators/ui/primitive-deps.js +2 -0
  34. package/src/generators/ui/primitive-deps.js.map +1 -1
  35. package/src/generators/ui/primitives.d.ts +1 -1
  36. package/src/generators/ui/style-luma.css +78 -0
  37. package/src/generators/ui/style-lyra.css +74 -0
  38. package/src/generators/ui/style-maia.css +74 -0
  39. package/src/generators/ui/style-mira.css +73 -0
  40. package/src/generators/ui/style-nova.css +74 -0
  41. package/src/generators/ui/style-vega.css +74 -0
  42. package/src/generators/ui/supported-ui-libraries.json +63 -43
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spartan-ng/cli",
3
- "version": "1.7.0",
3
+ "version": "1.8.0-beta.1",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/spartan-ng/spartan.git"
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.brainCollapsibleHealthcheck = void 0;
4
4
  const devkit_1 = require("@nx/devkit");
5
5
  const generator_1 = require("../../migrate-collapsible/generator");
6
+ const helm_collapsible_files_1 = require("../../migrate-collapsible/helm-collapsible-files");
6
7
  const healthchecks_1 = require("../healthchecks");
7
8
  exports.brainCollapsibleHealthcheck = {
8
9
  name: 'Brain Collapsible',
@@ -12,10 +13,8 @@ exports.brainCollapsibleHealthcheck = {
12
13
  if (!file.endsWith('.ts') && !file.endsWith('.html')) {
13
14
  return;
14
15
  }
15
- // skip HlmCollapsible itself
16
- if (file.endsWith('hlm-collapsible.ts') ||
17
- file.endsWith('hlm-collapsible-trigger.ts') ||
18
- file.endsWith('hlm-collapsible-content.ts')) {
16
+ // skip the Helm Collapsible and Trace implementations
17
+ if (helm_collapsible_files_1.HELM_COLLAPSIBLE_FILES.some((name) => file.endsWith(name))) {
19
18
  return;
20
19
  }
21
20
  const contents = tree.read(file, 'utf-8');
@@ -1 +1 @@
1
- {"version":3,"file":"brn-collapsible.js","sourceRoot":"","sources":["../../../../../../../libs/cli/src/generators/healthcheck/healthchecks/brn-collapsible.ts"],"names":[],"mappings":";;;AAAA,uCAAkD;AAClD,mEAAkF;AAClF,kDAAwE;AAE3D,QAAA,2BAA2B,GAAgB;IACvD,IAAI,EAAE,mBAAmB;IACzB,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO;QACzB,IAAA,6BAAoB,EAAC,IAAI,EAAE,GAAG,EAAE,CAAC,IAAI,EAAE,EAAE;YACxC,2DAA2D;YAC3D,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;gBACtD,OAAO;YACR,CAAC;YAED,6BAA6B;YAC7B,IACC,IAAI,CAAC,QAAQ,CAAC,oBAAoB,CAAC;gBACnC,IAAI,CAAC,QAAQ,CAAC,4BAA4B,CAAC;gBAC3C,IAAI,CAAC,QAAQ,CAAC,4BAA4B,CAAC,EAC1C,CAAC;gBACF,OAAO;YACR,CAAC;YAED,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YAE1C,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACf,OAAO;YACR,CAAC;YAED,IAAI,QAAQ,CAAC,QAAQ,CAAC,iCAAiC,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,CAAC;gBAClG,OAAO,CACN,0FAA0F,EAC1F,kCAAmB,CAAC,KAAK,EACzB,IAAI,CACJ,CAAC;YACH,CAAC;QACF,CAAC,CAAC,CAAC;IACJ,CAAC;IACD,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;QACnB,MAAM,IAAA,uCAA2B,EAAC,IAAI,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;QAC9D,OAAO,IAAI,CAAC;IACb,CAAC;IACD,MAAM,EAAE,+DAA+D;CACvE,CAAC"}
1
+ {"version":3,"file":"brn-collapsible.js","sourceRoot":"","sources":["../../../../../../../libs/cli/src/generators/healthcheck/healthchecks/brn-collapsible.ts"],"names":[],"mappings":";;;AAAA,uCAAkD;AAClD,mEAAkF;AAClF,6FAA0F;AAC1F,kDAAwE;AAE3D,QAAA,2BAA2B,GAAgB;IACvD,IAAI,EAAE,mBAAmB;IACzB,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO;QACzB,IAAA,6BAAoB,EAAC,IAAI,EAAE,GAAG,EAAE,CAAC,IAAI,EAAE,EAAE;YACxC,2DAA2D;YAC3D,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;gBACtD,OAAO;YACR,CAAC;YAED,sDAAsD;YACtD,IAAI,+CAAsB,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;gBAChE,OAAO;YACR,CAAC;YAED,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YAE1C,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACf,OAAO;YACR,CAAC;YAED,IAAI,QAAQ,CAAC,QAAQ,CAAC,iCAAiC,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,CAAC;gBAClG,OAAO,CACN,0FAA0F,EAC1F,kCAAmB,CAAC,KAAK,EACzB,IAAI,CACJ,CAAC;YACH,CAAC;QACF,CAAC,CAAC,CAAC;IACJ,CAAC;IACD,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;QACnB,MAAM,IAAA,uCAA2B,EAAC,IAAI,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;QAC9D,OAAO,IAAI,CAAC;IACb,CAAC;IACD,MAAM,EAAE,+DAA+D;CACvE,CAAC"}
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.migrateCollapsibleGenerator = migrateCollapsibleGenerator;
4
4
  const devkit_1 = require("@nx/devkit");
5
5
  const visit_files_1 = require("../../utils/visit-files");
6
+ const helm_collapsible_files_1 = require("./helm-collapsible-files");
6
7
  async function migrateCollapsibleGenerator(tree, { skipFormat }) {
7
8
  updateImports(tree);
8
9
  replaceSelector(tree);
@@ -15,10 +16,8 @@ async function migrateCollapsibleGenerator(tree, { skipFormat }) {
15
16
  */
16
17
  function updateImports(tree) {
17
18
  (0, visit_files_1.visitFiles)(tree, '/', (path) => {
18
- // skip HlmCollapsible itself
19
- if (path.endsWith('hlm-collapsible.ts') ||
20
- path.endsWith('hlm-collapsible-trigger.ts') ||
21
- path.endsWith('hlm-collapsible-content.ts')) {
19
+ // skip the Helm Collapsible and Trace implementations
20
+ if (helm_collapsible_files_1.HELM_COLLAPSIBLE_FILES.some((name) => path.endsWith(name))) {
22
21
  return;
23
22
  }
24
23
  const content = tree.read(path, 'utf-8');
@@ -1 +1 @@
1
- {"version":3,"file":"generator.js","sourceRoot":"","sources":["../../../../../../libs/cli/src/generators/migrate-collapsible/generator.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"generator.js","sourceRoot":"","sources":["../../../../../../libs/cli/src/generators/migrate-collapsible/generator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Helm components that intentionally wrap the brain collapsible directives as host directives (to
3
+ * expose their inputs). They are not consumers of the deprecated `<brn-collapsible>` component, so
4
+ * both the healthcheck and the migration must skip them.
5
+ */
6
+ export declare const HELM_COLLAPSIBLE_FILES: string[];
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HELM_COLLAPSIBLE_FILES = void 0;
4
+ /**
5
+ * Helm components that intentionally wrap the brain collapsible directives as host directives (to
6
+ * expose their inputs). They are not consumers of the deprecated `<brn-collapsible>` component, so
7
+ * both the healthcheck and the migration must skip them.
8
+ */
9
+ exports.HELM_COLLAPSIBLE_FILES = [
10
+ 'hlm-collapsible.ts',
11
+ 'hlm-collapsible-trigger.ts',
12
+ 'hlm-collapsible-content.ts',
13
+ 'hlm-trace-collapsible.ts',
14
+ 'hlm-trace-collapsible-trigger.ts',
15
+ 'hlm-trace-collapsible-content.ts',
16
+ ];
17
+ //# sourceMappingURL=helm-collapsible-files.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helm-collapsible-files.js","sourceRoot":"","sources":["../../../../../../libs/cli/src/generators/migrate-collapsible/helm-collapsible-files.ts"],"names":[],"mappings":";;;AAAA;;;;GAIG;AACU,QAAA,sBAAsB,GAAG;IACrC,oBAAoB;IACpB,4BAA4B;IAC5B,4BAA4B;IAC5B,0BAA0B;IAC1B,kCAAkC;IAClC,kCAAkC;CAClC,CAAC"}
@@ -0,0 +1,28 @@
1
+ import { HlmCodeBlock } from './lib/hlm-code-block';
2
+ import { HlmCodeBlockActions } from './lib/hlm-code-block-actions';
3
+ import { HlmCodeBlockContent } from './lib/hlm-code-block-content';
4
+ import { HlmCodeBlockCopyButton } from './lib/hlm-code-block-copy-button';
5
+ import { HlmCodeBlockFooter } from './lib/hlm-code-block-footer';
6
+ import { HlmCodeBlockHeader } from './lib/hlm-code-block-header';
7
+ import { HlmCodeBlockLine } from './lib/hlm-code-block-line';
8
+ import { HlmCodeBlockTitle } from './lib/hlm-code-block-title';
9
+
10
+ export * from './lib/hlm-code-block';
11
+ export * from './lib/hlm-code-block-actions';
12
+ export * from './lib/hlm-code-block-content';
13
+ export * from './lib/hlm-code-block-copy-button';
14
+ export * from './lib/hlm-code-block-footer';
15
+ export * from './lib/hlm-code-block-header';
16
+ export * from './lib/hlm-code-block-line';
17
+ export * from './lib/hlm-code-block-title';
18
+
19
+ export const HlmCodeBlockImports = [
20
+ HlmCodeBlock,
21
+ HlmCodeBlockActions,
22
+ HlmCodeBlockContent,
23
+ HlmCodeBlockCopyButton,
24
+ HlmCodeBlockFooter,
25
+ HlmCodeBlockHeader,
26
+ HlmCodeBlockLine,
27
+ HlmCodeBlockTitle,
28
+ ] as const;
@@ -0,0 +1,16 @@
1
+ import { Directive } from '@angular/core';
2
+ import { classes } from '<%- importAlias %>/utils';
3
+
4
+ @Directive({
5
+ selector: '[hlmCodeBlockActions],hlm-code-block-actions',
6
+ exportAs: 'hlmCodeBlockActions',
7
+ host: { 'data-slot': 'code-block-actions' },
8
+ })
9
+ export class HlmCodeBlockActions {
10
+ constructor() {
11
+ classes(
12
+ () =>
13
+ 'spartan-code-block-actions ms-auto flex shrink-0 items-center [[data-slot=code-block]>&]:absolute [[data-slot=code-block]>&]:z-10 [[data-slot=code-block]>&]:opacity-0 [[data-slot=code-block]>&]:transition-opacity [[data-slot=code-block]>&]:group-focus-within/code-block:opacity-100 [[data-slot=code-block]>&]:group-hover/code-block:opacity-100 [[data-slot=code-block]>&]:pointer-coarse:opacity-100',
14
+ );
15
+ }
16
+ }
@@ -0,0 +1,85 @@
1
+ import { Directionality } from '@angular/cdk/bidi';
2
+ import { BooleanInput, NumberInput } from '@angular/cdk/coercion';
3
+ import {
4
+ booleanAttribute,
5
+ ChangeDetectionStrategy,
6
+ Component,
7
+ computed,
8
+ inject,
9
+ input,
10
+ numberAttribute,
11
+ } from '@angular/core';
12
+ import { classes } from '<%- importAlias %>/utils';
13
+ import { HlmCodeBlockLine } from './hlm-code-block-line';
14
+
15
+ @Component({
16
+ // eslint-disable-next-line @angular-eslint/component-selector
17
+ selector: 'pre[hlmCodeBlockContent]',
18
+ exportAs: 'hlmCodeBlockContent',
19
+ imports: [HlmCodeBlockLine],
20
+ changeDetection: ChangeDetectionStrategy.OnPush,
21
+ host: {
22
+ 'data-slot': 'code-block-content',
23
+ '[attr.data-wrap]': 'wrap() || null',
24
+ '[attr.data-numbered]': 'lineNumbers() || null',
25
+ '[attr.dir]': '_direction()',
26
+ '[style.counter-reset]': '_style()',
27
+ tabindex: '0',
28
+ },
29
+ template: `
30
+ <code
31
+ data-slot="code-block-code"
32
+ class="spartan-code-block-code grid min-h-lh min-w-max content-start in-data-numbered:grid-cols-[auto_1fr] in-data-wrap:min-w-0"
33
+ >
34
+ @if (_lines(); as lines) {
35
+ @for (line of lines; track $index) {
36
+ <span hlmCodeBlockLine>{{ line }}</span>
37
+ }
38
+ } @else if (_hasCode()) {
39
+ <span [textContent]="_code()"></span>
40
+ } @else {
41
+ <ng-content />
42
+ }
43
+ </code>
44
+ `,
45
+ })
46
+ export class HlmCodeBlockContent {
47
+ private readonly _dir = inject(Directionality);
48
+
49
+ protected readonly _direction = this._dir.valueSignal;
50
+
51
+ public readonly wrap = input<boolean, BooleanInput>(false, { transform: booleanAttribute });
52
+ public readonly lineNumbers = input<boolean, BooleanInput>(false, { transform: booleanAttribute });
53
+
54
+ public readonly startLine = input<number, NumberInput>(1, { transform: numberAttribute });
55
+
56
+ /** When set, the code is rendered line by line instead of projecting `<ng-content />`. */
57
+ public readonly code = input<string>();
58
+
59
+ protected readonly _code = computed(() => {
60
+ const code = this.code();
61
+ return typeof code === 'string' ? code : null;
62
+ });
63
+
64
+ protected readonly _hasCode = computed(() => this._code() !== null);
65
+
66
+ protected readonly _lines = computed(() => {
67
+ const code = this._code();
68
+ if (!this.lineNumbers() || code === null) return null;
69
+
70
+ // An empty line renders a newline so copying a selection keeps blank lines.
71
+ return code
72
+ .replace(/\n$/, '')
73
+ .split('\n')
74
+ .map((line) => (line === '' ? '\n' : line));
75
+ });
76
+
77
+ protected readonly _style = computed(() => `line ${this.startLine() - 1}`);
78
+
79
+ constructor() {
80
+ classes(
81
+ () =>
82
+ 'spartan-code-block-content scroll-fade-x data-wrap:scroll-fade-y min-h-0 min-w-0 scrollbar-thin overflow-auto text-start font-mono outline-none data-wrap:wrap-break-word data-wrap:whitespace-pre-wrap',
83
+ );
84
+ }
85
+ }
@@ -0,0 +1,62 @@
1
+ import { ChangeDetectionStrategy, Component, computed, effect, input, signal } from '@angular/core';
2
+ import { NgIcon, provideIcons } from '@ng-icons/core';
3
+ import { lucideCheck, lucideCopy } from '@ng-icons/lucide';
4
+ import { HlmButton, provideBrnButtonConfig } from '<%- importAlias %>/button';
5
+ import { classes } from '<%- importAlias %>/utils';
6
+
7
+ @Component({
8
+ // eslint-disable-next-line @angular-eslint/component-selector
9
+ selector: 'button[hlmCodeBlockCopyButton]',
10
+ exportAs: 'hlmCodeBlockCopyButton',
11
+ imports: [NgIcon],
12
+ providers: [provideIcons({ lucideCopy, lucideCheck }), provideBrnButtonConfig({ variant: 'ghost', size: 'icon-xs' })],
13
+ changeDetection: ChangeDetectionStrategy.OnPush,
14
+ hostDirectives: [{ directive: HlmButton, inputs: ['variant', 'size'] }],
15
+ host: {
16
+ type: 'button',
17
+ 'data-slot': 'code-block-copy-button',
18
+ '[attr.data-copied]': '_copied() || null',
19
+ '[attr.aria-label]': '_ariaLabel()',
20
+ '(click)': '_copy()',
21
+ },
22
+ template: `
23
+ <ng-icon [name]="_icon()" />
24
+
25
+ @if (_copied()) {
26
+ <span aria-live="polite" class="sr-only">
27
+ {{ copiedText() }}
28
+ </span>
29
+ }
30
+ `,
31
+ })
32
+ export class HlmCodeBlockCopyButton {
33
+ protected readonly _copied = signal(false);
34
+
35
+ protected readonly _icon = computed(() => (this._copied() ? 'lucideCheck' : 'lucideCopy'));
36
+
37
+ public readonly value = input<string>('');
38
+ public readonly copyText = input<string>('Copy');
39
+ public readonly copiedText = input<string>('Copied');
40
+
41
+ protected readonly _ariaLabel = computed(() => (this._copied() ? this.copiedText() : this.copyText()));
42
+
43
+ constructor() {
44
+ classes(() => 'spartan-code-block-copy-button');
45
+
46
+ effect((onCleanup) => {
47
+ if (!this._copied()) return;
48
+
49
+ const timeout = setTimeout(() => this._copied.set(false), 2000);
50
+ onCleanup(() => clearTimeout(timeout));
51
+ });
52
+ }
53
+
54
+ protected async _copy(): Promise<void> {
55
+ try {
56
+ await navigator.clipboard.writeText(this.value());
57
+ this._copied.set(true);
58
+ } catch {
59
+ // ignore clipboard errors
60
+ }
61
+ }
62
+ }
@@ -0,0 +1,13 @@
1
+ import { Directive } from '@angular/core';
2
+ import { classes } from '<%- importAlias %>/utils';
3
+
4
+ @Directive({
5
+ selector: '[hlmCodeBlockFooter],hlm-code-block-footer',
6
+ exportAs: 'hlmCodeBlockFooter',
7
+ host: { 'data-slot': 'code-block-footer' },
8
+ })
9
+ export class HlmCodeBlockFooter {
10
+ constructor() {
11
+ classes(() => 'spartan-code-block-footer flex min-w-0 shrink-0 items-center');
12
+ }
13
+ }
@@ -0,0 +1,16 @@
1
+ import { Directive } from '@angular/core';
2
+ import { classes } from '<%- importAlias %>/utils';
3
+
4
+ @Directive({
5
+ selector: '[hlmCodeBlockHeader],hlm-code-block-header',
6
+ exportAs: 'hlmCodeBlockHeader',
7
+ host: { 'data-slot': 'code-block-header' },
8
+ })
9
+ export class HlmCodeBlockHeader {
10
+ constructor() {
11
+ classes(
12
+ () =>
13
+ 'spartan-code-block-header flex min-w-0 shrink-0 items-center *:has-[>[data-slot=code-block-title]]:min-w-0',
14
+ );
15
+ }
16
+ }
@@ -0,0 +1,42 @@
1
+ import { ChangeDetectionStrategy, Component, input } from '@angular/core';
2
+ import { classes } from '<%- importAlias %>/utils';
3
+ import { cva, VariantProps } from 'class-variance-authority';
4
+
5
+ const codeBlockLineVariants = cva(
6
+ "spartan-code-block-line relative block min-h-lh after:absolute after:top-0 after:select-none in-data-numbered:col-span-2 in-data-numbered:grid in-data-numbered:grid-cols-subgrid in-data-numbered:[counter-increment:line] in-data-numbered:before:content-[counter(line)] in-data-numbered:before:select-none in-data-numbered:supports-[content:counter(line)_/_'']:before:content-[counter(line)_/_'']",
7
+ {
8
+ variants: {
9
+ variant: {
10
+ default: 'spartan-code-block-line-variant-default',
11
+ added: 'spartan-code-block-line-variant-added',
12
+ removed: 'spartan-code-block-line-variant-removed',
13
+ highlighted: 'spartan-code-block-line-variant-highlighted',
14
+ },
15
+ },
16
+ defaultVariants: {
17
+ variant: 'default',
18
+ },
19
+ },
20
+ );
21
+
22
+ type CodeBlockLineVariants = VariantProps<typeof codeBlockLineVariants>;
23
+
24
+ @Component({
25
+ // eslint-disable-next-line @angular-eslint/component-selector
26
+ selector: 'span[hlmCodeBlockLine]',
27
+ exportAs: 'hlmCodeBlockLine',
28
+ changeDetection: ChangeDetectionStrategy.OnPush,
29
+ host: { 'data-slot': 'code-block-line', '[attr.data-variant]': 'variant()' },
30
+ template: `
31
+ <span data-slot="code-block-line-content" class="min-w-0">
32
+ <ng-content />
33
+ </span>
34
+ `,
35
+ })
36
+ export class HlmCodeBlockLine {
37
+ public readonly variant = input<CodeBlockLineVariants['variant']>('default');
38
+
39
+ constructor() {
40
+ classes(() => codeBlockLineVariants({ variant: this.variant() }));
41
+ }
42
+ }
@@ -0,0 +1,16 @@
1
+ import { Directive } from '@angular/core';
2
+ import { classes } from '<%- importAlias %>/utils';
3
+
4
+ @Directive({
5
+ selector: '[hlmCodeBlockTitle],hlm-code-block-title',
6
+ exportAs: 'hlmCodeBlockTitle',
7
+ host: { 'data-slot': 'code-block-title' },
8
+ })
9
+ export class HlmCodeBlockTitle {
10
+ constructor() {
11
+ classes(
12
+ () =>
13
+ 'spartan-code-block-title min-w-0 truncate [&_ng-icon]:pointer-events-none [&_ng-icon]:inline-block [&_ng-icon]:align-middle',
14
+ );
15
+ }
16
+ }
@@ -0,0 +1,34 @@
1
+ import { Directive, input } from '@angular/core';
2
+ import { classes } from '<%- importAlias %>/utils';
3
+ import { cva, type VariantProps } from 'class-variance-authority';
4
+
5
+ const codeBlockVariants = cva(
6
+ 'spartan-code-block group/code-block relative flex w-full min-w-0 flex-col overflow-hidden',
7
+ {
8
+ variants: {
9
+ variant: {
10
+ default: 'spartan-code-block-variant-default',
11
+ destructive: 'spartan-code-block-variant-destructive',
12
+ },
13
+ },
14
+ defaultVariants: {
15
+ variant: 'default',
16
+ },
17
+ },
18
+ );
19
+
20
+ type CodeBlockVariants = VariantProps<typeof codeBlockVariants>;
21
+
22
+ @Directive({
23
+ selector: '[hlmCodeBlock],hlm-code-block',
24
+ exportAs: 'hlmCodeBlock',
25
+ host: { 'data-slot': 'code-block', '[attr.data-variant]': 'variant()', '[attr.data-size]': 'size()' },
26
+ })
27
+ export class HlmCodeBlock {
28
+ public readonly variant = input<CodeBlockVariants['variant']>('default');
29
+ public readonly size = input<'default' | 'sm'>('default');
30
+
31
+ constructor() {
32
+ classes(() => codeBlockVariants({ variant: this.variant() }));
33
+ }
34
+ }
@@ -0,0 +1,3 @@
1
+ import type { Tree } from '@nx/devkit';
2
+ import type { HlmBaseGeneratorSchema } from '../../../base/schema';
3
+ export declare function generator(tree: Tree, options: HlmBaseGeneratorSchema): Promise<import("@nx/devkit").GeneratorCallback>;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generator = generator;
4
+ const tslib_1 = require("tslib");
5
+ const generator_1 = tslib_1.__importDefault(require("../../../base/generator"));
6
+ async function generator(tree, options) {
7
+ return await (0, generator_1.default)(tree, { ...options, name: 'code-block' });
8
+ }
9
+ //# sourceMappingURL=generator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generator.js","sourceRoot":"","sources":["../../../../../../../../libs/cli/src/generators/ui/libs/code-block/generator.ts"],"names":[],"mappings":";;AAIA,8BAEC;;AALD,gFAAuD;AAGhD,KAAK,UAAU,SAAS,CAAC,IAAU,EAAE,OAA+B;IAC1E,OAAO,MAAM,IAAA,mBAAgB,EAAC,IAAI,EAAE,EAAE,GAAG,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,CAAC;AACzE,CAAC"}
@@ -0,0 +1,28 @@
1
+ import { HlmTrace } from './lib/hlm-trace';
2
+ import { HlmTraceCollapsible } from './lib/hlm-trace-collapsible';
3
+ import { HlmTraceCollapsibleContent } from './lib/hlm-trace-collapsible-content';
4
+ import { HlmTraceCollapsibleTrigger } from './lib/hlm-trace-collapsible-trigger';
5
+ import { HlmTraceDescription } from './lib/hlm-trace-description';
6
+ import { HlmTraceIcon } from './lib/hlm-trace-icon';
7
+ import { HlmTraceLine } from './lib/hlm-trace-line';
8
+ import { HlmTraceTitle } from './lib/hlm-trace-title';
9
+
10
+ export * from './lib/hlm-trace';
11
+ export * from './lib/hlm-trace-collapsible';
12
+ export * from './lib/hlm-trace-collapsible-content';
13
+ export * from './lib/hlm-trace-collapsible-trigger';
14
+ export * from './lib/hlm-trace-description';
15
+ export * from './lib/hlm-trace-icon';
16
+ export * from './lib/hlm-trace-line';
17
+ export * from './lib/hlm-trace-title';
18
+
19
+ export const HlmTraceImports = [
20
+ HlmTrace,
21
+ HlmTraceCollapsible,
22
+ HlmTraceCollapsibleContent,
23
+ HlmTraceCollapsibleTrigger,
24
+ HlmTraceDescription,
25
+ HlmTraceIcon,
26
+ HlmTraceLine,
27
+ HlmTraceTitle,
28
+ ] as const;
@@ -0,0 +1,34 @@
1
+ import { ChangeDetectionStrategy, Component, computed, input } from '@angular/core';
2
+ import { BrnCollapsibleContent } from '@spartan-ng/brain/collapsible';
3
+ import { classes, hlm } from '<%- importAlias %>/utils';
4
+ import { ClassValue } from 'clsx';
5
+
6
+ @Component({
7
+ selector: 'hlm-trace-collapsible-content',
8
+ exportAs: 'hlmTraceCollapsibleContent',
9
+ changeDetection: ChangeDetectionStrategy.OnPush,
10
+ hostDirectives: [{ directive: BrnCollapsibleContent, inputs: ['id'] }],
11
+ host: { 'data-slot': 'trace-collapsible-content' },
12
+ template: `
13
+ <div [class]="_computedContentInnerClasses()" data-slot="trace-collapsible-content-inner">
14
+ <ng-content />
15
+ </div>
16
+ `,
17
+ })
18
+ export class HlmTraceCollapsibleContent {
19
+ public readonly contentInnerClasses = input<ClassValue>();
20
+
21
+ protected readonly _computedContentInnerClasses = computed(() =>
22
+ hlm(
23
+ 'spartan-trace-collapsible-content-inner text-muted-foreground min-w-0 wrap-break-word',
24
+ this.contentInnerClasses(),
25
+ ),
26
+ );
27
+
28
+ constructor() {
29
+ classes(
30
+ () =>
31
+ 'spartan-trace-collapsible-content block min-w-0 overflow-hidden transition-[height] data-[state=closed]:h-0 data-[state=open]:h-(--brn-collapsible-content-height) motion-reduce:transition-none',
32
+ );
33
+ }
34
+ }
@@ -0,0 +1,31 @@
1
+ import { ChangeDetectionStrategy, Component } from '@angular/core';
2
+ import { NgIcon, provideIcons } from '@ng-icons/core';
3
+ import { lucideChevronRight } from '@ng-icons/lucide';
4
+ import { BrnCollapsibleTrigger } from '@spartan-ng/brain/collapsible';
5
+ import { classes } from '<%- importAlias %>/utils';
6
+
7
+ @Component({
8
+ // eslint-disable-next-line @angular-eslint/component-selector
9
+ selector: 'button[hlmTraceCollapsibleTrigger]',
10
+ exportAs: 'hlmTraceCollapsibleTrigger',
11
+ imports: [NgIcon],
12
+ providers: [provideIcons({ lucideChevronRight })],
13
+ changeDetection: ChangeDetectionStrategy.OnPush,
14
+ hostDirectives: [{ directive: BrnCollapsibleTrigger, inputs: ['type'] }],
15
+ host: { 'data-slot': 'trace-collapsible-trigger' },
16
+ template: `
17
+ <ng-content />
18
+ <ng-icon
19
+ name="lucideChevronRight"
20
+ class="transition-transform group-aria-expanded/trace-collapsible-trigger:rotate-90 motion-reduce:transition-none"
21
+ />
22
+ `,
23
+ })
24
+ export class HlmTraceCollapsibleTrigger {
25
+ constructor() {
26
+ classes(
27
+ () =>
28
+ 'spartan-trace-collapsible-trigger group/trace-collapsible-trigger text-muted-foreground hover:text-foreground has-[[data-status=error]]:text-destructive flex w-fit max-w-full min-w-0 cursor-pointer items-center text-left transition-colors outline-none',
29
+ );
30
+ }
31
+ }
@@ -0,0 +1,21 @@
1
+ import { Directive } from '@angular/core';
2
+ import { BrnCollapsible } from '@spartan-ng/brain/collapsible';
3
+ import { classes } from '<%- importAlias %>/utils';
4
+
5
+ @Directive({
6
+ selector: '[hlmTraceCollapsible],hlm-trace-collapsible',
7
+ exportAs: 'hlmTraceCollapsible',
8
+ hostDirectives: [
9
+ {
10
+ directive: BrnCollapsible,
11
+ inputs: ['expanded', 'disabled'],
12
+ outputs: ['expandedChange'],
13
+ },
14
+ ],
15
+ host: { 'data-slot': 'trace-collapsible' },
16
+ })
17
+ export class HlmTraceCollapsible {
18
+ constructor() {
19
+ classes(() => 'spartan-trace-collapsible flex w-full min-w-0 flex-col');
20
+ }
21
+ }
@@ -0,0 +1,13 @@
1
+ import { Directive } from '@angular/core';
2
+ import { classes } from '<%- importAlias %>/utils';
3
+
4
+ @Directive({
5
+ selector: '[hlmTraceDescription],hlm-trace-description',
6
+ exportAs: 'hlmTraceDescription',
7
+ host: { 'data-slot': 'trace-description' },
8
+ })
9
+ export class HlmTraceDescription {
10
+ constructor() {
11
+ classes(() => 'spartan-trace-description text-muted-foreground/70 shrink-0 tabular-nums');
12
+ }
13
+ }
@@ -0,0 +1,13 @@
1
+ import { Directive } from '@angular/core';
2
+ import { classes } from '<%- importAlias %>/utils';
3
+
4
+ @Directive({
5
+ selector: '[hlmTraceIcon],hlm-trace-icon',
6
+ exportAs: 'hlmTraceIcon',
7
+ host: { 'data-slot': 'trace-icon', '[attr.aria-hidden]': 'true' },
8
+ })
9
+ export class HlmTraceIcon {
10
+ constructor() {
11
+ classes(() => 'spartan-trace-icon flex shrink-0 items-center justify-center [&_ng-icon]:pointer-events-none');
12
+ }
13
+ }
@@ -0,0 +1,18 @@
1
+ import { Directive, input } from '@angular/core';
2
+ import { classes } from '<%- importAlias %>/utils';
3
+
4
+ @Directive({
5
+ selector: '[hlmTraceLine],hlm-trace-line',
6
+ exportAs: 'hlmTraceLine',
7
+ host: { 'data-slot': 'trace-line', '[attr.data-status]': 'status()' },
8
+ })
9
+ export class HlmTraceLine {
10
+ public readonly status = input<'running' | 'error' | 'pending'>();
11
+
12
+ constructor() {
13
+ classes(
14
+ () =>
15
+ 'spartan-trace-line text-muted-foreground [a:hover,button:hover]:text-foreground data-[status=error]:text-destructive data-[status=error]:in-[a:hover,button:hover]:text-destructive data-[status=running]:*:data-[slot=trace-title]:shimmer flex w-fit max-w-full min-w-0 items-center transition-colors data-[status=pending]:opacity-60 [a,button]:cursor-pointer',
16
+ );
17
+ }
18
+ }
@@ -0,0 +1,13 @@
1
+ import { Directive } from '@angular/core';
2
+ import { classes } from '<%- importAlias %>/utils';
3
+
4
+ @Directive({
5
+ selector: '[hlmTraceTitle],hlm-trace-title',
6
+ exportAs: 'hlmTraceTitle',
7
+ host: { 'data-slot': 'trace-title' },
8
+ })
9
+ export class HlmTraceTitle {
10
+ constructor() {
11
+ classes(() => 'spartan-trace-title motion-reduce:shimmer-none min-w-0 truncate');
12
+ }
13
+ }
@@ -0,0 +1,16 @@
1
+ import { Directive } from '@angular/core';
2
+ import { classes } from '<%- importAlias %>/utils';
3
+
4
+ @Directive({
5
+ selector: '[hlmTrace],hlm-trace',
6
+ exportAs: 'hlmTrace',
7
+ host: { 'data-slot': 'trace' },
8
+ })
9
+ export class HlmTrace {
10
+ constructor() {
11
+ classes(
12
+ () =>
13
+ 'spartan-trace flex w-full min-w-0 flex-col *:has-[>[data-slot=trace-line]]:flex *:has-[>[data-slot=trace-line]]:w-fit *:has-[>[data-slot=trace-line]]:max-w-full *:has-[>[data-slot=trace-line]]:min-w-0 *:has-[>[data-slot=trace-line]]:text-left *:has-[>[data-slot=trace-line]]:outline-none',
14
+ );
15
+ }
16
+ }