@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
  />
package/src/frameworks.ts CHANGED
@@ -155,6 +155,10 @@ export function registerFramework(framework: FrameworkDefinition) {
155
155
  }
156
156
 
157
157
  export function getFrameworkById(id: string) {
158
+ if (id === 'react-cra') {
159
+ return frameworks.find((framework) => framework.id === 'react')
160
+ }
161
+
158
162
  return frameworks.find((framework) => framework.id === id)
159
163
  }
160
164
 
@@ -99,7 +99,7 @@ export function createPackageJSON(options: Options) {
99
99
  }
100
100
 
101
101
  if (options.routerOnly) {
102
- if (options.framework.id === 'react-cra') {
102
+ if (options.framework.id === 'react') {
103
103
  delete packageJSON.dependencies?.['@tanstack/react-start']
104
104
  delete packageJSON.dependencies?.['@tanstack/react-router-ssr-query']
105
105
  packageJSON.devDependencies = {
package/src/registry.ts CHANGED
@@ -6,6 +6,18 @@ import { handleSpecialURL } from './utils.js'
6
6
  import type { AddOn, Starter } from './types'
7
7
 
8
8
  const registrySchema = z.object({
9
+ templates: z
10
+ .array(
11
+ z.object({
12
+ name: z.string(),
13
+ description: z.string(),
14
+ url: z.string(),
15
+ banner: z.string().optional(),
16
+ mode: z.string(),
17
+ framework: z.string(),
18
+ }),
19
+ )
20
+ .optional(),
9
21
  starters: z
10
22
  .array(
11
23
  z.object({
@@ -49,15 +61,27 @@ export async function getRawRegistry(
49
61
  const url = handleSpecialURL(regUrl)
50
62
  const registry = (await fetch(url).then((res) => res.json())) as Registry
51
63
  const parsedRegistry = registrySchema.parse(registry)
64
+
65
+ if (!parsedRegistry.starters && parsedRegistry.templates) {
66
+ parsedRegistry.starters = parsedRegistry.templates
67
+ }
68
+
69
+ if (!parsedRegistry.templates && parsedRegistry.starters) {
70
+ parsedRegistry.templates = parsedRegistry.starters
71
+ }
72
+
52
73
  for (const addOn of parsedRegistry['add-ons'] || []) {
53
74
  addOn.url = absolutizeUrl(url, addOn.url)
54
75
  }
55
- for (const starter of parsedRegistry.starters || []) {
56
- starter.url = absolutizeUrl(url, starter.url)
57
- if (starter.banner) {
58
- starter.banner = absolutizeUrl(url, starter.banner)
76
+ for (const template of parsedRegistry.templates || []) {
77
+ template.url = absolutizeUrl(url, template.url)
78
+ if (template.banner) {
79
+ template.banner = absolutizeUrl(url, template.banner)
59
80
  }
60
81
  }
82
+
83
+ parsedRegistry.starters = parsedRegistry.templates
84
+
61
85
  return parsedRegistry
62
86
  }
63
87
  }
@@ -8,7 +8,7 @@ describe('getAllAddOns', () => {
8
8
  it('filter add-ons', () => {
9
9
  const addOns = getAllAddOns(
10
10
  {
11
- id: 'react-cra',
11
+ id: 'react',
12
12
  getAddOns: () => [
13
13
  {
14
14
  id: 'add-on-1',
@@ -32,7 +32,7 @@ describe('getAllAddOns', () => {
32
32
  it('should sort add-ons by priority (higher priority first)', () => {
33
33
  const addOns = getAllAddOns(
34
34
  {
35
- id: 'react-cra',
35
+ id: 'react',
36
36
  getAddOns: () => [
37
37
  {
38
38
  id: 'low-priority',
@@ -72,7 +72,7 @@ describe('getAllAddOns', () => {
72
72
  it('should filter by mode and then sort by priority', () => {
73
73
  const addOns = getAllAddOns(
74
74
  {
75
- id: 'react-cra',
75
+ id: 'react',
76
76
  getAddOns: () => [
77
77
  {
78
78
  id: 'file-router-low',
@@ -107,7 +107,7 @@ describe('finalizeAddOns', () => {
107
107
  it('should finalize add-ons', async () => {
108
108
  const addOns = await finalizeAddOns(
109
109
  {
110
- id: 'react-cra',
110
+ id: 'react',
111
111
  getAddOns: () => [
112
112
  {
113
113
  id: 'add-on-1',
@@ -22,7 +22,7 @@ describe('writeConfigFile', () => {
22
22
  const targetDir = 'test-dir'
23
23
  const options = {
24
24
  framework: {
25
- id: 'react-cra',
25
+ id: 'react',
26
26
  getAddOns: () => [],
27
27
  } as unknown as Framework,
28
28
  chosenAddOns: [
@@ -54,7 +54,7 @@ describe('readConfigFileFromEnvironment', () => {
54
54
  const targetDir = 'test-dir'
55
55
  const persistedOptions = {
56
56
  version: 1,
57
- framework: 'react-cra',
57
+ framework: 'react',
58
58
  chosenAddOns: ['add-on-1'],
59
59
  }
60
60
  const { environment } = createMemoryEnvironment()
@@ -91,7 +91,7 @@ describe('readConfigFileFromEnvironment', () => {
91
91
  environment.finishRun()
92
92
 
93
93
  expect(config).toEqual({
94
- framework: 'react-cra',
94
+ framework: 'react',
95
95
  projectName: 'foo',
96
96
  typescript: false,
97
97
  tailwind: false,
@@ -1,7 +1,10 @@
1
1
  import { beforeEach, describe, expect, it, vi } from 'vitest'
2
2
  import { fs, vol } from 'memfs'
3
3
 
4
- import { readOrGenerateStarterInfo } from '../../src/custom-add-ons/starter.js'
4
+ import {
5
+ loadStarter,
6
+ readOrGenerateStarterInfo,
7
+ } from '../../src/custom-add-ons/starter.js'
5
8
 
6
9
  vi.mock('node:fs', () => fs)
7
10
  vi.mock('node:fs/promises', () => fs.promises)
@@ -23,7 +26,7 @@ describe('readOrGenerateStarterInfo', () => {
23
26
  git: true,
24
27
  chosenAddOns: [],
25
28
  })
26
- expect(starterInfo.id).toEqual('test-starter')
29
+ expect(starterInfo.id).toEqual('test-template')
27
30
  })
28
31
 
29
32
  it('should read the starter info', async () => {
@@ -84,4 +87,33 @@ describe('readOrGenerateStarterInfo', () => {
84
87
  })
85
88
  expect(starterInfo.version).toEqual('0.0.1')
86
89
  })
90
+
91
+ it('should load a local template/starter file path', async () => {
92
+ fs.mkdirSync(process.cwd(), { recursive: true })
93
+ fs.writeFileSync(
94
+ './template.json',
95
+ JSON.stringify({
96
+ id: 'template-id',
97
+ name: 'Template Name',
98
+ version: '0.0.1',
99
+ description: 'template description',
100
+ author: 'Test Author',
101
+ license: 'MIT',
102
+ link: 'https://example.com/template',
103
+ type: 'starter',
104
+ framework: 'react',
105
+ mode: 'file-router',
106
+ typescript: true,
107
+ files: {
108
+ './package.json': '{}',
109
+ },
110
+ deletedFiles: [],
111
+ }),
112
+ )
113
+
114
+ const starter = await loadStarter('./template.json')
115
+
116
+ expect(starter.id).toEqual('./template.json')
117
+ await expect(starter.getFiles()).resolves.toEqual(['./package.json'])
118
+ })
87
119
  })
@@ -2,6 +2,7 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'
2
2
  import { fs, vol } from 'memfs'
3
3
 
4
4
  import {
5
+ __testClearFrameworks,
5
6
  getFrameworks,
6
7
  getFrameworkById,
7
8
  getFrameworkByName,
@@ -13,6 +14,7 @@ vi.mock('node:fs/promises', () => fs.promises)
13
14
 
14
15
  beforeEach(() => {
15
16
  vol.reset()
17
+ __testClearFrameworks()
16
18
  })
17
19
 
18
20
  describe('registerFramework', () => {
@@ -60,4 +62,26 @@ describe('registerFramework', () => {
60
62
  expect(getFrameworkByName('test')).not.toBeUndefined()
61
63
  expect(getFrameworks().length).toEqual(1)
62
64
  })
65
+
66
+ it('should resolve legacy react-cra framework id', () => {
67
+ registerFramework({
68
+ id: 'react',
69
+ name: 'React',
70
+ addOns: [],
71
+ description: 'React',
72
+ version: '1.0.0',
73
+ base: {},
74
+ basePackageJSON: {},
75
+ optionalPackages: {},
76
+ supportedModes: {
77
+ 'file-router': {
78
+ displayName: 'File Router',
79
+ description: 'File Router',
80
+ forceTypescript: true,
81
+ },
82
+ },
83
+ })
84
+
85
+ expect(getFrameworkById('react-cra')?.id).toBe('react')
86
+ })
63
87
  })