@cloudflare/kumo 1.0.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/CHANGELOG.md +510 -0
- package/LICENSE +21 -0
- package/README.md +521 -0
- package/ai/component-registry.json +3754 -0
- package/ai/component-registry.md +4022 -0
- package/ai/schemas.ts +594 -0
- package/dist/badge-Dc99vsfo.js +51 -0
- package/dist/badge-Dc99vsfo.js.map +1 -0
- package/dist/banner-4fkH6Sbt.js +51 -0
- package/dist/banner-4fkH6Sbt.js.map +1 -0
- package/dist/breadcrumbs-B5SY2CWj.js +132 -0
- package/dist/breadcrumbs-B5SY2CWj.js.map +1 -0
- package/dist/button-E2-hZMZE.js +191 -0
- package/dist/button-E2-hZMZE.js.map +1 -0
- package/dist/catalog.js +229 -0
- package/dist/catalog.js.map +1 -0
- package/dist/checkbox-BexIU_lZ.js +224 -0
- package/dist/checkbox-BexIU_lZ.js.map +1 -0
- package/dist/clipboard-text-BFHWMjmr.js +108 -0
- package/dist/clipboard-text-BFHWMjmr.js.map +1 -0
- package/dist/cn-Bhsu1vx2.js +26 -0
- package/dist/cn-Bhsu1vx2.js.map +1 -0
- package/dist/code-T2wPDiM0.js +60 -0
- package/dist/code-T2wPDiM0.js.map +1 -0
- package/dist/collapsible-OBNkTO48.js +56 -0
- package/dist/collapsible-OBNkTO48.js.map +1 -0
- package/dist/combobox-Dld0kS0U.js +228 -0
- package/dist/combobox-Dld0kS0U.js.map +1 -0
- package/dist/command-line/cli.js +764 -0
- package/dist/command-line/commands/add.js +220 -0
- package/dist/command-line/commands/blocks.js +61 -0
- package/dist/command-line/commands/doc.js +167 -0
- package/dist/command-line/commands/init.js +95 -0
- package/dist/command-line/commands/ls.js +53 -0
- package/dist/command-palette-BgQ680BG.js +393 -0
- package/dist/command-palette-BgQ680BG.js.map +1 -0
- package/dist/components/badge.js +7 -0
- package/dist/components/badge.js.map +1 -0
- package/dist/components/banner.js +7 -0
- package/dist/components/banner.js.map +1 -0
- package/dist/components/breadcrumbs.js +9 -0
- package/dist/components/breadcrumbs.js.map +1 -0
- package/dist/components/button.js +9 -0
- package/dist/components/button.js.map +1 -0
- package/dist/components/checkbox.js +8 -0
- package/dist/components/checkbox.js.map +1 -0
- package/dist/components/clipboard-text.js +6 -0
- package/dist/components/clipboard-text.js.map +1 -0
- package/dist/components/code.js +7 -0
- package/dist/components/code.js.map +1 -0
- package/dist/components/collapsible.js +6 -0
- package/dist/components/collapsible.js.map +1 -0
- package/dist/components/combobox.js +6 -0
- package/dist/components/combobox.js.map +1 -0
- package/dist/components/command-palette.js +8 -0
- package/dist/components/command-palette.js.map +1 -0
- package/dist/components/date-range-picker.js +6 -0
- package/dist/components/date-range-picker.js.map +1 -0
- package/dist/components/dialog.js +11 -0
- package/dist/components/dialog.js.map +1 -0
- package/dist/components/dropdown.js +6 -0
- package/dist/components/dropdown.js.map +1 -0
- package/dist/components/empty.js +9 -0
- package/dist/components/empty.js.map +1 -0
- package/dist/components/field.js +9 -0
- package/dist/components/field.js.map +1 -0
- package/dist/components/grid.js +11 -0
- package/dist/components/grid.js.map +1 -0
- package/dist/components/input.js +11 -0
- package/dist/components/input.js.map +1 -0
- package/dist/components/label.js +10 -0
- package/dist/components/label.js.map +1 -0
- package/dist/components/layer-card.js +6 -0
- package/dist/components/layer-card.js.map +1 -0
- package/dist/components/link.js +9 -0
- package/dist/components/link.js.map +1 -0
- package/dist/components/loader.js +8 -0
- package/dist/components/loader.js.map +1 -0
- package/dist/components/menubar.js +7 -0
- package/dist/components/menubar.js.map +1 -0
- package/dist/components/meter.js +6 -0
- package/dist/components/meter.js.map +1 -0
- package/dist/components/pagination.js +6 -0
- package/dist/components/pagination.js.map +1 -0
- package/dist/components/popover.js +14 -0
- package/dist/components/popover.js.map +1 -0
- package/dist/components/radio.js +10 -0
- package/dist/components/radio.js.map +1 -0
- package/dist/components/select.js +6 -0
- package/dist/components/select.js.map +1 -0
- package/dist/components/sensitive-input.js +8 -0
- package/dist/components/sensitive-input.js.map +1 -0
- package/dist/components/surface.js +6 -0
- package/dist/components/surface.js.map +1 -0
- package/dist/components/switch.js +8 -0
- package/dist/components/switch.js.map +1 -0
- package/dist/components/table.js +8 -0
- package/dist/components/table.js.map +1 -0
- package/dist/components/tabs.js +6 -0
- package/dist/components/tabs.js.map +1 -0
- package/dist/components/text.js +6 -0
- package/dist/components/text.js.map +1 -0
- package/dist/components/toast.js +8 -0
- package/dist/components/toast.js.map +1 -0
- package/dist/components/tooltip.js +7 -0
- package/dist/components/tooltip.js.map +1 -0
- package/dist/date-range-picker-CbKEQ9pi.js +408 -0
- package/dist/date-range-picker-CbKEQ9pi.js.map +1 -0
- package/dist/dialog-B1TaN0oR.js +77 -0
- package/dist/dialog-B1TaN0oR.js.map +1 -0
- package/dist/dropdown-D0rhYKeG.js +263 -0
- package/dist/dropdown-D0rhYKeG.js.map +1 -0
- package/dist/empty-DzCqjea-.js +93 -0
- package/dist/empty-DzCqjea-.js.map +1 -0
- package/dist/field-V3J0Ql_V.js +71 -0
- package/dist/field-V3J0Ql_V.js.map +1 -0
- package/dist/grid-DKajRHh8.js +127 -0
- package/dist/grid-DKajRHh8.js.map +1 -0
- package/dist/index.js +125 -0
- package/dist/index.js.map +1 -0
- package/dist/input-Dqvc2AB_.js +109 -0
- package/dist/input-Dqvc2AB_.js.map +1 -0
- package/dist/input-area-B9qajxvZ.js +57 -0
- package/dist/input-area-B9qajxvZ.js.map +1 -0
- package/dist/input-group-Bl6tgD5-.js +111 -0
- package/dist/input-group-Bl6tgD5-.js.map +1 -0
- package/dist/label-87HQArUG.js +50 -0
- package/dist/label-87HQArUG.js.map +1 -0
- package/dist/layer-card-C8j5Hkkj.js +44 -0
- package/dist/layer-card-C8j5Hkkj.js.map +1 -0
- package/dist/link-6TIZ4JIw.js +73 -0
- package/dist/link-6TIZ4JIw.js.map +1 -0
- package/dist/link-provider-DPBGo-0n.js +22 -0
- package/dist/link-provider-DPBGo-0n.js.map +1 -0
- package/dist/loader-DHGMYlC6.js +105 -0
- package/dist/loader-DHGMYlC6.js.map +1 -0
- package/dist/menubar-DLwLRFB1.js +92 -0
- package/dist/menubar-DLwLRFB1.js.map +1 -0
- package/dist/meter-DKUuvXxS.js +51 -0
- package/dist/meter-DKUuvXxS.js.map +1 -0
- package/dist/pagination-C4HQqodz.js +99 -0
- package/dist/pagination-C4HQqodz.js.map +1 -0
- package/dist/popover-DhdIqrP7.js +178 -0
- package/dist/popover-DhdIqrP7.js.map +1 -0
- package/dist/primitives/accordion.js +6 -0
- package/dist/primitives/accordion.js.map +1 -0
- package/dist/primitives/alert-dialog.js +6 -0
- package/dist/primitives/alert-dialog.js.map +1 -0
- package/dist/primitives/autocomplete.js +6 -0
- package/dist/primitives/autocomplete.js.map +1 -0
- package/dist/primitives/avatar.js +6 -0
- package/dist/primitives/avatar.js.map +1 -0
- package/dist/primitives/button.js +6 -0
- package/dist/primitives/button.js.map +1 -0
- package/dist/primitives/checkbox-group.js +6 -0
- package/dist/primitives/checkbox-group.js.map +1 -0
- package/dist/primitives/checkbox.js +6 -0
- package/dist/primitives/checkbox.js.map +1 -0
- package/dist/primitives/collapsible.js +6 -0
- package/dist/primitives/collapsible.js.map +1 -0
- package/dist/primitives/combobox.js +6 -0
- package/dist/primitives/combobox.js.map +1 -0
- package/dist/primitives/context-menu.js +6 -0
- package/dist/primitives/context-menu.js.map +1 -0
- package/dist/primitives/dialog.js +6 -0
- package/dist/primitives/dialog.js.map +1 -0
- package/dist/primitives/direction-provider.js +7 -0
- package/dist/primitives/direction-provider.js.map +1 -0
- package/dist/primitives/field.js +6 -0
- package/dist/primitives/field.js.map +1 -0
- package/dist/primitives/fieldset.js +6 -0
- package/dist/primitives/fieldset.js.map +1 -0
- package/dist/primitives/form.js +6 -0
- package/dist/primitives/form.js.map +1 -0
- package/dist/primitives/input.js +6 -0
- package/dist/primitives/input.js.map +1 -0
- package/dist/primitives/menu.js +6 -0
- package/dist/primitives/menu.js.map +1 -0
- package/dist/primitives/menubar.js +6 -0
- package/dist/primitives/menubar.js.map +1 -0
- package/dist/primitives/meter.js +6 -0
- package/dist/primitives/meter.js.map +1 -0
- package/dist/primitives/navigation-menu.js +6 -0
- package/dist/primitives/navigation-menu.js.map +1 -0
- package/dist/primitives/number-field.js +6 -0
- package/dist/primitives/number-field.js.map +1 -0
- package/dist/primitives/popover.js +6 -0
- package/dist/primitives/popover.js.map +1 -0
- package/dist/primitives/preview-card.js +6 -0
- package/dist/primitives/preview-card.js.map +1 -0
- package/dist/primitives/progress.js +6 -0
- package/dist/primitives/progress.js.map +1 -0
- package/dist/primitives/radio-group.js +6 -0
- package/dist/primitives/radio-group.js.map +1 -0
- package/dist/primitives/radio.js +6 -0
- package/dist/primitives/radio.js.map +1 -0
- package/dist/primitives/scroll-area.js +6 -0
- package/dist/primitives/scroll-area.js.map +1 -0
- package/dist/primitives/select.js +6 -0
- package/dist/primitives/select.js.map +1 -0
- package/dist/primitives/separator.js +6 -0
- package/dist/primitives/separator.js.map +1 -0
- package/dist/primitives/slider.js +6 -0
- package/dist/primitives/slider.js.map +1 -0
- package/dist/primitives/switch.js +6 -0
- package/dist/primitives/switch.js.map +1 -0
- package/dist/primitives/tabs.js +6 -0
- package/dist/primitives/tabs.js.map +1 -0
- package/dist/primitives/toast.js +6 -0
- package/dist/primitives/toast.js.map +1 -0
- package/dist/primitives/toggle-group.js +6 -0
- package/dist/primitives/toggle-group.js.map +1 -0
- package/dist/primitives/toggle.js +6 -0
- package/dist/primitives/toggle.js.map +1 -0
- package/dist/primitives/toolbar.js +6 -0
- package/dist/primitives/toolbar.js.map +1 -0
- package/dist/primitives/tooltip.js +6 -0
- package/dist/primitives/tooltip.js.map +1 -0
- package/dist/primitives.js +43 -0
- package/dist/primitives.js.map +1 -0
- package/dist/radio-BVAG7hNp.js +125 -0
- package/dist/radio-BVAG7hNp.js.map +1 -0
- package/dist/registry.js +2 -0
- package/dist/registry.js.map +1 -0
- package/dist/schemas-BSdA0fz-.js +3210 -0
- package/dist/schemas-BSdA0fz-.js.map +1 -0
- package/dist/select-B5Vb3zou.js +122 -0
- package/dist/select-B5Vb3zou.js.map +1 -0
- package/dist/sensitive-input-D5HCV04N.js +258 -0
- package/dist/sensitive-input-D5HCV04N.js.map +1 -0
- package/dist/skeleton-line-CtpS1u1J.js +28 -0
- package/dist/skeleton-line-CtpS1u1J.js.map +1 -0
- package/dist/src/blocks/page-header/index.d.ts +2 -0
- package/dist/src/blocks/page-header/index.d.ts.map +1 -0
- package/dist/src/blocks/page-header/page-header.d.ts +38 -0
- package/dist/src/blocks/page-header/page-header.d.ts.map +1 -0
- package/dist/src/blocks/resource-list/index.d.ts +2 -0
- package/dist/src/blocks/resource-list/index.d.ts.map +1 -0
- package/dist/src/blocks/resource-list/resource-list.d.ts +18 -0
- package/dist/src/blocks/resource-list/resource-list.d.ts.map +1 -0
- package/dist/src/catalog/catalog.d.ts +75 -0
- package/dist/src/catalog/catalog.d.ts.map +1 -0
- package/dist/src/catalog/data.d.ts +44 -0
- package/dist/src/catalog/data.d.ts.map +1 -0
- package/dist/src/catalog/index.d.ts +39 -0
- package/dist/src/catalog/index.d.ts.map +1 -0
- package/dist/src/catalog/types.d.ts +226 -0
- package/dist/src/catalog/types.d.ts.map +1 -0
- package/dist/src/catalog/visibility.d.ts +37 -0
- package/dist/src/catalog/visibility.d.ts.map +1 -0
- package/dist/src/command-line/build-cli.d.ts +7 -0
- package/dist/src/command-line/build-cli.d.ts.map +1 -0
- package/dist/src/command-line/cli.d.ts +13 -0
- package/dist/src/command-line/cli.d.ts.map +1 -0
- package/dist/src/command-line/commands/add.d.ts +10 -0
- package/dist/src/command-line/commands/add.d.ts.map +1 -0
- package/dist/src/command-line/commands/blocks.d.ts +10 -0
- package/dist/src/command-line/commands/blocks.d.ts.map +1 -0
- package/dist/src/command-line/commands/doc.d.ts +14 -0
- package/dist/src/command-line/commands/doc.d.ts.map +1 -0
- package/dist/src/command-line/commands/init.d.ts +18 -0
- package/dist/src/command-line/commands/init.d.ts.map +1 -0
- package/dist/src/command-line/commands/ls.d.ts +10 -0
- package/dist/src/command-line/commands/ls.d.ts.map +1 -0
- package/dist/src/command-line/commands/migrate.d.ts +10 -0
- package/dist/src/command-line/commands/migrate.d.ts.map +1 -0
- package/dist/src/command-line/utils/config.d.ts +42 -0
- package/dist/src/command-line/utils/config.d.ts.map +1 -0
- package/dist/src/command-line/utils/transformer.d.ts +17 -0
- package/dist/src/command-line/utils/transformer.d.ts.map +1 -0
- package/dist/src/components/badge/badge.d.ts +46 -0
- package/dist/src/components/badge/badge.d.ts.map +1 -0
- package/dist/src/components/badge/index.d.ts +2 -0
- package/dist/src/components/badge/index.d.ts.map +1 -0
- package/dist/src/components/banner/banner.d.ts +45 -0
- package/dist/src/components/banner/banner.d.ts.map +1 -0
- package/dist/src/components/banner/index.d.ts +2 -0
- package/dist/src/components/banner/index.d.ts.map +1 -0
- package/dist/src/components/breadcrumbs/breadcrumbs.d.ts +43 -0
- package/dist/src/components/breadcrumbs/breadcrumbs.d.ts.map +1 -0
- package/dist/src/components/breadcrumbs/index.d.ts +2 -0
- package/dist/src/components/breadcrumbs/index.d.ts.map +1 -0
- package/dist/src/components/button/button.d.ts +118 -0
- package/dist/src/components/button/button.d.ts.map +1 -0
- package/dist/src/components/button/index.d.ts +2 -0
- package/dist/src/components/button/index.d.ts.map +1 -0
- package/dist/src/components/checkbox/checkbox.d.ts +167 -0
- package/dist/src/components/checkbox/checkbox.d.ts.map +1 -0
- package/dist/src/components/checkbox/index.d.ts +2 -0
- package/dist/src/components/checkbox/index.d.ts.map +1 -0
- package/dist/src/components/clipboard-text/clipboard-text.d.ts +38 -0
- package/dist/src/components/clipboard-text/clipboard-text.d.ts.map +1 -0
- package/dist/src/components/clipboard-text/index.d.ts +2 -0
- package/dist/src/components/clipboard-text/index.d.ts.map +1 -0
- package/dist/src/components/code/code.d.ts +138 -0
- package/dist/src/components/code/code.d.ts.map +1 -0
- package/dist/src/components/code/index.d.ts +4 -0
- package/dist/src/components/code/index.d.ts.map +1 -0
- package/dist/src/components/collapsible/collapsible.d.ts +62 -0
- package/dist/src/components/collapsible/collapsible.d.ts.map +1 -0
- package/dist/src/components/collapsible/index.d.ts +2 -0
- package/dist/src/components/collapsible/index.d.ts.map +1 -0
- package/dist/src/components/combobox/combobox.d.ts +124 -0
- package/dist/src/components/combobox/combobox.d.ts.map +1 -0
- package/dist/src/components/combobox/index.d.ts +2 -0
- package/dist/src/components/combobox/index.d.ts.map +1 -0
- package/dist/src/components/command-palette/command-palette.d.ts +225 -0
- package/dist/src/components/command-palette/command-palette.d.ts.map +1 -0
- package/dist/src/components/command-palette/index.d.ts +3 -0
- package/dist/src/components/command-palette/index.d.ts.map +1 -0
- package/dist/src/components/command-palette/types.d.ts +149 -0
- package/dist/src/components/command-palette/types.d.ts.map +1 -0
- package/dist/src/components/date-range-picker/date-range-picker.d.ts +65 -0
- package/dist/src/components/date-range-picker/date-range-picker.d.ts.map +1 -0
- package/dist/src/components/date-range-picker/index.d.ts +2 -0
- package/dist/src/components/date-range-picker/index.d.ts.map +1 -0
- package/dist/src/components/dialog/dialog.d.ts +121 -0
- package/dist/src/components/dialog/dialog.d.ts.map +1 -0
- package/dist/src/components/dialog/index.d.ts +2 -0
- package/dist/src/components/dialog/index.d.ts.map +1 -0
- package/dist/src/components/dropdown/dropdown.d.ts +58 -0
- package/dist/src/components/dropdown/dropdown.d.ts.map +1 -0
- package/dist/src/components/dropdown/index.d.ts +2 -0
- package/dist/src/components/dropdown/index.d.ts.map +1 -0
- package/dist/src/components/empty/empty.d.ts +34 -0
- package/dist/src/components/empty/empty.d.ts.map +1 -0
- package/dist/src/components/empty/index.d.ts +2 -0
- package/dist/src/components/empty/index.d.ts.map +1 -0
- package/dist/src/components/field/field.d.ts +38 -0
- package/dist/src/components/field/field.d.ts.map +1 -0
- package/dist/src/components/field/index.d.ts +2 -0
- package/dist/src/components/field/index.d.ts.map +1 -0
- package/dist/src/components/grid/grid.d.ts +107 -0
- package/dist/src/components/grid/grid.d.ts.map +1 -0
- package/dist/src/components/grid/index.d.ts +2 -0
- package/dist/src/components/grid/index.d.ts.map +1 -0
- package/dist/src/components/input/index.d.ts +4 -0
- package/dist/src/components/input/index.d.ts.map +1 -0
- package/dist/src/components/input/input-area.d.ts +46 -0
- package/dist/src/components/input/input-area.d.ts.map +1 -0
- package/dist/src/components/input/input-group.d.ts +39 -0
- package/dist/src/components/input/input-group.d.ts.map +1 -0
- package/dist/src/components/input/input.d.ts +157 -0
- package/dist/src/components/input/input.d.ts.map +1 -0
- package/dist/src/components/label/index.d.ts +2 -0
- package/dist/src/components/label/index.d.ts.map +1 -0
- package/dist/src/components/label/label.d.ts +54 -0
- package/dist/src/components/label/label.d.ts.map +1 -0
- package/dist/src/components/layer-card/index.d.ts +2 -0
- package/dist/src/components/layer-card/index.d.ts.map +1 -0
- package/dist/src/components/layer-card/layer-card.d.ts +16 -0
- package/dist/src/components/layer-card/layer-card.d.ts.map +1 -0
- package/dist/src/components/link/index.d.ts +2 -0
- package/dist/src/components/link/index.d.ts.map +1 -0
- package/dist/src/components/link/link.d.ts +35 -0
- package/dist/src/components/link/link.d.ts.map +1 -0
- package/dist/src/components/loader/index.d.ts +3 -0
- package/dist/src/components/loader/index.d.ts.map +1 -0
- package/dist/src/components/loader/loader.d.ts +30 -0
- package/dist/src/components/loader/loader.d.ts.map +1 -0
- package/dist/src/components/loader/skeleton-line.d.ts +10 -0
- package/dist/src/components/loader/skeleton-line.d.ts.map +1 -0
- package/dist/src/components/menubar/index.d.ts +3 -0
- package/dist/src/components/menubar/index.d.ts.map +1 -0
- package/dist/src/components/menubar/menubar.d.ts +22 -0
- package/dist/src/components/menubar/menubar.d.ts.map +1 -0
- package/dist/src/components/menubar/use-menu-navigation.d.ts +8 -0
- package/dist/src/components/menubar/use-menu-navigation.d.ts.map +1 -0
- package/dist/src/components/meter/index.d.ts +2 -0
- package/dist/src/components/meter/index.d.ts.map +1 -0
- package/dist/src/components/meter/meter.d.ts +18 -0
- package/dist/src/components/meter/meter.d.ts.map +1 -0
- package/dist/src/components/pagination/index.d.ts +2 -0
- package/dist/src/components/pagination/index.d.ts.map +1 -0
- package/dist/src/components/pagination/pagination.d.ts +28 -0
- package/dist/src/components/pagination/pagination.d.ts.map +1 -0
- package/dist/src/components/popover/index.d.ts +3 -0
- package/dist/src/components/popover/index.d.ts.map +1 -0
- package/dist/src/components/popover/popover.d.ts +110 -0
- package/dist/src/components/popover/popover.d.ts.map +1 -0
- package/dist/src/components/radio/index.d.ts +2 -0
- package/dist/src/components/radio/index.d.ts.map +1 -0
- package/dist/src/components/radio/radio.d.ts +141 -0
- package/dist/src/components/radio/radio.d.ts.map +1 -0
- package/dist/src/components/select/index.d.ts +2 -0
- package/dist/src/components/select/index.d.ts.map +1 -0
- package/dist/src/components/select/select.d.ts +128 -0
- package/dist/src/components/select/select.d.ts.map +1 -0
- package/dist/src/components/sensitive-input/index.d.ts +2 -0
- package/dist/src/components/sensitive-input/index.d.ts.map +1 -0
- package/dist/src/components/sensitive-input/sensitive-input.d.ts +70 -0
- package/dist/src/components/sensitive-input/sensitive-input.d.ts.map +1 -0
- package/dist/src/components/surface/index.d.ts +2 -0
- package/dist/src/components/surface/index.d.ts.map +1 -0
- package/dist/src/components/surface/surface.d.ts +48 -0
- package/dist/src/components/surface/surface.d.ts.map +1 -0
- package/dist/src/components/switch/index.d.ts +2 -0
- package/dist/src/components/switch/index.d.ts.map +1 -0
- package/dist/src/components/switch/switch.d.ts +155 -0
- package/dist/src/components/switch/switch.d.ts.map +1 -0
- package/dist/src/components/table/index.d.ts +2 -0
- package/dist/src/components/table/index.d.ts.map +1 -0
- package/dist/src/components/table/table.d.ts +54 -0
- package/dist/src/components/table/table.d.ts.map +1 -0
- package/dist/src/components/tabs/index.d.ts +3 -0
- package/dist/src/components/tabs/index.d.ts.map +1 -0
- package/dist/src/components/tabs/tabs.d.ts +64 -0
- package/dist/src/components/tabs/tabs.d.ts.map +1 -0
- package/dist/src/components/text/index.d.ts +2 -0
- package/dist/src/components/text/index.d.ts.map +1 -0
- package/dist/src/components/text/text.d.ts +153 -0
- package/dist/src/components/text/text.d.ts.map +1 -0
- package/dist/src/components/toast/index.d.ts +3 -0
- package/dist/src/components/toast/index.d.ts.map +1 -0
- package/dist/src/components/toast/toast.d.ts +66 -0
- package/dist/src/components/toast/toast.d.ts.map +1 -0
- package/dist/src/components/tooltip/index.d.ts +2 -0
- package/dist/src/components/tooltip/index.d.ts.map +1 -0
- package/dist/src/components/tooltip/tooltip.d.ts +43 -0
- package/dist/src/components/tooltip/tooltip.d.ts.map +1 -0
- package/dist/src/index.d.ts +39 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/primitives/accordion.d.ts +13 -0
- package/dist/src/primitives/accordion.d.ts.map +1 -0
- package/dist/src/primitives/alert-dialog.d.ts +13 -0
- package/dist/src/primitives/alert-dialog.d.ts.map +1 -0
- package/dist/src/primitives/autocomplete.d.ts +13 -0
- package/dist/src/primitives/autocomplete.d.ts.map +1 -0
- package/dist/src/primitives/avatar.d.ts +13 -0
- package/dist/src/primitives/avatar.d.ts.map +1 -0
- package/dist/src/primitives/button.d.ts +13 -0
- package/dist/src/primitives/button.d.ts.map +1 -0
- package/dist/src/primitives/checkbox-group.d.ts +13 -0
- package/dist/src/primitives/checkbox-group.d.ts.map +1 -0
- package/dist/src/primitives/checkbox.d.ts +13 -0
- package/dist/src/primitives/checkbox.d.ts.map +1 -0
- package/dist/src/primitives/collapsible.d.ts +13 -0
- package/dist/src/primitives/collapsible.d.ts.map +1 -0
- package/dist/src/primitives/combobox.d.ts +13 -0
- package/dist/src/primitives/combobox.d.ts.map +1 -0
- package/dist/src/primitives/context-menu.d.ts +13 -0
- package/dist/src/primitives/context-menu.d.ts.map +1 -0
- package/dist/src/primitives/dialog.d.ts +13 -0
- package/dist/src/primitives/dialog.d.ts.map +1 -0
- package/dist/src/primitives/direction-provider.d.ts +13 -0
- package/dist/src/primitives/direction-provider.d.ts.map +1 -0
- package/dist/src/primitives/field.d.ts +13 -0
- package/dist/src/primitives/field.d.ts.map +1 -0
- package/dist/src/primitives/fieldset.d.ts +13 -0
- package/dist/src/primitives/fieldset.d.ts.map +1 -0
- package/dist/src/primitives/form.d.ts +13 -0
- package/dist/src/primitives/form.d.ts.map +1 -0
- package/dist/src/primitives/index.d.ts +52 -0
- package/dist/src/primitives/index.d.ts.map +1 -0
- package/dist/src/primitives/input.d.ts +13 -0
- package/dist/src/primitives/input.d.ts.map +1 -0
- package/dist/src/primitives/menu.d.ts +13 -0
- package/dist/src/primitives/menu.d.ts.map +1 -0
- package/dist/src/primitives/menubar.d.ts +13 -0
- package/dist/src/primitives/menubar.d.ts.map +1 -0
- package/dist/src/primitives/meter.d.ts +13 -0
- package/dist/src/primitives/meter.d.ts.map +1 -0
- package/dist/src/primitives/navigation-menu.d.ts +13 -0
- package/dist/src/primitives/navigation-menu.d.ts.map +1 -0
- package/dist/src/primitives/number-field.d.ts +13 -0
- package/dist/src/primitives/number-field.d.ts.map +1 -0
- package/dist/src/primitives/popover.d.ts +13 -0
- package/dist/src/primitives/popover.d.ts.map +1 -0
- package/dist/src/primitives/preview-card.d.ts +13 -0
- package/dist/src/primitives/preview-card.d.ts.map +1 -0
- package/dist/src/primitives/progress.d.ts +13 -0
- package/dist/src/primitives/progress.d.ts.map +1 -0
- package/dist/src/primitives/radio-group.d.ts +13 -0
- package/dist/src/primitives/radio-group.d.ts.map +1 -0
- package/dist/src/primitives/radio.d.ts +13 -0
- package/dist/src/primitives/radio.d.ts.map +1 -0
- package/dist/src/primitives/scroll-area.d.ts +13 -0
- package/dist/src/primitives/scroll-area.d.ts.map +1 -0
- package/dist/src/primitives/select.d.ts +13 -0
- package/dist/src/primitives/select.d.ts.map +1 -0
- package/dist/src/primitives/separator.d.ts +13 -0
- package/dist/src/primitives/separator.d.ts.map +1 -0
- package/dist/src/primitives/slider.d.ts +13 -0
- package/dist/src/primitives/slider.d.ts.map +1 -0
- package/dist/src/primitives/switch.d.ts +13 -0
- package/dist/src/primitives/switch.d.ts.map +1 -0
- package/dist/src/primitives/tabs.d.ts +13 -0
- package/dist/src/primitives/tabs.d.ts.map +1 -0
- package/dist/src/primitives/toast.d.ts +13 -0
- package/dist/src/primitives/toast.d.ts.map +1 -0
- package/dist/src/primitives/toggle-group.d.ts +13 -0
- package/dist/src/primitives/toggle-group.d.ts.map +1 -0
- package/dist/src/primitives/toggle.d.ts +13 -0
- package/dist/src/primitives/toggle.d.ts.map +1 -0
- package/dist/src/primitives/toolbar.d.ts +13 -0
- package/dist/src/primitives/toolbar.d.ts.map +1 -0
- package/dist/src/primitives/tooltip.d.ts +13 -0
- package/dist/src/primitives/tooltip.d.ts.map +1 -0
- package/dist/src/registry/index.d.ts +8 -0
- package/dist/src/registry/index.d.ts.map +1 -0
- package/dist/src/registry/types.d.ts +191 -0
- package/dist/src/registry/types.d.ts.map +1 -0
- package/dist/src/utils/cn.d.ts +4 -0
- package/dist/src/utils/cn.d.ts.map +1 -0
- package/dist/src/utils/index.d.ts +3 -0
- package/dist/src/utils/index.d.ts.map +1 -0
- package/dist/src/utils/link-provider.d.ts +12 -0
- package/dist/src/utils/link-provider.d.ts.map +1 -0
- package/dist/src/utils/prop-examples.d.ts +36 -0
- package/dist/src/utils/prop-examples.d.ts.map +1 -0
- package/dist/styles/kumo-binding.css +190 -0
- package/dist/styles/kumo-standalone.css +2 -0
- package/dist/styles/kumo.css +55 -0
- package/dist/styles/theme-fedramp.css +20 -0
- package/dist/styles/theme-kumo.css +186 -0
- package/dist/surface-BIC6CXiz.js +21 -0
- package/dist/surface-BIC6CXiz.js.map +1 -0
- package/dist/switch-D4duMhJ0.js +257 -0
- package/dist/switch-D4duMhJ0.js.map +1 -0
- package/dist/table-KuvHGpL8.js +153 -0
- package/dist/table-KuvHGpL8.js.map +1 -0
- package/dist/tabs-lQup-IbT.js +85 -0
- package/dist/tabs-lQup-IbT.js.map +1 -0
- package/dist/text-BEhqwMfe.js +97 -0
- package/dist/text-BEhqwMfe.js.map +1 -0
- package/dist/toast-8YyyQuqZ.js +69 -0
- package/dist/toast-8YyyQuqZ.js.map +1 -0
- package/dist/tooltip-DJWsDTWJ.js +85 -0
- package/dist/tooltip-DJWsDTWJ.js.map +1 -0
- package/dist/utils.js +10 -0
- package/dist/utils.js.map +1 -0
- package/dist/vendor-base-ui-DWIDNgE1.js +20446 -0
- package/dist/vendor-base-ui-DWIDNgE1.js.map +1 -0
- package/dist/vendor-floating-ui-BgbEw62H.js +1286 -0
- package/dist/vendor-floating-ui-BgbEw62H.js.map +1 -0
- package/dist/vendor-styling-BQbxAbdS.js +2775 -0
- package/dist/vendor-styling-BQbxAbdS.js.map +1 -0
- package/dist/vendor-utils-DD8jNJwD.js +741 -0
- package/dist/vendor-utils-DD8jNJwD.js.map +1 -0
- package/package.json +444 -0
- package/scripts/component-registry/cache.ts +123 -0
- package/scripts/component-registry/discovery.ts +469 -0
- package/scripts/component-registry/example-cleanup.ts +168 -0
- package/scripts/component-registry/index.test.ts +680 -0
- package/scripts/component-registry/index.ts +874 -0
- package/scripts/component-registry/markdown-generator.ts +222 -0
- package/scripts/component-registry/metadata.ts +643 -0
- package/scripts/component-registry/props-filter.ts +310 -0
- package/scripts/component-registry/schema-generator.ts +326 -0
- package/scripts/component-registry/sub-components.ts +349 -0
- package/scripts/component-registry/types.ts +156 -0
- package/scripts/component-registry/utils.ts +280 -0
- package/scripts/component-registry/variant-parser.ts +261 -0
- package/scripts/css-build.ts +55 -0
- package/scripts/generate-primitives.ts +178 -0
- package/scripts/theme-generator/config.ts +392 -0
- package/scripts/theme-generator/generate-css.ts +250 -0
- package/scripts/theme-generator/index.ts +159 -0
- package/scripts/theme-generator/migrate.ts +560 -0
- package/scripts/theme-generator/types.ts +86 -0
|
@@ -0,0 +1,4022 @@
|
|
|
1
|
+
# Kumo Component Registry
|
|
2
|
+
|
|
3
|
+
> Auto-generated component metadata for AI/agent consumption.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
### Badge
|
|
8
|
+
|
|
9
|
+
Badge component
|
|
10
|
+
|
|
11
|
+
**Type:** component
|
|
12
|
+
|
|
13
|
+
**Import:** `import { Badge } from "@cloudflare/kumo";`
|
|
14
|
+
|
|
15
|
+
**Category:** Display
|
|
16
|
+
|
|
17
|
+
**Props:**
|
|
18
|
+
|
|
19
|
+
- `variant`: enum [default: primary]
|
|
20
|
+
- `"primary"`: Default high-emphasis badge for important labels
|
|
21
|
+
- `"secondary"`: Subtle badge for secondary information
|
|
22
|
+
- `"destructive"`: Error or danger state indicator
|
|
23
|
+
- `"outline"`: Bordered badge with transparent background
|
|
24
|
+
- `"beta"`: Indicates beta or experimental features
|
|
25
|
+
- `className`: string
|
|
26
|
+
- `children`: ReactNode
|
|
27
|
+
|
|
28
|
+
**Colors (kumo tokens used):**
|
|
29
|
+
|
|
30
|
+
`bg-kumo-contrast`, `bg-kumo-danger`, `bg-kumo-fill`, `border-kumo-brand`, `border-kumo-fill`, `text-kumo-default`, `text-kumo-inverse`, `text-kumo-link`
|
|
31
|
+
|
|
32
|
+
**Examples:**
|
|
33
|
+
|
|
34
|
+
```tsx
|
|
35
|
+
<div className="flex flex-wrap items-center gap-2">
|
|
36
|
+
<Badge variant="primary">Primary</Badge>
|
|
37
|
+
<Badge variant="secondary">Secondary</Badge>
|
|
38
|
+
<Badge variant="destructive">Destructive</Badge>
|
|
39
|
+
<Badge variant="outline">Outline</Badge>
|
|
40
|
+
<Badge variant="beta">Beta</Badge>
|
|
41
|
+
</div>
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
```tsx
|
|
45
|
+
<Badge variant="primary">Primary</Badge>
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
```tsx
|
|
49
|
+
<p className="flex items-center gap-2">
|
|
50
|
+
Workers
|
|
51
|
+
<Badge variant="beta">Beta</Badge>
|
|
52
|
+
</p>
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
### Banner
|
|
59
|
+
|
|
60
|
+
Banner component
|
|
61
|
+
|
|
62
|
+
**Type:** component
|
|
63
|
+
|
|
64
|
+
**Import:** `import { Banner } from "@cloudflare/kumo";`
|
|
65
|
+
|
|
66
|
+
**Category:** Feedback
|
|
67
|
+
|
|
68
|
+
**Props:**
|
|
69
|
+
|
|
70
|
+
- `icon`: ReactNode
|
|
71
|
+
- `text`: string
|
|
72
|
+
- `children`: ReactNode
|
|
73
|
+
- `variant`: enum [default: default]
|
|
74
|
+
- `"default"`: Informational banner for general messages
|
|
75
|
+
- `"alert"`: Warning banner for cautionary messages
|
|
76
|
+
- `"error"`: Error banner for critical issues
|
|
77
|
+
- `className`: string
|
|
78
|
+
|
|
79
|
+
**Colors (kumo tokens used):**
|
|
80
|
+
|
|
81
|
+
`bg-kumo-danger`, `bg-kumo-danger-tint`, `bg-kumo-info`, `bg-kumo-info-tint`, `bg-kumo-warning`, `bg-kumo-warning-tint`, `border-kumo-danger`, `border-kumo-info`, `border-kumo-warning`, `text-kumo-danger`, `text-kumo-link`, `text-kumo-warning`
|
|
82
|
+
|
|
83
|
+
**Examples:**
|
|
84
|
+
|
|
85
|
+
```tsx
|
|
86
|
+
<div className="space-y-3">
|
|
87
|
+
<Banner>This is an informational banner.</Banner>
|
|
88
|
+
<Banner variant="alert">This is an alert banner.</Banner>
|
|
89
|
+
<Banner variant="error">This is an error banner.</Banner>
|
|
90
|
+
</div>
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
```tsx
|
|
94
|
+
<Banner>This is an informational banner.</Banner>
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
```tsx
|
|
98
|
+
<Banner variant="alert">Your session will expire soon.</Banner>
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
```tsx
|
|
102
|
+
<Banner icon={<WarningCircle />} variant="alert">
|
|
103
|
+
Review your billing information.
|
|
104
|
+
</Banner>
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
```tsx
|
|
108
|
+
<Banner icon={<Info />}>
|
|
109
|
+
<Text DANGEROUS_className="text-inherit">
|
|
110
|
+
This banner supports <strong>custom content</strong> with Text.
|
|
111
|
+
</Text>
|
|
112
|
+
</Banner>
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
### Breadcrumbs
|
|
119
|
+
|
|
120
|
+
Breadcrumbs component
|
|
121
|
+
|
|
122
|
+
**Type:** component
|
|
123
|
+
|
|
124
|
+
**Import:** `import { Breadcrumbs } from "@cloudflare/kumo";`
|
|
125
|
+
|
|
126
|
+
**Category:** Display
|
|
127
|
+
|
|
128
|
+
**Props:**
|
|
129
|
+
|
|
130
|
+
- `size`: enum [default: base]
|
|
131
|
+
- `"sm"`: Compact breadcrumbs for dense UIs
|
|
132
|
+
- `"base"`: Default breadcrumbs size
|
|
133
|
+
- `children`: ReactNode
|
|
134
|
+
- `className`: string
|
|
135
|
+
|
|
136
|
+
**Colors (kumo tokens used):**
|
|
137
|
+
|
|
138
|
+
`text-kumo-inactive`, `text-kumo-subtle`, `text-kumo-success`
|
|
139
|
+
|
|
140
|
+
**Sub-Components:**
|
|
141
|
+
|
|
142
|
+
This is a compound component. Use these sub-components:
|
|
143
|
+
|
|
144
|
+
#### Breadcrumbs.Link
|
|
145
|
+
|
|
146
|
+
Link sub-component
|
|
147
|
+
|
|
148
|
+
Props:
|
|
149
|
+
- `href`: string (required)
|
|
150
|
+
- `icon`: React.ReactNode
|
|
151
|
+
|
|
152
|
+
#### Breadcrumbs.Current
|
|
153
|
+
|
|
154
|
+
Current sub-component
|
|
155
|
+
|
|
156
|
+
Props:
|
|
157
|
+
- `loading`: boolean
|
|
158
|
+
- `icon`: React.ReactNode
|
|
159
|
+
|
|
160
|
+
#### Breadcrumbs.Separator
|
|
161
|
+
|
|
162
|
+
Separator sub-component
|
|
163
|
+
|
|
164
|
+
#### Breadcrumbs.Clipboard
|
|
165
|
+
|
|
166
|
+
Clipboard sub-component
|
|
167
|
+
|
|
168
|
+
Props:
|
|
169
|
+
- `text`: string (required)
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
**Examples:**
|
|
173
|
+
|
|
174
|
+
```tsx
|
|
175
|
+
<Breadcrumbs>
|
|
176
|
+
<Breadcrumbs.Link href="#">Home</Breadcrumbs.Link>
|
|
177
|
+
<Breadcrumbs.Separator />
|
|
178
|
+
<Breadcrumbs.Link href="#">Docs</Breadcrumbs.Link>
|
|
179
|
+
<Breadcrumbs.Separator />
|
|
180
|
+
<Breadcrumbs.Current>Breadcrumbs</Breadcrumbs.Current>
|
|
181
|
+
</Breadcrumbs>
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
```tsx
|
|
185
|
+
<Breadcrumbs>
|
|
186
|
+
<Breadcrumbs.Link href="#" icon={<House size={16} />}>
|
|
187
|
+
Home
|
|
188
|
+
</Breadcrumbs.Link>
|
|
189
|
+
<Breadcrumbs.Separator />
|
|
190
|
+
<Breadcrumbs.Link href="#">Projects</Breadcrumbs.Link>
|
|
191
|
+
<Breadcrumbs.Separator />
|
|
192
|
+
<Breadcrumbs.Current>Current Project</Breadcrumbs.Current>
|
|
193
|
+
</Breadcrumbs>
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
```tsx
|
|
197
|
+
<Breadcrumbs>
|
|
198
|
+
<Breadcrumbs.Current icon={<House size={16} />}>
|
|
199
|
+
Worker Analytics
|
|
200
|
+
</Breadcrumbs.Current>
|
|
201
|
+
</Breadcrumbs>
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
```tsx
|
|
205
|
+
<Breadcrumbs>
|
|
206
|
+
<Breadcrumbs.Link href="#">Home</Breadcrumbs.Link>
|
|
207
|
+
<Breadcrumbs.Separator />
|
|
208
|
+
<Breadcrumbs.Current>Breadcrumbs</Breadcrumbs.Current>
|
|
209
|
+
<Breadcrumbs.Clipboard text="#" />
|
|
210
|
+
</Breadcrumbs>
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
---
|
|
215
|
+
|
|
216
|
+
### Button
|
|
217
|
+
|
|
218
|
+
Button component
|
|
219
|
+
|
|
220
|
+
**Type:** component
|
|
221
|
+
|
|
222
|
+
**Import:** `import { Button } from "@cloudflare/kumo";`
|
|
223
|
+
|
|
224
|
+
**Category:** Action
|
|
225
|
+
|
|
226
|
+
**Props:**
|
|
227
|
+
|
|
228
|
+
- `children`: ReactNode
|
|
229
|
+
- `className`: string
|
|
230
|
+
- `icon`: ReactNode
|
|
231
|
+
- `loading`: boolean
|
|
232
|
+
- `shape`: enum [default: base]
|
|
233
|
+
- `"base"`: Default rectangular button shape
|
|
234
|
+
- `"square"`: Square button for icon-only actions
|
|
235
|
+
- `"circle"`: Circular button for icon-only actions
|
|
236
|
+
- `size`: enum [default: base]
|
|
237
|
+
- `"xs"`: Extra small button for compact UIs
|
|
238
|
+
- `"sm"`: Small button for secondary actions
|
|
239
|
+
- `"base"`: Default button size
|
|
240
|
+
- `"lg"`: Large button for primary CTAs
|
|
241
|
+
- `variant`: enum [default: secondary]
|
|
242
|
+
- `"primary"`: High-emphasis button for primary actions
|
|
243
|
+
- `"secondary"`: Default button style for most actions
|
|
244
|
+
- `"ghost"`: Minimal button with no background
|
|
245
|
+
- `"destructive"`: Danger button for destructive actions like delete
|
|
246
|
+
- `"secondary-destructive"`: Secondary button with destructive text for less prominent dangerous actions
|
|
247
|
+
- `"outline"`: Bordered button with transparent background
|
|
248
|
+
|
|
249
|
+
**State Classes:**
|
|
250
|
+
- `"primary"`:
|
|
251
|
+
- `hover`: `hover:bg-kumo-brand-hover`
|
|
252
|
+
- `focus`: `focus:bg-kumo-brand-hover`
|
|
253
|
+
- `disabled`: `disabled:bg-kumo-brand/50`
|
|
254
|
+
- `"secondary"`:
|
|
255
|
+
- `not-disabled`: `not-disabled:hover:border-secondary! not-disabled:hover:bg-kumo-control`
|
|
256
|
+
- `disabled`: `disabled:bg-kumo-control/50 disabled:!text-kumo-default/70`
|
|
257
|
+
- `data-state`: `data-[state=open]:bg-kumo-control`
|
|
258
|
+
- `"ghost"`:
|
|
259
|
+
- `hover`: `hover:bg-kumo-tint`
|
|
260
|
+
- `"destructive"`:
|
|
261
|
+
- `hover`: `hover:bg-kumo-danger/70`
|
|
262
|
+
- `"secondary-destructive"`:
|
|
263
|
+
- `not-disabled`: `not-disabled:hover:border-secondary! not-disabled:hover:bg-kumo-control`
|
|
264
|
+
- `disabled`: `disabled:bg-kumo-control/50 disabled:!text-kumo-danger/70`
|
|
265
|
+
- `data-state`: `data-[state=open]:bg-kumo-control`
|
|
266
|
+
- `id`: string
|
|
267
|
+
- `lang`: string
|
|
268
|
+
- `title`: string
|
|
269
|
+
- `disabled`: boolean
|
|
270
|
+
- `name`: string
|
|
271
|
+
- `type`: enum
|
|
272
|
+
- `value`: string | string[] | number
|
|
273
|
+
|
|
274
|
+
**Colors (kumo tokens used):**
|
|
275
|
+
|
|
276
|
+
`bg-kumo-base`, `bg-kumo-brand`, `bg-kumo-brand-hover`, `bg-kumo-control`, `bg-kumo-danger`, `bg-kumo-tint`, `ring-kumo-line`, `ring-kumo-ring`, `text-kumo-danger`, `text-kumo-default`, `text-kumo-subtle`
|
|
277
|
+
|
|
278
|
+
**Examples:**
|
|
279
|
+
|
|
280
|
+
```tsx
|
|
281
|
+
<div className="flex flex-wrap items-center gap-2">
|
|
282
|
+
<Button variant="secondary">Button</Button>
|
|
283
|
+
<Button variant="secondary" shape="square" icon={PlusIcon} />
|
|
284
|
+
</div>
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
```tsx
|
|
288
|
+
<Button variant="primary">Primary</Button>
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
```tsx
|
|
292
|
+
<div className="flex flex-wrap items-center gap-3">
|
|
293
|
+
<Button size="xs" variant="secondary">
|
|
294
|
+
Extra Small
|
|
295
|
+
</Button>
|
|
296
|
+
<Button size="sm" variant="secondary">
|
|
297
|
+
Small
|
|
298
|
+
</Button>
|
|
299
|
+
<Button size="base" variant="secondary">
|
|
300
|
+
Base
|
|
301
|
+
</Button>
|
|
302
|
+
<Button size="lg" variant="secondary">
|
|
303
|
+
Large
|
|
304
|
+
</Button>
|
|
305
|
+
</div>
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
```tsx
|
|
309
|
+
<Button variant="secondary" icon={PlusIcon}>
|
|
310
|
+
Create Worker
|
|
311
|
+
</Button>
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
```tsx
|
|
315
|
+
<div className="flex flex-wrap items-center gap-3">
|
|
316
|
+
<Button variant="secondary" shape="square" icon={PlusIcon} />
|
|
317
|
+
<Button variant="secondary" shape="circle" icon={PlusIcon} />
|
|
318
|
+
</div>
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
|
|
322
|
+
---
|
|
323
|
+
|
|
324
|
+
### Checkbox
|
|
325
|
+
|
|
326
|
+
Checkbox component
|
|
327
|
+
|
|
328
|
+
**Type:** component
|
|
329
|
+
|
|
330
|
+
**Import:** `import { Checkbox } from "@cloudflare/kumo";`
|
|
331
|
+
|
|
332
|
+
**Category:** Input
|
|
333
|
+
|
|
334
|
+
**Props:**
|
|
335
|
+
|
|
336
|
+
- `variant`: enum [default: default]
|
|
337
|
+
- `"default"`: Default checkbox appearance
|
|
338
|
+
- `"error"`: Error state for validation failures
|
|
339
|
+
|
|
340
|
+
**State Classes:**
|
|
341
|
+
- `"default"`:
|
|
342
|
+
- `focus`: `[&:focus-within>span]:ring-kumo-ring`
|
|
343
|
+
- `hover`: `[&:hover>span]:ring-kumo-ring`
|
|
344
|
+
- `label`: ReactNode
|
|
345
|
+
Label content for the checkbox (enables built-in Field wrapper) - can be a string or any React node
|
|
346
|
+
- `labelTooltip`: ReactNode
|
|
347
|
+
Tooltip content to display next to the label via an info icon
|
|
348
|
+
- `controlFirst`: boolean
|
|
349
|
+
When true (default), checkbox appears before label. When false, label appears before checkbox.
|
|
350
|
+
- `checked`: boolean
|
|
351
|
+
Whether the checkbox is checked (controlled)
|
|
352
|
+
- `indeterminate`: boolean
|
|
353
|
+
Whether the checkbox is in indeterminate state
|
|
354
|
+
- `disabled`: boolean
|
|
355
|
+
Whether the checkbox is disabled
|
|
356
|
+
- `name`: string
|
|
357
|
+
Name for form submission
|
|
358
|
+
- `required`: boolean
|
|
359
|
+
Whether the field is required
|
|
360
|
+
- `className`: string
|
|
361
|
+
Additional class name
|
|
362
|
+
- `onValueChange`: (checked: boolean) => void
|
|
363
|
+
Callback when checkbox value changes
|
|
364
|
+
|
|
365
|
+
**Colors (kumo tokens used):**
|
|
366
|
+
|
|
367
|
+
`bg-kumo-base`, `bg-kumo-contrast`, `border-kumo-line`, `ring-kumo-danger`, `ring-kumo-line`, `ring-kumo-ring`, `text-kumo-danger`, `text-kumo-default`, `text-kumo-inverse`, `text-kumo-subtle`
|
|
368
|
+
|
|
369
|
+
**Styling:**
|
|
370
|
+
|
|
371
|
+
- **Dimensions:** `h-4 w-4`
|
|
372
|
+
- **Border Radius:** `rounded-sm`
|
|
373
|
+
- **Base Tokens:** `bg-kumo-base`, `ring-kumo-line`
|
|
374
|
+
- **States:**
|
|
375
|
+
- `checked`: `bg-kumo-contrast`, `text-kumo-inverse`
|
|
376
|
+
- `indeterminate`: `bg-kumo-contrast`, `text-kumo-inverse`
|
|
377
|
+
- `error`: `ring-kumo-danger`
|
|
378
|
+
- `hover`: `ring-kumo-ring`
|
|
379
|
+
- `focus`: `ring-kumo-ring`
|
|
380
|
+
- `disabled`: `opacity-50`, `cursor-not-allowed`
|
|
381
|
+
- **Icons:**
|
|
382
|
+
- `ph-check` (checked) size 12
|
|
383
|
+
- `ph-minus` (indeterminate) size 12
|
|
384
|
+
|
|
385
|
+
**Sub-Components:**
|
|
386
|
+
|
|
387
|
+
This is a compound component. Use these sub-components:
|
|
388
|
+
|
|
389
|
+
#### Checkbox.Item
|
|
390
|
+
|
|
391
|
+
Item sub-component
|
|
392
|
+
|
|
393
|
+
#### Checkbox.Group
|
|
394
|
+
|
|
395
|
+
Group sub-component
|
|
396
|
+
|
|
397
|
+
Props:
|
|
398
|
+
- `legend`: string (required)
|
|
399
|
+
- `children`: ReactNode (required)
|
|
400
|
+
- `error`: string
|
|
401
|
+
- `description`: ReactNode
|
|
402
|
+
- `value`: string[]
|
|
403
|
+
- `allValues`: string[]
|
|
404
|
+
- `disabled`: boolean
|
|
405
|
+
- `controlFirst`: boolean
|
|
406
|
+
- `className`: string
|
|
407
|
+
|
|
408
|
+
|
|
409
|
+
**Examples:**
|
|
410
|
+
|
|
411
|
+
```tsx
|
|
412
|
+
<Checkbox
|
|
413
|
+
label="Accept terms and conditions"
|
|
414
|
+
checked={checked}
|
|
415
|
+
onCheckedChange={setChecked}
|
|
416
|
+
/>
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
```tsx
|
|
420
|
+
<Checkbox
|
|
421
|
+
label="Select all"
|
|
422
|
+
indeterminate={indeterminate}
|
|
423
|
+
onCheckedChange={setIndeterminate}
|
|
424
|
+
/>
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
```tsx
|
|
428
|
+
<Checkbox
|
|
429
|
+
label="Remember me"
|
|
430
|
+
controlFirst={false}
|
|
431
|
+
checked={checked}
|
|
432
|
+
onCheckedChange={setChecked}
|
|
433
|
+
/>
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
```tsx
|
|
437
|
+
<Checkbox label="Disabled option" disabled />
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
```tsx
|
|
441
|
+
<Checkbox label="Invalid option" variant="error" />
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
```tsx
|
|
445
|
+
<Checkbox.Group
|
|
446
|
+
legend="Email preferences"
|
|
447
|
+
description="Choose how you'd like to receive updates"
|
|
448
|
+
value={preferences}
|
|
449
|
+
onValueChange={setPreferences}
|
|
450
|
+
>
|
|
451
|
+
<Checkbox.Item value="email" label="Email notifications" />
|
|
452
|
+
<Checkbox.Item value="sms" label="SMS notifications" />
|
|
453
|
+
<Checkbox.Item value="push" label="Push notifications" />
|
|
454
|
+
</Checkbox.Group>
|
|
455
|
+
```
|
|
456
|
+
|
|
457
|
+
```tsx
|
|
458
|
+
<Checkbox.Group
|
|
459
|
+
legend="Required preferences"
|
|
460
|
+
error="Please select at least one notification method"
|
|
461
|
+
value={[]}
|
|
462
|
+
onValueChange={() => {}}
|
|
463
|
+
>
|
|
464
|
+
<Checkbox.Item value="email" label="Email" variant="error" />
|
|
465
|
+
<Checkbox.Item value="sms" label="SMS" variant="error" />
|
|
466
|
+
</Checkbox.Group>
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
|
|
470
|
+
---
|
|
471
|
+
|
|
472
|
+
### ClipboardText
|
|
473
|
+
|
|
474
|
+
ClipboardText component
|
|
475
|
+
|
|
476
|
+
**Type:** component
|
|
477
|
+
|
|
478
|
+
**Import:** `import { ClipboardText } from "@cloudflare/kumo";`
|
|
479
|
+
|
|
480
|
+
**Category:** Action
|
|
481
|
+
|
|
482
|
+
**Props:**
|
|
483
|
+
|
|
484
|
+
- `size`: enum [default: lg]
|
|
485
|
+
- `"sm"`: Small clipboard text for compact UIs
|
|
486
|
+
- `"base"`: Default clipboard text size
|
|
487
|
+
- `"lg"`: Large clipboard text for prominent display
|
|
488
|
+
- `text`: string (required)
|
|
489
|
+
The text to display and copy to clipboard
|
|
490
|
+
- `className`: string
|
|
491
|
+
Additional CSS classes
|
|
492
|
+
|
|
493
|
+
**Colors (kumo tokens used):**
|
|
494
|
+
|
|
495
|
+
`bg-kumo-base`, `border-kumo-line`
|
|
496
|
+
|
|
497
|
+
**Styling:**
|
|
498
|
+
|
|
499
|
+
- **Base Tokens:** `bg-kumo-base`, `text-kumo-default`, `ring-kumo-line`, `border-kumo-fill`
|
|
500
|
+
- **States:**
|
|
501
|
+
- `input`: `bg-kumo-control`, `text-kumo-default`, `ring-kumo-line`
|
|
502
|
+
- `text`: `bg-kumo-base`, `font-mono`
|
|
503
|
+
- `button`: `border-kumo-fill`
|
|
504
|
+
- **Icons:**
|
|
505
|
+
- `ph-clipboard` (default) size 16
|
|
506
|
+
- `ph-check` (copied) size 16
|
|
507
|
+
- **Input Styles:**
|
|
508
|
+
- Base: `bg-kumo-control text-kumo-default ring ring-kumo-line`
|
|
509
|
+
- Sizes:
|
|
510
|
+
- `xs`: `h-5 gap-1 rounded-sm px-1.5 text-xs`
|
|
511
|
+
- `sm`: `h-6.5 gap-1 rounded-md px-2 text-xs`
|
|
512
|
+
- `base`: `h-9 gap-1.5 rounded-lg px-3 text-base`
|
|
513
|
+
- `lg`: `h-10 gap-2 rounded-lg px-4 text-base`
|
|
514
|
+
- **Size Variants:**
|
|
515
|
+
- `sm`:
|
|
516
|
+
- Height: 26px
|
|
517
|
+
- Classes: `text-xs`
|
|
518
|
+
- Button Size: `sm`
|
|
519
|
+
- Dimensions:
|
|
520
|
+
- paddingX: 8
|
|
521
|
+
- gap: 1
|
|
522
|
+
- borderRadius: 6
|
|
523
|
+
- fontSize: 12
|
|
524
|
+
- `base`:
|
|
525
|
+
- Height: 36px
|
|
526
|
+
- Classes: `text-sm`
|
|
527
|
+
- Button Size: `base`
|
|
528
|
+
- Dimensions:
|
|
529
|
+
- paddingX: 12
|
|
530
|
+
- gap: 6
|
|
531
|
+
- borderRadius: 8
|
|
532
|
+
- fontSize: 14
|
|
533
|
+
- `lg`:
|
|
534
|
+
- Height: 40px
|
|
535
|
+
- Classes: `text-sm`
|
|
536
|
+
- Button Size: `lg`
|
|
537
|
+
- Dimensions:
|
|
538
|
+
- paddingX: 16
|
|
539
|
+
- gap: 8
|
|
540
|
+
- borderRadius: 8
|
|
541
|
+
- fontSize: 14
|
|
542
|
+
|
|
543
|
+
**Examples:**
|
|
544
|
+
|
|
545
|
+
```tsx
|
|
546
|
+
<ClipboardText text="0c239dd2" />
|
|
547
|
+
```
|
|
548
|
+
|
|
549
|
+
|
|
550
|
+
---
|
|
551
|
+
|
|
552
|
+
### Code
|
|
553
|
+
|
|
554
|
+
Code component
|
|
555
|
+
|
|
556
|
+
**Type:** component
|
|
557
|
+
|
|
558
|
+
**Import:** `import { Code } from "@cloudflare/kumo";`
|
|
559
|
+
|
|
560
|
+
**Category:** Display
|
|
561
|
+
|
|
562
|
+
**Props:**
|
|
563
|
+
|
|
564
|
+
- `lang`: enum [default: ts]
|
|
565
|
+
- `"ts"`: TypeScript code
|
|
566
|
+
- `"tsx"`: TypeScript JSX code
|
|
567
|
+
- `"jsonc"`: JSON with comments
|
|
568
|
+
- `"bash"`: Shell/Bash commands
|
|
569
|
+
- `"css"`: CSS styles
|
|
570
|
+
- `code`: string (required)
|
|
571
|
+
The code content to display
|
|
572
|
+
- `values`: Record<string, { value: string; highlight?: boolean }>
|
|
573
|
+
Template values for interpolation
|
|
574
|
+
- `className`: string
|
|
575
|
+
Additional CSS classes
|
|
576
|
+
|
|
577
|
+
**Colors (kumo tokens used):**
|
|
578
|
+
|
|
579
|
+
`bg-kumo-base`, `border-kumo-fill`, `text-kumo-strong`
|
|
580
|
+
|
|
581
|
+
**Styling:**
|
|
582
|
+
|
|
583
|
+
- **Dimensions:** `[object Object]`
|
|
584
|
+
- **Base Tokens:** `text-kumo-strong`
|
|
585
|
+
|
|
586
|
+
**Sub-Components:**
|
|
587
|
+
|
|
588
|
+
This is a compound component. Use these sub-components:
|
|
589
|
+
|
|
590
|
+
#### Code.Block
|
|
591
|
+
|
|
592
|
+
Block sub-component
|
|
593
|
+
|
|
594
|
+
Props:
|
|
595
|
+
- `code`: string (required)
|
|
596
|
+
- `lang`: CodeLang
|
|
597
|
+
|
|
598
|
+
|
|
599
|
+
**Examples:**
|
|
600
|
+
|
|
601
|
+
```tsx
|
|
602
|
+
<CodeBlock
|
|
603
|
+
lang="tsx"
|
|
604
|
+
code={`const greeting = "Hello, World!";
|
|
605
|
+
console.log(greeting);`}
|
|
606
|
+
/>
|
|
607
|
+
```
|
|
608
|
+
|
|
609
|
+
```tsx
|
|
610
|
+
<Code
|
|
611
|
+
lang="bash"
|
|
612
|
+
code="export API_KEY={{apiKey}}"
|
|
613
|
+
values={{
|
|
614
|
+
apiKey: { value: "sk_live_123", highlight: true },
|
|
615
|
+
}}
|
|
616
|
+
/>
|
|
617
|
+
```
|
|
618
|
+
|
|
619
|
+
|
|
620
|
+
---
|
|
621
|
+
|
|
622
|
+
### Collapsible
|
|
623
|
+
|
|
624
|
+
Collapsible component for showing/hiding content. Features: - Animated chevron indicator (rotates 180° when open) - Accessible with aria-expanded and aria-controls - Content panel with left border accent
|
|
625
|
+
|
|
626
|
+
**Type:** component
|
|
627
|
+
|
|
628
|
+
**Import:** `import { Collapsible } from "@cloudflare/kumo";`
|
|
629
|
+
|
|
630
|
+
**Category:** Display
|
|
631
|
+
|
|
632
|
+
**Props:**
|
|
633
|
+
|
|
634
|
+
- `children`: ReactNode
|
|
635
|
+
- `label`: string (required)
|
|
636
|
+
Text label displayed in the trigger button
|
|
637
|
+
- `open`: boolean
|
|
638
|
+
Whether the collapsible content is visible
|
|
639
|
+
- `className`: string
|
|
640
|
+
Additional CSS classes for the content panel
|
|
641
|
+
- `onOpenChange`: (open: boolean) => void
|
|
642
|
+
Callback when collapsed state changes
|
|
643
|
+
|
|
644
|
+
**Colors (kumo tokens used):**
|
|
645
|
+
|
|
646
|
+
`border-kumo-fill`, `text-kumo-link`
|
|
647
|
+
|
|
648
|
+
**Examples:**
|
|
649
|
+
|
|
650
|
+
```tsx
|
|
651
|
+
<div className="w-full">
|
|
652
|
+
<Collapsible label="What is Kumo?" open={isOpen} onOpenChange={setIsOpen}>
|
|
653
|
+
Kumo is Cloudflare's new design system.
|
|
654
|
+
</Collapsible>
|
|
655
|
+
</div>
|
|
656
|
+
```
|
|
657
|
+
|
|
658
|
+
```tsx
|
|
659
|
+
<div className="w-full space-y-2">
|
|
660
|
+
<Collapsible label="What is Kumo?" open={open1} onOpenChange={setOpen1}>
|
|
661
|
+
Kumo is Cloudflare's new design system.
|
|
662
|
+
</Collapsible>
|
|
663
|
+
<Collapsible
|
|
664
|
+
label="How do I use it?"
|
|
665
|
+
open={open2}
|
|
666
|
+
onOpenChange={setOpen2}
|
|
667
|
+
>
|
|
668
|
+
Install the components and import them into your project.
|
|
669
|
+
</Collapsible>
|
|
670
|
+
<Collapsible
|
|
671
|
+
label="Is it open source?"
|
|
672
|
+
open={open3}
|
|
673
|
+
onOpenChange={setOpen3}
|
|
674
|
+
>
|
|
675
|
+
Check the repository for license information.
|
|
676
|
+
</Collapsible>
|
|
677
|
+
</div>
|
|
678
|
+
```
|
|
679
|
+
|
|
680
|
+
|
|
681
|
+
---
|
|
682
|
+
|
|
683
|
+
### Combobox
|
|
684
|
+
|
|
685
|
+
Combobox component
|
|
686
|
+
|
|
687
|
+
**Type:** component
|
|
688
|
+
|
|
689
|
+
**Import:** `import { Combobox } from "@cloudflare/kumo";`
|
|
690
|
+
|
|
691
|
+
**Category:** Input
|
|
692
|
+
|
|
693
|
+
**Props:**
|
|
694
|
+
|
|
695
|
+
- `inputSide`: enum [default: right]
|
|
696
|
+
- `"right"`: Input positioned inline to the right of chips
|
|
697
|
+
- `"top"`: Input positioned above chips
|
|
698
|
+
- `items`: T[] (required)
|
|
699
|
+
Array of items to display in the dropdown
|
|
700
|
+
- `value`: T | T[]
|
|
701
|
+
Currently selected value(s)
|
|
702
|
+
- `children`: ReactNode
|
|
703
|
+
Combobox content (trigger, content, items)
|
|
704
|
+
- `className`: string
|
|
705
|
+
Additional CSS classes
|
|
706
|
+
- `label`: ReactNode
|
|
707
|
+
Label content for the combobox (enables Field wrapper) - can be a string or any React node
|
|
708
|
+
- `required`: boolean
|
|
709
|
+
Whether the combobox is required
|
|
710
|
+
- `labelTooltip`: ReactNode
|
|
711
|
+
Tooltip content to display next to the label via an info icon
|
|
712
|
+
- `description`: ReactNode
|
|
713
|
+
Helper text displayed below the combobox
|
|
714
|
+
- `error`: string | object
|
|
715
|
+
Error message or validation error object
|
|
716
|
+
- `onValueChange`: (value: T | T[]) => void
|
|
717
|
+
Callback when selection changes
|
|
718
|
+
- `multiple`: boolean
|
|
719
|
+
Allow multiple selections
|
|
720
|
+
- `isItemEqualToValue`: (item: T, value: T) => boolean
|
|
721
|
+
Custom equality function for comparing items
|
|
722
|
+
|
|
723
|
+
**Colors (kumo tokens used):**
|
|
724
|
+
|
|
725
|
+
`bg-kumo-control`, `bg-kumo-fill-hover`, `bg-kumo-overlay`, `fill-kumo-ring`, `ring-kumo-line`, `text-kumo-default`, `text-kumo-subtle`
|
|
726
|
+
|
|
727
|
+
**Sub-Components:**
|
|
728
|
+
|
|
729
|
+
This is a compound component. Use these sub-components:
|
|
730
|
+
|
|
731
|
+
#### Combobox.Content
|
|
732
|
+
|
|
733
|
+
Content sub-component
|
|
734
|
+
|
|
735
|
+
Props:
|
|
736
|
+
- `className`: string
|
|
737
|
+
- `align`: ComboboxBase.Positioner.Props["align"]
|
|
738
|
+
- `alignOffset`: ComboboxBase.Positioner.Props["alignOffset"]
|
|
739
|
+
- `side`: ComboboxBase.Positioner.Props["side"]
|
|
740
|
+
- `sideOffset`: ComboboxBase.Positioner.Props["sideOffset"]
|
|
741
|
+
|
|
742
|
+
#### Combobox.TriggerValue
|
|
743
|
+
|
|
744
|
+
TriggerValue sub-component
|
|
745
|
+
|
|
746
|
+
#### Combobox.TriggerInput
|
|
747
|
+
|
|
748
|
+
TriggerInput sub-component
|
|
749
|
+
|
|
750
|
+
#### Combobox.TriggerMultipleWithInput
|
|
751
|
+
|
|
752
|
+
TriggerMultipleWithInput sub-component
|
|
753
|
+
|
|
754
|
+
#### Combobox.Chip
|
|
755
|
+
|
|
756
|
+
Chip sub-component
|
|
757
|
+
|
|
758
|
+
#### Combobox.Item
|
|
759
|
+
|
|
760
|
+
Item sub-component
|
|
761
|
+
|
|
762
|
+
#### Combobox.Input
|
|
763
|
+
|
|
764
|
+
Input sub-component
|
|
765
|
+
|
|
766
|
+
#### Combobox.Empty
|
|
767
|
+
|
|
768
|
+
Empty sub-component
|
|
769
|
+
|
|
770
|
+
#### Combobox.GroupLabel
|
|
771
|
+
|
|
772
|
+
GroupLabel sub-component
|
|
773
|
+
|
|
774
|
+
#### Combobox.Group
|
|
775
|
+
|
|
776
|
+
Group sub-component
|
|
777
|
+
|
|
778
|
+
#### Combobox.List
|
|
779
|
+
|
|
780
|
+
A container for combobox items. Supports render prop for custom item rendering. Renders a `<div>` element.
|
|
781
|
+
|
|
782
|
+
Props:
|
|
783
|
+
- `children`: ReactNode | ((item: T, index: number) => ReactNode) - Items to render, or a function that receives each item and returns a node
|
|
784
|
+
|
|
785
|
+
Usage:
|
|
786
|
+
```tsx
|
|
787
|
+
<Combobox.List>
|
|
788
|
+
{(item) => <Combobox.Item value={item}>{item.label}</Combobox.Item>}
|
|
789
|
+
</Combobox.List>
|
|
790
|
+
```
|
|
791
|
+
|
|
792
|
+
#### Combobox.Collection
|
|
793
|
+
|
|
794
|
+
Renders filtered list items. Use when you need more control over item rendering.
|
|
795
|
+
|
|
796
|
+
Props:
|
|
797
|
+
- `children`: (item: T, index: number) => ReactNode (required) - Function that receives each filtered item and returns a node
|
|
798
|
+
|
|
799
|
+
Usage:
|
|
800
|
+
```tsx
|
|
801
|
+
<Combobox.Collection>
|
|
802
|
+
{(item, index) => (
|
|
803
|
+
<Combobox.Item key={index} value={item}>
|
|
804
|
+
{item.label}
|
|
805
|
+
</Combobox.Item>
|
|
806
|
+
)}
|
|
807
|
+
</Combobox.Collection>
|
|
808
|
+
```
|
|
809
|
+
|
|
810
|
+
|
|
811
|
+
**Examples:**
|
|
812
|
+
|
|
813
|
+
```tsx
|
|
814
|
+
<Combobox
|
|
815
|
+
value={value}
|
|
816
|
+
onValueChange={(v) => setValue(v as string | null)}
|
|
817
|
+
items={fruits}
|
|
818
|
+
>
|
|
819
|
+
<Combobox.TriggerInput placeholder="Please select" />
|
|
820
|
+
<Combobox.Content>
|
|
821
|
+
<Combobox.Empty />
|
|
822
|
+
<Combobox.List>
|
|
823
|
+
{(item: string) => (
|
|
824
|
+
<Combobox.Item key={item} value={item}>
|
|
825
|
+
{item}
|
|
826
|
+
</Combobox.Item>
|
|
827
|
+
)}
|
|
828
|
+
</Combobox.List>
|
|
829
|
+
</Combobox.Content>
|
|
830
|
+
</Combobox>
|
|
831
|
+
```
|
|
832
|
+
|
|
833
|
+
```tsx
|
|
834
|
+
<Combobox
|
|
835
|
+
value={value}
|
|
836
|
+
onValueChange={(v) => setValue(v as Language)}
|
|
837
|
+
items={languages}
|
|
838
|
+
>
|
|
839
|
+
<Combobox.TriggerValue className="w-[200px]" />
|
|
840
|
+
<Combobox.Content>
|
|
841
|
+
<Combobox.Input placeholder="Search languages" />
|
|
842
|
+
<Combobox.Empty />
|
|
843
|
+
<Combobox.List>
|
|
844
|
+
{(item: Language) => (
|
|
845
|
+
<Combobox.Item key={item.value} value={item}>
|
|
846
|
+
{item.emoji} {item.label}
|
|
847
|
+
</Combobox.Item>
|
|
848
|
+
)}
|
|
849
|
+
</Combobox.List>
|
|
850
|
+
</Combobox.Content>
|
|
851
|
+
</Combobox>
|
|
852
|
+
```
|
|
853
|
+
|
|
854
|
+
```tsx
|
|
855
|
+
<Combobox
|
|
856
|
+
value={value}
|
|
857
|
+
onValueChange={(v) => setValue(v as ServerLocation | null)}
|
|
858
|
+
items={servers}
|
|
859
|
+
>
|
|
860
|
+
<Combobox.TriggerInput
|
|
861
|
+
className="w-[200px]"
|
|
862
|
+
placeholder="Select server"
|
|
863
|
+
/>
|
|
864
|
+
<Combobox.Content>
|
|
865
|
+
<Combobox.Empty />
|
|
866
|
+
<Combobox.List>
|
|
867
|
+
{(group: ServerLocationGroup) => (
|
|
868
|
+
<Combobox.Group key={group.value} items={group.items}>
|
|
869
|
+
<Combobox.GroupLabel>{group.value}</Combobox.GroupLabel>
|
|
870
|
+
<Combobox.Collection>
|
|
871
|
+
{(item: ServerLocation) => (
|
|
872
|
+
<Combobox.Item key={item.value} value={item}>
|
|
873
|
+
{item.label}
|
|
874
|
+
</Combobox.Item>
|
|
875
|
+
)}
|
|
876
|
+
</Combobox.Collection>
|
|
877
|
+
</Combobox.Group>
|
|
878
|
+
)}
|
|
879
|
+
</Combobox.List>
|
|
880
|
+
</Combobox.Content>
|
|
881
|
+
</Combobox>
|
|
882
|
+
```
|
|
883
|
+
|
|
884
|
+
```tsx
|
|
885
|
+
<div className="flex gap-2">
|
|
886
|
+
<Combobox
|
|
887
|
+
value={value}
|
|
888
|
+
onValueChange={setValue}
|
|
889
|
+
items={bots}
|
|
890
|
+
isItemEqualToValue={(bot: BotItem, selected: BotItem) =>
|
|
891
|
+
bot.value === selected.value
|
|
892
|
+
}
|
|
893
|
+
multiple
|
|
894
|
+
>
|
|
895
|
+
<Combobox.TriggerMultipleWithInput
|
|
896
|
+
className="w-[400px]"
|
|
897
|
+
placeholder="Select bots"
|
|
898
|
+
renderItem={(selected: BotItem) => (
|
|
899
|
+
<Combobox.Chip key={selected.value}>{selected.label}</Combobox.Chip>
|
|
900
|
+
)}
|
|
901
|
+
inputSide="right"
|
|
902
|
+
/>
|
|
903
|
+
<Combobox.Content className="max-h-[200px] min-w-auto overflow-y-auto">
|
|
904
|
+
<Combobox.Empty />
|
|
905
|
+
<Combobox.List>
|
|
906
|
+
{(item: BotItem) => (
|
|
907
|
+
<Combobox.Item key={item.value} value={item}>
|
|
908
|
+
<div className="flex gap-2">
|
|
909
|
+
<Text>{item.label}</Text>
|
|
910
|
+
<Text variant="secondary">{item.author}</Text>
|
|
911
|
+
</div>
|
|
912
|
+
</Combobox.Item>
|
|
913
|
+
)}
|
|
914
|
+
</Combobox.List>
|
|
915
|
+
</Combobox.Content>
|
|
916
|
+
</Combobox>
|
|
917
|
+
<Button variant="primary">Submit</Button>
|
|
918
|
+
</div>
|
|
919
|
+
```
|
|
920
|
+
|
|
921
|
+
```tsx
|
|
922
|
+
<div className="w-80">
|
|
923
|
+
<Combobox
|
|
924
|
+
items={databases}
|
|
925
|
+
value={value}
|
|
926
|
+
onValueChange={setValue}
|
|
927
|
+
label="Database"
|
|
928
|
+
description="Select your preferred database"
|
|
929
|
+
>
|
|
930
|
+
<Combobox.TriggerInput placeholder="Select database" />
|
|
931
|
+
<Combobox.Content>
|
|
932
|
+
<Combobox.Empty />
|
|
933
|
+
<Combobox.List>
|
|
934
|
+
{(item: DatabaseItem) => (
|
|
935
|
+
<Combobox.Item key={item.value} value={item}>
|
|
936
|
+
{item.label}
|
|
937
|
+
</Combobox.Item>
|
|
938
|
+
)}
|
|
939
|
+
</Combobox.List>
|
|
940
|
+
</Combobox.Content>
|
|
941
|
+
</Combobox>
|
|
942
|
+
</div>
|
|
943
|
+
```
|
|
944
|
+
|
|
945
|
+
```tsx
|
|
946
|
+
<div className="w-80">
|
|
947
|
+
<Combobox
|
|
948
|
+
items={databases}
|
|
949
|
+
value={value}
|
|
950
|
+
onValueChange={setValue}
|
|
951
|
+
label="Database"
|
|
952
|
+
error={{ message: "Please select a database", match: true }}
|
|
953
|
+
>
|
|
954
|
+
<Combobox.TriggerInput placeholder="Select database" />
|
|
955
|
+
<Combobox.Content>
|
|
956
|
+
<Combobox.Empty />
|
|
957
|
+
<Combobox.List>
|
|
958
|
+
{(item: DatabaseItem) => (
|
|
959
|
+
<Combobox.Item key={item.value} value={item}>
|
|
960
|
+
{item.label}
|
|
961
|
+
</Combobox.Item>
|
|
962
|
+
)}
|
|
963
|
+
</Combobox.List>
|
|
964
|
+
</Combobox.Content>
|
|
965
|
+
</Combobox>
|
|
966
|
+
</div>
|
|
967
|
+
```
|
|
968
|
+
|
|
969
|
+
|
|
970
|
+
---
|
|
971
|
+
|
|
972
|
+
### CommandPalette
|
|
973
|
+
|
|
974
|
+
CommandPalette component
|
|
975
|
+
|
|
976
|
+
**Type:** component
|
|
977
|
+
|
|
978
|
+
**Import:** `import { CommandPalette } from "@cloudflare/kumo";`
|
|
979
|
+
|
|
980
|
+
**Category:** Navigation
|
|
981
|
+
|
|
982
|
+
**Props:**
|
|
983
|
+
|
|
984
|
+
- `open`: boolean (required)
|
|
985
|
+
Whether the dialog is open
|
|
986
|
+
- `children`: ReactNode
|
|
987
|
+
Child content - typically one or more Panel components
|
|
988
|
+
|
|
989
|
+
**Colors (kumo tokens used):**
|
|
990
|
+
|
|
991
|
+
`bg-kumo-base`, `bg-kumo-elevated`, `bg-kumo-overlay`, `bg-kumo-warning`, `ring-kumo-line`, `text-kumo-default`, `text-kumo-strong`, `text-kumo-subtle`
|
|
992
|
+
|
|
993
|
+
**Examples:**
|
|
994
|
+
|
|
995
|
+
```tsx
|
|
996
|
+
<div className="flex flex-col items-start gap-4">
|
|
997
|
+
<Button onClick={() => setOpen(true)}>Open Command Palette</Button>
|
|
998
|
+
{selectedItem && (
|
|
999
|
+
<p className="text-sm text-kumo-subtle">
|
|
1000
|
+
Last selected:{" "}
|
|
1001
|
+
<span className="text-kumo-default">{selectedItem}</span>
|
|
1002
|
+
</p>
|
|
1003
|
+
)}
|
|
1004
|
+
|
|
1005
|
+
<CommandPalette.Root
|
|
1006
|
+
open={open}
|
|
1007
|
+
onOpenChange={setOpen}
|
|
1008
|
+
items={sampleGroups}
|
|
1009
|
+
value={search}
|
|
1010
|
+
onValueChange={setSearch}
|
|
1011
|
+
itemToStringValue={(group) => group.label}
|
|
1012
|
+
onSelect={(item, { newTab }) => {
|
|
1013
|
+
console.log("Selected:", item.title, newTab ? "(new tab)" : "");
|
|
1014
|
+
handleSelect(item);
|
|
1015
|
+
}}
|
|
1016
|
+
getSelectableItems={getSelectableItems}
|
|
1017
|
+
>
|
|
1018
|
+
<CommandPalette.Input placeholder="Type a command or search..." />
|
|
1019
|
+
<CommandPalette.List>
|
|
1020
|
+
<CommandPalette.Results>
|
|
1021
|
+
{(group: CommandGroup) => (
|
|
1022
|
+
<CommandPalette.Group key={group.id}>
|
|
1023
|
+
<CommandPalette.GroupLabel>
|
|
1024
|
+
{group.label}
|
|
1025
|
+
</CommandPalette.GroupLabel>
|
|
1026
|
+
<CommandPalette.Items>
|
|
1027
|
+
{(item: CommandItem) => (
|
|
1028
|
+
<CommandPalette.Item
|
|
1029
|
+
key={item.id}
|
|
1030
|
+
value={item}
|
|
1031
|
+
onClick={() => handleSelect(item)}
|
|
1032
|
+
>
|
|
1033
|
+
<span className="flex items-center gap-3">
|
|
1034
|
+
{item.icon && (
|
|
1035
|
+
<span className="text-kumo-subtle">{item.icon}</span>
|
|
1036
|
+
)}
|
|
1037
|
+
<span>{item.title}</span>
|
|
1038
|
+
</span>
|
|
1039
|
+
</CommandPalette.Item>
|
|
1040
|
+
)}
|
|
1041
|
+
</CommandPalette.Items>
|
|
1042
|
+
</CommandPalette.Group>
|
|
1043
|
+
)}
|
|
1044
|
+
</CommandPalette.Results>
|
|
1045
|
+
<CommandPalette.Empty>No commands found</CommandPalette.Empty>
|
|
1046
|
+
</CommandPalette.List>
|
|
1047
|
+
<CommandPalette.Footer>
|
|
1048
|
+
<span className="flex items-center gap-2">
|
|
1049
|
+
<kbd className="rounded border border-kumo-line bg-kumo-base px-1.5 py-0.5 text-[10px]">
|
|
1050
|
+
↑↓
|
|
1051
|
+
</kbd>
|
|
1052
|
+
<span>Navigate</span>
|
|
1053
|
+
</span>
|
|
1054
|
+
<span className="flex items-center gap-2">
|
|
1055
|
+
<kbd className="rounded border border-kumo-line bg-kumo-base px-1.5 py-0.5 text-[10px]">
|
|
1056
|
+
↵
|
|
1057
|
+
</kbd>
|
|
1058
|
+
<span>Select</span>
|
|
1059
|
+
</span>
|
|
1060
|
+
</CommandPalette.Footer>
|
|
1061
|
+
</CommandPalette.Root>
|
|
1062
|
+
</div>
|
|
1063
|
+
```
|
|
1064
|
+
|
|
1065
|
+
```tsx
|
|
1066
|
+
<div>
|
|
1067
|
+
<Button onClick={() => setOpen(true)}>Open Simple Palette</Button>
|
|
1068
|
+
|
|
1069
|
+
<CommandPalette.Root
|
|
1070
|
+
open={open}
|
|
1071
|
+
onOpenChange={setOpen}
|
|
1072
|
+
items={simpleItems}
|
|
1073
|
+
value={search}
|
|
1074
|
+
onValueChange={setSearch}
|
|
1075
|
+
itemToStringValue={(item) => item.title}
|
|
1076
|
+
onSelect={(item) => {
|
|
1077
|
+
console.log("Selected:", item.title);
|
|
1078
|
+
setOpen(false);
|
|
1079
|
+
}}
|
|
1080
|
+
getSelectableItems={(items) => items}
|
|
1081
|
+
>
|
|
1082
|
+
<CommandPalette.Input placeholder="Search actions..." />
|
|
1083
|
+
<CommandPalette.List>
|
|
1084
|
+
<CommandPalette.Results>
|
|
1085
|
+
{(item: SimpleItem) => (
|
|
1086
|
+
<CommandPalette.Item
|
|
1087
|
+
key={item.id}
|
|
1088
|
+
value={item}
|
|
1089
|
+
onClick={() => {
|
|
1090
|
+
console.log("Clicked:", item.title);
|
|
1091
|
+
setOpen(false);
|
|
1092
|
+
}}
|
|
1093
|
+
>
|
|
1094
|
+
{item.title}
|
|
1095
|
+
</CommandPalette.Item>
|
|
1096
|
+
)}
|
|
1097
|
+
</CommandPalette.Results>
|
|
1098
|
+
<CommandPalette.Empty>No actions found</CommandPalette.Empty>
|
|
1099
|
+
</CommandPalette.List>
|
|
1100
|
+
</CommandPalette.Root>
|
|
1101
|
+
</div>
|
|
1102
|
+
```
|
|
1103
|
+
|
|
1104
|
+
```tsx
|
|
1105
|
+
<div>
|
|
1106
|
+
<Button onClick={handleOpen}>Open with Loading</Button>
|
|
1107
|
+
|
|
1108
|
+
<CommandPalette.Root
|
|
1109
|
+
open={open}
|
|
1110
|
+
onOpenChange={setOpen}
|
|
1111
|
+
items={loading ? [] : sampleGroups}
|
|
1112
|
+
value={search}
|
|
1113
|
+
onValueChange={setSearch}
|
|
1114
|
+
itemToStringValue={(group) => group.label}
|
|
1115
|
+
getSelectableItems={getSelectableItems}
|
|
1116
|
+
>
|
|
1117
|
+
<CommandPalette.Input placeholder="Search..." />
|
|
1118
|
+
<CommandPalette.List>
|
|
1119
|
+
{loading ? (
|
|
1120
|
+
<CommandPalette.Loading />
|
|
1121
|
+
) : (
|
|
1122
|
+
<>
|
|
1123
|
+
<CommandPalette.Results>
|
|
1124
|
+
{(group: CommandGroup) => (
|
|
1125
|
+
<CommandPalette.Group key={group.id}>
|
|
1126
|
+
<CommandPalette.GroupLabel>
|
|
1127
|
+
{group.label}
|
|
1128
|
+
</CommandPalette.GroupLabel>
|
|
1129
|
+
<CommandPalette.Items>
|
|
1130
|
+
{(item: CommandItem) => (
|
|
1131
|
+
<CommandPalette.Item
|
|
1132
|
+
key={item.id}
|
|
1133
|
+
value={item}
|
|
1134
|
+
onClick={() => setOpen(false)}
|
|
1135
|
+
>
|
|
1136
|
+
<span className="flex items-center gap-3">
|
|
1137
|
+
{item.icon && (
|
|
1138
|
+
<span className="text-kumo-subtle">
|
|
1139
|
+
{item.icon}
|
|
1140
|
+
</span>
|
|
1141
|
+
)}
|
|
1142
|
+
<span>{item.title}</span>
|
|
1143
|
+
</span>
|
|
1144
|
+
</CommandPalette.Item>
|
|
1145
|
+
)}
|
|
1146
|
+
</CommandPalette.Items>
|
|
1147
|
+
</CommandPalette.Group>
|
|
1148
|
+
)}
|
|
1149
|
+
</CommandPalette.Results>
|
|
1150
|
+
<CommandPalette.Empty>No results found</CommandPalette.Empty>
|
|
1151
|
+
</>
|
|
1152
|
+
)}
|
|
1153
|
+
</CommandPalette.List>
|
|
1154
|
+
</CommandPalette.Root>
|
|
1155
|
+
</div>
|
|
1156
|
+
```
|
|
1157
|
+
|
|
1158
|
+
```tsx
|
|
1159
|
+
<div>
|
|
1160
|
+
<Button onClick={() => setOpen(true)}>Open with ResultItem</Button>
|
|
1161
|
+
|
|
1162
|
+
<CommandPalette.Root
|
|
1163
|
+
open={open}
|
|
1164
|
+
onOpenChange={setOpen}
|
|
1165
|
+
items={searchResults}
|
|
1166
|
+
value={search}
|
|
1167
|
+
onValueChange={setSearch}
|
|
1168
|
+
itemToStringValue={(item) => item.title}
|
|
1169
|
+
getSelectableItems={(items) => items}
|
|
1170
|
+
>
|
|
1171
|
+
<CommandPalette.Input placeholder="Search documentation..." />
|
|
1172
|
+
<CommandPalette.List>
|
|
1173
|
+
<CommandPalette.Results>
|
|
1174
|
+
{(item: SearchResult) => (
|
|
1175
|
+
<CommandPalette.ResultItem
|
|
1176
|
+
key={item.id}
|
|
1177
|
+
value={item}
|
|
1178
|
+
title={item.title}
|
|
1179
|
+
breadcrumbs={item.breadcrumbs}
|
|
1180
|
+
icon={item.icon}
|
|
1181
|
+
onClick={() => {
|
|
1182
|
+
console.log("Navigate to:", item.title);
|
|
1183
|
+
setOpen(false);
|
|
1184
|
+
}}
|
|
1185
|
+
/>
|
|
1186
|
+
)}
|
|
1187
|
+
</CommandPalette.Results>
|
|
1188
|
+
<CommandPalette.Empty>No pages found</CommandPalette.Empty>
|
|
1189
|
+
</CommandPalette.List>
|
|
1190
|
+
<CommandPalette.Footer>
|
|
1191
|
+
<span className="flex items-center gap-2">
|
|
1192
|
+
<kbd className="rounded border border-kumo-line bg-kumo-base px-1.5 py-0.5 text-[10px]">
|
|
1193
|
+
↑↓
|
|
1194
|
+
</kbd>
|
|
1195
|
+
<span>Navigate</span>
|
|
1196
|
+
</span>
|
|
1197
|
+
<span className="flex items-center gap-2">
|
|
1198
|
+
<kbd className="rounded border border-kumo-line bg-kumo-base px-1.5 py-0.5 text-[10px]">
|
|
1199
|
+
⌘↵
|
|
1200
|
+
</kbd>
|
|
1201
|
+
<span>Open in new tab</span>
|
|
1202
|
+
</span>
|
|
1203
|
+
</CommandPalette.Footer>
|
|
1204
|
+
</CommandPalette.Root>
|
|
1205
|
+
</div>
|
|
1206
|
+
```
|
|
1207
|
+
|
|
1208
|
+
|
|
1209
|
+
---
|
|
1210
|
+
|
|
1211
|
+
### DateRangePicker
|
|
1212
|
+
|
|
1213
|
+
DateRangePicker component
|
|
1214
|
+
|
|
1215
|
+
**Type:** component
|
|
1216
|
+
|
|
1217
|
+
**Import:** `import { DateRangePicker } from "@cloudflare/kumo";`
|
|
1218
|
+
|
|
1219
|
+
**Category:** Input
|
|
1220
|
+
|
|
1221
|
+
**Props:**
|
|
1222
|
+
|
|
1223
|
+
- `size`: enum [default: base]
|
|
1224
|
+
- `"sm"`: Compact calendar for tight spaces
|
|
1225
|
+
- `"base"`: Default calendar size
|
|
1226
|
+
- `"lg"`: Large calendar for prominent date selection
|
|
1227
|
+
- `variant`: enum [default: default]
|
|
1228
|
+
- `"default"`: Default calendar appearance
|
|
1229
|
+
- `"subtle"`: Subtle calendar with minimal background
|
|
1230
|
+
- `timezone`: string
|
|
1231
|
+
Display timezone (display only)
|
|
1232
|
+
- `className`: string
|
|
1233
|
+
Additional CSS classes
|
|
1234
|
+
- `onStartDateChange`: (date: Date | null) => void
|
|
1235
|
+
Callback when start date changes
|
|
1236
|
+
- `onEndDateChange`: (date: Date | null) => void
|
|
1237
|
+
Callback when end date changes
|
|
1238
|
+
|
|
1239
|
+
**Colors (kumo tokens used):**
|
|
1240
|
+
|
|
1241
|
+
`bg-kumo-base`, `bg-kumo-contrast`, `bg-kumo-fill`, `bg-kumo-interact`, `bg-kumo-overlay`, `text-kumo-default`, `text-kumo-inverse`, `text-kumo-strong`, `text-kumo-subtle`
|
|
1242
|
+
|
|
1243
|
+
**Styling:**
|
|
1244
|
+
|
|
1245
|
+
- **Size Variants:**
|
|
1246
|
+
- `sm`:
|
|
1247
|
+
- Classes: `p-3 gap-2`
|
|
1248
|
+
- Dimensions:
|
|
1249
|
+
- calendarWidth: 168
|
|
1250
|
+
- cellHeight: 22
|
|
1251
|
+
- cellWidth: 24
|
|
1252
|
+
- textSize: 12
|
|
1253
|
+
- iconSize: 14
|
|
1254
|
+
- padding: 12
|
|
1255
|
+
- gap: 8
|
|
1256
|
+
- `base`:
|
|
1257
|
+
- Classes: `p-4 gap-2.5`
|
|
1258
|
+
- Dimensions:
|
|
1259
|
+
- calendarWidth: 196
|
|
1260
|
+
- cellHeight: 26
|
|
1261
|
+
- cellWidth: 28
|
|
1262
|
+
- textSize: 14
|
|
1263
|
+
- iconSize: 16
|
|
1264
|
+
- padding: 16
|
|
1265
|
+
- gap: 10
|
|
1266
|
+
- `lg`:
|
|
1267
|
+
- Classes: `p-5 gap-3`
|
|
1268
|
+
- Dimensions:
|
|
1269
|
+
- calendarWidth: 252
|
|
1270
|
+
- cellHeight: 32
|
|
1271
|
+
- cellWidth: 36
|
|
1272
|
+
- textSize: 16
|
|
1273
|
+
- iconSize: 18
|
|
1274
|
+
- padding: 20
|
|
1275
|
+
- gap: 12
|
|
1276
|
+
|
|
1277
|
+
**Examples:**
|
|
1278
|
+
|
|
1279
|
+
```tsx
|
|
1280
|
+
<div className="flex flex-col gap-4">
|
|
1281
|
+
<DateRangePicker
|
|
1282
|
+
onStartDateChange={setStartDate}
|
|
1283
|
+
onEndDateChange={setEndDate}
|
|
1284
|
+
/>
|
|
1285
|
+
<div className="text-sm text-kumo-subtle">
|
|
1286
|
+
{startDate && endDate ? (
|
|
1287
|
+
<span>
|
|
1288
|
+
Selected: {startDate.toLocaleDateString()} -{" "}
|
|
1289
|
+
{endDate.toLocaleDateString()}
|
|
1290
|
+
</span>
|
|
1291
|
+
) : startDate ? (
|
|
1292
|
+
<span>Start: {startDate.toLocaleDateString()} (select end date)</span>
|
|
1293
|
+
) : (
|
|
1294
|
+
<span>Select a date range</span>
|
|
1295
|
+
)}
|
|
1296
|
+
</div>
|
|
1297
|
+
</div>
|
|
1298
|
+
```
|
|
1299
|
+
|
|
1300
|
+
```tsx
|
|
1301
|
+
<div className="flex flex-col gap-8">
|
|
1302
|
+
<div>
|
|
1303
|
+
<p className="mb-2 text-sm font-medium text-kumo-default">Small</p>
|
|
1304
|
+
<DateRangePicker
|
|
1305
|
+
size="sm"
|
|
1306
|
+
onStartDateChange={() => {}}
|
|
1307
|
+
onEndDateChange={() => {}}
|
|
1308
|
+
/>
|
|
1309
|
+
</div>
|
|
1310
|
+
<div>
|
|
1311
|
+
<p className="mb-2 text-sm font-medium text-kumo-default">
|
|
1312
|
+
Base (default)
|
|
1313
|
+
</p>
|
|
1314
|
+
<DateRangePicker
|
|
1315
|
+
size="base"
|
|
1316
|
+
onStartDateChange={() => {}}
|
|
1317
|
+
onEndDateChange={() => {}}
|
|
1318
|
+
/>
|
|
1319
|
+
</div>
|
|
1320
|
+
<div>
|
|
1321
|
+
<p className="mb-2 text-sm font-medium text-kumo-default">Large</p>
|
|
1322
|
+
<DateRangePicker
|
|
1323
|
+
size="lg"
|
|
1324
|
+
onStartDateChange={() => {}}
|
|
1325
|
+
onEndDateChange={() => {}}
|
|
1326
|
+
/>
|
|
1327
|
+
</div>
|
|
1328
|
+
</div>
|
|
1329
|
+
```
|
|
1330
|
+
|
|
1331
|
+
```tsx
|
|
1332
|
+
<div className="flex flex-col gap-8">
|
|
1333
|
+
<div>
|
|
1334
|
+
<p className="mb-2 text-sm font-medium text-kumo-default">
|
|
1335
|
+
Default variant
|
|
1336
|
+
</p>
|
|
1337
|
+
<DateRangePicker
|
|
1338
|
+
variant="default"
|
|
1339
|
+
onStartDateChange={() => {}}
|
|
1340
|
+
onEndDateChange={() => {}}
|
|
1341
|
+
/>
|
|
1342
|
+
</div>
|
|
1343
|
+
<div>
|
|
1344
|
+
<p className="mb-2 text-sm font-medium text-kumo-default">
|
|
1345
|
+
Subtle variant
|
|
1346
|
+
</p>
|
|
1347
|
+
<DateRangePicker
|
|
1348
|
+
variant="subtle"
|
|
1349
|
+
onStartDateChange={() => {}}
|
|
1350
|
+
onEndDateChange={() => {}}
|
|
1351
|
+
/>
|
|
1352
|
+
</div>
|
|
1353
|
+
</div>
|
|
1354
|
+
```
|
|
1355
|
+
|
|
1356
|
+
```tsx
|
|
1357
|
+
<DateRangePicker
|
|
1358
|
+
timezone="London, UK (GMT+0)"
|
|
1359
|
+
onStartDateChange={() => {}}
|
|
1360
|
+
onEndDateChange={() => {}}
|
|
1361
|
+
/>
|
|
1362
|
+
```
|
|
1363
|
+
|
|
1364
|
+
|
|
1365
|
+
---
|
|
1366
|
+
|
|
1367
|
+
### Dialog
|
|
1368
|
+
|
|
1369
|
+
Dialog component
|
|
1370
|
+
|
|
1371
|
+
**Type:** component
|
|
1372
|
+
|
|
1373
|
+
**Import:** `import { Dialog } from "@cloudflare/kumo";`
|
|
1374
|
+
|
|
1375
|
+
**Category:** Overlay
|
|
1376
|
+
|
|
1377
|
+
**Props:**
|
|
1378
|
+
|
|
1379
|
+
- `className`: string
|
|
1380
|
+
- `children`: ReactNode
|
|
1381
|
+
- `size`: enum [default: base]
|
|
1382
|
+
- `"base"`: Default dialog width
|
|
1383
|
+
- `"sm"`: Small dialog for simple confirmations
|
|
1384
|
+
- `"lg"`: Large dialog for complex content
|
|
1385
|
+
- `"xl"`: Extra large dialog for detailed views
|
|
1386
|
+
|
|
1387
|
+
**Colors (kumo tokens used):**
|
|
1388
|
+
|
|
1389
|
+
`bg-kumo-base`, `bg-kumo-overlay`, `text-kumo-default`
|
|
1390
|
+
|
|
1391
|
+
**Styling:**
|
|
1392
|
+
|
|
1393
|
+
- **Dimensions:** `[object Object]`
|
|
1394
|
+
|
|
1395
|
+
**Sub-Components:**
|
|
1396
|
+
|
|
1397
|
+
This is a compound component. Use these sub-components:
|
|
1398
|
+
|
|
1399
|
+
#### Dialog.Root
|
|
1400
|
+
|
|
1401
|
+
Controls the open state of the dialog. Doesn't render its own HTML element.
|
|
1402
|
+
|
|
1403
|
+
Props:
|
|
1404
|
+
- `open`: boolean - Whether the dialog is currently open (controlled mode)
|
|
1405
|
+
- `defaultOpen`: boolean [default: false] - Whether the dialog is initially open (uncontrolled mode)
|
|
1406
|
+
- `onOpenChange`: (open: boolean, event: Event) => void - Callback fired when the dialog opens or closes
|
|
1407
|
+
- `modal`: boolean | 'trap-focus' [default: true] - Whether the dialog is modal. When true, focus is trapped and page scroll is locked
|
|
1408
|
+
- `dismissible`: boolean [default: true] - Whether clicking outside closes the dialog
|
|
1409
|
+
|
|
1410
|
+
Usage:
|
|
1411
|
+
```tsx
|
|
1412
|
+
<Dialog.Root open={isOpen} onOpenChange={setIsOpen}>
|
|
1413
|
+
```
|
|
1414
|
+
```tsx
|
|
1415
|
+
<Dialog.Root defaultOpen={false}>
|
|
1416
|
+
```
|
|
1417
|
+
|
|
1418
|
+
#### Dialog.Trigger
|
|
1419
|
+
|
|
1420
|
+
A button that opens the dialog when clicked. Renders a `<button>` element.
|
|
1421
|
+
|
|
1422
|
+
Props:
|
|
1423
|
+
- `render`: ReactElement | ((props, state) => ReactElement) - Custom element to render instead of the default button
|
|
1424
|
+
- `disabled`: boolean - Whether the trigger is disabled
|
|
1425
|
+
|
|
1426
|
+
Usage:
|
|
1427
|
+
```tsx
|
|
1428
|
+
<Dialog.Trigger render={<Button>Open</Button>} />
|
|
1429
|
+
```
|
|
1430
|
+
```tsx
|
|
1431
|
+
<Dialog.Trigger>Open Dialog</Dialog.Trigger>
|
|
1432
|
+
```
|
|
1433
|
+
|
|
1434
|
+
#### Dialog.Title
|
|
1435
|
+
|
|
1436
|
+
A heading that labels the dialog for accessibility. Renders a `<h2>` element.
|
|
1437
|
+
|
|
1438
|
+
Props:
|
|
1439
|
+
- `render`: ReactElement | ((props, state) => ReactElement) - Custom element to render instead of the default h2
|
|
1440
|
+
|
|
1441
|
+
Usage:
|
|
1442
|
+
```tsx
|
|
1443
|
+
<Dialog.Title>Confirm Action</Dialog.Title>
|
|
1444
|
+
```
|
|
1445
|
+
```tsx
|
|
1446
|
+
<Dialog.Title render={<h3 />}>Custom Heading</Dialog.Title>
|
|
1447
|
+
```
|
|
1448
|
+
|
|
1449
|
+
#### Dialog.Description
|
|
1450
|
+
|
|
1451
|
+
A paragraph providing additional context about the dialog. Renders a `<p>` element.
|
|
1452
|
+
|
|
1453
|
+
Props:
|
|
1454
|
+
- `render`: ReactElement | ((props, state) => ReactElement) - Custom element to render instead of the default p
|
|
1455
|
+
|
|
1456
|
+
Usage:
|
|
1457
|
+
```tsx
|
|
1458
|
+
<Dialog.Description>Are you sure you want to proceed?</Dialog.Description>
|
|
1459
|
+
```
|
|
1460
|
+
|
|
1461
|
+
#### Dialog.Close
|
|
1462
|
+
|
|
1463
|
+
A button that closes the dialog when clicked. Renders a `<button>` element.
|
|
1464
|
+
|
|
1465
|
+
Props:
|
|
1466
|
+
- `render`: ReactElement | ((props, state) => ReactElement) - Custom element to render instead of the default button
|
|
1467
|
+
- `disabled`: boolean - Whether the close button is disabled
|
|
1468
|
+
|
|
1469
|
+
Usage:
|
|
1470
|
+
```tsx
|
|
1471
|
+
<Dialog.Close render={<Button>Cancel</Button>} />
|
|
1472
|
+
```
|
|
1473
|
+
```tsx
|
|
1474
|
+
<Dialog.Close>×</Dialog.Close>
|
|
1475
|
+
```
|
|
1476
|
+
|
|
1477
|
+
|
|
1478
|
+
**Examples:**
|
|
1479
|
+
|
|
1480
|
+
```tsx
|
|
1481
|
+
<Dialog.Root>
|
|
1482
|
+
<Dialog.Trigger render={(p) => <Button {...p}>Click me</Button>} />
|
|
1483
|
+
<Dialog className="p-8">
|
|
1484
|
+
<div className="mb-4 flex items-start justify-between gap-4">
|
|
1485
|
+
<Dialog.Title className="text-2xl font-semibold">
|
|
1486
|
+
Modal Title
|
|
1487
|
+
</Dialog.Title>
|
|
1488
|
+
<Dialog.Close
|
|
1489
|
+
aria-label="Close"
|
|
1490
|
+
render={(props) => (
|
|
1491
|
+
<Button
|
|
1492
|
+
{...props}
|
|
1493
|
+
variant="secondary"
|
|
1494
|
+
shape="square"
|
|
1495
|
+
icon={<X />}
|
|
1496
|
+
/>
|
|
1497
|
+
)}
|
|
1498
|
+
/>
|
|
1499
|
+
</div>
|
|
1500
|
+
<Dialog.Description className="text-kumo-subtle">
|
|
1501
|
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
|
|
1502
|
+
eiusmod tempor incididunt ut labore et dolore magna aliqua.
|
|
1503
|
+
</Dialog.Description>
|
|
1504
|
+
</Dialog>
|
|
1505
|
+
</Dialog.Root>
|
|
1506
|
+
```
|
|
1507
|
+
|
|
1508
|
+
```tsx
|
|
1509
|
+
<Dialog.Root>
|
|
1510
|
+
<Dialog.Trigger render={(p) => <Button {...p}>Delete</Button>} />
|
|
1511
|
+
<Dialog className="p-8">
|
|
1512
|
+
<div className="mb-4 flex items-start justify-between gap-4">
|
|
1513
|
+
<Dialog.Title className="text-2xl font-semibold">
|
|
1514
|
+
Modal Title
|
|
1515
|
+
</Dialog.Title>
|
|
1516
|
+
<Dialog.Close
|
|
1517
|
+
aria-label="Close"
|
|
1518
|
+
render={(props) => (
|
|
1519
|
+
<Button
|
|
1520
|
+
{...props}
|
|
1521
|
+
variant="secondary"
|
|
1522
|
+
shape="square"
|
|
1523
|
+
icon={<X />}
|
|
1524
|
+
/>
|
|
1525
|
+
)}
|
|
1526
|
+
/>
|
|
1527
|
+
</div>
|
|
1528
|
+
<Dialog.Description className="text-kumo-subtle">
|
|
1529
|
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
|
|
1530
|
+
eiusmod tempor incididunt ut labore et dolore magna aliqua.
|
|
1531
|
+
</Dialog.Description>
|
|
1532
|
+
<div className="mt-8 flex justify-end gap-2">
|
|
1533
|
+
<Button variant="secondary">Cancel</Button>
|
|
1534
|
+
<Dialog.Close
|
|
1535
|
+
render={(props) => (
|
|
1536
|
+
<Button variant="destructive" {...props}>
|
|
1537
|
+
Delete
|
|
1538
|
+
</Button>
|
|
1539
|
+
)}
|
|
1540
|
+
/>
|
|
1541
|
+
</div>
|
|
1542
|
+
</Dialog>
|
|
1543
|
+
</Dialog.Root>
|
|
1544
|
+
```
|
|
1545
|
+
|
|
1546
|
+
|
|
1547
|
+
---
|
|
1548
|
+
|
|
1549
|
+
### DropdownMenu
|
|
1550
|
+
|
|
1551
|
+
DropdownMenu component
|
|
1552
|
+
|
|
1553
|
+
**Type:** component
|
|
1554
|
+
|
|
1555
|
+
**Import:** `import { DropdownMenu } from "@cloudflare/kumo";`
|
|
1556
|
+
|
|
1557
|
+
**Category:** Overlay
|
|
1558
|
+
|
|
1559
|
+
**Props:**
|
|
1560
|
+
|
|
1561
|
+
- `variant`: enum [default: default]
|
|
1562
|
+
- `"default"`: Default dropdown item appearance
|
|
1563
|
+
- `"danger"`: Destructive action item
|
|
1564
|
+
|
|
1565
|
+
**Colors (kumo tokens used):**
|
|
1566
|
+
|
|
1567
|
+
`bg-kumo-control`, `bg-kumo-danger`, `bg-kumo-line`, `bg-kumo-overlay`, `bg-kumo-tint`, `ring-kumo-line`, `text-kumo-danger`, `text-kumo-default`
|
|
1568
|
+
|
|
1569
|
+
**Sub-Components:**
|
|
1570
|
+
|
|
1571
|
+
This is a compound component. Use these sub-components:
|
|
1572
|
+
|
|
1573
|
+
#### DropdownMenu.Trigger
|
|
1574
|
+
|
|
1575
|
+
Trigger sub-component
|
|
1576
|
+
|
|
1577
|
+
#### DropdownMenu.Portal
|
|
1578
|
+
|
|
1579
|
+
Portal sub-component (wraps DropdownMenuPrimitive)
|
|
1580
|
+
|
|
1581
|
+
#### DropdownMenu.Sub
|
|
1582
|
+
|
|
1583
|
+
Sub sub-component (wraps DropdownMenuPrimitive)
|
|
1584
|
+
|
|
1585
|
+
#### DropdownMenu.SubTrigger
|
|
1586
|
+
|
|
1587
|
+
SubTrigger sub-component
|
|
1588
|
+
|
|
1589
|
+
#### DropdownMenu.SubContent
|
|
1590
|
+
|
|
1591
|
+
SubContent sub-component
|
|
1592
|
+
|
|
1593
|
+
#### DropdownMenu.Content
|
|
1594
|
+
|
|
1595
|
+
Content sub-component
|
|
1596
|
+
|
|
1597
|
+
#### DropdownMenu.Item
|
|
1598
|
+
|
|
1599
|
+
Item sub-component
|
|
1600
|
+
|
|
1601
|
+
#### DropdownMenu.CheckboxItem
|
|
1602
|
+
|
|
1603
|
+
CheckboxItem sub-component
|
|
1604
|
+
|
|
1605
|
+
#### DropdownMenu.RadioGroup
|
|
1606
|
+
|
|
1607
|
+
RadioGroup sub-component (wraps DropdownMenuPrimitive)
|
|
1608
|
+
|
|
1609
|
+
#### DropdownMenu.RadioItem
|
|
1610
|
+
|
|
1611
|
+
RadioItem sub-component
|
|
1612
|
+
|
|
1613
|
+
#### DropdownMenu.RadioItemIndicator
|
|
1614
|
+
|
|
1615
|
+
RadioItemIndicator sub-component
|
|
1616
|
+
|
|
1617
|
+
#### DropdownMenu.Label
|
|
1618
|
+
|
|
1619
|
+
Label sub-component
|
|
1620
|
+
|
|
1621
|
+
#### DropdownMenu.Separator
|
|
1622
|
+
|
|
1623
|
+
Separator sub-component
|
|
1624
|
+
|
|
1625
|
+
#### DropdownMenu.Shortcut
|
|
1626
|
+
|
|
1627
|
+
Shortcut sub-component
|
|
1628
|
+
|
|
1629
|
+
#### DropdownMenu.Group
|
|
1630
|
+
|
|
1631
|
+
Group sub-component (wraps DropdownMenuPrimitive)
|
|
1632
|
+
|
|
1633
|
+
|
|
1634
|
+
---
|
|
1635
|
+
|
|
1636
|
+
### Empty
|
|
1637
|
+
|
|
1638
|
+
Empty component
|
|
1639
|
+
|
|
1640
|
+
**Type:** component
|
|
1641
|
+
|
|
1642
|
+
**Import:** `import { Empty } from "@cloudflare/kumo";`
|
|
1643
|
+
|
|
1644
|
+
**Category:** Display
|
|
1645
|
+
|
|
1646
|
+
**Props:**
|
|
1647
|
+
|
|
1648
|
+
- `size`: enum [default: base]
|
|
1649
|
+
- `"sm"`: Compact empty state for smaller containers
|
|
1650
|
+
- `"base"`: Default empty state size
|
|
1651
|
+
- `"lg"`: Large empty state for prominent placement
|
|
1652
|
+
- `icon`: ReactNode
|
|
1653
|
+
- `title`: string (required)
|
|
1654
|
+
- `description`: string
|
|
1655
|
+
- `commandLine`: string
|
|
1656
|
+
- `contents`: ReactNode
|
|
1657
|
+
- `className`: string
|
|
1658
|
+
|
|
1659
|
+
**Colors (kumo tokens used):**
|
|
1660
|
+
|
|
1661
|
+
`bg-kumo-control`, `bg-kumo-overlay`, `border-kumo-fill`, `border-kumo-interact`, `text-kumo-brand`, `text-kumo-default`, `text-kumo-inactive`, `text-kumo-strong`, `text-kumo-success`
|
|
1662
|
+
|
|
1663
|
+
**Examples:**
|
|
1664
|
+
|
|
1665
|
+
```tsx
|
|
1666
|
+
<Empty
|
|
1667
|
+
icon={<PackageIcon size={48} />}
|
|
1668
|
+
title="No packages found"
|
|
1669
|
+
description="Get started by installing your first package."
|
|
1670
|
+
commandLine="npm install @cloudflare/kumo"
|
|
1671
|
+
contents={
|
|
1672
|
+
<div className="flex items-center gap-2">
|
|
1673
|
+
<Button icon={<CodeIcon />}>See examples</Button>
|
|
1674
|
+
<Button icon={<GlobeIcon />} variant="primary">
|
|
1675
|
+
View documentation
|
|
1676
|
+
</Button>
|
|
1677
|
+
</div>
|
|
1678
|
+
}
|
|
1679
|
+
/>
|
|
1680
|
+
```
|
|
1681
|
+
|
|
1682
|
+
```tsx
|
|
1683
|
+
<div className="flex flex-col gap-8">
|
|
1684
|
+
<div>
|
|
1685
|
+
<p className="mb-2 text-sm text-kumo-subtle">Small</p>
|
|
1686
|
+
<Empty
|
|
1687
|
+
size="sm"
|
|
1688
|
+
icon={<Database size={32} className="text-kumo-inactive" />}
|
|
1689
|
+
title="No data available"
|
|
1690
|
+
description="There is no data to display."
|
|
1691
|
+
/>
|
|
1692
|
+
</div>
|
|
1693
|
+
<div>
|
|
1694
|
+
<p className="mb-2 text-sm text-kumo-subtle">Base</p>
|
|
1695
|
+
<Empty
|
|
1696
|
+
size="base"
|
|
1697
|
+
icon={<Database size={48} className="text-kumo-inactive" />}
|
|
1698
|
+
title="No data available"
|
|
1699
|
+
description="There is no data to display."
|
|
1700
|
+
/>
|
|
1701
|
+
</div>
|
|
1702
|
+
<div>
|
|
1703
|
+
<p className="mb-2 text-sm text-kumo-subtle">Large</p>
|
|
1704
|
+
<Empty
|
|
1705
|
+
size="lg"
|
|
1706
|
+
icon={<Database size={64} className="text-kumo-inactive" />}
|
|
1707
|
+
title="No data available"
|
|
1708
|
+
description="There is no data to display."
|
|
1709
|
+
/>
|
|
1710
|
+
</div>
|
|
1711
|
+
</div>
|
|
1712
|
+
```
|
|
1713
|
+
|
|
1714
|
+
```tsx
|
|
1715
|
+
<Empty
|
|
1716
|
+
icon={<FolderOpen size={48} className="text-kumo-inactive" />}
|
|
1717
|
+
title="No projects found"
|
|
1718
|
+
description="Get started by creating your first project using the command below."
|
|
1719
|
+
commandLine="npm create kumo-project"
|
|
1720
|
+
/>
|
|
1721
|
+
```
|
|
1722
|
+
|
|
1723
|
+
```tsx
|
|
1724
|
+
<Empty
|
|
1725
|
+
icon={<CloudSlash size={48} className="text-kumo-inactive" />}
|
|
1726
|
+
title="No connection"
|
|
1727
|
+
description="Unable to connect to the server. Please check your connection and try again."
|
|
1728
|
+
contents={
|
|
1729
|
+
<div className="flex gap-2">
|
|
1730
|
+
<Button variant="primary">Retry</Button>
|
|
1731
|
+
<Button variant="secondary">Go Back</Button>
|
|
1732
|
+
</div>
|
|
1733
|
+
}
|
|
1734
|
+
/>
|
|
1735
|
+
```
|
|
1736
|
+
|
|
1737
|
+
```tsx
|
|
1738
|
+
<Empty title="Nothing here" />
|
|
1739
|
+
```
|
|
1740
|
+
|
|
1741
|
+
```tsx
|
|
1742
|
+
<Empty
|
|
1743
|
+
title="No results found"
|
|
1744
|
+
description="Try adjusting your search or filter to find what you're looking for."
|
|
1745
|
+
/>
|
|
1746
|
+
```
|
|
1747
|
+
|
|
1748
|
+
|
|
1749
|
+
---
|
|
1750
|
+
|
|
1751
|
+
### Field
|
|
1752
|
+
|
|
1753
|
+
Field component
|
|
1754
|
+
|
|
1755
|
+
**Type:** component
|
|
1756
|
+
|
|
1757
|
+
**Import:** `import { Field } from "@cloudflare/kumo";`
|
|
1758
|
+
|
|
1759
|
+
**Category:** Input
|
|
1760
|
+
|
|
1761
|
+
**Props:**
|
|
1762
|
+
|
|
1763
|
+
- `controlFirst`: boolean
|
|
1764
|
+
When true, places the control (checkbox/switch) before the label visually. When false (default), places the label before the control. Used to support different layout patterns (e.g., iOS-style toggles on the right).
|
|
1765
|
+
- `children`: ReactNode
|
|
1766
|
+
- `label`: ReactNode
|
|
1767
|
+
The label content - can be a string or any React node
|
|
1768
|
+
- `required`: boolean
|
|
1769
|
+
When explicitly false, shows gray "(optional)" text after the label. When true or undefined, no indicator is shown.
|
|
1770
|
+
- `labelTooltip`: ReactNode
|
|
1771
|
+
Tooltip content to display next to the label via an info icon
|
|
1772
|
+
- `error`: object
|
|
1773
|
+
- `description`: ReactNode
|
|
1774
|
+
|
|
1775
|
+
**Colors (kumo tokens used):**
|
|
1776
|
+
|
|
1777
|
+
`text-kumo-danger`, `text-kumo-default`, `text-kumo-subtle`
|
|
1778
|
+
|
|
1779
|
+
---
|
|
1780
|
+
|
|
1781
|
+
### Grid
|
|
1782
|
+
|
|
1783
|
+
Grid component
|
|
1784
|
+
|
|
1785
|
+
**Type:** component
|
|
1786
|
+
|
|
1787
|
+
**Import:** `import { Grid } from "@cloudflare/kumo";`
|
|
1788
|
+
|
|
1789
|
+
**Category:** Layout
|
|
1790
|
+
|
|
1791
|
+
**Props:**
|
|
1792
|
+
|
|
1793
|
+
- `children`: ReactNode
|
|
1794
|
+
Child node(s) that can be nested inside component
|
|
1795
|
+
- `className`: string
|
|
1796
|
+
CSS class names that can be appended to the component
|
|
1797
|
+
- `id`: string
|
|
1798
|
+
- `lang`: string
|
|
1799
|
+
- `title`: string
|
|
1800
|
+
- `mobileDivider`: boolean
|
|
1801
|
+
Show dividers between grid items on mobile (only works with 4up variant)
|
|
1802
|
+
- `gap`: enum [default: base]
|
|
1803
|
+
- `"none"`: No gap between grid items
|
|
1804
|
+
- `"sm"`: Small gap between grid items
|
|
1805
|
+
- `"base"`: Default responsive gap between grid items
|
|
1806
|
+
- `"lg"`: Large gap between grid items
|
|
1807
|
+
- `variant`: enum
|
|
1808
|
+
- `"2up"`: Grid items stack on small screens, display side-by-side on medium screens and up
|
|
1809
|
+
- `"side-by-side"`: Grid items always displayed side-by-side
|
|
1810
|
+
- `"2-1"`: Two-thirds / one-third split (66%/33%) on medium screens and up
|
|
1811
|
+
- `"1-2"`: One-third / two-thirds split (33%/66%) on medium screens and up
|
|
1812
|
+
- `"1-3up"`: Grid items stack on small screens, expand to 3 across on large screens
|
|
1813
|
+
- `"3up"`: Grid items stack on small screens, 2 across on medium, 3 across on large
|
|
1814
|
+
- `"4up"`: Grid items stack on small screens, progressively increase columns at larger breakpoints
|
|
1815
|
+
- `"6up"`: Grid items start at 2 across, expand to 6 across on XL
|
|
1816
|
+
- `"1-2-4up"`: Grid items stack on small screens, 2 across on medium, 4 across on large
|
|
1817
|
+
|
|
1818
|
+
**Colors (kumo tokens used):**
|
|
1819
|
+
|
|
1820
|
+
`border-kumo-line`
|
|
1821
|
+
|
|
1822
|
+
**Examples:**
|
|
1823
|
+
|
|
1824
|
+
```tsx
|
|
1825
|
+
<Grid variant="2up" gap="base">
|
|
1826
|
+
<GridItem>
|
|
1827
|
+
<Surface className="rounded-lg p-4">
|
|
1828
|
+
<Text bold>Item 1</Text>
|
|
1829
|
+
<div className="mt-1">
|
|
1830
|
+
<Text variant="secondary">First grid item</Text>
|
|
1831
|
+
</div>
|
|
1832
|
+
</Surface>
|
|
1833
|
+
</GridItem>
|
|
1834
|
+
<GridItem>
|
|
1835
|
+
<Surface className="rounded-lg p-4">
|
|
1836
|
+
<Text bold>Item 2</Text>
|
|
1837
|
+
<div className="mt-1">
|
|
1838
|
+
<Text variant="secondary">Second grid item</Text>
|
|
1839
|
+
</div>
|
|
1840
|
+
</Surface>
|
|
1841
|
+
</GridItem>
|
|
1842
|
+
</Grid>
|
|
1843
|
+
```
|
|
1844
|
+
|
|
1845
|
+
```tsx
|
|
1846
|
+
<div className="flex flex-col gap-8">
|
|
1847
|
+
<div>
|
|
1848
|
+
<p className="mb-2 text-kumo-subtle">variant="2up"</p>
|
|
1849
|
+
<Grid variant="2up" gap="sm">
|
|
1850
|
+
<GridItem>
|
|
1851
|
+
<Surface className="rounded-lg p-4 text-center">
|
|
1852
|
+
<Text>1</Text>
|
|
1853
|
+
</Surface>
|
|
1854
|
+
</GridItem>
|
|
1855
|
+
<GridItem>
|
|
1856
|
+
<Surface className="rounded-lg p-4 text-center">
|
|
1857
|
+
<Text>2</Text>
|
|
1858
|
+
</Surface>
|
|
1859
|
+
</GridItem>
|
|
1860
|
+
</Grid>
|
|
1861
|
+
</div>
|
|
1862
|
+
|
|
1863
|
+
<div>
|
|
1864
|
+
<p className="mb-2 text-kumo-subtle">variant="3up"</p>
|
|
1865
|
+
<Grid variant="3up" gap="sm">
|
|
1866
|
+
<GridItem>
|
|
1867
|
+
<Surface className="rounded-lg p-4 text-center">
|
|
1868
|
+
<Text>1</Text>
|
|
1869
|
+
</Surface>
|
|
1870
|
+
</GridItem>
|
|
1871
|
+
<GridItem>
|
|
1872
|
+
<Surface className="rounded-lg p-4 text-center">
|
|
1873
|
+
<Text>2</Text>
|
|
1874
|
+
</Surface>
|
|
1875
|
+
</GridItem>
|
|
1876
|
+
<GridItem>
|
|
1877
|
+
<Surface className="rounded-lg p-4 text-center">
|
|
1878
|
+
<Text>3</Text>
|
|
1879
|
+
</Surface>
|
|
1880
|
+
</GridItem>
|
|
1881
|
+
</Grid>
|
|
1882
|
+
</div>
|
|
1883
|
+
|
|
1884
|
+
<div>
|
|
1885
|
+
<p className="mb-2 text-kumo-subtle">variant="4up"</p>
|
|
1886
|
+
<Grid variant="4up" gap="sm">
|
|
1887
|
+
<GridItem>
|
|
1888
|
+
<Surface className="rounded-lg p-4 text-center">
|
|
1889
|
+
<Text>1</Text>
|
|
1890
|
+
</Surface>
|
|
1891
|
+
</GridItem>
|
|
1892
|
+
<GridItem>
|
|
1893
|
+
<Surface className="rounded-lg p-4 text-center">
|
|
1894
|
+
<Text>2</Text>
|
|
1895
|
+
</Surface>
|
|
1896
|
+
</GridItem>
|
|
1897
|
+
<GridItem>
|
|
1898
|
+
<Surface className="rounded-lg p-4 text-center">
|
|
1899
|
+
<Text>3</Text>
|
|
1900
|
+
</Surface>
|
|
1901
|
+
</GridItem>
|
|
1902
|
+
<GridItem>
|
|
1903
|
+
<Surface className="rounded-lg p-4 text-center">
|
|
1904
|
+
<Text>4</Text>
|
|
1905
|
+
</Surface>
|
|
1906
|
+
</GridItem>
|
|
1907
|
+
</Grid>
|
|
1908
|
+
</div>
|
|
1909
|
+
</div>
|
|
1910
|
+
```
|
|
1911
|
+
|
|
1912
|
+
```tsx
|
|
1913
|
+
<div className="flex flex-col gap-8">
|
|
1914
|
+
<div>
|
|
1915
|
+
<p className="mb-2 text-kumo-subtle">variant="2-1" (66% / 33%)</p>
|
|
1916
|
+
<Grid variant="2-1" gap="sm">
|
|
1917
|
+
<GridItem>
|
|
1918
|
+
<Surface className="rounded-lg p-4">
|
|
1919
|
+
<Text bold>Main Content</Text>
|
|
1920
|
+
<div className="mt-1">
|
|
1921
|
+
<Text variant="secondary">Two-thirds width</Text>
|
|
1922
|
+
</div>
|
|
1923
|
+
</Surface>
|
|
1924
|
+
</GridItem>
|
|
1925
|
+
<GridItem>
|
|
1926
|
+
<Surface className="rounded-lg p-4">
|
|
1927
|
+
<Text bold>Sidebar</Text>
|
|
1928
|
+
<div className="mt-1">
|
|
1929
|
+
<Text variant="secondary">One-third width</Text>
|
|
1930
|
+
</div>
|
|
1931
|
+
</Surface>
|
|
1932
|
+
</GridItem>
|
|
1933
|
+
</Grid>
|
|
1934
|
+
</div>
|
|
1935
|
+
|
|
1936
|
+
<div>
|
|
1937
|
+
<p className="mb-2 text-kumo-subtle">variant="1-2" (33% / 66%)</p>
|
|
1938
|
+
<Grid variant="1-2" gap="sm">
|
|
1939
|
+
<GridItem>
|
|
1940
|
+
<Surface className="rounded-lg p-4">
|
|
1941
|
+
<Text bold>Sidebar</Text>
|
|
1942
|
+
<div className="mt-1">
|
|
1943
|
+
<Text variant="secondary">One-third width</Text>
|
|
1944
|
+
</div>
|
|
1945
|
+
</Surface>
|
|
1946
|
+
</GridItem>
|
|
1947
|
+
<GridItem>
|
|
1948
|
+
<Surface className="rounded-lg p-4">
|
|
1949
|
+
<Text bold>Main Content</Text>
|
|
1950
|
+
<div className="mt-1">
|
|
1951
|
+
<Text variant="secondary">Two-thirds width</Text>
|
|
1952
|
+
</div>
|
|
1953
|
+
</Surface>
|
|
1954
|
+
</GridItem>
|
|
1955
|
+
</Grid>
|
|
1956
|
+
</div>
|
|
1957
|
+
</div>
|
|
1958
|
+
```
|
|
1959
|
+
|
|
1960
|
+
```tsx
|
|
1961
|
+
<div className="flex flex-col gap-8">
|
|
1962
|
+
<div>
|
|
1963
|
+
<p className="mb-2 text-kumo-subtle">gap="none"</p>
|
|
1964
|
+
<Grid variant="side-by-side" gap="none">
|
|
1965
|
+
<GridItem>
|
|
1966
|
+
<Surface className="rounded-lg p-4 text-center">
|
|
1967
|
+
<Text>1</Text>
|
|
1968
|
+
</Surface>
|
|
1969
|
+
</GridItem>
|
|
1970
|
+
<GridItem>
|
|
1971
|
+
<Surface className="rounded-lg p-4 text-center">
|
|
1972
|
+
<Text>2</Text>
|
|
1973
|
+
</Surface>
|
|
1974
|
+
</GridItem>
|
|
1975
|
+
</Grid>
|
|
1976
|
+
</div>
|
|
1977
|
+
|
|
1978
|
+
<div>
|
|
1979
|
+
<p className="mb-2 text-kumo-subtle">gap="sm"</p>
|
|
1980
|
+
<Grid variant="side-by-side" gap="sm">
|
|
1981
|
+
<GridItem>
|
|
1982
|
+
<Surface className="rounded-lg p-4 text-center">
|
|
1983
|
+
<Text>1</Text>
|
|
1984
|
+
</Surface>
|
|
1985
|
+
</GridItem>
|
|
1986
|
+
<GridItem>
|
|
1987
|
+
<Surface className="rounded-lg p-4 text-center">
|
|
1988
|
+
<Text>2</Text>
|
|
1989
|
+
</Surface>
|
|
1990
|
+
</GridItem>
|
|
1991
|
+
</Grid>
|
|
1992
|
+
</div>
|
|
1993
|
+
|
|
1994
|
+
<div>
|
|
1995
|
+
<p className="mb-2 text-kumo-subtle">
|
|
1996
|
+
gap="base" (default, responsive)
|
|
1997
|
+
</p>
|
|
1998
|
+
<Grid variant="side-by-side" gap="base">
|
|
1999
|
+
<GridItem>
|
|
2000
|
+
<Surface className="rounded-lg p-4 text-center">
|
|
2001
|
+
<Text>1</Text>
|
|
2002
|
+
</Surface>
|
|
2003
|
+
</GridItem>
|
|
2004
|
+
<GridItem>
|
|
2005
|
+
<Surface className="rounded-lg p-4 text-center">
|
|
2006
|
+
<Text>2</Text>
|
|
2007
|
+
</Surface>
|
|
2008
|
+
</GridItem>
|
|
2009
|
+
</Grid>
|
|
2010
|
+
</div>
|
|
2011
|
+
|
|
2012
|
+
<div>
|
|
2013
|
+
<p className="mb-2 text-kumo-subtle">gap="lg"</p>
|
|
2014
|
+
<Grid variant="side-by-side" gap="lg">
|
|
2015
|
+
<GridItem>
|
|
2016
|
+
<Surface className="rounded-lg p-4 text-center">
|
|
2017
|
+
<Text>1</Text>
|
|
2018
|
+
</Surface>
|
|
2019
|
+
</GridItem>
|
|
2020
|
+
<GridItem>
|
|
2021
|
+
<Surface className="rounded-lg p-4 text-center">
|
|
2022
|
+
<Text>2</Text>
|
|
2023
|
+
</Surface>
|
|
2024
|
+
</GridItem>
|
|
2025
|
+
</Grid>
|
|
2026
|
+
</div>
|
|
2027
|
+
</div>
|
|
2028
|
+
```
|
|
2029
|
+
|
|
2030
|
+
```tsx
|
|
2031
|
+
<Grid variant="4up" gap="base" mobileDivider>
|
|
2032
|
+
<GridItem>
|
|
2033
|
+
<Surface className="rounded-lg p-4">
|
|
2034
|
+
<Text bold>Item 1</Text>
|
|
2035
|
+
<div className="mt-1">
|
|
2036
|
+
<Text variant="secondary">Has divider on mobile</Text>
|
|
2037
|
+
</div>
|
|
2038
|
+
</Surface>
|
|
2039
|
+
</GridItem>
|
|
2040
|
+
<GridItem>
|
|
2041
|
+
<Surface className="rounded-lg p-4">
|
|
2042
|
+
<Text bold>Item 2</Text>
|
|
2043
|
+
<div className="mt-1">
|
|
2044
|
+
<Text variant="secondary">Has divider on mobile</Text>
|
|
2045
|
+
</div>
|
|
2046
|
+
</Surface>
|
|
2047
|
+
</GridItem>
|
|
2048
|
+
<GridItem>
|
|
2049
|
+
<Surface className="rounded-lg p-4">
|
|
2050
|
+
<Text bold>Item 3</Text>
|
|
2051
|
+
<div className="mt-1">
|
|
2052
|
+
<Text variant="secondary">Has divider on mobile</Text>
|
|
2053
|
+
</div>
|
|
2054
|
+
</Surface>
|
|
2055
|
+
</GridItem>
|
|
2056
|
+
<GridItem>
|
|
2057
|
+
<Surface className="rounded-lg p-4">
|
|
2058
|
+
<Text bold>Item 4</Text>
|
|
2059
|
+
<div className="mt-1">
|
|
2060
|
+
<Text variant="secondary">Has divider on mobile</Text>
|
|
2061
|
+
</div>
|
|
2062
|
+
</Surface>
|
|
2063
|
+
</GridItem>
|
|
2064
|
+
</Grid>
|
|
2065
|
+
```
|
|
2066
|
+
|
|
2067
|
+
|
|
2068
|
+
---
|
|
2069
|
+
|
|
2070
|
+
### Input
|
|
2071
|
+
|
|
2072
|
+
Input component
|
|
2073
|
+
|
|
2074
|
+
**Type:** component
|
|
2075
|
+
|
|
2076
|
+
**Import:** `import { Input } from "@cloudflare/kumo";`
|
|
2077
|
+
|
|
2078
|
+
**Category:** Input
|
|
2079
|
+
|
|
2080
|
+
**Props:**
|
|
2081
|
+
|
|
2082
|
+
- `label`: ReactNode
|
|
2083
|
+
Label content for the input (enables Field wrapper) - can be a string or any React node
|
|
2084
|
+
- `labelTooltip`: ReactNode
|
|
2085
|
+
Tooltip content to display next to the label via an info icon
|
|
2086
|
+
- `description`: ReactNode
|
|
2087
|
+
Helper text displayed below the input
|
|
2088
|
+
- `error`: string | object
|
|
2089
|
+
Error message or validation error object
|
|
2090
|
+
- `size`: enum [default: base]
|
|
2091
|
+
- `"xs"`: Extra small input for compact UIs
|
|
2092
|
+
- `"sm"`: Small input for secondary fields
|
|
2093
|
+
- `"base"`: Default input size
|
|
2094
|
+
- `"lg"`: Large input for prominent fields
|
|
2095
|
+
- `variant`: enum [default: default]
|
|
2096
|
+
- `"default"`: Default input appearance
|
|
2097
|
+
- `"error"`: Error state for validation failures
|
|
2098
|
+
|
|
2099
|
+
**State Classes:**
|
|
2100
|
+
- `"default"`:
|
|
2101
|
+
- `focus`: `focus:ring-kumo-ring`
|
|
2102
|
+
- `"error"`:
|
|
2103
|
+
- `focus`: `focus:ring-kumo-danger`
|
|
2104
|
+
|
|
2105
|
+
**Colors (kumo tokens used):**
|
|
2106
|
+
|
|
2107
|
+
`bg-kumo-control`, `ring-kumo-danger`, `ring-kumo-line`, `ring-kumo-ring`, `text-kumo-default`, `text-kumo-subtle`
|
|
2108
|
+
|
|
2109
|
+
**Styling:**
|
|
2110
|
+
|
|
2111
|
+
- **Dimensions:** `[object Object]`
|
|
2112
|
+
|
|
2113
|
+
**Examples:**
|
|
2114
|
+
|
|
2115
|
+
```tsx
|
|
2116
|
+
<Input
|
|
2117
|
+
label="Email"
|
|
2118
|
+
placeholder="you@example.com"
|
|
2119
|
+
description="We'll never share your email"
|
|
2120
|
+
/>
|
|
2121
|
+
```
|
|
2122
|
+
|
|
2123
|
+
```tsx
|
|
2124
|
+
<Input
|
|
2125
|
+
label="Email"
|
|
2126
|
+
placeholder="you@example.com"
|
|
2127
|
+
value="invalid-email"
|
|
2128
|
+
variant="error"
|
|
2129
|
+
error="Please enter a valid email address"
|
|
2130
|
+
/>
|
|
2131
|
+
```
|
|
2132
|
+
|
|
2133
|
+
```tsx
|
|
2134
|
+
<Input
|
|
2135
|
+
label="Password"
|
|
2136
|
+
type="password"
|
|
2137
|
+
value="short"
|
|
2138
|
+
variant="error"
|
|
2139
|
+
error={{
|
|
2140
|
+
message: "Password must be at least 8 characters",
|
|
2141
|
+
match: "tooShort",
|
|
2142
|
+
}}
|
|
2143
|
+
minLength={8}
|
|
2144
|
+
/>
|
|
2145
|
+
```
|
|
2146
|
+
|
|
2147
|
+
```tsx
|
|
2148
|
+
<div className="flex flex-col gap-4">
|
|
2149
|
+
<Input size="xs" label="Extra Small" placeholder="Extra small input" />
|
|
2150
|
+
<Input size="sm" label="Small" placeholder="Small input" />
|
|
2151
|
+
<Input label="Base" placeholder="Base input (default)" />
|
|
2152
|
+
<Input size="lg" label="Large" placeholder="Large input" />
|
|
2153
|
+
</div>
|
|
2154
|
+
```
|
|
2155
|
+
|
|
2156
|
+
```tsx
|
|
2157
|
+
<Input label="Disabled field" placeholder="Cannot edit" disabled />
|
|
2158
|
+
```
|
|
2159
|
+
|
|
2160
|
+
```tsx
|
|
2161
|
+
<div className="flex flex-col gap-4">
|
|
2162
|
+
<Input type="email" label="Email" placeholder="you@example.com" />
|
|
2163
|
+
<Input type="password" label="Password" placeholder="••••••••" />
|
|
2164
|
+
<Input type="number" label="Age" placeholder="18" />
|
|
2165
|
+
<Input type="tel" label="Phone" placeholder="+1 (555) 000-0000" />
|
|
2166
|
+
</div>
|
|
2167
|
+
```
|
|
2168
|
+
|
|
2169
|
+
```tsx
|
|
2170
|
+
<Input
|
|
2171
|
+
label="Phone Number"
|
|
2172
|
+
required={false}
|
|
2173
|
+
placeholder="+1 (555) 000-0000"
|
|
2174
|
+
/>
|
|
2175
|
+
```
|
|
2176
|
+
|
|
2177
|
+
```tsx
|
|
2178
|
+
<Input
|
|
2179
|
+
label="API Key"
|
|
2180
|
+
labelTooltip="Find this in your dashboard under Settings > API Keys"
|
|
2181
|
+
placeholder="sk_live_..."
|
|
2182
|
+
/>
|
|
2183
|
+
```
|
|
2184
|
+
|
|
2185
|
+
```tsx
|
|
2186
|
+
<Input
|
|
2187
|
+
label={
|
|
2188
|
+
<span>
|
|
2189
|
+
Email for <strong>billing</strong>
|
|
2190
|
+
</span>
|
|
2191
|
+
}
|
|
2192
|
+
required
|
|
2193
|
+
placeholder="billing@company.com"
|
|
2194
|
+
type="email"
|
|
2195
|
+
/>
|
|
2196
|
+
```
|
|
2197
|
+
|
|
2198
|
+
|
|
2199
|
+
---
|
|
2200
|
+
|
|
2201
|
+
### Label
|
|
2202
|
+
|
|
2203
|
+
Label component for form fields. Provides a standardized way to display labels with optional indicators: - Optional indicator: gray "(optional)" text when `showOptional={true}` - Tooltip: info icon with hover tooltip for additional context
|
|
2204
|
+
|
|
2205
|
+
**Type:** component
|
|
2206
|
+
|
|
2207
|
+
**Import:** `import { Label } from "@cloudflare/kumo";`
|
|
2208
|
+
|
|
2209
|
+
**Category:** Other
|
|
2210
|
+
|
|
2211
|
+
**Props:**
|
|
2212
|
+
|
|
2213
|
+
- `children`: ReactNode
|
|
2214
|
+
The label content - can be a string or any React node
|
|
2215
|
+
- `showOptional`: boolean
|
|
2216
|
+
When true (and required is false), shows gray "(optional)" text after the label
|
|
2217
|
+
- `tooltip`: ReactNode
|
|
2218
|
+
Tooltip content to display next to the label via an info icon
|
|
2219
|
+
- `className`: string
|
|
2220
|
+
Additional CSS classes
|
|
2221
|
+
- `asContent`: boolean
|
|
2222
|
+
When true, only renders the inline content (indicators, tooltip) without the outer span with font styling. Useful when composed inside another label element that already provides the text styling.
|
|
2223
|
+
|
|
2224
|
+
**Colors (kumo tokens used):**
|
|
2225
|
+
|
|
2226
|
+
`text-kumo-default`, `text-kumo-strong`
|
|
2227
|
+
|
|
2228
|
+
**Examples:**
|
|
2229
|
+
|
|
2230
|
+
```tsx
|
|
2231
|
+
<div className="flex flex-col gap-4">
|
|
2232
|
+
<Label>Default Label</Label>
|
|
2233
|
+
<Label showOptional>Optional Label</Label>
|
|
2234
|
+
<Label tooltip="More information about this field">
|
|
2235
|
+
Label with Tooltip
|
|
2236
|
+
</Label>
|
|
2237
|
+
</div>
|
|
2238
|
+
```
|
|
2239
|
+
|
|
2240
|
+
```tsx
|
|
2241
|
+
<Input label="Phone Number" required={false} placeholder="+1 555-0000" />
|
|
2242
|
+
```
|
|
2243
|
+
|
|
2244
|
+
```tsx
|
|
2245
|
+
<Input
|
|
2246
|
+
label="API Key"
|
|
2247
|
+
labelTooltip="Find this in your dashboard settings under API > Keys"
|
|
2248
|
+
placeholder="sk_live_..."
|
|
2249
|
+
/>
|
|
2250
|
+
```
|
|
2251
|
+
|
|
2252
|
+
```tsx
|
|
2253
|
+
<Checkbox
|
|
2254
|
+
label={
|
|
2255
|
+
<span>
|
|
2256
|
+
I agree to the <strong>Terms of Service</strong>
|
|
2257
|
+
</span>
|
|
2258
|
+
}
|
|
2259
|
+
/>
|
|
2260
|
+
```
|
|
2261
|
+
|
|
2262
|
+
```tsx
|
|
2263
|
+
<div className="flex max-w-md flex-col gap-4">
|
|
2264
|
+
<Input label="Full Name" placeholder="John Doe" />
|
|
2265
|
+
<Input
|
|
2266
|
+
label="Email"
|
|
2267
|
+
labelTooltip="We'll send your receipt here"
|
|
2268
|
+
placeholder="john@example.com"
|
|
2269
|
+
type="email"
|
|
2270
|
+
/>
|
|
2271
|
+
<Input label="Company" required={false} placeholder="Acme Inc." />
|
|
2272
|
+
<Select label="Country" hideLabel={false} placeholder="Select a country">
|
|
2273
|
+
<Select.Option value="us">United States</Select.Option>
|
|
2274
|
+
<Select.Option value="uk">United Kingdom</Select.Option>
|
|
2275
|
+
<Select.Option value="ca">Canada</Select.Option>
|
|
2276
|
+
</Select>
|
|
2277
|
+
</div>
|
|
2278
|
+
```
|
|
2279
|
+
|
|
2280
|
+
|
|
2281
|
+
---
|
|
2282
|
+
|
|
2283
|
+
### LayerCard
|
|
2284
|
+
|
|
2285
|
+
LayerCard component
|
|
2286
|
+
|
|
2287
|
+
**Type:** component
|
|
2288
|
+
|
|
2289
|
+
**Import:** `import { LayerCard } from "@cloudflare/kumo";`
|
|
2290
|
+
|
|
2291
|
+
**Category:** Display
|
|
2292
|
+
|
|
2293
|
+
**Props:**
|
|
2294
|
+
|
|
2295
|
+
- `children`: ReactNode
|
|
2296
|
+
- `className`: string
|
|
2297
|
+
|
|
2298
|
+
**Colors (kumo tokens used):**
|
|
2299
|
+
|
|
2300
|
+
`bg-kumo-base`, `bg-kumo-elevated`, `ring-kumo-fill`, `ring-kumo-line`, `text-kumo-strong`
|
|
2301
|
+
|
|
2302
|
+
**Styling:**
|
|
2303
|
+
|
|
2304
|
+
|
|
2305
|
+
**Sub-Components:**
|
|
2306
|
+
|
|
2307
|
+
This is a compound component. Use these sub-components:
|
|
2308
|
+
|
|
2309
|
+
#### LayerCard.Primary
|
|
2310
|
+
|
|
2311
|
+
Primary sub-component
|
|
2312
|
+
|
|
2313
|
+
#### LayerCard.Secondary
|
|
2314
|
+
|
|
2315
|
+
Secondary sub-component
|
|
2316
|
+
|
|
2317
|
+
|
|
2318
|
+
**Examples:**
|
|
2319
|
+
|
|
2320
|
+
```tsx
|
|
2321
|
+
<LayerCard>
|
|
2322
|
+
<LayerCard.Secondary className="flex items-center justify-between">
|
|
2323
|
+
<div>Next Steps</div>
|
|
2324
|
+
<Button variant="ghost" size="sm" shape="square">
|
|
2325
|
+
<ArrowRightIcon size={16} />
|
|
2326
|
+
</Button>
|
|
2327
|
+
</LayerCard.Secondary>
|
|
2328
|
+
|
|
2329
|
+
<LayerCard.Primary>Get started with Kumo</LayerCard.Primary>
|
|
2330
|
+
</LayerCard>
|
|
2331
|
+
```
|
|
2332
|
+
|
|
2333
|
+
```tsx
|
|
2334
|
+
<LayerCard className="w-[250px]">
|
|
2335
|
+
<LayerCard.Secondary>Getting Started</LayerCard.Secondary>
|
|
2336
|
+
<LayerCard.Primary>
|
|
2337
|
+
<p className="text-sm text-kumo-subtle">
|
|
2338
|
+
Quick start guide for new users
|
|
2339
|
+
</p>
|
|
2340
|
+
</LayerCard.Primary>
|
|
2341
|
+
</LayerCard>
|
|
2342
|
+
```
|
|
2343
|
+
|
|
2344
|
+
```tsx
|
|
2345
|
+
<div className="flex gap-4">
|
|
2346
|
+
<LayerCard className="w-[200px]">
|
|
2347
|
+
<LayerCard.Secondary>Components</LayerCard.Secondary>
|
|
2348
|
+
<LayerCard.Primary>
|
|
2349
|
+
<p className="text-sm">Browse all components</p>
|
|
2350
|
+
</LayerCard.Primary>
|
|
2351
|
+
</LayerCard>
|
|
2352
|
+
<LayerCard className="w-[200px]">
|
|
2353
|
+
<LayerCard.Secondary>Examples</LayerCard.Secondary>
|
|
2354
|
+
<LayerCard.Primary>
|
|
2355
|
+
<p className="text-sm">View code examples</p>
|
|
2356
|
+
</LayerCard.Primary>
|
|
2357
|
+
</LayerCard>
|
|
2358
|
+
</div>
|
|
2359
|
+
```
|
|
2360
|
+
|
|
2361
|
+
|
|
2362
|
+
---
|
|
2363
|
+
|
|
2364
|
+
### Link
|
|
2365
|
+
|
|
2366
|
+
Link component
|
|
2367
|
+
|
|
2368
|
+
**Type:** component
|
|
2369
|
+
|
|
2370
|
+
**Import:** `import { Link } from "@cloudflare/kumo";`
|
|
2371
|
+
|
|
2372
|
+
**Category:** Other
|
|
2373
|
+
|
|
2374
|
+
**Props:**
|
|
2375
|
+
|
|
2376
|
+
- `variant`: enum [default: inline]
|
|
2377
|
+
- `"inline"`: Inline text link that flows with content
|
|
2378
|
+
- `"current"`: Link that inherits color from parent text
|
|
2379
|
+
- `"plain"`: Link without underline decoration
|
|
2380
|
+
|
|
2381
|
+
**State Classes:**
|
|
2382
|
+
- `"plain"`:
|
|
2383
|
+
- `hover`: `hover:text-primary/70`
|
|
2384
|
+
- `to`: string
|
|
2385
|
+
- `children`: ReactNode
|
|
2386
|
+
- `className`: string
|
|
2387
|
+
- `id`: string
|
|
2388
|
+
- `lang`: string
|
|
2389
|
+
- `title`: string
|
|
2390
|
+
- `download`: unknown
|
|
2391
|
+
- `href`: string
|
|
2392
|
+
- `hrefLang`: string
|
|
2393
|
+
- `media`: string
|
|
2394
|
+
- `ping`: string
|
|
2395
|
+
- `target`: React.HTMLAttributeAnchorTarget
|
|
2396
|
+
- `type`: string
|
|
2397
|
+
- `referrerPolicy`: enum
|
|
2398
|
+
- `render`: ReactNode
|
|
2399
|
+
Allows you to replace the component’s HTML element with a different tag, or compose it with another component.
|
|
2400
|
+
|
|
2401
|
+
Accepts a `ReactElement` or a function that returns the element to render.
|
|
2402
|
+
|
|
2403
|
+
**Sub-Components:**
|
|
2404
|
+
|
|
2405
|
+
This is a compound component. Use these sub-components:
|
|
2406
|
+
|
|
2407
|
+
#### Link.ExternalIcon
|
|
2408
|
+
|
|
2409
|
+
ExternalIcon sub-component
|
|
2410
|
+
|
|
2411
|
+
|
|
2412
|
+
**Examples:**
|
|
2413
|
+
|
|
2414
|
+
```tsx
|
|
2415
|
+
<div className="grid gap-x-6 gap-y-4 text-base md:grid-cols-3">
|
|
2416
|
+
<Link href="#">Default inline link</Link>
|
|
2417
|
+
<Link href="#" variant="current">
|
|
2418
|
+
Current color link
|
|
2419
|
+
</Link>
|
|
2420
|
+
<Link href="#" variant="plain">
|
|
2421
|
+
Plain inline link
|
|
2422
|
+
</Link>
|
|
2423
|
+
</div>
|
|
2424
|
+
```
|
|
2425
|
+
|
|
2426
|
+
```tsx
|
|
2427
|
+
<p className="mx-auto max-w-md text-base leading-relaxed text-kumo-default">
|
|
2428
|
+
This is a paragraph with an <Link href="#">inline link</Link> that flows
|
|
2429
|
+
naturally with the surrounding text. Links maintain proper underline
|
|
2430
|
+
offset for readability.
|
|
2431
|
+
</p>
|
|
2432
|
+
```
|
|
2433
|
+
|
|
2434
|
+
```tsx
|
|
2435
|
+
<Link
|
|
2436
|
+
href="https://cloudflare.com"
|
|
2437
|
+
target="_blank"
|
|
2438
|
+
rel="noopener noreferrer"
|
|
2439
|
+
className="text-base"
|
|
2440
|
+
>
|
|
2441
|
+
Visit Cloudflare <Link.ExternalIcon />
|
|
2442
|
+
</Link>
|
|
2443
|
+
```
|
|
2444
|
+
|
|
2445
|
+
```tsx
|
|
2446
|
+
<p className="text-base text-kumo-danger">
|
|
2447
|
+
This error message contains a{" "}
|
|
2448
|
+
<Link href="#" variant="current">
|
|
2449
|
+
link
|
|
2450
|
+
</Link>{" "}
|
|
2451
|
+
that inherits the red color from its parent.
|
|
2452
|
+
</p>
|
|
2453
|
+
```
|
|
2454
|
+
|
|
2455
|
+
```tsx
|
|
2456
|
+
<div className="flex flex-col gap-x-6 gap-y-4 text-base md:flex-row">
|
|
2457
|
+
<Link render={<CustomRouterLink href="/dashboard" />} variant="inline">
|
|
2458
|
+
Dashboard (via render)
|
|
2459
|
+
</Link>
|
|
2460
|
+
<Link
|
|
2461
|
+
render={
|
|
2462
|
+
<CustomRouterLink
|
|
2463
|
+
href="https://developers.cloudflare.com"
|
|
2464
|
+
target="_blank"
|
|
2465
|
+
rel="noopener noreferrer"
|
|
2466
|
+
/>
|
|
2467
|
+
}
|
|
2468
|
+
variant="inline"
|
|
2469
|
+
>
|
|
2470
|
+
Cloudflare Docs <Link.ExternalIcon />
|
|
2471
|
+
</Link>
|
|
2472
|
+
</div>
|
|
2473
|
+
```
|
|
2474
|
+
|
|
2475
|
+
|
|
2476
|
+
---
|
|
2477
|
+
|
|
2478
|
+
### Loader
|
|
2479
|
+
|
|
2480
|
+
Loader component
|
|
2481
|
+
|
|
2482
|
+
**Type:** component
|
|
2483
|
+
|
|
2484
|
+
**Import:** `import { Loader } from "@cloudflare/kumo";`
|
|
2485
|
+
|
|
2486
|
+
**Category:** Feedback
|
|
2487
|
+
|
|
2488
|
+
**Props:**
|
|
2489
|
+
|
|
2490
|
+
- `className`: string
|
|
2491
|
+
- `size`: enum [default: base]
|
|
2492
|
+
- `"sm"`: Small loader for inline use
|
|
2493
|
+
- `"base"`: Default loader size
|
|
2494
|
+
- `"lg"`: Large loader for prominent loading states
|
|
2495
|
+
|
|
2496
|
+
**Examples:**
|
|
2497
|
+
|
|
2498
|
+
```tsx
|
|
2499
|
+
<div className="flex items-center gap-4">
|
|
2500
|
+
<Loader size="sm" />
|
|
2501
|
+
<Loader size="base" />
|
|
2502
|
+
<Loader size="lg" />
|
|
2503
|
+
</div>
|
|
2504
|
+
```
|
|
2505
|
+
|
|
2506
|
+
```tsx
|
|
2507
|
+
<Loader size={24} />
|
|
2508
|
+
```
|
|
2509
|
+
|
|
2510
|
+
|
|
2511
|
+
---
|
|
2512
|
+
|
|
2513
|
+
### MenuBar
|
|
2514
|
+
|
|
2515
|
+
MenuBar component
|
|
2516
|
+
|
|
2517
|
+
**Type:** component
|
|
2518
|
+
|
|
2519
|
+
**Import:** `import { MenuBar } from "@cloudflare/kumo";`
|
|
2520
|
+
|
|
2521
|
+
**Category:** Navigation
|
|
2522
|
+
|
|
2523
|
+
**Props:**
|
|
2524
|
+
|
|
2525
|
+
- `className`: string
|
|
2526
|
+
- `isActive`: number | boolean | string
|
|
2527
|
+
- `options`: MenuOptionProps[] (required)
|
|
2528
|
+
- `optionIds`: boolean
|
|
2529
|
+
|
|
2530
|
+
**Colors (kumo tokens used):**
|
|
2531
|
+
|
|
2532
|
+
`bg-kumo-base`, `bg-kumo-fill`, `border-kumo-fill`
|
|
2533
|
+
|
|
2534
|
+
**Styling:**
|
|
2535
|
+
|
|
2536
|
+
|
|
2537
|
+
**Examples:**
|
|
2538
|
+
|
|
2539
|
+
```tsx
|
|
2540
|
+
<MenuBar
|
|
2541
|
+
isActive="bold"
|
|
2542
|
+
optionIds
|
|
2543
|
+
options={[
|
|
2544
|
+
{
|
|
2545
|
+
icon: <TextBolderIcon />,
|
|
2546
|
+
id: "bold",
|
|
2547
|
+
tooltip: "Bold",
|
|
2548
|
+
onClick: () => {},
|
|
2549
|
+
},
|
|
2550
|
+
{
|
|
2551
|
+
icon: <TextItalicIcon />,
|
|
2552
|
+
id: "italic",
|
|
2553
|
+
tooltip: "Italic",
|
|
2554
|
+
onClick: () => {},
|
|
2555
|
+
},
|
|
2556
|
+
]}
|
|
2557
|
+
/>
|
|
2558
|
+
```
|
|
2559
|
+
|
|
2560
|
+
|
|
2561
|
+
---
|
|
2562
|
+
|
|
2563
|
+
### Meter
|
|
2564
|
+
|
|
2565
|
+
Meter component
|
|
2566
|
+
|
|
2567
|
+
**Type:** component
|
|
2568
|
+
|
|
2569
|
+
**Import:** `import { Meter } from "@cloudflare/kumo";`
|
|
2570
|
+
|
|
2571
|
+
**Category:** Display
|
|
2572
|
+
|
|
2573
|
+
**Props:**
|
|
2574
|
+
|
|
2575
|
+
- `customValue`: string
|
|
2576
|
+
- `label`: string (required)
|
|
2577
|
+
- `showValue`: boolean
|
|
2578
|
+
- `trackClassName`: string
|
|
2579
|
+
- `indicatorClassName`: string
|
|
2580
|
+
- `value`: number
|
|
2581
|
+
Current value of the meter
|
|
2582
|
+
- `max`: number
|
|
2583
|
+
Maximum value of the meter (default: 100)
|
|
2584
|
+
- `min`: number
|
|
2585
|
+
Minimum value of the meter (default: 0)
|
|
2586
|
+
|
|
2587
|
+
**Colors (kumo tokens used):**
|
|
2588
|
+
|
|
2589
|
+
`bg-kumo-fill`, `text-kumo-default`, `text-kumo-strong`
|
|
2590
|
+
|
|
2591
|
+
**Examples:**
|
|
2592
|
+
|
|
2593
|
+
```tsx
|
|
2594
|
+
<Meter label="Storage used" value={65} />
|
|
2595
|
+
```
|
|
2596
|
+
|
|
2597
|
+
```tsx
|
|
2598
|
+
<Meter label="API requests" value={75} customValue="750 / 1,000" />
|
|
2599
|
+
```
|
|
2600
|
+
|
|
2601
|
+
```tsx
|
|
2602
|
+
<Meter label="Progress" value={40} showValue={false} />
|
|
2603
|
+
```
|
|
2604
|
+
|
|
2605
|
+
```tsx
|
|
2606
|
+
<Meter
|
|
2607
|
+
label="Upload progress"
|
|
2608
|
+
value={80}
|
|
2609
|
+
indicatorClassName="from-green-500 via-green-500 to-green-500"
|
|
2610
|
+
/>
|
|
2611
|
+
```
|
|
2612
|
+
|
|
2613
|
+
|
|
2614
|
+
---
|
|
2615
|
+
|
|
2616
|
+
### Pagination
|
|
2617
|
+
|
|
2618
|
+
Pagination component
|
|
2619
|
+
|
|
2620
|
+
**Type:** component
|
|
2621
|
+
|
|
2622
|
+
**Import:** `import { Pagination } from "@cloudflare/kumo";`
|
|
2623
|
+
|
|
2624
|
+
**Category:** Navigation
|
|
2625
|
+
|
|
2626
|
+
**Props:**
|
|
2627
|
+
|
|
2628
|
+
- `controls`: enum [default: full]
|
|
2629
|
+
- `"full"`: Full pagination controls with first, previous, page input, next, and last buttons
|
|
2630
|
+
- `"simple"`: Simple pagination controls with only previous and next buttons
|
|
2631
|
+
- `setPage`: (page: number) => void (required)
|
|
2632
|
+
Callback when page changes
|
|
2633
|
+
- `page`: number
|
|
2634
|
+
- `perPage`: number
|
|
2635
|
+
- `totalCount`: number
|
|
2636
|
+
|
|
2637
|
+
**Colors (kumo tokens used):**
|
|
2638
|
+
|
|
2639
|
+
`text-kumo-strong`
|
|
2640
|
+
|
|
2641
|
+
**Styling:**
|
|
2642
|
+
|
|
2643
|
+
|
|
2644
|
+
**Examples:**
|
|
2645
|
+
|
|
2646
|
+
```tsx
|
|
2647
|
+
<Pagination page={page} setPage={setPage} perPage={10} totalCount={100} />
|
|
2648
|
+
```
|
|
2649
|
+
|
|
2650
|
+
```tsx
|
|
2651
|
+
<Pagination
|
|
2652
|
+
page={page}
|
|
2653
|
+
setPage={setPage}
|
|
2654
|
+
perPage={10}
|
|
2655
|
+
totalCount={100}
|
|
2656
|
+
controls="simple"
|
|
2657
|
+
/>
|
|
2658
|
+
```
|
|
2659
|
+
|
|
2660
|
+
|
|
2661
|
+
---
|
|
2662
|
+
|
|
2663
|
+
### Popover
|
|
2664
|
+
|
|
2665
|
+
Popover component for displaying accessible popup content anchored to a trigger.
|
|
2666
|
+
|
|
2667
|
+
**Type:** component
|
|
2668
|
+
|
|
2669
|
+
**Import:** `import { Popover } from "@cloudflare/kumo";`
|
|
2670
|
+
|
|
2671
|
+
**Category:** Overlay
|
|
2672
|
+
|
|
2673
|
+
**Props:**
|
|
2674
|
+
|
|
2675
|
+
- `side`: enum [default: bottom]
|
|
2676
|
+
- `"top"`: Popover appears above the trigger
|
|
2677
|
+
- `"bottom"`: Popover appears below the trigger
|
|
2678
|
+
- `"left"`: Popover appears to the left of the trigger
|
|
2679
|
+
- `"right"`: Popover appears to the right of the trigger
|
|
2680
|
+
|
|
2681
|
+
**Colors (kumo tokens used):**
|
|
2682
|
+
|
|
2683
|
+
`bg-kumo-base`, `fill-kumo-base`, `fill-kumo-tip-shadow`, `fill-kumo-tip-stroke`, `outline-kumo-fill`, `text-kumo-default`, `text-kumo-subtle`
|
|
2684
|
+
|
|
2685
|
+
**Sub-Components:**
|
|
2686
|
+
|
|
2687
|
+
This is a compound component. Use these sub-components:
|
|
2688
|
+
|
|
2689
|
+
#### Popover.Trigger
|
|
2690
|
+
|
|
2691
|
+
Trigger sub-component
|
|
2692
|
+
|
|
2693
|
+
#### Popover.Content
|
|
2694
|
+
|
|
2695
|
+
Content sub-component
|
|
2696
|
+
|
|
2697
|
+
#### Popover.Title
|
|
2698
|
+
|
|
2699
|
+
Title sub-component
|
|
2700
|
+
|
|
2701
|
+
#### Popover.Description
|
|
2702
|
+
|
|
2703
|
+
Description sub-component
|
|
2704
|
+
|
|
2705
|
+
#### Popover.Close
|
|
2706
|
+
|
|
2707
|
+
Close sub-component
|
|
2708
|
+
|
|
2709
|
+
|
|
2710
|
+
**Examples:**
|
|
2711
|
+
|
|
2712
|
+
```tsx
|
|
2713
|
+
<Popover>
|
|
2714
|
+
<Popover.Trigger asChild>
|
|
2715
|
+
<Button shape="square" icon={BellIcon} />
|
|
2716
|
+
</Popover.Trigger>
|
|
2717
|
+
<Popover.Content>
|
|
2718
|
+
<Popover.Title>Notifications</Popover.Title>
|
|
2719
|
+
<Popover.Description>
|
|
2720
|
+
You are all caught up. Good job!
|
|
2721
|
+
</Popover.Description>
|
|
2722
|
+
</Popover.Content>
|
|
2723
|
+
</Popover>
|
|
2724
|
+
```
|
|
2725
|
+
|
|
2726
|
+
```tsx
|
|
2727
|
+
<Popover>
|
|
2728
|
+
<Popover.Trigger asChild>
|
|
2729
|
+
<Button>Open Popover</Button>
|
|
2730
|
+
</Popover.Trigger>
|
|
2731
|
+
<Popover.Content>
|
|
2732
|
+
<Popover.Title>Popover Title</Popover.Title>
|
|
2733
|
+
<Popover.Description>
|
|
2734
|
+
This is a basic popover with a title and description.
|
|
2735
|
+
</Popover.Description>
|
|
2736
|
+
</Popover.Content>
|
|
2737
|
+
</Popover>
|
|
2738
|
+
```
|
|
2739
|
+
|
|
2740
|
+
```tsx
|
|
2741
|
+
<Popover>
|
|
2742
|
+
<Popover.Trigger asChild>
|
|
2743
|
+
<Button>Open Settings</Button>
|
|
2744
|
+
</Popover.Trigger>
|
|
2745
|
+
<Popover.Content>
|
|
2746
|
+
<Popover.Title>Settings</Popover.Title>
|
|
2747
|
+
<Popover.Description>
|
|
2748
|
+
Configure your preferences below.
|
|
2749
|
+
</Popover.Description>
|
|
2750
|
+
<div className="mt-3">
|
|
2751
|
+
<Popover.Close asChild>
|
|
2752
|
+
<Button variant="secondary" size="sm">
|
|
2753
|
+
Close
|
|
2754
|
+
</Button>
|
|
2755
|
+
</Popover.Close>
|
|
2756
|
+
</div>
|
|
2757
|
+
</Popover.Content>
|
|
2758
|
+
</Popover>
|
|
2759
|
+
```
|
|
2760
|
+
|
|
2761
|
+
```tsx
|
|
2762
|
+
<div className="flex flex-wrap gap-4">
|
|
2763
|
+
<Popover>
|
|
2764
|
+
<Popover.Trigger asChild>
|
|
2765
|
+
<Button variant="secondary">Bottom</Button>
|
|
2766
|
+
</Popover.Trigger>
|
|
2767
|
+
<Popover.Content side="bottom">
|
|
2768
|
+
<Popover.Title>Bottom</Popover.Title>
|
|
2769
|
+
<Popover.Description>
|
|
2770
|
+
Popover on bottom (default).
|
|
2771
|
+
</Popover.Description>
|
|
2772
|
+
</Popover.Content>
|
|
2773
|
+
</Popover>
|
|
2774
|
+
|
|
2775
|
+
<Popover>
|
|
2776
|
+
<Popover.Trigger asChild>
|
|
2777
|
+
<Button variant="secondary">Top</Button>
|
|
2778
|
+
</Popover.Trigger>
|
|
2779
|
+
<Popover.Content side="top">
|
|
2780
|
+
<Popover.Title>Top</Popover.Title>
|
|
2781
|
+
<Popover.Description>Popover on top.</Popover.Description>
|
|
2782
|
+
</Popover.Content>
|
|
2783
|
+
</Popover>
|
|
2784
|
+
|
|
2785
|
+
<Popover>
|
|
2786
|
+
<Popover.Trigger asChild>
|
|
2787
|
+
<Button variant="secondary">Left</Button>
|
|
2788
|
+
</Popover.Trigger>
|
|
2789
|
+
<Popover.Content side="left">
|
|
2790
|
+
<Popover.Title>Left</Popover.Title>
|
|
2791
|
+
<Popover.Description>Popover on left.</Popover.Description>
|
|
2792
|
+
</Popover.Content>
|
|
2793
|
+
</Popover>
|
|
2794
|
+
|
|
2795
|
+
<Popover>
|
|
2796
|
+
<Popover.Trigger asChild>
|
|
2797
|
+
<Button variant="secondary">Right</Button>
|
|
2798
|
+
</Popover.Trigger>
|
|
2799
|
+
<Popover.Content side="right">
|
|
2800
|
+
<Popover.Title>Right</Popover.Title>
|
|
2801
|
+
<Popover.Description>Popover on right.</Popover.Description>
|
|
2802
|
+
</Popover.Content>
|
|
2803
|
+
</Popover>
|
|
2804
|
+
</div>
|
|
2805
|
+
```
|
|
2806
|
+
|
|
2807
|
+
```tsx
|
|
2808
|
+
<Popover>
|
|
2809
|
+
<Popover.Trigger asChild>
|
|
2810
|
+
<Button>User Profile</Button>
|
|
2811
|
+
</Popover.Trigger>
|
|
2812
|
+
<Popover.Content className="w-64">
|
|
2813
|
+
<div className="flex items-center gap-3">
|
|
2814
|
+
<div className="size-10 rounded-full bg-kumo-recessed" />
|
|
2815
|
+
<div>
|
|
2816
|
+
<Popover.Title>Jane Doe</Popover.Title>
|
|
2817
|
+
<p className="text-sm text-kumo-subtle">jane@example.com</p>
|
|
2818
|
+
</div>
|
|
2819
|
+
</div>
|
|
2820
|
+
<div className="mt-3 flex gap-2 border-t border-kumo-line pt-3">
|
|
2821
|
+
<Button variant="secondary" size="sm" className="flex-1">
|
|
2822
|
+
Profile
|
|
2823
|
+
</Button>
|
|
2824
|
+
<Popover.Close asChild>
|
|
2825
|
+
<Button variant="ghost" size="sm" className="flex-1">
|
|
2826
|
+
Sign Out
|
|
2827
|
+
</Button>
|
|
2828
|
+
</Popover.Close>
|
|
2829
|
+
</div>
|
|
2830
|
+
</Popover.Content>
|
|
2831
|
+
</Popover>
|
|
2832
|
+
```
|
|
2833
|
+
|
|
2834
|
+
```tsx
|
|
2835
|
+
<Popover>
|
|
2836
|
+
<Popover.Trigger openOnHover delay={200} asChild>
|
|
2837
|
+
<Button variant="secondary">Hover Me</Button>
|
|
2838
|
+
</Popover.Trigger>
|
|
2839
|
+
<Popover.Content>
|
|
2840
|
+
<Popover.Title>Hover Triggered</Popover.Title>
|
|
2841
|
+
<Popover.Description>
|
|
2842
|
+
This popover opens on hover with a 200ms delay. It can still contain
|
|
2843
|
+
interactive content like buttons and links.
|
|
2844
|
+
</Popover.Description>
|
|
2845
|
+
<div className="mt-3">
|
|
2846
|
+
<Popover.Close asChild>
|
|
2847
|
+
<Button variant="secondary" size="sm">
|
|
2848
|
+
Got it
|
|
2849
|
+
</Button>
|
|
2850
|
+
</Popover.Close>
|
|
2851
|
+
</div>
|
|
2852
|
+
</Popover.Content>
|
|
2853
|
+
</Popover>
|
|
2854
|
+
```
|
|
2855
|
+
|
|
2856
|
+
|
|
2857
|
+
---
|
|
2858
|
+
|
|
2859
|
+
### Radio
|
|
2860
|
+
|
|
2861
|
+
Radio component
|
|
2862
|
+
|
|
2863
|
+
**Type:** component
|
|
2864
|
+
|
|
2865
|
+
**Import:** `import { Radio } from "@cloudflare/kumo";`
|
|
2866
|
+
|
|
2867
|
+
**Category:** Input
|
|
2868
|
+
|
|
2869
|
+
**Props:**
|
|
2870
|
+
|
|
2871
|
+
- `legend`: string (required)
|
|
2872
|
+
Legend text for the group (required for accessibility)
|
|
2873
|
+
- `children`: ReactNode
|
|
2874
|
+
Child Radio.Item components
|
|
2875
|
+
- `orientation`: enum
|
|
2876
|
+
Layout direction of the radio items
|
|
2877
|
+
- `error`: string
|
|
2878
|
+
Error message for the group
|
|
2879
|
+
- `description`: ReactNode
|
|
2880
|
+
Helper text for the group
|
|
2881
|
+
- `value`: string
|
|
2882
|
+
Value of the radio that should be selected (controlled)
|
|
2883
|
+
- `disabled`: boolean
|
|
2884
|
+
Whether all radios in the group are disabled
|
|
2885
|
+
- `controlPosition`: enum
|
|
2886
|
+
Position of radio control relative to label: "start" (default) puts radio before label, "end" puts label before radio
|
|
2887
|
+
- `name`: string
|
|
2888
|
+
Form submission name for the radio group
|
|
2889
|
+
- `className`: string
|
|
2890
|
+
Additional CSS classes
|
|
2891
|
+
|
|
2892
|
+
**Colors (kumo tokens used):**
|
|
2893
|
+
|
|
2894
|
+
`bg-kumo-base`, `bg-kumo-contrast`, `border-kumo-line`, `ring-kumo-danger`, `ring-kumo-line`, `ring-kumo-ring`, `text-kumo-danger`, `text-kumo-default`, `text-kumo-subtle`
|
|
2895
|
+
|
|
2896
|
+
**Examples:**
|
|
2897
|
+
|
|
2898
|
+
```tsx
|
|
2899
|
+
<Radio.Group
|
|
2900
|
+
legend="Notification preference"
|
|
2901
|
+
value={value}
|
|
2902
|
+
onValueChange={setValue}
|
|
2903
|
+
>
|
|
2904
|
+
<Radio.Item label="Email" value="email" />
|
|
2905
|
+
<Radio.Item label="SMS" value="sms" />
|
|
2906
|
+
<Radio.Item label="Push notification" value="push" />
|
|
2907
|
+
</Radio.Group>
|
|
2908
|
+
```
|
|
2909
|
+
|
|
2910
|
+
```tsx
|
|
2911
|
+
<Radio.Group
|
|
2912
|
+
legend="Size"
|
|
2913
|
+
orientation="horizontal"
|
|
2914
|
+
value={value}
|
|
2915
|
+
onValueChange={setValue}
|
|
2916
|
+
>
|
|
2917
|
+
<Radio.Item label="Small" value="sm" />
|
|
2918
|
+
<Radio.Item label="Medium" value="md" />
|
|
2919
|
+
<Radio.Item label="Large" value="lg" />
|
|
2920
|
+
</Radio.Group>
|
|
2921
|
+
```
|
|
2922
|
+
|
|
2923
|
+
```tsx
|
|
2924
|
+
<Radio.Group
|
|
2925
|
+
legend="Shipping method"
|
|
2926
|
+
description="Choose how you'd like to receive your order"
|
|
2927
|
+
value={value}
|
|
2928
|
+
onValueChange={setValue}
|
|
2929
|
+
>
|
|
2930
|
+
<Radio.Item label="Standard (5-7 days)" value="standard" />
|
|
2931
|
+
<Radio.Item label="Express (2-3 days)" value="express" />
|
|
2932
|
+
<Radio.Item label="Overnight" value="overnight" />
|
|
2933
|
+
</Radio.Group>
|
|
2934
|
+
```
|
|
2935
|
+
|
|
2936
|
+
```tsx
|
|
2937
|
+
<Radio.Group
|
|
2938
|
+
legend="Payment method"
|
|
2939
|
+
error="Please select a payment method to continue"
|
|
2940
|
+
>
|
|
2941
|
+
<Radio.Item label="Credit Card" value="card" variant="error" />
|
|
2942
|
+
<Radio.Item label="PayPal" value="paypal" variant="error" />
|
|
2943
|
+
<Radio.Item label="Bank Transfer" value="bank" variant="error" />
|
|
2944
|
+
</Radio.Group>
|
|
2945
|
+
```
|
|
2946
|
+
|
|
2947
|
+
```tsx
|
|
2948
|
+
<div className="flex flex-col gap-6">
|
|
2949
|
+
<Radio.Group legend="Disabled group" disabled defaultValue="a">
|
|
2950
|
+
<Radio.Item label="Option A" value="a" />
|
|
2951
|
+
<Radio.Item label="Option B" value="b" />
|
|
2952
|
+
</Radio.Group>
|
|
2953
|
+
<Radio.Group legend="Individual disabled" defaultValue="available">
|
|
2954
|
+
<Radio.Item label="Available" value="available" />
|
|
2955
|
+
<Radio.Item label="Unavailable" value="unavailable" disabled />
|
|
2956
|
+
</Radio.Group>
|
|
2957
|
+
</div>
|
|
2958
|
+
```
|
|
2959
|
+
|
|
2960
|
+
```tsx
|
|
2961
|
+
<Radio.Group legend="Preferences" controlPosition="end" defaultValue="a">
|
|
2962
|
+
<Radio.Item label="Label before radio" value="a" />
|
|
2963
|
+
<Radio.Item label="Another option" value="b" />
|
|
2964
|
+
</Radio.Group>
|
|
2965
|
+
```
|
|
2966
|
+
|
|
2967
|
+
|
|
2968
|
+
---
|
|
2969
|
+
|
|
2970
|
+
### Select
|
|
2971
|
+
|
|
2972
|
+
Select component
|
|
2973
|
+
|
|
2974
|
+
**Type:** component
|
|
2975
|
+
|
|
2976
|
+
**Import:** `import { Select } from "@cloudflare/kumo";`
|
|
2977
|
+
|
|
2978
|
+
**Category:** Input
|
|
2979
|
+
|
|
2980
|
+
**Props:**
|
|
2981
|
+
|
|
2982
|
+
- `className`: string
|
|
2983
|
+
Additional CSS classes
|
|
2984
|
+
- `label`: ReactNode
|
|
2985
|
+
Label content for the select (enables Field wrapper) - can be a string or any React node
|
|
2986
|
+
- `hideLabel`: boolean
|
|
2987
|
+
Whether to visually hide the label (still accessible to screen readers)
|
|
2988
|
+
- `placeholder`: string
|
|
2989
|
+
Placeholder text when no value is selected
|
|
2990
|
+
- `loading`: boolean
|
|
2991
|
+
Whether the select is in a loading state
|
|
2992
|
+
- `disabled`: boolean
|
|
2993
|
+
Whether the select is disabled
|
|
2994
|
+
- `required`: boolean
|
|
2995
|
+
Whether the select is required
|
|
2996
|
+
- `labelTooltip`: ReactNode
|
|
2997
|
+
Tooltip content to display next to the label via an info icon
|
|
2998
|
+
- `value`: string
|
|
2999
|
+
The currently selected value
|
|
3000
|
+
- `children`: ReactNode
|
|
3001
|
+
Child elements (Select.Option components)
|
|
3002
|
+
- `description`: ReactNode
|
|
3003
|
+
Helper text displayed below the select
|
|
3004
|
+
- `error`: string | object
|
|
3005
|
+
Error message or validation error object
|
|
3006
|
+
- `onValueChange`: (value: string) => void
|
|
3007
|
+
Callback when selection changes
|
|
3008
|
+
- `defaultValue`: string
|
|
3009
|
+
Initial value for uncontrolled mode
|
|
3010
|
+
|
|
3011
|
+
**Colors (kumo tokens used):**
|
|
3012
|
+
|
|
3013
|
+
`bg-kumo-control`, `bg-kumo-overlay`, `ring-kumo-line`, `ring-kumo-ring`, `text-kumo-default`
|
|
3014
|
+
|
|
3015
|
+
**Styling:**
|
|
3016
|
+
|
|
3017
|
+
|
|
3018
|
+
**Sub-Components:**
|
|
3019
|
+
|
|
3020
|
+
This is a compound component. Use these sub-components:
|
|
3021
|
+
|
|
3022
|
+
#### Select.Option
|
|
3023
|
+
|
|
3024
|
+
Option sub-component
|
|
3025
|
+
|
|
3026
|
+
|
|
3027
|
+
**Examples:**
|
|
3028
|
+
|
|
3029
|
+
```tsx
|
|
3030
|
+
<Select
|
|
3031
|
+
className="w-[200px]"
|
|
3032
|
+
value={value}
|
|
3033
|
+
onValueChange={(v) => setValue(v ?? "Apple")}
|
|
3034
|
+
placeholder="Please select"
|
|
3035
|
+
>
|
|
3036
|
+
<Select.Option value="Apple">Apple</Select.Option>
|
|
3037
|
+
<Select.Option value="Banana">Banana</Select.Option>
|
|
3038
|
+
<Select.Option value="Cherry">Cherry</Select.Option>
|
|
3039
|
+
</Select>
|
|
3040
|
+
```
|
|
3041
|
+
|
|
3042
|
+
```tsx
|
|
3043
|
+
<Select
|
|
3044
|
+
className="w-[200px]"
|
|
3045
|
+
value={value}
|
|
3046
|
+
onValueChange={(v) => setValue(v as string)}
|
|
3047
|
+
items={{
|
|
3048
|
+
bug: "Bug",
|
|
3049
|
+
documentation: "Documentation",
|
|
3050
|
+
feature: "Feature",
|
|
3051
|
+
}}
|
|
3052
|
+
>
|
|
3053
|
+
<Select.Option value="bug">Bug</Select.Option>
|
|
3054
|
+
<Select.Option value="documentation">Documentation</Select.Option>
|
|
3055
|
+
<Select.Option value="feature">Feature</Select.Option>
|
|
3056
|
+
</Select>
|
|
3057
|
+
```
|
|
3058
|
+
|
|
3059
|
+
```tsx
|
|
3060
|
+
<Select
|
|
3061
|
+
className="w-[200px]"
|
|
3062
|
+
renderValue={(v) => (
|
|
3063
|
+
<span>
|
|
3064
|
+
{v.emoji} {v.label}
|
|
3065
|
+
</span>
|
|
3066
|
+
)}
|
|
3067
|
+
value={value}
|
|
3068
|
+
onValueChange={(v) => setValue(v as (typeof languages)[0])}
|
|
3069
|
+
>
|
|
3070
|
+
{languages.map((language) => (
|
|
3071
|
+
<Select.Option key={language.value} value={language}>
|
|
3072
|
+
{language.emoji} {language.label}
|
|
3073
|
+
</Select.Option>
|
|
3074
|
+
))}
|
|
3075
|
+
</Select>
|
|
3076
|
+
```
|
|
3077
|
+
|
|
3078
|
+
```tsx
|
|
3079
|
+
<Select className="w-[200px]" loading />
|
|
3080
|
+
```
|
|
3081
|
+
|
|
3082
|
+
```tsx
|
|
3083
|
+
<Select
|
|
3084
|
+
className="w-[200px]"
|
|
3085
|
+
loading={loading}
|
|
3086
|
+
value={value}
|
|
3087
|
+
onValueChange={(v) => setValue(v as string | null)}
|
|
3088
|
+
placeholder="Please select"
|
|
3089
|
+
>
|
|
3090
|
+
{data?.map((item) => (
|
|
3091
|
+
<Select.Option key={item} value={item}>
|
|
3092
|
+
{item}
|
|
3093
|
+
</Select.Option>
|
|
3094
|
+
))}
|
|
3095
|
+
</Select>
|
|
3096
|
+
```
|
|
3097
|
+
|
|
3098
|
+
```tsx
|
|
3099
|
+
<Select
|
|
3100
|
+
className="w-[250px]"
|
|
3101
|
+
multiple
|
|
3102
|
+
renderValue={(value) => {
|
|
3103
|
+
if (value.length > 3) {
|
|
3104
|
+
return (
|
|
3105
|
+
<span className="line-clamp-1">
|
|
3106
|
+
{value.slice(2).join(", ") + ` and ${value.length - 2} more`}
|
|
3107
|
+
</span>
|
|
3108
|
+
);
|
|
3109
|
+
}
|
|
3110
|
+
return <span>{value.join(", ")}</span>;
|
|
3111
|
+
}}
|
|
3112
|
+
value={value}
|
|
3113
|
+
onValueChange={(v) => setValue(v as string[])}
|
|
3114
|
+
>
|
|
3115
|
+
<Select.Option value="Name">Name</Select.Option>
|
|
3116
|
+
<Select.Option value="Location">Location</Select.Option>
|
|
3117
|
+
<Select.Option value="Size">Size</Select.Option>
|
|
3118
|
+
<Select.Option value="Read">Read</Select.Option>
|
|
3119
|
+
<Select.Option value="Write">Write</Select.Option>
|
|
3120
|
+
<Select.Option value="CreatedAt">Created At</Select.Option>
|
|
3121
|
+
</Select>
|
|
3122
|
+
```
|
|
3123
|
+
|
|
3124
|
+
```tsx
|
|
3125
|
+
<Select
|
|
3126
|
+
className="w-[200px]"
|
|
3127
|
+
onValueChange={(v) => setValue(v as (typeof authors)[0] | null)}
|
|
3128
|
+
value={value}
|
|
3129
|
+
isItemEqualToValue={(item, value) => item?.id === value?.id}
|
|
3130
|
+
renderValue={(author) => {
|
|
3131
|
+
return author?.name ?? "Please select author";
|
|
3132
|
+
}}
|
|
3133
|
+
>
|
|
3134
|
+
{authors.map((author) => (
|
|
3135
|
+
<Select.Option key={author.id} value={author}>
|
|
3136
|
+
<div className="flex w-[300px] items-center justify-between gap-2">
|
|
3137
|
+
<Text>{author.name}</Text>
|
|
3138
|
+
<Text variant="secondary">{author.title}</Text>
|
|
3139
|
+
</div>
|
|
3140
|
+
</Select.Option>
|
|
3141
|
+
))}
|
|
3142
|
+
</Select>
|
|
3143
|
+
```
|
|
3144
|
+
|
|
3145
|
+
|
|
3146
|
+
---
|
|
3147
|
+
|
|
3148
|
+
### SensitiveInput
|
|
3149
|
+
|
|
3150
|
+
SensitiveInput component
|
|
3151
|
+
|
|
3152
|
+
**Type:** component
|
|
3153
|
+
|
|
3154
|
+
**Import:** `import { SensitiveInput } from "@cloudflare/kumo";`
|
|
3155
|
+
|
|
3156
|
+
**Category:** Other
|
|
3157
|
+
|
|
3158
|
+
**Props:**
|
|
3159
|
+
|
|
3160
|
+
- `alt`: string
|
|
3161
|
+
- `autoComplete`: React.HTMLInputAutoCompleteAttribute
|
|
3162
|
+
- `checked`: boolean
|
|
3163
|
+
- `disabled`: boolean
|
|
3164
|
+
- `height`: number | string
|
|
3165
|
+
- `list`: string
|
|
3166
|
+
- `name`: string
|
|
3167
|
+
- `placeholder`: string
|
|
3168
|
+
- `readOnly`: boolean
|
|
3169
|
+
- `required`: boolean
|
|
3170
|
+
- `width`: number | string
|
|
3171
|
+
- `className`: string
|
|
3172
|
+
- `id`: string
|
|
3173
|
+
- `lang`: string
|
|
3174
|
+
- `title`: string
|
|
3175
|
+
- `children`: ReactNode
|
|
3176
|
+
- `value`: string
|
|
3177
|
+
Controlled value
|
|
3178
|
+
- `size`: enum [default: base]
|
|
3179
|
+
Size variant
|
|
3180
|
+
- `variant`: enum [default: default]
|
|
3181
|
+
Style variant
|
|
3182
|
+
- `label`: ReactNode
|
|
3183
|
+
Label content for the input (enables Field wrapper and sets masked state label) - can be a string or any React node
|
|
3184
|
+
- `labelTooltip`: ReactNode
|
|
3185
|
+
Tooltip content to display next to the label via an info icon
|
|
3186
|
+
- `description`: ReactNode
|
|
3187
|
+
Helper text displayed below the input
|
|
3188
|
+
- `error`: string | object
|
|
3189
|
+
Error message or validation error object
|
|
3190
|
+
|
|
3191
|
+
**Colors (kumo tokens used):**
|
|
3192
|
+
|
|
3193
|
+
`bg-kumo-brand`, `bg-kumo-control`, `outline-kumo-ring`, `text-kumo-default`, `text-kumo-subtle`
|
|
3194
|
+
|
|
3195
|
+
**Examples:**
|
|
3196
|
+
|
|
3197
|
+
```tsx
|
|
3198
|
+
<div className="w-80">
|
|
3199
|
+
<SensitiveInput label="API Key" defaultValue="sk_live_abc123xyz789" />
|
|
3200
|
+
</div>
|
|
3201
|
+
```
|
|
3202
|
+
|
|
3203
|
+
```tsx
|
|
3204
|
+
<div className="flex flex-col gap-4">
|
|
3205
|
+
{sizes.map((size) => (
|
|
3206
|
+
<div key={size} className="flex items-center gap-2">
|
|
3207
|
+
<span className="w-12 text-sm text-kumo-subtle">{size}</span>
|
|
3208
|
+
<SensitiveInput
|
|
3209
|
+
label={`${size} size`}
|
|
3210
|
+
size={size}
|
|
3211
|
+
defaultValue="secret-api-key-123"
|
|
3212
|
+
/>
|
|
3213
|
+
</div>
|
|
3214
|
+
))}
|
|
3215
|
+
</div>
|
|
3216
|
+
```
|
|
3217
|
+
|
|
3218
|
+
```tsx
|
|
3219
|
+
<div className="flex w-80 flex-col gap-4">
|
|
3220
|
+
<SensitiveInput
|
|
3221
|
+
label="Controlled Secret"
|
|
3222
|
+
value={value}
|
|
3223
|
+
onValueChange={setValue}
|
|
3224
|
+
/>
|
|
3225
|
+
<div className="text-sm text-kumo-subtle">
|
|
3226
|
+
Current value: <code className="text-kumo-default">{value}</code>
|
|
3227
|
+
</div>
|
|
3228
|
+
<div className="flex gap-2">
|
|
3229
|
+
<Button
|
|
3230
|
+
onClick={() => setValue("new-secret-" + Date.now())}
|
|
3231
|
+
variant="primary"
|
|
3232
|
+
size="sm"
|
|
3233
|
+
>
|
|
3234
|
+
Change value
|
|
3235
|
+
</Button>
|
|
3236
|
+
<Button onClick={() => setValue("")} variant="secondary" size="sm">
|
|
3237
|
+
Clear
|
|
3238
|
+
</Button>
|
|
3239
|
+
</div>
|
|
3240
|
+
</div>
|
|
3241
|
+
```
|
|
3242
|
+
|
|
3243
|
+
```tsx
|
|
3244
|
+
<div className="flex w-80 flex-col gap-4">
|
|
3245
|
+
<SensitiveInput
|
|
3246
|
+
label="Error State"
|
|
3247
|
+
variant="error"
|
|
3248
|
+
defaultValue="invalid-key"
|
|
3249
|
+
error="This API key is not valid"
|
|
3250
|
+
/>
|
|
3251
|
+
<SensitiveInput label="Disabled" defaultValue="cannot-edit" disabled />
|
|
3252
|
+
<SensitiveInput
|
|
3253
|
+
label="Read-only"
|
|
3254
|
+
defaultValue="view-only-secret-key"
|
|
3255
|
+
readOnly
|
|
3256
|
+
/>
|
|
3257
|
+
<SensitiveInput
|
|
3258
|
+
label="With Description"
|
|
3259
|
+
defaultValue="my-secret-value"
|
|
3260
|
+
description="Keep this value secure and don't share it"
|
|
3261
|
+
/>
|
|
3262
|
+
</div>
|
|
3263
|
+
```
|
|
3264
|
+
|
|
3265
|
+
|
|
3266
|
+
---
|
|
3267
|
+
|
|
3268
|
+
### Surface
|
|
3269
|
+
|
|
3270
|
+
Surface component
|
|
3271
|
+
|
|
3272
|
+
**Type:** component
|
|
3273
|
+
|
|
3274
|
+
**Import:** `import { Surface } from "@cloudflare/kumo";`
|
|
3275
|
+
|
|
3276
|
+
**Category:** Layout
|
|
3277
|
+
|
|
3278
|
+
**Props:**
|
|
3279
|
+
|
|
3280
|
+
- `as`: React.ElementType
|
|
3281
|
+
The element type to render as (default: "div")
|
|
3282
|
+
- `className`: string
|
|
3283
|
+
Additional CSS classes
|
|
3284
|
+
- `children`: ReactNode
|
|
3285
|
+
Child elements
|
|
3286
|
+
|
|
3287
|
+
**Colors (kumo tokens used):**
|
|
3288
|
+
|
|
3289
|
+
`bg-kumo-base`, `ring-kumo-line`
|
|
3290
|
+
|
|
3291
|
+
**Examples:**
|
|
3292
|
+
|
|
3293
|
+
```tsx
|
|
3294
|
+
<Surface className="rounded-lg p-6">
|
|
3295
|
+
<Text size="lg" bold>
|
|
3296
|
+
Surface Component
|
|
3297
|
+
</Text>
|
|
3298
|
+
<div className="mt-2">
|
|
3299
|
+
<Text variant="secondary">
|
|
3300
|
+
A container with consistent elevation and border styling.
|
|
3301
|
+
</Text>
|
|
3302
|
+
</div>
|
|
3303
|
+
</Surface>
|
|
3304
|
+
```
|
|
3305
|
+
|
|
3306
|
+
```tsx
|
|
3307
|
+
<div className="flex flex-col gap-4">
|
|
3308
|
+
<Surface as="section" className="rounded-lg p-4">
|
|
3309
|
+
<Text bold>As section element</Text>
|
|
3310
|
+
</Surface>
|
|
3311
|
+
<Surface as="article" className="rounded-lg p-4">
|
|
3312
|
+
<Text bold>As article element</Text>
|
|
3313
|
+
</Surface>
|
|
3314
|
+
<Surface as="aside" className="rounded-lg p-4">
|
|
3315
|
+
<Text bold>As aside element</Text>
|
|
3316
|
+
</Surface>
|
|
3317
|
+
</div>
|
|
3318
|
+
```
|
|
3319
|
+
|
|
3320
|
+
```tsx
|
|
3321
|
+
<Surface className="rounded-lg p-6">
|
|
3322
|
+
<Text bold>Outer Surface</Text>
|
|
3323
|
+
<Surface className="mt-4 rounded-md bg-kumo-elevated p-4">
|
|
3324
|
+
<Text variant="secondary">Nested Surface</Text>
|
|
3325
|
+
</Surface>
|
|
3326
|
+
</Surface>
|
|
3327
|
+
```
|
|
3328
|
+
|
|
3329
|
+
|
|
3330
|
+
---
|
|
3331
|
+
|
|
3332
|
+
### Switch
|
|
3333
|
+
|
|
3334
|
+
Switch component
|
|
3335
|
+
|
|
3336
|
+
**Type:** component
|
|
3337
|
+
|
|
3338
|
+
**Import:** `import { Switch } from "@cloudflare/kumo";`
|
|
3339
|
+
|
|
3340
|
+
**Category:** Input
|
|
3341
|
+
|
|
3342
|
+
**Props:**
|
|
3343
|
+
|
|
3344
|
+
- `variant`: enum [default: default]
|
|
3345
|
+
- `"default"`: Default switch appearance
|
|
3346
|
+
- `"error"`: Error state for validation failures
|
|
3347
|
+
- `label`: ReactNode
|
|
3348
|
+
Label content for the switch (Field wrapper is built-in) - can be a string or any React node. Optional when used standalone for visual-only purposes.
|
|
3349
|
+
- `labelTooltip`: ReactNode
|
|
3350
|
+
Tooltip content to display next to the label via an info icon
|
|
3351
|
+
- `required`: boolean
|
|
3352
|
+
Whether the switch is required. When explicitly false, shows "(optional)" text after the label.
|
|
3353
|
+
- `controlFirst`: boolean
|
|
3354
|
+
When true (default), switch appears before label. When false, label appears before switch.
|
|
3355
|
+
- `size`: enum [default: base]
|
|
3356
|
+
- `"sm"`: Small switch for compact UIs
|
|
3357
|
+
- `"base"`: Default switch size
|
|
3358
|
+
- `"lg"`: Large switch for prominent toggles
|
|
3359
|
+
- `checked`: boolean
|
|
3360
|
+
- `disabled`: boolean
|
|
3361
|
+
- `transitioning`: boolean
|
|
3362
|
+
- `name`: string
|
|
3363
|
+
- `type`: enum
|
|
3364
|
+
- `value`: string | string[] | number
|
|
3365
|
+
- `className`: string
|
|
3366
|
+
- `id`: string
|
|
3367
|
+
- `lang`: string
|
|
3368
|
+
- `title`: string
|
|
3369
|
+
- `onClick`: (event: React.MouseEvent) => void (required)
|
|
3370
|
+
Callback when switch is clicked
|
|
3371
|
+
|
|
3372
|
+
**Colors (kumo tokens used):**
|
|
3373
|
+
|
|
3374
|
+
`bg-kumo-brand`, `bg-kumo-brand-hover`, `bg-kumo-danger`, `bg-kumo-interact`, `bg-kumo-recessed`, `border-kumo-line`, `ring-kumo-danger`, `text-kumo-danger`, `text-kumo-default`, `text-kumo-subtle`
|
|
3375
|
+
|
|
3376
|
+
**Sub-Components:**
|
|
3377
|
+
|
|
3378
|
+
This is a compound component. Use these sub-components:
|
|
3379
|
+
|
|
3380
|
+
#### Switch.Item
|
|
3381
|
+
|
|
3382
|
+
Item sub-component
|
|
3383
|
+
|
|
3384
|
+
#### Switch.Group
|
|
3385
|
+
|
|
3386
|
+
Group sub-component
|
|
3387
|
+
|
|
3388
|
+
Props:
|
|
3389
|
+
- `legend`: string (required)
|
|
3390
|
+
- `children`: ReactNode (required)
|
|
3391
|
+
- `error`: string
|
|
3392
|
+
- `description`: ReactNode
|
|
3393
|
+
- `disabled`: boolean
|
|
3394
|
+
- `controlFirst`: boolean
|
|
3395
|
+
- `className`: string
|
|
3396
|
+
|
|
3397
|
+
|
|
3398
|
+
**Examples:**
|
|
3399
|
+
|
|
3400
|
+
```tsx
|
|
3401
|
+
<Switch label="Switch" checked={checked} onCheckedChange={setChecked} />
|
|
3402
|
+
```
|
|
3403
|
+
|
|
3404
|
+
```tsx
|
|
3405
|
+
<Switch label="Disabled" checked={false} disabled />
|
|
3406
|
+
```
|
|
3407
|
+
|
|
3408
|
+
|
|
3409
|
+
---
|
|
3410
|
+
|
|
3411
|
+
### Table
|
|
3412
|
+
|
|
3413
|
+
Table component
|
|
3414
|
+
|
|
3415
|
+
**Type:** component
|
|
3416
|
+
|
|
3417
|
+
**Import:** `import { Table } from "@cloudflare/kumo";`
|
|
3418
|
+
|
|
3419
|
+
**Category:** Other
|
|
3420
|
+
|
|
3421
|
+
**Props:**
|
|
3422
|
+
|
|
3423
|
+
- `layout`: enum [default: auto]
|
|
3424
|
+
- `"auto"`: Auto table layout - columns resize based on content
|
|
3425
|
+
- `"fixed"`: Fixed table layout - columns have equal width, controlled via colgroup
|
|
3426
|
+
- `variant`: enum [default: default]
|
|
3427
|
+
- `"default"`: Default row variant
|
|
3428
|
+
- `"selected"`: Selected row variant
|
|
3429
|
+
- `className`: string
|
|
3430
|
+
Additional CSS classes
|
|
3431
|
+
- `children`: ReactNode
|
|
3432
|
+
Child elements
|
|
3433
|
+
|
|
3434
|
+
**Colors (kumo tokens used):**
|
|
3435
|
+
|
|
3436
|
+
`bg-kumo-base`, `bg-kumo-ring`, `bg-kumo-tint`, `border-kumo-fill`, `text-kumo-default`
|
|
3437
|
+
|
|
3438
|
+
**Sub-Components:**
|
|
3439
|
+
|
|
3440
|
+
This is a compound component. Use these sub-components:
|
|
3441
|
+
|
|
3442
|
+
#### Table.Header
|
|
3443
|
+
|
|
3444
|
+
Header sub-component
|
|
3445
|
+
|
|
3446
|
+
#### Table.Head
|
|
3447
|
+
|
|
3448
|
+
Head sub-component
|
|
3449
|
+
|
|
3450
|
+
#### Table.Row
|
|
3451
|
+
|
|
3452
|
+
Row sub-component
|
|
3453
|
+
|
|
3454
|
+
#### Table.Body
|
|
3455
|
+
|
|
3456
|
+
Body sub-component
|
|
3457
|
+
|
|
3458
|
+
#### Table.Cell
|
|
3459
|
+
|
|
3460
|
+
Cell sub-component
|
|
3461
|
+
|
|
3462
|
+
#### Table.CheckCell
|
|
3463
|
+
|
|
3464
|
+
CheckCell sub-component
|
|
3465
|
+
|
|
3466
|
+
#### Table.CheckHead
|
|
3467
|
+
|
|
3468
|
+
CheckHead sub-component
|
|
3469
|
+
|
|
3470
|
+
#### Table.Footer
|
|
3471
|
+
|
|
3472
|
+
Footer sub-component
|
|
3473
|
+
|
|
3474
|
+
#### Table.ResizeHandle
|
|
3475
|
+
|
|
3476
|
+
ResizeHandle sub-component
|
|
3477
|
+
|
|
3478
|
+
|
|
3479
|
+
**Examples:**
|
|
3480
|
+
|
|
3481
|
+
```tsx
|
|
3482
|
+
<LayerCard>
|
|
3483
|
+
<LayerCard.Primary className="p-0">
|
|
3484
|
+
<Table>
|
|
3485
|
+
<Table.Header>
|
|
3486
|
+
<Table.Row>
|
|
3487
|
+
<Table.Head>Subject</Table.Head>
|
|
3488
|
+
<Table.Head>From</Table.Head>
|
|
3489
|
+
<Table.Head>Date</Table.Head>
|
|
3490
|
+
</Table.Row>
|
|
3491
|
+
</Table.Header>
|
|
3492
|
+
<Table.Body>
|
|
3493
|
+
{emailData.slice(0, 3).map((row) => (
|
|
3494
|
+
<Table.Row key={row.id}>
|
|
3495
|
+
<Table.Cell>{row.subject}</Table.Cell>
|
|
3496
|
+
<Table.Cell>{row.from}</Table.Cell>
|
|
3497
|
+
<Table.Cell>{row.date}</Table.Cell>
|
|
3498
|
+
</Table.Row>
|
|
3499
|
+
))}
|
|
3500
|
+
</Table.Body>
|
|
3501
|
+
</Table>
|
|
3502
|
+
</LayerCard.Primary>
|
|
3503
|
+
</LayerCard>
|
|
3504
|
+
```
|
|
3505
|
+
|
|
3506
|
+
```tsx
|
|
3507
|
+
<LayerCard>
|
|
3508
|
+
<LayerCard.Primary className="p-0">
|
|
3509
|
+
<Table>
|
|
3510
|
+
<Table.Header>
|
|
3511
|
+
<Table.Row>
|
|
3512
|
+
<Table.CheckHead aria-label="Select all rows" />
|
|
3513
|
+
<Table.Head>Subject</Table.Head>
|
|
3514
|
+
<Table.Head>From</Table.Head>
|
|
3515
|
+
<Table.Head>Date</Table.Head>
|
|
3516
|
+
</Table.Row>
|
|
3517
|
+
</Table.Header>
|
|
3518
|
+
<Table.Body>
|
|
3519
|
+
{emailData.slice(0, 3).map((row) => (
|
|
3520
|
+
<Table.Row key={row.id}>
|
|
3521
|
+
<Table.CheckCell aria-label={`Select ${row.subject}`} />
|
|
3522
|
+
<Table.Cell>{row.subject}</Table.Cell>
|
|
3523
|
+
<Table.Cell>{row.from}</Table.Cell>
|
|
3524
|
+
<Table.Cell>{row.date}</Table.Cell>
|
|
3525
|
+
</Table.Row>
|
|
3526
|
+
))}
|
|
3527
|
+
</Table.Body>
|
|
3528
|
+
</Table>
|
|
3529
|
+
</LayerCard.Primary>
|
|
3530
|
+
</LayerCard>
|
|
3531
|
+
```
|
|
3532
|
+
|
|
3533
|
+
```tsx
|
|
3534
|
+
<LayerCard>
|
|
3535
|
+
<LayerCard.Primary className="p-0">
|
|
3536
|
+
<Table>
|
|
3537
|
+
<Table.Header>
|
|
3538
|
+
<Table.Row>
|
|
3539
|
+
<Table.CheckHead aria-label="Select all rows" />
|
|
3540
|
+
<Table.Head>Subject</Table.Head>
|
|
3541
|
+
<Table.Head>From</Table.Head>
|
|
3542
|
+
<Table.Head>Date</Table.Head>
|
|
3543
|
+
</Table.Row>
|
|
3544
|
+
</Table.Header>
|
|
3545
|
+
<Table.Body>
|
|
3546
|
+
<Table.Row>
|
|
3547
|
+
<Table.CheckCell aria-label="Select row 1" />
|
|
3548
|
+
<Table.Cell>Kumo v1.0.0 released</Table.Cell>
|
|
3549
|
+
<Table.Cell>Visal In</Table.Cell>
|
|
3550
|
+
<Table.Cell>5 seconds ago</Table.Cell>
|
|
3551
|
+
</Table.Row>
|
|
3552
|
+
<Table.Row variant="selected">
|
|
3553
|
+
<Table.CheckCell checked aria-label="Select row 2" />
|
|
3554
|
+
<Table.Cell>New Job Offer</Table.Cell>
|
|
3555
|
+
<Table.Cell>Cloudflare</Table.Cell>
|
|
3556
|
+
<Table.Cell>10 minutes ago</Table.Cell>
|
|
3557
|
+
</Table.Row>
|
|
3558
|
+
<Table.Row>
|
|
3559
|
+
<Table.CheckCell aria-label="Select row 3" />
|
|
3560
|
+
<Table.Cell>Daily Email Digest</Table.Cell>
|
|
3561
|
+
<Table.Cell>Cloudflare</Table.Cell>
|
|
3562
|
+
<Table.Cell>1 hour ago</Table.Cell>
|
|
3563
|
+
</Table.Row>
|
|
3564
|
+
</Table.Body>
|
|
3565
|
+
</Table>
|
|
3566
|
+
</LayerCard.Primary>
|
|
3567
|
+
</LayerCard>
|
|
3568
|
+
```
|
|
3569
|
+
|
|
3570
|
+
```tsx
|
|
3571
|
+
<LayerCard>
|
|
3572
|
+
<LayerCard.Primary className="p-0">
|
|
3573
|
+
<Table layout="fixed">
|
|
3574
|
+
<colgroup>
|
|
3575
|
+
<col />
|
|
3576
|
+
<col className="w-[150px]" />
|
|
3577
|
+
<col className="w-[150px]" />
|
|
3578
|
+
</colgroup>
|
|
3579
|
+
<Table.Header>
|
|
3580
|
+
<Table.Row>
|
|
3581
|
+
<Table.Head>Subject</Table.Head>
|
|
3582
|
+
<Table.Head>From</Table.Head>
|
|
3583
|
+
<Table.Head>Date</Table.Head>
|
|
3584
|
+
</Table.Row>
|
|
3585
|
+
</Table.Header>
|
|
3586
|
+
<Table.Body>
|
|
3587
|
+
{emailData.map((row) => (
|
|
3588
|
+
<Table.Row key={row.id}>
|
|
3589
|
+
<Table.Cell>{row.subject}</Table.Cell>
|
|
3590
|
+
<Table.Cell>{row.from}</Table.Cell>
|
|
3591
|
+
<Table.Cell>{row.date}</Table.Cell>
|
|
3592
|
+
</Table.Row>
|
|
3593
|
+
))}
|
|
3594
|
+
</Table.Body>
|
|
3595
|
+
</Table>
|
|
3596
|
+
</LayerCard.Primary>
|
|
3597
|
+
</LayerCard>
|
|
3598
|
+
```
|
|
3599
|
+
|
|
3600
|
+
```tsx
|
|
3601
|
+
<LayerCard>
|
|
3602
|
+
<LayerCard.Primary className="w-full overflow-x-auto p-0">
|
|
3603
|
+
<Table layout="fixed">
|
|
3604
|
+
<colgroup>
|
|
3605
|
+
<col style={{ width: "40px" }} />
|
|
3606
|
+
<col />
|
|
3607
|
+
<col style={{ width: "150px" }} />
|
|
3608
|
+
<col style={{ width: "120px" }} />
|
|
3609
|
+
<col style={{ width: "50px" }} />
|
|
3610
|
+
</colgroup>
|
|
3611
|
+
<Table.Header>
|
|
3612
|
+
<Table.Row>
|
|
3613
|
+
<Table.CheckHead aria-label="Select all rows" />
|
|
3614
|
+
<Table.Head>Subject</Table.Head>
|
|
3615
|
+
<Table.Head>From</Table.Head>
|
|
3616
|
+
<Table.Head>Date</Table.Head>
|
|
3617
|
+
<Table.Head></Table.Head>
|
|
3618
|
+
</Table.Row>
|
|
3619
|
+
</Table.Header>
|
|
3620
|
+
<Table.Body>
|
|
3621
|
+
{emailData.map((row, index) => (
|
|
3622
|
+
<Table.Row
|
|
3623
|
+
key={row.id}
|
|
3624
|
+
variant={index === 1 ? "selected" : "default"}
|
|
3625
|
+
>
|
|
3626
|
+
<Table.CheckCell
|
|
3627
|
+
checked={index === 1}
|
|
3628
|
+
aria-label={`Select ${row.subject}`}
|
|
3629
|
+
/>
|
|
3630
|
+
<Table.Cell>
|
|
3631
|
+
<div className="flex items-center gap-2">
|
|
3632
|
+
<EnvelopeSimple size={16} />
|
|
3633
|
+
<span className="truncate">{row.subject}</span>
|
|
3634
|
+
{row.tags && (
|
|
3635
|
+
<div className="ml-2 inline-flex gap-1">
|
|
3636
|
+
{row.tags.map((tag) => (
|
|
3637
|
+
<Badge key={tag}>{tag}</Badge>
|
|
3638
|
+
))}
|
|
3639
|
+
</div>
|
|
3640
|
+
)}
|
|
3641
|
+
</div>
|
|
3642
|
+
</Table.Cell>
|
|
3643
|
+
<Table.Cell>
|
|
3644
|
+
<span className="truncate">{row.from}</span>
|
|
3645
|
+
</Table.Cell>
|
|
3646
|
+
<Table.Cell>
|
|
3647
|
+
<span className="truncate">{row.date}</span>
|
|
3648
|
+
</Table.Cell>
|
|
3649
|
+
<Table.Cell className="text-right">
|
|
3650
|
+
<Button
|
|
3651
|
+
variant="ghost"
|
|
3652
|
+
size="sm"
|
|
3653
|
+
shape="square"
|
|
3654
|
+
aria-label="More options"
|
|
3655
|
+
>
|
|
3656
|
+
<DotsThree weight="bold" size={16} />
|
|
3657
|
+
</Button>
|
|
3658
|
+
</Table.Cell>
|
|
3659
|
+
</Table.Row>
|
|
3660
|
+
))}
|
|
3661
|
+
</Table.Body>
|
|
3662
|
+
</Table>
|
|
3663
|
+
</LayerCard.Primary>
|
|
3664
|
+
</LayerCard>
|
|
3665
|
+
```
|
|
3666
|
+
|
|
3667
|
+
|
|
3668
|
+
---
|
|
3669
|
+
|
|
3670
|
+
### Tabs
|
|
3671
|
+
|
|
3672
|
+
Tabs component
|
|
3673
|
+
|
|
3674
|
+
**Type:** component
|
|
3675
|
+
|
|
3676
|
+
**Import:** `import { Tabs } from "@cloudflare/kumo";`
|
|
3677
|
+
|
|
3678
|
+
**Category:** Navigation
|
|
3679
|
+
|
|
3680
|
+
**Props:**
|
|
3681
|
+
|
|
3682
|
+
- `tabs`: TabsItem[]
|
|
3683
|
+
Array of tab items to render
|
|
3684
|
+
- `value`: string
|
|
3685
|
+
Controlled value. When set, component becomes controlled.
|
|
3686
|
+
- `selectedValue`: string
|
|
3687
|
+
Default selected value for uncontrolled mode. Ignored when `value` is set.
|
|
3688
|
+
- `activateOnFocus`: boolean
|
|
3689
|
+
When true, tabs are activated immediately upon receiving focus via arrow keys. When false (default), tabs receive focus but require Enter/Space to activate. Set to true for better keyboard UX in most cases.
|
|
3690
|
+
- `className`: string
|
|
3691
|
+
Additional class name for the root element
|
|
3692
|
+
- `listClassName`: string
|
|
3693
|
+
Additional class name for the tab list element
|
|
3694
|
+
- `indicatorClassName`: string
|
|
3695
|
+
Additional class name for the indicator element
|
|
3696
|
+
- `variant`: enum [default: segmented]
|
|
3697
|
+
- `onValueChange`: (value: string) => void
|
|
3698
|
+
Callback when active tab changes
|
|
3699
|
+
|
|
3700
|
+
**Colors (kumo tokens used):**
|
|
3701
|
+
|
|
3702
|
+
`bg-kumo-brand`, `bg-kumo-overlay`, `bg-kumo-tint`, `border-kumo-line`, `border-kumo-tint`, `ring-kumo-fill-hover`, `ring-kumo-ring`, `text-kumo-default`, `text-kumo-strong`, `text-kumo-subtle`
|
|
3703
|
+
|
|
3704
|
+
**Styling:**
|
|
3705
|
+
|
|
3706
|
+
|
|
3707
|
+
**Examples:**
|
|
3708
|
+
|
|
3709
|
+
```tsx
|
|
3710
|
+
<div className="flex flex-col gap-6">
|
|
3711
|
+
<div>
|
|
3712
|
+
<p className="mb-2 text-sm text-kumo-subtle">Segmented (default)</p>
|
|
3713
|
+
<Tabs
|
|
3714
|
+
variant="segmented"
|
|
3715
|
+
tabs={[
|
|
3716
|
+
{ value: "tab1", label: "Tab 1" },
|
|
3717
|
+
{ value: "tab2", label: "Tab 2" },
|
|
3718
|
+
{ value: "tab3", label: "Tab 3" },
|
|
3719
|
+
]}
|
|
3720
|
+
selectedValue="tab1"
|
|
3721
|
+
/>
|
|
3722
|
+
</div>
|
|
3723
|
+
<div>
|
|
3724
|
+
<p className="mb-2 text-sm text-kumo-subtle">Underline</p>
|
|
3725
|
+
<Tabs
|
|
3726
|
+
variant="underline"
|
|
3727
|
+
tabs={[
|
|
3728
|
+
{ value: "tab1", label: "Tab 1" },
|
|
3729
|
+
{ value: "tab2", label: "Tab 2" },
|
|
3730
|
+
{ value: "tab3", label: "Tab 3" },
|
|
3731
|
+
]}
|
|
3732
|
+
selectedValue="tab1"
|
|
3733
|
+
/>
|
|
3734
|
+
</div>
|
|
3735
|
+
</div>
|
|
3736
|
+
```
|
|
3737
|
+
|
|
3738
|
+
```tsx
|
|
3739
|
+
<Tabs
|
|
3740
|
+
variant="segmented"
|
|
3741
|
+
tabs={[
|
|
3742
|
+
{ value: "tab1", label: "Tab 1" },
|
|
3743
|
+
{ value: "tab2", label: "Tab 2" },
|
|
3744
|
+
{ value: "tab3", label: "Tab 3" },
|
|
3745
|
+
]}
|
|
3746
|
+
selectedValue="tab1"
|
|
3747
|
+
/>
|
|
3748
|
+
```
|
|
3749
|
+
|
|
3750
|
+
```tsx
|
|
3751
|
+
<div className="space-y-4">
|
|
3752
|
+
<Tabs
|
|
3753
|
+
tabs={[
|
|
3754
|
+
{ value: "tab1", label: "Tab 1" },
|
|
3755
|
+
{ value: "tab2", label: "Tab 2" },
|
|
3756
|
+
{ value: "tab3", label: "Tab 3" },
|
|
3757
|
+
]}
|
|
3758
|
+
value={activeTab}
|
|
3759
|
+
onValueChange={setActiveTab}
|
|
3760
|
+
/>
|
|
3761
|
+
<p className="text-sm text-kumo-subtle">
|
|
3762
|
+
Active tab: <code className="text-sm">{activeTab}</code>
|
|
3763
|
+
</p>
|
|
3764
|
+
</div>
|
|
3765
|
+
```
|
|
3766
|
+
|
|
3767
|
+
```tsx
|
|
3768
|
+
<Tabs
|
|
3769
|
+
tabs={[
|
|
3770
|
+
{ value: "overview", label: "Overview" },
|
|
3771
|
+
{ value: "analytics", label: "Analytics" },
|
|
3772
|
+
{ value: "reports", label: "Reports" },
|
|
3773
|
+
{ value: "notifications", label: "Notifications" },
|
|
3774
|
+
{ value: "settings", label: "Settings" },
|
|
3775
|
+
{ value: "billing", label: "Billing" },
|
|
3776
|
+
]}
|
|
3777
|
+
selectedValue="overview"
|
|
3778
|
+
/>
|
|
3779
|
+
```
|
|
3780
|
+
|
|
3781
|
+
```tsx
|
|
3782
|
+
<Tabs
|
|
3783
|
+
tabs={[
|
|
3784
|
+
{
|
|
3785
|
+
value: "tab1",
|
|
3786
|
+
label: "Regular Tab",
|
|
3787
|
+
},
|
|
3788
|
+
{
|
|
3789
|
+
value: "tab2",
|
|
3790
|
+
label: "Link Tab",
|
|
3791
|
+
render: (props) => <a {...props} href="#tab2" />,
|
|
3792
|
+
},
|
|
3793
|
+
{
|
|
3794
|
+
value: "tab3",
|
|
3795
|
+
label: "Another Link",
|
|
3796
|
+
render: (props) => <a {...props} href="#tab3" />,
|
|
3797
|
+
},
|
|
3798
|
+
]}
|
|
3799
|
+
selectedValue="tab1"
|
|
3800
|
+
/>
|
|
3801
|
+
```
|
|
3802
|
+
|
|
3803
|
+
|
|
3804
|
+
---
|
|
3805
|
+
|
|
3806
|
+
### Text
|
|
3807
|
+
|
|
3808
|
+
Text component
|
|
3809
|
+
|
|
3810
|
+
**Type:** component
|
|
3811
|
+
|
|
3812
|
+
**Import:** `import { Text } from "@cloudflare/kumo";`
|
|
3813
|
+
|
|
3814
|
+
**Category:** Display
|
|
3815
|
+
|
|
3816
|
+
**Props:**
|
|
3817
|
+
|
|
3818
|
+
- `variant`: enum [default: body]
|
|
3819
|
+
- `"heading1"`: Large heading for page titles
|
|
3820
|
+
- `"heading2"`: Medium heading for section titles
|
|
3821
|
+
- `"heading3"`: Small heading for subsections
|
|
3822
|
+
- `"body"`: Default body text
|
|
3823
|
+
- `"secondary"`: Muted text for secondary information
|
|
3824
|
+
- `"success"`: Success state text
|
|
3825
|
+
- `"error"`: Error state text
|
|
3826
|
+
- `"mono"`: Monospace text for code
|
|
3827
|
+
- `"mono-secondary"`: Muted monospace text
|
|
3828
|
+
- `size`: enum [default: base]
|
|
3829
|
+
- `"xs"`: Extra small text
|
|
3830
|
+
- `"sm"`: Small text
|
|
3831
|
+
- `"base"`: Default text size
|
|
3832
|
+
- `"lg"`: Large text
|
|
3833
|
+
- `bold`: boolean
|
|
3834
|
+
Whether to use bold font weight (only applies to body variants)
|
|
3835
|
+
- `as`: React.ElementType
|
|
3836
|
+
The element type to render as
|
|
3837
|
+
- `children`: ReactNode
|
|
3838
|
+
Child text content
|
|
3839
|
+
|
|
3840
|
+
**Colors (kumo tokens used):**
|
|
3841
|
+
|
|
3842
|
+
`text-kumo-danger`, `text-kumo-default`, `text-kumo-link`, `text-kumo-subtle`
|
|
3843
|
+
|
|
3844
|
+
**Styling:**
|
|
3845
|
+
|
|
3846
|
+
|
|
3847
|
+
**Examples:**
|
|
3848
|
+
|
|
3849
|
+
```tsx
|
|
3850
|
+
<div className="grid w-full grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3">
|
|
3851
|
+
<div className="flex flex-col justify-end gap-1 rounded-lg border border-kumo-line bg-kumo-base p-4">
|
|
3852
|
+
<Text variant="heading1">Heading 1</Text>
|
|
3853
|
+
<p className="font-mono text-xs text-kumo-subtle">text-3xl (30px)</p>
|
|
3854
|
+
</div>
|
|
3855
|
+
<div className="flex flex-col justify-end gap-1 rounded-lg border border-kumo-line bg-kumo-base p-4">
|
|
3856
|
+
<Text variant="heading2">Heading 2</Text>
|
|
3857
|
+
<p className="font-mono text-xs text-kumo-subtle">text-2xl (24px)</p>
|
|
3858
|
+
</div>
|
|
3859
|
+
<div className="flex flex-col justify-end gap-1 rounded-lg border border-kumo-line bg-kumo-base p-4">
|
|
3860
|
+
<Text variant="heading3">Heading 3</Text>
|
|
3861
|
+
<p className="font-mono text-xs text-kumo-subtle">text-lg (16px)</p>
|
|
3862
|
+
</div>
|
|
3863
|
+
<div className="flex flex-col justify-end gap-1 rounded-lg border border-kumo-line bg-kumo-base p-4">
|
|
3864
|
+
<Text>Body</Text>
|
|
3865
|
+
<p className="font-mono text-xs text-kumo-subtle">text-base (14px)</p>
|
|
3866
|
+
</div>
|
|
3867
|
+
<div className="flex flex-col justify-end gap-1 rounded-lg border border-kumo-line bg-kumo-base p-4">
|
|
3868
|
+
<Text bold>Body bold</Text>
|
|
3869
|
+
<p className="font-mono text-xs text-kumo-subtle">text-base (14px)</p>
|
|
3870
|
+
</div>
|
|
3871
|
+
<div className="flex flex-col justify-end gap-1 rounded-lg border border-kumo-line bg-kumo-base p-4">
|
|
3872
|
+
<Text size="lg">Body lg</Text>
|
|
3873
|
+
<p className="font-mono text-xs text-kumo-subtle">text-lg (16px)</p>
|
|
3874
|
+
</div>
|
|
3875
|
+
<div className="flex flex-col justify-end gap-1 rounded-lg border border-kumo-line bg-kumo-base p-4">
|
|
3876
|
+
<Text size="sm">Body sm</Text>
|
|
3877
|
+
<p className="font-mono text-xs text-kumo-subtle">text-sm (13px)</p>
|
|
3878
|
+
</div>
|
|
3879
|
+
<div className="flex flex-col justify-end gap-1 rounded-lg border border-kumo-line bg-kumo-base p-4">
|
|
3880
|
+
<Text size="xs">Body xs</Text>
|
|
3881
|
+
<p className="font-mono text-xs text-kumo-subtle">text-xs (12px)</p>
|
|
3882
|
+
</div>
|
|
3883
|
+
<div className="flex flex-col justify-end gap-1 rounded-lg border border-kumo-line bg-kumo-base p-4">
|
|
3884
|
+
<Text variant="secondary">Body secondary</Text>
|
|
3885
|
+
<p className="font-mono text-xs text-kumo-subtle">text-base (14px)</p>
|
|
3886
|
+
</div>
|
|
3887
|
+
<div className="flex flex-col justify-end gap-1 rounded-lg border border-kumo-line bg-kumo-base p-4">
|
|
3888
|
+
<Text variant="mono">Monospace</Text>
|
|
3889
|
+
<p className="font-mono text-xs text-kumo-subtle">text-sm (13px)</p>
|
|
3890
|
+
</div>
|
|
3891
|
+
<div className="flex flex-col justify-end gap-1 rounded-lg border border-kumo-line bg-kumo-base p-4">
|
|
3892
|
+
<Text variant="mono" size="lg">
|
|
3893
|
+
Monospace lg
|
|
3894
|
+
</Text>
|
|
3895
|
+
<p className="font-mono text-xs text-kumo-subtle">text-base (14px)</p>
|
|
3896
|
+
</div>
|
|
3897
|
+
<div className="flex flex-col justify-end gap-1 rounded-lg border border-kumo-line bg-kumo-base p-4">
|
|
3898
|
+
<Text variant="mono-secondary">Monospace secondary</Text>
|
|
3899
|
+
<p className="font-mono text-xs text-kumo-subtle">text-sm (13px)</p>
|
|
3900
|
+
</div>
|
|
3901
|
+
<div className="flex flex-col justify-end gap-1 rounded-lg border border-kumo-line bg-kumo-base p-4">
|
|
3902
|
+
<Text variant="success">Success</Text>
|
|
3903
|
+
<p className="font-mono text-xs text-kumo-subtle">text-base (14px)</p>
|
|
3904
|
+
</div>
|
|
3905
|
+
<div className="flex flex-col justify-end gap-1 rounded-lg border border-kumo-line bg-kumo-base p-4">
|
|
3906
|
+
<Text variant="error">Error</Text>
|
|
3907
|
+
<p className="font-mono text-xs text-kumo-subtle">text-base (14px)</p>
|
|
3908
|
+
</div>
|
|
3909
|
+
</div>
|
|
3910
|
+
```
|
|
3911
|
+
|
|
3912
|
+
|
|
3913
|
+
---
|
|
3914
|
+
|
|
3915
|
+
### Toasty
|
|
3916
|
+
|
|
3917
|
+
Toasty component
|
|
3918
|
+
|
|
3919
|
+
**Type:** component
|
|
3920
|
+
|
|
3921
|
+
**Import:** `import { Toasty } from "@cloudflare/kumo";`
|
|
3922
|
+
|
|
3923
|
+
**Category:** Feedback
|
|
3924
|
+
|
|
3925
|
+
**Props:**
|
|
3926
|
+
|
|
3927
|
+
- `children`: ReactNode
|
|
3928
|
+
|
|
3929
|
+
**Colors (kumo tokens used):**
|
|
3930
|
+
|
|
3931
|
+
`bg-kumo-control`, `bg-kumo-fill-hover`, `border-kumo-fill`, `text-kumo-default`, `text-kumo-strong`, `text-kumo-subtle`
|
|
3932
|
+
|
|
3933
|
+
**Styling:**
|
|
3934
|
+
|
|
3935
|
+
|
|
3936
|
+
---
|
|
3937
|
+
|
|
3938
|
+
### Tooltip
|
|
3939
|
+
|
|
3940
|
+
Tooltip component
|
|
3941
|
+
|
|
3942
|
+
**Type:** component
|
|
3943
|
+
|
|
3944
|
+
**Import:** `import { Tooltip } from "@cloudflare/kumo";`
|
|
3945
|
+
|
|
3946
|
+
**Category:** Overlay
|
|
3947
|
+
|
|
3948
|
+
**Props:**
|
|
3949
|
+
|
|
3950
|
+
- `align`: enum
|
|
3951
|
+
- `asChild`: boolean
|
|
3952
|
+
- `className`: string
|
|
3953
|
+
- `side`: enum [default: top]
|
|
3954
|
+
- `"top"`: Tooltip appears above the trigger
|
|
3955
|
+
- `"bottom"`: Tooltip appears below the trigger
|
|
3956
|
+
- `"left"`: Tooltip appears to the left of the trigger
|
|
3957
|
+
- `"right"`: Tooltip appears to the right of the trigger
|
|
3958
|
+
- `content`: ReactNode (required)
|
|
3959
|
+
Content to display in the tooltip
|
|
3960
|
+
|
|
3961
|
+
**Colors (kumo tokens used):**
|
|
3962
|
+
|
|
3963
|
+
`bg-kumo-base`, `fill-kumo-base`, `fill-kumo-tip-shadow`, `fill-kumo-tip-stroke`, `outline-kumo-fill`, `text-kumo-default`
|
|
3964
|
+
|
|
3965
|
+
**Examples:**
|
|
3966
|
+
|
|
3967
|
+
```tsx
|
|
3968
|
+
<TooltipProvider>
|
|
3969
|
+
<Tooltip content="Add new item" asChild>
|
|
3970
|
+
<Button shape="square" icon={PlusIcon} />
|
|
3971
|
+
</Tooltip>
|
|
3972
|
+
</TooltipProvider>
|
|
3973
|
+
```
|
|
3974
|
+
|
|
3975
|
+
```tsx
|
|
3976
|
+
<TooltipProvider>
|
|
3977
|
+
<div className="flex gap-2">
|
|
3978
|
+
<Tooltip content="Add" asChild>
|
|
3979
|
+
<Button shape="square" icon={PlusIcon} />
|
|
3980
|
+
</Tooltip>
|
|
3981
|
+
<Tooltip content="Change language" asChild>
|
|
3982
|
+
<Button shape="square" icon={TranslateIcon} />
|
|
3983
|
+
</Tooltip>
|
|
3984
|
+
</div>
|
|
3985
|
+
</TooltipProvider>
|
|
3986
|
+
```
|
|
3987
|
+
|
|
3988
|
+
|
|
3989
|
+
---
|
|
3990
|
+
|
|
3991
|
+
### InputArea
|
|
3992
|
+
|
|
3993
|
+
Multi-line textarea input with Input variants and InputArea-specific dimensions
|
|
3994
|
+
|
|
3995
|
+
**Type:** component
|
|
3996
|
+
|
|
3997
|
+
**Import:** `import { InputArea } from "@cloudflare/kumo (synthetic - uses Input component)";`
|
|
3998
|
+
|
|
3999
|
+
**Category:** Input
|
|
4000
|
+
|
|
4001
|
+
**Props:**
|
|
4002
|
+
|
|
4003
|
+
|
|
4004
|
+
**Styling:**
|
|
4005
|
+
|
|
4006
|
+
- **Size Variants:**
|
|
4007
|
+
- `xs`:
|
|
4008
|
+
- `sm`:
|
|
4009
|
+
- `base`:
|
|
4010
|
+
- `lg`:
|
|
4011
|
+
|
|
4012
|
+
## Quick Reference
|
|
4013
|
+
|
|
4014
|
+
**Components by Category:**
|
|
4015
|
+
- **Display:** Badge, Breadcrumbs, Code, Collapsible, Empty, LayerCard, Meter, Text
|
|
4016
|
+
- **Feedback:** Banner, Loader, Toasty
|
|
4017
|
+
- **Action:** Button, ClipboardText
|
|
4018
|
+
- **Input:** Checkbox, Combobox, DateRangePicker, Field, Input, Radio, Select, Switch
|
|
4019
|
+
- **Navigation:** CommandPalette, MenuBar, Pagination, Tabs
|
|
4020
|
+
- **Overlay:** Dialog, DropdownMenu, Popover, Tooltip
|
|
4021
|
+
- **Layout:** Grid, Surface, PageHeader, ResourceListPage
|
|
4022
|
+
- **Other:** Label, Link, SensitiveInput, Table
|