@krizaka/ui 2.1.0 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -9
- package/dist/{button-Cgfkg_3y.d.ts → button-BMAO7dKF.d.ts} +29 -2
- package/dist/button.d.ts +32 -5
- package/dist/button.js +62 -9
- package/dist/button.js.map +1 -1
- package/dist/chip-link.d.ts +53 -0
- package/dist/chip-link.js +32 -0
- package/dist/chip-link.js.map +1 -0
- package/dist/chunk-43PTCDTL.js +31 -0
- package/dist/chunk-43PTCDTL.js.map +1 -0
- package/dist/chunk-6ISW63JI.js +11 -0
- package/dist/chunk-6ISW63JI.js.map +1 -0
- package/dist/chunk-HAQWKORZ.js +117 -0
- package/dist/chunk-HAQWKORZ.js.map +1 -0
- package/dist/{chunk-FHYZSO2S.js → chunk-R6SDS7JM.js} +5 -3
- package/dist/chunk-R6SDS7JM.js.map +1 -0
- package/dist/chunk-RUPNPMP3.js +103 -0
- package/dist/chunk-RUPNPMP3.js.map +1 -0
- package/dist/chunk-VDR2EP6K.js +49 -0
- package/dist/chunk-VDR2EP6K.js.map +1 -0
- package/dist/chunk-WEVYKZIF.js +33 -0
- package/dist/chunk-WEVYKZIF.js.map +1 -0
- package/dist/command.d.ts +7 -7
- package/dist/command.js +3 -2
- package/dist/command.js.map +1 -1
- package/dist/confirm-button.d.ts +1 -1
- package/dist/confirm-button.js +2 -1
- package/dist/confirm-button.js.map +1 -1
- package/dist/{dialog-GQ4Nvuyf.d.ts → dialog-D42QwYb_.d.ts} +11 -1
- package/dist/dialog.d.ts +1 -1
- package/dist/dialog.js +3 -2
- package/dist/dialog.js.map +1 -1
- package/dist/glow-card.d.ts +20 -0
- package/dist/glow-card.js +30 -0
- package/dist/glow-card.js.map +1 -0
- package/dist/index.d.ts +2 -20
- package/dist/index.js +7 -64
- package/dist/index.js.map +1 -1
- package/dist/iso.d.ts +400 -0
- package/dist/iso.js +363 -0
- package/dist/iso.js.map +1 -0
- package/dist/loader.d.ts +206 -0
- package/dist/loader.js +138 -0
- package/dist/loader.js.map +1 -0
- package/dist/marquee.d.ts +33 -0
- package/dist/marquee.js +52 -0
- package/dist/marquee.js.map +1 -0
- package/dist/mascots.d.ts +40 -0
- package/dist/mascots.js +253 -0
- package/dist/mascots.js.map +1 -0
- package/dist/meter.d.ts +146 -0
- package/dist/meter.js +107 -0
- package/dist/meter.js.map +1 -0
- package/dist/motion.css +394 -3
- package/dist/motion.d.ts +46 -0
- package/dist/motion.js +10 -0
- package/dist/motion.js.map +1 -0
- package/dist/native.d.ts +40 -1
- package/dist/native.js +326 -128
- package/dist/native.js.map +1 -1
- package/dist/nav-bar.d.ts +178 -0
- package/dist/nav-bar.js +157 -0
- package/dist/nav-bar.js.map +1 -0
- package/dist/number-ticker.d.ts +32 -0
- package/dist/number-ticker.js +61 -0
- package/dist/number-ticker.js.map +1 -0
- package/dist/progress.d.ts +56 -1
- package/dist/progress.js +72 -25
- package/dist/progress.js.map +1 -1
- package/dist/skeleton.d.ts +18 -3
- package/dist/skeleton.js +9 -1
- package/dist/skeleton.js.map +1 -1
- package/dist/spinner.d.ts +21 -5
- package/dist/spinner.js +13 -12
- package/dist/spinner.js.map +1 -1
- package/dist/stepper.d.ts +112 -0
- package/dist/stepper.js +67 -0
- package/dist/stepper.js.map +1 -0
- package/dist/tabs.d.ts +1 -1
- package/dist/tabs.js +14 -8
- package/dist/tabs.js.map +1 -1
- package/dist/theme.d.ts +1 -1
- package/dist/theme.js +2 -1
- package/dist/theme.js.map +1 -1
- package/dist/toast.d.ts +39 -4
- package/dist/toast.js +81 -7
- package/dist/toast.js.map +1 -1
- package/package.json +159 -9
- package/registry/alert.json +1 -1
- package/registry/avatar.json +1 -1
- package/registry/badge.json +1 -1
- package/registry/button.json +232 -26
- package/registry/card.json +1 -1
- package/registry/checkbox.json +1 -1
- package/registry/chip-link.json +158 -0
- package/registry/chip.json +1 -1
- package/registry/command.json +1 -1
- package/registry/confirm-button.json +91 -7
- package/registry/countdown.json +1 -1
- package/registry/dialog.json +15 -7
- package/registry/dropdown-menu.json +1 -1
- package/registry/empty-state.json +1 -1
- package/registry/examples/button/error.js +11 -0
- package/registry/examples/button/error.tsx +10 -0
- package/registry/examples/button/loading.tsx +1 -1
- package/registry/examples/button/save-flow.d.ts +4 -0
- package/registry/examples/button/save-flow.js +28 -0
- package/registry/examples/button/save-flow.tsx +24 -0
- package/registry/examples/button/signature.d.ts +4 -0
- package/registry/examples/button/signature.js +17 -0
- package/registry/examples/button/signature.tsx +19 -0
- package/registry/examples/button/upload-progress.d.ts +4 -0
- package/registry/examples/button/upload-progress.js +23 -0
- package/registry/examples/button/upload-progress.tsx +26 -0
- package/registry/examples/chip-link/filters.d.ts +4 -0
- package/registry/examples/chip-link/filters.js +12 -0
- package/registry/examples/chip-link/filters.tsx +17 -0
- package/registry/examples/dialog/left.d.ts +4 -0
- package/registry/examples/dialog/left.js +22 -0
- package/registry/examples/dialog/left.tsx +32 -0
- package/registry/examples/glow-card/link-card.d.ts +4 -0
- package/registry/examples/glow-card/link-card.js +14 -0
- package/registry/examples/glow-card/link-card.tsx +13 -0
- package/registry/examples/glow-card/plans.d.ts +4 -0
- package/registry/examples/glow-card/plans.js +25 -0
- package/registry/examples/glow-card/plans.tsx +26 -0
- package/registry/examples/glow-card/spotlight.d.ts +4 -0
- package/registry/examples/glow-card/spotlight.js +14 -0
- package/registry/examples/glow-card/spotlight.tsx +15 -0
- package/registry/examples/iso/compose.d.ts +4 -0
- package/registry/examples/iso/compose.js +22 -0
- package/registry/examples/iso/compose.tsx +19 -0
- package/registry/examples/iso/orazaka-hero.d.ts +4 -0
- package/registry/examples/iso/orazaka-hero.js +26 -0
- package/registry/examples/iso/orazaka-hero.tsx +21 -0
- package/registry/examples/iso/orochia-hero.d.ts +4 -0
- package/registry/examples/iso/orochia-hero.js +29 -0
- package/registry/examples/iso/orochia-hero.tsx +23 -0
- package/registry/examples/iso/still.d.ts +4 -0
- package/registry/examples/iso/still.js +21 -0
- package/registry/examples/iso/still.tsx +15 -0
- package/registry/examples/loader/endings.d.ts +4 -0
- package/registry/examples/loader/endings.js +14 -0
- package/registry/examples/loader/endings.tsx +11 -0
- package/registry/examples/loader/fetch-flow.d.ts +4 -0
- package/registry/examples/loader/fetch-flow.js +24 -0
- package/registry/examples/loader/fetch-flow.tsx +24 -0
- package/registry/examples/loader/minimal.d.ts +4 -0
- package/registry/examples/loader/minimal.js +11 -0
- package/registry/examples/loader/minimal.tsx +6 -0
- package/registry/examples/loader/overlay.d.ts +4 -0
- package/registry/examples/loader/overlay.js +16 -0
- package/registry/examples/loader/overlay.tsx +13 -0
- package/registry/examples/loader/region-handover.d.ts +4 -0
- package/registry/examples/loader/region-handover.js +42 -0
- package/registry/examples/loader/region-handover.tsx +29 -0
- package/registry/examples/loader/upload-eta.d.ts +4 -0
- package/registry/examples/loader/upload-eta.js +11 -0
- package/registry/examples/loader/upload-eta.tsx +10 -0
- package/registry/examples/marquee/cards.d.ts +4 -0
- package/registry/examples/marquee/cards.js +23 -0
- package/registry/examples/marquee/cards.tsx +21 -0
- package/registry/examples/marquee/logos.d.ts +4 -0
- package/registry/examples/marquee/logos.js +12 -0
- package/registry/examples/marquee/logos.tsx +17 -0
- package/registry/examples/mascots/empty-state.d.ts +4 -0
- package/registry/examples/mascots/empty-state.js +24 -0
- package/registry/examples/mascots/empty-state.tsx +18 -0
- package/registry/examples/mascots/flock.d.ts +4 -0
- package/registry/examples/mascots/flock.js +14 -0
- package/registry/examples/mascots/flock.tsx +15 -0
- package/registry/examples/mascots/long-task.d.ts +4 -0
- package/registry/examples/mascots/long-task.js +18 -0
- package/registry/examples/mascots/long-task.tsx +15 -0
- package/registry/examples/mascots/moods.d.ts +4 -0
- package/registry/examples/mascots/moods.js +14 -0
- package/registry/examples/mascots/moods.tsx +15 -0
- package/registry/examples/mascots/native/default.d.ts +4 -0
- package/registry/examples/mascots/native/default.dark.png +0 -0
- package/registry/examples/mascots/native/default.js +25 -0
- package/registry/examples/mascots/native/default.light.png +0 -0
- package/registry/examples/mascots/native/default.tsx +22 -0
- package/registry/examples/mascots/own-tone.d.ts +4 -0
- package/registry/examples/mascots/own-tone.js +11 -0
- package/registry/examples/mascots/own-tone.tsx +12 -0
- package/registry/examples/meter/balance.d.ts +4 -0
- package/registry/examples/meter/balance.js +14 -0
- package/registry/examples/meter/balance.tsx +15 -0
- package/registry/examples/meter/quota.d.ts +4 -0
- package/registry/examples/meter/quota.js +15 -0
- package/registry/examples/meter/quota.tsx +12 -0
- package/registry/examples/meter/split.d.ts +4 -0
- package/registry/examples/meter/split.js +18 -0
- package/registry/examples/meter/split.tsx +18 -0
- package/registry/examples/nav-bar/app-bar.d.ts +4 -0
- package/registry/examples/nav-bar/app-bar.js +22 -0
- package/registry/examples/nav-bar/app-bar.tsx +21 -0
- package/registry/examples/nav-bar/menu-open.d.ts +4 -0
- package/registry/examples/nav-bar/menu-open.js +26 -0
- package/registry/examples/nav-bar/menu-open.tsx +26 -0
- package/registry/examples/nav-bar/site.d.ts +4 -0
- package/registry/examples/nav-bar/site.js +31 -0
- package/registry/examples/nav-bar/site.tsx +36 -0
- package/registry/examples/number-ticker/gradient.d.ts +4 -0
- package/registry/examples/number-ticker/gradient.js +11 -0
- package/registry/examples/number-ticker/gradient.tsx +10 -0
- package/registry/examples/number-ticker/live-total.d.ts +4 -0
- package/registry/examples/number-ticker/live-total.js +17 -0
- package/registry/examples/number-ticker/live-total.tsx +21 -0
- package/registry/examples/number-ticker/stats.d.ts +4 -0
- package/registry/examples/number-ticker/stats.js +19 -0
- package/registry/examples/number-ticker/stats.tsx +23 -0
- package/registry/examples/progress/buffer.d.ts +4 -0
- package/registry/examples/progress/buffer.js +11 -0
- package/registry/examples/progress/buffer.tsx +10 -0
- package/registry/examples/progress/statuses.d.ts +4 -0
- package/registry/examples/progress/statuses.js +14 -0
- package/registry/examples/progress/statuses.tsx +11 -0
- package/registry/examples/progress/steps.d.ts +4 -0
- package/registry/examples/progress/steps.js +14 -0
- package/registry/examples/progress/steps.tsx +13 -0
- package/registry/examples/progress/upload.d.ts +4 -0
- package/registry/examples/progress/upload.js +11 -0
- package/registry/examples/progress/upload.tsx +10 -0
- package/registry/examples/skeleton/paragraph.d.ts +4 -0
- package/registry/examples/skeleton/paragraph.js +14 -0
- package/registry/examples/skeleton/paragraph.tsx +12 -0
- package/registry/examples/skeleton/shape-of-content.d.ts +4 -0
- package/registry/examples/skeleton/shape-of-content.js +23 -0
- package/registry/examples/skeleton/shape-of-content.tsx +26 -0
- package/registry/examples/spinner/default.js +5 -2
- package/registry/examples/spinner/default.tsx +7 -1
- package/registry/examples/spinner/sizes.js +2 -1
- package/registry/examples/spinner/sizes.tsx +2 -0
- package/registry/examples/spinner/value.d.ts +4 -0
- package/registry/examples/spinner/value.js +11 -0
- package/registry/examples/spinner/value.tsx +12 -0
- package/registry/examples/stepper/checkout.d.ts +4 -0
- package/registry/examples/stepper/checkout.js +22 -0
- package/registry/examples/stepper/checkout.tsx +17 -0
- package/registry/examples/stepper/failed.d.ts +4 -0
- package/registry/examples/stepper/failed.js +26 -0
- package/registry/examples/stepper/failed.tsx +21 -0
- package/registry/examples/stepper/job.d.ts +4 -0
- package/registry/examples/stepper/job.js +32 -0
- package/registry/examples/stepper/job.tsx +28 -0
- package/registry/examples/toast/grouped.d.ts +4 -0
- package/registry/examples/toast/grouped.js +21 -0
- package/registry/examples/toast/grouped.tsx +23 -0
- package/registry/examples/toast/undo.d.ts +4 -0
- package/registry/examples/toast/undo.js +29 -0
- package/registry/examples/toast/undo.tsx +30 -0
- package/registry/examples/toast/upload-progress.d.ts +4 -0
- package/registry/examples/toast/upload-progress.js +29 -0
- package/registry/examples/toast/upload-progress.tsx +31 -0
- package/registry/field.json +1 -1
- package/registry/glow-card.json +162 -0
- package/registry/index.json +207 -20
- package/registry/iso.json +1355 -0
- package/registry/kbd.json +1 -1
- package/registry/loader.json +399 -0
- package/registry/marquee.json +225 -0
- package/registry/mascots.json +314 -0
- package/registry/meter.json +324 -0
- package/registry/nav-bar.json +480 -0
- package/registry/number-ticker.json +219 -0
- package/registry/page-header.json +1 -1
- package/registry/popover.json +1 -1
- package/registry/progress.json +116 -11
- package/registry/radio-group.json +1 -1
- package/registry/section-backdrop.json +1 -1
- package/registry/separator.json +1 -1
- package/registry/skeleton.json +69 -13
- package/registry/slider.json +1 -1
- package/registry/slot.json +1 -1
- package/registry/spinner.json +91 -27
- package/registry/stat.json +1 -1
- package/registry/stepper.json +174 -0
- package/registry/switch.json +1 -1
- package/registry/tabs.json +11 -7
- package/registry/theme.json +3 -3
- package/registry/toast.json +41 -13
- package/registry/tooltip.json +1 -1
- package/dist/chunk-FHYZSO2S.js.map +0 -1
- package/dist/chunk-PESA2R4U.js +0 -51
- package/dist/chunk-PESA2R4U.js.map +0 -1
- package/registry/examples/spinner/muted.js +0 -11
- package/registry/examples/spinner/muted.tsx +0 -6
- /package/registry/examples/{spinner/muted.d.ts → button/error.d.ts} +0 -0
package/README.md
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
<div align="center">
|
|
2
2
|
|
|
3
|
-
<
|
|
3
|
+
<picture>
|
|
4
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/krizaka/.github/main/profile/assets/krizaka-dark.svg">
|
|
5
|
+
<img src="https://raw.githubusercontent.com/krizaka/.github/main/profile/assets/krizaka-light.svg" alt="Krizaka" width="96">
|
|
6
|
+
</picture>
|
|
4
7
|
|
|
5
8
|
# @krizaka/ui
|
|
6
9
|
|
|
@@ -9,7 +12,7 @@ The primitives (button, badge, avatar, field, theme, countdown…) on the semant
|
|
|
9
12
|
of Krizaka, Orazaka and Orochia, and the Krizaka motion signature — one easing, one way to enter, reveal, roll, shine
|
|
10
13
|
and open.
|
|
11
14
|
|
|
12
|
-
[](https://www.npmjs.com/package/@krizaka/ui)
|
|
13
16
|
[](https://github.com/krizaka/krizaka-ui/actions/workflows/ci.yml)
|
|
14
17
|
[](LICENSE)
|
|
15
18
|
|
|
@@ -121,18 +124,19 @@ light or a product's — is a set of tokens.
|
|
|
121
124
|
| :-- | :-- | :-- |
|
|
122
125
|
| `@krizaka/ui/cn` | `cn(...classes)` — clsx + tailwind-merge (the engine `tailwind-variants` ships) | server |
|
|
123
126
|
| `@krizaka/ui/slot` | `Slot`, `VisuallyHidden` (Radix) | server |
|
|
124
|
-
| `@krizaka/ui/button` | `Button` (`variant` primary·gradient·secondary·outline·ghost·danger, `size` sm·md·lg·icon, `shape` rounded·pill, `loading`, `asChild`), `IconButton` (`label` required), `buttonVariants` | server |
|
|
127
|
+
| `@krizaka/ui/button` | `Button` (`variant` primary·gradient·secondary·outline·ghost·danger, `size` sm·md·lg·icon, `shape` rounded·pill·cut, `loading` (the loader glyph; `indicator={false}` to draw your own), `progress`, `status` success·error, `announce`, `shimmer`, `magnetic`, `asChild`), `IconButton` (`label` required; the glyph takes the icon's place), `buttonVariants` | server |
|
|
125
128
|
| `@krizaka/ui/badge` | `Badge` (`tone` neutral·accent·success·warning·danger·scrim, `size` sm·md, `dot`, `pulse`), `badgeVariants` | server |
|
|
126
129
|
| `@krizaka/ui/avatar` | `Avatar` (`src`, `alt`, `fallback`, `size` xs·sm·md·lg·xl), `Avatar.Group` (`max`) | client |
|
|
127
130
|
| `@krizaka/ui/field` | `Field.Root/Label/Hint/Error`, `Input`, `Textarea`, `Select` (native, styled) — `invalid` | server |
|
|
128
131
|
| `@krizaka/ui/theme` | `ThemeScript` (in `<head>`, no flash), `ThemeProvider`, `useTheme()` → `{ mode, setMode, theme, setTheme }`, `ThemeToggle` (`label`) | client |
|
|
129
|
-
| `@krizaka/ui/skeleton` | `Skeleton` (`shape` text·circle·rect) | server |
|
|
132
|
+
| `@krizaka/ui/skeleton` | `Skeleton` (`shape` text·circle·rect), `SkeletonText` (`lines`), `SkeletonShape` (the real component turned into its skeleton; `data-skeleton` marks a shape) — one brand reflection across the page | server |
|
|
130
133
|
| `@krizaka/ui/empty-state` | `EmptyState` (`icon`, `title`, `description`, `action`) | server |
|
|
131
|
-
| `@krizaka/ui/spinner` | `Spinner` (`label`, `size`) | server |
|
|
134
|
+
| `@krizaka/ui/spinner` | `Spinner` (`label`, `size`, `value`): the Krizaka glyph (a hexagon traced by light around a node), `LoaderGlyph` (`state` loading·success·error, `value`) | server |
|
|
135
|
+
| `@krizaka/ui/loader` | `Loader` (`label`, `status` loading·success·error, `successLabel`, `errorLabel`, `value`, `eta`, `delay` 250, `minDuration` 600, `endDuration` 1600, `variant` inline·block·overlay·page), `LoadingRegion` (`loading`, `skeleton`, `label`, `slowLabel`, `slowAfter`), `useDelayedWait` | client |
|
|
132
136
|
| `@krizaka/ui/countdown` | `Countdown` (`target`, `label`, `showLabel`, `units`, `size`, `urgentBelowMs`, `skewMs`), `useCountdown`, `splitDuration` | client |
|
|
133
137
|
| `@krizaka/ui/card` | `Card.Root` (`asChild`, `reveal`, `radius` md·lg·xl, `tone` default·elevated·glass, `interactive`), `Card.Media` (`aspect` video·square·portrait·auto), `Card.Image` (`fallback`), `Card.Overlay` (`corner`), `Card.Body` (`padding`), `Card.Title` (`as`), `Card.Description`, `Card.Stat` (`label`), `Card.Footer`; `card` (the slots) | server |
|
|
134
|
-
| `@krizaka/ui/dialog` | `Dialog.Root/Trigger/Content/Header/Title/Description/Body/Footer/Close` (`placement` center·bottom·right, `size` sm·md·lg, `closeLabel` required unless `hideClose`, `dismissible={false}`: no close on Escape or outside click), `Sheet` (= `placement="bottom"`), `AlertDialog` (`title`, `description`, `confirmLabel`, `cancelLabel`, `tone` danger·primary, async `onConfirm`, `trigger`) | client |
|
|
135
|
-
| `@krizaka/ui/toast` | `Toaster` (sonner styled by roles: `label`, `closeLabel`, `position`, `closeButton`; `richColors` off), `toast` (`.success/.warning/.error/.info/.custom`…) | client |
|
|
138
|
+
| `@krizaka/ui/dialog` | `Dialog.Root/Trigger/Content/Header/Title/Description/Body/Footer/Close` (`placement` center·bottom·right·left, `size` sm·md·lg, `closeLabel` required unless `hideClose`, `dismissible={false}`: no close on Escape or outside click), `Sheet` (= `placement="bottom"`), `AlertDialog` (`title`, `description`, `confirmLabel`, `cancelLabel`, `tone` danger·primary, async `onConfirm`, `trigger`) | client |
|
|
139
|
+
| `@krizaka/ui/toast` | `Toaster` (sonner styled by roles: `label`, `closeLabel`, `position`, `closeButton`; `richColors` off; a hairline counts each toast's time left), `toast` (`.success/.warning/.error/.info/.custom`…), `undoToast` (`undoLabel`, `onUndo`, `onCommit`), `progressToast` (`id`, `value`, `doneMessage`), `groupedToast` (`key`, `countLabel`) | client |
|
|
136
140
|
| `@krizaka/ui/popover` | `Popover.Root/Trigger/Anchor/Content/Close` | client |
|
|
137
141
|
| `@krizaka/ui/dropdown-menu` | `DropdownMenu.Root/Trigger/Content/Item/CheckboxItem/Label/Separator/Group` (`Item` `tone` default·danger), `menu` (the slots) | client |
|
|
138
142
|
| `@krizaka/ui/tooltip` | `Tooltip` (`content`, `delayDuration` 300, `side`, `open`/`defaultOpen`), `TooltipProvider` | client |
|
|
@@ -141,16 +145,26 @@ light or a product's — is a set of tokens.
|
|
|
141
145
|
| `@krizaka/ui/alert` | `Alert` (`tone` info·success·warning·danger, `icon`, `title`, `action`; `role="alert"` for danger and warning, `status` otherwise), `alertVariants` | server |
|
|
142
146
|
| `@krizaka/ui/separator` | `Separator` (`orientation`, `decorative`, Radix), `separatorVariants` | server |
|
|
143
147
|
| `@krizaka/ui/kbd` | `Kbd` (`size` sm·md), `kbdVariants` | server |
|
|
144
|
-
| `@krizaka/ui/tabs` | `Tabs.Root/List/Trigger/Content` (`variant` underline·segmented·pills on the root, `orientation`, `value`/`defaultValue` + `onValueChange
|
|
148
|
+
| `@krizaka/ui/tabs` | `Tabs.Root/List/Trigger/Content` (`variant` underline·segmented·pills on the root, `orientation`, `value`/`defaultValue` + `onValueChange`; one light glides to the active tab), `tabs` (the slots) | client |
|
|
149
|
+
| `@krizaka/ui/nav-bar` | `NavBar.Root` (`label`, `compactAfter`, `floating`) `/Brand/Items/Link` (`active`) `/Menu` (`label`, `columns`) `/MenuLink` (`title`, `description`, `icon`) `/Actions/Mobile` (`openLabel`, `closeLabel`) `/MobileLink`, `navBar` (the slots) | client |
|
|
145
150
|
| `@krizaka/ui/chip` | `Chip` (`selected`/`defaultSelected` + `onSelectedChange`, `size` sm·md; `removable` + `removeLabel` + `onRemove`), `Chip.Group` (`type` single·multiple, `label`, `required` for single), `chip` (the slots) | client |
|
|
151
|
+
| `@krizaka/ui/chip-link` | `ChipLink` (a filter that is a link: `selected`, `current`, `size`, `asChild`), `chipVariants` (`size`, `selected`) | server |
|
|
146
152
|
| `@krizaka/ui/switch` | `Switch` (`checked`/`defaultChecked` + `onCheckedChange`, `label` unless a visible label names it, `size` sm·md, `invalid`), `switchVariants` | client |
|
|
147
153
|
| `@krizaka/ui/slider` | `Slider` (`value`: a number or a `[min, max]` range, `onValueChange`, `onValueCommit`, `label`, `thumbLabels`, `formatValue` → aria-valuetext, `showLabel`, `origin`), `slider` (the slots) | client |
|
|
148
154
|
| `@krizaka/ui/checkbox` | `Checkbox` (`checked` true·false·"indeterminate" + `onCheckedChange`, `invalid`, its words as children) — sits in a `Field` | client |
|
|
149
155
|
| `@krizaka/ui/radio-group` | `RadioGroup.Root` (`label`, `orientation`, `invalid`), `RadioGroup.Item` (a dot and its words), `RadioGroup.Card` (a whole card is the radio) | client |
|
|
150
156
|
| `@krizaka/ui/command` | `Command.Root` (`label`, `shouldFilter`…) `/Input` (`placeholder`, `trailing`) `/List` (`label`) `/Empty` (`emptyLabel`) `/Loading/Group/Item/Separator/Shortcut` on cmdk; `CommandDialog` (`label`, `open`/`onOpenChange`, `footer`, `contentProps`) | client |
|
|
151
157
|
| `@krizaka/ui/confirm-button` | `ConfirmButton` (two presses: `confirmLabel`, `onConfirm`, `timeoutMs` 4000, `label` for an icon, `armedContent`; the `Button` variants), `confirmArmed` | client |
|
|
152
|
-
| `@krizaka/ui/progress` | `Progress` (`variant` bar·ring, `size` sm·md·lg, `value`/`max`, indeterminate without a value, `label`, `valueText`, a ring's centre as children) | server |
|
|
158
|
+
| `@krizaka/ui/progress` | `Progress` (`variant` bar·ring, `size` sm·md·lg, `value`/`max`, indeterminate without a value, `label`, `valueText`, `showLabel`, `eta`, `buffer`, `segments`, `status` active·paused·error, a ring's centre as children) | server |
|
|
159
|
+
| `@krizaka/ui/meter` | `Meter` (`label`, `value`/`min`/`max`, `valueText`, `thresholds`, `optimum` low·high, `parts` with their legend, `variant` bar·ring, `size`, `showLabel`), `MeterValue` | server |
|
|
160
|
+
| `@krizaka/ui/stepper` | `Stepper` (`steps`: `title`, `description`, `status`, `value`, `content`; `current`, `labels` of the states, `orientation`) | server |
|
|
161
|
+
| `@krizaka/ui/number-ticker` | `NumberTicker` (`value`, `locale`, `format`, `trigger` view·change, `duration`, `announce`, `align`) | client |
|
|
162
|
+
| `@krizaka/ui/glow-card` | `GlowCard` (`glow` border·spotlight·both, `alive`, `asChild`) | client |
|
|
163
|
+
| `@krizaka/ui/marquee` | `Marquee` (`label`, `pauseLabel`, `playLabel`, `speed` px/s, `direction`, `fade`, `defaultPaused`) | client |
|
|
153
164
|
| `@krizaka/ui/section-backdrop` | `SectionBackdrop` (`as`, `direction` down·up, `dome`, `grid`, `media` blurred for depth of field, `animated`): a page section on the brand's section gradient — see `@krizaka/tokens` BRAND.md, "Visual language" | server |
|
|
165
|
+
| `@krizaka/ui/mascots` | `Mascot` (`bird` falcon·owl·duck·flamingo·pigeon, `mood` welcome·thinking·success·empty·error, `tone` brand·own, `size`, `animated`, `title`), `MASCOT_BIRDS`, `MASCOT_MOODS`: the Krizaka flock, in the host brand's accent — one bird at a moment that matters (onboarding, a long wait, a success, an empty list, an error); native `Mascot` in `/native` | client |
|
|
166
|
+
| `@krizaka/ui/iso` | the isometric kit: `IsoHub` (a hero driven by data: `layers`, `dome`, `satellites`, `highlight`), `IsoScene`, `IsoPrism`, `IsoStack`, `IsoDome`, `IsoTile`, `IsoLink`, `IsoNode`, `IsoLabel`, the projection helpers — static SVG animated by motion.css | server |
|
|
167
|
+
| `@krizaka/ui/motion` | `MotionObserver` (reveal, off-screen pause, settle, spotlight, magnetism) and `RotatingWord` (no layout shift) | client |
|
|
154
168
|
| `@krizaka/ui` | the marks, `MotionObserver`, `RotatingWord`, `cx` (unchanged) | client |
|
|
155
169
|
| `@krizaka/ui/native` | React Native: `ThemeProvider`/`useTheme`, `Txt`, `Button`, `IconButton`, `Card.*`, `Badge`, `Chip` (+ `Group`), `Avatar` (+ `Group`), `Skeleton`, `EmptyState`, `Spinner`, `Countdown`, `Segmented`, `Progress`, `Toaster`/`toast`, the marks — see [React Native](#react-native) | native |
|
|
156
170
|
| `@krizaka/ui/motion.css`, `@krizaka/ui/tailwind.css` | the motion signature; the `@source` of the primitives' classes | CSS |
|
|
@@ -20,6 +20,7 @@ declare const buttonVariants: tailwind_variants.TVReturnType<{
|
|
|
20
20
|
shape: {
|
|
21
21
|
rounded: "rounded-lg";
|
|
22
22
|
pill: "rounded-full";
|
|
23
|
+
cut: "rounded-[10px] [corner-shape:bevel]";
|
|
23
24
|
};
|
|
24
25
|
}, undefined, string, {
|
|
25
26
|
variant: {
|
|
@@ -39,6 +40,7 @@ declare const buttonVariants: tailwind_variants.TVReturnType<{
|
|
|
39
40
|
shape: {
|
|
40
41
|
rounded: "rounded-lg";
|
|
41
42
|
pill: "rounded-full";
|
|
43
|
+
cut: "rounded-[10px] [corner-shape:bevel]";
|
|
42
44
|
};
|
|
43
45
|
}, undefined, tailwind_variants.TVReturnTypeLike<{
|
|
44
46
|
variant: {
|
|
@@ -58,6 +60,7 @@ declare const buttonVariants: tailwind_variants.TVReturnType<{
|
|
|
58
60
|
shape: {
|
|
59
61
|
rounded: "rounded-lg";
|
|
60
62
|
pill: "rounded-full";
|
|
63
|
+
cut: "rounded-[10px] [corner-shape:bevel]";
|
|
61
64
|
};
|
|
62
65
|
}, undefined>>;
|
|
63
66
|
type ButtonVariants = VariantProps<typeof buttonVariants>;
|
|
@@ -74,14 +77,38 @@ type ButtonProps = React.ComponentProps<"button"> & ButtonVariants & {
|
|
|
74
77
|
*/
|
|
75
78
|
size?: ButtonVariants["size"];
|
|
76
79
|
/**
|
|
77
|
-
* rounded · pill.
|
|
80
|
+
* rounded · pill · cut (45° corners, the Krizaka chamfer).
|
|
78
81
|
* @default "rounded"
|
|
79
82
|
*/
|
|
80
83
|
shape?: ButtonVariants["shape"];
|
|
81
84
|
/** Renders the child (e.g. a <Link>) instead of the <button>, with props, classes and ref merged. */
|
|
82
85
|
asChild?: boolean;
|
|
83
|
-
/**
|
|
86
|
+
/**
|
|
87
|
+
* Disables and signals the wait (aria-busy, data-loading) and shows the Krizaka loader glyph before the label; the
|
|
88
|
+
* button keeps its colour.
|
|
89
|
+
*/
|
|
84
90
|
loading?: boolean;
|
|
91
|
+
/**
|
|
92
|
+
* Between 0 and 1, while `loading`: the glyph's trace and a light fill across the button grow to the value (an
|
|
93
|
+
* upload, an export).
|
|
94
|
+
*/
|
|
95
|
+
progress?: number | null;
|
|
96
|
+
/**
|
|
97
|
+
* How the action ended: `success` draws a check, `error` a cross (and the button shakes its head once); a ring of
|
|
98
|
+
* the status colour opens around it. Clear it to return to rest.
|
|
99
|
+
*/
|
|
100
|
+
status?: "success" | "error" | null;
|
|
101
|
+
/** A message announced politely by assistive technology when it changes (“Saved”, “Upload failed”) — passed translated. */
|
|
102
|
+
announce?: string;
|
|
103
|
+
/**
|
|
104
|
+
* Shows the glyph while `loading` / with a `status`. `false`: you draw your own.
|
|
105
|
+
* @default true
|
|
106
|
+
*/
|
|
107
|
+
indicator?: boolean;
|
|
108
|
+
/** A sheen of light crosses the button on hover — for the one action a page is about. */
|
|
109
|
+
shimmer?: boolean;
|
|
110
|
+
/** The button leans a few pixels toward a fine pointer (driven by `MotionObserver`; never under reduced motion or on touch). */
|
|
111
|
+
magnetic?: boolean;
|
|
85
112
|
};
|
|
86
113
|
|
|
87
114
|
export type { ButtonProps as B, ButtonVariants as a };
|
package/dist/button.d.ts
CHANGED
|
@@ -20,6 +20,7 @@ declare const buttonVariants: tailwind_variants.TVReturnType<{
|
|
|
20
20
|
shape: {
|
|
21
21
|
rounded: "rounded-lg";
|
|
22
22
|
pill: "rounded-full";
|
|
23
|
+
cut: "rounded-[10px] [corner-shape:bevel]";
|
|
23
24
|
};
|
|
24
25
|
}, undefined, string, {
|
|
25
26
|
variant: {
|
|
@@ -39,6 +40,7 @@ declare const buttonVariants: tailwind_variants.TVReturnType<{
|
|
|
39
40
|
shape: {
|
|
40
41
|
rounded: "rounded-lg";
|
|
41
42
|
pill: "rounded-full";
|
|
43
|
+
cut: "rounded-[10px] [corner-shape:bevel]";
|
|
42
44
|
};
|
|
43
45
|
}, undefined, tailwind_variants.TVReturnTypeLike<{
|
|
44
46
|
variant: {
|
|
@@ -58,6 +60,7 @@ declare const buttonVariants: tailwind_variants.TVReturnType<{
|
|
|
58
60
|
shape: {
|
|
59
61
|
rounded: "rounded-lg";
|
|
60
62
|
pill: "rounded-full";
|
|
63
|
+
cut: "rounded-[10px] [corner-shape:bevel]";
|
|
61
64
|
};
|
|
62
65
|
}, undefined>>;
|
|
63
66
|
type ButtonVariants = VariantProps<typeof buttonVariants>;
|
|
@@ -74,16 +77,40 @@ type ButtonProps = React.ComponentProps<"button"> & ButtonVariants & {
|
|
|
74
77
|
*/
|
|
75
78
|
size?: ButtonVariants["size"];
|
|
76
79
|
/**
|
|
77
|
-
* rounded · pill.
|
|
80
|
+
* rounded · pill · cut (45° corners, the Krizaka chamfer).
|
|
78
81
|
* @default "rounded"
|
|
79
82
|
*/
|
|
80
83
|
shape?: ButtonVariants["shape"];
|
|
81
84
|
/** Renders the child (e.g. a <Link>) instead of the <button>, with props, classes and ref merged. */
|
|
82
85
|
asChild?: boolean;
|
|
83
|
-
/**
|
|
86
|
+
/**
|
|
87
|
+
* Disables and signals the wait (aria-busy, data-loading) and shows the Krizaka loader glyph before the label; the
|
|
88
|
+
* button keeps its colour.
|
|
89
|
+
*/
|
|
84
90
|
loading?: boolean;
|
|
91
|
+
/**
|
|
92
|
+
* Between 0 and 1, while `loading`: the glyph's trace and a light fill across the button grow to the value (an
|
|
93
|
+
* upload, an export).
|
|
94
|
+
*/
|
|
95
|
+
progress?: number | null;
|
|
96
|
+
/**
|
|
97
|
+
* How the action ended: `success` draws a check, `error` a cross (and the button shakes its head once); a ring of
|
|
98
|
+
* the status colour opens around it. Clear it to return to rest.
|
|
99
|
+
*/
|
|
100
|
+
status?: "success" | "error" | null;
|
|
101
|
+
/** A message announced politely by assistive technology when it changes (“Saved”, “Upload failed”) — passed translated. */
|
|
102
|
+
announce?: string;
|
|
103
|
+
/**
|
|
104
|
+
* Shows the glyph while `loading` / with a `status`. `false`: you draw your own.
|
|
105
|
+
* @default true
|
|
106
|
+
*/
|
|
107
|
+
indicator?: boolean;
|
|
108
|
+
/** A sheen of light crosses the button on hover — for the one action a page is about. */
|
|
109
|
+
shimmer?: boolean;
|
|
110
|
+
/** The button leans a few pixels toward a fine pointer (driven by `MotionObserver`; never under reduced motion or on touch). */
|
|
111
|
+
magnetic?: boolean;
|
|
85
112
|
};
|
|
86
|
-
declare function Button({ asChild, loading, variant, size, shape, className, disabled, ...props }: ButtonProps): React.JSX.Element;
|
|
113
|
+
declare function Button({ asChild, loading, progress, status, announce, indicator, shimmer, magnetic, variant, size, shape, className, disabled, children, ...props }: ButtonProps): React.JSX.Element;
|
|
87
114
|
type IconButtonProps = Omit<ButtonProps, "size"> & {
|
|
88
115
|
/** The accessible name (and tooltip) of the button — required, passed translated. */
|
|
89
116
|
label: string;
|
|
@@ -93,7 +120,7 @@ type IconButtonProps = Omit<ButtonProps, "size"> & {
|
|
|
93
120
|
*/
|
|
94
121
|
size?: ButtonProps["size"];
|
|
95
122
|
};
|
|
96
|
-
/** An icon-only button: `label` is required, it is its accessible name. */
|
|
97
|
-
declare function IconButton({ label, size, ...props }: IconButtonProps): React.JSX.Element;
|
|
123
|
+
/** An icon-only button: `label` is required, it is its accessible name. Loading or with a status, the glyph takes the icon's place. */
|
|
124
|
+
declare function IconButton({ label, size, children, ...props }: IconButtonProps): React.JSX.Element;
|
|
98
125
|
|
|
99
126
|
export { Button, type ButtonProps, type ButtonVariants, IconButton, type IconButtonProps, buttonVariants };
|
package/dist/button.js
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
|
+
import {
|
|
2
|
+
LoaderGlyph
|
|
3
|
+
} from "./chunk-43PTCDTL.js";
|
|
4
|
+
|
|
1
5
|
// src/button/button.tsx
|
|
2
6
|
import { Slot } from "radix-ui";
|
|
3
7
|
import { tv } from "tailwind-variants";
|
|
4
|
-
import { jsx } from "react/jsx-runtime";
|
|
8
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
5
9
|
var buttonVariants = tv({
|
|
6
|
-
base: "inline-flex shrink-0 select-none items-center justify-center gap-2 whitespace-nowrap font-semibold transition-all focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-surface-0 disabled:pointer-events-none disabled:opacity-40 data-loading:cursor-progress active:scale-[0.98]",
|
|
10
|
+
base: "inline-flex shrink-0 select-none items-center justify-center gap-2 whitespace-nowrap font-semibold transition-all focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-surface-0 disabled:pointer-events-none disabled:opacity-40 data-loading:cursor-progress active:scale-[0.98] [&[data-loading]]:opacity-100",
|
|
7
11
|
variants: {
|
|
8
12
|
variant: {
|
|
9
13
|
primary: "bg-accent text-on-accent shadow-sm hover:bg-accent-hover",
|
|
@@ -17,28 +21,77 @@ var buttonVariants = tv({
|
|
|
17
21
|
danger: "border border-danger/50 bg-danger/10 text-fg hover:border-danger hover:bg-danger/20"
|
|
18
22
|
},
|
|
19
23
|
size: { sm: "h-8 px-3 text-xs", md: "h-10 px-4 text-sm", lg: "h-12 px-6 text-sm", icon: "h-10 w-10" },
|
|
20
|
-
|
|
24
|
+
// `cut`: the Krizaka chamfer — 45° corners (CSS corner-shape, where supported; rounded elsewhere). The border, the
|
|
25
|
+
// focus ring and the hover follow the cut, unlike a clip-path.
|
|
26
|
+
shape: { rounded: "rounded-lg", pill: "rounded-full", cut: "rounded-[10px] [corner-shape:bevel]" }
|
|
21
27
|
},
|
|
22
28
|
defaultVariants: { variant: "secondary", size: "md", shape: "rounded" }
|
|
23
29
|
});
|
|
24
|
-
|
|
30
|
+
var STATUS_TEXT = { success: "text-fg-success", error: "text-fg-danger" };
|
|
31
|
+
function Button({
|
|
32
|
+
asChild,
|
|
33
|
+
loading,
|
|
34
|
+
progress,
|
|
35
|
+
status,
|
|
36
|
+
announce,
|
|
37
|
+
indicator = true,
|
|
38
|
+
shimmer,
|
|
39
|
+
magnetic,
|
|
40
|
+
variant,
|
|
41
|
+
size,
|
|
42
|
+
shape,
|
|
43
|
+
className,
|
|
44
|
+
disabled,
|
|
45
|
+
children,
|
|
46
|
+
...props
|
|
47
|
+
}) {
|
|
25
48
|
const Comp = asChild ? Slot.Root : "button";
|
|
26
|
-
|
|
49
|
+
const known = loading && typeof progress === "number" && Number.isFinite(progress);
|
|
50
|
+
const ratio = known ? Math.min(1, Math.max(0, progress)) : 0;
|
|
51
|
+
const glyph = indicator && !asChild && (loading || status) ? status ?? "loading" : null;
|
|
52
|
+
const filled = variant === "primary" || variant === "gradient";
|
|
53
|
+
const button = /* @__PURE__ */ jsx(
|
|
27
54
|
Comp,
|
|
28
55
|
{
|
|
29
56
|
type: asChild ? void 0 : "button",
|
|
30
57
|
"aria-busy": loading || void 0,
|
|
31
58
|
"data-loading": loading ? "" : void 0,
|
|
32
59
|
"data-variant": variant ?? "secondary",
|
|
60
|
+
"data-kz-status": status ?? void 0,
|
|
61
|
+
"data-kz-magnetic": magnetic ? "" : void 0,
|
|
33
62
|
disabled: asChild ? void 0 : disabled || loading,
|
|
34
63
|
"aria-disabled": asChild && (disabled || loading) ? true : void 0,
|
|
35
|
-
className: buttonVariants({
|
|
36
|
-
|
|
64
|
+
className: buttonVariants({
|
|
65
|
+
variant,
|
|
66
|
+
size,
|
|
67
|
+
shape,
|
|
68
|
+
className: [known && "relative isolate overflow-hidden", shimmer && "kz-sheen", className].filter(Boolean).join(" ") || void 0
|
|
69
|
+
}),
|
|
70
|
+
...props,
|
|
71
|
+
children: asChild ? children : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
72
|
+
known && /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "absolute inset-y-0 left-0 -z-10 bg-current opacity-15 transition-[width] duration-500", style: { width: `${ratio * 100}%` } }),
|
|
73
|
+
glyph && /* @__PURE__ */ jsx(
|
|
74
|
+
"span",
|
|
75
|
+
{
|
|
76
|
+
"aria-hidden": true,
|
|
77
|
+
"data-slot": "indicator",
|
|
78
|
+
className: "-my-1 grid grid-cols-[1fr] transition-[grid-template-columns,margin,opacity] duration-300 starting:-mr-2 starting:grid-cols-[0fr] starting:opacity-0",
|
|
79
|
+
children: /* @__PURE__ */ jsx("span", { className: "overflow-hidden", children: /* @__PURE__ */ jsx(LoaderGlyph, { state: glyph, value: known ? ratio : null, className: ["h-4 w-4", glyph !== "loading" && !filled && STATUS_TEXT[glyph]].filter(Boolean).join(" ") }) })
|
|
80
|
+
}
|
|
81
|
+
),
|
|
82
|
+
children
|
|
83
|
+
] })
|
|
37
84
|
}
|
|
38
85
|
);
|
|
86
|
+
if (announce === void 0 || asChild) return button;
|
|
87
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
88
|
+
button,
|
|
89
|
+
/* @__PURE__ */ jsx("span", { role: "status", className: "sr-only", children: announce })
|
|
90
|
+
] });
|
|
39
91
|
}
|
|
40
|
-
function IconButton({ label, size = "icon", ...props }) {
|
|
41
|
-
|
|
92
|
+
function IconButton({ label, size = "icon", children, ...props }) {
|
|
93
|
+
const swap = props.indicator !== false && !props.asChild && (props.loading || props.status);
|
|
94
|
+
return /* @__PURE__ */ jsx(Button, { "aria-label": label, title: label, size, ...props, children: swap ? null : children });
|
|
42
95
|
}
|
|
43
96
|
export {
|
|
44
97
|
Button,
|
package/dist/button.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/button/button.tsx"],"sourcesContent":["// Server-safe: no hook, no context. `buttonVariants` styles a <Link> or a Server Component without the component.\nimport { Slot } from \"radix-ui\";\nimport type * as React from \"react\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\n\nexport const buttonVariants = tv({\n base:\n \"inline-flex shrink-0 select-none items-center justify-center gap-2 whitespace-nowrap font-semibold transition-all \" +\n \"focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-surface-0 \" +\n \"disabled:pointer-events-none disabled:opacity-40 data-loading:cursor-progress active:scale-[0.98]\",\n variants: {\n variant: {\n primary: \"bg-accent text-on-accent shadow-sm hover:bg-accent-hover\",\n // The brand's signature: accent → accent-2 (on-accent reads on both stops, tested in @krizaka/tokens).\n gradient: \"bg-linear-to-r from-accent to-accent-2 text-on-accent shadow-sm hover:brightness-110\",\n secondary: \"border border-border-default bg-surface-2 text-fg hover:border-border-strong hover:bg-surface-3\",\n outline: \"border border-border-default bg-transparent text-fg hover:border-accent hover:text-fg-accent\",\n ghost: \"text-fg-secondary hover:bg-surface-2 hover:text-fg\",\n // The border and the tint carry the danger; the label stays the primary text role, legible on the tint at rest\n // and hovered over every surface (`text-fg-danger` is for text set directly on a surface).\n danger: \"border border-danger/50 bg-danger/10 text-fg hover:border-danger hover:bg-danger/20\",\n },\n size: { sm: \"h-8 px-3 text-xs\", md: \"h-10 px-4 text-sm\", lg: \"h-12 px-6 text-sm\", icon: \"h-10 w-10\" },\n shape: { rounded: \"rounded-lg\", pill: \"rounded-full\" },\n },\n defaultVariants: { variant: \"secondary\", size: \"md\", shape: \"rounded\" },\n});\n\nexport type ButtonVariants = VariantProps<typeof buttonVariants>;\n\nexport type ButtonProps = React.ComponentProps<\"button\"> &\n ButtonVariants & {\n /**\n * The look: `primary` (the accent), `gradient` (accent → accent-2), `secondary` (a raised surface), `outline`,\n * `ghost`, `danger`.\n * @default \"secondary\"\n */\n variant?: ButtonVariants[\"variant\"];\n /**\n * sm · md · lg, or `icon` (a square).\n * @default \"md\"\n */\n size?: ButtonVariants[\"size\"];\n /**\n * rounded · pill.\n * @default \"rounded\"\n */\n shape?: ButtonVariants[\"shape\"];\n /** Renders the child (e.g. a <Link>) instead of the <button>, with props, classes and ref merged. */\n asChild?: boolean;\n
|
|
1
|
+
{"version":3,"sources":["../src/button/button.tsx"],"sourcesContent":["// Server-safe: no hook, no context. `buttonVariants` styles a <Link> or a Server Component without the component.\nimport { Slot } from \"radix-ui\";\nimport type * as React from \"react\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\n\nimport { LoaderGlyph } from \"../spinner/glyph\";\n\nexport const buttonVariants = tv({\n base:\n \"inline-flex shrink-0 select-none items-center justify-center gap-2 whitespace-nowrap font-semibold transition-all \" +\n \"focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-surface-0 \" +\n \"disabled:pointer-events-none disabled:opacity-40 data-loading:cursor-progress active:scale-[0.98] \" +\n // Busy is not unavailable: a loading button keeps its colour (it is disabled only so it is not pressed twice).\n \"[&[data-loading]]:opacity-100\",\n variants: {\n variant: {\n primary: \"bg-accent text-on-accent shadow-sm hover:bg-accent-hover\",\n // The brand's signature: accent → accent-2 (on-accent reads on both stops, tested in @krizaka/tokens).\n gradient: \"bg-linear-to-r from-accent to-accent-2 text-on-accent shadow-sm hover:brightness-110\",\n secondary: \"border border-border-default bg-surface-2 text-fg hover:border-border-strong hover:bg-surface-3\",\n outline: \"border border-border-default bg-transparent text-fg hover:border-accent hover:text-fg-accent\",\n ghost: \"text-fg-secondary hover:bg-surface-2 hover:text-fg\",\n // The border and the tint carry the danger; the label stays the primary text role, legible on the tint at rest\n // and hovered over every surface (`text-fg-danger` is for text set directly on a surface).\n danger: \"border border-danger/50 bg-danger/10 text-fg hover:border-danger hover:bg-danger/20\",\n },\n size: { sm: \"h-8 px-3 text-xs\", md: \"h-10 px-4 text-sm\", lg: \"h-12 px-6 text-sm\", icon: \"h-10 w-10\" },\n // `cut`: the Krizaka chamfer — 45° corners (CSS corner-shape, where supported; rounded elsewhere). The border, the\n // focus ring and the hover follow the cut, unlike a clip-path.\n shape: { rounded: \"rounded-lg\", pill: \"rounded-full\", cut: \"rounded-[10px] [corner-shape:bevel]\" },\n },\n defaultVariants: { variant: \"secondary\", size: \"md\", shape: \"rounded\" },\n});\n\nexport type ButtonVariants = VariantProps<typeof buttonVariants>;\n\nexport type ButtonProps = React.ComponentProps<\"button\"> &\n ButtonVariants & {\n /**\n * The look: `primary` (the accent), `gradient` (accent → accent-2), `secondary` (a raised surface), `outline`,\n * `ghost`, `danger`.\n * @default \"secondary\"\n */\n variant?: ButtonVariants[\"variant\"];\n /**\n * sm · md · lg, or `icon` (a square).\n * @default \"md\"\n */\n size?: ButtonVariants[\"size\"];\n /**\n * rounded · pill · cut (45° corners, the Krizaka chamfer).\n * @default \"rounded\"\n */\n shape?: ButtonVariants[\"shape\"];\n /** Renders the child (e.g. a <Link>) instead of the <button>, with props, classes and ref merged. */\n asChild?: boolean;\n /**\n * Disables and signals the wait (aria-busy, data-loading) and shows the Krizaka loader glyph before the label; the\n * button keeps its colour.\n */\n loading?: boolean;\n /**\n * Between 0 and 1, while `loading`: the glyph's trace and a light fill across the button grow to the value (an\n * upload, an export).\n */\n progress?: number | null;\n /**\n * How the action ended: `success` draws a check, `error` a cross (and the button shakes its head once); a ring of\n * the status colour opens around it. Clear it to return to rest.\n */\n status?: \"success\" | \"error\" | null;\n /** A message announced politely by assistive technology when it changes (“Saved”, “Upload failed”) — passed translated. */\n announce?: string;\n /**\n * Shows the glyph while `loading` / with a `status`. `false`: you draw your own.\n * @default true\n */\n indicator?: boolean;\n /** A sheen of light crosses the button on hover — for the one action a page is about. */\n shimmer?: boolean;\n /** The button leans a few pixels toward a fine pointer (driven by `MotionObserver`; never under reduced motion or on touch). */\n magnetic?: boolean;\n };\n\nconst STATUS_TEXT = { success: \"text-fg-success\", error: \"text-fg-danger\" } as const;\n\nexport function Button({\n asChild,\n loading,\n progress,\n status,\n announce,\n indicator = true,\n shimmer,\n magnetic,\n variant,\n size,\n shape,\n className,\n disabled,\n children,\n ...props\n}: ButtonProps) {\n const Comp = asChild ? Slot.Root : \"button\";\n const known = loading && typeof progress === \"number\" && Number.isFinite(progress);\n const ratio = known ? Math.min(1, Math.max(0, progress)) : 0;\n const glyph = indicator && !asChild && (loading || status) ? (status ?? \"loading\") : null;\n // On a filled variant the glyph stays in the label's colour; on the others it takes the status colour.\n const filled = variant === \"primary\" || variant === \"gradient\";\n const button = (\n <Comp\n type={asChild ? undefined : \"button\"}\n aria-busy={loading || undefined}\n data-loading={loading ? \"\" : undefined}\n data-variant={variant ?? \"secondary\"}\n data-kz-status={status ?? undefined}\n data-kz-magnetic={magnetic ? \"\" : undefined}\n disabled={asChild ? undefined : disabled || loading}\n aria-disabled={asChild && (disabled || loading) ? true : undefined}\n className={buttonVariants({\n variant,\n size,\n shape,\n className: [known && \"relative isolate overflow-hidden\", shimmer && \"kz-sheen\", className].filter(Boolean).join(\" \") || undefined,\n })}\n {...props}\n >\n {asChild ? (\n children\n ) : (\n <>\n {known && (\n <span aria-hidden className=\"absolute inset-y-0 left-0 -z-10 bg-current opacity-15 transition-[width] duration-500\" style={{ width: `${ratio * 100}%` }} />\n )}\n {glyph && (\n <span\n aria-hidden\n data-slot=\"indicator\"\n className=\"-my-1 grid grid-cols-[1fr] transition-[grid-template-columns,margin,opacity] duration-300 starting:-mr-2 starting:grid-cols-[0fr] starting:opacity-0\"\n >\n <span className=\"overflow-hidden\">\n <LoaderGlyph state={glyph} value={known ? ratio : null} className={[\"h-4 w-4\", glyph !== \"loading\" && !filled && STATUS_TEXT[glyph]].filter(Boolean).join(\" \")} />\n </span>\n </span>\n )}\n {children}\n </>\n )}\n </Comp>\n );\n if (announce === undefined || asChild) return button;\n return (\n <>\n {button}\n <span role=\"status\" className=\"sr-only\">\n {announce}\n </span>\n </>\n );\n}\n\nexport type IconButtonProps = Omit<ButtonProps, \"size\"> & {\n /** The accessible name (and tooltip) of the button — required, passed translated. */\n label: string;\n /**\n * sm · md · lg, or `icon` (a square).\n * @default \"icon\"\n */\n size?: ButtonProps[\"size\"];\n};\n\n/** An icon-only button: `label` is required, it is its accessible name. Loading or with a status, the glyph takes the icon's place. */\nexport function IconButton({ label, size = \"icon\", children, ...props }: IconButtonProps) {\n const swap = props.indicator !== false && !props.asChild && (props.loading || props.status);\n return (\n <Button aria-label={label} title={label} size={size} {...props}>\n {swap ? null : children}\n </Button>\n );\n}\n"],"mappings":";;;;;AACA,SAAS,YAAY;AAErB,SAAS,UAA6B;AA+H9B,mBAEI,KAFJ;AA3HD,IAAM,iBAAiB,GAAG;AAAA,EAC/B,MACE;AAAA,EAKF,UAAU;AAAA,IACR,SAAS;AAAA,MACP,SAAS;AAAA;AAAA,MAET,UAAU;AAAA,MACV,WAAW;AAAA,MACX,SAAS;AAAA,MACT,OAAO;AAAA;AAAA;AAAA,MAGP,QAAQ;AAAA,IACV;AAAA,IACA,MAAM,EAAE,IAAI,oBAAoB,IAAI,qBAAqB,IAAI,qBAAqB,MAAM,YAAY;AAAA;AAAA;AAAA,IAGpG,OAAO,EAAE,SAAS,cAAc,MAAM,gBAAgB,KAAK,sCAAsC;AAAA,EACnG;AAAA,EACA,iBAAiB,EAAE,SAAS,aAAa,MAAM,MAAM,OAAO,UAAU;AACxE,CAAC;AAoDD,IAAM,cAAc,EAAE,SAAS,mBAAmB,OAAO,iBAAiB;AAEnE,SAAS,OAAO;AAAA,EACrB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,YAAY;AAAA,EACZ;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAgB;AACd,QAAM,OAAO,UAAU,KAAK,OAAO;AACnC,QAAM,QAAQ,WAAW,OAAO,aAAa,YAAY,OAAO,SAAS,QAAQ;AACjF,QAAM,QAAQ,QAAQ,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,QAAQ,CAAC,IAAI;AAC3D,QAAM,QAAQ,aAAa,CAAC,YAAY,WAAW,UAAW,UAAU,YAAa;AAErF,QAAM,SAAS,YAAY,aAAa,YAAY;AACpD,QAAM,SACJ;AAAA,IAAC;AAAA;AAAA,MACC,MAAM,UAAU,SAAY;AAAA,MAC5B,aAAW,WAAW;AAAA,MACtB,gBAAc,UAAU,KAAK;AAAA,MAC7B,gBAAc,WAAW;AAAA,MACzB,kBAAgB,UAAU;AAAA,MAC1B,oBAAkB,WAAW,KAAK;AAAA,MAClC,UAAU,UAAU,SAAY,YAAY;AAAA,MAC5C,iBAAe,YAAY,YAAY,WAAW,OAAO;AAAA,MACzD,WAAW,eAAe;AAAA,QACxB;AAAA,QACA;AAAA,QACA;AAAA,QACA,WAAW,CAAC,SAAS,oCAAoC,WAAW,YAAY,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,KAAK;AAAA,MAC1H,CAAC;AAAA,MACA,GAAG;AAAA,MAEH,oBACC,WAEA,iCACG;AAAA,iBACC,oBAAC,UAAK,eAAW,MAAC,WAAU,yFAAwF,OAAO,EAAE,OAAO,GAAG,QAAQ,GAAG,IAAI,GAAG;AAAA,QAE1J,SACC;AAAA,UAAC;AAAA;AAAA,YACC,eAAW;AAAA,YACX,aAAU;AAAA,YACV,WAAU;AAAA,YAEV,8BAAC,UAAK,WAAU,mBACd,8BAAC,eAAY,OAAO,OAAO,OAAO,QAAQ,QAAQ,MAAM,WAAW,CAAC,WAAW,UAAU,aAAa,CAAC,UAAU,YAAY,KAAK,CAAC,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAAG,GAClK;AAAA;AAAA,QACF;AAAA,QAED;AAAA,SACH;AAAA;AAAA,EAEJ;AAEF,MAAI,aAAa,UAAa,QAAS,QAAO;AAC9C,SACE,iCACG;AAAA;AAAA,IACD,oBAAC,UAAK,MAAK,UAAS,WAAU,WAC3B,oBACH;AAAA,KACF;AAEJ;AAaO,SAAS,WAAW,EAAE,OAAO,OAAO,QAAQ,UAAU,GAAG,MAAM,GAAoB;AACxF,QAAM,OAAO,MAAM,cAAc,SAAS,CAAC,MAAM,YAAY,MAAM,WAAW,MAAM;AACpF,SACE,oBAAC,UAAO,cAAY,OAAO,OAAO,OAAO,MAAa,GAAG,OACtD,iBAAO,OAAO,UACjB;AAEJ;","names":[]}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import * as tailwind_variants from 'tailwind-variants';
|
|
2
|
+
import { VariantProps } from 'tailwind-variants';
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
|
|
5
|
+
declare const chipVariants: tailwind_variants.TVReturnType<{
|
|
6
|
+
size: {
|
|
7
|
+
sm: "h-7 px-3 text-xs";
|
|
8
|
+
md: "h-9 px-3.5 text-xs";
|
|
9
|
+
};
|
|
10
|
+
selected: {
|
|
11
|
+
false: "border-border-default bg-surface-1 text-fg-secondary hover:border-border-strong hover:text-fg";
|
|
12
|
+
true: "border-accent bg-accent-soft text-fg";
|
|
13
|
+
};
|
|
14
|
+
}, undefined, string, {
|
|
15
|
+
size: {
|
|
16
|
+
sm: "h-7 px-3 text-xs";
|
|
17
|
+
md: "h-9 px-3.5 text-xs";
|
|
18
|
+
};
|
|
19
|
+
selected: {
|
|
20
|
+
false: "border-border-default bg-surface-1 text-fg-secondary hover:border-border-strong hover:text-fg";
|
|
21
|
+
true: "border-accent bg-accent-soft text-fg";
|
|
22
|
+
};
|
|
23
|
+
}, undefined, tailwind_variants.TVReturnTypeLike<{
|
|
24
|
+
size: {
|
|
25
|
+
sm: "h-7 px-3 text-xs";
|
|
26
|
+
md: "h-9 px-3.5 text-xs";
|
|
27
|
+
};
|
|
28
|
+
selected: {
|
|
29
|
+
false: "border-border-default bg-surface-1 text-fg-secondary hover:border-border-strong hover:text-fg";
|
|
30
|
+
true: "border-accent bg-accent-soft text-fg";
|
|
31
|
+
};
|
|
32
|
+
}, undefined>>;
|
|
33
|
+
type ChipVariantsProps = VariantProps<typeof chipVariants>;
|
|
34
|
+
type ChipLinkProps = React.ComponentProps<"a"> & {
|
|
35
|
+
/**
|
|
36
|
+
* sm · md.
|
|
37
|
+
* @default "md"
|
|
38
|
+
*/
|
|
39
|
+
size?: ChipVariantsProps["size"];
|
|
40
|
+
/** The current filter: the accent, `aria-current` (`page` by default) and `data-state="on"`. */
|
|
41
|
+
selected?: boolean;
|
|
42
|
+
/**
|
|
43
|
+
* What `aria-current` says when selected: `page` (a filter that is a page) or `true`.
|
|
44
|
+
* @default "page"
|
|
45
|
+
*/
|
|
46
|
+
current?: "page" | "true";
|
|
47
|
+
/** Renders your router's `<Link>` with the chip's look. */
|
|
48
|
+
asChild?: boolean;
|
|
49
|
+
};
|
|
50
|
+
/** A filter that is a link, with the look of `Chip`. */
|
|
51
|
+
declare function ChipLink({ size, selected, current, asChild, className, ...props }: ChipLinkProps): React.JSX.Element;
|
|
52
|
+
|
|
53
|
+
export { ChipLink, type ChipLinkProps, type ChipVariantsProps, chipVariants };
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// src/chip-link/chip-link.tsx
|
|
2
|
+
import { Slot } from "radix-ui";
|
|
3
|
+
import { tv } from "tailwind-variants";
|
|
4
|
+
import { jsx } from "react/jsx-runtime";
|
|
5
|
+
var chipVariants = tv({
|
|
6
|
+
base: "inline-flex shrink-0 select-none items-center justify-center gap-1.5 whitespace-nowrap rounded-full border font-semibold no-underline transition-colors focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring",
|
|
7
|
+
variants: {
|
|
8
|
+
size: { sm: "h-7 px-3 text-xs", md: "h-9 px-3.5 text-xs" },
|
|
9
|
+
selected: {
|
|
10
|
+
false: "border-border-default bg-surface-1 text-fg-secondary hover:border-border-strong hover:text-fg",
|
|
11
|
+
true: "border-accent bg-accent-soft text-fg"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
defaultVariants: { size: "md", selected: false }
|
|
15
|
+
});
|
|
16
|
+
function ChipLink({ size, selected = false, current = "page", asChild, className, ...props }) {
|
|
17
|
+
const Comp = asChild ? Slot.Root : "a";
|
|
18
|
+
return /* @__PURE__ */ jsx(
|
|
19
|
+
Comp,
|
|
20
|
+
{
|
|
21
|
+
"data-state": selected ? "on" : "off",
|
|
22
|
+
"aria-current": selected ? current : void 0,
|
|
23
|
+
className: chipVariants({ size, selected, className }),
|
|
24
|
+
...props
|
|
25
|
+
}
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
export {
|
|
29
|
+
ChipLink,
|
|
30
|
+
chipVariants
|
|
31
|
+
};
|
|
32
|
+
//# sourceMappingURL=chip-link.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/chip-link/chip-link.tsx"],"sourcesContent":["// Server-safe: no hook, no context. A chip that is a link — a filter that is an address (`/explore?tag=night`): the look\n// of `Chip`, the current filter marked by `selected` (`aria-current`, the accent), usable in a Server Component.\n// `chipVariants` styles anything else (a router link you render yourself).\nimport { Slot } from \"radix-ui\";\nimport type * as React from \"react\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\n\nexport const chipVariants = tv({\n base:\n \"inline-flex shrink-0 select-none items-center justify-center gap-1.5 whitespace-nowrap rounded-full border font-semibold no-underline transition-colors \" +\n \"focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring\",\n variants: {\n size: { sm: \"h-7 px-3 text-xs\", md: \"h-9 px-3.5 text-xs\" },\n selected: {\n false: \"border-border-default bg-surface-1 text-fg-secondary hover:border-border-strong hover:text-fg\",\n true: \"border-accent bg-accent-soft text-fg\",\n },\n },\n defaultVariants: { size: \"md\", selected: false },\n});\n\nexport type ChipVariantsProps = VariantProps<typeof chipVariants>;\n\nexport type ChipLinkProps = React.ComponentProps<\"a\"> & {\n /**\n * sm · md.\n * @default \"md\"\n */\n size?: ChipVariantsProps[\"size\"];\n /** The current filter: the accent, `aria-current` (`page` by default) and `data-state=\"on\"`. */\n selected?: boolean;\n /**\n * What `aria-current` says when selected: `page` (a filter that is a page) or `true`.\n * @default \"page\"\n */\n current?: \"page\" | \"true\";\n /** Renders your router's `<Link>` with the chip's look. */\n asChild?: boolean;\n};\n\n/** A filter that is a link, with the look of `Chip`. */\nexport function ChipLink({ size, selected = false, current = \"page\", asChild, className, ...props }: ChipLinkProps) {\n const Comp = asChild ? Slot.Root : \"a\";\n return (\n <Comp\n data-state={selected ? \"on\" : \"off\"}\n aria-current={selected ? current : undefined}\n className={chipVariants({ size, selected, className })}\n {...props}\n />\n );\n}\n"],"mappings":";AAGA,SAAS,YAAY;AAErB,SAAS,UAA6B;AAuClC;AArCG,IAAM,eAAe,GAAG;AAAA,EAC7B,MACE;AAAA,EAEF,UAAU;AAAA,IACR,MAAM,EAAE,IAAI,oBAAoB,IAAI,qBAAqB;AAAA,IACzD,UAAU;AAAA,MACR,OAAO;AAAA,MACP,MAAM;AAAA,IACR;AAAA,EACF;AAAA,EACA,iBAAiB,EAAE,MAAM,MAAM,UAAU,MAAM;AACjD,CAAC;AAsBM,SAAS,SAAS,EAAE,MAAM,WAAW,OAAO,UAAU,QAAQ,SAAS,WAAW,GAAG,MAAM,GAAkB;AAClH,QAAM,OAAO,UAAU,KAAK,OAAO;AACnC,SACE;AAAA,IAAC;AAAA;AAAA,MACC,cAAY,WAAW,OAAO;AAAA,MAC9B,gBAAc,WAAW,UAAU;AAAA,MACnC,WAAW,aAAa,EAAE,MAAM,UAAU,UAAU,CAAC;AAAA,MACpD,GAAG;AAAA;AAAA,EACN;AAEJ;","names":[]}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// src/spinner/glyph.tsx
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
var HEX = "M12 3 19.79 7.5 19.79 16.5 12 21 4.21 16.5 4.21 7.5Z";
|
|
4
|
+
function LoaderGlyph({ state = "loading", value, ...props }) {
|
|
5
|
+
const known = typeof value === "number" && Number.isFinite(value);
|
|
6
|
+
const fill = state !== "loading" ? 100 : known ? Math.round(Math.min(1, Math.max(0, value)) * 100) : null;
|
|
7
|
+
return /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 24 24", fill: "none", "aria-hidden": true, "data-state": state, "data-progress": fill === null ? void 0 : fill, ...props, children: [
|
|
8
|
+
/* @__PURE__ */ jsx("path", { d: HEX, stroke: "currentColor", strokeOpacity: "0.22", strokeWidth: "2.2", strokeLinejoin: "round" }),
|
|
9
|
+
/* @__PURE__ */ jsx(
|
|
10
|
+
"path",
|
|
11
|
+
{
|
|
12
|
+
d: HEX,
|
|
13
|
+
pathLength: 100,
|
|
14
|
+
stroke: "currentColor",
|
|
15
|
+
strokeWidth: "2.2",
|
|
16
|
+
strokeLinejoin: "round",
|
|
17
|
+
strokeLinecap: "round",
|
|
18
|
+
className: "kz-loader-trace",
|
|
19
|
+
strokeDasharray: fill === null ? void 0 : `${fill} ${100 - fill}`
|
|
20
|
+
}
|
|
21
|
+
),
|
|
22
|
+
state === "loading" && /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "2.6", fill: "currentColor", className: "kz-loader-node" }),
|
|
23
|
+
state === "success" && /* @__PURE__ */ jsx("path", { d: "M8.3 12.3l2.6 2.6 4.9-5.3", pathLength: 20, stroke: "currentColor", strokeWidth: "2.2", strokeLinecap: "round", strokeLinejoin: "round", className: "kz-loader-mark" }),
|
|
24
|
+
state === "error" && /* @__PURE__ */ jsx("path", { d: "M9.4 9.4l5.2 5.2M14.6 9.4l-5.2 5.2", pathLength: 20, stroke: "currentColor", strokeWidth: "2.2", strokeLinecap: "round", className: "kz-loader-mark" })
|
|
25
|
+
] });
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export {
|
|
29
|
+
LoaderGlyph
|
|
30
|
+
};
|
|
31
|
+
//# sourceMappingURL=chunk-43PTCDTL.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/spinner/glyph.tsx"],"sourcesContent":["// The Krizaka loader glyph, server-safe: a hexagon (the marks' shape) traced by a segment of light around a node that\n// breathes; determinate, it fills to its value; done, the trace closes and a check (or a cross) draws itself. Animated by\n// motion.css (`kz-loader-*`); still under prefers-reduced-motion — a segment at rest and the node lit, never blank.\nimport type * as React from \"react\";\n\n/** The hexagon, pointy top, radius 9 around (12, 12). */\nconst HEX = \"M12 3 19.79 7.5 19.79 16.5 12 21 4.21 16.5 4.21 7.5Z\";\n\n/** What the glyph shows: a wait (with an optional value), or how it ended. */\nexport type LoaderGlyphState = \"loading\" | \"success\" | \"error\";\n\nexport interface LoaderGlyphProps extends Omit<React.ComponentProps<\"svg\">, \"children\"> {\n /** loading · success · error. */\n state?: LoaderGlyphState;\n /** Between 0 and 1: a determinate wait, the trace grows to it. Absent: indeterminate. */\n value?: number | null;\n}\n\n/** The glyph alone (decorative): the Spinner, the Loader and the Button's `loading` draw it. */\nexport function LoaderGlyph({ state = \"loading\", value, ...props }: LoaderGlyphProps) {\n const known = typeof value === \"number\" && Number.isFinite(value);\n const fill = state !== \"loading\" ? 100 : known ? Math.round(Math.min(1, Math.max(0, value)) * 100) : null;\n return (\n <svg viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden data-state={state} data-progress={fill === null ? undefined : fill} {...props}>\n <path d={HEX} stroke=\"currentColor\" strokeOpacity=\"0.22\" strokeWidth=\"2.2\" strokeLinejoin=\"round\" />\n <path\n d={HEX}\n pathLength={100}\n stroke=\"currentColor\"\n strokeWidth=\"2.2\"\n strokeLinejoin=\"round\"\n strokeLinecap=\"round\"\n className=\"kz-loader-trace\"\n strokeDasharray={fill === null ? undefined : `${fill} ${100 - fill}`}\n />\n {state === \"loading\" && <circle cx=\"12\" cy=\"12\" r=\"2.6\" fill=\"currentColor\" className=\"kz-loader-node\" />}\n {state === \"success\" && <path d=\"M8.3 12.3l2.6 2.6 4.9-5.3\" pathLength={20} stroke=\"currentColor\" strokeWidth=\"2.2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" className=\"kz-loader-mark\" />}\n {state === \"error\" && <path d=\"M9.4 9.4l5.2 5.2M14.6 9.4l-5.2 5.2\" pathLength={20} stroke=\"currentColor\" strokeWidth=\"2.2\" strokeLinecap=\"round\" className=\"kz-loader-mark\" />}\n </svg>\n );\n}\n"],"mappings":";AAuBI,SACE,KADF;AAjBJ,IAAM,MAAM;AAaL,SAAS,YAAY,EAAE,QAAQ,WAAW,OAAO,GAAG,MAAM,GAAqB;AACpF,QAAM,QAAQ,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK;AAChE,QAAM,OAAO,UAAU,YAAY,MAAM,QAAQ,KAAK,MAAM,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,KAAK,CAAC,IAAI,GAAG,IAAI;AACrG,SACE,qBAAC,SAAI,SAAQ,aAAY,MAAK,QAAO,eAAW,MAAC,cAAY,OAAO,iBAAe,SAAS,OAAO,SAAY,MAAO,GAAG,OACvH;AAAA,wBAAC,UAAK,GAAG,KAAK,QAAO,gBAAe,eAAc,QAAO,aAAY,OAAM,gBAAe,SAAQ;AAAA,IAClG;AAAA,MAAC;AAAA;AAAA,QACC,GAAG;AAAA,QACH,YAAY;AAAA,QACZ,QAAO;AAAA,QACP,aAAY;AAAA,QACZ,gBAAe;AAAA,QACf,eAAc;AAAA,QACd,WAAU;AAAA,QACV,iBAAiB,SAAS,OAAO,SAAY,GAAG,IAAI,IAAI,MAAM,IAAI;AAAA;AAAA,IACpE;AAAA,IACC,UAAU,aAAa,oBAAC,YAAO,IAAG,MAAK,IAAG,MAAK,GAAE,OAAM,MAAK,gBAAe,WAAU,kBAAiB;AAAA,IACtG,UAAU,aAAa,oBAAC,UAAK,GAAE,6BAA4B,YAAY,IAAI,QAAO,gBAAe,aAAY,OAAM,eAAc,SAAQ,gBAAe,SAAQ,WAAU,kBAAiB;AAAA,IAC3L,UAAU,WAAW,oBAAC,UAAK,GAAE,sCAAqC,YAAY,IAAI,QAAO,gBAAe,aAAY,OAAM,eAAc,SAAQ,WAAU,kBAAiB;AAAA,KAC9K;AAEJ;","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cx.ts"],"sourcesContent":["/** Joins class names, skipping the falsy ones. */\nexport function cx(...parts: Array<string | false | null | undefined>): string {\n return parts.filter(Boolean).join(\" \");\n}\n"],"mappings":";;;AACO,SAAS,MAAM,OAAyD;AAC7E,SAAO,MAAM,OAAO,OAAO,EAAE,KAAK,GAAG;AACvC;","names":[]}
|