@tanstack/create 0.61.5 → 0.62.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.
Files changed (147) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/dist/config-file.js +5 -2
  3. package/dist/custom-add-ons/starter.js +45 -28
  4. package/dist/file-helpers.js +1 -0
  5. package/dist/frameworks/react/add-ons/shadcn/assets/src/styles.css +224 -15
  6. package/dist/frameworks/react/add-ons/store/assets/src/lib/demo-store.ts +5 -6
  7. package/dist/frameworks/react/add-ons/store/assets/src/routes/demo/store.tsx.ejs +1 -1
  8. package/dist/frameworks/react/add-ons/store/package.json +2 -2
  9. package/dist/frameworks/react/add-ons/strapi/README.md +158 -8
  10. package/dist/frameworks/react/add-ons/strapi/assets/_dot_env.local.append +1 -1
  11. package/dist/frameworks/react/add-ons/strapi/assets/src/components/blocks/block-renderer.tsx +55 -0
  12. package/dist/frameworks/react/add-ons/strapi/assets/src/components/blocks/index.ts +14 -0
  13. package/dist/frameworks/react/add-ons/strapi/assets/src/components/blocks/media.tsx +27 -0
  14. package/dist/frameworks/react/add-ons/strapi/assets/src/components/blocks/quote.tsx +19 -0
  15. package/dist/frameworks/react/add-ons/strapi/assets/src/components/blocks/rich-text.tsx +11 -0
  16. package/dist/frameworks/react/add-ons/strapi/assets/src/components/blocks/slider.tsx +28 -0
  17. package/dist/frameworks/react/add-ons/strapi/assets/src/components/markdown-content.tsx +74 -0
  18. package/dist/frameworks/react/add-ons/strapi/assets/src/components/pagination.tsx +120 -0
  19. package/dist/frameworks/react/add-ons/strapi/assets/src/components/search.tsx +35 -0
  20. package/dist/frameworks/react/add-ons/strapi/assets/src/components/strapi-image.tsx +47 -0
  21. package/dist/frameworks/react/add-ons/strapi/assets/src/data/loaders/articles.ts +106 -0
  22. package/dist/frameworks/react/add-ons/strapi/assets/src/data/loaders/index.ts +28 -0
  23. package/dist/frameworks/react/add-ons/strapi/assets/src/data/strapi-sdk.ts +9 -0
  24. package/dist/frameworks/react/add-ons/strapi/assets/src/lib/strapi-utils.ts +25 -0
  25. package/dist/frameworks/react/add-ons/strapi/assets/src/routes/demo/strapi.$articleId.tsx +170 -0
  26. package/dist/frameworks/react/add-ons/strapi/assets/src/routes/demo/strapi.tsx +269 -43
  27. package/dist/frameworks/react/add-ons/strapi/assets/src/types/strapi.ts +90 -0
  28. package/dist/frameworks/react/add-ons/strapi/info.json +3 -3
  29. package/dist/frameworks/react/add-ons/strapi/package.json +5 -2
  30. package/dist/frameworks/react/index.js +2 -2
  31. package/dist/frameworks/react/project/base/content/blog/fifth-post.mdx.ejs +54 -0
  32. package/dist/frameworks/react/project/base/content/blog/first-post.md.ejs +47 -0
  33. package/dist/frameworks/react/project/base/content/blog/fourth-post.md.ejs +42 -0
  34. package/dist/frameworks/react/project/base/content/blog/second-post.mdx.ejs +46 -0
  35. package/dist/frameworks/react/project/base/content/blog/third-post.md.ejs +49 -0
  36. package/dist/frameworks/react/project/base/content-collections.ts.ejs +37 -0
  37. package/dist/frameworks/react/project/base/package.json +8 -1
  38. package/dist/frameworks/react/project/base/public/images/lagoon-1.svg +13 -0
  39. package/dist/frameworks/react/project/base/public/images/lagoon-2.svg +12 -0
  40. package/dist/frameworks/react/project/base/public/images/lagoon-3.svg +12 -0
  41. package/dist/frameworks/react/project/base/public/images/lagoon-4.svg +12 -0
  42. package/dist/frameworks/react/project/base/public/images/lagoon-5.svg +12 -0
  43. package/dist/frameworks/react/project/base/public/images/lagoon-about.svg +14 -0
  44. package/dist/frameworks/react/project/base/src/components/Footer.tsx.ejs +42 -0
  45. package/dist/frameworks/react/project/base/src/components/Header.tsx.ejs +92 -138
  46. package/dist/frameworks/react/project/base/src/components/MdxCallout.tsx.ejs +16 -0
  47. package/dist/frameworks/react/project/base/src/components/MdxMetrics.tsx.ejs +23 -0
  48. package/dist/frameworks/react/project/base/src/components/ThemeToggle.tsx.ejs +81 -0
  49. package/dist/frameworks/react/project/base/src/lib/site.ts.ejs +4 -0
  50. package/dist/frameworks/react/project/base/src/main.tsx.ejs +0 -1
  51. package/dist/frameworks/react/project/base/src/routes/__root.tsx.ejs +10 -6
  52. package/dist/frameworks/react/project/base/src/routes/about.tsx.ejs +27 -0
  53. package/dist/frameworks/react/project/base/src/routes/blog.$slug.tsx.ejs +71 -0
  54. package/dist/frameworks/react/project/base/src/routes/blog.index.tsx.ejs +93 -0
  55. package/dist/frameworks/react/project/base/src/routes/index.tsx.ejs +58 -91
  56. package/dist/frameworks/react/project/base/src/routes/rss[.]xml.ts.ejs +35 -0
  57. package/dist/frameworks/react/project/base/src/styles.css.ejs +268 -6
  58. package/dist/frameworks/react/project/base/tsconfig.json.ejs +2 -0
  59. package/dist/frameworks/react/project/base/vite.config.ts.ejs +2 -0
  60. package/dist/frameworks/solid/add-ons/store/assets/src/lib/demo-store.ts +5 -6
  61. package/dist/frameworks/solid/add-ons/store/assets/src/routes/demo.store.tsx.ejs +2 -2
  62. package/dist/frameworks/solid/examples/tanchat/assets/src/lib/demo-store.ts +5 -6
  63. package/dist/frameworks/solid/project/base/src/components/Header.tsx.ejs +8 -6
  64. package/dist/frameworks/solid/project/base/src/routes/__root.tsx.ejs +1 -1
  65. package/dist/frameworks/solid/project/base/src/routes/index.tsx.ejs +1 -1
  66. package/dist/frameworks.js +3 -0
  67. package/dist/package-json.js +1 -1
  68. package/dist/registry.js +21 -4
  69. package/dist/types/registry.d.ts +38 -0
  70. package/package.json +1 -1
  71. package/src/config-file.ts +6 -2
  72. package/src/custom-add-ons/starter.ts +30 -10
  73. package/src/file-helpers.ts +1 -0
  74. package/src/frameworks/react/add-ons/shadcn/assets/src/styles.css +224 -15
  75. package/src/frameworks/react/add-ons/store/assets/src/lib/demo-store.ts +5 -6
  76. package/src/frameworks/react/add-ons/store/assets/src/routes/demo/store.tsx.ejs +1 -1
  77. package/src/frameworks/react/add-ons/store/package.json +2 -2
  78. package/src/frameworks/react/add-ons/strapi/README.md +158 -8
  79. package/src/frameworks/react/add-ons/strapi/assets/_dot_env.local.append +1 -1
  80. package/src/frameworks/react/add-ons/strapi/assets/src/components/blocks/block-renderer.tsx +55 -0
  81. package/src/frameworks/react/add-ons/strapi/assets/src/components/blocks/index.ts +14 -0
  82. package/src/frameworks/react/add-ons/strapi/assets/src/components/blocks/media.tsx +27 -0
  83. package/src/frameworks/react/add-ons/strapi/assets/src/components/blocks/quote.tsx +19 -0
  84. package/src/frameworks/react/add-ons/strapi/assets/src/components/blocks/rich-text.tsx +11 -0
  85. package/src/frameworks/react/add-ons/strapi/assets/src/components/blocks/slider.tsx +28 -0
  86. package/src/frameworks/react/add-ons/strapi/assets/src/components/markdown-content.tsx +74 -0
  87. package/src/frameworks/react/add-ons/strapi/assets/src/components/pagination.tsx +120 -0
  88. package/src/frameworks/react/add-ons/strapi/assets/src/components/search.tsx +35 -0
  89. package/src/frameworks/react/add-ons/strapi/assets/src/components/strapi-image.tsx +47 -0
  90. package/src/frameworks/react/add-ons/strapi/assets/src/data/loaders/articles.ts +106 -0
  91. package/src/frameworks/react/add-ons/strapi/assets/src/data/loaders/index.ts +28 -0
  92. package/src/frameworks/react/add-ons/strapi/assets/src/data/strapi-sdk.ts +9 -0
  93. package/src/frameworks/react/add-ons/strapi/assets/src/lib/strapi-utils.ts +25 -0
  94. package/src/frameworks/react/add-ons/strapi/assets/src/routes/demo/strapi.$articleId.tsx +170 -0
  95. package/src/frameworks/react/add-ons/strapi/assets/src/routes/demo/strapi.tsx +269 -43
  96. package/src/frameworks/react/add-ons/strapi/assets/src/types/strapi.ts +90 -0
  97. package/src/frameworks/react/add-ons/strapi/info.json +3 -3
  98. package/src/frameworks/react/add-ons/strapi/package.json +5 -2
  99. package/src/frameworks/react/index.ts +2 -2
  100. package/src/frameworks/react/project/base/content/blog/fifth-post.mdx.ejs +54 -0
  101. package/src/frameworks/react/project/base/content/blog/first-post.md.ejs +47 -0
  102. package/src/frameworks/react/project/base/content/blog/fourth-post.md.ejs +42 -0
  103. package/src/frameworks/react/project/base/content/blog/second-post.mdx.ejs +46 -0
  104. package/src/frameworks/react/project/base/content/blog/third-post.md.ejs +49 -0
  105. package/src/frameworks/react/project/base/content-collections.ts.ejs +37 -0
  106. package/src/frameworks/react/project/base/package.json +8 -1
  107. package/src/frameworks/react/project/base/public/images/lagoon-1.svg +13 -0
  108. package/src/frameworks/react/project/base/public/images/lagoon-2.svg +12 -0
  109. package/src/frameworks/react/project/base/public/images/lagoon-3.svg +12 -0
  110. package/src/frameworks/react/project/base/public/images/lagoon-4.svg +12 -0
  111. package/src/frameworks/react/project/base/public/images/lagoon-5.svg +12 -0
  112. package/src/frameworks/react/project/base/public/images/lagoon-about.svg +14 -0
  113. package/src/frameworks/react/project/base/src/components/Footer.tsx.ejs +42 -0
  114. package/src/frameworks/react/project/base/src/components/Header.tsx.ejs +92 -138
  115. package/src/frameworks/react/project/base/src/components/MdxCallout.tsx.ejs +16 -0
  116. package/src/frameworks/react/project/base/src/components/MdxMetrics.tsx.ejs +23 -0
  117. package/src/frameworks/react/project/base/src/components/ThemeToggle.tsx.ejs +81 -0
  118. package/src/frameworks/react/project/base/src/lib/site.ts.ejs +4 -0
  119. package/src/frameworks/react/project/base/src/main.tsx.ejs +0 -1
  120. package/src/frameworks/react/project/base/src/routes/__root.tsx.ejs +10 -6
  121. package/src/frameworks/react/project/base/src/routes/about.tsx.ejs +27 -0
  122. package/src/frameworks/react/project/base/src/routes/blog.$slug.tsx.ejs +71 -0
  123. package/src/frameworks/react/project/base/src/routes/blog.index.tsx.ejs +93 -0
  124. package/src/frameworks/react/project/base/src/routes/index.tsx.ejs +58 -91
  125. package/src/frameworks/react/project/base/src/routes/rss[.]xml.ts.ejs +35 -0
  126. package/src/frameworks/react/project/base/src/styles.css.ejs +268 -6
  127. package/src/frameworks/react/project/base/tsconfig.json.ejs +2 -0
  128. package/src/frameworks/react/project/base/vite.config.ts.ejs +2 -0
  129. package/src/frameworks/solid/add-ons/store/assets/src/lib/demo-store.ts +5 -6
  130. package/src/frameworks/solid/add-ons/store/assets/src/routes/demo.store.tsx.ejs +2 -2
  131. package/src/frameworks/solid/examples/tanchat/assets/src/lib/demo-store.ts +5 -6
  132. package/src/frameworks/solid/project/base/src/components/Header.tsx.ejs +8 -6
  133. package/src/frameworks/solid/project/base/src/routes/__root.tsx.ejs +1 -1
  134. package/src/frameworks/solid/project/base/src/routes/index.tsx.ejs +1 -1
  135. package/src/frameworks.ts +4 -0
  136. package/src/package-json.ts +1 -1
  137. package/src/registry.ts +28 -4
  138. package/tests/add-ons.test.ts +4 -4
  139. package/tests/config-file.test.ts +3 -3
  140. package/tests/custom-add-ons/starter.test.ts +34 -2
  141. package/tests/frameworks.test.ts +24 -0
  142. package/tests/options.test.ts +4 -4
  143. package/tests/utils.test.ts +2 -2
  144. package/dist/frameworks/react/add-ons/strapi/assets/src/lib/strapiClient.ts +0 -7
  145. package/dist/frameworks/react/add-ons/strapi/assets/src/routes/demo/strapi_.$articleId.tsx +0 -78
  146. package/src/frameworks/react/add-ons/strapi/assets/src/lib/strapiClient.ts +0 -7
  147. package/src/frameworks/react/add-ons/strapi/assets/src/routes/demo/strapi_.$articleId.tsx +0 -78
@@ -1,15 +1,277 @@
1
+ @import url("https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,500;9..144,700&family=Manrope:wght@400;500;600;700;800&display=swap");
1
2
  @import "tailwindcss";
3
+ @plugin "@tailwindcss/typography";
4
+
5
+ @theme {
6
+ --font-sans: "Manrope", ui-sans-serif, system-ui, sans-serif;
7
+ }
8
+
9
+ :root {
10
+ --sea-ink: #173a40;
11
+ --sea-ink-soft: #416166;
12
+ --lagoon: #4fb8b2;
13
+ --lagoon-deep: #328f97;
14
+ --palm: #2f6a4a;
15
+ --sand: #e7f0e8;
16
+ --foam: #f3faf5;
17
+ --surface: rgba(255, 255, 255, 0.74);
18
+ --surface-strong: rgba(255, 255, 255, 0.9);
19
+ --line: rgba(23, 58, 64, 0.14);
20
+ --inset-glint: rgba(255, 255, 255, 0.82);
21
+ --kicker: rgba(47, 106, 74, 0.9);
22
+ --bg-base: #e7f3ec;
23
+ --header-bg: rgba(251, 255, 248, 0.84);
24
+ --chip-bg: rgba(255, 255, 255, 0.8);
25
+ --chip-line: rgba(47, 106, 74, 0.18);
26
+ --link-bg-hover: rgba(255, 255, 255, 0.9);
27
+ --hero-a: rgba(79, 184, 178, 0.36);
28
+ --hero-b: rgba(47, 106, 74, 0.2);
29
+ }
30
+
31
+ :root[data-theme="dark"] {
32
+ --sea-ink: #d7ece8;
33
+ --sea-ink-soft: #afcdc8;
34
+ --lagoon: #60d7cf;
35
+ --lagoon-deep: #8de5db;
36
+ --palm: #6ec89a;
37
+ --sand: #0f1a1e;
38
+ --foam: #101d22;
39
+ --surface: rgba(16, 30, 34, 0.8);
40
+ --surface-strong: rgba(15, 27, 31, 0.92);
41
+ --line: rgba(141, 229, 219, 0.18);
42
+ --inset-glint: rgba(194, 247, 238, 0.14);
43
+ --kicker: #b8efe5;
44
+ --bg-base: #0a1418;
45
+ --header-bg: rgba(10, 20, 24, 0.8);
46
+ --chip-bg: rgba(13, 28, 32, 0.9);
47
+ --chip-line: rgba(141, 229, 219, 0.24);
48
+ --link-bg-hover: rgba(24, 44, 49, 0.8);
49
+ --hero-a: rgba(96, 215, 207, 0.18);
50
+ --hero-b: rgba(110, 200, 154, 0.12);
51
+ }
52
+
53
+ @media (prefers-color-scheme: dark) {
54
+ :root:not([data-theme="light"]) {
55
+ --sea-ink: #d7ece8;
56
+ --sea-ink-soft: #afcdc8;
57
+ --lagoon: #60d7cf;
58
+ --lagoon-deep: #8de5db;
59
+ --palm: #6ec89a;
60
+ --sand: #0f1a1e;
61
+ --foam: #101d22;
62
+ --surface: rgba(16, 30, 34, 0.8);
63
+ --surface-strong: rgba(15, 27, 31, 0.92);
64
+ --line: rgba(141, 229, 219, 0.18);
65
+ --inset-glint: rgba(194, 247, 238, 0.14);
66
+ --kicker: #b8efe5;
67
+ --bg-base: #0a1418;
68
+ --header-bg: rgba(10, 20, 24, 0.8);
69
+ --chip-bg: rgba(13, 28, 32, 0.9);
70
+ --chip-line: rgba(141, 229, 219, 0.24);
71
+ --link-bg-hover: rgba(24, 44, 49, 0.8);
72
+ --hero-a: rgba(96, 215, 207, 0.18);
73
+ --hero-b: rgba(110, 200, 154, 0.12);
74
+ }
75
+ }
76
+
77
+ * {
78
+ box-sizing: border-box;
79
+ }
80
+
81
+ html,
82
+ body,
83
+ #app {
84
+ min-height: 100%;
85
+ }
2
86
 
3
87
  body {
4
- @apply m-0;
5
- font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
6
- "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
7
- sans-serif;
88
+ margin: 0;
89
+ color: var(--sea-ink);
90
+ font-family: var(--font-sans);
91
+ background-color: var(--bg-base);
92
+ background:
93
+ radial-gradient(1100px 620px at -8% -10%, var(--hero-a), transparent 58%),
94
+ radial-gradient(1050px 620px at 112% -12%, var(--hero-b), transparent 62%),
95
+ radial-gradient(720px 380px at 50% 115%, rgba(79, 184, 178, 0.1), transparent 68%),
96
+ linear-gradient(180deg, color-mix(in oklab, var(--sand) 68%, white) 0%, var(--foam) 44%, var(--bg-base) 100%);
97
+ overflow-x: hidden;
8
98
  -webkit-font-smoothing: antialiased;
9
99
  -moz-osx-font-smoothing: grayscale;
10
100
  }
11
101
 
102
+ body::before {
103
+ content: "";
104
+ position: fixed;
105
+ inset: 0;
106
+ pointer-events: none;
107
+ z-index: -1;
108
+ opacity: 0.28;
109
+ background:
110
+ radial-gradient(circle at 20% 15%, rgba(255, 255, 255, 0.8), transparent 34%),
111
+ radial-gradient(circle at 78% 26%, rgba(79, 184, 178, 0.2), transparent 42%),
112
+ radial-gradient(circle at 42% 82%, rgba(47, 106, 74, 0.14), transparent 36%);
113
+ }
114
+
115
+ body::after {
116
+ content: "";
117
+ position: fixed;
118
+ inset: 0;
119
+ pointer-events: none;
120
+ z-index: -1;
121
+ opacity: 0.14;
122
+ background-image:
123
+ linear-gradient(rgba(255, 255, 255, 0.07) 1px, transparent 1px),
124
+ linear-gradient(90deg, rgba(255, 255, 255, 0.06) 1px, transparent 1px);
125
+ background-size: 28px 28px;
126
+ mask-image: radial-gradient(circle at 50% 30%, black, transparent 78%);
127
+ }
128
+
129
+ a {
130
+ color: var(--lagoon-deep);
131
+ text-decoration-color: rgba(50, 143, 151, 0.4);
132
+ text-decoration-thickness: 1px;
133
+ text-underline-offset: 2px;
134
+ }
135
+
136
+ a:hover {
137
+ color: #246f76;
138
+ }
139
+
12
140
  code {
13
- font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
14
- monospace;
141
+ font-size: 0.9em;
142
+ border: 1px solid var(--line);
143
+ background: color-mix(in oklab, var(--surface-strong) 82%, white 18%);
144
+ border-radius: 7px;
145
+ padding: 2px 7px;
146
+ }
147
+
148
+ pre code {
149
+ border: 0;
150
+ background: transparent;
151
+ padding: 0;
152
+ border-radius: 0;
153
+ font-size: inherit;
154
+ color: inherit;
155
+ }
156
+
157
+ .prose pre {
158
+ border: 1px solid var(--line);
159
+ border-radius: 12px;
160
+ background: #1d2e45;
161
+ color: #e8efff;
162
+ overflow-x: auto;
163
+ }
164
+
165
+ .prose {
166
+ overflow-wrap: anywhere;
167
+ }
168
+
169
+ .prose table {
170
+ display: block;
171
+ width: 100%;
172
+ overflow-x: auto;
173
+ }
174
+
175
+ .page-wrap {
176
+ width: min(1080px, calc(100% - 2rem));
177
+ margin-inline: auto;
178
+ }
179
+
180
+ .display-title {
181
+ font-family: "Fraunces", Georgia, serif;
182
+ }
183
+
184
+ .island-shell {
185
+ border: 1px solid var(--line);
186
+ background: linear-gradient(165deg, var(--surface-strong), var(--surface));
187
+ box-shadow:
188
+ 0 1px 0 var(--inset-glint) inset,
189
+ 0 22px 44px rgba(30, 90, 72, 0.1),
190
+ 0 6px 18px rgba(23, 58, 64, 0.08);
191
+ backdrop-filter: blur(4px);
192
+ }
193
+
194
+ .feature-card {
195
+ background: linear-gradient(165deg, color-mix(in oklab, var(--surface-strong) 93%, white 7%), var(--surface));
196
+ box-shadow:
197
+ 0 1px 0 var(--inset-glint) inset,
198
+ 0 18px 34px rgba(30, 90, 72, 0.1),
199
+ 0 4px 14px rgba(23, 58, 64, 0.06);
200
+ }
201
+
202
+ .feature-card:hover {
203
+ transform: translateY(-2px);
204
+ border-color: color-mix(in oklab, var(--lagoon-deep) 35%, var(--line));
205
+ }
206
+
207
+ button,
208
+ .island-shell,
209
+ a {
210
+ transition: background-color 180ms ease, color 180ms ease, border-color 180ms ease,
211
+ transform 180ms ease;
212
+ }
213
+
214
+ .island-kicker {
215
+ letter-spacing: 0.16em;
216
+ text-transform: uppercase;
217
+ font-weight: 700;
218
+ font-size: 0.69rem;
219
+ color: var(--kicker);
220
+ }
221
+
222
+ .nav-link {
223
+ position: relative;
224
+ display: inline-flex;
225
+ align-items: center;
226
+ text-decoration: none;
227
+ color: var(--sea-ink-soft);
228
+ }
229
+
230
+ .nav-link::after {
231
+ content: "";
232
+ position: absolute;
233
+ left: 0;
234
+ bottom: -6px;
235
+ width: 100%;
236
+ height: 2px;
237
+ transform: scaleX(0);
238
+ transform-origin: left;
239
+ background: linear-gradient(90deg, var(--lagoon), #7ed3bf);
240
+ transition: transform 170ms ease;
241
+ }
242
+
243
+ .nav-link:hover,
244
+ .nav-link.is-active {
245
+ color: var(--sea-ink);
246
+ }
247
+
248
+ .nav-link:hover::after,
249
+ .nav-link.is-active::after {
250
+ transform: scaleX(1);
251
+ }
252
+
253
+ @media (max-width: 640px) {
254
+ .nav-link::after {
255
+ bottom: -4px;
256
+ }
257
+ }
258
+
259
+ .site-footer {
260
+ border-top: 1px solid var(--line);
261
+ background: color-mix(in oklab, var(--header-bg) 84%, transparent 16%);
262
+ }
263
+
264
+ .rise-in {
265
+ animation: rise-in 700ms cubic-bezier(0.16, 1, 0.3, 1) both;
266
+ }
267
+
268
+ @keyframes rise-in {
269
+ from {
270
+ opacity: 0;
271
+ transform: translateY(12px);
272
+ }
273
+ to {
274
+ opacity: 1;
275
+ transform: translateY(0);
276
+ }
15
277
  }
@@ -7,6 +7,8 @@
7
7
  "module": "ESNext",
8
8
  "baseUrl": ".",
9
9
  "paths": {
10
+ "#/*": ["./src/*"],
11
+ "content-collections": ["./.content-collections/generated"],
10
12
  "@/*": ["./src/*"]
11
13
  },
12
14
  "lib": ["ES2022", "DOM", "DOM.Iterable"],
@@ -1,5 +1,6 @@
1
1
  import { defineConfig } from 'vite'
2
2
  import { devtools } from '@tanstack/devtools-vite'
3
+ import contentCollections from '@content-collections/vite'
3
4
  import tsconfigPaths from 'vite-tsconfig-paths'
4
5
  <% if (addOnEnabled.paraglide) { -%>
5
6
  import { paraglideVitePlugin } from "@inlang/paraglide-js"
@@ -20,6 +21,7 @@ const config = defineConfig({
20
21
  outdir: './src/paraglide',
21
22
  strategy: ['url', "baseLocale"],
22
23
  }), <% } %><% for(const integration of integrations.filter(i => i.type === 'vite-plugin')) { %><%- integrationImportCode(integration) %>,<% } %>
24
+ contentCollections(),
23
25
  tsconfigPaths({ projects: ['./tsconfig.json'] }),
24
26
  tailwindcss(),
25
27
  <% if (routerOnly) { %>tanstackRouter({ target: 'react', autoCodeSplitting: true }),<% } else { %>tanstackStart(),<% } %>
@@ -1,13 +1,12 @@
1
- import { Derived, Store } from '@tanstack/store'
1
+ import { Store } from '@tanstack/store'
2
2
 
3
3
  export const store = new Store({
4
4
  firstName: 'Jane',
5
5
  lastName: 'Smith',
6
6
  })
7
7
 
8
- export const fullName = new Derived({
9
- fn: () => `${store.state.firstName} ${store.state.lastName}`,
10
- deps: [store],
11
- })
8
+ export const fullName = new Store(`${store.state.firstName} ${store.state.lastName}`)
12
9
 
13
- fullName.mount()
10
+ store.subscribe(() => {
11
+ fullName.setState(() => `${store.state.firstName} ${store.state.lastName}`)
12
+ })
@@ -43,7 +43,7 @@ function FullName() {
43
43
  const fName = useStore(fullName)
44
44
  return (
45
45
  <div class="bg-white/10 rounded-lg px-4 py-2 outline-none ">
46
- {fName}
46
+ {fName()}
47
47
  </div>
48
48
  )
49
49
  }
@@ -74,4 +74,4 @@ export default (parentRoute: RootRoute) => createRoute({
74
74
  getParentRoute: () => parentRoute,
75
75
  })
76
76
  <% } %>
77
-
77
+
@@ -1,13 +1,12 @@
1
- import { Derived, Store } from '@tanstack/store'
1
+ import { Store } from '@tanstack/store'
2
2
 
3
3
  export const store = new Store({
4
4
  firstName: 'Jane',
5
5
  lastName: 'Smith',
6
6
  })
7
7
 
8
- export const fullName = new Derived({
9
- fn: () => `${store.state.firstName} ${store.state.lastName}`,
10
- deps: [store],
11
- })
8
+ export const fullName = new Store(`${store.state.firstName} ${store.state.lastName}`)
12
9
 
13
- fullName.mount()
10
+ store.subscribe(() => {
11
+ fullName.setState(() => `${store.state.firstName} ${store.state.lastName}`)
12
+ })
@@ -5,17 +5,17 @@ import <%= integration.jsName %> from "<%= relativePath(integration.path) %>";
5
5
  const icons = new Set([
6
6
  "Menu",
7
7
  "X",
8
- "House",
9
8
  "Home",
10
9
  "Globe",
11
- "ChevronDown",
12
- "ChevronRight",
13
- "Layers",
14
10
  ])
15
11
 
16
12
  for(const addOn of addOns) {
17
13
  for(const route of (addOn?.routes||[])?.filter(r => r.url && r.name)) {
18
14
  icons.add( route.icon || "Globe");
15
+ if (route.children?.length) {
16
+ icons.add("ChevronDown")
17
+ icons.add("ChevronRight")
18
+ }
19
19
  }
20
20
  }
21
21
  %>
@@ -26,11 +26,13 @@ import {
26
26
 
27
27
  export default function Header() {
28
28
  <%
29
- const menusWithChildren = addOns.filter(a => a.routes?.some(r => r.children));
29
+ const hasNestedRouteGroups = addOns.some(a => a.routes?.some(r => r.children?.length));
30
30
  const userHeaders = integrations.filter(i => i.type === 'header-user');
31
31
  %>
32
32
  const [isOpen, setIsOpen] = createSignal(false);
33
+ <% if (hasNestedRouteGroups) { %>
33
34
  const [groupedExpanded, setGroupedExpanded] = createSignal<Record<string, boolean>>({});
35
+ <% } %>
34
36
 
35
37
  return (
36
38
  <>
@@ -45,7 +47,7 @@ const userHeaders = integrations.filter(i => i.type === 'header-user');
45
47
  <h1 class="ml-4 text-xl font-semibold">
46
48
  <Link to="/">
47
49
  <img
48
- src="/tanstack-word-logo-white.svg"
50
+ src="/logo192.png"
49
51
  alt="TanStack Logo"
50
52
  class="h-10"
51
53
  />
@@ -21,7 +21,7 @@ import { HeadContent, Outlet, Scripts, createRootRouteWithContext } from '@tanst
21
21
  import { TanStackRouterDevtools } from '@tanstack/solid-router-devtools'
22
22
 
23
23
  <% if (addOnEnabled['solid-ui']) { %>
24
- import "@fontsource/inter"
24
+ import "@fontsource/inter/400.css"
25
25
  <% } %>
26
26
 
27
27
  import { HydrationScript } from 'solid-js/web'
@@ -47,7 +47,7 @@ function App() {
47
47
  <div class="relative max-w-5xl mx-auto">
48
48
  <div class="flex items-center justify-center gap-6 mb-6">
49
49
  <img
50
- src="/tanstack-circle-logo.png"
50
+ src="/logo192.png"
51
51
  alt="TanStack Logo"
52
52
  class="w-24 h-24 md:w-32 md:h-32"
53
53
  />
@@ -104,6 +104,9 @@ export function registerFramework(framework) {
104
104
  frameworks.push(frameworkWithBundler);
105
105
  }
106
106
  export function getFrameworkById(id) {
107
+ if (id === 'react-cra') {
108
+ return frameworks.find((framework) => framework.id === 'react');
109
+ }
107
110
  return frameworks.find((framework) => framework.id === id);
108
111
  }
109
112
  export function getFrameworkByName(name) {
@@ -73,7 +73,7 @@ export function createPackageJSON(options) {
73
73
  packageJSON = mergePackageJSON(packageJSON, options.starter.packageAdditions);
74
74
  }
75
75
  if (options.routerOnly) {
76
- if (options.framework.id === 'react-cra') {
76
+ if (options.framework.id === 'react') {
77
77
  delete packageJSON.dependencies?.['@tanstack/react-start'];
78
78
  delete packageJSON.dependencies?.['@tanstack/react-router-ssr-query'];
79
79
  packageJSON.devDependencies = {
package/dist/registry.js CHANGED
@@ -3,6 +3,16 @@ import { loadRemoteAddOn } from './custom-add-ons/add-on.js';
3
3
  import { loadStarter } from './custom-add-ons/starter.js';
4
4
  import { handleSpecialURL } from './utils.js';
5
5
  const registrySchema = z.object({
6
+ templates: z
7
+ .array(z.object({
8
+ name: z.string(),
9
+ description: z.string(),
10
+ url: z.string(),
11
+ banner: z.string().optional(),
12
+ mode: z.string(),
13
+ framework: z.string(),
14
+ }))
15
+ .optional(),
6
16
  starters: z
7
17
  .array(z.object({
8
18
  name: z.string(),
@@ -36,15 +46,22 @@ export async function getRawRegistry(registryUrl) {
36
46
  const url = handleSpecialURL(regUrl);
37
47
  const registry = (await fetch(url).then((res) => res.json()));
38
48
  const parsedRegistry = registrySchema.parse(registry);
49
+ if (!parsedRegistry.starters && parsedRegistry.templates) {
50
+ parsedRegistry.starters = parsedRegistry.templates;
51
+ }
52
+ if (!parsedRegistry.templates && parsedRegistry.starters) {
53
+ parsedRegistry.templates = parsedRegistry.starters;
54
+ }
39
55
  for (const addOn of parsedRegistry['add-ons'] || []) {
40
56
  addOn.url = absolutizeUrl(url, addOn.url);
41
57
  }
42
- for (const starter of parsedRegistry.starters || []) {
43
- starter.url = absolutizeUrl(url, starter.url);
44
- if (starter.banner) {
45
- starter.banner = absolutizeUrl(url, starter.banner);
58
+ for (const template of parsedRegistry.templates || []) {
59
+ template.url = absolutizeUrl(url, template.url);
60
+ if (template.banner) {
61
+ template.banner = absolutizeUrl(url, template.banner);
46
62
  }
47
63
  }
64
+ parsedRegistry.starters = parsedRegistry.templates;
48
65
  return parsedRegistry;
49
66
  }
50
67
  }
@@ -1,6 +1,28 @@
1
1
  import { z } from 'zod';
2
2
  import type { AddOn, Starter } from './types';
3
3
  declare const registrySchema: z.ZodObject<{
4
+ templates: z.ZodOptional<z.ZodArray<z.ZodObject<{
5
+ name: z.ZodString;
6
+ description: z.ZodString;
7
+ url: z.ZodString;
8
+ banner: z.ZodOptional<z.ZodString>;
9
+ mode: z.ZodString;
10
+ framework: z.ZodString;
11
+ }, "strip", z.ZodTypeAny, {
12
+ description: string;
13
+ name: string;
14
+ url: string;
15
+ framework: string;
16
+ mode: string;
17
+ banner?: string | undefined;
18
+ }, {
19
+ description: string;
20
+ name: string;
21
+ url: string;
22
+ framework: string;
23
+ mode: string;
24
+ banner?: string | undefined;
25
+ }>, "many">>;
4
26
  starters: z.ZodOptional<z.ZodArray<z.ZodObject<{
5
27
  name: z.ZodString;
6
28
  description: z.ZodString;
@@ -50,6 +72,14 @@ declare const registrySchema: z.ZodObject<{
50
72
  framework: string;
51
73
  modes: string[];
52
74
  }[] | undefined;
75
+ templates?: {
76
+ description: string;
77
+ name: string;
78
+ url: string;
79
+ framework: string;
80
+ mode: string;
81
+ banner?: string | undefined;
82
+ }[] | undefined;
53
83
  starters?: {
54
84
  description: string;
55
85
  name: string;
@@ -66,6 +96,14 @@ declare const registrySchema: z.ZodObject<{
66
96
  framework: string;
67
97
  modes: string[];
68
98
  }[] | undefined;
99
+ templates?: {
100
+ description: string;
101
+ name: string;
102
+ url: string;
103
+ framework: string;
104
+ mode: string;
105
+ banner?: string | undefined;
106
+ }[] | undefined;
69
107
  starters?: {
70
108
  description: string;
71
109
  name: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/create",
3
- "version": "0.61.5",
3
+ "version": "0.62.0",
4
4
  "description": "TanStack Application Builder Engine",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -50,8 +50,8 @@ export async function readConfigFileFromEnvironment(
50
50
 
51
51
  // Look for markers out outdated config files and upgrade the format on the fly (it will be written in the updated version after we add add-ons)
52
52
  if (originalJSON.existingAddOns) {
53
- if (originalJSON.framework === 'react') {
54
- originalJSON.framework = 'react-cra'
53
+ if (originalJSON.framework === 'react-cra') {
54
+ originalJSON.framework = 'react'
55
55
  }
56
56
  originalJSON.chosenAddOns = originalJSON.existingAddOns
57
57
  delete originalJSON.existingAddOns
@@ -63,6 +63,10 @@ export async function readConfigFileFromEnvironment(
63
63
  delete originalJSON.variableValues
64
64
  }
65
65
 
66
+ if (originalJSON.framework === 'react-cra') {
67
+ originalJSON.framework = 'react'
68
+ }
69
+
66
70
  return originalJSON
67
71
  } catch {
68
72
  return null
@@ -21,22 +21,26 @@ import type {
21
21
  StarterInfo,
22
22
  } from '../types'
23
23
 
24
- const INFO_FILE = 'starter-info.json'
25
- const COMPILED_FILE = 'starter.json'
24
+ const INFO_FILE = 'template-info.json'
25
+ const LEGACY_INFO_FILE = 'starter-info.json'
26
+ const COMPILED_FILE = 'template.json'
27
+ const LEGACY_COMPILED_FILE = 'starter.json'
26
28
 
27
29
  export async function readOrGenerateStarterInfo(
28
30
  options: PersistedOptions,
29
31
  ): Promise<StarterInfo> {
30
32
  const info = existsSync(INFO_FILE)
31
33
  ? JSON.parse((await readFile(INFO_FILE)).toString())
34
+ : existsSync(LEGACY_INFO_FILE)
35
+ ? JSON.parse((await readFile(LEGACY_INFO_FILE)).toString())
32
36
  : {
33
- id: `${options.projectName}-starter`,
34
- name: `${options.projectName}-starter`,
37
+ id: `${options.projectName}-template`,
38
+ name: `${options.projectName} Template`,
35
39
  version: '0.0.1',
36
- description: 'Project starter',
40
+ description: 'Project template',
37
41
  author: 'Jane Smith <jane.smith@example.com>',
38
42
  license: 'MIT',
39
- link: `https://github.com/jane-smith/${options.projectName}-starter`,
43
+ link: `https://github.com/jane-smith/${options.projectName}-template`,
40
44
  shadcnComponents: [],
41
45
  framework: options.framework,
42
46
  mode: options.mode!,
@@ -75,12 +79,19 @@ async function loadCurrentStarterInfo(environment: Environment) {
75
79
  export async function updateStarterInfo(environment: Environment) {
76
80
  const { info, output } = await loadCurrentStarterInfo(environment)
77
81
 
82
+ const generatedPackageJson =
83
+ output.files['./package.json'] ?? output.files['package.json']
84
+ if (!generatedPackageJson) {
85
+ throw new Error('Unable to find generated package.json in template output')
86
+ }
87
+
78
88
  info.packageAdditions = createPackageAdditions(
79
- JSON.parse(output.files['./package.json']),
89
+ JSON.parse(generatedPackageJson),
80
90
  JSON.parse((await readFile('package.json')).toString()),
81
91
  )
82
92
 
83
93
  writeFileSync(INFO_FILE, JSON.stringify(info, null, 2))
94
+ writeFileSync(LEGACY_INFO_FILE, JSON.stringify(info, null, 2))
84
95
  }
85
96
 
86
97
  export async function compileStarter(environment: Environment) {
@@ -104,6 +115,7 @@ export async function compileStarter(environment: Environment) {
104
115
  }
105
116
 
106
117
  writeFileSync(COMPILED_FILE, JSON.stringify(compiledInfo, null, 2))
118
+ writeFileSync(LEGACY_COMPILED_FILE, JSON.stringify(compiledInfo, null, 2))
107
119
  }
108
120
 
109
121
  export async function initStarter(environment: Environment) {
@@ -112,8 +124,16 @@ export async function initStarter(environment: Environment) {
112
124
  }
113
125
 
114
126
  export async function loadStarter(url: string): Promise<Starter> {
115
- const response = await fetch(url)
116
- const jsonContent = await response.json()
127
+ const absoluteLocalPath = resolve(process.cwd(), url)
128
+ const localPath = existsSync(url)
129
+ ? url
130
+ : existsSync(absoluteLocalPath)
131
+ ? absoluteLocalPath
132
+ : undefined
133
+
134
+ const jsonContent = localPath
135
+ ? JSON.parse((await readFile(localPath)).toString())
136
+ : await (await fetch(url)).json()
117
137
 
118
138
  const checked = StarterCompiledSchema.safeParse(jsonContent)
119
139
  if (!checked.success) {
@@ -121,7 +141,7 @@ export async function loadStarter(url: string): Promise<Starter> {
121
141
  }
122
142
 
123
143
  const starter = checked.data
124
- starter.id = url
144
+ starter.id = localPath ?? url
125
145
  return {
126
146
  ...starter,
127
147
  getFiles: () => Promise.resolve(Object.keys(starter.files)),
@@ -209,6 +209,7 @@ export async function recursivelyGatherFilesFromEnvironment(
209
209
 
210
210
  export const IGNORE_FILES = [
211
211
  '.starter',
212
+ '.template',
212
213
  '.add-on',
213
214
  '.cta.json',
214
215
  '.git',