rizzo-css 0.0.74 → 0.0.76
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 +3 -3
- package/bin/rizzo-css.js +10 -10
- package/dist/rizzo.min.css +4 -2
- package/package.json +4 -4
- package/scaffold/astro/Footer.astro +1 -1
- package/scaffold/astro/base/README-RIZZO.md +1 -1
- package/scaffold/astro/variants/full/README-RIZZO.md +1 -1
- package/scaffold/landing/index.html +27 -2
- package/scaffold/react/base/package.json +1 -1
- package/scaffold/svelte/Chart.svelte +34 -0
- package/scaffold/svelte/Command.svelte +89 -0
- package/scaffold/svelte/Direction.svelte +17 -0
- package/scaffold/svelte/InputOtp.svelte +57 -0
- package/scaffold/svelte/Menubar.svelte +78 -0
- package/scaffold/svelte/base/README-RIZZO.md +1 -1
- package/scaffold/svelte/variants/full/README-RIZZO.md +1 -1
- package/scaffold/vanilla/README-RIZZO.md +2 -2
- package/scaffold/vanilla/components/accordion.html +18 -0
- package/scaffold/vanilla/components/alert-dialog.html +18 -0
- package/scaffold/vanilla/components/alert.html +18 -0
- package/scaffold/vanilla/components/aspect-ratio.html +18 -0
- package/scaffold/vanilla/components/avatar.html +18 -0
- package/scaffold/vanilla/components/back-to-top.html +18 -0
- package/scaffold/vanilla/components/badge.html +18 -0
- package/scaffold/vanilla/components/breadcrumb.html +18 -0
- package/scaffold/vanilla/components/button-group.html +18 -0
- package/scaffold/vanilla/components/button.html +18 -0
- package/scaffold/vanilla/components/calendar.html +18 -0
- package/scaffold/vanilla/components/cards.html +18 -0
- package/scaffold/vanilla/components/carousel.html +18 -0
- package/scaffold/vanilla/components/chart.html +872 -0
- package/scaffold/vanilla/components/collapsible.html +18 -0
- package/scaffold/vanilla/components/command.html +872 -0
- package/scaffold/vanilla/components/context-menu.html +18 -0
- package/scaffold/vanilla/components/copy-to-clipboard.html +18 -0
- package/scaffold/vanilla/components/dashboard.html +18 -0
- package/scaffold/vanilla/components/direction.html +872 -0
- package/scaffold/vanilla/components/divider.html +18 -0
- package/scaffold/vanilla/components/docs-sidebar.html +18 -0
- package/scaffold/vanilla/components/dropdown.html +18 -0
- package/scaffold/vanilla/components/empty.html +18 -0
- package/scaffold/vanilla/components/font-switcher.html +18 -0
- package/scaffold/vanilla/components/footer.html +18 -0
- package/scaffold/vanilla/components/forms.html +18 -0
- package/scaffold/vanilla/components/hover-card.html +18 -0
- package/scaffold/vanilla/components/icons.html +18 -0
- package/scaffold/vanilla/components/index.html +23 -0
- package/scaffold/vanilla/components/input-group.html +18 -0
- package/scaffold/vanilla/components/input-otp.html +872 -0
- package/scaffold/vanilla/components/kbd.html +18 -0
- package/scaffold/vanilla/components/label.html +18 -0
- package/scaffold/vanilla/components/menubar.html +872 -0
- package/scaffold/vanilla/components/modal.html +18 -0
- package/scaffold/vanilla/components/navbar.html +18 -0
- package/scaffold/vanilla/components/pagination.html +18 -0
- package/scaffold/vanilla/components/popover.html +18 -0
- package/scaffold/vanilla/components/progress-bar.html +18 -0
- package/scaffold/vanilla/components/range-calendar.html +18 -0
- package/scaffold/vanilla/components/resizable.html +18 -0
- package/scaffold/vanilla/components/scroll-area.html +18 -0
- package/scaffold/vanilla/components/search.html +18 -0
- package/scaffold/vanilla/components/separator.html +18 -0
- package/scaffold/vanilla/components/settings.html +18 -0
- package/scaffold/vanilla/components/sheet.html +18 -0
- package/scaffold/vanilla/components/skeleton.html +18 -0
- package/scaffold/vanilla/components/slider.html +18 -0
- package/scaffold/vanilla/components/sound-effects.html +18 -0
- package/scaffold/vanilla/components/spinner.html +18 -0
- package/scaffold/vanilla/components/switch.html +18 -0
- package/scaffold/vanilla/components/table.html +18 -0
- package/scaffold/vanilla/components/tabs.html +18 -0
- package/scaffold/vanilla/components/theme-switcher.html +18 -0
- package/scaffold/vanilla/components/toast.html +18 -0
- package/scaffold/vanilla/components/toggle-group.html +18 -0
- package/scaffold/vanilla/components/toggle.html +18 -0
- package/scaffold/vanilla/components/tooltip.html +18 -0
- package/scaffold/vanilla/index.html +18 -0
- package/scaffold/vue/Accordion.vue +1 -1
- package/scaffold/vue/Alert.vue +1 -1
- package/scaffold/vue/AlertDialog.vue +1 -1
- package/scaffold/vue/AspectRatio.vue +1 -1
- package/scaffold/vue/Avatar.vue +1 -1
- package/scaffold/vue/BackToTop.vue +1 -1
- package/scaffold/vue/Badge.vue +6 -12
- package/scaffold/vue/Breadcrumb.vue +1 -1
- package/scaffold/vue/Button.vue +6 -11
- package/scaffold/vue/ButtonGroup.vue +1 -1
- package/scaffold/vue/Card.vue +4 -7
- package/scaffold/vue/Checkbox.vue +12 -12
- package/scaffold/vue/Collapsible.vue +1 -1
- package/scaffold/vue/ContextMenu.vue +1 -1
- package/scaffold/vue/CopyToClipboard.vue +1 -1
- package/scaffold/vue/Dashboard.vue +1 -1
- package/scaffold/vue/Divider.vue +5 -8
- package/scaffold/vue/DocsSidebar.vue +1 -1
- package/scaffold/vue/Dropdown.vue +1 -1
- package/scaffold/vue/Empty.vue +1 -1
- package/scaffold/vue/FontSwitcher.vue +1 -1
- package/scaffold/vue/Footer.vue +1 -1
- package/scaffold/vue/FormGroup.vue +9 -12
- package/scaffold/vue/HoverCard.vue +1 -1
- package/scaffold/vue/Icons.vue +1 -1
- package/scaffold/vue/Input.vue +17 -30
- package/scaffold/vue/Kbd.vue +1 -1
- package/scaffold/vue/Label.vue +5 -8
- package/scaffold/vue/Modal.vue +1 -1
- package/scaffold/vue/Navbar.vue +1 -1
- package/scaffold/vue/Pagination.vue +1 -1
- package/scaffold/vue/Popover.vue +1 -1
- package/scaffold/vue/ProgressBar.vue +1 -1
- package/scaffold/vue/Radio.vue +10 -13
- package/scaffold/vue/ResizableHandle.vue +1 -1
- package/scaffold/vue/ResizablePane.vue +1 -1
- package/scaffold/vue/ResizablePaneGroup.vue +1 -1
- package/scaffold/vue/ScrollArea.vue +1 -1
- package/scaffold/vue/Search.vue +1 -1
- package/scaffold/vue/Select.vue +14 -25
- package/scaffold/vue/Separator.vue +1 -1
- package/scaffold/vue/Settings.vue +1 -1
- package/scaffold/vue/Sheet.vue +1 -1
- package/scaffold/vue/Skeleton.vue +1 -1
- package/scaffold/vue/Slider.vue +1 -1
- package/scaffold/vue/SoundEffects.vue +1 -1
- package/scaffold/vue/Spinner.vue +6 -9
- package/scaffold/vue/Switch.vue +1 -1
- package/scaffold/vue/Table.vue +1 -1
- package/scaffold/vue/Tabs.vue +1 -1
- package/scaffold/vue/Textarea.vue +18 -31
- package/scaffold/vue/ThemeSwitcher.vue +1 -1
- package/scaffold/vue/Toast.vue +1 -1
- package/scaffold/vue/Toggle.vue +1 -1
- package/scaffold/vue/ToggleGroup.vue +1 -1
- package/scaffold/vue/Tooltip.vue +1 -1
- package/scaffold/vue/base/package.json +1 -1
package/README.md
CHANGED
|
@@ -16,7 +16,7 @@ bun add rizzo-css
|
|
|
16
16
|
|
|
17
17
|
The package works with **npm**, **pnpm**, **yarn**, and **bun**. After install, run the CLI with your manager’s runner: `npx` (npm/yarn), `pnpm dlx`, or `bunx`.
|
|
18
18
|
|
|
19
|
-
**Quick start (no install):** `npx rizzo-css init` — choose **framework** (Vanilla, Astro, Svelte, React, or Vue), then **add to existing** or **create new**. Both flows use the **same template choice**: **Landing** (hero/features), **Docs** (sidebar + sample doc), **Dashboard** (sidebar + stats/table), or **Full** (clone of the docs site). Landing/Docs/Dashboard = component picker (all
|
|
19
|
+
**Quick start (no install):** `npx rizzo-css init` — choose **framework** (Vanilla, Astro, Svelte, React, or Vue), then **add to existing** or **create new**. Both flows use the **same template choice**: **Landing** (hero/features), **Docs** (sidebar + sample doc), **Dashboard** (sidebar + stats/table), or **Full** (clone of the docs site). Landing/Docs/Dashboard = component picker (all 58 or pick). We **never overwrite your existing files**; any skipped content is in **RIZZO-SETUP.md**. You must add the `<link>` yourself (CLI prints the exact tag). Non-interactive: `npx rizzo-css init --yes --framework vanilla|astro|svelte|react|vue --template landing|docs|dashboard|full` or `npx rizzo-css add --template landing|docs|dashboard|full`. 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`:
|
|
20
20
|
|
|
21
21
|
```bash
|
|
22
22
|
npm create svelte@latest my-app && cd my-app && npx rizzo-css add
|
|
@@ -25,7 +25,7 @@ npm create astro@latest my-app && cd my-app && npx rizzo-css add
|
|
|
25
25
|
|
|
26
26
|
**Running the CLI:** npm → `npx`; pnpm → `pnpm dlx`; yarn → `npx` (Yarn 1 has no `dlx`; works with Yarn 2+ too); bun → `bunx`. The [docs site](https://rizzo-css.vercel.app/docs/getting-started) tabs show the correct command for each manager.
|
|
27
27
|
|
|
28
|
-
**Same flow for new and existing:** Both prompt for **Landing** | **Docs** | **Dashboard** | **Full**. Landing/Docs/Dashboard = component picker (all
|
|
28
|
+
**Same flow for new and existing:** Both prompt for **Landing** | **Docs** | **Dashboard** | **Full**. Landing/Docs/Dashboard = component picker (all 58 or pick). Full = site clone (no picker); also writes **RIZZO-SNIPPET.txt** (link + theme) unless `--no-snippet`. `npx rizzo-css doctor` checks config and CSS path. `npx rizzo-css theme` lists themes.
|
|
29
29
|
|
|
30
30
|
| | **Create new** (`init` → new) | **Add to existing** (`add` or `init` → existing) |
|
|
31
31
|
|---|------------------------------|--------------------------------------------------|
|
|
@@ -72,7 +72,7 @@ import 'rizzo-css';
|
|
|
72
72
|
**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:
|
|
73
73
|
|
|
74
74
|
```html
|
|
75
|
-
<!-- unpkg (pin version: replace @latest with @0.0.
|
|
75
|
+
<!-- unpkg (pin version: replace @latest with @0.0.76 or any version) -->
|
|
76
76
|
<link rel="stylesheet" href="https://unpkg.com/rizzo-css@latest/dist/rizzo.min.css" />
|
|
77
77
|
|
|
78
78
|
<!-- or jsDelivr -->
|
package/bin/rizzo-css.js
CHANGED
|
@@ -196,18 +196,18 @@ const THEMES = [...DARK_THEMES, ...LIGHT_THEMES];
|
|
|
196
196
|
const VALID_THEME_VALUES = ['system', ...THEMES];
|
|
197
197
|
// Components available for scaffold (must match scaffold/svelte and scaffold/astro; missing files are skipped on copy)
|
|
198
198
|
const SVELTE_COMPONENTS = [
|
|
199
|
-
'Button', 'Badge', 'Card', 'Calendar', 'RangeCalendar', 'Carousel', 'Dashboard', 'Divider', 'DocsSidebar', 'Footer', 'Spinner', 'ProgressBar', 'Avatar', 'Alert',
|
|
200
|
-
'BackToTop', 'Breadcrumb',
|
|
201
|
-
'CopyToClipboard', 'Tooltip', 'Pagination', 'Tabs', 'Accordion', 'Dropdown',
|
|
199
|
+
'Button', 'Badge', 'Card', 'Calendar', 'RangeCalendar', 'Carousel', 'Chart', 'Dashboard', 'Divider', 'DocsSidebar', 'Footer', 'Spinner', 'ProgressBar', 'Avatar', 'Alert',
|
|
200
|
+
'BackToTop', 'Breadcrumb', 'Command', 'FormGroup', 'Input', 'InputGroup', 'InputOtp', 'Checkbox', 'Textarea', 'Select', 'Radio',
|
|
201
|
+
'CopyToClipboard', 'Tooltip', 'Pagination', 'Tabs', 'Accordion', 'Dropdown', 'Direction', 'Menubar',
|
|
202
202
|
'Modal', 'Toast', 'Table', 'ThemeSwitcher', 'FontSwitcher', 'SoundEffects',
|
|
203
203
|
'Navbar', 'Settings', 'Search', 'Icons', 'Skeleton', 'Switch',
|
|
204
204
|
'Label', 'Kbd', 'Collapsible', 'AlertDialog', 'AspectRatio', 'ButtonGroup', 'Empty', 'Separator',
|
|
205
205
|
'Slider', 'Sheet', 'Popover', 'Toggle', 'ToggleGroup', 'ScrollArea', 'HoverCard', 'ContextMenu', 'ResizablePaneGroup', 'ResizablePane', 'ResizableHandle',
|
|
206
206
|
];
|
|
207
207
|
const ASTRO_COMPONENTS = [
|
|
208
|
-
'Button', 'Badge', 'Card', 'Calendar', 'RangeCalendar', 'Carousel', 'Dashboard', 'Divider', 'DocsSidebar', 'Footer', 'Spinner', 'ProgressBar', 'Avatar', 'Alert',
|
|
209
|
-
'BackToTop', 'Breadcrumb',
|
|
210
|
-
'CopyToClipboard', 'Tooltip', 'Pagination', 'Tabs', 'Accordion', 'Dropdown',
|
|
208
|
+
'Button', 'Badge', 'Card', 'Calendar', 'RangeCalendar', 'Carousel', 'Chart', 'Dashboard', 'Divider', 'DocsSidebar', 'Footer', 'Spinner', 'ProgressBar', 'Avatar', 'Alert',
|
|
209
|
+
'BackToTop', 'Breadcrumb', 'Command', 'FormGroup', 'Input', 'InputGroup', 'InputOtp', 'Checkbox', 'Textarea', 'Select', 'Radio',
|
|
210
|
+
'CopyToClipboard', 'Tooltip', 'Pagination', 'Tabs', 'Accordion', 'Dropdown', 'Direction', 'Menubar',
|
|
211
211
|
'Modal', 'Toast', 'Table', 'ThemeSwitcher', 'FontSwitcher', 'SoundEffects',
|
|
212
212
|
'Navbar', 'Settings', 'Search', 'Icons', 'Skeleton', 'Switch',
|
|
213
213
|
'Label', 'Kbd', 'Collapsible', 'AlertDialog', 'AspectRatio', 'ButtonGroup', 'Empty', 'Separator',
|
|
@@ -290,8 +290,8 @@ function logAddedDeps(selected, expanded, framework) {
|
|
|
290
290
|
// Vanilla scaffold: component name (same as ASTRO_COMPONENTS) -> components/*.html slug. New components (label, kbd, etc.) have stub pages in scaffold/vanilla/components/.
|
|
291
291
|
const VANILLA_COMPONENT_SLUGS = {
|
|
292
292
|
Accordion: 'accordion', Alert: 'alert', AlertDialog: 'alert-dialog', AspectRatio: 'aspect-ratio', Avatar: 'avatar', BackToTop: 'back-to-top', Badge: 'badge', Breadcrumb: 'breadcrumb', Button: 'button', ButtonGroup: 'button-group',
|
|
293
|
-
Card: 'cards', Calendar: 'calendar', RangeCalendar: 'range-calendar', Carousel: 'carousel', Checkbox: 'forms', Collapsible: 'collapsible', ContextMenu: 'context-menu', CopyToClipboard: 'copy-to-clipboard', Dashboard: 'dashboard', Divider: 'divider', DocsSidebar: 'docs-sidebar', Dropdown: 'dropdown',
|
|
294
|
-
Empty: 'empty', Footer: 'footer', FormGroup: 'forms', HoverCard: 'hover-card', Input: 'forms', InputGroup: 'input-group', Icons: 'icons', Kbd: 'kbd', Label: 'label',
|
|
293
|
+
Card: 'cards', Calendar: 'calendar', RangeCalendar: 'range-calendar', Carousel: 'carousel', Chart: 'chart', Checkbox: 'forms', Collapsible: 'collapsible', Command: 'command', ContextMenu: 'context-menu', CopyToClipboard: 'copy-to-clipboard', Dashboard: 'dashboard', Direction: 'direction', Divider: 'divider', DocsSidebar: 'docs-sidebar', Dropdown: 'dropdown',
|
|
294
|
+
Empty: 'empty', Footer: 'footer', FormGroup: 'forms', HoverCard: 'hover-card', Input: 'forms', InputGroup: 'input-group', InputOtp: 'input-otp', Icons: 'icons', Kbd: 'kbd', Label: 'label', Menubar: 'menubar',
|
|
295
295
|
Modal: 'modal', Navbar: 'navbar', Pagination: 'pagination', Popover: 'popover', ProgressBar: 'progress-bar',
|
|
296
296
|
Radio: 'forms', ResizableHandle: 'resizable', ResizablePane: 'resizable', ResizablePaneGroup: 'resizable', ScrollArea: 'scroll-area', Search: 'search', Separator: 'separator', Select: 'forms', Settings: 'settings', Sheet: 'sheet',
|
|
297
297
|
Skeleton: 'skeleton', Slider: 'slider', SoundEffects: 'sound-effects', Spinner: 'spinner', Switch: 'switch', Table: 'table',
|
|
@@ -1124,7 +1124,7 @@ Commands:
|
|
|
1124
1124
|
Options (init):
|
|
1125
1125
|
--yes Non-interactive: scaffold new in cwd with defaults (framework: astro, template: landing)
|
|
1126
1126
|
--path <dir> Project directory (relative to cwd or absolute). Scaffold and run install there. With --yes; interactive: "Enter path" option.
|
|
1127
|
-
--framework <fw> vanilla | astro | svelte | react | vue (same
|
|
1127
|
+
--framework <fw> vanilla | astro | svelte | react | vue (same 58 components each)
|
|
1128
1128
|
--template <t> create new: css-only | landing | docs | dashboard | full (default: landing). add: same options.
|
|
1129
1129
|
--package-manager <pm> npm | pnpm | yarn | bun (with --yes, or skip PM prompt when interactive)
|
|
1130
1130
|
--install After scaffolding, run package manager install in project directory (no prompt)
|
|
@@ -1189,7 +1189,7 @@ Component dependencies (Full template):
|
|
|
1189
1189
|
Full list of available components and what relies on what: npx rizzo-css help components
|
|
1190
1190
|
|
|
1191
1191
|
Frameworks:
|
|
1192
|
-
Scaffolds (init/add): Vanilla, Astro, Svelte, React, Vue. Same
|
|
1192
|
+
Scaffolds (init/add): Vanilla, Astro, Svelte, React, Vue. Same 58 components in each framework’s syntax; same CSS and BEM. Docs: https://rizzo-css.vercel.app/docs/react and Vue.
|
|
1193
1193
|
|
|
1194
1194
|
Docs: https://rizzo-css.vercel.app
|
|
1195
1195
|
`);
|
package/dist/rizzo.min.css
CHANGED
|
@@ -213,7 +213,9 @@ div.navbar__link{background:none;border:none;color:inherit;cursor:pointer;font:i
|
|
|
213
213
|
.calendar__next,.calendar__prev{align-items:center;background:transparent;border:none;border-radius:var(--radius-md);color:var(--text);cursor:pointer;display:inline-flex;height:36px;justify-content:center;padding:0;transition:background var(--transition-fast);width:36px}
|
|
214
214
|
.calendar__next:hover,.calendar__prev:hover{background:var(--border)}.calendar__month{color:var(--text);font-size:var(--font-size-base);font-weight:var(--font-weight-semibold)}.calendar__grid{display:flex;flex-direction:column;gap:0}.calendar__row{display:grid;gap:0;grid-template-columns:repeat(7,1fr)}.calendar__weekday{color:var(--text-dim);font-size:var(--font-size-sm);font-weight:var(--font-weight-medium);padding:var(--spacing-1) var(--spacing-2);text-align:center}.calendar__day{align-items:center;background:transparent;border:none;border-radius:var(--radius-md);color:var(--text);cursor:pointer;display:inline-flex;font-size:var(--font-size-sm);height:36px;justify-content:center;margin:2px;min-width:36px;padding:0;transition:background var(--transition-fast)}.calendar__day:hover{background:var(--border)}.calendar__day--today{font-weight:var(--font-weight-semibold);outline:2px solid var(--accent);outline-offset:-2px}.calendar__day--selected{background:var(--accent);color:var(--background)}.calendar__day--selected:hover{background:var(--accent-hover);color:var(--background)}.calendar__day--other-month{color:var(--text-dim);opacity:.7}.calendar__day--in-range{background:oklch(from var(--accent) l c h/20%);color:var(--text)}.calendar__day--in-range:hover{background:oklch(from var(--accent) l c h/35%)}
|
|
215
215
|
.calendar__day--range-end,.calendar__day--range-start{background:var(--accent);color:var(--accent-text)}
|
|
216
|
-
.calendar__day--range-end:hover,.calendar__day--range-start:hover{background:var(--accent-hover);color:var(--accent-text-on-hover)}.
|
|
216
|
+
.calendar__day--range-end:hover,.calendar__day--range-start:hover{background:var(--accent-hover);color:var(--accent-text-on-hover)}.chart{--chart-bar-fill:var(--accent);display:block;width:100%}.chart__bars{align-items:flex-end;display:flex;gap:var(--spacing-2);min-height:120px;padding:var(--spacing-4) 0}.chart__bar-wrap{align-items:center;display:flex;flex:1;flex-direction:column;gap:var(--spacing-1)}.chart__bar{background:var(--chart-bar-fill);border-radius:var(--radius-sm);max-width:2.5rem;min-height:4px;transition:height .2s ease;width:100%}.chart__label{color:var(--text-dim);font-size:var(--font-size-sm)}.command-root{position:relative}.command__overlay{background:oklch(from var(--overlay) l c h/60%);inset:0;z-index:var(--z-modal,4000)}.command__dialog,.command__overlay{animation:overlay-in .15s ease;position:fixed}.command__dialog{background:var(--background);border:1px solid var(--border);border-radius:var(--radius-lg);box-shadow:var(--shadow-lg);display:flex;flex-direction:column;left:50%;max-height:70vh;top:15%;transform:translateX(-50%);width:min(100% - var(--spacing-8),28rem);z-index:calc(var(--z-modal, 4000) + 1)}.command__search-wrap{border-bottom:1px solid var(--border);padding:var(--spacing-2)}.command__search{background:var(--background);border:1px solid var(--border);border-radius:var(--radius);color:var(--text);font-size:var(--font-size-base);padding:var(--spacing-2) var(--spacing-3);width:100%}.command__list{max-height:280px;overflow-y:auto;padding:var(--spacing-2)}.command__item{background:transparent;border:none;border-radius:var(--radius);color:var(--text);cursor:pointer;display:block;font-size:var(--font-size-sm);padding:var(--spacing-2) var(--spacing-3);text-align:left;width:100%}.command__item:hover,
|
|
217
|
+
.command__item[aria-selected="true"]{background:var(--background-alt)}.command__item kbd{color:var(--text-dim);font-size:var(--font-size-xs);margin-left:var(--spacing-2)}.direction{display:block}.direction--rtl{direction:rtl}.direction--ltr{direction:ltr}.input-otp{display:flex;gap:var(--spacing-2);justify-content:center}.input-otp__digit{background:var(--background);border:1px solid var(--border);border-radius:var(--radius);color:var(--text);font-size:var(--font-size-lg);font-variant-numeric:tabular-nums;height:2.5rem;text-align:center;width:2.5rem}.input-otp__digit:focus{outline:2px solid var(--accent);outline-offset:2px}.input-otp__digit::-moz-placeholder{color:var(--text-dim)}.input-otp__digit::placeholder{color:var(--text-dim)}.menubar{align-items:center;background:var(--background-alt);border:1px solid var(--border);border-radius:var(--radius);display:flex;gap:0;min-height:2.5rem;padding:0 var(--spacing-2)}.menubar__item{position:relative}.menubar__trigger{background:transparent;border:none;border-radius:var(--radius);color:var(--text);cursor:pointer;font-size:var(--font-size-sm);padding:var(--spacing-2) var(--spacing-3)}.menubar__menu,.menubar__trigger:hover,
|
|
218
|
+
.menubar__trigger[aria-expanded="true"]{background:var(--background)}.menubar__menu{border:1px solid var(--border);border-radius:var(--radius);box-shadow:var(--shadow-md);left:0;margin-top:var(--spacing-1);min-width:10rem;padding:var(--spacing-1);position:absolute;top:100%;z-index:100}.menubar__menu-item{background:transparent;border:none;border-radius:var(--radius);color:var(--text);cursor:pointer;display:block;font-size:var(--font-size-sm);padding:var(--spacing-2) var(--spacing-3);text-align:left;text-decoration:none;width:100%}.menubar__menu-item:hover{background:var(--background-alt)}.home{padding:var(--content-padding-y) 0}.home__container{box-sizing:border-box;margin-left:auto;margin-right:auto;max-width:var(--container-default);min-width:0;padding-left:var(--content-padding-x);padding-right:var(--content-padding-x);width:100%}.home__announcement{align-items:center;background-color:oklch(from var(--accent-fg) l c h/8%);border:var(--border-width) solid oklch(from var(--accent-fg) l c h/14%);border-radius:var(--radius-lg);color:var(--text);display:flex;flex-wrap:wrap;font-size:var(--font-size-sm);gap:var(--spacing-2);justify-content:center;margin-bottom:var(--section-spacing);padding:var(--spacing-3) var(--spacing-4);text-decoration:none;transition:background-color var(--transition-base),border-color var(--transition-base)}.home__announcement:hover{background-color:oklch(from var(--accent-fg) l c h/12%);border-color:oklch(from var(--accent-fg) l c h/20%)}.home__announcement-label{color:var(--accent-fg);font-weight:var(--font-weight-semibold)}.home__announcement-text{color:var(--text-dim)}.home__announcement-arrow{color:var(--text-dim);transition:transform var(--transition-base)}.home__announcement:hover .home__announcement-arrow{transform:translateX(var(--spacing-0-5))}.home__hero{margin-bottom:var(--section-spacing-lg);padding:var(--spacing-14) 0 var(--spacing-16);text-align:center}.home__title{color:var(--text);font-size:var(--font-size-5xl);font-weight:var(--font-weight-extrabold);line-height:var(--line-height-tight);margin:0 0 var(--spacing-6) 0}.home__subtitle{color:var(--text-dim);font-size:var(--font-size-xl);line-height:var(--line-height-relaxed);margin:0 auto var(--spacing-8) auto;max-width:var(--spacing-175)}.home__hero-ctas{display:flex;flex-wrap:wrap;gap:var(--spacing-4);justify-content:center;margin-top:var(--spacing-6)}.home__hero-cta{text-decoration:none}.home__examples-row{display:flex;flex-wrap:wrap;gap:var(--spacing-3);justify-content:center;margin-top:var(--spacing-10)}.home__example-pill{background-color:var(--background-alt);border:var(--border-width) solid var(--border);border-radius:var(--radius-full);color:var(--text);display:inline-block;font-size:var(--font-size-sm);font-weight:var(--font-weight-medium);padding:var(--spacing-2) var(--spacing-4);text-decoration:none;transition:background-color var(--transition-base),border-color var(--transition-base),color var(--transition-base)}.home__example-pill:hover{background-color:var(--background);border-color:var(--accent);color:var(--accent-fg)}.home__example-pill:focus-visible{outline:var(--outline-width) solid var(--accent);outline-offset:var(--outline-offset)}.home__showcase{margin-bottom:var(--section-spacing-lg)}.home__showcase-grid{display:grid;gap:var(--spacing-8);grid-template-columns:1fr;margin:0 auto;max-width:var(--spacing-150)}@media (width >= 768px){.home__showcase-grid{grid-template-columns:1fr 1fr;max-width:100%}}.home__showcase .home__example{margin-bottom:0}.home__showcase .home__example:last-child{grid-column:1/-1;justify-self:center;max-width:var(--spacing-80)}@media (width >= 768px){.home__showcase .home__example:last-child{grid-column:auto;max-width:100%}}.home__section-title{color:var(--text);font-size:var(--font-size-3xl);font-weight:var(--font-weight-bold);margin-bottom:var(--page-header-margin-bottom);text-align:center}.home__install{align-items:center;display:flex;flex-direction:column;justify-content:center;margin-bottom:var(--section-spacing-lg);max-width:100%;min-width:0}.home__install-grid{display:grid;gap:0;grid-template-columns:1fr;margin:0 auto;max-width:var(--spacing-150);min-width:0;width:100%}@media (width >= 768px){.home__install-grid{grid-template-columns:1fr auto 1fr;max-width:100%}}.home__install-block{align-items:stretch;background-color:var(--background-alt);border:var(--border-width) solid var(--border);border-radius:var(--radius-lg);box-sizing:border-box;display:flex;flex-direction:column;justify-content:center;min-height:var(--spacing-24);min-width:0;overflow:hidden;padding:var(--spacing-6);width:100%}.home__install-or{align-items:center;color:var(--text-dim);display:flex;font-size:var(--font-size-sm);font-weight:var(--font-weight-semibold);gap:var(--spacing-4);justify-content:center;letter-spacing:var(--letter-spacing-wider);padding:var(--spacing-4) 0}
|
|
217
219
|
.home__install-or::after,.home__install-or::before{border-top:var(--border-width) solid var(--border);content:"";flex:1;height:0}@media (width >= 768px){.home__install-or{flex-direction:column;gap:var(--spacing-4);padding:0 var(--spacing-4)}
|
|
218
220
|
.home__install-or::after,.home__install-or::before{border-left:var(--border-width) solid var(--border);border-top:none;flex:1;min-height:var(--spacing-8);width:0}}.home__install-title{color:var(--text);font-size:var(--font-size-base);font-weight:var(--font-weight-semibold);margin:0 0 var(--spacing-2) 0;text-align:center}.home__install-label{color:var(--text-dim);font-size:var(--font-size-sm);margin:0 0 var(--spacing-4) 0;text-align:center}.home__install-copy{align-items:center;display:flex;justify-content:center;width:100%}.home__install-copy .copy-to-clipboard{justify-content:space-between;width:100%}.home__install-copy .copy-to-clipboard__text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.home__cli-tabs{margin-top:var(--spacing-1)}.home__cli-tabs .cli-command-tabs__tabs,
|
|
219
221
|
.home__cli-tabs .package-install-tabs__tabs{margin-top:0}.home__cli-tabs .tabs__list{margin-bottom:var(--spacing-2);overflow-x:visible;overflow-y:visible;scrollbar-width:none}.home__cli-tabs .tabs__list::-webkit-scrollbar{display:none}.home__cli-tabs .tabs__panel{min-height:0;padding:0}.home__cli-tabs .cli-command-tabs__panel .code-block__header{padding:var(--spacing-1) var(--spacing-2)}.home__cli-tabs .cli-command-tabs__panel .code-block pre{padding:var(--spacing-2)}.home__cli-tabs .cli-command-tabs__panel .code-block,
|
|
@@ -237,7 +239,7 @@ div.navbar__link{background:none;border:none;color:inherit;cursor:pointer;font:i
|
|
|
237
239
|
#themes-preview .themes-page__preview-dropdown-menu .dropdown__item:focus-visible:not(.dropdown__item--disabled) span,#themes-preview .themes-page__preview-dropdown-menu .dropdown__item:hover:not(.dropdown__item--disabled) span,
|
|
238
240
|
#themes-preview .themes-page__preview-dropdown-menu .dropdown__item[aria-current="true"] span,
|
|
239
241
|
#themes-preview .themes-page__preview-dropdown-menu .dropdown__item[aria-current="true"]:focus-visible span,
|
|
240
|
-
#themes-preview .themes-page__preview-dropdown-menu .dropdown__item[aria-current="true"]:hover span{color:var(--accent)!important}.block-preview-wrapper{border:1px solid var(--border);border-radius:var(--radius-lg);margin:var(--spacing-6) 0;overflow:hidden}.block-preview-wrapper--hero{background:var(--background-alt);padding:
|
|
242
|
+
#themes-preview .themes-page__preview-dropdown-menu .dropdown__item[aria-current="true"]:hover span{color:var(--accent)!important}.block-preview-wrapper{border:1px solid var(--border);border-radius:var(--radius-lg);margin:var(--spacing-6) 0;overflow:hidden}.block-preview-wrapper--hero{background:var(--background-alt);padding:0}.block-preview-wrapper--pricing{background:var(--background-alt);padding:var(--spacing-6)}.block-preview-wrapper--docs{min-height:16rem}.block-preview-wrapper--dashboard{min-height:24rem}.docs-dim{color:var(--text-dim);font-size:var(--font-size-sm);margin-top:0}.landing-hero{align-items:center;background:var(--background-alt);box-sizing:border-box;display:flex;flex-direction:column;justify-content:center;min-height:28rem;padding:var(--spacing-20) var(--spacing-6);text-align:center}.landing-hero__title{color:var(--text);font-size:var(--font-size-4xl);font-weight:var(--font-weight-extrabold);line-height:var(--line-height-tight);margin:0 0 var(--spacing-4)}@media (width >= 48rem){.landing-hero__title{font-size:var(--font-size-5xl)}}.landing-hero__subtitle{color:var(--text-dim);font-size:var(--font-size-xl);line-height:var(--line-height-relaxed);margin:0 auto var(--spacing-8);max-width:var(--spacing-175)}.landing-hero__ctas{display:flex;flex-wrap:wrap;gap:var(--spacing-3);justify-content:center}.landing-features{box-sizing:border-box;margin:0 auto;max-width:var(--container-default);padding:var(--spacing-16) var(--spacing-6);width:100%}.landing-features__title{color:var(--text);font-size:var(--font-size-2xl);font-weight:var(--font-weight-bold);margin:0 0 var(--spacing-8);text-align:center}.landing-features__grid{display:grid;gap:var(--spacing-8);grid-template-columns:repeat(auto-fit,minmax(min(100%,18rem),1fr));list-style:none;margin:0;padding:0}.landing-features__item{background:var(--background);border:1px solid var(--border);border-radius:var(--radius-lg);padding:var(--spacing-6);transition:border-color var(--transition-base),box-shadow var(--transition-base)}.landing-features__item:hover{border-color:var(--accent);box-shadow:0 0 0 1px oklch(from var(--accent) l c h/15%)}.landing-features__item-title{color:var(--text);font-size:var(--font-size-lg);font-weight:var(--font-weight-semibold);margin:0 0 var(--spacing-2)}.landing-features__item-desc{color:var(--text-dim);font-size:var(--font-size-base);line-height:var(--line-height-relaxed);margin:0}.pricing-grid{display:grid;gap:var(--spacing-6);grid-template-columns:repeat(auto-fit,minmax(min(100%,16rem),1fr));margin:0 auto;max-width:56rem}.pricing-card{display:flex;flex-direction:column}.pricing-card .card__body{display:flex;flex:1;flex-direction:column}.pricing-card--featured{border-color:var(--accent);box-shadow:0 0 0 2px oklch(from var(--accent) l c h/20%)}.pricing-card__badge{align-self:flex-start;margin-bottom:var(--spacing-2)}.pricing-card__name{color:var(--text);font-size:var(--font-size-lg);font-weight:var(--font-weight-semibold);margin:0 0 var(--spacing-2)}.pricing-card__price{color:var(--text);font-size:var(--font-size-3xl);font-weight:var(--font-weight-bold);margin:0 0 var(--spacing-0-5)}.pricing-card__currency,
|
|
241
243
|
.pricing-card__period-inline{color:var(--text-dim);font-size:var(--font-size-lg);font-weight:var(--font-weight-normal)}.pricing-card__period{color:var(--text-dim);font-size:var(--font-size-sm);margin:0 0 var(--spacing-4)}.pricing-card__features{color:var(--text);flex:1;font-size:var(--font-size-sm);list-style:none;margin:0 0 var(--spacing-6);padding:0}.pricing-card__features li{padding:var(--spacing-1) 0;padding-left:var(--spacing-4);position:relative}.pricing-card__features li::before{background:var(--accent);border-radius:50%;content:"";height:.35em;left:0;position:absolute;top:.65em;width:.35em}.pricing-card__cta{justify-content:center;width:100%}.dashboard-page__header{margin-bottom:var(--spacing-6)}.dashboard-page__title{color:var(--text);font-size:var(--font-size-2xl);font-weight:var(--font-weight-bold);margin:0 0 var(--spacing-1)}.dashboard-page__subtitle{color:var(--text-dim);font-size:var(--font-size-sm);margin:0}.dashboard-page__stats-grid{display:grid;gap:var(--spacing-4);grid-template-columns:repeat(auto-fill,minmax(10rem,1fr));margin-bottom:var(--spacing-8)}.dashboard-page__stat .card__body{display:flex;flex-direction:column;gap:var(--spacing-1)}.dashboard-page__stat .card__label{color:var(--text-dim);font-size:var(--font-size-sm)}.dashboard-page__stat .card__value{color:var(--text);font-size:var(--font-size-xl);font-weight:var(--font-weight-bold)}.dashboard-page__section-title{color:var(--text);font-size:var(--font-size-lg);font-weight:var(--font-weight-semibold);margin:0 0 var(--spacing-4)}.docs-layout-demo{display:flex;min-height:16rem}.docs-layout-demo__sidebar{background:var(--background-alt);border-right:1px solid var(--border);flex-shrink:0;padding:var(--spacing-4);width:12rem}.docs-layout-demo__nav{display:flex;flex-direction:column;gap:var(--spacing-1)}.docs-layout-demo__nav-link{border-radius:var(--radius-md);color:var(--text);display:block;font-size:var(--font-size-sm);padding:var(--spacing-2) var(--spacing-3);text-decoration:none}.docs-layout-demo__nav-link:hover{background:var(--background)}.docs-layout-demo__nav-link--active{background:var(--accent);color:var(--accent-text)}.docs-layout-demo__main{flex:1;overflow:auto;padding:var(--spacing-6)}.docs-layout-demo__header{margin-bottom:var(--spacing-4)}.docs-layout-demo__title{color:var(--text);font-size:var(--font-size-2xl);font-weight:var(--font-weight-bold);margin:0 0 var(--spacing-1)}.docs-layout-demo__desc{color:var(--text-dim);margin:0}.docs-layout-demo__content{margin-top:var(--spacing-4)}.block-preview-wrapper--login,
|
|
242
244
|
.block-preview-wrapper--signup{align-items:center;background:var(--background-alt);display:flex;justify-content:center;min-height:20rem;padding:var(--spacing-16) var(--spacing-6)}.login-block,
|
|
243
245
|
.signup-block{display:flex;flex-direction:column;gap:var(--spacing-6);max-width:24rem;width:100%}.login-block__brand,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rizzo-css",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.76",
|
|
4
4
|
"engines": {
|
|
5
5
|
"node": ">=18"
|
|
6
6
|
},
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
}
|
|
21
21
|
},
|
|
22
22
|
"bin": {
|
|
23
|
-
"rizzo-css": "
|
|
23
|
+
"rizzo-css": "bin/rizzo-css.js"
|
|
24
24
|
},
|
|
25
25
|
"files": [
|
|
26
26
|
".env.example",
|
|
@@ -53,9 +53,9 @@
|
|
|
53
53
|
],
|
|
54
54
|
"repository": {
|
|
55
55
|
"type": "git",
|
|
56
|
-
"url": "https://github.com/mingleusa/rizzo-css.git"
|
|
56
|
+
"url": "git+https://github.com/mingleusa/rizzo-css.git"
|
|
57
57
|
},
|
|
58
58
|
"homepage": "https://rizzo-css.vercel.app",
|
|
59
59
|
"license": "MIT",
|
|
60
60
|
"author": "mingleusa"
|
|
61
|
-
}
|
|
61
|
+
}
|
|
@@ -13,7 +13,7 @@ interface Props {
|
|
|
13
13
|
links?: FooterLink[];
|
|
14
14
|
/** Optional class for the root element */
|
|
15
15
|
class?: string;
|
|
16
|
-
/** Optional version string (e.g. from package.json); shown as "v0.0.
|
|
16
|
+
/** Optional version string (e.g. from package.json); shown as "v0.0.76" with link to CHANGELOG */
|
|
17
17
|
version?: string;
|
|
18
18
|
}
|
|
19
19
|
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
Design system · Vanilla · Astro · Svelte
|
|
16
16
|
</pre>
|
|
17
17
|
|
|
18
|
-
Astro project with Rizzo CSS. Scaffolded with `npx rizzo-css init` when you chose **Create new** and Astro, then **Landing**, **Docs**, **Dashboard**, or **Full**. **Full** = clone of the docs site. **Landing** / **Docs** / **Dashboard** = base + component picker (all
|
|
18
|
+
Astro project with Rizzo CSS. Scaffolded with `npx rizzo-css init` when you chose **Create new** and Astro, then **Landing**, **Docs**, **Dashboard**, or **Full**. **Full** = clone of the docs site. **Landing** / **Docs** / **Dashboard** = base + component picker (all 58 or pick). Same template choice for **Add to existing** (`npx rizzo-css add`).
|
|
19
19
|
|
|
20
20
|
## Setup
|
|
21
21
|
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
Design system · Vanilla · Astro · Svelte
|
|
16
16
|
</pre>
|
|
17
17
|
|
|
18
|
-
Astro project with Rizzo CSS. Scaffolded with `npx rizzo-css init` when you chose **Create new** and Astro, then **Full** template. **Full** = clone of the Rizzo docs site (no component picker). **Landing** / **Docs** / **Dashboard** = base + component picker (all
|
|
18
|
+
Astro project with Rizzo CSS. Scaffolded with `npx rizzo-css init` when you chose **Create new** and Astro, then **Full** template. **Full** = clone of the Rizzo docs site (no component picker). **Landing** / **Docs** / **Dashboard** = base + component picker (all 58 or pick). Same template choice for **Add to existing** (`npx rizzo-css add`).
|
|
19
19
|
|
|
20
20
|
## Setup
|
|
21
21
|
|
|
@@ -7,7 +7,32 @@
|
|
|
7
7
|
<link rel="stylesheet" href="{{LINK_HREF}}" />
|
|
8
8
|
</head>
|
|
9
9
|
<body>
|
|
10
|
-
<
|
|
11
|
-
|
|
10
|
+
<main>
|
|
11
|
+
<header class="landing-hero">
|
|
12
|
+
<h1 class="landing-hero__title">Build something great</h1>
|
|
13
|
+
<p class="landing-hero__subtitle">A themeable, accessible design system. Same CSS across frameworks. Edit this page and add your own content.</p>
|
|
14
|
+
<div class="landing-hero__ctas">
|
|
15
|
+
<a href="https://rizzo-css.vercel.app/docs/getting-started" class="btn btn-primary">Get started</a>
|
|
16
|
+
<a href="https://rizzo-css.vercel.app/docs/components" class="btn btn-outline">View components</a>
|
|
17
|
+
</div>
|
|
18
|
+
</header>
|
|
19
|
+
<section class="landing-features" aria-labelledby="features-heading">
|
|
20
|
+
<h2 id="features-heading" class="landing-features__title">Why use Rizzo CSS</h2>
|
|
21
|
+
<ul class="landing-features__grid">
|
|
22
|
+
<li class="landing-features__item">
|
|
23
|
+
<h3 class="landing-features__item-title">Framework-agnostic</h3>
|
|
24
|
+
<p class="landing-features__item-desc">One design system for Vanilla, Astro, Svelte, React, and Vue. Same BEM classes and tokens everywhere.</p>
|
|
25
|
+
</li>
|
|
26
|
+
<li class="landing-features__item">
|
|
27
|
+
<h3 class="landing-features__item-title">Accessible by default</h3>
|
|
28
|
+
<p class="landing-features__item-desc">Components follow WCAG guidance: focus, ARIA, keyboard nav, and reduced motion built in.</p>
|
|
29
|
+
</li>
|
|
30
|
+
<li class="landing-features__item">
|
|
31
|
+
<h3 class="landing-features__item-title">Themable</h3>
|
|
32
|
+
<p class="landing-features__item-desc">Light, dark, and custom themes via CSS variables. No runtime lock-in.</p>
|
|
33
|
+
</li>
|
|
34
|
+
</ul>
|
|
35
|
+
</section>
|
|
36
|
+
</main>
|
|
12
37
|
</body>
|
|
13
38
|
</html>
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
interface ChartDataItem {
|
|
3
|
+
label: string;
|
|
4
|
+
value: number;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
interface Props {
|
|
8
|
+
data?: ChartDataItem[];
|
|
9
|
+
class?: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
let {
|
|
13
|
+
data = [
|
|
14
|
+
{ label: 'A', value: 40 },
|
|
15
|
+
{ label: 'B', value: 65 },
|
|
16
|
+
{ label: 'C', value: 30 },
|
|
17
|
+
],
|
|
18
|
+
class: className = '',
|
|
19
|
+
}: Props = $props();
|
|
20
|
+
|
|
21
|
+
const max = $derived(Math.max(1, ...data.map((d) => d.value)));
|
|
22
|
+
const ariaLabel = $derived(`Bar chart: ${data.map((d) => `${d.label} ${d.value}`).join(', ')}`);
|
|
23
|
+
</script>
|
|
24
|
+
|
|
25
|
+
<div class="chart {className}" role="img" aria-label={ariaLabel}>
|
|
26
|
+
<div class="chart__bars">
|
|
27
|
+
{#each data as d (d.label)}
|
|
28
|
+
<div class="chart__bar-wrap">
|
|
29
|
+
<div class="chart__bar" style="height: {(d.value / max) * 100}%" />
|
|
30
|
+
<span class="chart__label">{d.label}</span>
|
|
31
|
+
</div>
|
|
32
|
+
{/each}
|
|
33
|
+
</div>
|
|
34
|
+
</div>
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
interface CommandItem {
|
|
3
|
+
id: string;
|
|
4
|
+
label: string;
|
|
5
|
+
shortcut?: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
interface Props {
|
|
9
|
+
triggerLabel?: string;
|
|
10
|
+
searchPlaceholder?: string;
|
|
11
|
+
items?: CommandItem[];
|
|
12
|
+
class?: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
let {
|
|
16
|
+
triggerLabel = 'Open command palette (⌘K)',
|
|
17
|
+
searchPlaceholder = 'Search…',
|
|
18
|
+
items = [],
|
|
19
|
+
class: className = '',
|
|
20
|
+
}: Props = $props();
|
|
21
|
+
|
|
22
|
+
let open = $state(false);
|
|
23
|
+
let query = $state('');
|
|
24
|
+
let selectedIndex = $state(0);
|
|
25
|
+
let searchEl: HTMLInputElement;
|
|
26
|
+
|
|
27
|
+
const filtered = $derived(items.filter((item) => item.label.toLowerCase().includes(query.toLowerCase())));
|
|
28
|
+
|
|
29
|
+
$effect(() => {
|
|
30
|
+
if (filtered.length) selectedIndex = 0;
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
function close() {
|
|
34
|
+
open = false;
|
|
35
|
+
query = '';
|
|
36
|
+
selectedIndex = 0;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function onKey(e: KeyboardEvent) {
|
|
40
|
+
if (e.key === 'Escape') close();
|
|
41
|
+
if ((e.metaKey || e.ctrlKey) && e.key === 'k') {
|
|
42
|
+
e.preventDefault();
|
|
43
|
+
open = !open;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
$effect(() => {
|
|
48
|
+
if (!open) return;
|
|
49
|
+
document.addEventListener('keydown', onKey);
|
|
50
|
+
queueMicrotask(() => searchEl?.focus());
|
|
51
|
+
return () => document.removeEventListener('keydown', onKey);
|
|
52
|
+
});
|
|
53
|
+
</script>
|
|
54
|
+
|
|
55
|
+
<div class="command-root {className}">
|
|
56
|
+
<button type="button" class="btn btn-outline" onclick={() => (open = true)} aria-haspopup="dialog" aria-expanded={open}>
|
|
57
|
+
{triggerLabel}
|
|
58
|
+
</button>
|
|
59
|
+
{#if open}
|
|
60
|
+
<div class="command__overlay" aria-hidden="false" role="presentation" onclick={close}></div>
|
|
61
|
+
<div class="command__dialog" role="dialog" aria-modal="true" aria-label="Command palette">
|
|
62
|
+
<div class="command__search-wrap">
|
|
63
|
+
<input
|
|
64
|
+
type="search"
|
|
65
|
+
class="command__search"
|
|
66
|
+
placeholder={searchPlaceholder}
|
|
67
|
+
autocomplete="off"
|
|
68
|
+
bind:value={query}
|
|
69
|
+
bind:this={searchEl}
|
|
70
|
+
/>
|
|
71
|
+
</div>
|
|
72
|
+
<div class="command__list" role="listbox">
|
|
73
|
+
{#each filtered as item, i}
|
|
74
|
+
<button
|
|
75
|
+
type="button"
|
|
76
|
+
class="command__item"
|
|
77
|
+
role="option"
|
|
78
|
+
aria-selected={i === selectedIndex}
|
|
79
|
+
onclick={close}
|
|
80
|
+
onmouseenter={() => (selectedIndex = i)}
|
|
81
|
+
>
|
|
82
|
+
{item.label}
|
|
83
|
+
{#if item.shortcut}<kbd>{item.shortcut}</kbd>{/if}
|
|
84
|
+
</button>
|
|
85
|
+
{/each}
|
|
86
|
+
</div>
|
|
87
|
+
</div>
|
|
88
|
+
{/if}
|
|
89
|
+
</div>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
|
|
4
|
+
interface Props {
|
|
5
|
+
dir?: 'ltr' | 'rtl';
|
|
6
|
+
class?: string;
|
|
7
|
+
children?: Snippet;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
let { dir = 'ltr', class: className = '', children }: Props = $props();
|
|
11
|
+
|
|
12
|
+
const dirClass = $derived(dir === 'rtl' ? 'direction--rtl' : 'direction--ltr');
|
|
13
|
+
</script>
|
|
14
|
+
|
|
15
|
+
<div class="direction {dirClass} {className}" {dir}>
|
|
16
|
+
{@render children?.()}
|
|
17
|
+
</div>
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
interface Props {
|
|
3
|
+
length?: number;
|
|
4
|
+
ariaLabel?: string;
|
|
5
|
+
class?: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
let { length = 6, ariaLabel = 'One-time code', class: className = '' }: Props = $props();
|
|
9
|
+
|
|
10
|
+
const indices = $derived(Array.from({ length }, (_, i) => i));
|
|
11
|
+
let digits = $state<string[]>(Array(length).fill(''));
|
|
12
|
+
let containerEl: HTMLDivElement;
|
|
13
|
+
|
|
14
|
+
function inputs() {
|
|
15
|
+
return containerEl?.querySelectorAll<HTMLInputElement>('.input-otp__digit') ?? [];
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function handleInput(i: number, e: Event) {
|
|
19
|
+
const v = (e.target as HTMLInputElement).value.replace(/\D/g, '').slice(-1);
|
|
20
|
+
digits = [...digits];
|
|
21
|
+
digits[i] = v;
|
|
22
|
+
if (v && i < length - 1) inputs()[i + 1]?.focus();
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function handleKeyDown(i: number, e: KeyboardEvent) {
|
|
26
|
+
if (e.key === 'Backspace' && !digits[i] && i > 0) inputs()[i - 1]?.focus();
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function handlePaste(e: ClipboardEvent) {
|
|
30
|
+
e.preventDefault();
|
|
31
|
+
const pasted = (e.clipboardData?.getData('text') || '').replace(/\D/g, '').slice(0, length);
|
|
32
|
+
const next = [...digits];
|
|
33
|
+
pasted.split('').forEach((ch, j) => {
|
|
34
|
+
if (next[j] !== undefined) next[j] = ch;
|
|
35
|
+
});
|
|
36
|
+
digits = next;
|
|
37
|
+
const focusIdx = Math.min(pasted.length, length) - 1;
|
|
38
|
+
inputs()[focusIdx]?.focus();
|
|
39
|
+
}
|
|
40
|
+
</script>
|
|
41
|
+
|
|
42
|
+
<div class="input-otp {className}" role="group" aria-label={ariaLabel} bind:this={containerEl}>
|
|
43
|
+
{#each indices as i}
|
|
44
|
+
<input
|
|
45
|
+
type="text"
|
|
46
|
+
inputmode="numeric"
|
|
47
|
+
maxlength="1"
|
|
48
|
+
autocomplete="one-time-code"
|
|
49
|
+
class="input-otp__digit"
|
|
50
|
+
aria-label="Digit {i + 1} of {length}"
|
|
51
|
+
value={digits[i]}
|
|
52
|
+
oninput={(e) => handleInput(i, e)}
|
|
53
|
+
onkeydown={(e) => handleKeyDown(i, e)}
|
|
54
|
+
onpaste={handlePaste}
|
|
55
|
+
/>
|
|
56
|
+
{/each}
|
|
57
|
+
</div>
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
interface MenubarMenuItem {
|
|
3
|
+
label: string;
|
|
4
|
+
href?: string;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
interface MenubarItem {
|
|
8
|
+
label: string;
|
|
9
|
+
menu: MenubarMenuItem[];
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
interface Props {
|
|
13
|
+
items?: MenubarItem[];
|
|
14
|
+
class?: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
let {
|
|
18
|
+
items = [
|
|
19
|
+
{ label: 'File', menu: [{ label: 'New', href: '#' }, { label: 'Open', href: '#' }] },
|
|
20
|
+
{ label: 'Edit', menu: [{ label: 'Undo', href: '#' }] },
|
|
21
|
+
],
|
|
22
|
+
class: className = '',
|
|
23
|
+
}: Props = $props();
|
|
24
|
+
|
|
25
|
+
let openIndex = $state<number | null>(null);
|
|
26
|
+
let navRef: HTMLElement;
|
|
27
|
+
|
|
28
|
+
function close(e?: MouseEvent) {
|
|
29
|
+
if (e && navRef && navRef.contains(e.target as Node)) return;
|
|
30
|
+
openIndex = null;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
$effect(() => {
|
|
34
|
+
if (openIndex === null) return;
|
|
35
|
+
const onClose = (e: MouseEvent) => close(e);
|
|
36
|
+
const onKey = (e: KeyboardEvent) => {
|
|
37
|
+
if (e.key === 'Escape') openIndex = null;
|
|
38
|
+
};
|
|
39
|
+
const t = setTimeout(() => document.addEventListener('click', onClose), 0);
|
|
40
|
+
document.addEventListener('keydown', onKey);
|
|
41
|
+
return () => {
|
|
42
|
+
clearTimeout(t);
|
|
43
|
+
document.removeEventListener('click', onClose);
|
|
44
|
+
document.removeEventListener('keydown', onKey);
|
|
45
|
+
};
|
|
46
|
+
});
|
|
47
|
+
</script>
|
|
48
|
+
|
|
49
|
+
<nav bind:this={navRef} class="menubar {className}" role="menubar" aria-label="Main menu">
|
|
50
|
+
{#each items as item, i}
|
|
51
|
+
<div class="menubar__item" role="none">
|
|
52
|
+
<button
|
|
53
|
+
type="button"
|
|
54
|
+
role="menuitem"
|
|
55
|
+
class="menubar__trigger"
|
|
56
|
+
aria-haspopup="true"
|
|
57
|
+
aria-expanded={openIndex === i}
|
|
58
|
+
onclick={() => (openIndex = openIndex === i ? null : i)}
|
|
59
|
+
>
|
|
60
|
+
{item.label}
|
|
61
|
+
</button>
|
|
62
|
+
<div
|
|
63
|
+
class="menubar__menu"
|
|
64
|
+
role="menu"
|
|
65
|
+
aria-label={item.label}
|
|
66
|
+
hidden={openIndex !== i}
|
|
67
|
+
>
|
|
68
|
+
{#each item.menu as entry}
|
|
69
|
+
{#if entry.href}
|
|
70
|
+
<a href={entry.href} class="menubar__menu-item" role="menuitem">{entry.label}</a>
|
|
71
|
+
{:else}
|
|
72
|
+
<button type="button" class="menubar__menu-item" role="menuitem" onclick={() => (openIndex = null)}>{entry.label}</button>
|
|
73
|
+
{/if}
|
|
74
|
+
{/each}
|
|
75
|
+
</div>
|
|
76
|
+
</div>
|
|
77
|
+
{/each}
|
|
78
|
+
</nav>
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
Design system · Vanilla · Astro · Svelte
|
|
16
16
|
</pre>
|
|
17
17
|
|
|
18
|
-
SvelteKit project with Rizzo CSS. Scaffolded with `npx rizzo-css init` when you chose **Create new** and Svelte, then **Landing**, **Docs**, **Dashboard**, or **Full**. **Full** = clone of the docs site. **Landing** / **Docs** / **Dashboard** = base + component picker (all
|
|
18
|
+
SvelteKit project with Rizzo CSS. Scaffolded with `npx rizzo-css init` when you chose **Create new** and Svelte, then **Landing**, **Docs**, **Dashboard**, or **Full**. **Full** = clone of the docs site. **Landing** / **Docs** / **Dashboard** = base + component picker (all 58 or pick). Same template choice for **Add to existing** (`npx rizzo-css add`).
|
|
19
19
|
|
|
20
20
|
## Setup
|
|
21
21
|
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
Design system · Vanilla · Astro · Svelte
|
|
16
16
|
</pre>
|
|
17
17
|
|
|
18
|
-
SvelteKit project with Rizzo CSS. Scaffolded with `npx rizzo-css init` when you chose **Create new** and Svelte, then **Full** template. **Full** = clone of the Rizzo docs site (no component picker). **Landing** / **Docs** / **Dashboard** = base + component picker (all
|
|
18
|
+
SvelteKit project with Rizzo CSS. Scaffolded with `npx rizzo-css init` when you chose **Create new** and Svelte, then **Full** template. **Full** = clone of the Rizzo docs site (no component picker). **Landing** / **Docs** / **Dashboard** = base + component picker (all 58 or pick). Same template choice for **Add to existing** (`npx rizzo-css add`).
|
|
19
19
|
|
|
20
20
|
## Setup
|
|
21
21
|
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
Design system · Vanilla · Astro · Svelte
|
|
16
16
|
</pre>
|
|
17
17
|
|
|
18
|
-
This project was scaffolded with `npx rizzo-css init` when you chose **Create new project** and Vanilla JS, then **Landing**, **Docs**, **Dashboard**, or **Full**. **Full** = clone of the docs site. **Landing** / **Docs** / **Dashboard** = CSS, fonts, icons, sfx + component picker (all
|
|
18
|
+
This project was scaffolded with `npx rizzo-css init` when you chose **Create new project** and Vanilla JS, then **Landing**, **Docs**, **Dashboard**, or **Full**. **Full** = clone of the docs site. **Landing** / **Docs** / **Dashboard** = CSS, fonts, icons, sfx + component picker (all 58 or pick); Landing adds hero/features; Docs adds sidebar + sample doc; Dashboard adds sidebar + stats/table. **Add to existing project** (or `npx rizzo-css add`) uses the **same template choice**; you must add the stylesheet `<link>` yourself (CLI prints the exact tag).
|
|
19
19
|
|
|
20
20
|
## First-time setup
|
|
21
21
|
|
|
@@ -28,7 +28,7 @@ If you prefer to load CSS from a CDN instead of the local file, replace the `<li
|
|
|
28
28
|
- `<link rel="stylesheet" href="https://unpkg.com/rizzo-css@latest/dist/rizzo.min.css" />`
|
|
29
29
|
- Or jsDelivr: `https://cdn.jsdelivr.net/npm/rizzo-css@latest/dist/rizzo.min.css`
|
|
30
30
|
|
|
31
|
-
(Replace `@latest` with a specific version, e.g. `@0.0.
|
|
31
|
+
(Replace `@latest` with a specific version, e.g. `@0.0.76`, in production.)
|
|
32
32
|
|
|
33
33
|
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.
|
|
34
34
|
|