create-fluixi 0.1.0-alpha.10 → 0.1.0-alpha.11

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 (2) hide show
  1. package/dist/index.js +42 -16
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -145,20 +145,31 @@ function addDeps(pkg, section, deps) {
145
145
  pkg[section] = Object.fromEntries(Object.entries({ ...(pkg[section] ?? {}), ...deps }).sort(([a], [b]) => a.localeCompare(b)));
146
146
  }
147
147
  /**
148
- * The stylesheet the app imports, assembled from what was chosen.
148
+ * The app's own stylesheet, in the shape the chosen css engine expects.
149
149
  *
150
- * Tokens first: the kit's components read those custom properties, so a framework layer
151
- * loaded before them would be overridden by nothing and a component would render unstyled.
150
+ * The component tokens are not here: they are a stylesheet the package ships and the
151
+ * entry imports directly, so this file only holds what the engine has to read, the dark
152
+ * variant, where to scan, and the theme the app defines.
152
153
  */
153
154
  function styleSheet(ui, css) {
154
- const lines = [];
155
- if (ui === 'fluixi-ui')
156
- lines.push(`@import '@fluixi-ui/tokens/css';`);
157
- if (css === 'tailwind')
158
- lines.push(`@import 'tailwindcss';`);
159
- if (css === 'fluixi-css')
160
- lines.push(`@import '@fluixi-css/core';`);
161
- return lines.join('\n') + '\n';
155
+ // Dark from the attribute @fluixi/core's createTheme sets, not the OS preference, so
156
+ // a theme toggle in the app actually drives it.
157
+ const darkVariant = `@custom-variant dark (&:where([data-theme='dark'], [data-theme='dark'] *));`;
158
+ // Where to look for utility classes. Relative to this file.
159
+ const sources = `@source '.';\n@source '../index.html';`;
160
+ const theme = `@theme {\n /* Design tokens. A --color-* scale here drives the whole app. */\n}`;
161
+ if (css === 'fluixi-css') {
162
+ // No import: the vite plugin injects the engine, and `emitUiTokens` bridges the
163
+ // scales below onto the `--flx-ui-*` properties the components read, so importing
164
+ // the token sheet as well would only restate what the bridge already emits.
165
+ return [darkVariant, '', sources, '', theme, ''].join('\n');
166
+ }
167
+ if (css === 'tailwind') {
168
+ return [`@import 'tailwindcss';`, '', darkVariant, '', theme, ''].join('\n');
169
+ }
170
+ // No css engine: the component tokens are imported from the entry like any other
171
+ // stylesheet, so there is nothing for this file to hold.
172
+ return '';
162
173
  }
163
174
  /** Where the component resolver is configured, which differs by mode. */
164
175
  const configFor = (mode) => mode === 'ssr' ? 'fluixi.config.ts' : 'vite.config.ts';
@@ -199,15 +210,27 @@ function addVitePlugin(target, mode, importLine, call) {
199
210
  : src.replace('plugins: [', `plugins: [\n ${call},`);
200
211
  writeFileSync(file, src);
201
212
  }
202
- /** Import the stylesheet from whichever file boots the client. */
203
- function importStyles(target, mode, format) {
213
+ /**
214
+ * Import the stylesheets from whichever file boots the client.
215
+ *
216
+ * The component tokens come first and from the entry rather than from `styles.css`:
217
+ * they are a stylesheet the package ships, not something the app's css engine should be
218
+ * asked to resolve, and the components below need them defined before their own rules
219
+ * land. `emitUiTokens` does not replace this, that bridge covers a subset.
220
+ */
221
+ function importStyles(target, mode, ui) {
204
222
  const base = mode === 'ssr' ? 'entry-client' : 'main';
205
223
  const file = ['tsx', 'ts']
206
224
  .map((ext) => join(target, 'src', `${base}.${ext}`))
207
225
  .find((p) => existsSync(p));
208
226
  if (!file)
209
227
  return;
210
- writeFileSync(file, `import './styles.css';\n` + readFileSync(file, 'utf8'));
228
+ const head = [
229
+ ...(ui === 'fluixi-ui' ? [`import '@fluixi-ui/tokens/tokens.css';`] : []),
230
+ `import './styles.css';`,
231
+ '',
232
+ ].join('\n');
233
+ writeFileSync(file, head + readFileSync(file, 'utf8'));
211
234
  }
212
235
  async function main() {
213
236
  const args = argv.slice(2);
@@ -289,8 +312,11 @@ async function main() {
289
312
  writeFileSync(join(target, 'fluixi.css.config.js'), `const config = {\n purge: true,\n content: ['./index.html', './src/**/*.{js,ts,jsx,tsx}'],\n mode: { dark: '[data-theme="dark"]' },\n theme: { extend: {} },\n};\n\nexport default config;\n`);
290
313
  }
291
314
  if (ui === 'fluixi-ui' || css !== 'none') {
292
- writeFileSync(join(target, 'src', 'styles.css'), styleSheet(ui, css));
293
- importStyles(target, mode, format);
315
+ const sheet = styleSheet(ui, css);
316
+ // An empty sheet still gets written: it is where an app puts its own css, and the
317
+ // entry already imports it.
318
+ writeFileSync(join(target, 'src', 'styles.css'), sheet);
319
+ importStyles(target, mode, ui);
294
320
  }
295
321
  writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n');
296
322
  // Outro + next steps. The leading gutter only makes sense after the intro/prompts.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-fluixi",
3
- "version": "0.1.0-alpha.10",
3
+ "version": "0.1.0-alpha.11",
4
4
  "license": "MIT",
5
5
  "author": "Ibrahima Touré",
6
6
  "description": "Scaffold a new Fluixi app — `npm create fluixi <dir>`.",