@krizaka/ui 3.8.0 → 3.10.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 +13 -9
- package/dist/action-bar.js +2 -1
- package/dist/action-bar.js.map +1 -1
- package/dist/app-shell.d.ts +81 -3
- package/dist/app-shell.js +163 -35
- package/dist/app-shell.js.map +1 -1
- package/dist/audio-player.js +1 -1
- package/dist/badge.d.ts +36 -39
- package/dist/badge.js +11 -2
- package/dist/badge.js.map +1 -1
- package/dist/blocks.css +56 -4
- package/dist/button-BmCrLCq7.d.ts +114 -0
- package/dist/button.d.ts +48 -48
- package/dist/button.js +2 -1
- package/dist/card.d.ts +111 -111
- package/dist/card.js +10 -2
- package/dist/card.js.map +1 -1
- package/dist/chip.d.ts +24 -24
- package/dist/chip.js +10 -2
- package/dist/chip.js.map +1 -1
- package/dist/{chunk-UOMP6VOZ.js → chunk-276PTQMQ.js} +10 -4
- package/dist/chunk-276PTQMQ.js.map +1 -0
- package/dist/{chunk-Z6FUPB3Q.js → chunk-2NB27LM7.js} +11 -3
- package/dist/chunk-2NB27LM7.js.map +1 -0
- package/dist/chunk-2VNYHG4E.js +9 -0
- package/dist/chunk-2VNYHG4E.js.map +1 -0
- package/dist/{chunk-ND3L5VHT.js → chunk-5Z7FWCV2.js} +2 -2
- package/dist/{chunk-YH4LMWRU.js → chunk-7UCPGXKN.js} +11 -3
- package/dist/chunk-7UCPGXKN.js.map +1 -0
- package/dist/{chunk-AZPKXP3O.js → chunk-AFY35UCB.js} +6 -1
- package/dist/{chunk-AZPKXP3O.js.map → chunk-AFY35UCB.js.map} +1 -1
- package/dist/{chunk-LCZXS6AK.js → chunk-CKSHLSDH.js} +5 -5
- package/dist/chunk-CKSHLSDH.js.map +1 -0
- package/dist/chunk-D3T54RSL.js +11 -0
- package/dist/chunk-D3T54RSL.js.map +1 -0
- package/dist/{chunk-ZKVQGXLD.js → chunk-FKBHWS4N.js} +2 -2
- package/dist/{chunk-BRKMQ6JV.js → chunk-FZBWEDQI.js} +1 -23
- package/dist/chunk-FZBWEDQI.js.map +1 -0
- package/dist/chunk-HG65YAV4.js +379 -0
- package/dist/chunk-HG65YAV4.js.map +1 -0
- package/dist/{chunk-HCNOOPZE.js → chunk-KVDB4GXV.js} +2 -2
- package/dist/chunk-OT6HX3PN.js +85 -0
- package/dist/chunk-OT6HX3PN.js.map +1 -0
- package/dist/{chunk-RUPNPMP3.js → chunk-OWC2LZD2.js} +11 -3
- package/dist/chunk-OWC2LZD2.js.map +1 -0
- package/dist/{chunk-FDCMBWUU.js → chunk-REPTKUJ6.js} +4 -4
- package/dist/chunk-REPTKUJ6.js.map +1 -0
- package/dist/code-block.d.ts +32 -10
- package/dist/code-block.js +51 -43
- package/dist/code-block.js.map +1 -1
- package/dist/combobox.d.ts +3 -3
- package/dist/combobox.js +4 -3
- package/dist/command.js +3 -2
- package/dist/command.js.map +1 -1
- package/dist/component-page.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/continue-prompt.js +11 -3
- package/dist/continue-prompt.js.map +1 -1
- package/dist/data-table.js +7 -6
- package/dist/data-table.js.map +1 -1
- package/dist/date-picker.js +1 -1
- package/dist/dialog.js +3 -2
- package/dist/dialog.js.map +1 -1
- package/dist/file-upload.d.ts +12 -1
- package/dist/file-upload.js +73 -89
- package/dist/file-upload.js.map +1 -1
- package/dist/filter-bar.js +3 -2
- package/dist/image-cropper.js +1 -1
- package/dist/index.js +9 -367
- package/dist/index.js.map +1 -1
- package/dist/list.js +1 -1
- package/dist/map.js.map +1 -1
- package/dist/markdown.d.ts +38 -0
- package/dist/markdown.js +150 -0
- package/dist/markdown.js.map +1 -0
- package/dist/match-dialog.js +2 -1
- package/dist/match-dialog.js.map +1 -1
- package/dist/media-capture.js +1 -1
- package/dist/native/markdown.d.ts +24 -0
- package/dist/native/markdown.js +200 -0
- package/dist/native/markdown.js.map +1 -0
- package/dist/native.d.ts +49 -8
- package/dist/native.js +728 -349
- package/dist/native.js.map +1 -1
- package/dist/nav-bar.d.ts +86 -3
- package/dist/nav-bar.js +88 -2
- package/dist/nav-bar.js.map +1 -1
- package/dist/recipes.d.ts +143 -0
- package/dist/recipes.js +180 -0
- package/dist/recipes.js.map +1 -0
- package/dist/search-field.js +2 -2
- package/dist/showcase.d.ts +69 -0
- package/dist/showcase.js +218 -0
- package/dist/showcase.js.map +1 -0
- package/dist/site-footer.d.ts +172 -0
- package/dist/site-footer.js +105 -0
- package/dist/site-footer.js.map +1 -0
- package/dist/sites-CgJrxejx.d.ts +32 -0
- package/dist/sites.d.ts +64 -0
- package/dist/sites.js +69 -0
- package/dist/sites.js.map +1 -0
- package/dist/swipe-deck.js +1 -1
- package/dist/tag-input.js +4 -3
- package/dist/tag-input.js.map +1 -1
- package/dist/tag-selector.js +2 -1
- package/dist/tag-selector.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/tree-view.js +1 -1
- package/dist/vertical-video.js +2 -1
- package/dist/vertical-video.js.map +1 -1
- package/dist/video-player.js +1 -1
- package/dist/video-trimmer.js +1 -1
- package/dist/virtual.js +2 -2
- package/package.json +87 -18
- package/registry/achievement.json +1 -1
- package/registry/action-bar.json +1 -1
- package/registry/activity-feed.json +1 -1
- package/registry/alert.json +1 -1
- package/registry/app-shell.json +135 -12
- package/registry/argument-card.json +1 -1
- package/registry/audio-player.json +2 -2
- package/registry/auth-layout.json +1 -1
- package/registry/avatar.json +1 -1
- package/registry/badge.json +9 -3
- package/registry/button.json +7 -2
- package/registry/card-grid.json +1 -1
- package/registry/card.json +8 -3
- package/registry/catalogue-page.json +1 -1
- package/registry/changelog-page.json +1 -1
- package/registry/chat.json +1 -1
- package/registry/checkbox.json +1 -1
- package/registry/chip-link.json +1 -1
- package/registry/chip.json +9 -3
- package/registry/choice-grid.json +1 -1
- package/registry/code-block.json +65 -21
- package/registry/combobox.json +4 -3
- package/registry/command.json +1 -1
- package/registry/component-page.json +4 -4
- package/registry/confirm-button.json +1 -1
- package/registry/contact-page.json +1 -1
- package/registry/continue-prompt.json +1 -1
- package/registry/countdown.json +1 -1
- package/registry/cta-panel.json +1 -1
- package/registry/dashboard-layout.json +1 -1
- package/registry/data-table.json +2 -2
- package/registry/date-picker.json +3 -3
- package/registry/decision-list.json +1 -1
- package/registry/description-list.json +1 -1
- package/registry/detail-layout.json +1 -1
- package/registry/dialog.json +1 -1
- package/registry/docs-article-page.json +1 -1
- package/registry/docs-hub-page.json +1 -1
- package/registry/docs-layout.json +1 -1
- package/registry/dropdown-menu.json +1 -1
- package/registry/empty-state.json +1 -1
- package/registry/error-page.json +1 -1
- package/registry/examples/app-shell/console.d.ts +4 -0
- package/registry/examples/app-shell/console.js +93 -0
- package/registry/examples/app-shell/console.tsx +103 -0
- package/registry/examples/badge/native/dot.dark.png +0 -0
- package/registry/examples/badge/native/dot.light.png +0 -0
- package/registry/examples/badge/native/scrim.dark.png +0 -0
- package/registry/examples/badge/native/scrim.light.png +0 -0
- package/registry/examples/badge/native/tones.dark.png +0 -0
- package/registry/examples/badge/native/tones.light.png +0 -0
- package/registry/examples/card/native/default.dark.png +0 -0
- package/registry/examples/card/native/default.light.png +0 -0
- package/registry/examples/card/native/elevated.light.png +0 -0
- package/registry/examples/chip/native/multiple.dark.png +0 -0
- package/registry/examples/chip/native/multiple.light.png +0 -0
- package/registry/examples/chip/native/removable.dark.png +0 -0
- package/registry/examples/chip/native/removable.light.png +0 -0
- package/registry/examples/chip/native/single.dark.png +0 -0
- package/registry/examples/chip/native/single.light.png +0 -0
- package/registry/examples/chip/native/toggle.dark.png +0 -0
- package/registry/examples/chip/native/toggle.light.png +0 -0
- package/registry/examples/code-block/annotated.d.ts +4 -0
- package/registry/examples/code-block/annotated.js +31 -0
- package/registry/examples/code-block/annotated.tsx +26 -0
- package/registry/examples/component-page/button.tsx +1 -1
- package/registry/examples/form/native/amount.dark.png +0 -0
- package/registry/examples/form/native/amount.light.png +0 -0
- package/registry/examples/markdown/ai-stream.d.ts +4 -0
- package/registry/examples/markdown/ai-stream.js +31 -0
- package/registry/examples/markdown/ai-stream.tsx +32 -0
- package/registry/examples/markdown/basic.d.ts +4 -0
- package/registry/examples/markdown/basic.js +26 -0
- package/registry/examples/markdown/basic.tsx +22 -0
- package/registry/examples/markdown/native/ai-stream.d.ts +4 -0
- package/registry/examples/markdown/native/ai-stream.dark.png +0 -0
- package/registry/examples/markdown/native/ai-stream.js +17 -0
- package/registry/examples/markdown/native/ai-stream.light.png +0 -0
- package/registry/examples/markdown/native/ai-stream.tsx +17 -0
- package/registry/examples/markdown/native/basic.d.ts +4 -0
- package/registry/examples/markdown/native/basic.dark.png +0 -0
- package/registry/examples/markdown/native/basic.js +28 -0
- package/registry/examples/markdown/native/basic.light.png +0 -0
- package/registry/examples/markdown/native/basic.tsx +27 -0
- package/registry/examples/nav-bar/family-admin.d.ts +4 -0
- package/registry/examples/nav-bar/family-admin.js +21 -0
- package/registry/examples/nav-bar/family-admin.tsx +20 -0
- package/registry/examples/nav-bar/family-java.d.ts +4 -0
- package/registry/examples/nav-bar/family-java.js +33 -0
- package/registry/examples/nav-bar/family-java.tsx +34 -0
- package/registry/examples/nav-bar/family-product.d.ts +4 -0
- package/registry/examples/nav-bar/family-product.js +35 -0
- package/registry/examples/nav-bar/family-product.tsx +39 -0
- package/registry/examples/nav-bar/family-ui.d.ts +4 -0
- package/registry/examples/nav-bar/family-ui.js +34 -0
- package/registry/examples/nav-bar/family-ui.tsx +35 -0
- package/registry/examples/nav-bar/family-www.d.ts +4 -0
- package/registry/examples/nav-bar/family-www.js +34 -0
- package/registry/examples/nav-bar/family-www.tsx +36 -0
- package/registry/examples/recipes/tone-chip.d.ts +4 -0
- package/registry/examples/recipes/tone-chip.js +46 -0
- package/registry/examples/recipes/tone-chip.tsx +32 -0
- package/registry/examples/screen/native/profile.dark.png +0 -0
- package/registry/examples/screen/native/profile.light.png +0 -0
- package/registry/examples/showcase/native/slides.d.ts +4 -0
- package/registry/examples/showcase/native/slides.dark.png +0 -0
- package/registry/examples/showcase/native/slides.js +27 -0
- package/registry/examples/showcase/native/slides.light.png +0 -0
- package/registry/examples/showcase/native/slides.tsx +28 -0
- package/registry/examples/showcase/prompt-image.d.ts +4 -0
- package/registry/examples/showcase/prompt-image.js +29 -0
- package/registry/examples/showcase/prompt-image.tsx +28 -0
- package/registry/examples/showcase/slides.d.ts +4 -0
- package/registry/examples/showcase/slides.js +29 -0
- package/registry/examples/showcase/slides.tsx +24 -0
- package/registry/examples/site-footer/company.d.ts +4 -0
- package/registry/examples/site-footer/company.js +26 -0
- package/registry/examples/site-footer/company.tsx +23 -0
- package/registry/examples/site-footer/open-source-fr.d.ts +4 -0
- package/registry/examples/site-footer/open-source-fr.js +17 -0
- package/registry/examples/site-footer/open-source-fr.tsx +17 -0
- package/registry/examples/site-footer/product.d.ts +4 -0
- package/registry/examples/site-footer/product.js +22 -0
- package/registry/examples/site-footer/product.tsx +19 -0
- package/registry/examples/sites/family.d.ts +4 -0
- package/registry/examples/sites/family.js +20 -0
- package/registry/examples/sites/family.tsx +30 -0
- package/registry/examples/sites/french.d.ts +4 -0
- package/registry/examples/sites/french.js +25 -0
- package/registry/examples/sites/french.tsx +25 -0
- package/registry/examples/tag-selector/native/interests.dark.png +0 -0
- package/registry/examples/tag-selector/native/interests.light.png +0 -0
- package/registry/field.json +1 -1
- package/registry/file-upload.json +8 -3
- package/registry/filter-bar.json +1 -1
- package/registry/form.json +2 -2
- package/registry/gallery-page.json +1 -1
- package/registry/glow-card.json +1 -1
- package/registry/goal-gauge.json +1 -1
- package/registry/how-it-works-page.json +1 -1
- package/registry/image-cropper.json +2 -2
- package/registry/index.json +138 -20
- package/registry/iso.json +1 -1
- package/registry/kanban.json +1 -1
- package/registry/kbd.json +1 -1
- package/registry/landing-page.json +1 -1
- package/registry/landscape.json +1 -1
- package/registry/legal-page.json +1 -1
- package/registry/link-card.json +1 -1
- package/registry/list.json +2 -2
- package/registry/loader.json +1 -1
- package/registry/longform-page.json +1 -1
- package/registry/map.json +3 -3
- package/registry/markdown.json +266 -0
- package/registry/marketing-layout.json +1 -1
- package/registry/marquee.json +1 -1
- package/registry/mascot-quote.json +1 -1
- package/registry/mascot-state.json +1 -1
- package/registry/mascots.json +1 -1
- package/registry/match-dialog.json +1 -1
- package/registry/media-capture.json +2 -2
- package/registry/meter.json +1 -1
- package/registry/nav-bar.json +257 -13
- package/registry/number-ticker.json +1 -1
- package/registry/page-header.json +1 -1
- package/registry/page-hero.json +1 -1
- package/registry/page.json +1 -1
- package/registry/pagination.json +1 -1
- package/registry/photo-grid.json +1 -1
- package/registry/pointer-light.json +1 -1
- package/registry/popover.json +1 -1
- package/registry/pricing-page.json +1 -1
- package/registry/product-page.json +1 -1
- package/registry/profile-card.json +1 -1
- package/registry/progress.json +1 -1
- package/registry/promise-card.json +1 -1
- package/registry/radio-group.json +1 -1
- package/registry/recipes.json +99 -0
- package/registry/scroll-stage.json +1 -1
- package/registry/search-field.json +4 -3
- package/registry/section-backdrop.json +1 -1
- package/registry/separator.json +1 -1
- package/registry/settings-layout.json +1 -1
- package/registry/showcase.json +421 -0
- package/registry/site-footer.json +389 -0
- package/registry/sites.json +93 -0
- package/registry/skeleton.json +1 -1
- package/registry/skip-link.json +1 -1
- package/registry/slider.json +1 -1
- package/registry/slot.json +1 -1
- package/registry/spinner.json +1 -1
- package/registry/split-view.json +1 -1
- package/registry/stage-banner.json +1 -1
- package/registry/stat.json +1 -1
- package/registry/status-page.json +1 -1
- package/registry/step-progress.json +1 -1
- package/registry/stepper.json +1 -1
- package/registry/swipe-deck.json +2 -2
- package/registry/switch.json +1 -1
- package/registry/tabs.json +1 -1
- package/registry/tag-input.json +2 -2
- package/registry/tag-selector.json +1 -1
- package/registry/terminal-replay.json +1 -1
- package/registry/theme.json +1 -1
- package/registry/toast.json +1 -1
- package/registry/toc.json +1 -1
- package/registry/tooltip.json +1 -1
- package/registry/tree-view.json +2 -2
- package/registry/verified-badge.json +1 -1
- package/registry/vertical-video.json +2 -2
- package/registry/video-player.json +2 -2
- package/registry/video-trimmer.json +2 -2
- package/registry/virtual.json +2 -2
- package/dist/button-BMAO7dKF.d.ts +0 -114
- package/dist/chunk-BRKMQ6JV.js.map +0 -1
- package/dist/chunk-FDCMBWUU.js.map +0 -1
- package/dist/chunk-LCZXS6AK.js.map +0 -1
- package/dist/chunk-RUPNPMP3.js.map +0 -1
- package/dist/chunk-UOMP6VOZ.js.map +0 -1
- package/dist/chunk-YH4LMWRU.js.map +0 -1
- package/dist/chunk-Z6FUPB3Q.js.map +0 -1
- /package/dist/{chunk-ND3L5VHT.js.map → chunk-5Z7FWCV2.js.map} +0 -0
- /package/dist/{chunk-ZKVQGXLD.js.map → chunk-FKBHWS4N.js.map} +0 -0
- /package/dist/{chunk-HCNOOPZE.js.map → chunk-KVDB4GXV.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/button/button.tsx","../src/button/recipe.ts"],"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\";\nimport { buttonRecipe } from \"./recipe\";\n\nexport const buttonVariants = tv(buttonRecipe);\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","// The button's variants, written once as classes of the Krizaka tokens: the web wears them with `tv(buttonRecipe)`\n// (button.tsx), React Native reads the same classes into styles (native/button.tsx, `nativeRecipe`).\nimport { defineRecipe } from \"../recipes/define\";\n\nexport const buttonRecipe = defineRecipe({\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"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/recipes/define.ts"],"sourcesContent":["import type { TV } from \"tailwind-variants\";\n\n/** What a recipe is made of: the `tv()` options — `base`, `slots`, `variants`, `defaultVariants`, `compoundVariants`. */\nexport type RecipeConfig = Parameters<TV>[0];\n\n/**\n * A recipe is data: the variants of a component (a `variant`, a `size`, a `tone`…) as classes of the Krizaka tokens.\n * `defineRecipe` only keeps the literal types, so `tv(recipe)` is typed exactly as `tv({ … })` would be (the web side) and\n * `nativeRecipe(recipe)` reads the same classes into styles on the theme's roles (the native side, `./native`).\n *\n * Sizes are a variant dimension (`size: { sm: \"h-8 px-3 text-xs\" }`); states are the prefixes (`hover:`, `disabled:`,\n * `data-[state=on]:`). Write colours as roles (`bg-accent`, `text-fg-secondary`, `border-border-default`, `ring-accent/40`),\n * spacing as Tailwind units (`h-10`, `px-4`), type as `text-sm` / `text-[11px]` / `font-semibold`.\n */\nexport function defineRecipe<const C extends RecipeConfig>(config: C): C {\n return config;\n}\n"],"mappings":";AAcO,SAAS,aAA2C,QAAc;AACvE,SAAO;AACT;","names":[]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import {
|
|
3
3
|
IconButton
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-OWC2LZD2.js";
|
|
5
5
|
|
|
6
6
|
// src/dialog/dialog.tsx
|
|
7
7
|
import { Dialog as DialogPrimitive } from "radix-ui";
|
|
@@ -143,4 +143,4 @@ export {
|
|
|
143
143
|
Dialog,
|
|
144
144
|
Sheet
|
|
145
145
|
};
|
|
146
|
-
//# sourceMappingURL=chunk-
|
|
146
|
+
//# sourceMappingURL=chunk-5Z7FWCV2.js.map
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
"use client";
|
|
2
|
+
import {
|
|
3
|
+
defineRecipe
|
|
4
|
+
} from "./chunk-D3T54RSL.js";
|
|
2
5
|
|
|
3
6
|
// src/chip/chip.tsx
|
|
4
7
|
import { Toggle as TogglePrimitive, ToggleGroup as ToggleGroupPrimitive } from "radix-ui";
|
|
5
8
|
import * as React from "react";
|
|
6
9
|
import { tv } from "tailwind-variants";
|
|
7
|
-
|
|
8
|
-
|
|
10
|
+
|
|
11
|
+
// src/chip/recipe.ts
|
|
12
|
+
var chipRecipe = defineRecipe({
|
|
9
13
|
slots: {
|
|
10
14
|
group: "flex flex-wrap items-center gap-2 data-[orientation=vertical]:flex-col data-[orientation=vertical]:items-stretch",
|
|
11
15
|
base: "inline-flex shrink-0 select-none items-center justify-center gap-1.5 whitespace-nowrap rounded-full border font-semibold transition-colors focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-40 border-border-default bg-surface-1 text-fg-secondary hover:border-border-strong hover:text-fg data-[state=on]:border-accent data-[state=on]:bg-accent-soft data-[state=on]:text-fg",
|
|
@@ -16,6 +20,10 @@ var chip = tv({
|
|
|
16
20
|
},
|
|
17
21
|
defaultVariants: { size: "md" }
|
|
18
22
|
});
|
|
23
|
+
|
|
24
|
+
// src/chip/chip.tsx
|
|
25
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
26
|
+
var chip = tv(chipRecipe);
|
|
19
27
|
var ChipGroupContext = React.createContext(null);
|
|
20
28
|
function RemoveIcon() {
|
|
21
29
|
return /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", className: "h-3.5 w-3.5", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx("path", { d: "M18 6 6 18M6 6l12 12" }) });
|
|
@@ -89,4 +97,4 @@ var Chip = Object.assign(ChipBase, { Group: ChipGroup });
|
|
|
89
97
|
export {
|
|
90
98
|
Chip
|
|
91
99
|
};
|
|
92
|
-
//# sourceMappingURL=chunk-
|
|
100
|
+
//# sourceMappingURL=chunk-7UCPGXKN.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/chip/chip.tsx","../src/chip/recipe.ts"],"sourcesContent":["// Client (a context). A chip is a pressable pill: alone it is a Radix Toggle (aria-pressed), inside `Chip.Group` an\n// item of a Radix Toggle Group (roving focus with the arrows; `single` = radio semantics, `multiple` = pressed\n// buttons). A `removable` chip is a static label with its own remove button (two buttons cannot nest).\nimport { Toggle as TogglePrimitive, ToggleGroup as ToggleGroupPrimitive } from \"radix-ui\";\nimport * as React from \"react\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\n\nimport { chipRecipe } from \"./recipe\";\n\nexport const chip = tv(chipRecipe);\n\nexport type ChipVariants = VariantProps<typeof chip>;\n\ntype GroupContext = { size: ChipVariants[\"size\"] };\nconst ChipGroupContext = React.createContext<GroupContext | null>(null);\n\nfunction RemoveIcon() {\n return (\n <svg viewBox=\"0 0 24 24\" className=\"h-3.5 w-3.5\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\" strokeLinecap=\"round\" aria-hidden>\n <path d=\"M18 6 6 18M6 6l12 12\" />\n </svg>\n );\n}\n\ntype ToggleChipProps = Omit<React.ComponentProps<\"button\">, \"value\" | \"defaultValue\"> &\n ChipVariants & {\n /**\n * sm · md (inside `Chip.Group`, the group's size by default).\n * @default \"md\"\n */\n size?: ChipVariants[\"size\"];\n /** Inside `Chip.Group`: the value this chip stands for (required there, ignored alone). */\n value?: string;\n /** Alone: pressed or not (`defaultSelected` uncontrolled), `onSelectedChange` on every press. */\n selected?: boolean;\n /** Alone: pressed at first, uncontrolled. */\n defaultSelected?: boolean;\n /** Alone: called with the new state on every press. */\n onSelectedChange?: (selected: boolean) => void;\n /** A pressable chip (the default); `true` makes it a static chip with a remove button. */\n removable?: false;\n };\n\ntype RemovableChipProps = Omit<React.ComponentProps<\"span\">, \"onSelect\"> &\n ChipVariants & {\n /** A static chip (a chosen tag, an applied filter) with a remove button. */\n removable: true;\n /** The accessible name of the remove button — passed translated, e.g. \"Remove #night\". */\n removeLabel: string;\n /** Runs when the remove button is pressed. */\n onRemove: () => void;\n /** Disables the remove button. */\n disabled?: boolean;\n };\n\nexport type ChipProps = ToggleChipProps | RemovableChipProps;\n\n/** A selectable pill (`selected` / `onSelectedChange`), an item of `Chip.Group` (`value`), or `removable`. */\nfunction ChipBase(props: ChipProps) {\n const group = React.useContext(ChipGroupContext);\n if (props.removable) {\n const { removable: _removable, removeLabel, onRemove, disabled, size, className, children, ...rest } = props;\n const s = chip({ size: size ?? group?.size });\n return (\n <span data-removable=\"\" className={s.base({ className })} {...rest}>\n {children}\n <button type=\"button\" aria-label={removeLabel} title={removeLabel} disabled={disabled} onClick={onRemove} className={s.remove()}>\n <RemoveIcon />\n </button>\n </span>\n );\n }\n const { removable: _removable, value, selected, defaultSelected, onSelectedChange, size, className, ...rest } = props;\n const s = chip({ size: size ?? group?.size });\n if (group) {\n if (value === undefined) throw new Error(\"Chip: a chip inside Chip.Group needs a `value`.\");\n return <ToggleGroupPrimitive.Item value={value} className={s.base({ className })} {...rest} />;\n }\n return (\n <TogglePrimitive.Root\n pressed={selected}\n defaultPressed={defaultSelected}\n onPressedChange={onSelectedChange}\n className={s.base({ className })}\n {...rest}\n />\n );\n}\n\ntype GroupBase = Omit<React.ComponentProps<\"div\">, \"defaultValue\" | \"dir\"> &\n ChipVariants & {\n /**\n * sm · md: the size of every chip of the group.\n * @default \"md\"\n */\n size?: ChipVariants[\"size\"];\n /** The group's accessible name — passed translated (\"Filter by format\"). */\n label?: string;\n /** The arrow keys that move: left / right (horizontal, a row) or up / down (vertical, a column). */\n orientation?: \"horizontal\" | \"vertical\";\n /** Arrow keys wrap from the last chip to the first (default `true`). */\n loop?: boolean;\n /** Disables every chip of the group. */\n disabled?: boolean;\n };\n\nexport type ChipGroupProps =\n | (GroupBase & {\n /** One choice: the chips behave as radios. */\n type: \"single\";\n /** The chosen value (controlled), `\"\"` when none. */\n value?: string;\n /** The value chosen at first, uncontrolled. */\n defaultValue?: string;\n /** Called with the new value on every choice. */\n onValueChange?: (value: string) => void;\n /** Keeps one chip selected: pressing the selected chip does not clear it (default `false`). */\n required?: boolean;\n })\n | (GroupBase & {\n /** Any number of choices: the chips are pressed buttons. */\n type: \"multiple\";\n /** The chosen values (controlled). */\n value?: string[];\n /** The values chosen at first, uncontrolled. */\n defaultValue?: string[];\n /** Called with the new values on every press. */\n onValueChange?: (value: string[]) => void;\n required?: never;\n });\n\n/** Chips that choose together: `type` single · multiple, `value`/`defaultValue` + `onValueChange`. */\nexport function ChipGroup({ label, size, className, children, ...props }: ChipGroupProps) {\n const s = chip({ size });\n const context = React.useMemo(() => ({ size }), [size]);\n const common = { \"aria-label\": label, className: s.group({ className }) };\n let group: React.ReactNode;\n if (props.type === \"single\") {\n const { type: _type, value, defaultValue, onValueChange, required, ...rest } = props;\n group = <SingleGroup {...rest} {...common} value={value} defaultValue={defaultValue} onValueChange={onValueChange} required={required}>{children}</SingleGroup>;\n } else {\n const { type: _type, required: _required, ...rest } = props;\n group = (\n <ToggleGroupPrimitive.Root type=\"multiple\" {...rest} {...common}>\n {children}\n </ToggleGroupPrimitive.Root>\n );\n }\n return <ChipGroupContext.Provider value={context}>{group}</ChipGroupContext.Provider>;\n}\n\n/** Radix's single group, plus `required`: the value is held here so that an empty change can be refused. */\nfunction SingleGroup({\n value,\n defaultValue,\n onValueChange,\n required,\n ...props\n}: Omit<GroupBase, \"size\" | \"label\"> & {\n value?: string;\n defaultValue?: string;\n onValueChange?: (value: string) => void;\n required?: boolean;\n}) {\n const [inner, setInner] = React.useState(defaultValue ?? \"\");\n const current = value ?? inner;\n return (\n <ToggleGroupPrimitive.Root\n type=\"single\"\n value={current}\n onValueChange={(next) => {\n if (required && !next) return;\n if (value === undefined) setInner(next);\n onValueChange?.(next);\n }}\n {...props}\n />\n );\n}\n\n/** `Chip` (selectable, removable) and `Chip.Group` (single · multiple). */\nexport const Chip = Object.assign(ChipBase, { Group: ChipGroup });\n","// The chip's parts and sizes, written once as classes of the Krizaka tokens: the web wears them with `tv(chipRecipe)`,\n// React Native reads the same classes into styles (native/chip.tsx). `data-[state=on]:` is the chosen chip.\nimport { defineRecipe } from \"../recipes/define\";\n\nexport const chipRecipe = defineRecipe({\n slots: {\n group: \"flex flex-wrap items-center gap-2 data-[orientation=vertical]:flex-col data-[orientation=vertical]:items-stretch\",\n base:\n \"inline-flex shrink-0 select-none items-center justify-center gap-1.5 whitespace-nowrap rounded-full border font-semibold transition-colors \" +\n \"focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-40 \" +\n \"border-border-default bg-surface-1 text-fg-secondary hover:border-border-strong hover:text-fg \" +\n \"data-[state=on]:border-accent data-[state=on]:bg-accent-soft data-[state=on]:text-fg\",\n remove:\n \"-mr-1.5 inline-flex h-6 w-6 items-center justify-center rounded-full text-fg-secondary transition-colors hover:bg-surface-3 hover:text-fg \" +\n \"focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring\",\n },\n variants: {\n size: { sm: { base: \"h-7 px-3 text-xs\" }, md: { base: \"h-9 px-3.5 text-xs\" } },\n },\n defaultVariants: { size: \"md\" },\n});\n"],"mappings":"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","names":["_removable","size","className","rest","s"]}
|
|
@@ -19,6 +19,10 @@ function Glyph({ className = "h-4 w-4", fill, children }) {
|
|
|
19
19
|
}
|
|
20
20
|
);
|
|
21
21
|
}
|
|
22
|
+
var SearchGlyph = (p) => /* @__PURE__ */ jsxs(Glyph, { ...p, children: [
|
|
23
|
+
/* @__PURE__ */ jsx("circle", { cx: "11", cy: "11", r: "7" }),
|
|
24
|
+
/* @__PURE__ */ jsx("path", { d: "m20 20-3.5-3.5" })
|
|
25
|
+
] });
|
|
22
26
|
var CloseGlyph = (p) => /* @__PURE__ */ jsx(Glyph, { ...p, children: /* @__PURE__ */ jsx("path", { d: "M18 6 6 18M6 6l12 12" }) });
|
|
23
27
|
var ChevronGlyph = ({ direction = "down", ...p }) => /* @__PURE__ */ jsx(Glyph, { ...p, children: /* @__PURE__ */ jsx("path", { d: { left: "m15 6-6 6 6 6", right: "m9 6 6 6-6 6", up: "m6 15 6-6 6 6", down: "m6 9 6 6 6-6" }[direction] }) });
|
|
24
28
|
var CheckGlyph = (p) => /* @__PURE__ */ jsx(Glyph, { ...p, children: /* @__PURE__ */ jsx("path", { d: "M20 6 9 17l-5-5" }) });
|
|
@@ -28,9 +32,10 @@ var CopyGlyph = (p) => /* @__PURE__ */ jsxs(Glyph, { ...p, children: [
|
|
|
28
32
|
] });
|
|
29
33
|
|
|
30
34
|
export {
|
|
35
|
+
SearchGlyph,
|
|
31
36
|
CloseGlyph,
|
|
32
37
|
ChevronGlyph,
|
|
33
38
|
CheckGlyph,
|
|
34
39
|
CopyGlyph
|
|
35
40
|
};
|
|
36
|
-
//# sourceMappingURL=chunk-
|
|
41
|
+
//# sourceMappingURL=chunk-AFY35UCB.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/glyphs.tsx"],"sourcesContent":["// The small line glyphs the data and media primitives draw (play, volume, search, chevrons…): decorative, 24-unit\n// box, `currentColor`, sized by the caller's class. Shared by the entries that need them; never exported on its own —\n// a product draws its own icons with @krizaka/icons.\nimport type * as React from \"react\";\n\ntype GlyphProps = { className?: string };\n\nfunction Glyph({ className = \"h-4 w-4\", fill, children }: GlyphProps & { fill?: boolean; children: React.ReactNode }) {\n return (\n <svg\n viewBox=\"0 0 24 24\"\n className={className}\n fill={fill ? \"currentColor\" : \"none\"}\n stroke={fill ? \"none\" : \"currentColor\"}\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden\n focusable=\"false\"\n >\n {children}\n </svg>\n );\n}\n\nexport const PlayGlyph = (p: GlyphProps) => (\n <Glyph {...p} fill>\n <path d=\"M8 5.5v13a1 1 0 0 0 1.5.86l10.4-6.5a1 1 0 0 0 0-1.72L9.5 4.64A1 1 0 0 0 8 5.5Z\" />\n </Glyph>\n);\nexport const PauseGlyph = (p: GlyphProps) => (\n <Glyph {...p} fill>\n <rect x=\"6\" y=\"5\" width=\"4\" height=\"14\" rx=\"1\" />\n <rect x=\"14\" y=\"5\" width=\"4\" height=\"14\" rx=\"1\" />\n </Glyph>\n);\nexport const VolumeGlyph = ({ muted, ...p }: GlyphProps & { muted?: boolean }) => (\n <Glyph {...p}>\n <path d=\"M11 5 6 9H3v6h3l5 4V5Z\" />\n {muted ? <path d=\"m22 9-6 6m0-6 6 6\" /> : <path d=\"M15.5 8.5a5 5 0 0 1 0 7M18.5 5.5a9 9 0 0 1 0 13\" />}\n </Glyph>\n);\nexport const FullscreenGlyph = ({ exit, ...p }: GlyphProps & { exit?: boolean }) => (\n <Glyph {...p}>\n {exit ? <path d=\"M9 4v5H4m11-5v5h5M9 20v-5H4m11 5v-5h5\" /> : <path d=\"M4 9V4h5m6 0h5v5M4 15v5h5m11-5v5h-5\" />}\n </Glyph>\n);\nexport const CaptionsGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <rect x=\"3\" y=\"5\" width=\"18\" height=\"14\" rx=\"2\" />\n <path d=\"M10 10.5a2 2 0 1 0 0 3M17 10.5a2 2 0 1 0 0 3\" />\n </Glyph>\n);\nexport const PipGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <rect x=\"3\" y=\"5\" width=\"18\" height=\"14\" rx=\"2\" />\n <rect x=\"12\" y=\"12\" width=\"6\" height=\"4\" rx=\"1\" />\n </Glyph>\n);\nexport const SearchGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <circle cx=\"11\" cy=\"11\" r=\"7\" />\n <path d=\"m20 20-3.5-3.5\" />\n </Glyph>\n);\nexport const CloseGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <path d=\"M18 6 6 18M6 6l12 12\" />\n </Glyph>\n);\nexport const ChevronGlyph = ({ direction = \"down\", ...p }: GlyphProps & { direction?: \"left\" | \"right\" | \"up\" | \"down\" }) => (\n <Glyph {...p}>\n <path d={{ left: \"m15 6-6 6 6 6\", right: \"m9 6 6 6-6 6\", up: \"m6 15 6-6 6 6\", down: \"m6 9 6 6 6-6\" }[direction]} />\n </Glyph>\n);\nexport const CheckGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <path d=\"M20 6 9 17l-5-5\" />\n </Glyph>\n);\nexport const PlusGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <path d=\"M12 5v14M5 12h14\" />\n </Glyph>\n);\nexport const CalendarGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <rect x=\"3\" y=\"5\" width=\"18\" height=\"16\" rx=\"2\" />\n <path d=\"M3 10h18M8 3v4M16 3v4\" />\n </Glyph>\n);\nexport const UploadGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <path d=\"M12 16V4m0 0L7 9m5-5 5 5\" />\n <path d=\"M4 16v2a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-2\" />\n </Glyph>\n);\nexport const FileGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <path d=\"M14 3H7a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V8l-5-5Z\" />\n <path d=\"M14 3v5h5\" />\n </Glyph>\n);\nexport const CameraGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <path d=\"M4 8h3l2-3h6l2 3h3a1 1 0 0 1 1 1v10a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V9a1 1 0 0 1 1-1Z\" />\n <circle cx=\"12\" cy=\"13.5\" r=\"3.5\" />\n </Glyph>\n);\nexport const FlipGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <path d=\"M4 12a8 8 0 0 1 14-5.3M20 12a8 8 0 0 1-14 5.3\" />\n <path d=\"M18 3v4h-4M6 21v-4h4\" />\n </Glyph>\n);\nexport const RetryGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <path d=\"M4 12a8 8 0 1 0 2.3-5.7L4 8.5\" />\n <path d=\"M4 4v4.5h4.5\" />\n </Glyph>\n);\nexport const SortGlyph = ({ direction, ...p }: GlyphProps & { direction?: \"ascending\" | \"descending\" }) => (\n <Glyph {...p}>\n {direction === \"ascending\" ? <path d=\"m7 14 5-5 5 5\" /> : direction === \"descending\" ? <path d=\"m7 10 5 5 5-5\" /> : <path d=\"m8 9 4-4 4 4M8 15l4 4 4-4\" />}\n </Glyph>\n);\nexport const ArrowGlyph = ({ direction = \"right\", ...p }: GlyphProps & { direction?: \"left\" | \"right\" }) => (\n <Glyph {...p}>\n <path d={direction === \"left\" ? \"M19 12H5m0 0 6-6m-6 6 6 6\" : \"M5 12h14m0 0-6-6m6 6-6 6\"} />\n </Glyph>\n);\nexport const ExternalGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <path d=\"M14 4h6v6M20 4l-9 9\" />\n <path d=\"M18 14v4a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4\" />\n </Glyph>\n);\nexport const WarningGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <path d=\"M12 4 2.5 20h19L12 4Z\" />\n <path d=\"M12 10v4M12 17.2v.1\" />\n </Glyph>\n);\nexport const CopyGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <rect x=\"9\" y=\"9\" width=\"11\" height=\"11\" rx=\"2\" />\n <path d=\"M15 9V6a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v7a2 2 0 0 0 2 2h3\" />\n </Glyph>\n);\n"],"mappings":";;;AASI,cAsBF,YAtBE;AAFJ,SAAS,MAAM,EAAE,YAAY,WAAW,MAAM,SAAS,GAA+D;AACpH,SACE;AAAA,IAAC;AAAA;AAAA,MACC,SAAQ;AAAA,MACR;AAAA,MACA,MAAM,OAAO,iBAAiB;AAAA,MAC9B,QAAQ,OAAO,SAAS;AAAA,MACxB,aAAY;AAAA,MACZ,eAAc;AAAA,MACd,gBAAe;AAAA,MACf,eAAW;AAAA,MACX,WAAU;AAAA,MAET;AAAA;AAAA,EACH;AAEJ;
|
|
1
|
+
{"version":3,"sources":["../src/glyphs.tsx"],"sourcesContent":["// The small line glyphs the data and media primitives draw (play, volume, search, chevrons…): decorative, 24-unit\n// box, `currentColor`, sized by the caller's class. Shared by the entries that need them; never exported on its own —\n// a product draws its own icons with @krizaka/icons.\nimport type * as React from \"react\";\n\ntype GlyphProps = { className?: string };\n\nfunction Glyph({ className = \"h-4 w-4\", fill, children }: GlyphProps & { fill?: boolean; children: React.ReactNode }) {\n return (\n <svg\n viewBox=\"0 0 24 24\"\n className={className}\n fill={fill ? \"currentColor\" : \"none\"}\n stroke={fill ? \"none\" : \"currentColor\"}\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden\n focusable=\"false\"\n >\n {children}\n </svg>\n );\n}\n\nexport const PlayGlyph = (p: GlyphProps) => (\n <Glyph {...p} fill>\n <path d=\"M8 5.5v13a1 1 0 0 0 1.5.86l10.4-6.5a1 1 0 0 0 0-1.72L9.5 4.64A1 1 0 0 0 8 5.5Z\" />\n </Glyph>\n);\nexport const PauseGlyph = (p: GlyphProps) => (\n <Glyph {...p} fill>\n <rect x=\"6\" y=\"5\" width=\"4\" height=\"14\" rx=\"1\" />\n <rect x=\"14\" y=\"5\" width=\"4\" height=\"14\" rx=\"1\" />\n </Glyph>\n);\nexport const VolumeGlyph = ({ muted, ...p }: GlyphProps & { muted?: boolean }) => (\n <Glyph {...p}>\n <path d=\"M11 5 6 9H3v6h3l5 4V5Z\" />\n {muted ? <path d=\"m22 9-6 6m0-6 6 6\" /> : <path d=\"M15.5 8.5a5 5 0 0 1 0 7M18.5 5.5a9 9 0 0 1 0 13\" />}\n </Glyph>\n);\nexport const FullscreenGlyph = ({ exit, ...p }: GlyphProps & { exit?: boolean }) => (\n <Glyph {...p}>\n {exit ? <path d=\"M9 4v5H4m11-5v5h5M9 20v-5H4m11 5v-5h5\" /> : <path d=\"M4 9V4h5m6 0h5v5M4 15v5h5m11-5v5h-5\" />}\n </Glyph>\n);\nexport const CaptionsGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <rect x=\"3\" y=\"5\" width=\"18\" height=\"14\" rx=\"2\" />\n <path d=\"M10 10.5a2 2 0 1 0 0 3M17 10.5a2 2 0 1 0 0 3\" />\n </Glyph>\n);\nexport const PipGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <rect x=\"3\" y=\"5\" width=\"18\" height=\"14\" rx=\"2\" />\n <rect x=\"12\" y=\"12\" width=\"6\" height=\"4\" rx=\"1\" />\n </Glyph>\n);\nexport const SearchGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <circle cx=\"11\" cy=\"11\" r=\"7\" />\n <path d=\"m20 20-3.5-3.5\" />\n </Glyph>\n);\nexport const CloseGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <path d=\"M18 6 6 18M6 6l12 12\" />\n </Glyph>\n);\nexport const ChevronGlyph = ({ direction = \"down\", ...p }: GlyphProps & { direction?: \"left\" | \"right\" | \"up\" | \"down\" }) => (\n <Glyph {...p}>\n <path d={{ left: \"m15 6-6 6 6 6\", right: \"m9 6 6 6-6 6\", up: \"m6 15 6-6 6 6\", down: \"m6 9 6 6 6-6\" }[direction]} />\n </Glyph>\n);\nexport const CheckGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <path d=\"M20 6 9 17l-5-5\" />\n </Glyph>\n);\nexport const PlusGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <path d=\"M12 5v14M5 12h14\" />\n </Glyph>\n);\nexport const CalendarGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <rect x=\"3\" y=\"5\" width=\"18\" height=\"16\" rx=\"2\" />\n <path d=\"M3 10h18M8 3v4M16 3v4\" />\n </Glyph>\n);\nexport const UploadGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <path d=\"M12 16V4m0 0L7 9m5-5 5 5\" />\n <path d=\"M4 16v2a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-2\" />\n </Glyph>\n);\nexport const FileGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <path d=\"M14 3H7a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V8l-5-5Z\" />\n <path d=\"M14 3v5h5\" />\n </Glyph>\n);\nexport const CameraGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <path d=\"M4 8h3l2-3h6l2 3h3a1 1 0 0 1 1 1v10a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V9a1 1 0 0 1 1-1Z\" />\n <circle cx=\"12\" cy=\"13.5\" r=\"3.5\" />\n </Glyph>\n);\nexport const FlipGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <path d=\"M4 12a8 8 0 0 1 14-5.3M20 12a8 8 0 0 1-14 5.3\" />\n <path d=\"M18 3v4h-4M6 21v-4h4\" />\n </Glyph>\n);\nexport const RetryGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <path d=\"M4 12a8 8 0 1 0 2.3-5.7L4 8.5\" />\n <path d=\"M4 4v4.5h4.5\" />\n </Glyph>\n);\nexport const SortGlyph = ({ direction, ...p }: GlyphProps & { direction?: \"ascending\" | \"descending\" }) => (\n <Glyph {...p}>\n {direction === \"ascending\" ? <path d=\"m7 14 5-5 5 5\" /> : direction === \"descending\" ? <path d=\"m7 10 5 5 5-5\" /> : <path d=\"m8 9 4-4 4 4M8 15l4 4 4-4\" />}\n </Glyph>\n);\nexport const ArrowGlyph = ({ direction = \"right\", ...p }: GlyphProps & { direction?: \"left\" | \"right\" }) => (\n <Glyph {...p}>\n <path d={direction === \"left\" ? \"M19 12H5m0 0 6-6m-6 6 6 6\" : \"M5 12h14m0 0-6-6m6 6-6 6\"} />\n </Glyph>\n);\nexport const ExternalGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <path d=\"M14 4h6v6M20 4l-9 9\" />\n <path d=\"M18 14v4a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4\" />\n </Glyph>\n);\nexport const WarningGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <path d=\"M12 4 2.5 20h19L12 4Z\" />\n <path d=\"M12 10v4M12 17.2v.1\" />\n </Glyph>\n);\nexport const CopyGlyph = (p: GlyphProps) => (\n <Glyph {...p}>\n <rect x=\"9\" y=\"9\" width=\"11\" height=\"11\" rx=\"2\" />\n <path d=\"M15 9V6a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v7a2 2 0 0 0 2 2h3\" />\n </Glyph>\n);\n"],"mappings":";;;AASI,cAsBF,YAtBE;AAFJ,SAAS,MAAM,EAAE,YAAY,WAAW,MAAM,SAAS,GAA+D;AACpH,SACE;AAAA,IAAC;AAAA;AAAA,MACC,SAAQ;AAAA,MACR;AAAA,MACA,MAAM,OAAO,iBAAiB;AAAA,MAC9B,QAAQ,OAAO,SAAS;AAAA,MACxB,aAAY;AAAA,MACZ,eAAc;AAAA,MACd,gBAAe;AAAA,MACf,eAAW;AAAA,MACX,WAAU;AAAA,MAET;AAAA;AAAA,EACH;AAEJ;AAoCO,IAAM,cAAc,CAAC,MAC1B,qBAAC,SAAO,GAAG,GACT;AAAA,sBAAC,YAAO,IAAG,MAAK,IAAG,MAAK,GAAE,KAAI;AAAA,EAC9B,oBAAC,UAAK,GAAE,kBAAiB;AAAA,GAC3B;AAEK,IAAM,aAAa,CAAC,MACzB,oBAAC,SAAO,GAAG,GACT,8BAAC,UAAK,GAAE,wBAAuB,GACjC;AAEK,IAAM,eAAe,CAAC,EAAE,YAAY,QAAQ,GAAG,EAAE,MACtD,oBAAC,SAAO,GAAG,GACT,8BAAC,UAAK,GAAG,EAAE,MAAM,iBAAiB,OAAO,gBAAgB,IAAI,iBAAiB,MAAM,eAAe,EAAE,SAAS,GAAG,GACnH;AAEK,IAAM,aAAa,CAAC,MACzB,oBAAC,SAAO,GAAG,GACT,8BAAC,UAAK,GAAE,mBAAkB,GAC5B;AAiEK,IAAM,YAAY,CAAC,MACxB,qBAAC,SAAO,GAAG,GACT;AAAA,sBAAC,UAAK,GAAE,KAAI,GAAE,KAAI,OAAM,MAAK,QAAO,MAAK,IAAG,KAAI;AAAA,EAChD,oBAAC,UAAK,GAAE,2DAA0D;AAAA,GACpE;","names":[]}
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import {
|
|
3
3
|
Chip
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-7UCPGXKN.js";
|
|
5
5
|
import {
|
|
6
6
|
useListbox
|
|
7
7
|
} from "./chunk-ZIXB33X7.js";
|
|
8
8
|
import {
|
|
9
|
-
useControllable
|
|
10
|
-
|
|
11
|
-
} from "./chunk-BRKMQ6JV.js";
|
|
9
|
+
useControllable
|
|
10
|
+
} from "./chunk-FZBWEDQI.js";
|
|
12
11
|
import {
|
|
13
12
|
CheckGlyph,
|
|
14
13
|
ChevronGlyph,
|
|
@@ -17,6 +16,7 @@ import {
|
|
|
17
16
|
} from "./chunk-CPA5CF35.js";
|
|
18
17
|
|
|
19
18
|
// src/combobox/combobox.tsx
|
|
19
|
+
import { useDebouncedCallback } from "@krizaka/pacer/react";
|
|
20
20
|
import * as React from "react";
|
|
21
21
|
import { tv } from "tailwind-variants";
|
|
22
22
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -280,4 +280,4 @@ export {
|
|
|
280
280
|
comboboxLabels,
|
|
281
281
|
Combobox
|
|
282
282
|
};
|
|
283
|
-
//# sourceMappingURL=chunk-
|
|
283
|
+
//# sourceMappingURL=chunk-CKSHLSDH.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/combobox/combobox.tsx"],"sourcesContent":["// Client. The ARIA 1.2 combobox (`../listbox`): a text input that filters a listbox, the focus never leaves the input\n// (`aria-activedescendant`), the number of results announced in a polite live region. Static options filtered here,\n// or `onSearch` (debounced, the previous request aborted) for a server's; one value or several (chips, Backspace\n// removes the last), and new values created from the query when `creatable`.\nimport { useDebouncedCallback } from \"@krizaka/pacer/react\";\nimport * as React from \"react\";\nimport { tv } from \"tailwind-variants\";\n\nimport { Chip } from \"../chip\";\nimport { CheckGlyph, ChevronGlyph, CloseGlyph, PlusGlyph } from \"../glyphs\";\nimport { useListbox } from \"../listbox\";\nimport { useControllable } from \"../media\";\n\nexport const combobox = tv({\n slots: {\n root: \"relative flex w-full flex-col gap-1.5\",\n label: \"text-xs font-semibold text-fg-secondary\",\n control:\n \"flex min-h-11 w-full flex-wrap items-center gap-1.5 rounded-lg border border-border-default bg-surface-2 py-1.5 pl-2 pr-1 text-sm text-fg \" +\n \"transition-[border-color,box-shadow] focus-within:border-accent focus-within:ring-2 focus-within:ring-ring \" +\n \"data-[invalid]:border-danger data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50\",\n input: \"h-8 min-w-24 flex-1 bg-transparent px-1 text-sm text-fg outline-hidden placeholder:text-fg-muted disabled:cursor-not-allowed\",\n icon:\n \"inline-flex h-8 w-8 shrink-0 items-center justify-center rounded-md text-fg-secondary hover:bg-surface-3 hover:text-fg \" +\n \"focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring\",\n list: \"absolute inset-x-0 top-full z-50 mt-1 max-h-64 overflow-y-auto rounded-lg border border-border-default bg-surface-2 p-1 shadow-lg\",\n option:\n \"flex cursor-pointer select-none items-center gap-2.5 rounded-md px-2.5 py-2 text-sm text-fg \" +\n \"data-[active]:bg-surface-3 aria-disabled:cursor-not-allowed aria-disabled:opacity-40\",\n check: \"h-4 w-4 shrink-0 text-fg-accent\",\n description: \"block text-xs text-fg-secondary\",\n status: \"px-2.5 py-3 text-sm text-fg-secondary\",\n hint: \"text-xs text-fg-secondary\",\n error: \"flex items-center gap-1.5 text-xs font-medium text-fg-danger before:h-1.5 before:w-1.5 before:shrink-0 before:rounded-full before:bg-danger\",\n },\n});\n\nexport type ComboboxOption = {\n /** What the app stores. */\n value: string;\n /** What the person reads, passed translated. */\n label: string;\n /** A second line under the label. */\n description?: string;\n /** Shown but not choosable. */\n disabled?: boolean;\n};\n\nexport type ComboboxLabels = {\n /** No option matches (\"No results\"). */\n empty: string;\n /** While `onSearch` runs (\"Searching…\"). */\n loading: string;\n /** `onSearch` failed (\"Search unavailable\"). */\n error: string;\n /** The option that creates a value: `(query) => \"Create “\" + query + \"”\"`. */\n create: (query: string) => string;\n /** A chip's remove button: `(label) => \"Remove \" + label`. */\n remove: (label: string) => string;\n /** The button that empties a single choice (\"Clear\"). */\n clear: string;\n /** The button that opens the list (\"Show options\"). */\n toggle: string;\n /** Announced when the results change: `(n) => n + \" results\"`. */\n results: (count: number) => string;\n};\n\nexport const comboboxLabels: ComboboxLabels = {\n empty: \"No results\",\n loading: \"Searching…\",\n error: \"Search unavailable\",\n create: (query) => `Create “${query}”`,\n remove: (label) => `Remove ${label}`,\n clear: \"Clear\",\n toggle: \"Show options\",\n results: (count) => (count === 1 ? \"1 result\" : `${count} results`),\n};\n\ntype BaseProps = {\n /** The visible label of the field, passed translated (also its accessible name). */\n label: string;\n /** Hides the label visually, keeping it as the accessible name (a search bar with its own context). */\n hideLabel?: boolean;\n /** The options, filtered as the person types (by `filter`). */\n options?: readonly ComboboxOption[];\n /** Fetches the options for a query (debounced by `debounce`); the `signal` aborts when a newer query starts. */\n onSearch?: (query: string, signal: AbortSignal) => Promise<readonly ComboboxOption[]>;\n /** The wait, in ms, between the last key and `onSearch`. Default 250. */\n debounce?: number;\n /** Whether an option matches a query. Default: its label contains the query, ignoring case and accents. */\n filter?: (option: ComboboxOption, query: string) => boolean;\n /** Offers to create the query as a new value when no option has that exact label. */\n creatable?: boolean;\n /** Turns a query into the created option (an id from the server…). Default `{ value: query, label: query }`. */\n onCreate?: (query: string) => ComboboxOption;\n /** Keys that create the query at once, as Enter does (`[\",\"]` for tags); a paste is split on them too. */\n separators?: readonly string[];\n /** The input's placeholder, passed translated. */\n placeholder?: string;\n /** A help text under the field. */\n hint?: string;\n /** An error under the field: marks it invalid and is read with it. */\n error?: string;\n /** Not available. */\n disabled?: boolean;\n /** The name of a hidden input holding the value(s), for a plain `<form>` post. */\n name?: string;\n /** The words, passed translated; English by default. */\n labels?: Partial<ComboboxLabels>;\n /** Classes merged on the root. */\n className?: string;\n /** The id of the text input (default: generated). */\n id?: string;\n};\n\ntype SingleProps = BaseProps & {\n /** One value (default) or several. */\n multiple?: false;\n /** The chosen option (controlled), `null` for none. */\n value?: ComboboxOption | null;\n /** The chosen option at first, uncontrolled. */\n defaultValue?: ComboboxOption | null;\n /** Called with the chosen option, or `null` when it is cleared. */\n onValueChange?: (value: ComboboxOption | null) => void;\n /** Most options that can be chosen (several values only). */\n maxSelected?: never;\n};\n\ntype MultipleProps = BaseProps & {\n /** Several values, shown as chips. */\n multiple: true;\n /** The chosen options (controlled). */\n value?: readonly ComboboxOption[];\n /** The chosen options at first, uncontrolled. */\n defaultValue?: readonly ComboboxOption[];\n /** Called with every chosen option. */\n onValueChange?: (value: ComboboxOption[]) => void;\n /** Most options that can be chosen; the list stops offering more past it. */\n maxSelected?: number;\n};\n\nexport type ComboboxProps = SingleProps | MultipleProps;\n\nconst fold = (text: string) => text.normalize(\"NFD\").replace(/\\p{Diacritic}/gu, \"\").toLowerCase();\nconst defaultFilter = (option: ComboboxOption, query: string) => fold(option.label).includes(fold(query.trim()));\n\ntype Item = { kind: \"option\"; option: ComboboxOption } | { kind: \"create\"; query: string };\n\n/** A text field that suggests, filters and completes: one value or several (chips), static or fetched, creatable. */\nexport function Combobox(props: ComboboxProps) {\n const {\n label,\n hideLabel,\n options,\n onSearch,\n debounce = 250,\n filter = defaultFilter,\n creatable,\n onCreate = (query: string) => ({ value: query, label: query }),\n separators,\n placeholder,\n hint,\n error,\n disabled,\n name,\n labels: given,\n className,\n id: givenId,\n } = props;\n const labels = { ...comboboxLabels, ...given };\n const s = combobox();\n const autoId = React.useId();\n const inputId = givenId ?? `${autoId}-input`;\n const hintId = `${autoId}-hint`;\n const errorId = `${autoId}-error`;\n const multiple = props.multiple === true;\n\n const [values, setValues] = useControllable<readonly ComboboxOption[]>(\n props.value === undefined ? undefined : multiple ? (props.value as readonly ComboboxOption[]) : props.value ? [props.value as ComboboxOption] : [],\n multiple ? ((props.defaultValue as readonly ComboboxOption[]) ?? []) : props.defaultValue ? [props.defaultValue as ComboboxOption] : [],\n (next) => (multiple ? (props.onValueChange as ((v: ComboboxOption[]) => void) | undefined)?.([...next]) : (props.onValueChange as ((v: ComboboxOption | null) => void) | undefined)?.(next[0] ?? null)),\n );\n const single = multiple ? null : (values[0] ?? null);\n const [query, setQuery] = React.useState(single?.label ?? \"\");\n const [editing, setEditing] = React.useState(false);\n const [open, setOpenState] = React.useState(false);\n const [remote, setRemote] = React.useState<{ query: string; options: readonly ComboboxOption[]; state: \"idle\" | \"loading\" | \"error\" }>({ query: \"\", options: [], state: \"idle\" });\n const request = React.useRef<AbortController | null>(null);\n const inputRef = React.useRef<HTMLInputElement>(null);\n\n // The single choice's label shows in the input while the person is not typing.\n const shownQuery = !multiple && !editing ? (single?.label ?? \"\") : query;\n const searchQuery = editing ? query : \"\";\n\n const search = useDebouncedCallback((text: string) => {\n if (!onSearch) return;\n request.current?.abort();\n const controller = new AbortController();\n request.current = controller;\n onSearch(text, controller.signal).then(\n (found) => !controller.signal.aborted && setRemote({ query: text, options: found, state: \"idle\" }),\n () => !controller.signal.aborted && setRemote({ query: text, options: [], state: \"error\" }),\n );\n }, debounce);\n React.useEffect(() => () => request.current?.abort(), []);\n\n const setOpen = (next: boolean) => {\n if (next && onSearch && remote.state === \"idle\" && remote.query !== searchQuery) {\n setRemote((r) => ({ ...r, state: \"loading\" }));\n search(searchQuery);\n }\n setOpenState(next);\n };\n\n const chosen = new Set(values.map((v) => v.value));\n const source = onSearch ? remote.options : (options ?? []).filter((o) => !searchQuery.trim() || filter(o, searchQuery));\n const full = multiple && props.maxSelected !== undefined && values.length >= props.maxSelected;\n const trimmed = searchQuery.trim();\n const exact = [...source, ...values].some((o) => fold(o.label) === fold(trimmed));\n const items: Item[] = [\n ...source.map((option) => ({ kind: \"option\" as const, option })),\n ...(creatable && trimmed && !exact && !full ? [{ kind: \"create\" as const, query: trimmed }] : []),\n ];\n const isDisabled = (i: number) => {\n const item = items[i];\n if (!item) return true;\n if (item.kind === \"create\") return false;\n return Boolean(item.option.disabled) || (full && !chosen.has(item.option.value));\n };\n\n const commit = (option: ComboboxOption) => {\n if (multiple) {\n setValues(chosen.has(option.value) ? values.filter((v) => v.value !== option.value) : [...values, option]);\n setQuery(\"\");\n listbox.setActive(-1);\n } else {\n setValues([option]);\n setQuery(option.label);\n setEditing(false);\n setOpenState(false);\n }\n };\n const create = (text: string) => {\n const clean = text.trim();\n if (!clean || full) return;\n const existing = [...source, ...values].find((o) => fold(o.label) === fold(clean));\n if (multiple && existing && chosen.has(existing.value)) {\n setQuery(\"\");\n return;\n }\n commit(existing ?? onCreate(clean));\n };\n const pick = (i: number) => {\n const item = items[i];\n if (!item) return;\n if (item.kind === \"create\") create(item.query);\n else commit(item.option);\n };\n\n const listbox = useListbox({ count: items.length, isDisabled, onPick: pick, open, setOpen });\n\n const onChange = (text: string) => {\n setQuery(text);\n setEditing(true);\n listbox.setActive(-1);\n if (onSearch) {\n setRemote((r) => ({ ...r, state: \"loading\" }));\n search(text);\n }\n setOpenState(true);\n if (!multiple && text === \"\" && single) setValues([]);\n };\n\n const onKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {\n if (separators?.includes(event.key) && query.trim()) {\n event.preventDefault();\n create(query);\n return;\n }\n if (listbox.onKeyDown(event)) return;\n if (event.key === \"Enter\" && creatable && query.trim()) {\n event.preventDefault();\n create(query);\n } else if (event.key === \"Backspace\" && multiple && query === \"\" && values.length > 0) {\n setValues(values.slice(0, -1));\n } else if (event.key === \"Escape\" && !multiple && editing) {\n setEditing(false);\n setQuery(single?.label ?? \"\");\n }\n };\n\n const onPaste = (event: React.ClipboardEvent<HTMLInputElement>) => {\n if (!separators?.length || !multiple) return;\n const text = event.clipboardData.getData(\"text\");\n const parts = text.split(new RegExp(`[${separators.map((c) => c.replace(/[\\\\\\]^-]/g, \"\\\\$&\")).join(\"\")}\\\\n]`)).map((p) => p.trim()).filter(Boolean);\n if (parts.length < 2) return;\n event.preventDefault();\n const next = [...values];\n for (const part of parts) {\n if (props.maxSelected !== undefined && next.length >= props.maxSelected) break;\n if (next.some((v) => fold(v.label) === fold(part))) continue;\n next.push((options ?? []).find((o) => fold(o.label) === fold(part)) ?? onCreate(part));\n }\n setValues(next);\n };\n\n const loading = Boolean(onSearch) && remote.state === \"loading\";\n const failed = Boolean(onSearch) && remote.state === \"error\";\n const describedBy = [hint ? hintId : null, error ? errorId : null].filter(Boolean).join(\" \") || undefined;\n\n return (\n <div\n className={s.root({ className })}\n onBlur={(event) => {\n if (event.currentTarget.contains(event.relatedTarget as Node | null)) return;\n setOpenState(false);\n if (!multiple) {\n setEditing(false);\n setQuery(single?.label ?? \"\");\n }\n }}\n >\n <label htmlFor={inputId} className={hideLabel ? \"sr-only\" : s.label()}>\n {label}\n </label>\n <div className={s.control()} data-invalid={error ? \"\" : undefined} data-disabled={disabled ? \"\" : undefined} onMouseDown={(event) => {\n if (event.target === event.currentTarget) {\n event.preventDefault();\n inputRef.current?.focus();\n }\n }}>\n {multiple &&\n values.map((option) => (\n <Chip key={option.value} size=\"sm\" removable removeLabel={labels.remove(option.label)} disabled={disabled} onRemove={() => setValues(values.filter((v) => v.value !== option.value))}>\n {option.label}\n </Chip>\n ))}\n <input\n ref={inputRef}\n id={inputId}\n type=\"text\"\n autoComplete=\"off\"\n spellCheck={false}\n {...listbox.inputProps}\n aria-describedby={describedBy}\n aria-invalid={error ? true : undefined}\n aria-busy={loading || undefined}\n value={shownQuery}\n placeholder={multiple && values.length > 0 ? undefined : placeholder}\n disabled={disabled}\n className={s.input()}\n onChange={(event) => onChange(event.target.value)}\n onKeyDown={onKeyDown}\n onPaste={onPaste}\n onClick={() => !open && setOpen(true)}\n />\n {!multiple && single && !disabled ? (\n <button type=\"button\" aria-label={labels.clear} className={s.icon()} onClick={() => {\n setValues([]);\n setQuery(\"\");\n inputRef.current?.focus();\n }}>\n <CloseGlyph className=\"h-4 w-4\" />\n </button>\n ) : null}\n <button type=\"button\" tabIndex={-1} aria-label={labels.toggle} aria-expanded={open} aria-controls={listbox.listId} disabled={disabled} className={s.icon()} onClick={() => {\n setOpen(!open);\n inputRef.current?.focus();\n }}>\n <ChevronGlyph direction={open ? \"up\" : \"down\"} className=\"h-4 w-4\" />\n </button>\n </div>\n {name && values.map((v) => <input key={v.value} type=\"hidden\" name={name} value={v.value} />)}\n <div id={listbox.listId} role=\"listbox\" aria-label={label} aria-multiselectable={multiple || undefined} hidden={!open || (items.length === 0 && !loading && !failed && !labels.empty)} className={s.list()}>\n {open && loading && items.length === 0 ? <div className={s.status()}>{labels.loading}</div> : null}\n {open && failed ? <div className={s.status()}>{labels.error}</div> : null}\n {open && !loading && !failed && items.length === 0 && labels.empty ? <div className={s.status()}>{labels.empty}</div> : null}\n {open &&\n items.map((item, i) =>\n item.kind === \"create\" ? (\n <div key=\"__create\" {...listbox.optionProps(i, false)} className={s.option()}>\n <PlusGlyph className={s.check()} />\n {labels.create(item.query)}\n </div>\n ) : (\n <div key={item.option.value} {...listbox.optionProps(i, chosen.has(item.option.value))} className={s.option()}>\n <span className=\"flex h-4 w-4 shrink-0 items-center justify-center\">{chosen.has(item.option.value) ? <CheckGlyph className={s.check()} /> : null}</span>\n <span className=\"min-w-0 flex-1\">\n {item.option.label}\n {item.option.description ? <span className={s.description()}>{item.option.description}</span> : null}\n </span>\n </div>\n ),\n )}\n </div>\n <span className=\"sr-only\" aria-live=\"polite\" aria-atomic>\n {open && !loading ? labels.results(items.length) : \"\"}\n </span>\n {hint ? (\n <p id={hintId} className={s.hint()}>\n {hint}\n </p>\n ) : null}\n {error ? (\n <p id={errorId} className={s.error()}>\n {error}\n </p>\n ) : null}\n </div>\n );\n}\n"],"mappings":"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","names":["query"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/recipes/define.ts"],"sourcesContent":["import type { TV } from \"tailwind-variants\";\n\n/** What a recipe is made of: the `tv()` options — `base`, `slots`, `variants`, `defaultVariants`, `compoundVariants`. */\nexport type RecipeConfig = Parameters<TV>[0];\n\n/**\n * A recipe is data: the variants of a component (a `variant`, a `size`, a `tone`…) as classes of the Krizaka tokens.\n * `defineRecipe` only keeps the literal types, so `tv(recipe)` is typed exactly as `tv({ … })` would be (the web side) and\n * `nativeRecipe(recipe)` reads the same classes into styles on the theme's roles (the native side, `./native`).\n *\n * Sizes are a variant dimension (`size: { sm: \"h-8 px-3 text-xs\" }`); states are the prefixes (`hover:`, `disabled:`,\n * `data-[state=on]:`). Write colours as roles (`bg-accent`, `text-fg-secondary`, `border-border-default`, `ring-accent/40`),\n * spacing as Tailwind units (`h-10`, `px-4`), type as `text-sm` / `text-[11px]` / `font-semibold`.\n */\nexport function defineRecipe<const C extends RecipeConfig>(config: C): C {\n return config;\n}\n"],"mappings":";;;AAcO,SAAS,aAA2C,QAAc;AACvE,SAAO;AACT;","names":[]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import {
|
|
3
3
|
Chip
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-7UCPGXKN.js";
|
|
5
5
|
import {
|
|
6
6
|
floating
|
|
7
7
|
} from "./chunk-J3NC6ER4.js";
|
|
@@ -156,4 +156,4 @@ export {
|
|
|
156
156
|
readFilterParams,
|
|
157
157
|
writeFilterParams
|
|
158
158
|
};
|
|
159
|
-
//# sourceMappingURL=chunk-
|
|
159
|
+
//# sourceMappingURL=chunk-FKBHWS4N.js.map
|
|
@@ -41,27 +41,6 @@ function useInView(ref, onChange, enabled = true, threshold = 0.25) {
|
|
|
41
41
|
return () => observer.disconnect();
|
|
42
42
|
}, [ref, enabled, threshold, latest]);
|
|
43
43
|
}
|
|
44
|
-
function useDebouncedCallback(callback, delay) {
|
|
45
|
-
const latest = useLatest(callback);
|
|
46
|
-
const [debounced] = React.useState(() => {
|
|
47
|
-
let timer;
|
|
48
|
-
let wait = delay;
|
|
49
|
-
const run = (...args) => {
|
|
50
|
-
clearTimeout(timer);
|
|
51
|
-
if (wait <= 0) latest.current(...args);
|
|
52
|
-
else timer = setTimeout(() => latest.current(...args), wait);
|
|
53
|
-
};
|
|
54
|
-
return Object.assign(run, {
|
|
55
|
-
cancel: () => clearTimeout(timer),
|
|
56
|
-
setDelay: (next) => {
|
|
57
|
-
wait = next;
|
|
58
|
-
}
|
|
59
|
-
});
|
|
60
|
-
});
|
|
61
|
-
React.useEffect(() => debounced.setDelay(delay), [debounced, delay]);
|
|
62
|
-
React.useEffect(() => () => debounced.cancel(), [debounced]);
|
|
63
|
-
return debounced;
|
|
64
|
-
}
|
|
65
44
|
function useControllable(value, defaultValue, onChange) {
|
|
66
45
|
const [inner, setInner] = React.useState(defaultValue);
|
|
67
46
|
const controlled = value !== void 0;
|
|
@@ -89,8 +68,7 @@ export {
|
|
|
89
68
|
usePrefersReducedMotion,
|
|
90
69
|
useLatest,
|
|
91
70
|
useInView,
|
|
92
|
-
useDebouncedCallback,
|
|
93
71
|
useControllable,
|
|
94
72
|
playSafely
|
|
95
73
|
};
|
|
96
|
-
//# sourceMappingURL=chunk-
|
|
74
|
+
//# sourceMappingURL=chunk-FZBWEDQI.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/media.ts"],"sourcesContent":["// Shared by the data and media primitives (client): the clock format, the reduced-motion preference, the\n// in-view observer, a debounced callback. Never an entry of its own.\nimport * as React from \"react\";\n\n/** Seconds as a clock: `75` → `1:15`, `3725` → `1:02:05`. Negative or unknown values read `0:00`. */\nexport function formatClock(seconds: number): string {\n const s = Number.isFinite(seconds) && seconds > 0 ? Math.floor(seconds) : 0;\n const h = Math.floor(s / 3600);\n const m = Math.floor((s % 3600) / 60);\n const rest = String(s % 60).padStart(2, \"0\");\n return h > 0 ? `${h}:${String(m).padStart(2, \"0\")}:${rest}` : `${m}:${rest}`;\n}\n\n/** Clamps `value` between `min` and `max`. */\nexport const clamp = (value: number, min: number, max: number) => Math.min(max, Math.max(min, value));\n\nconst REDUCE = \"(prefers-reduced-motion: reduce)\";\nconst subscribeReduce = (notify: () => void) => {\n if (typeof window === \"undefined\" || !window.matchMedia) return () => undefined;\n const query = window.matchMedia(REDUCE);\n query.addEventListener?.(\"change\", notify);\n return () => query.removeEventListener?.(\"change\", notify);\n};\n\n/** `true` when the person asked for less motion (`prefers-reduced-motion: reduce`); follows a change of the setting. */\nexport function usePrefersReducedMotion(): boolean {\n return React.useSyncExternalStore(\n subscribeReduce,\n () => (typeof window !== \"undefined\" && window.matchMedia ? window.matchMedia(REDUCE).matches : false),\n () => false,\n );\n}\n\n/** The latest value of a callback, for an effect or an event that must not re-subscribe when it changes. */\nexport function useLatest<T>(value: T) {\n const ref = React.useRef(value);\n React.useLayoutEffect(() => {\n ref.current = value;\n });\n return ref;\n}\n\n/** Calls `onChange(visible)` when at least `threshold` of the element enters or leaves the viewport. */\nexport function useInView(ref: React.RefObject<Element | null>, onChange: (visible: boolean) => void, enabled = true, threshold = 0.25) {\n const latest = useLatest(onChange);\n React.useEffect(() => {\n const element = ref.current;\n if (!enabled || !element || typeof IntersectionObserver === \"undefined\") return;\n const observer = new IntersectionObserver(([entry]) => entry && latest.current(entry.isIntersecting), { threshold });\n observer.observe(element);\n return () => observer.disconnect();\n }, [ref, enabled, threshold, latest]);\n}\n\n/** A value controlled by a prop when it is given, held inside otherwise; `set` calls `onChange` either way. */\nexport function useControllable<T>(value: T | undefined, defaultValue: T, onChange?: (next: T) => void) {\n const [inner, setInner] = React.useState(defaultValue);\n const controlled = value !== undefined;\n const current = controlled ? value : inner;\n const set = React.useCallback(\n (next: T) => {\n if (!controlled) setInner(next);\n onChange?.(next);\n },\n [controlled, onChange],\n );\n return [current, set] as const;\n}\n\n/** Starts a media element without an unhandled rejection (autoplay refused, the source replaced meanwhile). */\nexport function playSafely(media: HTMLMediaElement | null | undefined) {\n try {\n const started = media?.play() as Promise<void> | undefined;\n started?.catch?.(() => undefined);\n } catch {\n // Not playable here (no media support): the controls stay as they are.\n }\n}\n"],"mappings":";;;AAEA,YAAY,WAAW;AAGhB,SAAS,YAAY,SAAyB;AACnD,QAAM,IAAI,OAAO,SAAS,OAAO,KAAK,UAAU,IAAI,KAAK,MAAM,OAAO,IAAI;AAC1E,QAAM,IAAI,KAAK,MAAM,IAAI,IAAI;AAC7B,QAAM,IAAI,KAAK,MAAO,IAAI,OAAQ,EAAE;AACpC,QAAM,OAAO,OAAO,IAAI,EAAE,EAAE,SAAS,GAAG,GAAG;AAC3C,SAAO,IAAI,IAAI,GAAG,CAAC,IAAI,OAAO,CAAC,EAAE,SAAS,GAAG,GAAG,CAAC,IAAI,IAAI,KAAK,GAAG,CAAC,IAAI,IAAI;AAC5E;AAGO,IAAM,QAAQ,CAAC,OAAe,KAAa,QAAgB,KAAK,IAAI,KAAK,KAAK,IAAI,KAAK,KAAK,CAAC;AAEpG,IAAM,SAAS;AACf,IAAM,kBAAkB,CAAC,WAAuB;AAC9C,MAAI,OAAO,WAAW,eAAe,CAAC,OAAO,WAAY,QAAO,MAAM;AACtE,QAAM,QAAQ,OAAO,WAAW,MAAM;AACtC,QAAM,mBAAmB,UAAU,MAAM;AACzC,SAAO,MAAM,MAAM,sBAAsB,UAAU,MAAM;AAC3D;AAGO,SAAS,0BAAmC;AACjD,SAAa;AAAA,IACX;AAAA,IACA,MAAO,OAAO,WAAW,eAAe,OAAO,aAAa,OAAO,WAAW,MAAM,EAAE,UAAU;AAAA,IAChG,MAAM;AAAA,EACR;AACF;AAGO,SAAS,UAAa,OAAU;AACrC,QAAM,MAAY,aAAO,KAAK;AAC9B,EAAM,sBAAgB,MAAM;AAC1B,QAAI,UAAU;AAAA,EAChB,CAAC;AACD,SAAO;AACT;AAGO,SAAS,UAAU,KAAsC,UAAsC,UAAU,MAAM,YAAY,MAAM;AACtI,QAAM,SAAS,UAAU,QAAQ;AACjC,EAAM,gBAAU,MAAM;AACpB,UAAM,UAAU,IAAI;AACpB,QAAI,CAAC,WAAW,CAAC,WAAW,OAAO,yBAAyB,YAAa;AACzE,UAAM,WAAW,IAAI,qBAAqB,CAAC,CAAC,KAAK,MAAM,SAAS,OAAO,QAAQ,MAAM,cAAc,GAAG,EAAE,UAAU,CAAC;AACnH,aAAS,QAAQ,OAAO;AACxB,WAAO,MAAM,SAAS,WAAW;AAAA,EACnC,GAAG,CAAC,KAAK,SAAS,WAAW,MAAM,CAAC;AACtC;AAGO,SAAS,gBAAmB,OAAsB,cAAiB,UAA8B;AACtG,QAAM,CAAC,OAAO,QAAQ,IAAU,eAAS,YAAY;AACrD,QAAM,aAAa,UAAU;AAC7B,QAAM,UAAU,aAAa,QAAQ;AACrC,QAAM,MAAY;AAAA,IAChB,CAAC,SAAY;AACX,UAAI,CAAC,WAAY,UAAS,IAAI;AAC9B,iBAAW,IAAI;AAAA,IACjB;AAAA,IACA,CAAC,YAAY,QAAQ;AAAA,EACvB;AACA,SAAO,CAAC,SAAS,GAAG;AACtB;AAGO,SAAS,WAAW,OAA4C;AACrE,MAAI;AACF,UAAM,UAAU,OAAO,KAAK;AAC5B,aAAS,QAAQ,MAAM,MAAS;AAAA,EAClC,QAAQ;AAAA,EAER;AACF;","names":[]}
|