@ng-cn/core 1.0.12 → 1.0.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/schematics/ng-add/index.js +112 -8
- package/schematics/ng-add/index.ts +124 -9
package/package.json
CHANGED
|
@@ -17,6 +17,65 @@ const ALL_COMPONENTS = [
|
|
|
17
17
|
'table', 'tabs', 'textarea', 'toast', 'toggle', 'toggle-group', 'tooltip',
|
|
18
18
|
'typography'
|
|
19
19
|
];
|
|
20
|
+
const COMPONENT_REGISTRY = {
|
|
21
|
+
accordion: { files: ['accordion.component.ts', 'accordion-content.component.ts', 'accordion-context.ts', 'accordion-item.component.ts', 'accordion-trigger.component.ts', 'index.ts'] },
|
|
22
|
+
alert: { files: ['alert.component.ts', 'alert-title.component.ts', 'alert-description.component.ts', 'alert-variants.ts', 'index.ts'] },
|
|
23
|
+
'alert-dialog': { files: ['alert-dialog.component.ts', 'alert-dialog-action.component.ts', 'alert-dialog-cancel.component.ts', 'alert-dialog-content.component.ts', 'alert-dialog-context.ts', 'alert-dialog-description.component.ts', 'alert-dialog-footer.component.ts', 'alert-dialog-header.component.ts', 'alert-dialog-title.component.ts', 'alert-dialog-trigger.component.ts', 'index.ts'] },
|
|
24
|
+
'aspect-ratio': { files: ['aspect-ratio.component.ts', 'index.ts'] },
|
|
25
|
+
avatar: { files: ['avatar.component.ts', 'avatar-fallback.component.ts', 'avatar-image.component.ts', 'ui-avatar.component.ts', 'index.ts'] },
|
|
26
|
+
badge: { files: ['badge.component.ts', 'badge-variants.ts', 'index.ts'] },
|
|
27
|
+
breadcrumb: { files: ['breadcrumb.component.ts', 'breadcrumb-ellipsis.component.ts', 'breadcrumb-item.component.ts', 'breadcrumb-link.component.ts', 'breadcrumb-list.component.ts', 'breadcrumb-page.component.ts', 'breadcrumb-separator.component.ts', 'index.ts'] },
|
|
28
|
+
button: { files: ['button.component.ts', 'button-variants.ts', 'index.ts'] },
|
|
29
|
+
'button-group': { files: ['button-group.component.ts', 'button-group-variants.ts', 'index.ts'] },
|
|
30
|
+
calendar: { files: ['calendar.component.ts', 'index.ts'] },
|
|
31
|
+
card: { files: ['card.component.ts', 'card-action.component.ts', 'card-content.component.ts', 'card-description.component.ts', 'card-footer.component.ts', 'card-header.component.ts', 'card-title.component.ts', 'index.ts'] },
|
|
32
|
+
carousel: { files: ['carousel.component.ts', 'carousel-content.component.ts', 'carousel-context.ts', 'carousel-item.component.ts', 'carousel-next.component.ts', 'carousel-previous.component.ts', 'index.ts'] },
|
|
33
|
+
chart: { files: ['chart.component.ts', 'chart-container.component.ts', 'chart-context.ts', 'chart-legend.component.ts', 'chart-legend-content.component.ts', 'chart-tooltip.component.ts', 'chart-tooltip-content.component.ts', 'index.ts'] },
|
|
34
|
+
checkbox: { files: ['checkbox.component.ts', 'index.ts'] },
|
|
35
|
+
collapsible: { files: ['collapsible.component.ts', 'collapsible-content.component.ts', 'collapsible-context.ts', 'collapsible-trigger.component.ts', 'index.ts'] },
|
|
36
|
+
combobox: { files: ['combobox.component.ts', 'combobox-content.component.ts', 'combobox-context.ts', 'combobox-empty.component.ts', 'combobox-group.component.ts', 'combobox-input.component.ts', 'combobox-item.component.ts', 'combobox-list.component.ts', 'combobox-trigger.component.ts', 'combobox-value.component.ts', 'index.ts'] },
|
|
37
|
+
command: { files: ['command.component.ts', 'command-context.ts', 'command-dialog.component.ts', 'command-empty.component.ts', 'command-group.component.ts', 'command-input.component.ts', 'command-item.component.ts', 'command-list.component.ts', 'command-separator.component.ts', 'command-shortcut.component.ts', 'index.ts'] },
|
|
38
|
+
'context-menu': { files: ['context-menu.component.ts', 'context-menu-checkbox-item.component.ts', 'context-menu-content.component.ts', 'context-menu-context.ts', 'context-menu-item.component.ts', 'context-menu-label.component.ts', 'context-menu-radio-group.component.ts', 'context-menu-radio-item.component.ts', 'context-menu-separator.component.ts', 'context-menu-shortcut.component.ts', 'context-menu-sub.component.ts', 'context-menu-sub-content.component.ts', 'context-menu-sub-trigger.component.ts', 'context-menu-trigger.component.ts', 'index.ts'] },
|
|
39
|
+
'data-table': { files: ['data-table.component.ts', 'data-table-content.component.ts', 'data-table-context.ts', 'data-table-pagination.component.ts', 'data-table-search.component.ts', 'data-table-toolbar.component.ts', 'data-table-view-options.component.ts', 'index.ts'] },
|
|
40
|
+
'date-picker': { files: ['date-picker.component.ts', 'index.ts'] },
|
|
41
|
+
dialog: { files: ['dialog.component.ts', 'dialog-close.component.ts', 'dialog-content.component.ts', 'dialog-context.ts', 'dialog-description.component.ts', 'dialog-footer.component.ts', 'dialog-header.component.ts', 'dialog-title.component.ts', 'dialog-trigger.component.ts', 'index.ts'] },
|
|
42
|
+
drawer: { files: ['drawer.component.ts', 'drawer-close.component.ts', 'drawer-content.component.ts', 'drawer-context.ts', 'drawer-description.component.ts', 'drawer-footer.component.ts', 'drawer-header.component.ts', 'drawer-title.component.ts', 'drawer-trigger.component.ts', 'index.ts'] },
|
|
43
|
+
'dropdown-menu': { files: ['dropdown-menu.component.ts', 'dropdown-menu-checkbox-item.component.ts', 'dropdown-menu-content.component.ts', 'dropdown-menu-context.ts', 'dropdown-menu-group.component.ts', 'dropdown-menu-item.component.ts', 'dropdown-menu-label.component.ts', 'dropdown-menu-radio-group.component.ts', 'dropdown-menu-radio-item.component.ts', 'dropdown-menu-separator.component.ts', 'dropdown-menu-shortcut.component.ts', 'dropdown-menu-sub.component.ts', 'dropdown-menu-sub-content.component.ts', 'dropdown-menu-sub-trigger.component.ts', 'dropdown-menu-trigger.component.ts', 'index.ts'] },
|
|
44
|
+
empty: { files: ['empty.component.ts', 'empty-action.component.ts', 'empty-description.component.ts', 'empty-icon.component.ts', 'empty-title.component.ts', 'index.ts'] },
|
|
45
|
+
form: { files: ['form.component.ts', 'form-context.ts', 'form-control.component.ts', 'form-description.component.ts', 'form-field.component.ts', 'form-item.component.ts', 'form-label.component.ts', 'form-message.component.ts', 'index.ts'] },
|
|
46
|
+
'hover-card': { files: ['hover-card.component.ts', 'hover-card-content.component.ts', 'hover-card-context.ts', 'hover-card-trigger.component.ts', 'index.ts'] },
|
|
47
|
+
input: { files: ['input.component.ts', 'index.ts'] },
|
|
48
|
+
'input-group': { files: ['input-group.component.ts', 'input-group-addon.component.ts', 'input-group-input.component.ts', 'index.ts'] },
|
|
49
|
+
'input-otp': { files: ['input-otp.component.ts', 'input-otp-context.ts', 'input-otp-group.component.ts', 'input-otp-separator.component.ts', 'input-otp-slot.component.ts', 'index.ts'] },
|
|
50
|
+
kbd: { files: ['kbd.component.ts', 'kbd-variants.ts', 'index.ts'] },
|
|
51
|
+
label: { files: ['label.component.ts', 'index.ts'] },
|
|
52
|
+
menubar: { files: ['menubar.component.ts', 'menubar-checkbox-item.component.ts', 'menubar-content.component.ts', 'menubar-context.ts', 'menubar-item.component.ts', 'menubar-label.component.ts', 'menubar-menu.component.ts', 'menubar-radio-group.component.ts', 'menubar-radio-item.component.ts', 'menubar-separator.component.ts', 'menubar-shortcut.component.ts', 'menubar-sub.component.ts', 'menubar-sub-content.component.ts', 'menubar-sub-trigger.component.ts', 'menubar-trigger.component.ts', 'index.ts'] },
|
|
53
|
+
'native-select': { files: ['native-select.component.ts', 'native-select-variants.ts', 'index.ts'] },
|
|
54
|
+
'navigation-menu': { files: ['navigation-menu.component.ts', 'navigation-menu-content.component.ts', 'navigation-menu-context.ts', 'navigation-menu-indicator.component.ts', 'navigation-menu-item.component.ts', 'navigation-menu-link.component.ts', 'navigation-menu-list.component.ts', 'navigation-menu-trigger.component.ts', 'navigation-menu-trigger-style.ts', 'navigation-menu-viewport.component.ts', 'index.ts'] },
|
|
55
|
+
pagination: { files: ['pagination.component.ts', 'pagination-content.component.ts', 'pagination-ellipsis.component.ts', 'pagination-item.component.ts', 'pagination-link.component.ts', 'pagination-next.component.ts', 'pagination-previous.component.ts', 'index.ts'] },
|
|
56
|
+
popover: { files: ['popover.component.ts', 'popover-anchor.component.ts', 'popover-content.component.ts', 'popover-context.ts', 'popover-trigger.component.ts', 'index.ts'] },
|
|
57
|
+
progress: { files: ['progress.component.ts', 'index.ts'] },
|
|
58
|
+
'radio-group': { files: ['radio-group.component.ts', 'radio-group-context.ts', 'radio-group-item.component.ts', 'index.ts'] },
|
|
59
|
+
resizable: { files: ['resizable-panel-group.component.ts', 'resizable-context.ts', 'resizable-handle.component.ts', 'resizable-panel.component.ts', 'index.ts'] },
|
|
60
|
+
'scroll-area': { files: ['scroll-area.component.ts', 'scroll-bar.component.ts', 'index.ts'] },
|
|
61
|
+
segmented: { files: ['segmented.component.ts', 'segmented-context.ts', 'segmented-item.component.ts', 'segmented-variants.ts', 'index.ts'] },
|
|
62
|
+
select: { files: ['select.component.ts', 'select-content.component.ts', 'select-context.ts', 'select-group.component.ts', 'select-item.component.ts', 'select-label.component.ts', 'select-separator.component.ts', 'select-trigger.component.ts', 'select-value.component.ts', 'index.ts'] },
|
|
63
|
+
separator: { files: ['separator.component.ts', 'index.ts'] },
|
|
64
|
+
sheet: { files: ['sheet.component.ts', 'sheet-close.component.ts', 'sheet-content.component.ts', 'sheet-context.ts', 'sheet-description.component.ts', 'sheet-footer.component.ts', 'sheet-header.component.ts', 'sheet-title.component.ts', 'sheet-trigger.component.ts', 'sheet-variants.ts', 'index.ts'] },
|
|
65
|
+
sidebar: { files: ['sidebar.component.ts', 'sidebar-content.component.ts', 'sidebar-context.ts', 'sidebar-footer.component.ts', 'sidebar-group.component.ts', 'sidebar-group-action.component.ts', 'sidebar-group-content.component.ts', 'sidebar-group-label.component.ts', 'sidebar-header.component.ts', 'sidebar-input.component.ts', 'sidebar-inset.component.ts', 'sidebar-menu.component.ts', 'sidebar-menu-action.component.ts', 'sidebar-menu-badge.component.ts', 'sidebar-menu-button.component.ts', 'sidebar-menu-item.component.ts', 'sidebar-menu-skeleton.component.ts', 'sidebar-menu-sub.component.ts', 'sidebar-menu-sub-button.component.ts', 'sidebar-menu-sub-item.component.ts', 'sidebar-provider.component.ts', 'sidebar-rail.component.ts', 'sidebar-route-active.service.ts', 'sidebar-separator.component.ts', 'sidebar-trigger.component.ts', 'index.ts'] },
|
|
66
|
+
skeleton: { files: ['skeleton.component.ts', 'index.ts'] },
|
|
67
|
+
slider: { files: ['slider.component.ts', 'index.ts'] },
|
|
68
|
+
spinner: { files: ['spinner.component.ts', 'spinner-variants.ts', 'index.ts'] },
|
|
69
|
+
switch: { files: ['switch.component.ts', 'index.ts'] },
|
|
70
|
+
table: { files: ['table.component.ts', 'table-body.component.ts', 'table-caption.component.ts', 'table-cell.component.ts', 'table-footer.component.ts', 'table-head.component.ts', 'table-header.component.ts', 'table-row.component.ts', 'index.ts'] },
|
|
71
|
+
tabs: { files: ['tabs.component.ts', 'tabs-content.component.ts', 'tabs-context.ts', 'tabs-list.component.ts', 'tabs-trigger.component.ts', 'index.ts'] },
|
|
72
|
+
textarea: { files: ['textarea.component.ts', 'index.ts'] },
|
|
73
|
+
toast: { files: ['toast.component.ts', 'toast-action.component.ts', 'toast-description.component.ts', 'toast-title.component.ts', 'toast-variants.ts', 'toast.service.ts', 'toaster.component.ts', 'index.ts'] },
|
|
74
|
+
toggle: { files: ['toggle.component.ts', 'toggle-variants.ts', 'index.ts'] },
|
|
75
|
+
'toggle-group': { files: ['toggle-group.component.ts', 'toggle-group-context.ts', 'toggle-group-item.component.ts', 'index.ts'] },
|
|
76
|
+
tooltip: { files: ['tooltip.component.ts', 'tooltip-content.component.ts', 'tooltip-context.ts', 'tooltip-provider.component.ts', 'tooltip-trigger.component.ts', 'index.ts'] },
|
|
77
|
+
typography: { files: ['typography-blockquote.component.ts', 'typography-h1.component.ts', 'typography-h2.component.ts', 'typography-h3.component.ts', 'typography-h4.component.ts', 'typography-inline-code.component.ts', 'typography-large.component.ts', 'typography-lead.component.ts', 'typography-list.component.ts', 'typography-muted.component.ts', 'typography-p.component.ts', 'typography-small.component.ts', 'index.ts'] },
|
|
78
|
+
};
|
|
20
79
|
// Registry of all utility files that need to be copied
|
|
21
80
|
const UTILS_FILES_REGISTRY = [
|
|
22
81
|
// Core utils
|
|
@@ -545,12 +604,17 @@ function ngAdd(options) {
|
|
|
545
604
|
const packageJsonPath = '/package.json';
|
|
546
605
|
if (tree.exists(packageJsonPath)) {
|
|
547
606
|
const packageJson = JSON.parse(tree.read(packageJsonPath).toString('utf-8'));
|
|
607
|
+
// Detect Angular version to determine CDK version
|
|
608
|
+
const angularCoreVersion = packageJson.dependencies?.['@angular/core'] || packageJson.devDependencies?.['@angular/core'] || '';
|
|
609
|
+
const angularMajorVersion = parseInt(angularCoreVersion.replace(/[\^~]/, '').split('.')[0], 10) || 21;
|
|
610
|
+
// Use compatible CDK version based on Angular version
|
|
611
|
+
const cdkVersion = angularMajorVersion >= 21 ? '^21.0.5' : angularMajorVersion >= 20 ? '^20.0.0' : '^19.0.0';
|
|
548
612
|
const requiredDependencies = {
|
|
549
613
|
'lucide-angular': '^0.562.0',
|
|
550
614
|
'class-variance-authority': '^0.7.1',
|
|
551
615
|
'clsx': '^2.1.1',
|
|
552
616
|
'tailwind-merge': '^3.4.0',
|
|
553
|
-
'@angular/cdk':
|
|
617
|
+
'@angular/cdk': cdkVersion,
|
|
554
618
|
'tailwindcss': '^4.1.18',
|
|
555
619
|
'@tailwindcss/postcss': '^4.1.18'
|
|
556
620
|
};
|
|
@@ -712,15 +776,55 @@ function ngAdd(options) {
|
|
|
712
776
|
else {
|
|
713
777
|
context.logger.info('📦 Selected Components');
|
|
714
778
|
}
|
|
715
|
-
//
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
779
|
+
// Actually copy the component files
|
|
780
|
+
const componentBasePath = 'node_modules/@ng-cn/core/src/app/lib/components/ui';
|
|
781
|
+
const fallbackBasePath = 'src/app/lib/components/ui';
|
|
782
|
+
let totalFilesCopied = 0;
|
|
783
|
+
for (const componentName of componentsToInstall) {
|
|
784
|
+
const componentInfo = COMPONENT_REGISTRY[componentName];
|
|
785
|
+
if (!componentInfo) {
|
|
786
|
+
context.logger.warn(` ⚠ Unknown component: ${componentName}`);
|
|
787
|
+
continue;
|
|
788
|
+
}
|
|
789
|
+
const targetComponentPath = `/src/app/lib/components/ui/${componentName}`;
|
|
790
|
+
let filesCopied = 0;
|
|
791
|
+
for (const file of componentInfo.files) {
|
|
792
|
+
// Try package path first, then fallback to local dev path
|
|
793
|
+
let sourcePath = `${componentBasePath}/${componentName}/${file}`;
|
|
794
|
+
const targetPath = `${targetComponentPath}/${file}`;
|
|
795
|
+
let content = tree.read(sourcePath);
|
|
796
|
+
if (!content) {
|
|
797
|
+
// Fallback to local development path
|
|
798
|
+
sourcePath = `${fallbackBasePath}/${componentName}/${file}`;
|
|
799
|
+
content = tree.read(sourcePath);
|
|
800
|
+
}
|
|
801
|
+
if (content) {
|
|
802
|
+
if (tree.exists(targetPath)) {
|
|
803
|
+
tree.overwrite(targetPath, content);
|
|
804
|
+
}
|
|
805
|
+
else {
|
|
806
|
+
tree.create(targetPath, content);
|
|
807
|
+
}
|
|
808
|
+
filesCopied++;
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
if (filesCopied > 0) {
|
|
812
|
+
context.logger.info(` ✓ ${componentName} (${filesCopied} files)`);
|
|
813
|
+
totalFilesCopied += filesCopied;
|
|
814
|
+
}
|
|
815
|
+
else {
|
|
816
|
+
context.logger.warn(` ⚠ ${componentName} - no files found (use: ng g @ng-cn/core:c ${componentName})`);
|
|
817
|
+
}
|
|
719
818
|
}
|
|
720
819
|
context.logger.info('');
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
820
|
+
if (totalFilesCopied > 0) {
|
|
821
|
+
context.logger.info(` 📦 ${totalFilesCopied} total files copied`);
|
|
822
|
+
}
|
|
823
|
+
else {
|
|
824
|
+
context.logger.info('💡 To copy components after install, use:');
|
|
825
|
+
context.logger.info(` ng g @ng-cn/core:component button`);
|
|
826
|
+
context.logger.info(` ng g @ng-cn/core:component card`);
|
|
827
|
+
}
|
|
724
828
|
}
|
|
725
829
|
// Success message with ASCII art banner
|
|
726
830
|
context.logger.info('');
|
|
@@ -27,6 +27,71 @@ const ALL_COMPONENTS = [
|
|
|
27
27
|
'typography'
|
|
28
28
|
];
|
|
29
29
|
|
|
30
|
+
// Component registry - maps component names to their file structure (for --components option)
|
|
31
|
+
interface ComponentInfo {
|
|
32
|
+
files: string[];
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const COMPONENT_REGISTRY: Record<string, ComponentInfo> = {
|
|
36
|
+
accordion: { files: ['accordion.component.ts', 'accordion-content.component.ts', 'accordion-context.ts', 'accordion-item.component.ts', 'accordion-trigger.component.ts', 'index.ts'] },
|
|
37
|
+
alert: { files: ['alert.component.ts', 'alert-title.component.ts', 'alert-description.component.ts', 'alert-variants.ts', 'index.ts'] },
|
|
38
|
+
'alert-dialog': { files: ['alert-dialog.component.ts', 'alert-dialog-action.component.ts', 'alert-dialog-cancel.component.ts', 'alert-dialog-content.component.ts', 'alert-dialog-context.ts', 'alert-dialog-description.component.ts', 'alert-dialog-footer.component.ts', 'alert-dialog-header.component.ts', 'alert-dialog-title.component.ts', 'alert-dialog-trigger.component.ts', 'index.ts'] },
|
|
39
|
+
'aspect-ratio': { files: ['aspect-ratio.component.ts', 'index.ts'] },
|
|
40
|
+
avatar: { files: ['avatar.component.ts', 'avatar-fallback.component.ts', 'avatar-image.component.ts', 'ui-avatar.component.ts', 'index.ts'] },
|
|
41
|
+
badge: { files: ['badge.component.ts', 'badge-variants.ts', 'index.ts'] },
|
|
42
|
+
breadcrumb: { files: ['breadcrumb.component.ts', 'breadcrumb-ellipsis.component.ts', 'breadcrumb-item.component.ts', 'breadcrumb-link.component.ts', 'breadcrumb-list.component.ts', 'breadcrumb-page.component.ts', 'breadcrumb-separator.component.ts', 'index.ts'] },
|
|
43
|
+
button: { files: ['button.component.ts', 'button-variants.ts', 'index.ts'] },
|
|
44
|
+
'button-group': { files: ['button-group.component.ts', 'button-group-variants.ts', 'index.ts'] },
|
|
45
|
+
calendar: { files: ['calendar.component.ts', 'index.ts'] },
|
|
46
|
+
card: { files: ['card.component.ts', 'card-action.component.ts', 'card-content.component.ts', 'card-description.component.ts', 'card-footer.component.ts', 'card-header.component.ts', 'card-title.component.ts', 'index.ts'] },
|
|
47
|
+
carousel: { files: ['carousel.component.ts', 'carousel-content.component.ts', 'carousel-context.ts', 'carousel-item.component.ts', 'carousel-next.component.ts', 'carousel-previous.component.ts', 'index.ts'] },
|
|
48
|
+
chart: { files: ['chart.component.ts', 'chart-container.component.ts', 'chart-context.ts', 'chart-legend.component.ts', 'chart-legend-content.component.ts', 'chart-tooltip.component.ts', 'chart-tooltip-content.component.ts', 'index.ts'] },
|
|
49
|
+
checkbox: { files: ['checkbox.component.ts', 'index.ts'] },
|
|
50
|
+
collapsible: { files: ['collapsible.component.ts', 'collapsible-content.component.ts', 'collapsible-context.ts', 'collapsible-trigger.component.ts', 'index.ts'] },
|
|
51
|
+
combobox: { files: ['combobox.component.ts', 'combobox-content.component.ts', 'combobox-context.ts', 'combobox-empty.component.ts', 'combobox-group.component.ts', 'combobox-input.component.ts', 'combobox-item.component.ts', 'combobox-list.component.ts', 'combobox-trigger.component.ts', 'combobox-value.component.ts', 'index.ts'] },
|
|
52
|
+
command: { files: ['command.component.ts', 'command-context.ts', 'command-dialog.component.ts', 'command-empty.component.ts', 'command-group.component.ts', 'command-input.component.ts', 'command-item.component.ts', 'command-list.component.ts', 'command-separator.component.ts', 'command-shortcut.component.ts', 'index.ts'] },
|
|
53
|
+
'context-menu': { files: ['context-menu.component.ts', 'context-menu-checkbox-item.component.ts', 'context-menu-content.component.ts', 'context-menu-context.ts', 'context-menu-item.component.ts', 'context-menu-label.component.ts', 'context-menu-radio-group.component.ts', 'context-menu-radio-item.component.ts', 'context-menu-separator.component.ts', 'context-menu-shortcut.component.ts', 'context-menu-sub.component.ts', 'context-menu-sub-content.component.ts', 'context-menu-sub-trigger.component.ts', 'context-menu-trigger.component.ts', 'index.ts'] },
|
|
54
|
+
'data-table': { files: ['data-table.component.ts', 'data-table-content.component.ts', 'data-table-context.ts', 'data-table-pagination.component.ts', 'data-table-search.component.ts', 'data-table-toolbar.component.ts', 'data-table-view-options.component.ts', 'index.ts'] },
|
|
55
|
+
'date-picker': { files: ['date-picker.component.ts', 'index.ts'] },
|
|
56
|
+
dialog: { files: ['dialog.component.ts', 'dialog-close.component.ts', 'dialog-content.component.ts', 'dialog-context.ts', 'dialog-description.component.ts', 'dialog-footer.component.ts', 'dialog-header.component.ts', 'dialog-title.component.ts', 'dialog-trigger.component.ts', 'index.ts'] },
|
|
57
|
+
drawer: { files: ['drawer.component.ts', 'drawer-close.component.ts', 'drawer-content.component.ts', 'drawer-context.ts', 'drawer-description.component.ts', 'drawer-footer.component.ts', 'drawer-header.component.ts', 'drawer-title.component.ts', 'drawer-trigger.component.ts', 'index.ts'] },
|
|
58
|
+
'dropdown-menu': { files: ['dropdown-menu.component.ts', 'dropdown-menu-checkbox-item.component.ts', 'dropdown-menu-content.component.ts', 'dropdown-menu-context.ts', 'dropdown-menu-group.component.ts', 'dropdown-menu-item.component.ts', 'dropdown-menu-label.component.ts', 'dropdown-menu-radio-group.component.ts', 'dropdown-menu-radio-item.component.ts', 'dropdown-menu-separator.component.ts', 'dropdown-menu-shortcut.component.ts', 'dropdown-menu-sub.component.ts', 'dropdown-menu-sub-content.component.ts', 'dropdown-menu-sub-trigger.component.ts', 'dropdown-menu-trigger.component.ts', 'index.ts'] },
|
|
59
|
+
empty: { files: ['empty.component.ts', 'empty-action.component.ts', 'empty-description.component.ts', 'empty-icon.component.ts', 'empty-title.component.ts', 'index.ts'] },
|
|
60
|
+
form: { files: ['form.component.ts', 'form-context.ts', 'form-control.component.ts', 'form-description.component.ts', 'form-field.component.ts', 'form-item.component.ts', 'form-label.component.ts', 'form-message.component.ts', 'index.ts'] },
|
|
61
|
+
'hover-card': { files: ['hover-card.component.ts', 'hover-card-content.component.ts', 'hover-card-context.ts', 'hover-card-trigger.component.ts', 'index.ts'] },
|
|
62
|
+
input: { files: ['input.component.ts', 'index.ts'] },
|
|
63
|
+
'input-group': { files: ['input-group.component.ts', 'input-group-addon.component.ts', 'input-group-input.component.ts', 'index.ts'] },
|
|
64
|
+
'input-otp': { files: ['input-otp.component.ts', 'input-otp-context.ts', 'input-otp-group.component.ts', 'input-otp-separator.component.ts', 'input-otp-slot.component.ts', 'index.ts'] },
|
|
65
|
+
kbd: { files: ['kbd.component.ts', 'kbd-variants.ts', 'index.ts'] },
|
|
66
|
+
label: { files: ['label.component.ts', 'index.ts'] },
|
|
67
|
+
menubar: { files: ['menubar.component.ts', 'menubar-checkbox-item.component.ts', 'menubar-content.component.ts', 'menubar-context.ts', 'menubar-item.component.ts', 'menubar-label.component.ts', 'menubar-menu.component.ts', 'menubar-radio-group.component.ts', 'menubar-radio-item.component.ts', 'menubar-separator.component.ts', 'menubar-shortcut.component.ts', 'menubar-sub.component.ts', 'menubar-sub-content.component.ts', 'menubar-sub-trigger.component.ts', 'menubar-trigger.component.ts', 'index.ts'] },
|
|
68
|
+
'native-select': { files: ['native-select.component.ts', 'native-select-variants.ts', 'index.ts'] },
|
|
69
|
+
'navigation-menu': { files: ['navigation-menu.component.ts', 'navigation-menu-content.component.ts', 'navigation-menu-context.ts', 'navigation-menu-indicator.component.ts', 'navigation-menu-item.component.ts', 'navigation-menu-link.component.ts', 'navigation-menu-list.component.ts', 'navigation-menu-trigger.component.ts', 'navigation-menu-trigger-style.ts', 'navigation-menu-viewport.component.ts', 'index.ts'] },
|
|
70
|
+
pagination: { files: ['pagination.component.ts', 'pagination-content.component.ts', 'pagination-ellipsis.component.ts', 'pagination-item.component.ts', 'pagination-link.component.ts', 'pagination-next.component.ts', 'pagination-previous.component.ts', 'index.ts'] },
|
|
71
|
+
popover: { files: ['popover.component.ts', 'popover-anchor.component.ts', 'popover-content.component.ts', 'popover-context.ts', 'popover-trigger.component.ts', 'index.ts'] },
|
|
72
|
+
progress: { files: ['progress.component.ts', 'index.ts'] },
|
|
73
|
+
'radio-group': { files: ['radio-group.component.ts', 'radio-group-context.ts', 'radio-group-item.component.ts', 'index.ts'] },
|
|
74
|
+
resizable: { files: ['resizable-panel-group.component.ts', 'resizable-context.ts', 'resizable-handle.component.ts', 'resizable-panel.component.ts', 'index.ts'] },
|
|
75
|
+
'scroll-area': { files: ['scroll-area.component.ts', 'scroll-bar.component.ts', 'index.ts'] },
|
|
76
|
+
segmented: { files: ['segmented.component.ts', 'segmented-context.ts', 'segmented-item.component.ts', 'segmented-variants.ts', 'index.ts'] },
|
|
77
|
+
select: { files: ['select.component.ts', 'select-content.component.ts', 'select-context.ts', 'select-group.component.ts', 'select-item.component.ts', 'select-label.component.ts', 'select-separator.component.ts', 'select-trigger.component.ts', 'select-value.component.ts', 'index.ts'] },
|
|
78
|
+
separator: { files: ['separator.component.ts', 'index.ts'] },
|
|
79
|
+
sheet: { files: ['sheet.component.ts', 'sheet-close.component.ts', 'sheet-content.component.ts', 'sheet-context.ts', 'sheet-description.component.ts', 'sheet-footer.component.ts', 'sheet-header.component.ts', 'sheet-title.component.ts', 'sheet-trigger.component.ts', 'sheet-variants.ts', 'index.ts'] },
|
|
80
|
+
sidebar: { files: ['sidebar.component.ts', 'sidebar-content.component.ts', 'sidebar-context.ts', 'sidebar-footer.component.ts', 'sidebar-group.component.ts', 'sidebar-group-action.component.ts', 'sidebar-group-content.component.ts', 'sidebar-group-label.component.ts', 'sidebar-header.component.ts', 'sidebar-input.component.ts', 'sidebar-inset.component.ts', 'sidebar-menu.component.ts', 'sidebar-menu-action.component.ts', 'sidebar-menu-badge.component.ts', 'sidebar-menu-button.component.ts', 'sidebar-menu-item.component.ts', 'sidebar-menu-skeleton.component.ts', 'sidebar-menu-sub.component.ts', 'sidebar-menu-sub-button.component.ts', 'sidebar-menu-sub-item.component.ts', 'sidebar-provider.component.ts', 'sidebar-rail.component.ts', 'sidebar-route-active.service.ts', 'sidebar-separator.component.ts', 'sidebar-trigger.component.ts', 'index.ts'] },
|
|
81
|
+
skeleton: { files: ['skeleton.component.ts', 'index.ts'] },
|
|
82
|
+
slider: { files: ['slider.component.ts', 'index.ts'] },
|
|
83
|
+
spinner: { files: ['spinner.component.ts', 'spinner-variants.ts', 'index.ts'] },
|
|
84
|
+
switch: { files: ['switch.component.ts', 'index.ts'] },
|
|
85
|
+
table: { files: ['table.component.ts', 'table-body.component.ts', 'table-caption.component.ts', 'table-cell.component.ts', 'table-footer.component.ts', 'table-head.component.ts', 'table-header.component.ts', 'table-row.component.ts', 'index.ts'] },
|
|
86
|
+
tabs: { files: ['tabs.component.ts', 'tabs-content.component.ts', 'tabs-context.ts', 'tabs-list.component.ts', 'tabs-trigger.component.ts', 'index.ts'] },
|
|
87
|
+
textarea: { files: ['textarea.component.ts', 'index.ts'] },
|
|
88
|
+
toast: { files: ['toast.component.ts', 'toast-action.component.ts', 'toast-description.component.ts', 'toast-title.component.ts', 'toast-variants.ts', 'toast.service.ts', 'toaster.component.ts', 'index.ts'] },
|
|
89
|
+
toggle: { files: ['toggle.component.ts', 'toggle-variants.ts', 'index.ts'] },
|
|
90
|
+
'toggle-group': { files: ['toggle-group.component.ts', 'toggle-group-context.ts', 'toggle-group-item.component.ts', 'index.ts'] },
|
|
91
|
+
tooltip: { files: ['tooltip.component.ts', 'tooltip-content.component.ts', 'tooltip-context.ts', 'tooltip-provider.component.ts', 'tooltip-trigger.component.ts', 'index.ts'] },
|
|
92
|
+
typography: { files: ['typography-blockquote.component.ts', 'typography-h1.component.ts', 'typography-h2.component.ts', 'typography-h3.component.ts', 'typography-h4.component.ts', 'typography-inline-code.component.ts', 'typography-large.component.ts', 'typography-lead.component.ts', 'typography-list.component.ts', 'typography-muted.component.ts', 'typography-p.component.ts', 'typography-small.component.ts', 'index.ts'] },
|
|
93
|
+
};
|
|
94
|
+
|
|
30
95
|
// Registry of all utility files that need to be copied
|
|
31
96
|
const UTILS_FILES_REGISTRY = [
|
|
32
97
|
// Core utils
|
|
@@ -594,12 +659,19 @@ export function ngAdd(options: NgAddOptions): Rule {
|
|
|
594
659
|
if (tree.exists(packageJsonPath)) {
|
|
595
660
|
const packageJson = JSON.parse(tree.read(packageJsonPath)!.toString('utf-8'));
|
|
596
661
|
|
|
597
|
-
|
|
662
|
+
// Detect Angular version to determine CDK version
|
|
663
|
+
const angularCoreVersion = packageJson.dependencies?.['@angular/core'] || packageJson.devDependencies?.['@angular/core'] || '';
|
|
664
|
+
const angularMajorVersion = parseInt(angularCoreVersion.replace(/[\^~]/, '').split('.')[0], 10) || 21;
|
|
665
|
+
|
|
666
|
+
// Use compatible CDK version based on Angular version
|
|
667
|
+
const cdkVersion = angularMajorVersion >= 21 ? '^21.0.5' : angularMajorVersion >= 20 ? '^20.0.0' : '^19.0.0';
|
|
668
|
+
|
|
669
|
+
const requiredDependencies: Record<string, string> = {
|
|
598
670
|
'lucide-angular': '^0.562.0',
|
|
599
671
|
'class-variance-authority': '^0.7.1',
|
|
600
672
|
'clsx': '^2.1.1',
|
|
601
673
|
'tailwind-merge': '^3.4.0',
|
|
602
|
-
'@angular/cdk':
|
|
674
|
+
'@angular/cdk': cdkVersion,
|
|
603
675
|
'tailwindcss': '^4.1.18',
|
|
604
676
|
'@tailwindcss/postcss': '^4.1.18'
|
|
605
677
|
};
|
|
@@ -779,16 +851,59 @@ export function ngAdd(options: NgAddOptions): Rule {
|
|
|
779
851
|
context.logger.info('📦 Selected Components');
|
|
780
852
|
}
|
|
781
853
|
|
|
782
|
-
//
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
854
|
+
// Actually copy the component files
|
|
855
|
+
const componentBasePath = 'node_modules/@ng-cn/core/src/app/lib/components/ui';
|
|
856
|
+
const fallbackBasePath = 'src/app/lib/components/ui';
|
|
857
|
+
let totalFilesCopied = 0;
|
|
858
|
+
|
|
859
|
+
for (const componentName of componentsToInstall) {
|
|
860
|
+
const componentInfo = COMPONENT_REGISTRY[componentName];
|
|
861
|
+
if (!componentInfo) {
|
|
862
|
+
context.logger.warn(` ⚠ Unknown component: ${componentName}`);
|
|
863
|
+
continue;
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
const targetComponentPath = `/src/app/lib/components/ui/${componentName}`;
|
|
867
|
+
let filesCopied = 0;
|
|
868
|
+
|
|
869
|
+
for (const file of componentInfo.files) {
|
|
870
|
+
// Try package path first, then fallback to local dev path
|
|
871
|
+
let sourcePath = `${componentBasePath}/${componentName}/${file}`;
|
|
872
|
+
const targetPath = `${targetComponentPath}/${file}`;
|
|
873
|
+
|
|
874
|
+
let content = tree.read(sourcePath);
|
|
875
|
+
if (!content) {
|
|
876
|
+
// Fallback to local development path
|
|
877
|
+
sourcePath = `${fallbackBasePath}/${componentName}/${file}`;
|
|
878
|
+
content = tree.read(sourcePath);
|
|
879
|
+
}
|
|
880
|
+
|
|
881
|
+
if (content) {
|
|
882
|
+
if (tree.exists(targetPath)) {
|
|
883
|
+
tree.overwrite(targetPath, content);
|
|
884
|
+
} else {
|
|
885
|
+
tree.create(targetPath, content);
|
|
886
|
+
}
|
|
887
|
+
filesCopied++;
|
|
888
|
+
}
|
|
889
|
+
}
|
|
890
|
+
|
|
891
|
+
if (filesCopied > 0) {
|
|
892
|
+
context.logger.info(` ✓ ${componentName} (${filesCopied} files)`);
|
|
893
|
+
totalFilesCopied += filesCopied;
|
|
894
|
+
} else {
|
|
895
|
+
context.logger.warn(` ⚠ ${componentName} - no files found (use: ng g @ng-cn/core:c ${componentName})`);
|
|
896
|
+
}
|
|
786
897
|
}
|
|
787
898
|
|
|
788
899
|
context.logger.info('');
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
900
|
+
if (totalFilesCopied > 0) {
|
|
901
|
+
context.logger.info(` 📦 ${totalFilesCopied} total files copied`);
|
|
902
|
+
} else {
|
|
903
|
+
context.logger.info('💡 To copy components after install, use:');
|
|
904
|
+
context.logger.info(` ng g @ng-cn/core:component button`);
|
|
905
|
+
context.logger.info(` ng g @ng-cn/core:component card`);
|
|
906
|
+
}
|
|
792
907
|
}
|
|
793
908
|
|
|
794
909
|
// Success message with ASCII art banner
|