azamat-ui-kit 0.1.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.
- package/LICENSE +21 -0
- package/README.md +323 -0
- package/dist/cli/index.js +725 -0
- package/dist/components/actions/action-menu.d.ts +26 -0
- package/dist/components/actions/copy-button.d.ts +13 -0
- package/dist/components/actions/index.d.ts +3 -0
- package/dist/components/actions/quick-action-grid.d.ts +27 -0
- package/dist/components/calendar/calendar.d.ts +28 -0
- package/dist/components/calendar/date-picker.d.ts +15 -0
- package/dist/components/calendar/date-range-picker.d.ts +18 -0
- package/dist/components/calendar/date-utils.d.ts +12 -0
- package/dist/components/calendar/index.d.ts +4 -0
- package/dist/components/command/command-palette.d.ts +54 -0
- package/dist/components/command/index.d.ts +1 -0
- package/dist/components/data-table/data-table-actions-column.d.ts +16 -0
- package/dist/components/data-table/data-table-bulk-actions.d.ts +17 -0
- package/dist/components/data-table/data-table-column-visibility-menu.d.ts +14 -0
- package/dist/components/data-table/data-table-pagination.d.ts +21 -0
- package/dist/components/data-table/data-table-row-actions.d.ts +13 -0
- package/dist/components/data-table/data-table-select-column.d.ts +13 -0
- package/dist/components/data-table/data-table-sortable-header.d.ts +11 -0
- package/dist/components/data-table/data-table-toolbar.d.ts +14 -0
- package/dist/components/data-table/data-table-view-presets.d.ts +27 -0
- package/dist/components/data-table/data-table.d.ts +86 -0
- package/dist/components/data-table/index.d.ts +10 -0
- package/dist/components/display/activity-feed.d.ts +25 -0
- package/dist/components/display/avatar.d.ts +26 -0
- package/dist/components/display/data-state.d.ts +16 -0
- package/dist/components/display/description-list.d.ts +31 -0
- package/dist/components/display/index.d.ts +10 -0
- package/dist/components/display/info-card.d.ts +18 -0
- package/dist/components/display/metric-grid.d.ts +22 -0
- package/dist/components/display/progress.d.ts +35 -0
- package/dist/components/display/result.d.ts +18 -0
- package/dist/components/display/status-legend.d.ts +27 -0
- package/dist/components/display/timeline.d.ts +25 -0
- package/dist/components/feedback/empty-state.d.ts +11 -0
- package/dist/components/feedback/index.d.ts +3 -0
- package/dist/components/feedback/loading-state.d.ts +8 -0
- package/dist/components/feedback/status-badge.d.ts +9 -0
- package/dist/components/filters/filter-bar.d.ts +14 -0
- package/dist/components/filters/filter-chips.d.ts +18 -0
- package/dist/components/filters/index.d.ts +2 -0
- package/dist/components/form/form-async-select.d.ts +12 -0
- package/dist/components/form/form-date-input.d.ts +12 -0
- package/dist/components/form/form-date-picker.d.ts +12 -0
- package/dist/components/form/form-date-range-input.d.ts +12 -0
- package/dist/components/form/form-date-range-picker.d.ts +15 -0
- package/dist/components/form/form-field-shell.d.ts +26 -0
- package/dist/components/form/form-input.d.ts +13 -0
- package/dist/components/form/form-number-input.d.ts +12 -0
- package/dist/components/form/form-password-input.d.ts +11 -0
- package/dist/components/form/form-phone-input.d.ts +13 -0
- package/dist/components/form/form-search-input.d.ts +11 -0
- package/dist/components/form/form-select.d.ts +12 -0
- package/dist/components/form/form-switch.d.ts +14 -0
- package/dist/components/form/form-textarea.d.ts +13 -0
- package/dist/components/form/index.d.ts +14 -0
- package/dist/components/inputs/async-select.d.ts +106 -0
- package/dist/components/inputs/clearable-input.d.ts +16 -0
- package/dist/components/inputs/combobox.d.ts +20 -0
- package/dist/components/inputs/date-input.d.ts +9 -0
- package/dist/components/inputs/date-range-input.d.ts +18 -0
- package/dist/components/inputs/index.d.ts +14 -0
- package/dist/components/inputs/masked-input.d.ts +11 -0
- package/dist/components/inputs/money-input.d.ts +13 -0
- package/dist/components/inputs/number-input.d.ts +16 -0
- package/dist/components/inputs/password-input.d.ts +17 -0
- package/dist/components/inputs/phone-input.d.ts +10 -0
- package/dist/components/inputs/quantity-input.d.ts +15 -0
- package/dist/components/inputs/search-input.d.ts +7 -0
- package/dist/components/inputs/simple-select.d.ts +20 -0
- package/dist/components/inputs/tag-input.d.ts +15 -0
- package/dist/components/layout/app-header.d.ts +10 -0
- package/dist/components/layout/app-shell.d.ts +32 -0
- package/dist/components/layout/app-sidebar.d.ts +28 -0
- package/dist/components/layout/breadcrumbs.d.ts +18 -0
- package/dist/components/layout/index.d.ts +8 -0
- package/dist/components/layout/page-container.d.ts +7 -0
- package/dist/components/layout/page-header.d.ts +12 -0
- package/dist/components/layout/sidebar-nav.d.ts +25 -0
- package/dist/components/layout/stat-card.d.ts +18 -0
- package/dist/components/navigation/index.d.ts +3 -0
- package/dist/components/navigation/page-tabs.d.ts +18 -0
- package/dist/components/navigation/pagination.d.ts +21 -0
- package/dist/components/navigation/stepper-tabs.d.ts +19 -0
- package/dist/components/notifications/index.d.ts +1 -0
- package/dist/components/notifications/toast.d.ts +42 -0
- package/dist/components/overlay/confirm-dialog.d.ts +17 -0
- package/dist/components/overlay/dialog-actions.d.ts +14 -0
- package/dist/components/overlay/index.d.ts +4 -0
- package/dist/components/overlay/modal-shell.d.ts +20 -0
- package/dist/components/overlay/sheet-shell.d.ts +34 -0
- package/dist/components/patterns/form-builder-presets.d.ts +23 -0
- package/dist/components/patterns/form-builder.d.ts +95 -0
- package/dist/components/patterns/index.d.ts +4 -0
- package/dist/components/patterns/resource-detail-page.d.ts +39 -0
- package/dist/components/patterns/resource-page.d.ts +34 -0
- package/dist/components/ui/badge.d.ts +7 -0
- package/dist/components/ui/button.d.ts +8 -0
- package/dist/components/ui/card.d.ts +11 -0
- package/dist/components/ui/checkbox.d.ts +13 -0
- package/dist/components/ui/component-preview.d.ts +10 -0
- package/dist/components/ui/dialog.d.ts +17 -0
- package/dist/components/ui/dropdown-menu.d.ts +29 -0
- package/dist/components/ui/input.d.ts +3 -0
- package/dist/components/ui/popover.d.ts +9 -0
- package/dist/components/ui/select.d.ts +15 -0
- package/dist/components/ui/switch.d.ts +12 -0
- package/dist/components/ui/table.d.ts +10 -0
- package/dist/components/ui/tabs.d.ts +6 -0
- package/dist/components/ui/textarea.d.ts +3 -0
- package/dist/components/upload/file-upload.d.ts +61 -0
- package/dist/components/upload/image-upload.d.ts +14 -0
- package/dist/components/upload/index.d.ts +2 -0
- package/dist/components/wizard/index.d.ts +2 -0
- package/dist/components/wizard/stepper.d.ts +16 -0
- package/dist/components/wizard/wizard.d.ts +17 -0
- package/dist/hooks/index.d.ts +6 -0
- package/dist/hooks/use-before-unload-when-dirty.d.ts +2 -0
- package/dist/hooks/use-data-table-view-state.d.ts +20 -0
- package/dist/hooks/use-debounce.d.ts +3 -0
- package/dist/hooks/use-disclosure.d.ts +13 -0
- package/dist/hooks/use-is-mobile.d.ts +3 -0
- package/dist/hooks/use-session-storage-state.d.ts +8 -0
- package/dist/index.cjs +9 -0
- package/dist/index.d.ts +34 -0
- package/dist/index.js +23213 -0
- package/dist/lib/utils.d.ts +2 -0
- package/package.json +118 -0
- package/registry.json +185 -0
|
@@ -0,0 +1,725 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// cli/index.ts
|
|
4
|
+
import { Command } from "commander";
|
|
5
|
+
|
|
6
|
+
// cli/commands/init.ts
|
|
7
|
+
import path3 from "path";
|
|
8
|
+
import fs3 from "fs-extra";
|
|
9
|
+
import prompts from "prompts";
|
|
10
|
+
|
|
11
|
+
// cli/utils/logger.ts
|
|
12
|
+
import { green, red, yellow, cyan } from "kolorist";
|
|
13
|
+
var logger = {
|
|
14
|
+
info(message) {
|
|
15
|
+
console.log(cyan(message));
|
|
16
|
+
},
|
|
17
|
+
success(message) {
|
|
18
|
+
console.log(green(message));
|
|
19
|
+
},
|
|
20
|
+
warn(message) {
|
|
21
|
+
console.log(yellow(message));
|
|
22
|
+
},
|
|
23
|
+
error(message) {
|
|
24
|
+
console.log(red(message));
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
// cli/utils/detect-package-manager.ts
|
|
29
|
+
import fs from "fs-extra";
|
|
30
|
+
import path from "path";
|
|
31
|
+
function detectPackageManager(cwd) {
|
|
32
|
+
if (fs.existsSync(path.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
|
|
33
|
+
if (fs.existsSync(path.join(cwd, "yarn.lock"))) return "yarn";
|
|
34
|
+
if (fs.existsSync(path.join(cwd, "bun.lockb"))) return "bun";
|
|
35
|
+
if (fs.existsSync(path.join(cwd, "bun.lock"))) return "bun";
|
|
36
|
+
return "npm";
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// cli/utils/install-packages.ts
|
|
40
|
+
import { execa } from "execa";
|
|
41
|
+
async function installPackages({
|
|
42
|
+
cwd,
|
|
43
|
+
packageManager,
|
|
44
|
+
packages,
|
|
45
|
+
dev = false
|
|
46
|
+
}) {
|
|
47
|
+
if (!packages.length) return;
|
|
48
|
+
const commandMap = {
|
|
49
|
+
npm: "npm",
|
|
50
|
+
pnpm: "pnpm",
|
|
51
|
+
yarn: "yarn",
|
|
52
|
+
bun: "bun"
|
|
53
|
+
};
|
|
54
|
+
const argsMap = {
|
|
55
|
+
npm: ["install", ...dev ? ["-D"] : [], ...packages],
|
|
56
|
+
pnpm: ["add", ...dev ? ["-D"] : [], ...packages],
|
|
57
|
+
yarn: ["add", ...dev ? ["-D"] : [], ...packages],
|
|
58
|
+
bun: ["add", ...dev ? ["-d"] : [], ...packages]
|
|
59
|
+
};
|
|
60
|
+
await execa(commandMap[packageManager], argsMap[packageManager], {
|
|
61
|
+
cwd,
|
|
62
|
+
stdio: "inherit"
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// cli/utils/upsert-theme-css.ts
|
|
67
|
+
import path2 from "path";
|
|
68
|
+
import fs2 from "fs-extra";
|
|
69
|
+
|
|
70
|
+
// cli/templates/theme-css.ts
|
|
71
|
+
var AZAMAT_UI_THEME_START = "/* azamat-ui-kit:start */";
|
|
72
|
+
var AZAMAT_UI_THEME_END = "/* azamat-ui-kit:end */";
|
|
73
|
+
var azamatUiThemeCss = `${AZAMAT_UI_THEME_START}
|
|
74
|
+
@import "tw-animate-css";
|
|
75
|
+
@import "shadcn/tailwind.css";
|
|
76
|
+
@import "@fontsource-variable/geist";
|
|
77
|
+
|
|
78
|
+
@custom-variant dark (&:is(.dark *));
|
|
79
|
+
|
|
80
|
+
@theme inline {
|
|
81
|
+
--font-heading: var(--font-sans);
|
|
82
|
+
--font-sans: 'Geist Variable', sans-serif;
|
|
83
|
+
|
|
84
|
+
--color-background: var(--background);
|
|
85
|
+
--color-foreground: var(--foreground);
|
|
86
|
+
--color-card: var(--card);
|
|
87
|
+
--color-card-foreground: var(--card-foreground);
|
|
88
|
+
--color-popover: var(--popover);
|
|
89
|
+
--color-popover-foreground: var(--popover-foreground);
|
|
90
|
+
--color-primary: var(--primary);
|
|
91
|
+
--color-primary-foreground: var(--primary-foreground);
|
|
92
|
+
--color-secondary: var(--secondary);
|
|
93
|
+
--color-secondary-foreground: var(--secondary-foreground);
|
|
94
|
+
--color-muted: var(--muted);
|
|
95
|
+
--color-muted-foreground: var(--muted-foreground);
|
|
96
|
+
--color-accent: var(--accent);
|
|
97
|
+
--color-accent-foreground: var(--accent-foreground);
|
|
98
|
+
--color-destructive: var(--destructive);
|
|
99
|
+
--color-border: var(--border);
|
|
100
|
+
--color-input: var(--input);
|
|
101
|
+
--color-ring: var(--ring);
|
|
102
|
+
|
|
103
|
+
--color-sidebar: var(--sidebar);
|
|
104
|
+
--color-sidebar-foreground: var(--sidebar-foreground);
|
|
105
|
+
--color-sidebar-primary: var(--sidebar-primary);
|
|
106
|
+
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
|
|
107
|
+
--color-sidebar-accent: var(--sidebar-accent);
|
|
108
|
+
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
|
|
109
|
+
--color-sidebar-border: var(--sidebar-border);
|
|
110
|
+
--color-sidebar-ring: var(--sidebar-ring);
|
|
111
|
+
|
|
112
|
+
--color-chart-1: var(--chart-1);
|
|
113
|
+
--color-chart-2: var(--chart-2);
|
|
114
|
+
--color-chart-3: var(--chart-3);
|
|
115
|
+
--color-chart-4: var(--chart-4);
|
|
116
|
+
--color-chart-5: var(--chart-5);
|
|
117
|
+
|
|
118
|
+
--radius-sm: calc(var(--radius) * 0.6);
|
|
119
|
+
--radius-md: calc(var(--radius) * 0.8);
|
|
120
|
+
--radius-lg: var(--radius);
|
|
121
|
+
--radius-xl: calc(var(--radius) * 1.4);
|
|
122
|
+
--radius-2xl: calc(var(--radius) * 1.8);
|
|
123
|
+
--radius-3xl: calc(var(--radius) * 2.2);
|
|
124
|
+
--radius-4xl: calc(var(--radius) * 2.6);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
:root {
|
|
128
|
+
--background: oklch(1 0 0);
|
|
129
|
+
--foreground: oklch(0.145 0 0);
|
|
130
|
+
--card: oklch(1 0 0);
|
|
131
|
+
--card-foreground: oklch(0.145 0 0);
|
|
132
|
+
--popover: oklch(1 0 0);
|
|
133
|
+
--popover-foreground: oklch(0.145 0 0);
|
|
134
|
+
--primary: oklch(0.205 0 0);
|
|
135
|
+
--primary-foreground: oklch(0.985 0 0);
|
|
136
|
+
--secondary: oklch(0.97 0 0);
|
|
137
|
+
--secondary-foreground: oklch(0.205 0 0);
|
|
138
|
+
--muted: oklch(0.97 0 0);
|
|
139
|
+
--muted-foreground: oklch(0.556 0 0);
|
|
140
|
+
--accent: oklch(0.97 0 0);
|
|
141
|
+
--accent-foreground: oklch(0.205 0 0);
|
|
142
|
+
--destructive: oklch(0.577 0.245 27.325);
|
|
143
|
+
--border: oklch(0.922 0 0);
|
|
144
|
+
--input: oklch(0.922 0 0);
|
|
145
|
+
--ring: oklch(0.708 0 0);
|
|
146
|
+
--chart-1: oklch(0.87 0 0);
|
|
147
|
+
--chart-2: oklch(0.556 0 0);
|
|
148
|
+
--chart-3: oklch(0.439 0 0);
|
|
149
|
+
--chart-4: oklch(0.371 0 0);
|
|
150
|
+
--chart-5: oklch(0.269 0 0);
|
|
151
|
+
--radius: 0.625rem;
|
|
152
|
+
--sidebar: oklch(0.985 0 0);
|
|
153
|
+
--sidebar-foreground: oklch(0.145 0 0);
|
|
154
|
+
--sidebar-primary: oklch(0.205 0 0);
|
|
155
|
+
--sidebar-primary-foreground: oklch(0.985 0 0);
|
|
156
|
+
--sidebar-accent: oklch(0.97 0 0);
|
|
157
|
+
--sidebar-accent-foreground: oklch(0.205 0 0);
|
|
158
|
+
--sidebar-border: oklch(0.922 0 0);
|
|
159
|
+
--sidebar-ring: oklch(0.708 0 0);
|
|
160
|
+
|
|
161
|
+
--aui-control-radius: var(--radius-lg);
|
|
162
|
+
--aui-control-shadow: 0 1px 2px oklch(0 0 0 / 5%);
|
|
163
|
+
--aui-card-radius: var(--radius-xl);
|
|
164
|
+
--aui-card-border: color-mix(in oklch, var(--border), transparent 5%);
|
|
165
|
+
--aui-card-shadow: 0 1px 2px oklch(0 0 0 / 4%), 0 10px 28px oklch(0 0 0 / 4%);
|
|
166
|
+
--aui-popover-shadow: 0 18px 60px oklch(0 0 0 / 16%);
|
|
167
|
+
--aui-table-header-bg: color-mix(in oklch, var(--muted), transparent 42%);
|
|
168
|
+
--aui-table-row-hover-bg: color-mix(in oklch, var(--muted), transparent 55%);
|
|
169
|
+
--aui-table-row-selected-bg: color-mix(in oklch, var(--primary), transparent 91%);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
.dark {
|
|
173
|
+
--background: oklch(0.145 0 0);
|
|
174
|
+
--foreground: oklch(0.985 0 0);
|
|
175
|
+
--card: oklch(0.205 0 0);
|
|
176
|
+
--card-foreground: oklch(0.985 0 0);
|
|
177
|
+
--popover: oklch(0.205 0 0);
|
|
178
|
+
--popover-foreground: oklch(0.985 0 0);
|
|
179
|
+
--primary: oklch(0.922 0 0);
|
|
180
|
+
--primary-foreground: oklch(0.205 0 0);
|
|
181
|
+
--secondary: oklch(0.269 0 0);
|
|
182
|
+
--secondary-foreground: oklch(0.985 0 0);
|
|
183
|
+
--muted: oklch(0.269 0 0);
|
|
184
|
+
--muted-foreground: oklch(0.708 0 0);
|
|
185
|
+
--accent: oklch(0.269 0 0);
|
|
186
|
+
--accent-foreground: oklch(0.985 0 0);
|
|
187
|
+
--destructive: oklch(0.704 0.191 22.216);
|
|
188
|
+
--border: oklch(1 0 0 / 10%);
|
|
189
|
+
--input: oklch(1 0 0 / 15%);
|
|
190
|
+
--ring: oklch(0.556 0 0);
|
|
191
|
+
--chart-1: oklch(0.87 0 0);
|
|
192
|
+
--chart-2: oklch(0.556 0 0);
|
|
193
|
+
--chart-3: oklch(0.439 0 0);
|
|
194
|
+
--chart-4: oklch(0.371 0 0);
|
|
195
|
+
--chart-5: oklch(0.269 0 0);
|
|
196
|
+
--sidebar: oklch(0.205 0 0);
|
|
197
|
+
--sidebar-foreground: oklch(0.985 0 0);
|
|
198
|
+
--sidebar-primary: oklch(0.488 0.243 264.376);
|
|
199
|
+
--sidebar-primary-foreground: oklch(0.985 0 0);
|
|
200
|
+
--sidebar-accent: oklch(0.269 0 0);
|
|
201
|
+
--sidebar-accent-foreground: oklch(0.985 0 0);
|
|
202
|
+
--sidebar-border: oklch(1 0 0 / 10%);
|
|
203
|
+
--sidebar-ring: oklch(0.556 0 0);
|
|
204
|
+
|
|
205
|
+
--aui-card-border: oklch(1 0 0 / 10%);
|
|
206
|
+
--aui-card-shadow: 0 1px 0 oklch(1 0 0 / 5%), 0 18px 70px oklch(0 0 0 / 24%);
|
|
207
|
+
--aui-popover-shadow: 0 18px 70px oklch(0 0 0 / 45%);
|
|
208
|
+
--aui-table-header-bg: oklch(1 0 0 / 5%);
|
|
209
|
+
--aui-table-row-hover-bg: oklch(1 0 0 / 5%);
|
|
210
|
+
--aui-table-row-selected-bg: color-mix(in oklch, var(--primary), transparent 88%);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
:root[data-radius="none"] { --radius: 0rem; }
|
|
214
|
+
:root[data-radius="sm"] { --radius: 0.375rem; }
|
|
215
|
+
:root[data-radius="md"] { --radius: 0.5rem; }
|
|
216
|
+
:root[data-radius="lg"] { --radius: 0.75rem; }
|
|
217
|
+
:root[data-radius="xl"] { --radius: 1rem; }
|
|
218
|
+
|
|
219
|
+
@layer base {
|
|
220
|
+
* {
|
|
221
|
+
@apply border-border outline-ring/50;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
html {
|
|
225
|
+
@apply font-sans;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
body {
|
|
229
|
+
@apply bg-background text-foreground;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
@layer components {
|
|
234
|
+
[data-slot="button"][data-slot="button"] {
|
|
235
|
+
border-radius: var(--aui-control-radius);
|
|
236
|
+
box-shadow: var(--aui-control-shadow);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
[data-slot="input"][data-slot="input"],
|
|
240
|
+
[data-slot="textarea"][data-slot="textarea"],
|
|
241
|
+
[data-slot="select-trigger"][data-slot="select-trigger"] {
|
|
242
|
+
border-radius: var(--aui-control-radius);
|
|
243
|
+
box-shadow: var(--aui-control-shadow);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
[data-slot="card"][data-slot="card"],
|
|
247
|
+
[data-slot="stat-card"][data-slot="stat-card"] {
|
|
248
|
+
border: 1px solid var(--aui-card-border);
|
|
249
|
+
border-radius: var(--aui-card-radius);
|
|
250
|
+
box-shadow: var(--aui-card-shadow);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
[data-slot="popover-content"][data-slot="popover-content"],
|
|
254
|
+
[data-slot="dropdown-menu-content"][data-slot="dropdown-menu-content"],
|
|
255
|
+
[data-slot="dialog-content"][data-slot="dialog-content"],
|
|
256
|
+
[data-slot="sheet-content"][data-slot="sheet-content"] {
|
|
257
|
+
box-shadow: var(--aui-popover-shadow);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
[data-slot="data-table-wrapper"][data-slot="data-table-wrapper"] {
|
|
261
|
+
box-shadow: var(--aui-card-shadow);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
[data-slot="data-table-wrapper"] thead {
|
|
265
|
+
background: var(--aui-table-header-bg);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
[data-slot="data-table-wrapper"] tbody tr:hover {
|
|
269
|
+
background: var(--aui-table-row-hover-bg);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
[data-slot="data-table-wrapper"] tbody tr[data-state="selected"] {
|
|
273
|
+
background: var(--aui-table-row-selected-bg);
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
[data-slot="file-upload-dropzone"][data-dragging="true"] {
|
|
277
|
+
border-color: var(--primary);
|
|
278
|
+
background: color-mix(in oklch, var(--primary), transparent 93%);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
${AZAMAT_UI_THEME_END}
|
|
282
|
+
`;
|
|
283
|
+
|
|
284
|
+
// cli/utils/upsert-theme-css.ts
|
|
285
|
+
function hasTailwindImport(content) {
|
|
286
|
+
return /@import\s+["']tailwindcss["'];?/.test(content);
|
|
287
|
+
}
|
|
288
|
+
function ensureTailwindImport(content) {
|
|
289
|
+
if (hasTailwindImport(content)) {
|
|
290
|
+
return content;
|
|
291
|
+
}
|
|
292
|
+
return `@import "tailwindcss";
|
|
293
|
+
|
|
294
|
+
${content}`.trimEnd() + "\n";
|
|
295
|
+
}
|
|
296
|
+
function replaceMarkedBlock(content, block) {
|
|
297
|
+
const startIndex = content.indexOf(AZAMAT_UI_THEME_START);
|
|
298
|
+
const endIndex = content.indexOf(AZAMAT_UI_THEME_END);
|
|
299
|
+
if (startIndex !== -1 && endIndex !== -1 && endIndex > startIndex) {
|
|
300
|
+
const before = content.slice(0, startIndex).trimEnd();
|
|
301
|
+
const after = content.slice(endIndex + AZAMAT_UI_THEME_END.length).trimStart();
|
|
302
|
+
return [before, block, after].filter(Boolean).join("\n\n") + "\n";
|
|
303
|
+
}
|
|
304
|
+
return `${content.trimEnd()}
|
|
305
|
+
|
|
306
|
+
${block}
|
|
307
|
+
`;
|
|
308
|
+
}
|
|
309
|
+
async function upsertThemeCss({ cwd, cssPath }) {
|
|
310
|
+
const targetPath = path2.resolve(cwd, cssPath);
|
|
311
|
+
await fs2.ensureDir(path2.dirname(targetPath));
|
|
312
|
+
const currentContent = fs2.existsSync(targetPath) ? await fs2.readFile(targetPath, "utf8") : "";
|
|
313
|
+
const withTailwind = ensureTailwindImport(currentContent);
|
|
314
|
+
const nextContent = replaceMarkedBlock(withTailwind, azamatUiThemeCss);
|
|
315
|
+
await fs2.writeFile(targetPath, nextContent);
|
|
316
|
+
return targetPath;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
// cli/commands/init.ts
|
|
320
|
+
var baseDependencies = [
|
|
321
|
+
"@base-ui/react",
|
|
322
|
+
"@fontsource-variable/geist",
|
|
323
|
+
"clsx",
|
|
324
|
+
"tailwind-merge",
|
|
325
|
+
"class-variance-authority",
|
|
326
|
+
"lucide-react",
|
|
327
|
+
"tw-animate-css",
|
|
328
|
+
"@tanstack/react-table",
|
|
329
|
+
"react-hook-form"
|
|
330
|
+
];
|
|
331
|
+
async function initCommand() {
|
|
332
|
+
const cwd = process.cwd();
|
|
333
|
+
const packageJsonPath = path3.join(cwd, "package.json");
|
|
334
|
+
if (!fs3.existsSync(packageJsonPath)) {
|
|
335
|
+
logger.error("package.json topilmadi. Commandni React/Vite project ichida ishlating.");
|
|
336
|
+
process.exit(1);
|
|
337
|
+
}
|
|
338
|
+
const response = await prompts([
|
|
339
|
+
{
|
|
340
|
+
type: "confirm",
|
|
341
|
+
name: "installDeps",
|
|
342
|
+
message: "Asosiy dependencylarni o\u2018rnataymi?",
|
|
343
|
+
initial: true
|
|
344
|
+
},
|
|
345
|
+
{
|
|
346
|
+
type: "text",
|
|
347
|
+
name: "alias",
|
|
348
|
+
message: "Path alias qanday?",
|
|
349
|
+
initial: "@"
|
|
350
|
+
},
|
|
351
|
+
{
|
|
352
|
+
type: "text",
|
|
353
|
+
name: "componentsPath",
|
|
354
|
+
message: "Component root qayerda?",
|
|
355
|
+
initial: "src/components"
|
|
356
|
+
},
|
|
357
|
+
{
|
|
358
|
+
type: "text",
|
|
359
|
+
name: "uiPath",
|
|
360
|
+
message: "UI primitives qayerga yozilsin?",
|
|
361
|
+
initial: "src/components/ui"
|
|
362
|
+
},
|
|
363
|
+
{
|
|
364
|
+
type: "text",
|
|
365
|
+
name: "hooksPath",
|
|
366
|
+
message: "Hooks qayerga yozilsin?",
|
|
367
|
+
initial: "src/hooks"
|
|
368
|
+
},
|
|
369
|
+
{
|
|
370
|
+
type: "text",
|
|
371
|
+
name: "utilsPath",
|
|
372
|
+
message: "utils.ts qayerga yozilsin?",
|
|
373
|
+
initial: "src/lib/utils.ts"
|
|
374
|
+
},
|
|
375
|
+
{
|
|
376
|
+
type: "text",
|
|
377
|
+
name: "globalCssPath",
|
|
378
|
+
message: "Theme tokenlar qaysi global CSS faylga yozilsin?",
|
|
379
|
+
initial: "src/index.css"
|
|
380
|
+
},
|
|
381
|
+
{
|
|
382
|
+
type: "confirm",
|
|
383
|
+
name: "writeThemeCss",
|
|
384
|
+
message: "Dark/light theme tokenlarni global CSS faylga yozaymi?",
|
|
385
|
+
initial: true
|
|
386
|
+
}
|
|
387
|
+
]);
|
|
388
|
+
const packageManager = detectPackageManager(cwd);
|
|
389
|
+
logger.info(`Package manager: ${packageManager}`);
|
|
390
|
+
if (response.installDeps) {
|
|
391
|
+
await installPackages({
|
|
392
|
+
cwd,
|
|
393
|
+
packageManager,
|
|
394
|
+
packages: baseDependencies
|
|
395
|
+
});
|
|
396
|
+
}
|
|
397
|
+
const config = {
|
|
398
|
+
style: "default",
|
|
399
|
+
alias: response.alias || "@",
|
|
400
|
+
componentsPath: response.uiPath,
|
|
401
|
+
utilsPath: response.utilsPath,
|
|
402
|
+
cssPath: response.globalCssPath,
|
|
403
|
+
globalCssPath: response.globalCssPath,
|
|
404
|
+
paths: {
|
|
405
|
+
components: response.componentsPath,
|
|
406
|
+
ui: response.uiPath,
|
|
407
|
+
hooks: response.hooksPath,
|
|
408
|
+
lib: path3.dirname(response.utilsPath)
|
|
409
|
+
}
|
|
410
|
+
};
|
|
411
|
+
await fs3.writeJson(path3.join(cwd, "azamat-ui.json"), config, {
|
|
412
|
+
spaces: 2
|
|
413
|
+
});
|
|
414
|
+
const utilsFullPath = path3.join(cwd, response.utilsPath);
|
|
415
|
+
await fs3.ensureDir(path3.dirname(utilsFullPath));
|
|
416
|
+
if (!fs3.existsSync(utilsFullPath)) {
|
|
417
|
+
await fs3.writeFile(
|
|
418
|
+
utilsFullPath,
|
|
419
|
+
`import { clsx, type ClassValue } from "clsx"
|
|
420
|
+
import { twMerge } from "tailwind-merge"
|
|
421
|
+
|
|
422
|
+
export function cn(...inputs: ClassValue[]) {
|
|
423
|
+
return twMerge(clsx(inputs))
|
|
424
|
+
}
|
|
425
|
+
`
|
|
426
|
+
);
|
|
427
|
+
}
|
|
428
|
+
if (response.writeThemeCss && response.globalCssPath) {
|
|
429
|
+
const cssTarget = await upsertThemeCss({
|
|
430
|
+
cwd,
|
|
431
|
+
cssPath: response.globalCssPath
|
|
432
|
+
});
|
|
433
|
+
logger.success(`Theme CSS yozildi: ${cssTarget}`);
|
|
434
|
+
}
|
|
435
|
+
logger.success("Azamat UI Kit init qilindi.");
|
|
436
|
+
logger.info("Componentlarni ko\u2018rish:");
|
|
437
|
+
logger.info("npx azamat-ui-kit list");
|
|
438
|
+
logger.info("Component qo\u2018shish:");
|
|
439
|
+
logger.info("npx azamat-ui-kit add button input data-table");
|
|
440
|
+
logger.info("Theme CSS ni yangilash:");
|
|
441
|
+
logger.info("npx azamat-ui-kit theme");
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
// cli/commands/add.ts
|
|
445
|
+
import path4 from "path";
|
|
446
|
+
import { fileURLToPath } from "url";
|
|
447
|
+
import fs4 from "fs-extra";
|
|
448
|
+
|
|
449
|
+
// cli/registry.ts
|
|
450
|
+
var file = (source, target) => ({ source, target });
|
|
451
|
+
var registry = {
|
|
452
|
+
utils: { name: "utils", category: "lib", dependencies: ["clsx", "tailwind-merge"], files: [file("src/lib/utils.ts", "{utils}")] },
|
|
453
|
+
button: { name: "button", category: "ui", dependencies: ["@base-ui/react", "class-variance-authority"], registryDependencies: ["utils"], files: [file("src/components/ui/button.tsx", "{ui}/button.tsx")] },
|
|
454
|
+
input: { name: "input", category: "ui", dependencies: ["@base-ui/react"], registryDependencies: ["utils"], files: [file("src/components/ui/input.tsx", "{ui}/input.tsx")] },
|
|
455
|
+
textarea: { name: "textarea", category: "ui", registryDependencies: ["utils"], files: [file("src/components/ui/textarea.tsx", "{ui}/textarea.tsx")] },
|
|
456
|
+
checkbox: { name: "checkbox", category: "ui", dependencies: ["lucide-react"], registryDependencies: ["utils"], files: [file("src/components/ui/checkbox.tsx", "{ui}/checkbox.tsx")] },
|
|
457
|
+
switch: { name: "switch", category: "ui", registryDependencies: ["utils"], files: [file("src/components/ui/switch.tsx", "{ui}/switch.tsx")] },
|
|
458
|
+
badge: { name: "badge", category: "ui", dependencies: ["@base-ui/react", "class-variance-authority"], registryDependencies: ["utils"], files: [file("src/components/ui/badge.tsx", "{ui}/badge.tsx")] },
|
|
459
|
+
card: { name: "card", category: "ui", registryDependencies: ["utils"], files: [file("src/components/ui/card.tsx", "{ui}/card.tsx")] },
|
|
460
|
+
dialog: { name: "dialog", category: "ui", dependencies: ["@base-ui/react", "lucide-react"], registryDependencies: ["button", "utils"], files: [file("src/components/ui/dialog.tsx", "{ui}/dialog.tsx")] },
|
|
461
|
+
"dropdown-menu": { name: "dropdown-menu", category: "ui", dependencies: ["@base-ui/react", "lucide-react"], registryDependencies: ["utils"], files: [file("src/components/ui/dropdown-menu.tsx", "{ui}/dropdown-menu.tsx")] },
|
|
462
|
+
popover: { name: "popover", category: "ui", dependencies: ["@base-ui/react"], registryDependencies: ["utils"], files: [file("src/components/ui/popover.tsx", "{ui}/popover.tsx")] },
|
|
463
|
+
select: { name: "select", category: "ui", dependencies: ["@base-ui/react", "lucide-react"], registryDependencies: ["utils"], files: [file("src/components/ui/select.tsx", "{ui}/select.tsx")] },
|
|
464
|
+
table: { name: "table", category: "ui", registryDependencies: ["utils"], files: [file("src/components/ui/table.tsx", "{ui}/table.tsx")] },
|
|
465
|
+
"dialog-actions": { name: "dialog-actions", category: "overlay", dependencies: ["lucide-react"], registryDependencies: ["button", "utils"], files: [file("src/components/overlay/dialog-actions.tsx", "{components}/overlay/dialog-actions.tsx")] },
|
|
466
|
+
"modal-shell": { name: "modal-shell", category: "overlay", registryDependencies: ["dialog", "utils"], files: [file("src/components/overlay/modal-shell.tsx", "{components}/overlay/modal-shell.tsx")] },
|
|
467
|
+
"confirm-dialog": { name: "confirm-dialog", category: "overlay", registryDependencies: ["modal-shell", "dialog-actions"], files: [file("src/components/overlay/confirm-dialog.tsx", "{components}/overlay/confirm-dialog.tsx")] },
|
|
468
|
+
"sheet-shell": { name: "sheet-shell", category: "overlay", dependencies: ["@base-ui/react", "lucide-react"], registryDependencies: ["button", "utils"], files: [file("src/components/overlay/sheet-shell.tsx", "{components}/overlay/sheet-shell.tsx")] },
|
|
469
|
+
overlay: { name: "overlay", category: "group", registryDependencies: ["dialog-actions", "modal-shell", "confirm-dialog", "sheet-shell"], files: [file("src/components/overlay/index.ts", "{components}/overlay/index.ts")] },
|
|
470
|
+
pagination: { name: "pagination", category: "navigation", dependencies: ["lucide-react"], registryDependencies: ["button", "utils"], files: [file("src/components/navigation/pagination.tsx", "{components}/navigation/pagination.tsx")] },
|
|
471
|
+
"clearable-input": { name: "clearable-input", category: "inputs", dependencies: ["lucide-react"], registryDependencies: ["input", "utils"], files: [file("src/components/inputs/clearable-input.tsx", "{components}/inputs/clearable-input.tsx")] },
|
|
472
|
+
"search-input": { name: "search-input", category: "inputs", dependencies: ["lucide-react"], registryDependencies: ["clearable-input"], files: [file("src/components/inputs/search-input.tsx", "{components}/inputs/search-input.tsx")] },
|
|
473
|
+
"password-input": { name: "password-input", category: "inputs", dependencies: ["lucide-react"], registryDependencies: ["input", "utils"], files: [file("src/components/inputs/password-input.tsx", "{components}/inputs/password-input.tsx")] },
|
|
474
|
+
"number-input": { name: "number-input", category: "inputs", registryDependencies: ["input"], files: [file("src/components/inputs/number-input.tsx", "{components}/inputs/number-input.tsx")] },
|
|
475
|
+
"date-input": { name: "date-input", category: "inputs", registryDependencies: ["input"], files: [file("src/components/inputs/date-input.tsx", "{components}/inputs/date-input.tsx")] },
|
|
476
|
+
"date-range-input": { name: "date-range-input", category: "inputs", registryDependencies: ["date-input", "utils"], files: [file("src/components/inputs/date-range-input.tsx", "{components}/inputs/date-range-input.tsx")] },
|
|
477
|
+
"money-input": { name: "money-input", category: "inputs", registryDependencies: ["input", "utils"], files: [file("src/components/inputs/money-input.tsx", "{components}/inputs/money-input.tsx")] },
|
|
478
|
+
"quantity-input": { name: "quantity-input", category: "inputs", dependencies: ["lucide-react"], registryDependencies: ["button", "input", "utils"], files: [file("src/components/inputs/quantity-input.tsx", "{components}/inputs/quantity-input.tsx")] },
|
|
479
|
+
"masked-input": { name: "masked-input", category: "inputs", registryDependencies: ["input"], files: [file("src/components/inputs/masked-input.tsx", "{components}/inputs/masked-input.tsx")] },
|
|
480
|
+
"phone-input": { name: "phone-input", category: "inputs", registryDependencies: ["masked-input"], files: [file("src/components/inputs/phone-input.tsx", "{components}/inputs/phone-input.tsx")] },
|
|
481
|
+
"simple-select": { name: "simple-select", category: "inputs", registryDependencies: ["select", "utils"], files: [file("src/components/inputs/simple-select.tsx", "{components}/inputs/simple-select.tsx")] },
|
|
482
|
+
"async-select": { name: "async-select", category: "inputs", dependencies: ["lucide-react"], registryDependencies: ["button", "input", "popover", "utils"], files: [file("src/components/inputs/async-select.tsx", "{components}/inputs/async-select.tsx")] },
|
|
483
|
+
inputs: { name: "inputs", category: "group", registryDependencies: ["clearable-input", "search-input", "password-input", "number-input", "date-input", "date-range-input", "money-input", "quantity-input", "masked-input", "phone-input", "simple-select", "async-select"], files: [file("src/components/inputs/index.ts", "{components}/inputs/index.ts")] },
|
|
484
|
+
"form-field-shell": { name: "form-field-shell", category: "form", registryDependencies: ["utils"], files: [file("src/components/form/form-field-shell.tsx", "{components}/form/form-field-shell.tsx")] },
|
|
485
|
+
"form-input": { name: "form-input", category: "form", dependencies: ["react-hook-form"], registryDependencies: ["input", "form-field-shell"], files: [file("src/components/form/form-input.tsx", "{components}/form/form-input.tsx")] },
|
|
486
|
+
"form-select": { name: "form-select", category: "form", dependencies: ["react-hook-form"], registryDependencies: ["simple-select", "form-field-shell"], files: [file("src/components/form/form-select.tsx", "{components}/form/form-select.tsx")] },
|
|
487
|
+
"form-async-select": { name: "form-async-select", category: "form", dependencies: ["react-hook-form"], registryDependencies: ["async-select", "form-field-shell"], files: [file("src/components/form/form-async-select.tsx", "{components}/form/form-async-select.tsx")] },
|
|
488
|
+
"form-textarea": { name: "form-textarea", category: "form", dependencies: ["react-hook-form"], registryDependencies: ["textarea", "form-field-shell"], files: [file("src/components/form/form-textarea.tsx", "{components}/form/form-textarea.tsx")] },
|
|
489
|
+
"form-switch": { name: "form-switch", category: "form", dependencies: ["react-hook-form"], registryDependencies: ["switch", "form-field-shell", "utils"], files: [file("src/components/form/form-switch.tsx", "{components}/form/form-switch.tsx")] },
|
|
490
|
+
"form-search-input": { name: "form-search-input", category: "form", dependencies: ["react-hook-form"], registryDependencies: ["search-input", "form-field-shell"], files: [file("src/components/form/form-search-input.tsx", "{components}/form/form-search-input.tsx")] },
|
|
491
|
+
"form-password-input": { name: "form-password-input", category: "form", dependencies: ["react-hook-form"], registryDependencies: ["password-input", "form-field-shell"], files: [file("src/components/form/form-password-input.tsx", "{components}/form/form-password-input.tsx")] },
|
|
492
|
+
"form-number-input": { name: "form-number-input", category: "form", dependencies: ["react-hook-form"], registryDependencies: ["number-input", "form-field-shell"], files: [file("src/components/form/form-number-input.tsx", "{components}/form/form-number-input.tsx")] },
|
|
493
|
+
"form-phone-input": { name: "form-phone-input", category: "form", dependencies: ["react-hook-form"], registryDependencies: ["phone-input", "form-field-shell"], files: [file("src/components/form/form-phone-input.tsx", "{components}/form/form-phone-input.tsx")] },
|
|
494
|
+
"form-date-input": { name: "form-date-input", category: "form", dependencies: ["react-hook-form"], registryDependencies: ["date-input", "form-field-shell"], files: [file("src/components/form/form-date-input.tsx", "{components}/form/form-date-input.tsx")] },
|
|
495
|
+
"form-date-range-input": { name: "form-date-range-input", category: "form", dependencies: ["react-hook-form"], registryDependencies: ["date-range-input", "form-field-shell"], files: [file("src/components/form/form-date-range-input.tsx", "{components}/form/form-date-range-input.tsx")] },
|
|
496
|
+
"form-date-picker": { name: "form-date-picker", category: "form", dependencies: ["react-hook-form"], registryDependencies: ["date-picker", "form-field-shell"], files: [file("src/components/form/form-date-picker.tsx", "{components}/form/form-date-picker.tsx")] },
|
|
497
|
+
"form-date-range-picker": { name: "form-date-range-picker", category: "form", dependencies: ["react-hook-form"], registryDependencies: ["date-range-picker", "form-field-shell"], files: [file("src/components/form/form-date-range-picker.tsx", "{components}/form/form-date-range-picker.tsx")] },
|
|
498
|
+
form: { name: "form", category: "group", registryDependencies: ["form-field-shell", "form-input", "form-select", "form-async-select", "form-textarea", "form-switch", "form-search-input", "form-password-input", "form-number-input", "form-phone-input", "form-date-input", "form-date-range-input", "form-date-picker", "form-date-range-picker"], files: [file("src/components/form/index.ts", "{components}/form/index.ts")] },
|
|
499
|
+
"empty-state": { name: "empty-state", category: "feedback", dependencies: ["lucide-react"], registryDependencies: ["button", "utils"], files: [file("src/components/feedback/empty-state.tsx", "{components}/feedback/empty-state.tsx")] },
|
|
500
|
+
"loading-state": { name: "loading-state", category: "feedback", dependencies: ["lucide-react"], registryDependencies: ["utils"], files: [file("src/components/feedback/loading-state.tsx", "{components}/feedback/loading-state.tsx")] },
|
|
501
|
+
"status-badge": { name: "status-badge", category: "feedback", registryDependencies: ["badge", "utils"], files: [file("src/components/feedback/status-badge.tsx", "{components}/feedback/status-badge.tsx")] },
|
|
502
|
+
feedback: { name: "feedback", category: "group", registryDependencies: ["empty-state", "loading-state", "status-badge"], files: [file("src/components/feedback/index.ts", "{components}/feedback/index.ts")] },
|
|
503
|
+
"description-list": { name: "description-list", category: "display", registryDependencies: ["card", "utils"], files: [file("src/components/display/description-list.tsx", "{components}/display/description-list.tsx")] },
|
|
504
|
+
progress: { name: "progress", category: "display", registryDependencies: ["utils"], files: [file("src/components/display/progress.tsx", "{components}/display/progress.tsx")] },
|
|
505
|
+
result: { name: "result", category: "display", dependencies: ["lucide-react"], registryDependencies: ["button", "utils"], files: [file("src/components/display/result.tsx", "{components}/display/result.tsx")] },
|
|
506
|
+
timeline: { name: "timeline", category: "display", registryDependencies: ["utils"], files: [file("src/components/display/timeline.tsx", "{components}/display/timeline.tsx")] },
|
|
507
|
+
"metric-grid": { name: "metric-grid", category: "display", registryDependencies: ["card", "utils"], files: [file("src/components/display/metric-grid.tsx", "{components}/display/metric-grid.tsx")] },
|
|
508
|
+
"info-card": { name: "info-card", category: "display", registryDependencies: ["card", "utils"], files: [file("src/components/display/info-card.tsx", "{components}/display/info-card.tsx")] },
|
|
509
|
+
"activity-feed": { name: "activity-feed", category: "display", registryDependencies: ["card", "utils"], files: [file("src/components/display/activity-feed.tsx", "{components}/display/activity-feed.tsx")] },
|
|
510
|
+
display: { name: "display", category: "group", registryDependencies: ["description-list", "progress", "result", "timeline", "metric-grid", "info-card", "activity-feed"], files: [file("src/components/display/index.ts", "{components}/display/index.ts")] },
|
|
511
|
+
"action-menu": { name: "action-menu", category: "actions", dependencies: ["lucide-react"], registryDependencies: ["button", "dropdown-menu", "utils"], files: [file("src/components/actions/action-menu.tsx", "{components}/actions/action-menu.tsx")] },
|
|
512
|
+
actions: { name: "actions", category: "group", registryDependencies: ["action-menu"], files: [file("src/components/actions/index.ts", "{components}/actions/index.ts")] },
|
|
513
|
+
"page-header": { name: "page-header", category: "layout", registryDependencies: ["utils"], files: [file("src/components/layout/page-header.tsx", "{components}/layout/page-header.tsx")] },
|
|
514
|
+
"stat-card": { name: "stat-card", category: "layout", registryDependencies: ["card", "utils"], files: [file("src/components/layout/stat-card.tsx", "{components}/layout/stat-card.tsx")] },
|
|
515
|
+
"app-shell": { name: "app-shell", category: "layout", dependencies: ["lucide-react"], registryDependencies: ["button", "utils"], files: [file("src/components/layout/app-shell.tsx", "{components}/layout/app-shell.tsx")] },
|
|
516
|
+
"app-header": { name: "app-header", category: "layout", registryDependencies: ["utils"], files: [file("src/components/layout/app-header.tsx", "{components}/layout/app-header.tsx")] },
|
|
517
|
+
"app-sidebar": { name: "app-sidebar", category: "layout", registryDependencies: ["utils"], files: [file("src/components/layout/app-sidebar.tsx", "{components}/layout/app-sidebar.tsx")] },
|
|
518
|
+
"sidebar-nav": { name: "sidebar-nav", category: "layout", registryDependencies: ["badge", "utils"], files: [file("src/components/layout/sidebar-nav.tsx", "{components}/layout/sidebar-nav.tsx")] },
|
|
519
|
+
breadcrumbs: { name: "breadcrumbs", category: "layout", dependencies: ["lucide-react"], registryDependencies: ["utils"], files: [file("src/components/layout/breadcrumbs.tsx", "{components}/layout/breadcrumbs.tsx")] },
|
|
520
|
+
"page-container": { name: "page-container", category: "layout", registryDependencies: ["utils"], files: [file("src/components/layout/page-container.tsx", "{components}/layout/page-container.tsx")] },
|
|
521
|
+
layout: { name: "layout", category: "group", registryDependencies: ["app-shell", "app-header", "app-sidebar", "page-header", "stat-card", "sidebar-nav", "breadcrumbs", "page-container"], files: [file("src/components/layout/index.ts", "{components}/layout/index.ts")] },
|
|
522
|
+
"filter-bar": { name: "filter-bar", category: "filters", dependencies: ["lucide-react"], registryDependencies: ["button", "utils"], files: [file("src/components/filters/filter-bar.tsx", "{components}/filters/filter-bar.tsx")] },
|
|
523
|
+
filters: { name: "filters", category: "group", registryDependencies: ["filter-bar"], files: [file("src/components/filters/index.ts", "{components}/filters/index.ts")] },
|
|
524
|
+
"data-table-toolbar": { name: "data-table-toolbar", category: "data-table", registryDependencies: ["utils"], files: [file("src/components/data-table/data-table-toolbar.tsx", "{components}/data-table/data-table-toolbar.tsx")] },
|
|
525
|
+
"data-table-pagination": { name: "data-table-pagination", category: "data-table", registryDependencies: ["pagination", "simple-select", "utils"], files: [file("src/components/data-table/data-table-pagination.tsx", "{components}/data-table/data-table-pagination.tsx")] },
|
|
526
|
+
"data-table-column-visibility-menu": { name: "data-table-column-visibility-menu", category: "data-table", dependencies: ["@tanstack/react-table", "lucide-react"], registryDependencies: ["button", "dropdown-menu", "utils"], files: [file("src/components/data-table/data-table-column-visibility-menu.tsx", "{components}/data-table/data-table-column-visibility-menu.tsx")] },
|
|
527
|
+
"data-table-select-column": { name: "data-table-select-column", category: "data-table", dependencies: ["@tanstack/react-table"], registryDependencies: ["checkbox", "utils"], files: [file("src/components/data-table/data-table-select-column.tsx", "{components}/data-table/data-table-select-column.tsx")] },
|
|
528
|
+
"data-table-sortable-header": { name: "data-table-sortable-header", category: "data-table", dependencies: ["@tanstack/react-table", "lucide-react"], registryDependencies: ["button", "utils"], files: [file("src/components/data-table/data-table-sortable-header.tsx", "{components}/data-table/data-table-sortable-header.tsx")] },
|
|
529
|
+
"data-table-row-actions": { name: "data-table-row-actions", category: "data-table", dependencies: ["@tanstack/react-table"], registryDependencies: ["action-menu"], files: [file("src/components/data-table/data-table-row-actions.tsx", "{components}/data-table/data-table-row-actions.tsx")] },
|
|
530
|
+
"data-table-actions-column": { name: "data-table-actions-column", category: "data-table", dependencies: ["@tanstack/react-table"], registryDependencies: ["data-table-row-actions", "utils"], files: [file("src/components/data-table/data-table-actions-column.tsx", "{components}/data-table/data-table-actions-column.tsx")] },
|
|
531
|
+
"data-table-bulk-actions": { name: "data-table-bulk-actions", category: "data-table", dependencies: ["lucide-react"], registryDependencies: ["action-menu", "button", "utils"], files: [file("src/components/data-table/data-table-bulk-actions.tsx", "{components}/data-table/data-table-bulk-actions.tsx")] },
|
|
532
|
+
"data-table-view-presets": { name: "data-table-view-presets", category: "data-table", registryDependencies: ["badge", "button", "utils"], files: [file("src/components/data-table/data-table-view-presets.tsx", "{components}/data-table/data-table-view-presets.tsx")] },
|
|
533
|
+
"data-table": { name: "data-table", category: "group", dependencies: ["@tanstack/react-table"], registryDependencies: ["table", "empty-state", "loading-state", "data-table-toolbar", "data-table-pagination", "data-table-column-visibility-menu", "data-table-select-column", "data-table-sortable-header", "data-table-row-actions", "data-table-actions-column", "data-table-bulk-actions", "data-table-view-presets", "utils"], files: [file("src/components/data-table/data-table.tsx", "{components}/data-table/data-table.tsx"), file("src/components/data-table/index.ts", "{components}/data-table/index.ts")] },
|
|
534
|
+
calendar: { name: "calendar", category: "calendar", dependencies: ["lucide-react"], registryDependencies: ["button", "utils"], files: [file("src/components/calendar/date-utils.ts", "{components}/calendar/date-utils.ts"), file("src/components/calendar/calendar.tsx", "{components}/calendar/calendar.tsx")] },
|
|
535
|
+
"date-picker": { name: "date-picker", category: "calendar", dependencies: ["lucide-react"], registryDependencies: ["calendar", "button", "popover", "utils"], files: [file("src/components/calendar/date-picker.tsx", "{components}/calendar/date-picker.tsx")] },
|
|
536
|
+
"date-range-picker": { name: "date-range-picker", category: "calendar", dependencies: ["lucide-react"], registryDependencies: ["calendar", "button", "popover", "utils"], files: [file("src/components/calendar/date-range-picker.tsx", "{components}/calendar/date-range-picker.tsx")] },
|
|
537
|
+
"calendar-kit": { name: "calendar-kit", category: "group", registryDependencies: ["calendar", "date-picker", "date-range-picker"], files: [file("src/components/calendar/index.ts", "{components}/calendar/index.ts")] },
|
|
538
|
+
"file-upload": { name: "file-upload", category: "upload", registryDependencies: ["button"], files: [file("src/components/upload/file-upload.tsx", "{components}/upload/file-upload.tsx")] },
|
|
539
|
+
"image-upload": { name: "image-upload", category: "upload", registryDependencies: ["file-upload"], files: [file("src/components/upload/image-upload.tsx", "{components}/upload/image-upload.tsx")] },
|
|
540
|
+
upload: { name: "upload", category: "group", registryDependencies: ["file-upload", "image-upload"], files: [file("src/components/upload/index.ts", "{components}/upload/index.ts")] },
|
|
541
|
+
stepper: { name: "stepper", category: "wizard", dependencies: ["lucide-react"], registryDependencies: ["utils"], files: [file("src/components/wizard/stepper.tsx", "{components}/wizard/stepper.tsx")] },
|
|
542
|
+
wizard: { name: "wizard", category: "wizard", registryDependencies: ["button", "stepper", "utils"], files: [file("src/components/wizard/wizard.tsx", "{components}/wizard/wizard.tsx")] },
|
|
543
|
+
"wizard-kit": { name: "wizard-kit", category: "group", registryDependencies: ["stepper", "wizard"], files: [file("src/components/wizard/index.ts", "{components}/wizard/index.ts")] },
|
|
544
|
+
toast: { name: "toast", category: "notifications", dependencies: ["lucide-react"], registryDependencies: ["button", "utils"], files: [file("src/components/notifications/toast.tsx", "{components}/notifications/toast.tsx")] },
|
|
545
|
+
notifications: { name: "notifications", category: "group", registryDependencies: ["toast"], files: [file("src/components/notifications/index.ts", "{components}/notifications/index.ts")] },
|
|
546
|
+
"command-palette": { name: "command-palette", category: "command", dependencies: ["lucide-react"], registryDependencies: ["dialog", "input", "utils"], files: [file("src/components/command/command-palette.tsx", "{components}/command/command-palette.tsx")] },
|
|
547
|
+
command: { name: "command", category: "group", registryDependencies: ["command-palette"], files: [file("src/components/command/index.ts", "{components}/command/index.ts")] },
|
|
548
|
+
"resource-page": { name: "resource-page", category: "patterns", registryDependencies: ["data-table", "page-header", "utils"], files: [file("src/components/patterns/resource-page.tsx", "{components}/patterns/resource-page.tsx")] },
|
|
549
|
+
"resource-detail-page": { name: "resource-detail-page", category: "patterns", registryDependencies: ["button", "description-list", "page-header", "utils"], files: [file("src/components/patterns/resource-detail-page.tsx", "{components}/patterns/resource-detail-page.tsx")] },
|
|
550
|
+
"form-builder": { name: "form-builder", category: "patterns", dependencies: ["react-hook-form"], registryDependencies: ["button", "form-input", "form-textarea", "form-select", "form-async-select", "form-switch", "form-number-input", "form-phone-input", "form-date-input", "form-date-range-input", "utils"], files: [file("src/components/patterns/form-builder.tsx", "{components}/patterns/form-builder.tsx")] },
|
|
551
|
+
"form-builder-presets": { name: "form-builder-presets", category: "patterns", dependencies: ["react-hook-form"], registryDependencies: ["form-builder"], files: [file("src/components/patterns/form-builder-presets.ts", "{components}/patterns/form-builder-presets.ts")] },
|
|
552
|
+
patterns: { name: "patterns", category: "group", registryDependencies: ["resource-page", "resource-detail-page", "form-builder", "form-builder-presets"], files: [file("src/components/patterns/index.ts", "{components}/patterns/index.ts")] },
|
|
553
|
+
"use-session-storage-state": { name: "use-session-storage-state", category: "hooks", files: [file("src/hooks/use-session-storage-state.ts", "{hooks}/use-session-storage-state.ts")] },
|
|
554
|
+
"use-before-unload-when-dirty": { name: "use-before-unload-when-dirty", category: "hooks", files: [file("src/hooks/use-before-unload-when-dirty.ts", "{hooks}/use-before-unload-when-dirty.ts")] },
|
|
555
|
+
"use-is-mobile": { name: "use-is-mobile", category: "hooks", files: [file("src/hooks/use-is-mobile.ts", "{hooks}/use-is-mobile.ts")] },
|
|
556
|
+
"use-disclosure": { name: "use-disclosure", category: "hooks", files: [file("src/hooks/use-disclosure.ts", "{hooks}/use-disclosure.ts")] },
|
|
557
|
+
"use-debounce": { name: "use-debounce", category: "hooks", files: [file("src/hooks/use-debounce.ts", "{hooks}/use-debounce.ts")] },
|
|
558
|
+
"use-data-table-view-state": { name: "use-data-table-view-state", category: "hooks", files: [file("src/hooks/use-data-table-view-state.ts", "{hooks}/use-data-table-view-state.ts")] },
|
|
559
|
+
hooks: { name: "hooks", category: "group", registryDependencies: ["use-session-storage-state", "use-before-unload-when-dirty", "use-is-mobile", "use-disclosure", "use-debounce", "use-data-table-view-state"], files: [file("src/hooks/index.ts", "{hooks}/index.ts")] },
|
|
560
|
+
dashboard: { name: "dashboard", category: "group", registryDependencies: ["layout", "actions", "filters", "feedback", "display", "data-table", "inputs", "form", "patterns", "notifications", "command"] },
|
|
561
|
+
all: { name: "all", category: "group", registryDependencies: ["dashboard", "overlay", "calendar-kit", "upload", "wizard-kit", "hooks"] }
|
|
562
|
+
};
|
|
563
|
+
var registryNames = Object.keys(registry);
|
|
564
|
+
|
|
565
|
+
// cli/commands/add.ts
|
|
566
|
+
function isComponentName(value) {
|
|
567
|
+
return value in registry;
|
|
568
|
+
}
|
|
569
|
+
function getPackageRoot() {
|
|
570
|
+
const currentDir = path4.dirname(fileURLToPath(import.meta.url));
|
|
571
|
+
const candidates = [
|
|
572
|
+
path4.resolve(currentDir, "../.."),
|
|
573
|
+
path4.resolve(currentDir, ".."),
|
|
574
|
+
process.cwd()
|
|
575
|
+
];
|
|
576
|
+
for (const candidate of candidates) {
|
|
577
|
+
const packageJsonPath = path4.join(candidate, "package.json");
|
|
578
|
+
if (!fs4.existsSync(packageJsonPath)) continue;
|
|
579
|
+
try {
|
|
580
|
+
const packageJson = fs4.readJsonSync(packageJsonPath);
|
|
581
|
+
if (packageJson.name === "azamat-ui-kit") return candidate;
|
|
582
|
+
} catch {
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
return path4.resolve(currentDir, "../..");
|
|
586
|
+
}
|
|
587
|
+
function getComponentsRoot(config) {
|
|
588
|
+
if (config.paths?.components) return config.paths.components;
|
|
589
|
+
const legacyComponentsPath = config.componentsPath ?? "src/components/ui";
|
|
590
|
+
return legacyComponentsPath.endsWith("/ui") || legacyComponentsPath.endsWith("\\ui") ? path4.dirname(legacyComponentsPath) : legacyComponentsPath;
|
|
591
|
+
}
|
|
592
|
+
function resolveTargetPath(target, config) {
|
|
593
|
+
const componentsRoot = getComponentsRoot(config);
|
|
594
|
+
const uiPath = config.paths?.ui ?? config.componentsPath ?? path4.join(componentsRoot, "ui");
|
|
595
|
+
const hooksPath = config.paths?.hooks ?? "src/hooks";
|
|
596
|
+
const libPath = config.paths?.lib ?? path4.dirname(config.utilsPath ?? "src/lib/utils.ts");
|
|
597
|
+
const utilsPath = config.utilsPath ?? path4.join(libPath, "utils.ts");
|
|
598
|
+
return target.replaceAll("{components}", componentsRoot).replaceAll("{ui}", uiPath).replaceAll("{hooks}", hooksPath).replaceAll("{lib}", libPath).replaceAll("{utils}", utilsPath);
|
|
599
|
+
}
|
|
600
|
+
function applyAlias(content, alias = "@") {
|
|
601
|
+
if (alias === "@") return content;
|
|
602
|
+
return content.replaceAll("@/", `${alias}/`);
|
|
603
|
+
}
|
|
604
|
+
function collectRegistryItems(componentNames) {
|
|
605
|
+
const collected = [];
|
|
606
|
+
const seen = /* @__PURE__ */ new Set();
|
|
607
|
+
function visit(componentName) {
|
|
608
|
+
if (seen.has(componentName)) return;
|
|
609
|
+
const item = registry[componentName];
|
|
610
|
+
item.registryDependencies?.forEach(visit);
|
|
611
|
+
seen.add(componentName);
|
|
612
|
+
collected.push(item);
|
|
613
|
+
}
|
|
614
|
+
componentNames.forEach(visit);
|
|
615
|
+
return collected;
|
|
616
|
+
}
|
|
617
|
+
function formatAvailableComponents() {
|
|
618
|
+
return registryNames.filter((name) => registry[name].category !== "lib").sort().join(", ");
|
|
619
|
+
}
|
|
620
|
+
async function addCommand(components, options = {}) {
|
|
621
|
+
const cwd = process.cwd();
|
|
622
|
+
const configPath = path4.join(cwd, "azamat-ui.json");
|
|
623
|
+
if (!fs4.existsSync(configPath)) {
|
|
624
|
+
logger.error("azamat-ui.json topilmadi. Avval init qiling:");
|
|
625
|
+
logger.info("npx azamat-ui-kit init");
|
|
626
|
+
process.exit(1);
|
|
627
|
+
}
|
|
628
|
+
if (!components.length) {
|
|
629
|
+
logger.error("Component nomini kiriting:");
|
|
630
|
+
logger.info("npx azamat-ui-kit add data-table async-select form-input");
|
|
631
|
+
logger.info(`Mavjud componentlar: ${formatAvailableComponents()}`);
|
|
632
|
+
process.exit(1);
|
|
633
|
+
}
|
|
634
|
+
const validComponents = [];
|
|
635
|
+
for (const componentName of components) {
|
|
636
|
+
if (!isComponentName(componentName)) {
|
|
637
|
+
logger.warn(`${componentName} registry ichida mavjud emas.`);
|
|
638
|
+
continue;
|
|
639
|
+
}
|
|
640
|
+
validComponents.push(componentName);
|
|
641
|
+
}
|
|
642
|
+
if (!validComponents.length) {
|
|
643
|
+
logger.error("Qo\u2018shish uchun valid component topilmadi.");
|
|
644
|
+
process.exit(1);
|
|
645
|
+
}
|
|
646
|
+
const config = await fs4.readJson(configPath);
|
|
647
|
+
const packageRoot = getPackageRoot();
|
|
648
|
+
const packageManager = detectPackageManager(cwd);
|
|
649
|
+
const items = collectRegistryItems(validComponents);
|
|
650
|
+
const dependenciesToInstall = /* @__PURE__ */ new Set();
|
|
651
|
+
for (const item of items) {
|
|
652
|
+
item.dependencies?.forEach((dep) => dependenciesToInstall.add(dep));
|
|
653
|
+
for (const file2 of item.files ?? []) {
|
|
654
|
+
const sourcePath = path4.join(packageRoot, file2.source);
|
|
655
|
+
const targetPath = path4.join(cwd, resolveTargetPath(file2.target, config));
|
|
656
|
+
if (!fs4.existsSync(sourcePath)) {
|
|
657
|
+
logger.warn(`${file2.source} topilmadi. O\u2018tkazib yuborildi.`);
|
|
658
|
+
continue;
|
|
659
|
+
}
|
|
660
|
+
if (options.dryRun) {
|
|
661
|
+
logger.info(`[dry-run] ${file2.source} -> ${path4.relative(cwd, targetPath)}`);
|
|
662
|
+
continue;
|
|
663
|
+
}
|
|
664
|
+
await fs4.ensureDir(path4.dirname(targetPath));
|
|
665
|
+
if (fs4.existsSync(targetPath) && !options.overwrite) {
|
|
666
|
+
logger.warn(`${path4.relative(cwd, targetPath)} allaqachon mavjud. O\u2018tkazib yuborildi.`);
|
|
667
|
+
continue;
|
|
668
|
+
}
|
|
669
|
+
const sourceContent = await fs4.readFile(sourcePath, "utf8");
|
|
670
|
+
await fs4.writeFile(targetPath, applyAlias(sourceContent, config.alias));
|
|
671
|
+
logger.success(`${path4.relative(cwd, targetPath)} qo\u2018shildi.`);
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
if (!options.skipInstall && dependenciesToInstall.size > 0 && !options.dryRun) {
|
|
675
|
+
await installPackages({
|
|
676
|
+
cwd,
|
|
677
|
+
packageManager,
|
|
678
|
+
packages: Array.from(dependenciesToInstall)
|
|
679
|
+
});
|
|
680
|
+
}
|
|
681
|
+
logger.success("Componentlar muvaffaqiyatli qo\u2018shildi.");
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
// cli/commands/list.ts
|
|
685
|
+
function listCommand() {
|
|
686
|
+
const grouped = registryNames.filter((name) => registry[name].category !== "lib").reduce((acc, name) => {
|
|
687
|
+
const category = registry[name].category;
|
|
688
|
+
acc[category] ??= [];
|
|
689
|
+
acc[category].push(name);
|
|
690
|
+
return acc;
|
|
691
|
+
}, {});
|
|
692
|
+
for (const [category, names] of Object.entries(grouped)) {
|
|
693
|
+
console.log(`
|
|
694
|
+
${category}`);
|
|
695
|
+
names.sort().forEach((name) => {
|
|
696
|
+
const item = registry[name];
|
|
697
|
+
const deps = item.registryDependencies?.length ? ` -> ${item.registryDependencies.join(", ")}` : "";
|
|
698
|
+
console.log(` ${name}${deps}`);
|
|
699
|
+
});
|
|
700
|
+
}
|
|
701
|
+
console.log("\nUsage:");
|
|
702
|
+
console.log(" npx azamat-ui-kit add button input data-table");
|
|
703
|
+
console.log(" npx azamat-ui-kit add form --overwrite");
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
// cli/commands/theme.ts
|
|
707
|
+
import path5 from "path";
|
|
708
|
+
import fs5 from "fs-extra";
|
|
709
|
+
async function themeCommand(cssPathArg) {
|
|
710
|
+
const cwd = process.cwd();
|
|
711
|
+
const configPath = path5.join(cwd, "azamat-ui.json");
|
|
712
|
+
const config = fs5.existsSync(configPath) ? await fs5.readJson(configPath) : {};
|
|
713
|
+
const cssPath = cssPathArg ?? config.cssPath ?? config.globalCssPath ?? "src/index.css";
|
|
714
|
+
const targetPath = await upsertThemeCss({ cwd, cssPath });
|
|
715
|
+
logger.success(`Azamat UI theme CSS yangilandi: ${targetPath}`);
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
// cli/index.ts
|
|
719
|
+
var program = new Command();
|
|
720
|
+
program.name("azamat-ui-kit").description("Azamat UI Kit CLI").version("0.0.1");
|
|
721
|
+
program.command("init").description("Initialize Azamat UI Kit in your project").action(initCommand);
|
|
722
|
+
program.command("list").description("List available registry components").action(listCommand);
|
|
723
|
+
program.command("add").description("Add components to your project").argument("[components...]", "components to add").option("-o, --overwrite", "overwrite existing files").option("--dry-run", "show files without writing").option("--skip-install", "do not install package dependencies").action(addCommand);
|
|
724
|
+
program.command("theme").description("Write or update Azamat UI theme CSS in your global CSS file").argument("[cssPath]", "global CSS path, default from azamat-ui.json or src/index.css").action(themeCommand);
|
|
725
|
+
program.parse();
|