rizzo-css 0.0.27 → 0.0.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -4
- package/bin/rizzo-css.js +195 -38
- package/package.json +1 -1
- package/scaffold/astro-minimal/gitignore +24 -0
- package/scaffold/svelte-minimal/gitignore +10 -0
- package/scaffold/vanilla/README-RIZZO.md +1 -1
- package/scaffold/vanilla/components/accordion.html +12 -0
- package/scaffold/vanilla/components/alert.html +12 -0
- package/scaffold/vanilla/components/avatar.html +12 -0
- package/scaffold/vanilla/components/badge.html +12 -0
- package/scaffold/vanilla/components/breadcrumb.html +12 -0
- package/scaffold/vanilla/components/button.html +12 -0
- package/scaffold/vanilla/components/cards.html +12 -0
- package/scaffold/vanilla/components/copy-to-clipboard.html +12 -0
- package/scaffold/vanilla/components/divider.html +12 -0
- package/scaffold/vanilla/components/dropdown.html +12 -0
- package/scaffold/vanilla/components/forms.html +12 -0
- package/scaffold/vanilla/components/icons.html +12 -0
- package/scaffold/vanilla/components/index.html +12 -0
- package/scaffold/vanilla/components/modal.html +12 -0
- package/scaffold/vanilla/components/navbar.html +12 -0
- package/scaffold/vanilla/components/pagination.html +12 -0
- package/scaffold/vanilla/components/progress-bar.html +12 -0
- package/scaffold/vanilla/components/search.html +12 -0
- package/scaffold/vanilla/components/settings.html +12 -0
- package/scaffold/vanilla/components/spinner.html +12 -0
- package/scaffold/vanilla/components/table.html +12 -0
- package/scaffold/vanilla/components/tabs.html +12 -0
- package/scaffold/vanilla/components/theme-switcher.html +12 -0
- package/scaffold/vanilla/components/toast.html +12 -0
- package/scaffold/vanilla/components/tooltip.html +12 -0
- package/scaffold/vanilla/gitignore +27 -0
- package/scaffold/vanilla/index.html +12 -0
- package/scaffold/vanilla/js/main.js +33 -0
package/README.md
CHANGED
|
@@ -12,14 +12,19 @@ pnpm add rizzo-css
|
|
|
12
12
|
yarn add rizzo-css
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
-
**Quick start (no install):** `npx rizzo-css init` — choose **framework** (Vanilla, Astro, or Svelte), then **add to existing** or **create new**. **Existing** (or `npx rizzo-css add`) → drop in CSS + hand-pick components; you must add the `<link>` yourself (CLI prints the exact tag). **New** → choose **Full**
|
|
15
|
+
**Quick start (no install):** `npx rizzo-css init` — choose **framework** (Vanilla, Astro, or Svelte), then **add to existing** or **create new**. **Existing** (or `npx rizzo-css add`) → drop in CSS + hand-pick components; you must add the `<link>` yourself (CLI prints the exact tag). **New** → choose **Full** | **Minimal** (recommended) | **Manual** (pick components; list shows which add others, e.g. Navbar adds Search and Settings, Settings adds ThemeSwitcher), then package manager. Full and Minimal include all required dependencies so every component works. Run `npx rizzo-css help components` for the dependency list. Non-interactive: `npx rizzo-css init --yes --framework vanilla|astro|svelte`. Optional **rizzo-css.json** and `add --install-package`. All get the **same CSS and component styles**. To use the **official Svelte or Astro create command** plus Rizzo, create the app first, then run `npx rizzo-css add`:
|
|
16
16
|
|
|
17
17
|
```bash
|
|
18
18
|
npm create svelte@latest my-app && cd my-app && npx rizzo-css add
|
|
19
19
|
npm create astro@latest my-app && cd my-app && npx rizzo-css add
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
-
`add`
|
|
22
|
+
`add` writes **RIZZO-SNIPPET.txt** (link + theme) by default; use `--no-snippet` to skip. `npx rizzo-css doctor` checks config and CSS path. `npx rizzo-css theme` lists themes.
|
|
23
|
+
|
|
24
|
+
| | **Create new** (`init` → new) | **Add to existing** (`add` or `init` → existing) |
|
|
25
|
+
|---|------------------------------|--------------------------------------------------|
|
|
26
|
+
| Writes | Scaffold, CSS, config, LICENSE-RIZZO, README-RIZZO, .gitignore | CSS, components, config, optional RIZZO-SNIPPET.txt |
|
|
27
|
+
| Link | Already in scaffold | You add it (CLI prints the tag) |
|
|
23
28
|
|
|
24
29
|
## One package, any framework
|
|
25
30
|
|
|
@@ -41,7 +46,7 @@ You install **the same package** for every framework: `npm install rizzo-css`. N
|
|
|
41
46
|
|
|
42
47
|
With `npx rizzo-css add --path <dir>`, the CLI still suggests the correct href for your framework (e.g. Astro/Svelte get a leading `/` path).
|
|
43
48
|
|
|
44
|
-
Scaffolds in the package: `scaffold/vanilla/` (Full or Manual), `scaffold/astro-minimal/`, `scaffold/svelte-minimal/`, plus `scaffold/astro/` and `scaffold/svelte/` (component templates for hand-pick). Use `npx rizzo-css init` and choose **Create new project** to get a **Full** or **Manual** scaffold; the stylesheet link is in the layout. **Add to existing** (or `add` command) drops in CSS + hand-pick components; **you must add the stylesheet `<link>` yourself** — the CLI prints the exact tag. Every scaffold includes LICENSE-RIZZO
|
|
49
|
+
Scaffolds in the package: `scaffold/vanilla/` (Full or Manual), `scaffold/astro-minimal/`, `scaffold/svelte-minimal/`, plus `scaffold/astro/` and `scaffold/svelte/` (component templates for hand-pick). Use `npx rizzo-css init` and choose **Create new project** to get a **Full** or **Manual** scaffold; the stylesheet link is in the layout. **Add to existing** (or `add` command) drops in CSS + hand-pick components; **you must add the stylesheet `<link>` yourself** — the CLI prints the exact tag. Every scaffold includes LICENSE-RIZZO, README-RIZZO.md, and .gitignore (does not overwrite your project files); Astro/Svelte minimal include package.json and .env.example.
|
|
45
50
|
|
|
46
51
|
## Use
|
|
47
52
|
|
|
@@ -56,7 +61,7 @@ import 'rizzo-css';
|
|
|
56
61
|
**Without a bundler (plain HTML):** Use a CDN. Both unpkg and jsDelivr resolve the package root to the built CSS (via the `unpkg` / `jsdelivr` fields in this package). For reliability or to pin a version, use the explicit path:
|
|
57
62
|
|
|
58
63
|
```html
|
|
59
|
-
<!-- unpkg (pin version: replace @latest with @0.0.
|
|
64
|
+
<!-- unpkg (pin version: replace @latest with @0.0.29 or any version) -->
|
|
60
65
|
<link rel="stylesheet" href="https://unpkg.com/rizzo-css@latest/dist/rizzo.min.css" />
|
|
61
66
|
|
|
62
67
|
<!-- or jsDelivr -->
|
package/bin/rizzo-css.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
const { copyFileSync, mkdirSync, writeFileSync, existsSync, readFileSync, readdirSync, statSync } = require('fs');
|
|
3
|
+
const { copyFileSync, mkdirSync, writeFileSync, existsSync, readFileSync, readdirSync, statSync, unlinkSync } = require('fs');
|
|
4
4
|
const { join, dirname } = require('path');
|
|
5
5
|
const { spawnSync } = require('child_process');
|
|
6
6
|
const readline = require('readline');
|
|
@@ -10,8 +10,10 @@ const RIZZO_CONFIG_FILE = 'rizzo-css.json';
|
|
|
10
10
|
const SCAFFOLD_README_FILENAME = 'README-RIZZO.md';
|
|
11
11
|
/** Scaffold license filename; avoids overwriting an existing project LICENSE. */
|
|
12
12
|
const SCAFFOLD_LICENSE_FILENAME = 'LICENSE-RIZZO';
|
|
13
|
+
/** Snippet file written by add command for copy-paste of link and theme. */
|
|
14
|
+
const RIZZO_SNIPPET_FILE = 'RIZZO-SNIPPET.txt';
|
|
13
15
|
|
|
14
|
-
const COMMANDS = ['init', 'add', 'theme', 'help'];
|
|
16
|
+
const COMMANDS = ['init', 'add', 'theme', 'doctor', 'help'];
|
|
15
17
|
const FRAMEWORKS = ['vanilla', 'astro', 'svelte'];
|
|
16
18
|
/** Supported package managers: detection, install/add commands, and --package-manager override. */
|
|
17
19
|
const VALID_PACKAGE_MANAGERS = ['npm', 'pnpm', 'yarn', 'bun'];
|
|
@@ -112,11 +114,14 @@ const RECOMMENDED_COMPONENTS = [
|
|
|
112
114
|
'Button', 'Badge', 'Card', 'Modal', 'Tabs', 'ThemeSwitcher', 'FormGroup', 'Alert', 'Toast', 'Dropdown',
|
|
113
115
|
];
|
|
114
116
|
|
|
117
|
+
// Vanilla components that need js/main.js for interactivity (modal, dropdown, tabs, toast, theme switcher).
|
|
118
|
+
const VANILLA_JS_COMPONENTS = ['Modal', 'Dropdown', 'Tabs', 'Toast', 'ThemeSwitcher'];
|
|
119
|
+
|
|
115
120
|
// Component dependencies per framework: when user selects a component, these are copied automatically so it works.
|
|
116
121
|
// Manual users can run: npx rizzo-css help components
|
|
117
122
|
const COMPONENT_DEPS = {
|
|
118
|
-
astro: { Settings: ['ThemeSwitcher'], Toast: ['Alert'] },
|
|
119
|
-
svelte: { Settings: ['ThemeSwitcher'], Toast: ['Alert'] },
|
|
123
|
+
astro: { Settings: ['ThemeSwitcher'], Toast: ['Alert'], Navbar: ['Search', 'Settings'] },
|
|
124
|
+
svelte: { Settings: ['ThemeSwitcher'], Toast: ['Alert'], Navbar: ['Search', 'Settings'] },
|
|
120
125
|
};
|
|
121
126
|
|
|
122
127
|
function getComponentDeps(framework, componentName) {
|
|
@@ -271,31 +276,38 @@ function copyPackageLicense(projectDir) {
|
|
|
271
276
|
}
|
|
272
277
|
}
|
|
273
278
|
|
|
274
|
-
/**
|
|
279
|
+
/** Name of the scaffold gitignore file (no leading dot so npm pack includes it). Copied to project as .gitignore. */
|
|
280
|
+
const SCAFFOLD_GITIGNORE_FILE = 'gitignore';
|
|
281
|
+
|
|
282
|
+
/** Copy scaffold vanilla gitignore into project as .gitignore so new vanilla projects have sensible defaults. */
|
|
275
283
|
function copyVanillaGitignore(projectDir) {
|
|
276
|
-
const gitignorePath = join(getPackageRoot(), 'scaffold', 'vanilla',
|
|
284
|
+
const gitignorePath = join(getPackageRoot(), 'scaffold', 'vanilla', SCAFFOLD_GITIGNORE_FILE);
|
|
277
285
|
if (existsSync(gitignorePath)) {
|
|
278
286
|
copyFileSync(gitignorePath, join(projectDir, '.gitignore'));
|
|
279
287
|
}
|
|
280
288
|
}
|
|
281
289
|
|
|
282
|
-
/** Copy Astro minimal scaffold
|
|
290
|
+
/** Copy Astro minimal scaffold gitignore into project as .gitignore (full and minimal templates). */
|
|
283
291
|
function copyAstroGitignore(projectDir) {
|
|
284
|
-
const gitignorePath = join(getScaffoldAstroMinimalDir(),
|
|
292
|
+
const gitignorePath = join(getScaffoldAstroMinimalDir(), SCAFFOLD_GITIGNORE_FILE);
|
|
285
293
|
if (existsSync(gitignorePath)) {
|
|
286
294
|
copyFileSync(gitignorePath, join(projectDir, '.gitignore'));
|
|
295
|
+
const copiedAsFile = join(projectDir, SCAFFOLD_GITIGNORE_FILE);
|
|
296
|
+
if (existsSync(copiedAsFile)) unlinkSync(copiedAsFile);
|
|
287
297
|
}
|
|
288
298
|
}
|
|
289
299
|
|
|
290
|
-
/** Copy Svelte minimal scaffold
|
|
300
|
+
/** Copy Svelte minimal scaffold gitignore into project as .gitignore (full and minimal templates). */
|
|
291
301
|
function copySvelteGitignore(projectDir) {
|
|
292
|
-
const gitignorePath = join(getScaffoldSvelteMinimalDir(),
|
|
302
|
+
const gitignorePath = join(getScaffoldSvelteMinimalDir(), SCAFFOLD_GITIGNORE_FILE);
|
|
293
303
|
if (existsSync(gitignorePath)) {
|
|
294
304
|
copyFileSync(gitignorePath, join(projectDir, '.gitignore'));
|
|
305
|
+
const copiedAsFile = join(projectDir, SCAFFOLD_GITIGNORE_FILE);
|
|
306
|
+
if (existsSync(copiedAsFile)) unlinkSync(copiedAsFile);
|
|
295
307
|
}
|
|
296
308
|
}
|
|
297
309
|
|
|
298
|
-
/** Read rizzo-css.json from cwd. Returns { targetDir?, framework?, packageManager? } or null. */
|
|
310
|
+
/** Read rizzo-css.json from cwd. Returns { targetDir?, framework?, packageManager?, theme? } or null. Preserves unknown keys. */
|
|
299
311
|
function readRizzoConfig(cwd) {
|
|
300
312
|
if (!cwd || !existsSync(cwd)) return null;
|
|
301
313
|
const configPath = join(cwd, RIZZO_CONFIG_FILE);
|
|
@@ -306,6 +318,7 @@ function readRizzoConfig(cwd) {
|
|
|
306
318
|
if (typeof raw.targetDir === 'string') out.targetDir = raw.targetDir;
|
|
307
319
|
if (typeof raw.framework === 'string' && FRAMEWORKS.includes(raw.framework)) out.framework = raw.framework;
|
|
308
320
|
if (typeof raw.packageManager === 'string' && ['npm', 'pnpm', 'yarn', 'bun'].includes(raw.packageManager)) out.packageManager = raw.packageManager;
|
|
321
|
+
if (typeof raw.theme === 'string') out.theme = raw.theme;
|
|
309
322
|
return Object.keys(out).length ? out : null;
|
|
310
323
|
} catch (_) { return null; }
|
|
311
324
|
}
|
|
@@ -324,6 +337,7 @@ function writeRizzoConfig(cwd, config) {
|
|
|
324
337
|
if (config.targetDir != null) obj.targetDir = config.targetDir;
|
|
325
338
|
if (config.framework != null) obj.framework = config.framework;
|
|
326
339
|
if (config.packageManager != null) obj.packageManager = config.packageManager;
|
|
340
|
+
if (config.theme != null) obj.theme = config.theme;
|
|
327
341
|
writeFileSync(configPath, JSON.stringify(obj, null, 2) + '\n', 'utf8');
|
|
328
342
|
}
|
|
329
343
|
|
|
@@ -449,6 +463,24 @@ async function confirmRunInstall(pm) {
|
|
|
449
463
|
return answer === '' || /^y(es)?$/i.test(answer);
|
|
450
464
|
}
|
|
451
465
|
|
|
466
|
+
/** Ask user to copy js/main.js for vanilla interactive components. */
|
|
467
|
+
async function confirmCopyVanillaJs() {
|
|
468
|
+
const answer = await question('\nCopy js/main.js for modal, dropdown, tabs, toast, theme switcher? (Y/n) ');
|
|
469
|
+
return answer === '' || /^y(es)?$/i.test(answer);
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
/** True if directory looks like an existing project (has package.json, src/, or index.html). */
|
|
473
|
+
function isDirNonEmpty(dir) {
|
|
474
|
+
if (!dir || !existsSync(dir)) return false;
|
|
475
|
+
return existsSync(join(dir, 'package.json')) || existsSync(join(dir, 'src')) || existsSync(join(dir, 'index.html'));
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
/** Ask user to confirm creating in a non-empty directory. */
|
|
479
|
+
async function confirmNonEmptyDir(projectDir) {
|
|
480
|
+
const answer = await question('\nCurrent directory is not empty. Continue? (y/N) ');
|
|
481
|
+
return /^y(es)?$/i.test(answer);
|
|
482
|
+
}
|
|
483
|
+
|
|
452
484
|
/** Format label with optional ANSI color (item.color). */
|
|
453
485
|
function formatLabel(item) {
|
|
454
486
|
const text = item.label || item.value;
|
|
@@ -740,12 +772,13 @@ function printHelp() {
|
|
|
740
772
|
console.log(`
|
|
741
773
|
rizzo-css CLI — Add Rizzo CSS to your project (Vanilla, Astro, Svelte)
|
|
742
774
|
|
|
743
|
-
Available commands: init, add, theme, help
|
|
775
|
+
Available commands: init, add, theme, doctor, help
|
|
744
776
|
|
|
745
777
|
Flags summary:
|
|
746
778
|
init --yes --framework <fw> --template <t> --package-manager <pm> --install --no-install
|
|
747
|
-
add --path <dir> --framework <fw> --
|
|
779
|
+
add --path <dir> --framework <fw> ... --no-snippet --readme --force --vanilla-js
|
|
748
780
|
theme (no flags)
|
|
781
|
+
doctor Check config, CSS file, and optional layout link
|
|
749
782
|
help (no flags)
|
|
750
783
|
|
|
751
784
|
Usage (use your package manager):
|
|
@@ -775,6 +808,10 @@ Options (add):
|
|
|
775
808
|
--package-manager <pm> npm | pnpm | yarn | bun (override detection for install/print commands)
|
|
776
809
|
--install-package After copying CSS, run package manager add rizzo-css
|
|
777
810
|
--no-install Do not run install or add (overrides --install-package)
|
|
811
|
+
--no-snippet Do not write RIZZO-SNIPPET.txt (link + theme copy-paste)
|
|
812
|
+
--readme Write README-RIZZO.md into the project
|
|
813
|
+
--force Overwrite existing rizzo.min.css without prompting
|
|
814
|
+
--vanilla-js (Vanilla) Copy js/main.js for interactive components (modal, dropdown, tabs, toast, theme switcher)
|
|
778
815
|
|
|
779
816
|
Package managers:
|
|
780
817
|
Supported: npm, pnpm, yarn, bun. Detection: lockfiles (pnpm-lock.yaml, yarn.lock, bun.lockb, package-lock.json) or package.json "packageManager"/"devEngines.packageManager". Use --package-manager to override.
|
|
@@ -835,12 +872,18 @@ Available to pick (Astro & Svelte; same list):
|
|
|
835
872
|
` + line1 + (line2 ? ',\n ' + line2 : '') + (line3 ? ',\n ' + line3 : '') + `
|
|
836
873
|
|
|
837
874
|
Dependencies (when you pick the component on the left, the right is added automatically):
|
|
875
|
+
Navbar → Search, Settings (navbar includes search bar; Settings so gear button works)
|
|
838
876
|
Settings → ThemeSwitcher (and themes.ts)
|
|
839
877
|
Toast → Alert
|
|
840
878
|
|
|
841
879
|
ThemeSwitcher and ThemeIcon: when selected, themes.ts (and Svelte theme.ts) is copied so they work.
|
|
842
880
|
Icons: copied whenever you add any component.
|
|
843
881
|
|
|
882
|
+
Where components are copied:
|
|
883
|
+
Astro → src/components/rizzo/ (import from there)
|
|
884
|
+
Svelte → src/lib/rizzo/ (import from '$lib/rizzo')
|
|
885
|
+
Vanilla → components/ (HTML) (for interactivity add js/main.js; use --vanilla-js on add)
|
|
886
|
+
|
|
844
887
|
Full = all components above; dependencies are included so everything works.
|
|
845
888
|
Minimal = recommended set; any component in that set that requires others gets them.
|
|
846
889
|
Manual = you pick; the picker shows e.g. "Settings (adds ThemeSwitcher)". Required deps are added when you confirm.
|
|
@@ -857,6 +900,45 @@ function cmdTheme() {
|
|
|
857
900
|
process.stdout.write('\nExample: <html lang="en" data-theme="github-dark-classic">\n\n');
|
|
858
901
|
}
|
|
859
902
|
|
|
903
|
+
/** Check project for Rizzo CSS: config, CSS file, optional link in layout. */
|
|
904
|
+
function cmdDoctor() {
|
|
905
|
+
const cwd = process.cwd();
|
|
906
|
+
const config = readRizzoConfig(cwd);
|
|
907
|
+
console.log('\nRizzo CSS doctor\n');
|
|
908
|
+
let ok = true;
|
|
909
|
+
if (!config) {
|
|
910
|
+
console.log(' ✗ No ' + RIZZO_CONFIG_FILE + '. Run: npx rizzo-css add or init');
|
|
911
|
+
ok = false;
|
|
912
|
+
} else {
|
|
913
|
+
console.log(' ✓ ' + RIZZO_CONFIG_FILE + ' (framework: ' + (config.framework || '?') + ')');
|
|
914
|
+
const fw = config.framework || 'vanilla';
|
|
915
|
+
const paths = getFrameworkCssPaths(fw);
|
|
916
|
+
const targetDir = (config.targetDir || paths.targetDir);
|
|
917
|
+
const cssPath = fw === 'astro' ? join(cwd, 'public', 'css', 'rizzo.min.css') : fw === 'svelte' ? join(cwd, 'static', 'css', 'rizzo.min.css') : join(cwd, targetDir, 'rizzo.min.css');
|
|
918
|
+
if (!existsSync(cssPath)) {
|
|
919
|
+
console.log(' ✗ CSS not found at ' + cssPath);
|
|
920
|
+
ok = false;
|
|
921
|
+
} else {
|
|
922
|
+
console.log(' ✓ CSS at ' + cssPath);
|
|
923
|
+
}
|
|
924
|
+
const layoutPaths = fw === 'svelte' ? ['src/app.html'] : fw === 'astro' ? ['src/layouts/Layout.astro', 'src/layouts/BaseLayout.astro'] : [];
|
|
925
|
+
for (const lp of layoutPaths) {
|
|
926
|
+
const full = join(cwd, lp);
|
|
927
|
+
if (existsSync(full)) {
|
|
928
|
+
const content = readFileSync(full, 'utf8');
|
|
929
|
+
if (!content.includes('rizzo') && !content.includes('rizzo.min.css')) {
|
|
930
|
+
console.log(' ? Layout ' + lp + ' may not include the stylesheet — add <link rel="stylesheet" href="' + (fw === 'svelte' ? '/css/rizzo.min.css' : '/css/rizzo.min.css') + '" />');
|
|
931
|
+
} else {
|
|
932
|
+
console.log(' ✓ Layout ' + lp + ' includes Rizzo link');
|
|
933
|
+
}
|
|
934
|
+
break;
|
|
935
|
+
}
|
|
936
|
+
}
|
|
937
|
+
}
|
|
938
|
+
if (config && config.theme) console.log(' Theme (from config): ' + config.theme);
|
|
939
|
+
console.log(ok ? '\nAll checks passed.\n' : '\nFix the items above, then run your dev server.\n');
|
|
940
|
+
}
|
|
941
|
+
|
|
860
942
|
/** Prompt for default dark theme, default light theme, and initial theme. Returns { theme, defaultDark, defaultLight }. */
|
|
861
943
|
async function promptThemes() {
|
|
862
944
|
const defaultDark = await selectMenu(
|
|
@@ -974,6 +1056,10 @@ async function cmdAdd(argv) {
|
|
|
974
1056
|
const explicitFramework = explicitFrameworkRaw && FRAMEWORKS.includes(explicitFrameworkRaw.toLowerCase()) ? explicitFrameworkRaw.toLowerCase() : null;
|
|
975
1057
|
const installPackage = hasFlag(argv, '--install-package');
|
|
976
1058
|
const noInstall = hasFlag(argv, '--no-install');
|
|
1059
|
+
const writeSnippet = !hasFlag(argv, '--no-snippet');
|
|
1060
|
+
const writeReadme = hasFlag(argv, '--readme');
|
|
1061
|
+
const force = hasFlag(argv, '--force');
|
|
1062
|
+
const copyVanillaJs = hasFlag(argv, '--vanilla-js');
|
|
977
1063
|
const positionals = getPositionalArgs(argv);
|
|
978
1064
|
|
|
979
1065
|
const cwd = process.cwd();
|
|
@@ -984,6 +1070,10 @@ async function cmdAdd(argv) {
|
|
|
984
1070
|
targetDir: customPath || (config && config.targetDir) || undefined,
|
|
985
1071
|
packageManager: pmOverride || undefined,
|
|
986
1072
|
preselectedComponents: positionals.length > 0 ? positionals : undefined,
|
|
1073
|
+
writeSnippet,
|
|
1074
|
+
writeReadme,
|
|
1075
|
+
force,
|
|
1076
|
+
copyVanillaJs,
|
|
987
1077
|
};
|
|
988
1078
|
await runAddToExisting(explicitFramework, options);
|
|
989
1079
|
if (installPackage && !noInstall) {
|
|
@@ -1320,17 +1410,37 @@ async function runAddToExisting(frameworkOverride, options) {
|
|
|
1320
1410
|
const targetDirRaw = (options && options.targetDir) || (config && config.targetDir) || paths.targetDir;
|
|
1321
1411
|
let cssTarget;
|
|
1322
1412
|
if (framework === 'astro') {
|
|
1323
|
-
copyRizzoCssAndFontsForAstro(cwd, cssSource);
|
|
1324
1413
|
cssTarget = join(cwd, 'public', 'css', 'rizzo.min.css');
|
|
1325
1414
|
} else if (framework === 'svelte') {
|
|
1326
|
-
copyRizzoCssAndFontsForSvelte(cwd, cssSource);
|
|
1327
1415
|
cssTarget = join(cwd, 'static', 'css', 'rizzo.min.css');
|
|
1328
1416
|
} else {
|
|
1329
1417
|
const targetDir = join(cwd, targetDirRaw);
|
|
1330
1418
|
cssTarget = join(targetDir, 'rizzo.min.css');
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1419
|
+
}
|
|
1420
|
+
const cssExists = existsSync(cssTarget);
|
|
1421
|
+
if (cssExists && !options.force) {
|
|
1422
|
+
const answer = await question('\nCSS already exists at ' + cssTarget + '. Overwrite? (y/N) ');
|
|
1423
|
+
if (answer !== '' && !/^y(es)?$/i.test(answer)) {
|
|
1424
|
+
console.log('Skipping CSS copy. Updating config and components only.');
|
|
1425
|
+
} else {
|
|
1426
|
+
options._overwriteCss = true;
|
|
1427
|
+
}
|
|
1428
|
+
} else if (cssExists && options.force) {
|
|
1429
|
+
options._overwriteCss = true;
|
|
1430
|
+
} else {
|
|
1431
|
+
options._overwriteCss = true;
|
|
1432
|
+
}
|
|
1433
|
+
if (options._overwriteCss) {
|
|
1434
|
+
if (framework === 'astro') {
|
|
1435
|
+
copyRizzoCssAndFontsForAstro(cwd, cssSource);
|
|
1436
|
+
} else if (framework === 'svelte') {
|
|
1437
|
+
copyRizzoCssAndFontsForSvelte(cwd, cssSource);
|
|
1438
|
+
} else {
|
|
1439
|
+
const targetDir = join(cwd, targetDirRaw);
|
|
1440
|
+
mkdirSync(targetDir, { recursive: true });
|
|
1441
|
+
copyFileSync(cssSource, cssTarget);
|
|
1442
|
+
copyRizzoFonts(dirname(cssTarget));
|
|
1443
|
+
}
|
|
1334
1444
|
}
|
|
1335
1445
|
|
|
1336
1446
|
copyRizzoIcons(cwd, framework);
|
|
@@ -1346,6 +1456,20 @@ async function runAddToExisting(frameworkOverride, options) {
|
|
|
1346
1456
|
const linkHrefForVanilla = (options && options.targetDir) ? getLinkHrefForTargetDir(framework, options.targetDir) : paths.linkHref;
|
|
1347
1457
|
const vanillaRepl = { '{{LINK_HREF}}': linkHrefForVanilla, '{{DATA_THEME}}': theme };
|
|
1348
1458
|
copyVanillaComponents(cwd, selectedComponents, vanillaRepl);
|
|
1459
|
+
const needsJs = selectedComponents.some((c) => VANILLA_JS_COMPONENTS.includes(c));
|
|
1460
|
+
const vanillaJsPath = join(cwd, 'js', 'main.js');
|
|
1461
|
+
if (needsJs && !existsSync(vanillaJsPath) && (options.copyVanillaJs || (!preselected && (await confirmCopyVanillaJs())))) {
|
|
1462
|
+
const vanillaJsSrc = join(getPackageRoot(), 'scaffold', 'vanilla', 'js', 'main.js');
|
|
1463
|
+
if (existsSync(vanillaJsSrc)) {
|
|
1464
|
+
mkdirSync(join(cwd, 'js'), { recursive: true });
|
|
1465
|
+
let mainJs = readFileSync(vanillaJsSrc, 'utf8');
|
|
1466
|
+
mainJs = mainJs.replace(/\{\{DEFAULT_DARK\}\}/g, defaultDark).replace(/\{\{DEFAULT_LIGHT\}\}/g, defaultLight);
|
|
1467
|
+
writeFileSync(vanillaJsPath, mainJs, 'utf8');
|
|
1468
|
+
console.log(' - Wrote js/main.js (for modal, dropdown, tabs, toast, theme switcher)');
|
|
1469
|
+
}
|
|
1470
|
+
} else if (needsJs && !existsSync(vanillaJsPath)) {
|
|
1471
|
+
options._vanillaJsHint = true;
|
|
1472
|
+
}
|
|
1349
1473
|
}
|
|
1350
1474
|
|
|
1351
1475
|
const linkHref = (framework === 'astro' || framework === 'svelte') ? paths.linkHref : ((options && options.targetDir) ? getLinkHrefForTargetDir(framework, options.targetDir) : paths.linkHref);
|
|
@@ -1357,38 +1481,56 @@ async function runAddToExisting(frameworkOverride, options) {
|
|
|
1357
1481
|
: resolvePackageManager(cwd);
|
|
1358
1482
|
const cliExample = pm.dlx('rizzo-css theme');
|
|
1359
1483
|
const configTargetDir = framework === 'astro' ? 'public/css' : framework === 'svelte' ? 'static/css' : targetDirRaw;
|
|
1360
|
-
writeRizzoConfig(cwd, { targetDir: configTargetDir, framework, packageManager: pm.agent });
|
|
1484
|
+
writeRizzoConfig(cwd, { targetDir: configTargetDir, framework, packageManager: pm.agent, theme });
|
|
1485
|
+
const writeSnippet = options.writeSnippet !== false;
|
|
1486
|
+
if (writeSnippet) {
|
|
1487
|
+
const where = framework === 'svelte' ? 'Root layout (e.g. src/app.html)' : framework === 'astro' ? 'Layout (e.g. src/layouts/Layout.astro)' : 'HTML or layout';
|
|
1488
|
+
const snippetBody = [
|
|
1489
|
+
'Add to ' + where + ':',
|
|
1490
|
+
'',
|
|
1491
|
+
' <link rel="stylesheet" href="' + linkHref + '" />',
|
|
1492
|
+
'',
|
|
1493
|
+
'On <html>: data-theme="' + theme + '"',
|
|
1494
|
+
'Themes: ' + cliExample,
|
|
1495
|
+
].join('\n');
|
|
1496
|
+
writeFileSync(join(cwd, RIZZO_SNIPPET_FILE), snippetBody + '\n', 'utf8');
|
|
1497
|
+
}
|
|
1498
|
+
if (options.writeReadme) {
|
|
1499
|
+
const readmePath = join(getPackageRoot(), 'scaffold', 'vanilla', SCAFFOLD_README_FILENAME);
|
|
1500
|
+
if (existsSync(readmePath)) {
|
|
1501
|
+
copyFileSync(readmePath, join(cwd, SCAFFOLD_README_FILENAME));
|
|
1502
|
+
}
|
|
1503
|
+
}
|
|
1361
1504
|
console.log('\n✓ Rizzo CSS added to your existing project');
|
|
1362
1505
|
console.log(' - ' + cssTarget);
|
|
1363
1506
|
console.log(' - Wrote ' + RIZZO_CONFIG_FILE);
|
|
1507
|
+
if (writeSnippet) console.log(' - Wrote ' + RIZZO_SNIPPET_FILE + ' (copy-paste link + theme)');
|
|
1508
|
+
if (options.writeReadme) console.log(' - Wrote ' + SCAFFOLD_README_FILENAME);
|
|
1364
1509
|
console.log('\nYou must add the stylesheet link yourself — it is not added automatically.');
|
|
1365
|
-
if (
|
|
1510
|
+
if (selectedComponents.length === 0) {
|
|
1511
|
+
console.log('\n <link rel="stylesheet" href="' + linkHref + '" />');
|
|
1512
|
+
console.log(' data-theme="' + theme + '" on <html> — list themes: ' + cliExample);
|
|
1513
|
+
} else if (framework === 'svelte') {
|
|
1366
1514
|
console.log('\nIn your root layout (e.g. src/app.html), add:');
|
|
1367
1515
|
console.log(' <link rel="stylesheet" href="' + linkHref + '" />');
|
|
1368
|
-
console.log('
|
|
1369
|
-
console.log('
|
|
1370
|
-
if (selectedComponents.length > 0) {
|
|
1371
|
-
console.log(' Components are in src/lib/rizzo — import from \'$lib/rizzo\'.');
|
|
1372
|
-
}
|
|
1516
|
+
console.log(' data-theme="' + theme + '" on <html> (themes: ' + cliExample + ')');
|
|
1517
|
+
console.log(' Components: src/lib/rizzo — import from \'$lib/rizzo\'.');
|
|
1373
1518
|
} else if (framework === 'astro') {
|
|
1374
1519
|
console.log('\nIn your layout (e.g. src/layouts/Layout.astro), add:');
|
|
1375
1520
|
console.log(' <link rel="stylesheet" href="' + linkHref + '" />');
|
|
1376
|
-
console.log('
|
|
1377
|
-
console.log('
|
|
1378
|
-
if (selectedComponents.length > 0) {
|
|
1379
|
-
console.log(' Components are in src/components/rizzo — import from there.');
|
|
1380
|
-
}
|
|
1521
|
+
console.log(' data-theme="' + theme + '" on <html> (themes: ' + cliExample + ')');
|
|
1522
|
+
console.log(' Components: src/components/rizzo — import from there.');
|
|
1381
1523
|
} else {
|
|
1382
1524
|
console.log('\nIn your HTML or layout, add:');
|
|
1383
1525
|
console.log(' <link rel="stylesheet" href="' + linkHref + '" />');
|
|
1384
|
-
console.log('
|
|
1385
|
-
console.log('
|
|
1386
|
-
if (
|
|
1387
|
-
console.log('
|
|
1526
|
+
console.log(' data-theme="' + theme + '" on <html> (themes: ' + cliExample + ')');
|
|
1527
|
+
console.log(' Component HTML files are in components/.');
|
|
1528
|
+
if (options._vanillaJsHint) {
|
|
1529
|
+
console.log(' For interactive components (modal, dropdown, tabs, toast, theme switcher), add js/main.js — run again with --vanilla-js or copy from a Full scaffold.');
|
|
1388
1530
|
}
|
|
1389
1531
|
}
|
|
1390
|
-
console.log('\nTo install the package
|
|
1391
|
-
console.log('\
|
|
1532
|
+
console.log('\nTo install the package: ' + pm.add('rizzo-css'));
|
|
1533
|
+
console.log('\nNext: add the link above, then run your dev server. Docs: https://rizzo-css.vercel.app\n');
|
|
1392
1534
|
}
|
|
1393
1535
|
|
|
1394
1536
|
async function cmdInit(argv) {
|
|
@@ -1412,7 +1554,8 @@ async function cmdInit(argv) {
|
|
|
1412
1554
|
framework = (frameworkArg && FRAMEWORKS.includes(frameworkArg.toLowerCase())) ? frameworkArg.toLowerCase() : (config && config.framework) || 'astro';
|
|
1413
1555
|
initMode = 'new';
|
|
1414
1556
|
const templateArg = getFlagValue(argv, '--template');
|
|
1415
|
-
|
|
1557
|
+
const defaultTemplate = framework === 'vanilla' ? 'minimal' : 'full';
|
|
1558
|
+
selectedTemplate = (templateArg && (templateArg === 'full' || templateArg === 'minimal' || templateArg === 'manual')) ? templateArg : defaultTemplate;
|
|
1416
1559
|
if (selectedTemplate === 'full' && (framework === 'astro' || framework === 'svelte')) {
|
|
1417
1560
|
selectedComponents = framework === 'svelte' ? [...SVELTE_COMPONENTS] : [...ASTRO_COMPONENTS];
|
|
1418
1561
|
} else if (selectedTemplate === 'minimal' && (framework === 'astro' || framework === 'svelte')) {
|
|
@@ -1489,6 +1632,13 @@ async function cmdInit(argv) {
|
|
|
1489
1632
|
}
|
|
1490
1633
|
|
|
1491
1634
|
const projectDir = name ? join(cwd, name) : cwd;
|
|
1635
|
+
if (projectDir === cwd && isDirNonEmpty(cwd) && !yes) {
|
|
1636
|
+
const ok = await confirmNonEmptyDir(projectDir);
|
|
1637
|
+
if (!ok) {
|
|
1638
|
+
console.log('Aborted.');
|
|
1639
|
+
return;
|
|
1640
|
+
}
|
|
1641
|
+
}
|
|
1492
1642
|
const cssSource = getCssPath();
|
|
1493
1643
|
|
|
1494
1644
|
if (!existsSync(cssSource)) {
|
|
@@ -1742,7 +1892,7 @@ async function cmdInit(argv) {
|
|
|
1742
1892
|
|
|
1743
1893
|
// Always write rizzo-css.json for new projects (targetDir, framework, packageManager).
|
|
1744
1894
|
const pathsForConfig = getFrameworkCssPaths(framework);
|
|
1745
|
-
writeRizzoConfig(projectDir, { targetDir: pathsForConfig.targetDir, framework, packageManager: selectedPm });
|
|
1895
|
+
writeRizzoConfig(projectDir, { targetDir: pathsForConfig.targetDir, framework, packageManager: selectedPm, theme });
|
|
1746
1896
|
console.log(' - Wrote ' + RIZZO_CONFIG_FILE);
|
|
1747
1897
|
|
|
1748
1898
|
if (runInstallAfterScaffold && !noInstall && hasPackageJson) {
|
|
@@ -1779,6 +1929,8 @@ async function cmdInit(argv) {
|
|
|
1779
1929
|
const createExample = getCreateProjectExample(pm, framework);
|
|
1780
1930
|
console.log('\n - Minimal template (CSS + index). To get a full app: ' + createExample + ', then cd into the project and run ' + pm.dlx('rizzo-css add') + '.');
|
|
1781
1931
|
}
|
|
1932
|
+
if (hasPackageJson) console.log('\nNext: ' + runPrefix + nextStep);
|
|
1933
|
+
else if (framework === 'vanilla') console.log('\nNext: open index.html or serve the folder.');
|
|
1782
1934
|
console.log('\nDocs: https://rizzo-css.vercel.app\n');
|
|
1783
1935
|
}
|
|
1784
1936
|
|
|
@@ -1803,6 +1955,11 @@ function main() {
|
|
|
1803
1955
|
return;
|
|
1804
1956
|
}
|
|
1805
1957
|
|
|
1958
|
+
if (command === 'doctor') {
|
|
1959
|
+
cmdDoctor();
|
|
1960
|
+
return;
|
|
1961
|
+
}
|
|
1962
|
+
|
|
1806
1963
|
if (command === 'add') {
|
|
1807
1964
|
cmdAdd(argv).catch((err) => {
|
|
1808
1965
|
console.error(err);
|
package/package.json
CHANGED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Astro default .gitignore (same as npm create astro@latest)
|
|
2
|
+
# build output
|
|
3
|
+
dist/
|
|
4
|
+
# generated types
|
|
5
|
+
.astro/
|
|
6
|
+
|
|
7
|
+
# dependencies
|
|
8
|
+
node_modules/
|
|
9
|
+
|
|
10
|
+
# logs
|
|
11
|
+
npm-debug.log*
|
|
12
|
+
yarn-debug.log*
|
|
13
|
+
yarn-error.log*
|
|
14
|
+
pnpm-debug.log*
|
|
15
|
+
|
|
16
|
+
# environment variables
|
|
17
|
+
.env
|
|
18
|
+
.env.production
|
|
19
|
+
|
|
20
|
+
# macOS-specific files
|
|
21
|
+
.DS_Store
|
|
22
|
+
|
|
23
|
+
# jetbrains setting folder
|
|
24
|
+
.idea/
|
|
@@ -13,7 +13,7 @@ If you prefer to load CSS from a CDN instead of the local file, replace the `<li
|
|
|
13
13
|
- `<link rel="stylesheet" href="https://unpkg.com/rizzo-css@latest/dist/rizzo.min.css" />`
|
|
14
14
|
- Or jsDelivr: `https://cdn.jsdelivr.net/npm/rizzo-css@latest/dist/rizzo.min.css`
|
|
15
15
|
|
|
16
|
-
(Replace `@latest` with a specific version, e.g. `@0.0.
|
|
16
|
+
(Replace `@latest` with a specific version, e.g. `@0.0.29`, in production.)
|
|
17
17
|
|
|
18
18
|
The CLI replaces placeholders in `index.html` (e.g. `{{DATA_THEME}}`, `{{TITLE}}`) when you run `rizzo-css init`. The theme selected during init is used on first load when you have no saved preference in the browser.
|
|
19
19
|
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Vanilla / static site default .gitignore (Rizzo CSS scaffold)
|
|
2
|
+
|
|
3
|
+
# OS files
|
|
4
|
+
.DS_Store
|
|
5
|
+
Thumbs.db
|
|
6
|
+
|
|
7
|
+
# Editor / IDE
|
|
8
|
+
.idea/
|
|
9
|
+
.vscode/
|
|
10
|
+
*.swp
|
|
11
|
+
*.swo
|
|
12
|
+
*~
|
|
13
|
+
|
|
14
|
+
# Environment
|
|
15
|
+
.env
|
|
16
|
+
.env.*
|
|
17
|
+
!.env.example
|
|
18
|
+
|
|
19
|
+
# Logs
|
|
20
|
+
*.log
|
|
21
|
+
npm-debug.log*
|
|
22
|
+
yarn-debug.log*
|
|
23
|
+
yarn-error.log*
|
|
24
|
+
pnpm-debug.log*
|
|
25
|
+
|
|
26
|
+
# Optional: if you add Node/npm later
|
|
27
|
+
node_modules/
|
|
@@ -731,6 +731,38 @@
|
|
|
731
731
|
document.querySelectorAll('[data-accordion]').forEach(initOne);
|
|
732
732
|
}
|
|
733
733
|
|
|
734
|
+
function initNavbarMobile() {
|
|
735
|
+
document.querySelectorAll('.navbar').forEach(function (navbar) {
|
|
736
|
+
var toggle = navbar.querySelector('.navbar__toggle');
|
|
737
|
+
var menu = navbar.querySelector('.navbar__menu');
|
|
738
|
+
if (!toggle || !menu) return;
|
|
739
|
+
function setMenuOpen(open) {
|
|
740
|
+
menu.classList.toggle('navbar__menu--open', open);
|
|
741
|
+
navbar.classList.toggle('navbar--menu-open', open);
|
|
742
|
+
toggle.setAttribute('aria-expanded', open ? 'true' : 'false');
|
|
743
|
+
menu.setAttribute('aria-hidden', open ? 'false' : 'true');
|
|
744
|
+
}
|
|
745
|
+
toggle.addEventListener('click', function () {
|
|
746
|
+
setMenuOpen(!menu.classList.contains('navbar__menu--open'));
|
|
747
|
+
});
|
|
748
|
+
menu.querySelectorAll('.navbar__link').forEach(function (link) {
|
|
749
|
+
link.addEventListener('click', function () { setMenuOpen(false); });
|
|
750
|
+
});
|
|
751
|
+
});
|
|
752
|
+
document.addEventListener('keydown', function (e) {
|
|
753
|
+
if (e.key === 'Escape') {
|
|
754
|
+
document.querySelectorAll('.navbar__menu.navbar__menu--open').forEach(function (menu) {
|
|
755
|
+
var navbar = menu.closest('.navbar');
|
|
756
|
+
var toggle = navbar && navbar.querySelector('.navbar__toggle');
|
|
757
|
+
menu.classList.remove('navbar__menu--open');
|
|
758
|
+
navbar.classList.remove('navbar--menu-open');
|
|
759
|
+
if (toggle) toggle.setAttribute('aria-expanded', 'false');
|
|
760
|
+
menu.setAttribute('aria-hidden', 'true');
|
|
761
|
+
});
|
|
762
|
+
}
|
|
763
|
+
});
|
|
764
|
+
}
|
|
765
|
+
|
|
734
766
|
function run() {
|
|
735
767
|
initTheme();
|
|
736
768
|
initSettings();
|
|
@@ -738,6 +770,7 @@
|
|
|
738
770
|
initModals();
|
|
739
771
|
initDropdowns();
|
|
740
772
|
initAccordions();
|
|
773
|
+
initNavbarMobile();
|
|
741
774
|
}
|
|
742
775
|
|
|
743
776
|
if (document.readyState === 'loading') {
|