@ng-cn/core 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,214 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.component = component;
4
+ const core_1 = require("@angular-devkit/core");
5
+ const schematics_1 = require("@angular-devkit/schematics");
6
+ // Component registry - maps component names to their file structure
7
+ const COMPONENT_REGISTRY = {
8
+ accordion: {
9
+ files: ['accordion.component.ts', 'index.ts'],
10
+ dependencies: ['@angular/cdk', 'clsx', 'tailwind-merge', 'lucide-angular']
11
+ },
12
+ alert: {
13
+ files: ['alert.component.ts', 'alert-title.component.ts', 'alert-description.component.ts', 'index.ts'],
14
+ dependencies: ['class-variance-authority', 'clsx', 'tailwind-merge']
15
+ },
16
+ 'alert-dialog': {
17
+ files: ['alert-dialog.component.ts', 'index.ts'],
18
+ dependencies: ['@angular/cdk', 'clsx', 'tailwind-merge']
19
+ },
20
+ avatar: {
21
+ files: ['avatar.component.ts', 'index.ts'],
22
+ dependencies: ['clsx', 'tailwind-merge']
23
+ },
24
+ badge: {
25
+ files: ['badge.component.ts', 'index.ts'],
26
+ dependencies: ['class-variance-authority', 'clsx', 'tailwind-merge']
27
+ },
28
+ breadcrumb: {
29
+ files: ['breadcrumb.component.ts', 'index.ts'],
30
+ dependencies: ['clsx', 'tailwind-merge', 'lucide-angular']
31
+ },
32
+ button: {
33
+ files: ['button.component.ts', 'index.ts'],
34
+ dependencies: ['class-variance-authority', 'clsx', 'tailwind-merge', '@angular/cdk']
35
+ },
36
+ calendar: {
37
+ files: ['calendar.component.ts', 'index.ts'],
38
+ dependencies: ['clsx', 'tailwind-merge', 'lucide-angular']
39
+ },
40
+ card: {
41
+ files: ['card.component.ts', 'card-header.component.ts', 'card-title.component.ts', 'card-description.component.ts', 'card-content.component.ts', 'card-footer.component.ts', 'index.ts'],
42
+ dependencies: ['clsx', 'tailwind-merge']
43
+ },
44
+ checkbox: {
45
+ files: ['checkbox.component.ts', 'index.ts'],
46
+ dependencies: ['@angular/cdk', 'clsx', 'tailwind-merge', 'lucide-angular']
47
+ },
48
+ collapsible: {
49
+ files: ['collapsible.component.ts', 'index.ts'],
50
+ dependencies: ['@angular/cdk', 'clsx', 'tailwind-merge']
51
+ },
52
+ 'data-table': {
53
+ files: [
54
+ 'data-table.component.ts',
55
+ 'data-table-content.component.ts',
56
+ 'data-table-context.ts',
57
+ 'data-table-pagination.component.ts',
58
+ 'data-table-search.component.ts',
59
+ 'data-table-toolbar.component.ts',
60
+ 'data-table-view-options.component.ts',
61
+ 'index.ts'
62
+ ],
63
+ dependencies: ['clsx', 'tailwind-merge', 'lucide-angular']
64
+ },
65
+ dialog: {
66
+ files: ['dialog.component.ts', 'dialog-content.component.ts', 'dialog-header.component.ts', 'dialog-footer.component.ts', 'dialog-title.component.ts', 'dialog-description.component.ts', 'index.ts'],
67
+ dependencies: ['@angular/cdk', 'clsx', 'tailwind-merge']
68
+ },
69
+ drawer: {
70
+ files: ['drawer.component.ts', 'index.ts'],
71
+ dependencies: ['@angular/cdk', 'clsx', 'tailwind-merge']
72
+ },
73
+ 'dropdown-menu': {
74
+ files: ['dropdown-menu.component.ts', 'index.ts'],
75
+ dependencies: ['@angular/cdk', 'clsx', 'tailwind-merge']
76
+ },
77
+ input: {
78
+ files: ['input.component.ts', 'index.ts'],
79
+ dependencies: ['clsx', 'tailwind-merge', '@angular/forms']
80
+ },
81
+ label: {
82
+ files: ['label.component.ts', 'index.ts'],
83
+ dependencies: ['class-variance-authority', 'clsx', 'tailwind-merge']
84
+ },
85
+ popover: {
86
+ files: ['popover.component.ts', 'index.ts'],
87
+ dependencies: ['@angular/cdk', 'clsx', 'tailwind-merge']
88
+ },
89
+ progress: {
90
+ files: ['progress.component.ts', 'index.ts'],
91
+ dependencies: ['clsx', 'tailwind-merge']
92
+ },
93
+ 'radio-group': {
94
+ files: ['radio-group.component.ts', 'index.ts'],
95
+ dependencies: ['@angular/cdk', 'clsx', 'tailwind-merge']
96
+ },
97
+ select: {
98
+ files: ['select.component.ts', 'index.ts'],
99
+ dependencies: ['@angular/cdk', 'clsx', 'tailwind-merge', 'lucide-angular']
100
+ },
101
+ separator: {
102
+ files: ['separator.component.ts', 'index.ts'],
103
+ dependencies: ['clsx', 'tailwind-merge']
104
+ },
105
+ sheet: {
106
+ files: ['sheet.component.ts', 'index.ts'],
107
+ dependencies: ['@angular/cdk', 'clsx', 'tailwind-merge', 'lucide-angular']
108
+ },
109
+ skeleton: {
110
+ files: ['skeleton.component.ts', 'index.ts'],
111
+ dependencies: ['clsx', 'tailwind-merge']
112
+ },
113
+ slider: {
114
+ files: ['slider.component.ts', 'index.ts'],
115
+ dependencies: ['@angular/cdk', 'clsx', 'tailwind-merge']
116
+ },
117
+ switch: {
118
+ files: ['switch.component.ts', 'index.ts'],
119
+ dependencies: ['@angular/cdk', 'clsx', 'tailwind-merge']
120
+ },
121
+ table: {
122
+ files: ['table.component.ts', 'index.ts'],
123
+ dependencies: ['clsx', 'tailwind-merge']
124
+ },
125
+ tabs: {
126
+ files: ['tabs.component.ts', 'index.ts'],
127
+ dependencies: ['@angular/cdk', 'clsx', 'tailwind-merge']
128
+ },
129
+ textarea: {
130
+ files: ['textarea.component.ts', 'index.ts'],
131
+ dependencies: ['clsx', 'tailwind-merge', '@angular/forms']
132
+ },
133
+ toast: {
134
+ files: ['toast.component.ts', 'toaster.component.ts', 'toast.service.ts', 'index.ts'],
135
+ dependencies: ['clsx', 'tailwind-merge', 'lucide-angular']
136
+ },
137
+ toggle: {
138
+ files: ['toggle.component.ts', 'index.ts'],
139
+ dependencies: ['class-variance-authority', 'clsx', 'tailwind-merge']
140
+ },
141
+ tooltip: {
142
+ files: ['tooltip.component.ts', 'index.ts'],
143
+ dependencies: ['@angular/cdk', 'clsx', 'tailwind-merge']
144
+ },
145
+ };
146
+ function component(options) {
147
+ return (tree, context) => {
148
+ const componentName = options.name.toLowerCase();
149
+ if (!COMPONENT_REGISTRY[componentName]) {
150
+ const availableComponents = Object.keys(COMPONENT_REGISTRY).sort().join(', ');
151
+ throw new schematics_1.SchematicsException(`\n❌ Component "${componentName}" not found.\n\n` +
152
+ `Available components:\n${availableComponents}\n\n` +
153
+ `Usage: ng g @ng-cn/core:c <component-name>\n`);
154
+ }
155
+ const componentInfo = COMPONENT_REGISTRY[componentName];
156
+ const basePath = options.path || 'src/app/lib/components/ui';
157
+ const componentPath = (0, core_1.normalize)((0, core_1.join)((0, core_1.normalize)(basePath), (0, core_1.normalize)(componentName)));
158
+ context.logger.info('');
159
+ context.logger.info(`📦 Installing ${componentName}...`);
160
+ context.logger.info('');
161
+ // Check if component directory already exists
162
+ const firstFilePath = (0, core_1.join)(componentPath, (0, core_1.normalize)(componentInfo.files[0]));
163
+ if (tree.exists(firstFilePath) && !options.overwrite) {
164
+ context.logger.warn(`⚠️ Component already exists at ${componentPath}`);
165
+ context.logger.info(` Use --overwrite to replace existing files.`);
166
+ context.logger.info('');
167
+ return tree;
168
+ }
169
+ // Copy component files from the package source
170
+ const sourceBasePath = `node_modules/@ng-cn/core/lib/components/ui/${componentName}`;
171
+ const fallbackSourcePath = `src/app/lib/components/ui/${componentName}`;
172
+ let filesCreated = 0;
173
+ for (const file of componentInfo.files) {
174
+ let sourcePath = (0, core_1.join)((0, core_1.normalize)(sourceBasePath), (0, core_1.normalize)(file));
175
+ const targetPath = (0, core_1.join)(componentPath, (0, core_1.normalize)(file));
176
+ // Try package path first, then fallback to local dev path
177
+ let content = tree.read(sourcePath);
178
+ if (!content) {
179
+ sourcePath = (0, core_1.join)((0, core_1.normalize)(fallbackSourcePath), (0, core_1.normalize)(file));
180
+ content = tree.read(sourcePath);
181
+ }
182
+ if (content) {
183
+ if (tree.exists(targetPath)) {
184
+ tree.overwrite(targetPath, content);
185
+ }
186
+ else {
187
+ tree.create(targetPath, content);
188
+ }
189
+ context.logger.info(` ✓ ${componentName}/${file}`);
190
+ filesCreated++;
191
+ }
192
+ }
193
+ if (filesCreated === 0) {
194
+ context.logger.warn(`⚠️ No source files found for ${componentName}`);
195
+ context.logger.info(` Make sure @ng-cn/core is properly installed.`);
196
+ context.logger.info('');
197
+ return tree;
198
+ }
199
+ // Success message
200
+ context.logger.info('');
201
+ context.logger.info(`✅ ${componentName} installed successfully!`);
202
+ context.logger.info('');
203
+ context.logger.info(' Import:');
204
+ context.logger.info(` import { ${toPascalCase(componentName)} } from '@/ui/${componentName}';`);
205
+ context.logger.info('');
206
+ return tree;
207
+ };
208
+ }
209
+ function toPascalCase(str) {
210
+ return str
211
+ .split('-')
212
+ .map(word => word.charAt(0).toUpperCase() + word.slice(1))
213
+ .join('');
214
+ }
@@ -0,0 +1,238 @@
1
+ import { join, normalize, Path } from '@angular-devkit/core';
2
+ import { Rule, SchematicContext, SchematicsException, Tree } from '@angular-devkit/schematics';
3
+
4
+ interface ComponentOptions {
5
+ name: string;
6
+ project?: string;
7
+ path?: string;
8
+ overwrite?: boolean;
9
+ }
10
+
11
+ // Component registry - maps component names to their file structure
12
+ const COMPONENT_REGISTRY: Record<string, ComponentInfo> = {
13
+ accordion: {
14
+ files: ['accordion.component.ts', 'index.ts'],
15
+ dependencies: ['@angular/cdk', 'clsx', 'tailwind-merge', 'lucide-angular']
16
+ },
17
+ alert: {
18
+ files: ['alert.component.ts', 'alert-title.component.ts', 'alert-description.component.ts', 'index.ts'],
19
+ dependencies: ['class-variance-authority', 'clsx', 'tailwind-merge']
20
+ },
21
+ 'alert-dialog': {
22
+ files: ['alert-dialog.component.ts', 'index.ts'],
23
+ dependencies: ['@angular/cdk', 'clsx', 'tailwind-merge']
24
+ },
25
+ avatar: {
26
+ files: ['avatar.component.ts', 'index.ts'],
27
+ dependencies: ['clsx', 'tailwind-merge']
28
+ },
29
+ badge: {
30
+ files: ['badge.component.ts', 'index.ts'],
31
+ dependencies: ['class-variance-authority', 'clsx', 'tailwind-merge']
32
+ },
33
+ breadcrumb: {
34
+ files: ['breadcrumb.component.ts', 'index.ts'],
35
+ dependencies: ['clsx', 'tailwind-merge', 'lucide-angular']
36
+ },
37
+ button: {
38
+ files: ['button.component.ts', 'index.ts'],
39
+ dependencies: ['class-variance-authority', 'clsx', 'tailwind-merge', '@angular/cdk']
40
+ },
41
+ calendar: {
42
+ files: ['calendar.component.ts', 'index.ts'],
43
+ dependencies: ['clsx', 'tailwind-merge', 'lucide-angular']
44
+ },
45
+ card: {
46
+ files: ['card.component.ts', 'card-header.component.ts', 'card-title.component.ts', 'card-description.component.ts', 'card-content.component.ts', 'card-footer.component.ts', 'index.ts'],
47
+ dependencies: ['clsx', 'tailwind-merge']
48
+ },
49
+ checkbox: {
50
+ files: ['checkbox.component.ts', 'index.ts'],
51
+ dependencies: ['@angular/cdk', 'clsx', 'tailwind-merge', 'lucide-angular']
52
+ },
53
+ collapsible: {
54
+ files: ['collapsible.component.ts', 'index.ts'],
55
+ dependencies: ['@angular/cdk', 'clsx', 'tailwind-merge']
56
+ },
57
+ 'data-table': {
58
+ files: [
59
+ 'data-table.component.ts',
60
+ 'data-table-content.component.ts',
61
+ 'data-table-context.ts',
62
+ 'data-table-pagination.component.ts',
63
+ 'data-table-search.component.ts',
64
+ 'data-table-toolbar.component.ts',
65
+ 'data-table-view-options.component.ts',
66
+ 'index.ts'
67
+ ],
68
+ dependencies: ['clsx', 'tailwind-merge', 'lucide-angular']
69
+ },
70
+ dialog: {
71
+ files: ['dialog.component.ts', 'dialog-content.component.ts', 'dialog-header.component.ts', 'dialog-footer.component.ts', 'dialog-title.component.ts', 'dialog-description.component.ts', 'index.ts'],
72
+ dependencies: ['@angular/cdk', 'clsx', 'tailwind-merge']
73
+ },
74
+ drawer: {
75
+ files: ['drawer.component.ts', 'index.ts'],
76
+ dependencies: ['@angular/cdk', 'clsx', 'tailwind-merge']
77
+ },
78
+ 'dropdown-menu': {
79
+ files: ['dropdown-menu.component.ts', 'index.ts'],
80
+ dependencies: ['@angular/cdk', 'clsx', 'tailwind-merge']
81
+ },
82
+ input: {
83
+ files: ['input.component.ts', 'index.ts'],
84
+ dependencies: ['clsx', 'tailwind-merge', '@angular/forms']
85
+ },
86
+ label: {
87
+ files: ['label.component.ts', 'index.ts'],
88
+ dependencies: ['class-variance-authority', 'clsx', 'tailwind-merge']
89
+ },
90
+ popover: {
91
+ files: ['popover.component.ts', 'index.ts'],
92
+ dependencies: ['@angular/cdk', 'clsx', 'tailwind-merge']
93
+ },
94
+ progress: {
95
+ files: ['progress.component.ts', 'index.ts'],
96
+ dependencies: ['clsx', 'tailwind-merge']
97
+ },
98
+ 'radio-group': {
99
+ files: ['radio-group.component.ts', 'index.ts'],
100
+ dependencies: ['@angular/cdk', 'clsx', 'tailwind-merge']
101
+ },
102
+ select: {
103
+ files: ['select.component.ts', 'index.ts'],
104
+ dependencies: ['@angular/cdk', 'clsx', 'tailwind-merge', 'lucide-angular']
105
+ },
106
+ separator: {
107
+ files: ['separator.component.ts', 'index.ts'],
108
+ dependencies: ['clsx', 'tailwind-merge']
109
+ },
110
+ sheet: {
111
+ files: ['sheet.component.ts', 'index.ts'],
112
+ dependencies: ['@angular/cdk', 'clsx', 'tailwind-merge', 'lucide-angular']
113
+ },
114
+ skeleton: {
115
+ files: ['skeleton.component.ts', 'index.ts'],
116
+ dependencies: ['clsx', 'tailwind-merge']
117
+ },
118
+ slider: {
119
+ files: ['slider.component.ts', 'index.ts'],
120
+ dependencies: ['@angular/cdk', 'clsx', 'tailwind-merge']
121
+ },
122
+ switch: {
123
+ files: ['switch.component.ts', 'index.ts'],
124
+ dependencies: ['@angular/cdk', 'clsx', 'tailwind-merge']
125
+ },
126
+ table: {
127
+ files: ['table.component.ts', 'index.ts'],
128
+ dependencies: ['clsx', 'tailwind-merge']
129
+ },
130
+ tabs: {
131
+ files: ['tabs.component.ts', 'index.ts'],
132
+ dependencies: ['@angular/cdk', 'clsx', 'tailwind-merge']
133
+ },
134
+ textarea: {
135
+ files: ['textarea.component.ts', 'index.ts'],
136
+ dependencies: ['clsx', 'tailwind-merge', '@angular/forms']
137
+ },
138
+ toast: {
139
+ files: ['toast.component.ts', 'toaster.component.ts', 'toast.service.ts', 'index.ts'],
140
+ dependencies: ['clsx', 'tailwind-merge', 'lucide-angular']
141
+ },
142
+ toggle: {
143
+ files: ['toggle.component.ts', 'index.ts'],
144
+ dependencies: ['class-variance-authority', 'clsx', 'tailwind-merge']
145
+ },
146
+ tooltip: {
147
+ files: ['tooltip.component.ts', 'index.ts'],
148
+ dependencies: ['@angular/cdk', 'clsx', 'tailwind-merge']
149
+ },
150
+ };
151
+
152
+ interface ComponentInfo {
153
+ files: string[];
154
+ dependencies: string[];
155
+ }
156
+
157
+ export function component(options: ComponentOptions): Rule {
158
+ return (tree: Tree, context: SchematicContext) => {
159
+ const componentName = options.name.toLowerCase();
160
+
161
+ if (!COMPONENT_REGISTRY[componentName]) {
162
+ const availableComponents = Object.keys(COMPONENT_REGISTRY).sort().join(', ');
163
+ throw new SchematicsException(
164
+ `\n❌ Component "${componentName}" not found.\n\n` +
165
+ `Available components:\n${availableComponents}\n\n` +
166
+ `Usage: ng g @ng-cn/core:c <component-name>\n`
167
+ );
168
+ }
169
+
170
+ const componentInfo = COMPONENT_REGISTRY[componentName];
171
+ const basePath = options.path || 'src/app/lib/components/ui';
172
+ const componentPath = normalize(join(normalize(basePath), normalize(componentName)) as Path);
173
+
174
+ context.logger.info('');
175
+ context.logger.info(`📦 Installing ${componentName}...`);
176
+ context.logger.info('');
177
+
178
+ // Check if component directory already exists
179
+ const firstFilePath = join(componentPath, normalize(componentInfo.files[0])) as Path;
180
+ if (tree.exists(firstFilePath) && !options.overwrite) {
181
+ context.logger.warn(`⚠️ Component already exists at ${componentPath}`);
182
+ context.logger.info(` Use --overwrite to replace existing files.`);
183
+ context.logger.info('');
184
+ return tree;
185
+ }
186
+
187
+ // Copy component files from the package source
188
+ const sourceBasePath = `node_modules/@ng-cn/core/lib/components/ui/${componentName}`;
189
+ const fallbackSourcePath = `src/app/lib/components/ui/${componentName}`;
190
+
191
+ let filesCreated = 0;
192
+ for (const file of componentInfo.files) {
193
+ let sourcePath = join(normalize(sourceBasePath), normalize(file)) as Path;
194
+ const targetPath = join(componentPath, normalize(file)) as Path;
195
+
196
+ // Try package path first, then fallback to local dev path
197
+ let content = tree.read(sourcePath);
198
+ if (!content) {
199
+ sourcePath = join(normalize(fallbackSourcePath), normalize(file)) as Path;
200
+ content = tree.read(sourcePath);
201
+ }
202
+
203
+ if (content) {
204
+ if (tree.exists(targetPath)) {
205
+ tree.overwrite(targetPath, content);
206
+ } else {
207
+ tree.create(targetPath, content);
208
+ }
209
+ context.logger.info(` ✓ ${componentName}/${file}`);
210
+ filesCreated++;
211
+ }
212
+ }
213
+
214
+ if (filesCreated === 0) {
215
+ context.logger.warn(`⚠️ No source files found for ${componentName}`);
216
+ context.logger.info(` Make sure @ng-cn/core is properly installed.`);
217
+ context.logger.info('');
218
+ return tree;
219
+ }
220
+
221
+ // Success message
222
+ context.logger.info('');
223
+ context.logger.info(`✅ ${componentName} installed successfully!`);
224
+ context.logger.info('');
225
+ context.logger.info(' Import:');
226
+ context.logger.info(` import { ${toPascalCase(componentName)} } from '@/ui/${componentName}';`);
227
+ context.logger.info('');
228
+
229
+ return tree;
230
+ };
231
+ }
232
+
233
+ function toPascalCase(str: string): string {
234
+ return str
235
+ .split('-')
236
+ .map(word => word.charAt(0).toUpperCase() + word.slice(1))
237
+ .join('');
238
+ }
@@ -0,0 +1,36 @@
1
+ {
2
+ "$schema": "http://json-schema.org/schema",
3
+ "$id": "NgCnComponentSchema",
4
+ "title": "@ng-cn/core component schematic",
5
+ "type": "object",
6
+ "properties": {
7
+ "name": {
8
+ "type": "string",
9
+ "description": "The name of the component to add (e.g., button, card, dialog).",
10
+ "$default": {
11
+ "$source": "argv",
12
+ "index": 0
13
+ },
14
+ "x-prompt": "Which component would you like to add?"
15
+ },
16
+ "project": {
17
+ "type": "string",
18
+ "description": "The name of the project.",
19
+ "$default": {
20
+ "$source": "projectName"
21
+ }
22
+ },
23
+ "path": {
24
+ "type": "string",
25
+ "format": "path",
26
+ "description": "Custom path to install the component.",
27
+ "default": "src/app/lib/components/ui"
28
+ },
29
+ "overwrite": {
30
+ "type": "boolean",
31
+ "default": false,
32
+ "description": "Overwrite existing component files."
33
+ }
34
+ },
35
+ "required": ["name"]
36
+ }
@@ -0,0 +1,8 @@
1
+ import { Rule } from '@angular-devkit/schematics';
2
+ interface NgAddOptions {
3
+ project?: string;
4
+ skipInstall?: boolean;
5
+ skipStyles?: boolean;
6
+ }
7
+ export declare function ngAdd(options: NgAddOptions): Rule;
8
+ export {};