untitledui 0.1.5 → 0.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. package/config/postcss.config.mjs +6 -0
  2. package/{templates/default/src → config}/styles/globals.css +2 -33
  3. package/{templates/default/src → config}/styles/theme.css +31 -33
  4. package/{templates/default/src → config}/styles/typography.css +24 -24
  5. package/dist/index.mjs +54 -15
  6. package/package.json +4 -3
  7. package/templates/default/.prettierrc +0 -10
  8. package/templates/default/README.md +0 -36
  9. package/templates/default/eslint.config.mjs +0 -58
  10. package/templates/default/next.config.ts +0 -6
  11. package/templates/default/package.json +0 -56
  12. package/templates/default/postcss.config.js +0 -5
  13. package/templates/default/public/favicon.ico +0 -0
  14. package/templates/default/public/marketing/smiling-girl.png +0 -0
  15. package/templates/default/public/marketing/spirals.webp +0 -0
  16. package/templates/default/src/app/home-screen.tsx +0 -108
  17. package/templates/default/src/app/layout.tsx +0 -34
  18. package/templates/default/src/app/not-found.tsx +0 -40
  19. package/templates/default/src/app/page.tsx +0 -3
  20. package/templates/default/src/components/foundations/dot-icon.tsx +0 -27
  21. package/templates/default/src/components/foundations/featured-icon/featured-icons.tsx +0 -153
  22. package/templates/default/src/components/foundations/logo/UntitledLogo.tsx +0 -63
  23. package/templates/default/src/components/foundations/logo/UntitledLogoMinimal.tsx +0 -164
  24. package/templates/default/src/components/foundations/payment-icons/amex-icon.tsx +0 -19
  25. package/templates/default/src/components/foundations/payment-icons/apple-pay-icon.tsx +0 -27
  26. package/templates/default/src/components/foundations/payment-icons/discover-icon.tsx +0 -34
  27. package/templates/default/src/components/foundations/payment-icons/index.tsx +0 -10
  28. package/templates/default/src/components/foundations/payment-icons/mastercard-icon.tsx +0 -39
  29. package/templates/default/src/components/foundations/payment-icons/paypal-icon.tsx +0 -45
  30. package/templates/default/src/components/foundations/payment-icons/stripe-icon.tsx +0 -27
  31. package/templates/default/src/components/foundations/payment-icons/union-pay-icon.tsx +0 -37
  32. package/templates/default/src/components/foundations/payment-icons/visa-icon.tsx +0 -27
  33. package/templates/default/src/components/marketing/header-navigation/base-components/nav-menu-item.tsx +0 -41
  34. package/templates/default/src/components/marketing/header-navigation/components/header.tsx +0 -245
  35. package/templates/default/src/components/marketing/header-navigation/dropdown-header-navigation.tsx +0 -53
  36. package/templates/default/src/components/shared/avatar/avatar-label-group.tsx +0 -32
  37. package/templates/default/src/components/shared/avatar/avatar-profile-photo.tsx +0 -84
  38. package/templates/default/src/components/shared/avatar/avatar.tsx +0 -131
  39. package/templates/default/src/components/shared/avatar/base-components/avatar-add-button.tsx +0 -33
  40. package/templates/default/src/components/shared/avatar/base-components/avatar-company-icon.tsx +0 -26
  41. package/templates/default/src/components/shared/avatar/base-components/avatar-online-indicator.tsx +0 -31
  42. package/templates/default/src/components/shared/avatar/base-components/index.ts +0 -4
  43. package/templates/default/src/components/shared/avatar/base-components/verified-tick.tsx +0 -34
  44. package/templates/default/src/components/shared/avatar/utils.ts +0 -12
  45. package/templates/default/src/components/shared/badges/badge-groups.tsx +0 -176
  46. package/templates/default/src/components/shared/badges/badge-types.ts +0 -264
  47. package/templates/default/src/components/shared/badges/badges.tsx +0 -479
  48. package/templates/default/src/components/shared/button-group/button-group.tsx +0 -97
  49. package/templates/default/src/components/shared/buttons/app-store-buttons-outline.tsx +0 -454
  50. package/templates/default/src/components/shared/buttons/app-store-buttons.tsx +0 -806
  51. package/templates/default/src/components/shared/buttons/button-utility.tsx +0 -87
  52. package/templates/default/src/components/shared/buttons/button.tsx +0 -285
  53. package/templates/default/src/components/shared/buttons/close-button.tsx +0 -39
  54. package/templates/default/src/components/shared/buttons/social-button.tsx +0 -135
  55. package/templates/default/src/components/shared/buttons/social-logos.tsx +0 -115
  56. package/templates/default/src/components/shared/checkbox/checkbox.tsx +0 -120
  57. package/templates/default/src/components/shared/dropdown/dropdown.tsx +0 -147
  58. package/templates/default/src/components/shared/file-upload-trigger/file-upload-trigger.tsx +0 -74
  59. package/templates/default/src/components/shared/form/form.tsx +0 -10
  60. package/templates/default/src/components/shared/form/hook-form.tsx +0 -75
  61. package/templates/default/src/components/shared/input/hint-text.tsx +0 -34
  62. package/templates/default/src/components/shared/input/index.tsx +0 -189
  63. package/templates/default/src/components/shared/input/input-payment.tsx +0 -134
  64. package/templates/default/src/components/shared/input/input-with-button.tsx +0 -69
  65. package/templates/default/src/components/shared/input/input-with-dropdown.tsx +0 -178
  66. package/templates/default/src/components/shared/input/input-with-prefix.tsx +0 -74
  67. package/templates/default/src/components/shared/input/label.tsx +0 -46
  68. package/templates/default/src/components/shared/progress-indicators/progress-circles.tsx +0 -176
  69. package/templates/default/src/components/shared/progress-indicators/progress-indicators.tsx +0 -86
  70. package/templates/default/src/components/shared/progress-indicators/simple-circle.tsx +0 -29
  71. package/templates/default/src/components/shared/radio-buttons/radio-buttons.tsx +0 -125
  72. package/templates/default/src/components/shared/radio-groups/radio-group-avatar.tsx +0 -62
  73. package/templates/default/src/components/shared/radio-groups/radio-group-checkbox.tsx +0 -72
  74. package/templates/default/src/components/shared/radio-groups/radio-group-icon-card.tsx +0 -95
  75. package/templates/default/src/components/shared/radio-groups/radio-group-icon-simple.tsx +0 -70
  76. package/templates/default/src/components/shared/radio-groups/radio-group-payment-icon.tsx +0 -71
  77. package/templates/default/src/components/shared/radio-groups/radio-group-radio-button.tsx +0 -76
  78. package/templates/default/src/components/shared/radio-groups/radio-groups.tsx +0 -8
  79. package/templates/default/src/components/shared/select/combobox.tsx +0 -161
  80. package/templates/default/src/components/shared/select/multi-select.tsx +0 -373
  81. package/templates/default/src/components/shared/select/popover.tsx +0 -36
  82. package/templates/default/src/components/shared/select/select-item.tsx +0 -70
  83. package/templates/default/src/components/shared/select/select-native.tsx +0 -63
  84. package/templates/default/src/components/shared/select/select.tsx +0 -143
  85. package/templates/default/src/components/shared/slider/slider.tsx +0 -76
  86. package/templates/default/src/components/shared/tags/base-components/tag-checkbox.tsx +0 -47
  87. package/templates/default/src/components/shared/tags/base-components/tag-close-x.tsx +0 -34
  88. package/templates/default/src/components/shared/tags/tags.tsx +0 -162
  89. package/templates/default/src/components/shared/textarea/textarea.tsx +0 -82
  90. package/templates/default/src/components/shared/toggle/toggle.tsx +0 -140
  91. package/templates/default/src/components/shared/tooltips/tooltips.tsx +0 -140
  92. package/templates/default/src/components/utils/index.ts +0 -48
  93. package/templates/default/src/components/utils/isDeepEqual.ts +0 -31
  94. package/templates/default/src/components/utils/isReactComponent.ts +0 -22
  95. package/templates/default/src/components/utils/mergeRefs.ts +0 -19
  96. package/templates/default/src/components/utils/useBreakpoint.ts +0 -36
  97. package/templates/default/src/components/utils/uuid.ts +0 -9
  98. package/templates/default/src/hooks/use-resize-observer.tsx +0 -55
  99. package/templates/default/src/providers/theme.tsx +0 -11
  100. package/templates/default/src/styles/text-styles.css +0 -177
  101. package/templates/default/tsconfig.json +0 -27
@@ -0,0 +1,6 @@
1
+ export default {
2
+ plugins: {
3
+ "@tailwindcss/postcss": {},
4
+ }
5
+ }
6
+
@@ -1,33 +1,10 @@
1
1
  @import "tailwindcss";
2
+ @import "./theme.css";
3
+ @import "./typography.css";
2
4
 
3
5
  @plugin "@tailwindcss/typography";
4
6
  @plugin "tailwindcss-react-aria-components";
5
7
  @plugin "tailwindcss-animate";
6
- @plugin "@designbycode/tailwindcss-mask-image";
7
-
8
- @import "./theme.css";
9
- @import "./text-styles.css";
10
- @import "./typography.css";
11
-
12
- @source "../components/application/code-snippet/code-snippet.style.css";
13
-
14
- /*
15
- The default border color has changed to `currentColor` in Tailwind CSS v4,
16
- so we've added these compatibility styles to make sure everything still
17
- looks the same as it did with Tailwind CSS v3.
18
-
19
- If we ever want to remove these styles, we need to add an explicit border
20
- color utility to any element that depends on these defaults.
21
- */
22
- @layer base {
23
- *,
24
- ::after,
25
- ::before,
26
- ::backdrop,
27
- ::file-selector-button {
28
- border-color: var(--color-gray-200, currentColor);
29
- }
30
- }
31
8
 
32
9
  @custom-variant dark (&:where(.dark-mode, .dark-mode *));
33
10
  @custom-variant label (& [data-label]);
@@ -45,14 +22,6 @@
45
22
  scrollbar-width: none; /* Firefox */
46
23
  }
47
24
 
48
- @utility animation-duration-150 {
49
- animation-duration: 150ms;
50
- }
51
-
52
- @utility animation-duration-300 {
53
- animation-duration: 300ms;
54
- }
55
-
56
25
  @utility transition-inherit-all {
57
26
  transition-property: inherit;
58
27
  transition-duration: inherit;
@@ -1,9 +1,4 @@
1
1
  @theme {
2
- /* BREAKPOINTS */
3
- --breakpoint-xxs: 320px;
4
- /* This must match the breakpoint in sonner: https://github.com/emilkowalski/sonner/blob/main/src/styles.css */
5
- --breakpoint-xs: 600px;
6
-
7
2
  /* FONT FAMILY */
8
3
  --font-body: var(--font-inter, "Inter"), -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
9
4
  --font-display: var(--font-inter, "Inter"), -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
@@ -11,39 +6,50 @@
11
6
 
12
7
  /* FONT SIZE */
13
8
  --text-xs: calc(var(--spacing) * 3);
9
+ --text-xs--line-height: calc(var(--spacing) * 4.5);
10
+
14
11
  --text-sm: calc(var(--spacing) * 3.5);
12
+ --text-sm--line-height: calc(var(--spacing) * 5);
13
+
15
14
  --text-md: calc(var(--spacing) * 4);
15
+ --text-md--line-height: calc(var(--spacing) * 6);
16
+
16
17
  --text-lg: calc(var(--spacing) * 4.5);
18
+ --text-lg--line-height: calc(var(--spacing) * 7);
19
+
17
20
  --text-xl: calc(var(--spacing) * 5);
21
+ --text-xl--line-height: calc(var(--spacing) * 7.5);
22
+
18
23
  --text-display-xs: calc(var(--spacing) * 6);
24
+ --text-display-xs--line-height: calc(var(--spacing) * 8);
25
+
19
26
  --text-display-sm: calc(var(--spacing) * 7.5);
27
+ --text-display-sm--line-height: calc(var(--spacing) * 9.5);
28
+
20
29
  --text-display-md: calc(var(--spacing) * 9);
30
+ --text-display-md--line-height: calc(var(--spacing) * 11);
31
+ --text-display-md--letter-spacing: -0.72px;
32
+
21
33
  --text-display-lg: calc(var(--spacing) * 12);
34
+ --text-display-lg--line-height: calc(var(--spacing) * 15);
35
+ --text-display-lg--letter-spacing: -0.96px;
36
+
22
37
  --text-display-xl: calc(var(--spacing) * 15);
23
- --text-display-2xl: calc(var(--spacing) * 18);
38
+ --text-display-xl--line-height: calc(var(--spacing) * 18);
39
+ --text-display-xl--letter-spacing: -1.2px;
24
40
 
25
- /* LINE HEIGHT */
26
- --leading-xs: calc(var(--spacing) * 4.5);
27
- --leading-sm: calc(var(--spacing) * 5);
28
- --leading-md: calc(var(--spacing) * 6);
29
- --leading-lg: calc(var(--spacing) * 7);
30
- --leading-xl: calc(var(--spacing) * 7.5);
31
- --leading-display-xs: calc(var(--spacing) * 8);
32
- --leading-display-sm: calc(var(--spacing) * 9.5);
33
- --leading-display-md: calc(var(--spacing) * 11);
34
- --leading-display-lg: calc(var(--spacing) * 15);
35
- --leading-display-xl: calc(var(--spacing) * 18);
36
- --leading-display-2xl: calc(var(--spacing) * 22.5);
37
-
38
- /* LETTER SPACING */
39
- --tracking-display-md: -0.72px;
40
- --tracking-display-lg: -0.96px;
41
- --tracking-display-xl: -1.2px;
42
- --tracking-display-2xl: -1.44px;
41
+ --text-display-2xl: calc(var(--spacing) * 18);
42
+ --text-display-2xl--line-height: calc(var(--spacing) * 22.5);
43
+ --text-display-2xl--letter-spacing: -1.44px;
43
44
 
44
45
  /* MAX WIDTH */
45
46
  --max-width-container: 1280px;
46
47
 
48
+ /* BREAKPOINTS */
49
+ --breakpoint-xxs: 320px;
50
+ /* This must match the breakpoint in sonner: https://github.com/emilkowalski/sonner/blob/main/src/styles.css */
51
+ --breakpoint-xs: 600px;
52
+
47
53
  /* RADUIS */
48
54
  --radius-none: 0px;
49
55
  --radius-xs: 0.25rem;
@@ -783,10 +789,6 @@
783
789
  --color-focus-ring: var(--color-brand-500);
784
790
  --color-footer-button-fg: var(--color-brand-200);
785
791
  --color-footer-button-fg_hover: var(--color-white);
786
- --color-header-abstract-100-bg: var(--color-brand-100);
787
- --color-header-abstract-200-bg: var(--color-brand-200);
788
- --color-header-abstract-300-bg: var(--color-brand-300);
789
- --color-header-abstract-50-bg: var(--color-brand-50);
790
792
  --color-icon-fg-brand: var(--color-brand-600);
791
793
  --color-icon-fg-brand_on-brand: var(--color-brand-200);
792
794
  /* THESE NEED TO BE REMOED */
@@ -1122,7 +1124,7 @@
1122
1124
  --color-border-disabled_subtle: var(--color-gray-dark-mode-800);
1123
1125
  --color-border-tertiary: var(--color-gray-dark-mode-800);
1124
1126
  --color-border-brand_alt: var(--color-gray-dark-mode-700);
1125
- --color-border-secondary_alt: var(--color-gray-dark-mode-700);
1127
+ --color-border-secondary_alt: var(--color-gray-dark-mode-800);
1126
1128
 
1127
1129
  /* FOREGROUND COLORS */
1128
1130
  --color-fg-secondary: var(--color-gray-dark-mode-300);
@@ -1199,10 +1201,6 @@
1199
1201
  --color-focus-ring: var(--color-brand-500);
1200
1202
  --color-footer-button-fg: var(--color-gray-dark-mode-300);
1201
1203
  --color-footer-button-fg_hover: var(--color-gray-dark-mode-100);
1202
- --color-header-abstract-100-bg: var(--color-gray-dark-mode-800);
1203
- --color-header-abstract-200-bg: var(--color-gray-dark-mode-700);
1204
- --color-header-abstract-300-bg: var(--color-gray-dark-mode-600);
1205
- --color-header-abstract-50-bg: var(--color-gray-dark-mode-900);
1206
1204
  --color-icon-fg-brand: var(--color-gray-dark-mode-400);
1207
1205
  --color-icon-fg-brand_on-brand: var(--color-gray-dark-mode-400);
1208
1206
  --color-nav-item-button-icon-fg: var(--color-gray-dark-mode-400);
@@ -21,7 +21,7 @@
21
21
  /* Base */
22
22
  color: var(--tw-prose-body);
23
23
  font-size: var(--text-md);
24
- line-height: var(--leading-md);
24
+ line-height: var(--text-md--line-height);
25
25
  }
26
26
 
27
27
  .prose :not(:where([class~="not-prose"], [class~="not-prose"] *)) {
@@ -33,7 +33,7 @@
33
33
 
34
34
  &:where([class~="lead"]) {
35
35
  font-size: var(--text-md);
36
- line-height: var(--leading-md);
36
+ line-height: var(--text-md--line-height);
37
37
  margin-top: 1.2em;
38
38
  margin-bottom: 1.2em;
39
39
  }
@@ -91,7 +91,7 @@
91
91
  font-style: italic;
92
92
 
93
93
  font-size: var(--text-xl);
94
- line-height: var(--leading-xl);
94
+ line-height: var(--text-xl--line-height);
95
95
  }
96
96
  &:where(blockquote p:first-of-type::before) {
97
97
  content: open-quote;
@@ -106,7 +106,7 @@
106
106
  font-weight: 600;
107
107
 
108
108
  font-size: var(--text-display-sm);
109
- line-height: var(--leading-display-sm);
109
+ line-height: var(--text-display-sm--line-height);
110
110
  margin-bottom: calc(var(--spacing) * 5);
111
111
  margin-top: calc(var(--spacing) * 10);
112
112
  }
@@ -115,7 +115,7 @@
115
115
  font-weight: 600;
116
116
 
117
117
  font-size: var(--text-display-xs);
118
- line-height: var(--leading-display-xs);
118
+ line-height: var(--text-display-xs--line-height);
119
119
  margin-bottom: calc(var(--spacing) * 4);
120
120
  margin-top: calc(var(--spacing) * 8);
121
121
  }
@@ -124,7 +124,7 @@
124
124
  font-weight: 600;
125
125
 
126
126
  font-size: var(--text-xl);
127
- line-height: var(--leading-xl);
127
+ line-height: var(--text-xl--line-height);
128
128
  margin-bottom: calc(var(--spacing) * 3);
129
129
  margin-top: calc(var(--spacing) * 8);
130
130
  }
@@ -133,7 +133,7 @@
133
133
  font-weight: 600;
134
134
 
135
135
  font-size: var(--text-lg);
136
- line-height: var(--leading-lg);
136
+ line-height: var(--text-lg--line-height);
137
137
  margin-bottom: calc(var(--spacing) * 2);
138
138
  margin-top: calc(var(--spacing) * 5);
139
139
  }
@@ -208,7 +208,7 @@
208
208
  color: var(--tw-prose-captions);
209
209
 
210
210
  font-size: var(--text-sm);
211
- line-height: var(--leading-sm);
211
+ line-height: var(--text-sm--line-height);
212
212
  margin-top: calc(var(--spacing) * 3);
213
213
  }
214
214
  &:where(cite) {
@@ -236,10 +236,10 @@
236
236
  /* Inline code element */
237
237
  &:where(code:not(pre code)) {
238
238
  font-weight: 600;
239
- border-radius: 4px;
240
- padding: 1px 2px;
241
- margin: -1px -2px;
242
- background: var(--color-bg-tertiary);
239
+ border-radius: 6px;
240
+ padding: 4px 8px;
241
+ margin: -2px 0px;
242
+ background: var(--color-bg-secondary);
243
243
  box-shadow: 0 0 0 1px var(--color-border-secondary);
244
244
 
245
245
  &::before,
@@ -279,7 +279,7 @@
279
279
  @media (width >= 48rem /* 768px */) {
280
280
  /* Base */
281
281
  font-size: var(--text-lg);
282
- line-height: var(--leading-lg);
282
+ line-height: var(--text-lg--line-height);
283
283
  }
284
284
  }
285
285
 
@@ -293,7 +293,7 @@
293
293
 
294
294
  &:where([class~="lead"]) {
295
295
  font-size: var(--text-xl);
296
- line-height: var(--leading-xl);
296
+ line-height: var(--text-xl--line-height);
297
297
  margin-top: 1.09em;
298
298
  margin-bottom: 1.09em;
299
299
  }
@@ -337,31 +337,31 @@
337
337
  margin: 0;
338
338
 
339
339
  font-size: var(--text-display-xs);
340
- line-height: var(--leading-display-xs);
340
+ line-height: var(--text-display-xs--line-height);
341
341
  }
342
342
 
343
343
  /* Headings */
344
344
  &:where(h1) {
345
345
  font-size: var(--text-display-md);
346
- line-height: var(--leading-display-md);
346
+ line-height: var(--text-display-md--line-height);
347
347
  margin-bottom: calc(var(--spacing) * 6);
348
348
  margin-top: calc(var(--spacing) * 12);
349
349
  }
350
350
  &:where(h2) {
351
351
  font-size: var(--text-display-sm);
352
- line-height: var(--leading-display-sm);
352
+ line-height: var(--text-display-sm--line-height);
353
353
  margin-bottom: calc(var(--spacing) * 5);
354
354
  margin-top: calc(var(--spacing) * 10);
355
355
  }
356
356
  &:where(h3) {
357
357
  font-size: var(--text-display-xs);
358
- line-height: var(--leading-display-xs);
358
+ line-height: var(--text-display-xs--line-height);
359
359
  margin-bottom: calc(var(--spacing) * 4);
360
360
  margin-top: calc(var(--spacing) * 8);
361
361
  }
362
362
  &:where(h4) {
363
363
  font-size: var(--text-xl);
364
- line-height: var(--leading-xl);
364
+ line-height: var(--text-xl--line-height);
365
365
  margin-bottom: calc(var(--spacing) * 3);
366
366
  margin-top: calc(var(--spacing) * 8);
367
367
  }
@@ -388,7 +388,7 @@
388
388
  }
389
389
  &:where(figure > blockquote + figcaption) {
390
390
  font-size: var(--text-md);
391
- line-height: var(--leading-md);
391
+ line-height: var(--text-md--line-height);
392
392
  }
393
393
 
394
394
  &:where(figcaption) {
@@ -410,10 +410,10 @@
410
410
  /* Inline code element */
411
411
  &:where(code:not(pre code)) {
412
412
  font-weight: 600;
413
- border-radius: 4px;
414
- padding: 1px 2px;
415
- margin: -1px -2px;
416
- background: var(--color-bg-tertiary);
413
+ border-radius: 6px;
414
+ padding: 4px 8px;
415
+ margin: -2px 0px;
416
+ background: var(--color-bg-secondary);
417
417
  box-shadow: 0 0 0 1px var(--color-border-secondary);
418
418
  }
419
419
  }
package/dist/index.mjs CHANGED
@@ -1,19 +1,58 @@
1
1
  #!/usr/bin/env node
2
- import{Command as $0}from"commander";import N3 from"async-retry";import v from"chalk";import{Command as s3}from"commander";import{execa as p}from"execa";import*as E from"fs";import g from"ora";import n3 from"os";import*as u from"path";import h from"prompts";import{Project as a3}from"ts-morph";import V3 from"node-fetch";import{posix as w3,sep as x3}from"path";import{Readable as T3,pipeline as y3}from"stream";import{x as S3}from"tar";import{promisify as C3}from"util";var k3=C3(y3);async function L3(z,W){try{let Q=await F3(W);await k3(Q,S3({cwd:z,strip:2,filter:(Y)=>{return Y.split(x3).join(w3.sep).includes(W.template||"basic-form")}}))}catch(Q){throw new Error(`Failed to download or extract repository from API: ${Q instanceof Error?Q.message:Q}`)}}async function F3(z){try{let Q=await V3("https://untitledui-docs.vercel.app/api/download-repo",{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/octet-stream"},body:JSON.stringify(z)});if(Q.status===403||Q.status===404)throw new Error(z.key?"License key is invalid or expired":"Repository not found");if(!Q.ok)throw new Error(`Failed to download from API. Status: ${Q.status} ${Q.statusText}`);if(!Q.body)throw new Error("Response body is empty");return T3.from(Q.body)}catch(Q){throw new Error(`Error downloading tarball: ${Q instanceof Error?Q.message:Q}`)}}async function P(z){let W=`https://untitledui-docs.vercel.app/api/validate-key?key=${z}`;try{return(await V3(W)).status===200}catch{return!1}}import O3 from"node-fetch";async function z3(z,W,Q){try{return await(await O3("https://untitledui-docs.vercel.app/api/components",{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify({type:z,components:W,key:Q})})).json()}catch(X){return console.error(X),null}}import J3 from"node-fetch";async function M3(z,W=""){let Q=`https://untitledui-docs.vercel.app/api/components/list?key=${W}&type=${z}`;try{let X=await(await J3(Q)).json();if(!X?.components?.length)return null;return X}catch(Y){return console.error(Y),null}}async function G3(z=""){let W=`https://untitledui-docs.vercel.app/api/components/list?key=${z}`;try{let Y=await(await J3(W)).json();if(!Y?.types?.length)return null;return Y}catch(Q){return console.error(Q),null}}import f3 from"fast-glob";import*as I3 from"fs";import*as Q3 from"path";import{Project as l3}from"ts-morph";import{loadConfig as j3}from"tsconfig-paths";import P3 from"prettier";async function H3(z,W="typescript"){try{return await P3.format(z,{parser:W})}catch(Q){return console.error("Error formatting with Prettier:",Q),z}}import r from"fast-glob";import*as l from"fs";import*as c from"path";import{loadConfig as g3}from"tsconfig-paths";var S=["**/node_modules/**",".next","public","dist","build"];async function s(z){let W=l.existsSync(c.resolve(z,"src")),Q=l.existsSync(c.resolve(z,`${W?"src/":""}app`)),[Y,X,V,Z]=await Promise.all([r.glob("**/{next,vite,astro}.config.*|gatsby-config.*",{cwd:z,deep:2,ignore:S}),h3(z),m3(z),d3(z)]),L={framework:"other",isTsx:X,tailwindFile:V||null,aliasPrefix:Z,isSrcDir:W,isUsingAppDir:Q};if(Y.find((B)=>B.startsWith("next.config."))?.length)return L.framework=Q?"next-app":"next-pages",L;else if(Y?.length||l.existsSync(c.resolve(z,"package.json")))return L.framework="other",L;return null}async function h3(z){return(await r.glob("tsconfig.*",{cwd:z,deep:2,ignore:S})).length>0}async function m3(z){let W=await r.glob("tailwind.config.*",{cwd:z,deep:2,ignore:S});if(!W.length)return null;return W[0]}async function d3(z){let W=await g3(z);if(W?.resultType==="failed"||!Object.keys(W.paths).length)return null;let Q={};for(let[Y,X]of Object.entries(W.paths)){let V=Y.replace(/\/\*$/,"/");if(X.some((Z)=>Z.includes("/app/*")))Q.appPrefix=V;else if(X.some((Z)=>Z.includes("/components/*")))Q.componentsPrefix=V;else if(X.some((Z)=>Z.includes("/utils/*")))Q.utilsPrefix=V;else if(X.some((Z)=>Z.includes("/styles/*")))Q.stylesPrefix=V;else if(X.some((Z)=>Z.includes("./*")||Z.includes("/src/*")))Q.srcPrefix=V}return Q||null}function n(z){let W=j3(z),Q=f3.sync(["tailwind.config.*","**/globals.css","**/{layout,_app}.tsx","package.json"],{cwd:z,deep:4,absolute:!0,onlyFiles:!0,ignore:S}),Y={tailwindFile:Q.find((X)=>X.includes("tailwind.config.")),cssFile:Q.find((X)=>X.includes("globals.css")),layoutFile:Q.find((X)=>X.includes("layout")),appFile:Q.find((X)=>X.includes("_app")),packageJson:Q.find((X)=>X.includes("package.json")),tsConfig:W?.resultType==="success"?W?.configFileAbsolutePath:void 0};if(W.resultType==="failed")throw new Error(`Failed to load tsconfig.json. ${W.message??""}`.trim());return Y}function X3(z,W,Q){if(z.includes("components")){if(W?.componentsPrefix)return z.replace(/@\/components\//,Q3.join(W?.componentsPrefix,Q?Q.replace(/components\//,""):"","/"));if(Q)return z.replace(/@\/components\//,Q3.join(W?.srcPrefix||"@/",Q,"/"))}if(z.includes("app")&&W?.appPrefix)return z.replace(/^@\/app\//,W?.appPrefix);if(z.includes("utils")&&W?.utilsPrefix)return z.replace(/^@\/utils\//,W?.utilsPrefix);if(z.includes("styles")&&W?.stylesPrefix)return z.replace(/^@\/styles\//,W?.stylesPrefix);if(W?.srcPrefix)return z.replace(/^@\//,W?.srcPrefix);return z}async function R3(z,W,Q="@/*"){let Y=await j3(z);if(Y?.resultType==="failed")return null;let X={};if(!Object.keys(Y.paths).length){Y.paths={[Q]:[`./${W?"src/":""}*`]},X.srcPrefix=Q.replace(/\/\*$/,"");let V=await I3.promises.readFile(Y.configFileAbsolutePath,"utf-8"),Z;if(!V.includes('"paths":'))Z=V.replace(/"compilerOptions":\s*{/,`"compilerOptions": {
3
- "paths": ${JSON.stringify(Y.paths)},`);else Z=V.replace(/"paths":\s*{[^}]*}/,`"paths": ${JSON.stringify(Y.paths)}`);let L=new l3,B=await H3(Z,"json");return L.createSourceFile(Y.configFileAbsolutePath,B,{overwrite:!0}),await L.save(),X}return X||null}import c3 from"node-fetch";async function r3(){try{return await(await c3("https://untitledui-docs.vercel.app/api/get-pkg")).json()}catch(W){return console.error(W),null}}async function a({dependencies:z,devDependencies:W,shouldThrow:Q=!0}){let Y=await r3();if(!Y)if(Q)throw new Error("package.json not found");else return null;let X=[],V=[];if(z)z.forEach((Z)=>{if(Y.dependencies?.[Z])X.push(`${Z}@${Y.dependencies[Z]}`)});if(W)W.forEach((Z)=>{if(Y.devDependencies?.[Z])V.push(`${Z}@${Y.devDependencies[Z]}`)});return{dependencies:X,devDependencies:V}}function D(){if("bun/1.2.4 npm/? node/v22.6.0 darwin arm64".startsWith("yarn"))return"yarn";if("bun/1.2.4 npm/? node/v22.6.0 darwin arm64".startsWith("pnpm"))return"pnpm";if("bun/1.2.4 npm/? node/v22.6.0 darwin arm64".startsWith("bun"))return"bun";return"npm"}var p3=u.join(n3.homedir(),".untitledui"),F=u.join(p3,"config.json"),$={components:[],path:"",type:void 0,license:""};if(E.existsSync(F)){let z=JSON.parse(E.readFileSync(F,"utf-8"));$.license=z.license}var i=(z)=>{if(z.aborted)process.stdout.write("\x1B[?25h"),process.stdout.write(`
4
- `),process.exit(1)},E3=new s3().name("add").description("add a component to your project").argument("[components...]","the components to add").option("-o, --overwrite","overwrite existing files.",!1).option("-a, --all","add all available components",!1).option("-p, --path <path>","the path to add the component to.").option("-t, --type <shared|marketing|shared-assets|application|foundations>","the type of the component to add.").option("-l, --license <license-key>","Add a license key for adding components.").action(async(z,W)=>{if(z)$.components=z;if(W)$.overwrite=W.overwrite,$.all=W.all,$.path=W.path,$.license=W.license||$.license;try{await i3($)}catch(Q){console.error(v.red(Q))}});async function i3(z){let W=g().start(),Q=process.cwd();if(!E.existsSync(u.resolve(Q,"package.json")))W.warn("This command should be run in a project directory."),process.exit(0);let X=await s(Q);if($.license){let q=await P($.license);if(console.log(q,$),!q)W.fail("Invalid license key"),process.exit(0);if(!E.existsSync(F)){let H=u.dirname(F);E.mkdirSync(H,{recursive:!0}),E.writeFileSync(F,JSON.stringify({license:$.license},null,2))}if(JSON.parse(E.readFileSync(F,"utf-8")).license!==$.license)E.writeFileSync(F,JSON.stringify({license:$.license},null,2))}W.stop();let V=[];if($.components.length){let q=await z3($.type,$.components,$.license);if(q?.pro?.length)q?.pro?.forEach((J)=>console.log(`The ${v.yellowBright(J.split("/")[1])} component is only available for PRO users. Get access to the PRO at ${v.cyan("https://www.untitledui.com/buy/untitled-ui")}`)),process.exit(0);if(!q?.components.length)console.log("No components found"),process.exit(0);V.push(...q.components)}if(!$?.type&&!$?.components.length){let q=await G3($.license);if(!q)console.log("No component types found"),process.exit(0);let J=await h({type:"select",name:"type",onState:i,message:`What type of ${v.cyan("component")} are you adding?`,choices:q?.types.map((H)=>({title:H,value:H}))});$.type=J.type}if(!$?.path){let q=await h({type:"text",name:"path",onState:i,message:`Where would you like to add the ${v.cyan("components")}?`,initial:"components"});$.path=q.path}if(X&&!X?.aliasPrefix){let q=/^[^*"]+\/\*\s*$/,J=await h({type:"text",name:"aliasPrefix",onState:i,initial:"@/*",message:`What is the ${v.cyan("import alias")} for your project?`,validate:(H)=>q.test(H)?!0:"Import alias must follow the pattern <prefix>/*"});X.aliasPrefix=await R3(Q,X?.isSrcDir,J?.aliasPrefix)}if(!$?.components.length){let q=await M3($?.type,$.license);if(!q)console.log("No components found"),process.exit(0);let J=await h({type:"multiselect",name:"components",onState:i,message:`Which ${v.cyan("components")} would you like to add?`,choices:q?.components?.map((H)=>({title:H||"example",value:H||"example",selected:$.components.includes(H)})),instructions:!1,hint:"- Space to select. Return to submit"});if($.components=J.components,!J.components||J.components.length===0)console.log("No option selected. Exiting..."),process.exit(0)}if(!$.components?.length)W.warn("No components selected. Exiting."),process.exit(0);let Z=n(Q),L=new Set,B=new Set,b=new Set,M=new a3({tsConfigFilePath:Z?.tsConfig});if($.type&&$.components.length){let q=await z3($.type,$.components,$.license);if(!q?.components.length)console.log("No components found"),process.exit(0);V.push(...q.components)}V.forEach((q)=>{let J=g(`Adding ${q.name}`).start(),H=q.files;q.dependencies.forEach((_)=>B.add(_)),q.devDependencies.forEach((_)=>b.add(_));try{H?.forEach(async({path:_,code:x})=>{let A=u.join(process.cwd(),`${X?.isSrcDir&&"src"}`,_.replace(/components\//,$.path+"/")),f=u.dirname(A);if(E.existsSync(A)&&!$.overwrite){if(E.readFileSync(A,"utf-8")!==x)L.add({code:x,path:A})}else{E.mkdirSync(f,{recursive:!0}),E.writeFileSync(A,x);let G=M.addSourceFileAtPath(u.resolve(A));G.getImportDeclarations().forEach((T)=>{let y=T.getModuleSpecifierValue();T.setModuleSpecifier(X3(y,X?.aliasPrefix,$.path))}),await G.save()}}),J.succeed(`${v.green(q.name)} is added`)}catch(_){J.fail(`
5
- Failed to add component`),console.error(v.red(_)),process.exit(0)}});let N=await a({dependencies:Array.from(B),devDependencies:Array.from(b),shouldThrow:!0}),j=D();if(N?.dependencies?.length){let q=g("Installing dependencies").start();await N3(()=>p(j,[j==="npm"?"install":"add",...Array.from(N.dependencies)]).catch(async(J)=>{if(J.message.includes("peer"))q.warn("Dependency conflict detected. Retrying with --legacy-peer-deps..."),q.start("Installing dependencies with --legacy-peer-deps flag"),await p(j,[j==="npm"?"install":"add",...Array.from(N.dependencies),"--legacy-peer-deps"])}),{retries:1}),q.succeed("Dependencies are installed")}if(N?.devDependencies?.length){let q=g("Installing devDependencies").start();await N3(()=>p(j,[j==="npm"?"install":"add",...Array.from(N.devDependencies)]).catch(async(J)=>{if(J.message.includes("peer"))q.warn("DevDependency conflict detected. Retrying with --legacy-peer-deps..."),q.start("Installing devDependencies with --legacy-peer-deps flag"),await p(j,[j==="npm"?"install":"add",...Array.from(N.devDependencies),"--legacy-peer-deps"])}),{retries:1}),q.succeed("DevDependencies are installed")}if(L.size&&!$?.overwrite)if(console.log(`
6
- Following files already exist in the directory.`),L.forEach((J)=>{console.log(v.green(`- ${u.relative(process.cwd(),J.path)}`))}),(await h({type:"confirm",name:"overwrite",message:"Do you want to overwrite the existing files?",initial:!0})).overwrite){let J=g("Overwriting files").start();L.forEach(async(H)=>{E.writeFileSync(H.path,H.code);let _=M.addSourceFileAtPath(u.resolve(H.path));_.getImportDeclarations().forEach((x)=>{let A=x.getModuleSpecifierValue();x.setModuleSpecifier(X3(A,X?.aliasPrefix,$.path))}),await _.save()}),J.succeed("Files are overwritten"),process.exit(1)}else console.log(`Use ${v.cyan("--overwrite")} or ${v.cyan("-o")} to overwrite existing files, or refer to the documentation ${v.cyan("https://untitled.xyz/docs")} for manual installation. The rest of the files are added.`),process.exit(0)}import u3 from"async-retry";import R from"chalk";import{Command as o3}from"commander";import{execa as e}from"execa";import B3 from"fast-glob";import I from"fs";import m from"ora";import t3 from"os";import*as K from"path";import d from"prompts";import{Project as e3}from"ts-morph";import{fileURLToPath as W0}from"url";import o from"fs";import v3 from"path";function Y3(z,W){if(!o.existsSync(W))o.mkdirSync(W,{recursive:!0});let Q=o.readdirSync(z,{withFileTypes:!0});for(let Y of Q){let X=v3.join(z,Y.name),V=v3.join(W,Y.name);if(Y.isDirectory())Y3(X,V);else o.copyFileSync(X,V)}}import Z3 from"chalk";import*as C from"fs";import*as t from"path";function $3(z){if(!C.existsSync(t.resolve(z)))console.log(Z3.red(`Error: CSS file not found at ${z}`)),process.exit(1);let W=C.readFileSync(t.resolve(z),"utf-8"),Q=/(--color-[a-zA-Z-]+-\d{1,3}):\s*(rgb\([^)]+\))/g,Y={},X;while((X=Q.exec(W))!==null)if(X[1]&&X[2])Y[X[1]]=X[2];return Y}function q3(z,W,Q){let Y=t.resolve(Q);if(!C.existsSync(Y)){console.log(Z3.red(`Error: CSS file not found at ${Y}`));return}let X=C.readFileSync(Y,"utf-8"),V=$3(Q),Z={},L={};for(let[b,M]of Object.entries(V))if(b.startsWith(`--color-${z}-`)){let N=b.replace(`--color-${z}-`,"");Z[N]=b}else if(b.startsWith(`--color-${W}-`)){let N=b.replace(`--color-${W}-`,"");L[N]=M}let B=!1;for(let[b,M]of Object.entries(Z))if(L[b]){let N=L[b],j=new RegExp(`(${M}):\\s*rgb\\([^)]*\\);?`,"g");if(j.test(X))X=X.replace(j,`$1: ${N};`),B=!0;else console.log(Z3.yellow(`No match found for ${M}`))}if(B)C.writeFileSync(Y,X,"utf-8")}var z0=W0(import.meta.url),K3=K.dirname(z0),Q0=K.join(t3.homedir(),".untitledui"),O=K.join(Q0,"config.json"),b3="default",X0=["with-stripe","otp","magic-link"],w="",U={template:"",color:""};if(I.existsSync(O)){let z=JSON.parse(I.readFileSync(O,"utf-8"));U.license=z.license}var W3=(z)=>{if(z.aborted)process.stdout.write("\x1B[?25h"),process.stdout.write(`
7
- `),process.exit(1)},_3=new o3().name("init").description("initialize a new project").argument("[directory]").usage("[directory] [options]").helpOption("-h, --help","Display this help message.").option("-t, --template <starter-kit>","Specify a template for the project.").option("-c, --color <color-name>","Specify a color for the project.").option("-o, --overwrite","Overwrite existing files.",!1).option("-l, --license <license-key>","Add a license key to download the repository.").action(async(z,W)=>{if(z)w=z;if(W)U.color=W.color,U.template=W.template,U.overwrite=W.overwrite,U.license=W.license||U.license;try{await Y0(W)}catch(Q){console.error(R.red(Q))}});async function Y0(z){let W=process.cwd(),Q=I.existsSync(K.resolve(W,"package.json")),Y=K.resolve(K.join(K3,"../templates/default","src/styles/theme.css")),X=$3(Y??""),V=Array.from(new Set(Object.keys(X).map((B)=>B?.split("--color-")?.[1]?.replace(/-\d{1,3}/,"")))),Z=m().start(),L=await s(W);if(U.license){if(!await P(U.license))Z.fail("Invalid license key"),process.exit(0);if(!I.existsSync(O)){let M=K.dirname(O);I.mkdirSync(M,{recursive:!0}),I.writeFileSync(O,JSON.stringify({license:U.license},null,2))}if(JSON.parse(I.readFileSync(O,"utf-8")).license!==U.license)I.writeFileSync(O,JSON.stringify({license:U.license},null,2))}if(!Q){if(Z.stop(),!w){let B=await d({onState:W3,type:"text",name:"path",message:"What is your project named?",initial:"untitled-ui"});if(typeof B.path==="string")w=B.path.trim()}if(I.existsSync(K.resolve(K.join(W,w))))Z.fail(R.red("Directory already exists!")),process.exit(1);if(!U.template){let B=await d({type:"select",name:"template",onState:W3,message:`Which ${R.cyan("starter kit")} would you like to use?`,choices:[{title:"default-template",value:b3},{title:"basic-form",value:"basic-form"},{title:"magic-link",value:"magic-link"},{title:"next-intl",value:"next-intl"},{title:"otp",value:"otp"},{title:"react-hook-form",value:"react-hook-form"},{title:"with-stripe",value:"with-stripe"}]});if(U.template=B.template,X0.includes(U.template)&&!U.license){let b=await d({type:"text",name:"license",onState:W3,message:`Enter the license key to download the ${R.cyan(U.template)} template:`});if(U.license=b.license,!await P(b.license))Z.fail("Invalid license key"),process.exit(0)}}Z.succeed("Template is selected: "+R.green(U.template))}else if(L?.framework==="other")Z.fail("Unsupported project framework"),console.log(`Please refer to the documentation ${R.cyan("https://untitled.xyz/docs")} for supported frameworks or proceed with manual installation.`),process.exit(1);else Z.succeed(R.yellow("Detected Next.js project, proceeding with the setup..."));if(!U.color){let B=await d({type:"select",name:"color",onState:W3,initial:z.color??"",message:`Which ${R.cyan("color")} would you like to use as the ${R.cyanBright("brand")} color?`,choices:V.map((b)=>({title:b,value:b}))});U.color=B.color}if(w&&!Q){let B=K.resolve(w);console.log(`
8
- Creating a new project in ${R.blue(w)}`);let b=m("Downloading and extracting the repository...").start();try{if(I.mkdirSync(B,{recursive:!0}),U.template===b3){let j=K.resolve(K.join(K3,"../templates/",b3));Y3(j,B)}else await u3(()=>L3(B,{username:"a-peak-works",repo:"starter-kits",branch:"master",template:U.template,key:U.license}),{retries:2});b.succeed("Files are downloaded and extracted successfully!");let M=m({text:"Installing dependencies..."}).start(),N=B3.sync(["**/styles/theme.css"],{cwd:B,absolute:!0,onlyFiles:!0})[0];q3("brand",U.color,N??""),await u3(()=>e("sh",["-c",`cd ${w} && ${D()} install && git init`]).catch(async(j)=>{if(j.message.includes("peer"))M.warn("Dependency conflict detected. Retrying with --legacy-peer-deps..."),M.start("Installing dependencies with --legacy-peer-deps flag"),await e("sh",["-c",`cd ${w} && ${D()==="npm"?"npm --legacy-peer-deps":D()} install && git init`])}),{retries:1}),M.succeed("Dependencies installed"),console.log(`
2
+ import{Command as k3}from"commander";import C0 from"async-retry";import N from"chalk";import{Command as o0,Option as t0}from"commander";import{execa as $0}from"execa";import*as S from"fs";import z0 from"ora";import e0 from"os";import*as w from"path";import X0 from"prompts";import{Project as z3}from"ts-morph";import f0 from"node-fetch";import{Readable as g3,pipeline as m0}from"stream";import{x as h3}from"tar";import{promisify as c0}from"util";var m3=c0(m0);async function a(B){let z=`https://untitledui-docs.vercel.app/api/validate-key?key=${B}`;try{return(await f0(z)).status===200}catch{return!1}}import l0 from"node-fetch";async function K0(B,z,Q){try{return await(await l0("https://untitledui-docs.vercel.app/api/components",{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify({type:B,components:z,key:Q})})).json()}catch(Y){return console.error(Y),null}}import w0 from"node-fetch";async function u0(B,z=""){let Q=`https://untitledui-docs.vercel.app/api/components/list?key=${z}&type=${B}`;try{let Y=await(await w0(Q)).json();if(!Y?.components?.length)return null;return Y}catch(X){return console.error(X),null}}async function T0(B=""){let z=`https://untitledui-docs.vercel.app/api/components/list?key=${B}`;try{let X=await(await w0(z)).json();if(!X?.types?.length)return null;return X}catch(Q){return console.error(Q),null}}import i0 from"fast-glob";import*as b0 from"path";import{Project as W1}from"ts-morph";import{loadConfig as p0}from"tsconfig-paths";import i3 from"prettier";import Z0 from"fast-glob";import*as W0 from"fs";import*as Y0 from"path";import{loadConfig as s0}from"tsconfig-paths";var h=["**/node_modules/**",".next","public","dist","build"],y0={"next-app":"Next.js (App)","next-pages":"Next.js (Pages)",vite:"Vite",other:"Other"};async function n(B){let z=W0.existsSync(Y0.resolve(B,"src")),Q=W0.existsSync(Y0.resolve(B,`${z?"src/":""}app`)),[X,Y,V,v]=await Promise.all([Z0.glob("**/{next,vite,astro}.config.*|gatsby-config.*",{cwd:B,deep:2,ignore:h}),a0(B),n0(B),r0(B)]),M={framework:"other",isTsx:Y,tailwindFile:V||null,aliasPrefix:v,isSrcDir:z,isUsingAppDir:Q};if(X.find((L)=>L.startsWith("next.config."))?.length)return M.framework=Q?"next-app":"next-pages",M;else if(X.find((L)=>L.startsWith("vite.config."))?.length)return M.framework="vite",M;else if(X?.length||W0.existsSync(Y0.resolve(B,"package.json")))return M.framework="other",M;return null}async function a0(B){return(await Z0.glob("tsconfig.*",{cwd:B,deep:2,ignore:h})).length>0}async function n0(B){let z=await Z0.glob("tailwind.config.*",{cwd:B,deep:2,ignore:h});if(!z.length)return null;return z[0]}async function r0(B){let z=await s0(B);if(z?.resultType==="failed"||!Object.keys(z.paths).length)return null;let Q={};for(let[X,Y]of Object.entries(z.paths)){let V=X.replace(/\/\*$/,"/");if(Y.some((v)=>v.includes("/app/*")))Q.appPrefix=V;else if(Y.some((v)=>v.includes("/components/*")))Q.componentsPrefix=V;else if(Y.some((v)=>v.includes("/utils/*")))Q.utilsPrefix=V;else if(Y.some((v)=>v.includes("/styles/*")))Q.stylesPrefix=V;else if(Y.some((v)=>v.includes("./*")||v.includes("/src/*")))Q.srcPrefix=V}return Q||null}function r(B){let z=p0(B),Q=i0.sync(["tailwind.config.*","**/globals.css","**/{layout,_app,main}.tsx","package.json"],{cwd:B,deep:4,absolute:!0,onlyFiles:!0,ignore:h}),X={tailwindFile:Q.find((Y)=>Y.includes("tailwind.config.")),cssFile:Q.find((Y)=>Y.includes("globals.css")),layoutFile:Q.find((Y)=>Y.includes("layout")),appFile:Q.find((Y)=>Y.includes("_app")),mainFile:Q.find((Y)=>Y.includes("main")),packageJson:Q.find((Y)=>Y.includes("package.json")),tsConfig:z?.resultType==="success"?z?.configFileAbsolutePath:void 0};if(z.resultType==="failed")throw new Error(`Failed to load tsconfig.json. ${z.message??""}`.trim());return X}function i(B,z,Q={},X=""){if(B.includes("components")){if(Q?.componentsPrefix)return B.replace(/@\/components\//,b0.posix.join(Q?.componentsPrefix,z?z.replace(/components\//,""):"","/"));if(z){let Y=Q?.srcPrefix?b0.posix.join(Q?.srcPrefix,z,"/"):X;return B.replace(/@\/components\//,Y)}}if(B.includes("app")&&Q?.appPrefix)return B.replace(/^@\/app\//,Q?.appPrefix);if(B.includes("utils")&&Q?.utilsPrefix)return B.replace(/^@\/utils\//,Q?.utilsPrefix);if(B.includes("styles")&&Q?.stylesPrefix)return B.replace(/^@\/styles\//,Q?.stylesPrefix);if(Q?.srcPrefix)return B.replace(/^@\//,Q?.srcPrefix);return B}function T(){if("bun/1.2.14 npm/? node/v22.6.0 darwin arm64".startsWith("yarn"))return"yarn";if("bun/1.2.14 npm/? node/v22.6.0 darwin arm64".startsWith("pnpm"))return"pnpm";if("bun/1.2.14 npm/? node/v22.6.0 darwin arm64".startsWith("bun"))return"bun";return"npm"}function S0(){switch(T()){case"yarn":return"yarn";case"pnpm":return"pnpx";case"bun":return"bun";default:return"npx"}}var B3=w.join(e0.homedir(),".untitledui"),m=w.join(B3,"config.json"),Z={components:[],path:"",type:void 0,license:""};if(S.existsSync(m)){let B=JSON.parse(S.readFileSync(m,"utf-8"));Z.license=B.license}var L0=(B)=>{if(B.aborted)process.stdout.write("\x1B[?25h"),process.stdout.write(`
3
+ `),process.exit(1)},x0=new o0().name("add").description("add a component to your project").argument("[components...]","the components to add").option("-a, --all","add all available components",!1).option("-o, --overwrite","overwrite existing files.",!1).option("-p, --path <path>","the path to add the component to.").option("-d, --dir <directory>","the directory where the project is located.").addOption(new t0("-l, --license <license-key>","Add a license key for adding components.").hideHelp()).option("-t, --type <shared|marketing|shared-assets|application|foundations>","the type of the component to add.").action(async(B,z)=>{if(B)Z.components=B;if(z)Z.all=z.all,Z.dir=z.dir,Z.path=z.path,Z.overwrite=z.overwrite,Z.license=z.license||Z.license;try{await Q3(Z)}catch(Q){console.error(N.red(Q))}});async function Q3(B){let z=z0().start(),Q=w.posix.join(process.cwd(),Z.dir||"");if(!S.existsSync(w.resolve(Q,"package.json")))z.warn("This command should be run in a project directory."),process.exit(1);let Y=await n(Q);if(Z.license){if(!await a(Z.license))z.fail("Invalid license key"),process.exit(1);if(!S.existsSync(m)){let U=w.dirname(m);S.mkdirSync(U,{recursive:!0}),S.writeFileSync(m,JSON.stringify({license:Z.license},null,2))}if(JSON.parse(S.readFileSync(m,"utf-8")).license!==Z.license)S.writeFileSync(m,JSON.stringify({license:Z.license},null,2),"utf-8")}z.stop();let V=[];if(Z.components.length){let q=await K0(Z.type,Z.components,Z.license);if(q&&q.pro&&q.pro.length>0){if(console.log(),q.pro.length===1){let W=q.pro[0]?.split("/")[1]||q.pro[0];console.log(N.yellow(`\uD83D\uDD12 The ${N.cyan(W)} component requires PRO access.`))}else console.log(N.yellow("\uD83D\uDD12 The following components require PRO access:")),q.pro.forEach((W)=>{let U=W?.split("/")[1]||W;console.log(` • ${N.cyan(U)}`)});console.log(),console.log("To access PRO components:"),console.log(` ${N.green("→")} If you've already purchased: ${N.cyan("npx untitledui@latest login")}`),console.log(` ${N.green("→")} To purchase PRO components: ${N.cyan("https://www.untitledui.com/buy/react")}`),console.log(),process.exit(1)}if(!q?.components.length)console.log("No components found"),process.exit(1);V.push(...q.components)}if(!Z?.type&&!Z?.components.length){let q=await T0(Z.license);if(!q)console.log("No component types found"),process.exit(1);let W=await X0({type:"select",name:"type",onState:L0,message:`What type of ${N.cyan("component")} are you adding?`,choices:q?.types.map((U)=>({title:U,value:U}))});Z.type=W.type}if(!Z?.path){let q=await X0({type:"text",name:"path",onState:L0,message:`Where would you like to add the ${N.cyan("components")}?`,initial:"components"});Z.path=q.path}if(!Z?.components.length){let q=await u0(Z?.type,Z.license);if(!q)console.log("No components found"),process.exit(1);let W=await X0({type:"multiselect",name:"components",onState:L0,message:`Which ${N.cyan("components")} would you like to add?`,choices:q?.components?.map((U)=>({title:U||"example",value:U||"example",selected:Z.components.includes(U)})),instructions:!1,hint:"- Space to select. Return to submit"});if(Z.components=W.components,!W.components||W.components.length===0)console.log("No option selected. Exiting..."),process.exit(1)}if(!Z.components?.length)z.warn("No components selected. Exiting."),process.exit(1);let v=r(Q),M=new Set,L=new Set,J=new Set,A=new z3({tsConfigFilePath:v?.tsConfig});if(Z.type&&Z.components.length){let q=await K0(Z.type,Z.components,Z.license);if(!q?.components.length)console.log("No components found"),process.exit(1);V.push(...q.components)}if(V.forEach((q)=>{let W=z0(`Adding ${q.name}...`).start(),U=q.files;q.dependencies.forEach((b)=>L.add(b)),q.devDependencies.forEach((b)=>J.add(b));try{if(U?.forEach(async({path:b,code:C})=>{let E=w.posix.join(Q,`${Y?.isSrcDir&&"src"}`,b.replace(/components\//,Z.path+"/")),x=w.dirname(E);if(S.existsSync(E)&&!Z.overwrite){if(S.readFileSync(E,"utf-8")!==C)M.add({code:C,path:E})}else{S.mkdirSync(x,{recursive:!0}),S.writeFileSync(E,C);let I=w.relative(w.resolve(Q,`${Y?.isSrcDir&&"src"}`,Z.path),E).split("/").length,y=I===1?"./":"../".repeat(I-1),k=A.addSourceFileAtPath(w.resolve(E));k.getImportDeclarations().forEach((F)=>{let e=F.getModuleSpecifierValue();F.setModuleSpecifier(i(e,Z.path,Y?.aliasPrefix,y))}),await k.save()}}),M.size)W.warn(`Some files of ${N.yellow(q.name)} already exist`);else W.succeed(`${N.green(q.name)} is added successfully`)}catch(b){W.fail(`
4
+ Failed to add the component ${N.red(q.name)}`),console.error(N.red(b)),process.exit(1)}}),M.size&&!Z?.overwrite)if(console.log(`
5
+ Following files already exist in the directory.`),M.forEach((W)=>{console.log(N.green(`- ${w.relative(Q,W.path)}`))}),(await X0({type:"confirm",name:"overwrite",message:"Do you want to overwrite the existing files?",initial:!0})).overwrite){let W=z0("Overwriting files").start();M.forEach((U)=>{let b=w.relative(w.resolve(Q,`${Y?.isSrcDir&&"src"}`,Z.path),U.path).split("/").length,C=b===1?"./":"../".repeat(b-1),E=A.addSourceFileAtPath(w.resolve(U.path));E.replaceWithText(U.code),E.getImportDeclarations().forEach((x)=>{let I=x.getModuleSpecifierValue();x.setModuleSpecifier(i(I,Z.path,Y?.aliasPrefix,C))}),E.saveSync()}),W.succeed("Files are overwritten")}else console.log(`Use ${N.cyan("--overwrite")} or ${N.cyan("-o")} to overwrite existing files, or refer to the documentation ${N.cyan("https://untitled.xyz/docs")} for manual installation. The rest of the files are added.`),process.exit(1);let K=T();if(L?.size){let q=z0("Installing dependencies").start();await C0(()=>$0("sh",["-c",`${Z?.dir?`cd ${Z?.dir} && `:""}${K} ${K==="npm"?"install":"add"} ${Array.from(L).join(" ")}`]).catch(async(W)=>{if(W.message.includes("peer"))q.warn("Dependency conflict detected. Retrying with --legacy-peer-deps..."),q.start("Installing dependencies with --legacy-peer-deps flag"),await $0("sh",["-c",`${Z?.dir?`cd ${Z?.dir} && `:""}${K} ${K==="npm"?"install":"add"} ${Array.from(L).join(" ")} --legacy-peer-deps`])}),{retries:1}),q.succeed("Dependencies are installed")}if(J?.size){let q=z0("Installing devDependencies").start();await C0(()=>$0("sh",["-c",`${Z?.dir?`cd ${Z?.dir} && `:""}${K} ${K==="npm"?"install":"add"} ${Array.from(J).join(" ")}`]).catch(async(W)=>{if(W.message.includes("peer"))q.warn("DevDependency conflict detected. Retrying with --legacy-peer-deps..."),q.start("Installing devDependencies with --legacy-peer-deps flag"),await $0("sh",["-c",`${Z?.dir?`cd ${Z?.dir} && `:""}${K} ${K==="npm"?"install":"add"} ${Array.from(J).join(" ")} --legacy-peer-deps`])}),{retries:1}),q.succeed("DevDependencies are installed")}process.exit(0)}import v0 from"chalk";import{Command as W3}from"commander";import*as d from"fs";import Y3 from"http";import Z3 from"open";import $3 from"ora";import X3 from"os";import*as G0 from"path";import{URL as q3}from"url";var H0=G0.join(X3.homedir(),".untitledui"),M0=G0.join(H0,"config.json"),k0=new W3().name("login").description("authenticate with Untitled UI to access PRO components").action(async()=>{let B=$3("Starting authentication...").start();try{await U3(B),B.succeed("Authentication completed successfully!"),console.log(v0.green(`
6
+ You can now access PRO components with the CLI!`)),process.exit(0)}catch(z){B.fail(`Authentication failed: ${z instanceof Error?z.message:z}`),process.exit(1)}});async function U3(B){return new Promise((z,Q)=>{let X=Y3.createServer((Y,V)=>{let v=new q3(Y.url,"http://localhost");if(v.pathname==="/callback"){let M=v.searchParams.get("apiKey"),L=v.searchParams.get("error");if(L){V.writeHead(400,{"Content-Type":"text/html"}),V.end(`
7
+ <html>
8
+ <body style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; text-align: center; padding: 50px;">
9
+ <h1 style="color: #dc2626;">Authentication Failed</h1>
10
+ <p>${decodeURIComponent(L)}</p>
11
+ <p style="color: #6b7280;">You can close this tab and return to your terminal.</p>
12
+ </body>
13
+ </html>
14
+ `),X.close(),Q(new Error(decodeURIComponent(L)));return}if(!M){V.writeHead(400,{"Content-Type":"text/html"}),V.end(`
15
+ <html>
16
+ <body style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; text-align: center; padding: 50px;">
17
+ <h1 style="color: #dc2626;">Authentication Failed</h1>
18
+ <p>No API key received</p>
19
+ <p style="color: #6b7280;">You can close this tab and return to your terminal.</p>
20
+ </body>
21
+ </html>
22
+ `),X.close(),Q(new Error("No API key received"));return}try{V3(M),V.writeHead(200,{"Content-Type":"text/html"}),V.end(`
23
+ <html>
24
+ <body style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; text-align: center; padding: 50px;">
25
+ <h1 style="color: #16a34a;">Authentication Successful!</h1>
26
+ <p>Your CLI has been authenticated successfully.</p>
27
+ <p style="color: #6b7280;">You can now close this tab and return to your terminal.</p>
28
+ </body>
29
+ </html>
30
+ `),X.close(),z()}catch(J){V.writeHead(500,{"Content-Type":"text/html"}),V.end(`
31
+ <html>
32
+ <body style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; text-align: center; padding: 50px;">
33
+ <h1 style="color: #dc2626;">Authentication Failed</h1>
34
+ <p>Failed to save authentication data</p>
35
+ <p style="color: #6b7280;">You can close this tab and return to your terminal.</p>
36
+ </body>
37
+ </html>
38
+ `),X.close(),Q(J)}}else V.writeHead(404),V.end("Not found")});X.listen(0,"localhost",()=>{let v=`https://untitledui-docs.vercel.app/api/cli-auth?port=${X.address().port}`;B.text="Opening browser for authentication...",Z3(v).catch((M)=>{console.log(v0.yellow(`
39
+ Failed to open browser automatically: ${M.message}`)),console.log(v0.cyan(`Please manually open: ${v}
40
+ `))}),B.text="Waiting for authentication in browser..."}),setTimeout(()=>{X.close(),Q(new Error("Authentication timeout. Please try again."))},300000)})}function V3(B){if(!d.existsSync(H0))d.mkdirSync(H0,{recursive:!0});let z={};if(d.existsSync(M0))try{z=JSON.parse(d.readFileSync(M0,"utf-8"))}catch{z={}}z.license=B,d.writeFileSync(M0,JSON.stringify(z,null,2),"utf-8")}import N0 from"async-retry";import H from"chalk";import{Command as w3,Option as u3}from"commander";import{execa as B0}from"execa";import*as u from"fs";import Q0 from"ora";import T3 from"os";import*as G from"path";import l from"prompts";import{Project as y3}from"ts-morph";import J3 from"node-fetch";async function q0(B,z){try{let X=await J3("https://untitledui-docs.vercel.app/api/components/example",{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify({example:B,key:z})});if(!X.ok){if(X.status===401||X.status===403)return{type:"error",status:X.status,message:"PRO access required"};return console.error(`API error: ${X.status} - ${X.statusText}`),null}return await X.json()}catch(X){return console.error(X?.message||"Error fetching example data."),null}}import V0 from"async-retry";import _ from"chalk";import{Command as G3}from"commander";import{execa as p}from"execa";import A0 from"fast-glob";import D from"fs";import o from"ora";import j3 from"os";import*as R from"path";import J0 from"prompts";import{Project as E3}from"ts-morph";import{fileURLToPath as R3}from"url";import K3 from"node-fetch";import{posix as P0,sep as b3}from"node:path";import{Readable as L3}from"node:stream";import{pipeline as M3}from"node:stream/promises";import{x as v3}from"tar";var F0=[".DS_Store",".git","node_modules","bun.lockb","yarn.lock","package-lock.json"];async function O0(B,{username:z,repo:Q,branch:X,template:Y}){try{let V=`https://codeload.github.com/${z}/${Q}/tar.gz/${X}`,v=await H3(V);await M3(v,v3({cwd:B,strip:1,filter:(M)=>{let L=M.split(P0.sep)?.pop()||"";if(F0.includes(L))return!1;if(Y)return M.split(b3).join(P0.sep).includes(Y);return!0}}))}catch(V){if(V instanceof Error)throw new Error(`Failed to download or extract repository: ${V.message}`);throw V}}async function H3(B){let z=await K3(B);if(!z.ok)throw new Error(`Failed to download: ${B} - Status: ${z.status} ${z.statusText}`);if(!z.body)throw new Error(`Failed to download: ${B} - No response body`);let Q=z.headers.get("content-type");if(Q&&!Q.includes("application/x-gzip")&&!Q.includes("application/octet-stream"))console.warn(`Warning: Unexpected content type: ${Q}. Expected application/x-gzip or application/octet-stream.`);return L3.from(z.body)}import j0 from"chalk";import*as f from"fs";import*as U0 from"path";function E0(B){if(!f.existsSync(U0.resolve(B)))console.log(j0.red(`Error: CSS file not found at ${B}`)),process.exit(1);let z=f.readFileSync(U0.resolve(B),"utf-8"),Q=/(--color-[a-zA-Z-]+-\d{1,3}):\s*(rgb\([^)]+\))/g,X={},Y;while((Y=Q.exec(z))!==null)if(Y[1]&&Y[2])X[Y[1]]=Y[2];return X}function R0(B,z,Q){let X=U0.resolve(Q);if(!f.existsSync(X)){console.log(j0.red(`Error: CSS file not found at ${X}`));return}let Y=f.readFileSync(X,"utf-8"),V=E0(Q),v={},M={};for(let[J,A]of Object.entries(V))if(J.startsWith(`--color-${B}-`)){let K=J.replace(`--color-${B}-`,"");v[K]=J}else if(J.startsWith(`--color-${z}-`)){let K=J.replace(`--color-${z}-`,"");M[K]=A}let L=!1;for(let[J,A]of Object.entries(v))if(M[J]){let K=M[J],q=new RegExp(`(${A}):\\s*rgb\\([^)]*\\);?`,"g");if(q.test(Y))Y=Y.replace(q,`$1: ${K};`),L=!0;else console.log(j0.yellow(`No match found for ${A}`))}if(L)f.writeFileSync(X,Y,"utf-8")}var A3=R3(import.meta.url),g0=R.dirname(A3),I3=R.join(j3.homedir(),".untitledui"),c=R.join(I3,"config.json"),_3={"nextjs-starter":"Next.js","vite-starter":"Vite"},N3="vite-starter",D3="nextjs-starter",P="",j={color:"",template:"",framework:void 0};if(D.existsSync(c)){let B=JSON.parse(D.readFileSync(c,"utf-8"));j.license=B.license}var I0=(B)=>{if(B.aborted)process.stdout.write("\x1B[?25h"),process.stdout.write(`
41
+ `),process.exit(1)},d0=new G3().name("init").description("initialize a new project or adjust an existing one").argument("[directory]").usage("[directory] [options]").helpOption("-h, --help","Display this help message.").option("--vite","Initialize a Vite project.",!1).option("--next","Initialize a Next.js project.",!1).option("-c, --color <color-name>","Specify a color for the project.").option("-o, --overwrite","Overwrite existing files.",!1).option("-l, --license <license-key>","Add a license key to download the repository.").action(async(B,z)=>{if(B)P=B;if(z){if(j.color=z.color,j.template=z.template,j.overwrite=z.overwrite,j.license=z.license||j.license,j.vite=z.vite,j.next=z.next,z.vite)j.framework=N3;if(z.next)j.framework=D3}try{await _0(z),process.exit(0)}catch(Q){console.error(_.red(Q)),process.exit(1)}});async function _0(B,z=null){let Q=process.cwd(),X=D.existsSync(R.resolve(Q,"package.json")),Y=R.resolve(R.join(g0,"../config/styles","theme.css")),V=E0(Y??""),v=Array.from(new Set(Object.keys(V).map((J)=>J?.split("--color-")?.[1]?.replace(/-\d{1,3}/,"")))),M=o().start(),L=await n(Q);if(j.license){if(!await a(j.license))M.fail("Invalid license key"),process.exit(1);if(!D.existsSync(c)){let K=R.dirname(c);D.mkdirSync(K,{recursive:!0}),D.writeFileSync(c,JSON.stringify({license:j.license},null,2))}if(JSON.parse(D.readFileSync(c,"utf-8")).license!==j.license)D.writeFileSync(c,JSON.stringify({license:j.license},null,2))}if(!X){if(M.stop(),!P){let J=await J0({onState:I0,type:"text",name:"path",message:"What is your project named?",initial:"untitled-ui"});if(typeof J.path==="string")P=J.path.trim()}if(z)z.projectPath=P;if(D.existsSync(R.resolve(R.posix.join(Q,P))))M.fail(_.red("Directory already exists!")),process.exit(1);if(j.vite&&j.next||!j.framework){let J=await J0({type:"select",name:"framework",onState:I0,message:`Which ${_.cyan("framework")} would you like to use?`,choices:[{title:_.cyan("Next"),value:"nextjs-starter"},{title:_.yellow("Vite"),value:"vite-starter"}]});j.framework=J.framework}M.succeed("Framework is selected: "+_.green(_3[j.framework]))}else if(L?.framework==="other")M.fail("Unsupported project framework"),console.log(`Please refer to the documentation ${_.cyan("https://untitled.xyz/docs")} for supported frameworks or proceed with manual installation.`),process.exit(1);else if(L?.framework.startsWith("next")||L?.framework.startsWith("vite"))M.succeed(_.yellow(`Detected ${y0[L.framework]} project, proceeding with the setup...`));if(!j.color){let J=await J0({type:"select",name:"color",onState:I0,initial:B.color??"",message:`Which ${_.cyan("color")} would you like to use as the ${_.cyanBright("brand")} color?`,choices:v.map((A)=>({title:A,value:A}))});j.color=J.color}if(P&&!X){let J=R.resolve(P);console.log(`
42
+ Creating a new project in ${_.blue(P)}`);let A=o("Downloading and extracting the repository...").start();try{D.mkdirSync(J,{recursive:!0}),await V0(()=>O0(J,{branch:"main",username:"a-peak-works",repo:j.framework}),{retries:2}),A.succeed("Files are downloaded and extracted successfully!");let K=o({text:"Installing dependencies..."}).start(),q=A0.sync(["**/styles/theme.css"],{cwd:J,absolute:!0,onlyFiles:!0})[0];if(R0("brand",j.color||"",q??""),await V0(()=>p("sh",["-c",`cd ${P} && ${T()} install && git init`]).catch(async(W)=>{if(W.message.includes("peer"))K.warn("Dependency conflict detected. Retrying with --legacy-peer-deps..."),K.start("Installing dependencies with --legacy-peer-deps flag"),await p("sh",["-c",`cd ${P} && ${T()==="npm"?"npm --legacy-peer-deps":T()} install && git init`])}),{retries:1}),K.succeed("Dependencies are installed"),!z)console.log(`
9
43
  Your project is ready, to get staretd run the following commands:
10
44
 
11
- cd ${R.cyan(w)}
12
- ${R.cyan(D())} run dev`),process.exit(1)}catch(M){if(b.fail(R.red(`
13
- Failed to download and extract the repository`)),M instanceof Error)console.error(M.message);else console.error(`
14
- `);I.rmdirSync(B,{recursive:!0}),process.exit(0)}}else{let B=new Set,b=n(W),M=K.resolve(K.join(K3,"../templates/default")),N=B3.sync(["**/{styles,plugins}/**","postcss.config.*"],{cwd:K.join(M,"src"),onlyFiles:!0,ignore:S.filter((G)=>!G.includes("public"))}),j=await a({dependencies:["tailwindcss","tailwindcss-animate","@tailwindcss/typography","tailwindcss-react-aria-components","@designbycode/tailwindcss-mask-image"],devDependencies:["@tailwindcss/postcss","postcss"]});if(N.forEach((G)=>{let T=G.includes("postcss.config"),y=K.resolve(K.join(M,"src"),G),k=K.resolve(process.cwd(),T?G:`${L?.isSrcDir?"src":""}/${G}`);if(I.existsSync(k)){if(U?.overwrite)I.copyFileSync(y,k);else{let A3=I.readFileSync(k,"utf-8"),D3=I.readFileSync(y,"utf-8");if(A3!==D3)B.add({targetFile:k,sourceFile:y})}return}I.mkdirSync(K.dirname(k),{recursive:!0}),I.writeFileSync(k,""),I.copyFileSync(K.resolve(K.join(M,"src"),G),k)}),B.size&&!U?.overwrite)if(console.log(`
15
- `),Z.fail("Following files already exist in the directory."),B.forEach((T)=>{console.log(`- ${R.green(T.targetFile)}`)}),(await d({type:"confirm",name:"overwrite",message:"Do you want to overwrite the existing files?",initial:!0})).overwrite){let T=m("Overwriting files").start();B.forEach((y)=>{I.copyFileSync(y.sourceFile,y.targetFile)}),T.succeed("Files are overwritten"),process.exit(1)}else console.log(`Use ${R.cyan("--overwrite")} or ${R.cyan("-o")} to overwrite existing files, or refer to the documentation ${R.cyan("https://untitled.xyz/docs")} for manual installation. The rest of the files are added.`),process.exit(0);if(b?.tailwindFile)console.log(`
45
+ cd ${_.cyan(P)}
46
+ ${_.cyan(T())} run dev`)}catch(K){if(A.fail(_.red(`
47
+ Failed to download and extract the repository`)),K instanceof Error)console.error(K.message);else console.error(`
48
+ `);D.rmdirSync(J,{recursive:!0}),process.exit(1)}}else{let J=o("Copying files to the project directory").start(),A=new Set,K=r(Q),q=R.resolve(R.join(g0,"../config")),W=A0.sync(["**"],{cwd:q,onlyFiles:!0,ignore:h}),U=["tailwindcss","tailwindcss-animate","@tailwindcss/typography","tailwindcss-react-aria-components"],b=["@tailwindcss/postcss","postcss"];if(W.forEach((I)=>{let y=I.includes("postcss.config"),k=R.resolve(R.posix.join(q),I),F=R.resolve(Q,y?I:`${L?.isSrcDir?"src":""}/${I}`);if(D.existsSync(F)){if(j?.overwrite)D.copyFileSync(k,F);else{let e=D.readFileSync(F,"utf-8"),g=D.readFileSync(k,"utf-8");if(e!==g)A.add({targetFile:F,sourceFile:k})}return}D.mkdirSync(R.dirname(F),{recursive:!0}),D.writeFileSync(F,""),D.copyFileSync(k,F)}),!A.size)J.succeed("Files are copied successfully!");if(A.size&&!j?.overwrite)if(console.log(`
49
+ `),J.fail("Following files already exist in the directory."),A.forEach((y)=>{console.log(`- ${_.green(y.targetFile)}`)}),(await J0({type:"confirm",name:"overwrite",message:"Do you want to overwrite the existing files?",initial:!0})).overwrite){let y=o("Overwriting files").start();A.forEach((k)=>{D.copyFileSync(k.sourceFile,k.targetFile)}),y.succeed("Files are overwritten")}else console.log(`Use ${_.cyan("--overwrite")} or ${_.cyan("-o")} to overwrite existing files, or refer to the documentation ${_.cyan("https://untitled.xyz/docs")} for manual installation. The rest of the files are added.`);if(K?.tailwindFile)console.log(`
16
50
  Tailwind config file exists in the project directory. You can add it to your globals.css as follows:`),console.log(`
17
- ${R.cyan(`@config "../${L?.isSrcDir&&"../"}${K.relative(process.cwd(),b.tailwindFile)}";`)}
18
- `);let q=b?.layoutFile||b?.appFile||"",H=new e3({tsConfigFilePath:K.resolve(b?.tsConfig||"")}).addSourceFileAtPath(K.resolve(q)),_=["colors.css","globals.css","inter.css","text-styles.css","theme.css","typography.css"];H.getImportDeclarations().filter((G)=>_.includes(G.getModuleSpecifierValue())).forEach((G)=>G.remove());let x=K.relative(K.resolve(process.cwd(),`${L?.isSrcDir&&"src"}`),q).split("/").length;H.addImportDeclarations(N.filter((G)=>G.includes("styles")).map((G)=>({moduleSpecifier:`${L?.aliasPrefix?.stylesPrefix||L?.aliasPrefix?.srcPrefix||"../".repeat(x-1)}${L?.aliasPrefix?.stylesPrefix?G?.split("styles/")[1]:G}`}))),H.saveSync();let A=m(),f=B3.sync(["**/styles/theme.css"],{cwd:W,absolute:!0,onlyFiles:!0,ignore:S});if(!f?.length)return Z.fail("Failed to copy theme.css file");if(q3("brand",U.color,f[0]??""),!j)A.fail("Failed to get dependencies from package.json"),process.exit(1);A.start("Installing dependencies"),await e(D(),[D()==="npm"?"install":"add",...j.dependencies],{}),await e(D(),[D()==="npm"?"install":"add","-D",...j.devDependencies],{}),A.succeed("Dependencies installed"),Z.succeed(R.green("Files are extracted successfully!")),console.log(`
19
- Your project is ready, you can now start adding components.`),process.exit(1)}}var U3={name:"untitledui",version:"0.1.5",main:"dist/index.mjs",description:"Untitled UI CLI",type:"module",publishConfig:{access:"public"},scripts:{test:'echo "Error: no test specified" && exit 1',dev:"bun build --entrypoints ./index.ts --entry-naming=[name].mjs --outdir=dist --target=node --minify --packages=external --env=inline --define=process.env.API_URL=http://localhost:3000/api --watch",build:"bun build --entrypoints ./index.ts --entry-naming=[name].mjs --outdir=dist --target=node --minify --packages=external --env=inline --define=process.env.API_URL=https://untitledui-docs.vercel.app/api","publish:npm":"bun run build && npm publish --access public",start:"node dist/index.js"},repository:{type:"git",url:"https://github.com/a-peak-works/untitledui-tailwind.git"},bugs:{url:"https://github.com/a-peak-works/untitledui-tailwind/issues"},homepage:"https://github.com/a-peak-works/untitledui-tailwind#readme",keywords:["untitled-ui","cli","tailwindcss","nextjs"],files:["dist","templates"],author:"",license:"MIT",bin:{untitledui:"dist/index.mjs"},exports:"./dist/index.mjs",dependencies:{"async-retry":"^1.3.3",chalk:"^5.4.1",commander:"^13.1.0",execa:"^7.0.0","fast-glob":"^3.3.3","node-fetch":"^3.3.2",ora:"^8.2.0",prettier:"^3.5.3",prompts:"^2.4.2",tar:"^7.4.3","ts-morph":"^25.0.1","tsconfig-paths":"^4.2.0","update-check":"^1.5.4"},devDependencies:{"@types/async-retry":"^1.4.9","@types/prompts":"^2.4.9","@types/tar":"^6.1.13","type-fest":"^4.37.0",typescript:"^5.8.2"}};process.on("SIGINT",()=>process.exit(0));process.on("SIGTERM",()=>process.exit(0));async function q0(){let z=new $0().name(U3.name).version(U3.version);z.addCommand(_3).addCommand(E3),z.parse()}q0();
51
+ ${_.cyan(`@config "../${L?.isSrcDir&&"../"}${R.relative(Q,K.tailwindFile)}";`)}
52
+ `);let C=K?.layoutFile||K?.appFile||L?.framework==="vite"&&K?.mainFile||"";if(!C)console.log(`Import following files to your main file:
53
+ `),W.forEach((I)=>{console.log(_.cyan(I))});else{let y=new E3({tsConfigFilePath:R.resolve(K?.tsConfig||"")}).addSourceFileAtPath(R.resolve(C)),k="globals.css";y.getImportDeclarations().filter((g)=>g.getModuleSpecifierValue().includes("globals.css")).forEach((g)=>g.remove());let F=R.relative(R.resolve(Q,`${L?.isSrcDir&&"src"}`),C).split("/").length,e=L?.aliasPrefix?.stylesPrefix||L?.aliasPrefix?.srcPrefix||(F===1?"./":"../".repeat(F-1));y.addImportDeclarations(W.filter((g)=>g.includes("globals.css")).map((g)=>({moduleSpecifier:`${e}${L?.aliasPrefix?.stylesPrefix?g?.split("styles/")[1]:g}`}))),y.saveSync()}let E=o(),x=A0.sync(["**/styles/theme.css"],{cwd:Q,absolute:!0,onlyFiles:!0,ignore:h});if(!x?.length)return J.fail(`Failed to copy ${_.cyan("theme.css")} file.
54
+ Ensure that the ${_.cyan("theme.css")} file exists in the project directory under ${_.yellow("styles/")} folder.`);if(R0("brand",j.color||"",x[0]??""),E.start("Installing dependencies"),await V0(()=>p(T(),[T()==="npm"?"install":"add",...U]).catch(async(I)=>{if(I.message.includes("peer"))E.warn("Dependency conflict detected. Retrying with --legacy-peer-deps..."),E.start("Installing dependencies with --legacy-peer-deps flag"),await p(T(),[T()==="npm"?"install":"add",...U,"--legacy-peer-deps"])}),{retries:1}),await V0(()=>p(T(),[T()==="npm"?"install":"add",...b]).catch(async(I)=>{if(I.message.includes("peer"))E.warn("DevDependency conflict detected. Retrying with --legacy-peer-deps..."),E.start("Installing dependencies with --legacy-peer-deps flag"),await p(T(),[T()==="npm"?"install":"add",...b,"--legacy-peer-deps"])}),{retries:1}),E.succeed("Dependencies are installed"),J.succeed(_.green("Project setup is completed!")),!z?.projectPath)console.log(`
55
+ Your project is ready, you can now start adding components.`)}}var S3=G.join(T3.homedir(),".untitledui"),s=G.join(S3,"config.json"),$={path:"",example:"",license:"",components:[]},O={};if(u.existsSync(s)){let B=JSON.parse(u.readFileSync(s,"utf-8"));$.license=B.license}var t=(B)=>{if(B.aborted)process.stdout.write("\x1B[?25h"),process.stdout.write(`
56
+ `),process.exit(1)},h0=new w3().name("example").description("add an example to the project").argument("[example]","the example to add").option("-o, --overwrite","overwrite existing files.",!1).option("-p, --path <path>","the path to add the component to.").option("-e, --example-path <example-path>","the path to add the example file to.").addOption(new u3("-l, --license <license-key>","Add a license key for adding components.").hideHelp()).action(async(B,z)=>{if(B)$.example=B;if(z)$.path=z.path,$.overwrite=z.overwrite,$.examplePath=z.examplePath,$.license=z.license||$.license;try{await _0(z,O),await C3($)}catch(Q){console.error(H.red(Q))}});async function C3(B){let z=Q0().start(),Q=G.posix.join(process.cwd(),O?.projectPath||"");if(!u.existsSync(G.posix.join(G.resolve(Q,"package.json"))))z.warn("This command should be run in a project directory."),process.exit(1);let Y=await n(Q);if($.license){if(!await a($.license))z.fail("Invalid license key"),process.exit(1);if(!u.existsSync(s)){let b=G.dirname(s);u.mkdirSync(b,{recursive:!0}),u.writeFileSync(s,JSON.stringify({license:$.license},null,2))}if(JSON.parse(u.readFileSync(s,"utf-8")).license!==$.license)u.writeFileSync(s,JSON.stringify({license:$.license},null,2),"utf-8")}if(z.stop(),!$.example){let W=await l({type:"select",name:"example",onState:t,message:"Select which type of example you want to add",choices:[{title:"Application",value:"application"},{title:"Marketing",value:"marketing"}]});$.example=W.example}let V=null;if($.example){let W=await q0($.example,$.license);if(W?.type==="error"&&(W.status===401||W.status===403))console.log(),console.log(H.yellow(`\uD83D\uDD12 The ${H.cyan($.example)} example requires PRO access.`)),console.log(),console.log("To access PRO examples:"),console.log(` ${H.green("→")} If you've already purchased: ${H.cyan("npx untitledui@latest login")}`),console.log(` ${H.green("→")} To purchase PRO examples: ${H.cyan("https://www.untitledui.com/buy/react")}`),console.log(),process.exit(1);if(W?.type==="directory"){let U=await l({type:"select",name:"example",onState:t,message:`Select a folder or file in "${$.example}"`,choices:W.results.map((b)=>({title:b,value:b}))});if(!U.example)return;if($.example=U.example,W=await q0(U.example,$.license),W?.type==="error"&&(W.status===401||W.status===403))console.log(),console.log(H.yellow(`\uD83D\uDD12 The ${H.cyan(U.example)} example requires PRO access.`)),console.log(),console.log("To access PRO examples:"),console.log(` ${H.green("→")} If you've already purchased: ${H.cyan("npx untitledui@latest login")}`),console.log(` ${H.green("→")} To purchase PRO examples: ${H.cyan("https://www.untitledui.com/buy/react")}`),console.log(),process.exit(1)}if(W?.type==="json-files"){let U=await l({type:"select",name:"example",onState:t,message:`Select a JSON file in "${$.example}"`,choices:W.results.map((b)=>({title:b,value:`${$.example}/${b}`}))});if(!U.example)return;if($.example=U.example,W=await q0(U.example,$.license),W?.type==="error"&&(W.status===401||W.status===403))console.log(),console.log(H.yellow(`\uD83D\uDD12 The ${H.cyan(U.example)} example requires PRO access.`)),console.log(),console.log("To access PRO examples:"),console.log(` ${H.green("→")} If you've already purchased: ${H.cyan("npx untitledui@latest login")}`),console.log(` ${H.green("→")} To purchase PRO examples: ${H.cyan("https://www.untitledui.com/buy/react")}`),console.log(),process.exit(1)}if(W?.type==="json-file")V=W.content}if(!V)z.fail("No example found"),process.exit(1);if(!$?.examplePath){let W=Y?.isUsingAppDir?"app":"pages",U=Y?.isSrcDir?G.posix.join("src",W):W,b=await l({type:"text",name:"examplePath",onState:t,message:`Where would you like to add the ${H.cyan($?.example)} example?`,initial:U});$.examplePath=b.examplePath}else if(!u.existsSync(G.posix.join(Q,$.examplePath)))u.mkdirSync(G.posix.join(Q,$.examplePath),{recursive:!0}),console.log(H.green(`Created directory ${$.examplePath}`));if(!$?.path){let W=await l({type:"text",name:"path",onState:t,message:`Where would you like to add the ${H.cyan("components")}?`,initial:"components"});$.path=W.path}let v=V.components.filter((W)=>!u.existsSync(G.posix.join(Q,`${Y?.isSrcDir&&"src"}`,W?.path?.replace(/components\//,$.path+"/"))));if(v?.length){let W=await l({type:"multiselect",name:"components",onState:t,message:`Select which components you want to add from ${H.cyan(V.name)} example`,choices:v.map((U)=>({title:U?.name,value:U?.name})),instructions:!1,hint:"- Space to select. Return to submit"});if($.components=W.components,!v.length&&!W.components?.length)z.warn("No components selected")}let M=r(Q),L=new Set,J=new y3({tsConfigFilePath:M?.tsConfig}),A=Q0(`Adding ${$?.example}...`).start();try{if(V.files?.forEach(async({path:W,code:U})=>{let b=G.posix.join(Q,`${Y?.isSrcDir&&"src"}`,W.replace(/components\//,$.path+"/"));if(W.includes("examples")){let E=G.basename(W);b=G.posix.join(Q,$?.examplePath??"",E)}let C=G.dirname(b);if(u.existsSync(b)&&!$.overwrite){if(u.readFileSync(b,"utf-8")!==U)L.add({code:U,path:b})}else{u.mkdirSync(C,{recursive:!0}),u.writeFileSync(b,U);let E=G.relative(G.resolve(Q,`${Y?.isSrcDir&&"src"}`,$.path),b).split("/").length,x=E===1?"./":"../".repeat(E-1),I=J.addSourceFileAtPath(G.resolve(b));I.getImportDeclarations().forEach((y)=>{let k=y.getModuleSpecifierValue();y.setModuleSpecifier(i(k,$.path,Y?.aliasPrefix,x))}),await I.save()}}),L.size)A.warn(`Some files of ${H.yellow($?.example)} already exist`);else A.succeed(`${H.green($?.example)} is added successfully`)}catch(W){A.fail(`
57
+ Failed to add the component ${H.red($?.example)}`),console.error(H.red(W)),process.exit(1)}if(L.size&&!$?.overwrite)if(console.log(`
58
+ Following files already exist in the directory.`),L.forEach((U)=>{console.log(H.green(`- ${G.relative(Q,U.path)}`))}),(await l({type:"confirm",name:"overwrite",message:"Do you want to overwrite the existing files?",initial:!0})).overwrite){let U=Q0("Overwriting files").start();L.forEach((b)=>{let C=G.relative(G.resolve(Q,`${Y?.isSrcDir&&"src"}`,$.path),b.path).split("/").length,E=C===1?"./":"../".repeat(C-1),x=J.addSourceFileAtPath(G.resolve(b.path));x.replaceWithText(b.code),x.getImportDeclarations().forEach((I)=>{let y=I.getModuleSpecifierValue();I.setModuleSpecifier(i(y,$.path,Y?.aliasPrefix,E))}),x.saveSync()}),U.succeed("Files are overwritten")}else console.log(`Use ${H.cyan("--overwrite")} or ${H.cyan("-o")} to overwrite existing files, or refer to the documentation ${H.cyan("https://untitled.xyz/docs")} for manual installation. The rest of the files are added.`),process.exit(1);let K=T();if(V?.dependencies?.length){let W=Q0("Installing example dependencies").start();await N0(()=>B0("sh",["-c",`${O?.projectPath?`cd ${O?.projectPath} && `:""}${K} ${K==="npm"?"install":"add"} ${Array.from(V.dependencies).join(" ")}`]).catch(async(U)=>{if(U.message.includes("peer"))W.warn("Dependency conflict detected. Retrying with --legacy-peer-deps..."),W.start("Installing dependencies with --legacy-peer-deps flag"),await B0("sh",["-c",`${O?.projectPath?`cd ${O?.projectPath} && `:""}${K} ${K==="npm"?"install":"add"} ${Array.from(V.dependencies).join(" ")} --legacy-peer-deps`])}),{retries:1}),W.succeed("Example dependencies are installed")}if(V?.devDependencies?.length){let W=Q0("Installing example devDependencies").start();await N0(()=>B0("sh",["-c",`${O?.projectPath?`cd ${O?.projectPath} && `:""}${K} ${K==="npm"?"install":"add"} ${Array.from(V.devDependencies).join(" ")}`]).catch(async(U)=>{if(U.message.includes("peer"))W.warn("DevDependency conflict detected. Retrying with --legacy-peer-deps..."),W.start("Installing devDependencies with --legacy-peer-deps flag"),await B0("sh",["-c",`${O?.projectPath?`cd ${O?.projectPath} && `:""}${K} ${K==="npm"?"install":"add"} ${Array.from(V.devDependencies).join(" ")} --legacy-peer-deps`])}),{retries:1}),W.succeed("Example devDependencies are installed")}let q=S0();if($?.components?.length)await N0(()=>B0(q,["untitledui@latest","add",...$.components,"--path",$.path,"--dir",O?.projectPath||""],{stdio:"inherit"}),{retries:1});process.exit(0)}var D0={name:"untitledui",version:"0.1.7",main:"dist/index.mjs",description:"Untitled UI CLI",type:"module",publishConfig:{access:"public"},scripts:{test:'echo "Error: no test specified" && exit 1',dev:"bun build --entrypoints ./index.ts --entry-naming=[name].mjs --outdir=dist --target=node --minify --packages=external --env=inline --define=process.env.API_URL=http://localhost:3000/api --watch",build:"bun build --entrypoints ./index.ts --entry-naming=[name].mjs --outdir=dist --target=node --minify --packages=external --env=inline --define=process.env.API_URL=https://untitledui-docs.vercel.app/api","publish:npm":"bun run build && npm publish --access public",start:"node dist/index.mjs"},repository:{type:"git",url:"https://github.com/a-peak-works/untitledui-tailwind.git"},bugs:{url:"https://github.com/a-peak-works/untitledui-tailwind/issues"},homepage:"https://github.com/a-peak-works/untitledui-tailwind#readme",keywords:["untitled-ui","cli","tailwindcss","nextjs"],files:["dist","config"],author:"",license:"MIT",bin:{untitledui:"dist/index.mjs"},exports:"./dist/index.mjs",dependencies:{"async-retry":"^1.3.3",chalk:"^5.4.1",commander:"^13.1.0",execa:"^7.0.0","fast-glob":"^3.3.3","node-fetch":"^3.3.2",open:"^10.1.0",ora:"^8.2.0",prettier:"^3.5.3",prompts:"^2.4.2",tar:"^7.4.3","ts-morph":"^25.0.1","tsconfig-paths":"^4.2.0","update-check":"^1.5.4"},devDependencies:{"@types/async-retry":"^1.4.9","@types/prompts":"^2.4.9","@types/tar":"^6.1.13","type-fest":"^4.37.0",typescript:"^5.8.2"}};process.on("SIGINT",()=>process.exit(0));process.on("SIGTERM",()=>process.exit(0));async function F3(){let B=new k3().name(D0.name).version(D0.version);B.addCommand(d0).addCommand(x0).addCommand(h0).addCommand(k0),B.parse()}F3();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "untitledui",
3
- "version": "0.1.5",
3
+ "version": "0.1.8",
4
4
  "main": "dist/index.mjs",
5
5
  "description": "Untitled UI CLI",
6
6
  "type": "module",
@@ -12,7 +12,7 @@
12
12
  "dev": "bun build --entrypoints ./index.ts --entry-naming=[name].mjs --outdir=dist --target=node --minify --packages=external --env=inline --define=process.env.API_URL=http://localhost:3000/api --watch",
13
13
  "build": "bun build --entrypoints ./index.ts --entry-naming=[name].mjs --outdir=dist --target=node --minify --packages=external --env=inline --define=process.env.API_URL=https://untitledui-docs.vercel.app/api",
14
14
  "publish:npm": "bun run build && npm publish --access public",
15
- "start": "node dist/index.js"
15
+ "start": "node dist/index.mjs"
16
16
  },
17
17
  "repository": {
18
18
  "type": "git",
@@ -30,7 +30,7 @@
30
30
  ],
31
31
  "files": [
32
32
  "dist",
33
- "templates"
33
+ "config"
34
34
  ],
35
35
  "author": "",
36
36
  "license": "MIT",
@@ -45,6 +45,7 @@
45
45
  "execa": "^7.0.0",
46
46
  "fast-glob": "^3.3.3",
47
47
  "node-fetch": "^3.3.2",
48
+ "open": "^10.1.0",
48
49
  "ora": "^8.2.0",
49
50
  "prettier": "^3.5.3",
50
51
  "prompts": "^2.4.2",