@cloudflare/kumo 2.0.1 → 2.0.2
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 +8 -0
- package/ai/component-registry.json +210 -13
- package/ai/component-registry.md +290 -4
- package/dist/.build-complete +1 -1
- package/dist/chunks/{collapsible-k8urhi16pg90jvxa.js → collapsible-nlp2jvcyuzxmq28o.js} +12 -11
- package/dist/chunks/{collapsible-k8urhi16pg90jvxa.js.map → collapsible-nlp2jvcyuzxmq28o.js.map} +1 -1
- package/dist/components/collapsible.js +1 -1
- package/dist/index.js +1 -1
- package/dist/src/components/collapsible/collapsible.d.ts +1 -1
- package/dist/src/components/collapsible/collapsible.d.ts.map +1 -1
- package/package.json +1 -1
- package/scripts/component-registry/index.test.ts +42 -0
- package/scripts/component-registry/index.ts +18 -4
- package/scripts/component-registry/metadata.ts +221 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# @cloudflare/kumo
|
|
2
2
|
|
|
3
|
+
## 2.0.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- fbf3eef: Forward all Base UI Panel props (including `keepMounted` and `hiddenUntilFound`) through `Collapsible.DefaultPanel`. Previously these were silently dropped because `DefaultPanel` used a standalone props interface instead of extending `BasePanelProps`.
|
|
8
|
+
- 40491c2: Fix registry codegen to match demo examples when component export name differs from directory name (e.g. DropdownMenu vs dropdown). This restores missing examples for DropdownMenu and other affected components.
|
|
9
|
+
- 3427221: TooltipProvider props (`delay`, `closeDelay`, `timeout`) are now shown in the Tooltip component's API Reference on the docs site.
|
|
10
|
+
|
|
3
11
|
## 2.0.1
|
|
4
12
|
|
|
5
13
|
### Patch Changes
|
|
@@ -2123,7 +2123,7 @@
|
|
|
2123
2123
|
"<div className=\"flex flex-wrap items-center gap-8\">\n <CloudflareLogo className=\"w-28\" color=\"color\" />\n <div className=\"rounded-lg bg-white p-4\">\n <CloudflareLogo className=\"w-28\" color=\"black\" />\n </div>\n <div className=\"rounded-lg bg-black p-4\">\n <CloudflareLogo className=\"w-28\" color=\"white\" />\n </div>\n </div>",
|
|
2124
2124
|
"<div className=\"flex flex-wrap items-center gap-8\">\n <CloudflareLogo variant=\"glyph\" className=\"w-12\" color=\"color\" />\n <div className=\"rounded-lg bg-white p-4\">\n <CloudflareLogo variant=\"glyph\" className=\"w-12\" color=\"black\" />\n </div>\n <div className=\"rounded-lg bg-black p-4\">\n <CloudflareLogo variant=\"glyph\" className=\"w-12\" color=\"white\" />\n </div>\n </div>",
|
|
2125
2125
|
"<div className=\"flex flex-wrap items-end gap-6\">\n <CloudflareLogo className=\"w-20\" />\n <CloudflareLogo className=\"w-28\" />\n <CloudflareLogo className=\"w-44\" />\n </div>",
|
|
2126
|
-
"<div className=\"flex items-center gap-4\">\n <DropdownMenu>\n <DropdownMenu.Trigger>\n <button\n type=\"button\"\n className=\"flex items-center gap-2 rounded-lg bg-black px-4 py-3 text-white transition-opacity hover:opacity-80\"\n >\n <CloudflareLogo variant=\"glyph\" color=\"white\" className=\"w-8\" />\n <span className=\"font-medium\">Logo</span>\n </button>\n </DropdownMenu.Trigger>\n <DropdownMenu.Content>\n <DropdownMenu.Item\n icon={CloudIcon}\n
|
|
2126
|
+
"<div className=\"flex items-center gap-4\">\n <DropdownMenu>\n <DropdownMenu.Trigger>\n <button\n type=\"button\"\n className=\"flex items-center gap-2 rounded-lg bg-black px-4 py-3 text-white transition-opacity hover:opacity-80\"\n >\n <CloudflareLogo variant=\"glyph\" color=\"white\" className=\"w-8\" />\n <span className=\"font-medium\">Logo</span>\n </button>\n </DropdownMenu.Trigger>\n <DropdownMenu.Content>\n <DropdownMenu.Item\n icon={CloudIcon}\n onClick={() =>\n copyToClipboard(\n generateCloudflareLogoSvg({ variant: \"glyph\" }),\n \"glyph\",\n )\n }\n >\n {copied === \"glyph\" ? \"Copied!\" : \"Copy logo as SVG\"}\n </DropdownMenu.Item>\n <DropdownMenu.Item\n icon={CodeIcon}\n onClick={() =>\n copyToClipboard(\n generateCloudflareLogoSvg({ variant: \"full\" }),\n \"full\",\n )\n }\n >\n {copied === \"full\" ? \"Copied!\" : \"Copy full logo as SVG\"}\n </DropdownMenu.Item>\n <DropdownMenu.Item\n icon={DownloadSimpleIcon}\n onClick={() =>\n window.open(\n \"https://www.cloudflare.com/press-kit/\",\n \"_blank\",\n \"noopener\",\n )\n }\n >\n Download brand assets\n </DropdownMenu.Item>\n <DropdownMenu.Separator />\n <DropdownMenu.Item\n icon={ArrowSquareOutIcon}\n onClick={() =>\n window.open(\n \"https://www.cloudflare.com/brand-assets/\",\n \"_blank\",\n \"noopener\",\n )\n }\n >\n Visit brand guidelines\n </DropdownMenu.Item>\n </DropdownMenu.Content>\n </DropdownMenu>\n\n <span className=\"text-sm text-kumo-subtle\">\n Click to open the brand assets menu\n </span>\n </div>",
|
|
2127
2127
|
"<PoweredByCloudflare />",
|
|
2128
2128
|
"<div className=\"flex flex-wrap items-center gap-4\">\n <PoweredByCloudflare />\n <PoweredByCloudflare color=\"black\" />\n <div className=\"rounded-lg bg-black p-3\">\n <PoweredByCloudflare color=\"white\" />\n </div>\n </div>",
|
|
2129
2129
|
"<footer className=\"flex w-full items-center justify-between rounded-lg border border-kumo-hairline bg-kumo-elevated px-6 py-4\">\n <span className=\"text-sm text-kumo-subtle\">\n © 2026 Your Company. All rights reserved.\n </span>\n <PoweredByCloudflare />\n </footer>"
|
|
@@ -2242,6 +2242,7 @@
|
|
|
2242
2242
|
"<div className=\"w-full\">\n <Collapsible.Root open={isOpen} onOpenChange={setIsOpen}>\n <Collapsible.DefaultTrigger>What is Kumo?</Collapsible.DefaultTrigger>\n <Collapsible.DefaultPanel>\n <Text>Kumo is Cloudflare's new design system.</Text>\n </Collapsible.DefaultPanel>\n </Collapsible.Root>\n </div>",
|
|
2243
2243
|
"<div className=\"w-full space-y-2\">\n <Collapsible.Root open={open1} onOpenChange={setOpen1}>\n <Collapsible.DefaultTrigger>What is Kumo?</Collapsible.DefaultTrigger>\n <Collapsible.DefaultPanel>\n <Text>Kumo is Cloudflare's new design system.</Text>\n </Collapsible.DefaultPanel>\n </Collapsible.Root>\n <Collapsible.Root open={open2} onOpenChange={setOpen2}>\n <Collapsible.DefaultTrigger>How do I use it?</Collapsible.DefaultTrigger>\n <Collapsible.DefaultPanel>\n <Text>Install the components and import them into your project.</Text>\n </Collapsible.DefaultPanel>\n </Collapsible.Root>\n <Collapsible.Root open={open3} onOpenChange={setOpen3}>\n <Collapsible.DefaultTrigger>Is it open source?</Collapsible.DefaultTrigger>\n <Collapsible.DefaultPanel>\n <Text>Check the repository for license information.</Text>\n </Collapsible.DefaultPanel>\n </Collapsible.Root>\n </div>",
|
|
2244
2244
|
"<div className=\"w-full\">\n <Collapsible.Root open={isOpen} onOpenChange={setIsOpen}>\n <Collapsible.Trigger\n render={<Button variant=\"secondary\" size=\"sm\" />}\n >\n {isOpen ? \"Hide details\" : \"Show details\"}\n </Collapsible.Trigger>\n <Collapsible.Panel className=\"mt-3 rounded-lg bg-kumo-tint p-4\">\n <Text>\n This panel uses custom styling instead of the default border-left accent.\n </Text>\n </Collapsible.Panel>\n </Collapsible.Root>\n </div>",
|
|
2245
|
+
"<div className=\"w-full space-y-4\">\n <Collapsible.Root open={isOpen} onOpenChange={setIsOpen}>\n <Collapsible.DefaultTrigger>Edit details</Collapsible.DefaultTrigger>\n <Collapsible.DefaultPanel keepMounted>\n <Text>\n Type something below, then collapse and re-open — your input is\n preserved because the panel stays mounted.\n </Text>\n <Input label=\"Name\" placeholder=\"Type here…\" />\n </Collapsible.DefaultPanel>\n </Collapsible.Root>\n </div>",
|
|
2245
2246
|
"<div className=\"w-full space-y-2\">\n {items.map((item, i) => (\n <Collapsible.Root\n key={i}\n open={activeIndex === i}\n onOpenChange={(open) => setActiveIndex(open ? i : null)}\n >\n <Collapsible.DefaultTrigger>{item.title}</Collapsible.DefaultTrigger>\n <Collapsible.DefaultPanel>\n <Text>{item.content}</Text>\n </Collapsible.DefaultPanel>\n </Collapsible.Root>\n ))}\n </div>"
|
|
2246
2247
|
],
|
|
2247
2248
|
"colors": [
|
|
@@ -2900,7 +2901,15 @@
|
|
|
2900
2901
|
"default": "default"
|
|
2901
2902
|
}
|
|
2902
2903
|
},
|
|
2903
|
-
"examples": [
|
|
2904
|
+
"examples": [
|
|
2905
|
+
"<DropdownMenu>\n <DropdownMenu.Trigger render={<Button icon={PlusIcon}>Add</Button>} />\n <DropdownMenu.Content>\n <DropdownMenu.Item>Worker</DropdownMenu.Item>\n <DropdownMenu.Item>Pages</DropdownMenu.Item>\n <DropdownMenu.Item>KV Namespace</DropdownMenu.Item>\n </DropdownMenu.Content>\n </DropdownMenu>",
|
|
2906
|
+
"<DropdownMenu>\n <DropdownMenu.Trigger render={<Button>View Options</Button>} />\n <DropdownMenu.Content>\n <DropdownMenu.Group>\n <DropdownMenu.Label>Display</DropdownMenu.Label>\n <DropdownMenu.CheckboxItem\n checked={showSidebar}\n onCheckedChange={setShowSidebar}\n >\n Show sidebar\n </DropdownMenu.CheckboxItem>\n <DropdownMenu.CheckboxItem\n checked={showLineNumbers}\n onCheckedChange={setShowLineNumbers}\n >\n Show line numbers\n </DropdownMenu.CheckboxItem>\n <DropdownMenu.CheckboxItem\n checked={wordWrap}\n onCheckedChange={setWordWrap}\n >\n Word wrap\n </DropdownMenu.CheckboxItem>\n </DropdownMenu.Group>\n </DropdownMenu.Content>\n </DropdownMenu>",
|
|
2907
|
+
"<DropdownMenu>\n <DropdownMenu.Trigger render={<Button icon={UserIcon}>Account</Button>} />\n <DropdownMenu.Content>\n <DropdownMenu.Item icon={UserIcon}>Profile</DropdownMenu.Item>\n <DropdownMenu.Item icon={CreditCardIcon}>Billing</DropdownMenu.Item>\n <DropdownMenu.Item icon={MoonIcon}>Dark mode</DropdownMenu.Item>\n\n {/* Language submenu with RadioGroup */}\n <DropdownMenu.Sub>\n <DropdownMenu.SubTrigger>Language</DropdownMenu.SubTrigger>\n <DropdownMenu.SubContent>\n <DropdownMenu.Group>\n <DropdownMenu.RadioGroup\n value={language}\n onValueChange={setLanguage}\n >\n {languages.map((lang) => (\n <DropdownMenu.RadioItem key={lang.code} value={lang.code}>\n {lang.label}\n <DropdownMenu.RadioItemIndicator />\n </DropdownMenu.RadioItem>\n ))}\n </DropdownMenu.RadioGroup>\n </DropdownMenu.Group>\n </DropdownMenu.SubContent>\n </DropdownMenu.Sub>\n\n {/* Timezone submenu with RadioGroup */}\n <DropdownMenu.Sub>\n <DropdownMenu.SubTrigger>Set Timezone</DropdownMenu.SubTrigger>\n <DropdownMenu.SubContent>\n <DropdownMenu.Group>\n <DropdownMenu.RadioGroup\n value={timezone}\n onValueChange={setTimezone}\n >\n {timezones.map((tz) => (\n <DropdownMenu.RadioItem key={tz.value} value={tz.value}>\n {tz.label}\n <DropdownMenu.RadioItemIndicator />\n </DropdownMenu.RadioItem>\n ))}\n </DropdownMenu.RadioGroup>\n </DropdownMenu.Group>\n </DropdownMenu.SubContent>\n </DropdownMenu.Sub>\n\n <DropdownMenu.Separator />\n <DropdownMenu.Item icon={SignOutIcon} variant=\"danger\">\n Log out\n </DropdownMenu.Item>\n </DropdownMenu.Content>\n </DropdownMenu>",
|
|
2908
|
+
"<DropdownMenu>\n <DropdownMenu.Trigger render={<Button>Edit</Button>} />\n <DropdownMenu.Content>\n <DropdownMenu.Item icon={PencilSimpleIcon}>Rename</DropdownMenu.Item>\n <DropdownMenu.Item icon={CopyIcon}>Duplicate</DropdownMenu.Item>\n <DropdownMenu.Separator />\n <DropdownMenu.Item inset>Move to folder</DropdownMenu.Item>\n <DropdownMenu.Item inset>Add to favorites</DropdownMenu.Item>\n <DropdownMenu.Separator />\n <DropdownMenu.Item icon={TrashIcon} variant=\"danger\">\n Delete\n </DropdownMenu.Item>\n </DropdownMenu.Content>\n </DropdownMenu>",
|
|
2909
|
+
"<div className=\"flex flex-col items-start gap-2\">\n <DropdownMenu>\n <DropdownMenu.Trigger render={<Button>Actions</Button>} />\n <DropdownMenu.Content>\n <DropdownMenu.Item\n icon={CopyIcon}\n onClick={() => setLastAction(\"Duplicated\")}\n >\n Duplicate\n </DropdownMenu.Item>\n <DropdownMenu.Item\n icon={PencilSimpleIcon}\n onClick={() => setLastAction(\"Renamed\")}\n >\n Rename\n </DropdownMenu.Item>\n <DropdownMenu.Separator />\n <DropdownMenu.Item\n icon={TrashIcon}\n variant=\"danger\"\n onClick={() => setLastAction(\"Deleted\")}\n >\n Delete\n </DropdownMenu.Item>\n </DropdownMenu.Content>\n </DropdownMenu>\n {lastAction && (\n <p className=\"text-sm text-kumo-subtle\">\n Last action: <span className=\"text-kumo-default\">{lastAction}</span>\n </p>\n )}\n </div>",
|
|
2910
|
+
"<DropdownMenu>\n <DropdownMenu.Trigger\n render={<button type=\"button\" className=\"rounded-full\" />}\n >\n <span className=\"flex h-8 w-8 items-center justify-center rounded-full bg-kumo-brand text-sm font-medium text-white\">\n MR\n </span>\n </DropdownMenu.Trigger>\n <DropdownMenu.Content>\n <DropdownMenu.Item icon={UserIcon}>Profile</DropdownMenu.Item>\n <DropdownMenu.Item icon={GearIcon}>Settings</DropdownMenu.Item>\n <DropdownMenu.Separator />\n <DropdownMenu.Item icon={SignOutIcon} variant=\"danger\">\n Log out\n </DropdownMenu.Item>\n </DropdownMenu.Content>\n </DropdownMenu>",
|
|
2911
|
+
"<DropdownMenu>\n <DropdownMenu.Trigger render={<Button>Resources</Button>} />\n <DropdownMenu.Content>\n <DropdownMenu.LinkItem href=\"/settings\" icon={GearIcon}>\n Settings\n </DropdownMenu.LinkItem>\n <DropdownMenu.LinkItem href=\"/docs\" icon={BookOpenIcon}>\n Documentation\n </DropdownMenu.LinkItem>\n <DropdownMenu.Separator />\n <DropdownMenu.LinkItem\n href=\"https://developers.cloudflare.com\"\n target=\"_blank\"\n icon={ArrowSquareOutIcon}\n >\n Developer Docs\n </DropdownMenu.LinkItem>\n </DropdownMenu.Content>\n </DropdownMenu>"
|
|
2912
|
+
],
|
|
2904
2913
|
"colors": [
|
|
2905
2914
|
"bg-kumo-control",
|
|
2906
2915
|
"bg-kumo-danger",
|
|
@@ -2936,7 +2945,16 @@
|
|
|
2936
2945
|
"SubTrigger": {
|
|
2937
2946
|
"name": "SubTrigger",
|
|
2938
2947
|
"description": "SubTrigger sub-component",
|
|
2939
|
-
"props": {
|
|
2948
|
+
"props": {
|
|
2949
|
+
"icon": {
|
|
2950
|
+
"type": "Icon",
|
|
2951
|
+
"description": "Icon displayed before the label."
|
|
2952
|
+
},
|
|
2953
|
+
"inset": {
|
|
2954
|
+
"type": "boolean",
|
|
2955
|
+
"description": "Adds left padding to align with items that have icons."
|
|
2956
|
+
}
|
|
2957
|
+
}
|
|
2940
2958
|
},
|
|
2941
2959
|
"SubContent": {
|
|
2942
2960
|
"name": "SubContent",
|
|
@@ -2946,34 +2964,164 @@
|
|
|
2946
2964
|
"Content": {
|
|
2947
2965
|
"name": "Content",
|
|
2948
2966
|
"description": "Content sub-component",
|
|
2949
|
-
"props": {
|
|
2967
|
+
"props": {
|
|
2968
|
+
"sideOffset": {
|
|
2969
|
+
"type": "number",
|
|
2970
|
+
"description": "Distance in pixels from the trigger.",
|
|
2971
|
+
"default": "8"
|
|
2972
|
+
},
|
|
2973
|
+
"container": {
|
|
2974
|
+
"type": "PortalContainer",
|
|
2975
|
+
"description": "Container element for the portal. Use this to render inside a Shadow DOM or custom container."
|
|
2976
|
+
}
|
|
2977
|
+
}
|
|
2950
2978
|
},
|
|
2951
2979
|
"Item": {
|
|
2952
2980
|
"name": "Item",
|
|
2953
2981
|
"description": "Item sub-component",
|
|
2954
|
-
"props": {
|
|
2982
|
+
"props": {
|
|
2983
|
+
"icon": {
|
|
2984
|
+
"type": "Icon | ReactNode",
|
|
2985
|
+
"description": "Icon displayed before the label."
|
|
2986
|
+
},
|
|
2987
|
+
"variant": {
|
|
2988
|
+
"type": "\"default\" | \"danger\"",
|
|
2989
|
+
"description": "Visual style of the item.",
|
|
2990
|
+
"default": "\"default\""
|
|
2991
|
+
},
|
|
2992
|
+
"selected": {
|
|
2993
|
+
"type": "boolean",
|
|
2994
|
+
"description": "Shows a check mark indicator when true."
|
|
2995
|
+
},
|
|
2996
|
+
"inset": {
|
|
2997
|
+
"type": "boolean",
|
|
2998
|
+
"description": "Adds left padding to align with items that have icons."
|
|
2999
|
+
},
|
|
3000
|
+
"onClick": {
|
|
3001
|
+
"type": "(event: React.MouseEvent) => void",
|
|
3002
|
+
"description": "Callback when the item is clicked."
|
|
3003
|
+
},
|
|
3004
|
+
"closeOnClick": {
|
|
3005
|
+
"type": "boolean",
|
|
3006
|
+
"description": "Whether the menu closes after clicking this item.",
|
|
3007
|
+
"default": "true"
|
|
3008
|
+
},
|
|
3009
|
+
"disabled": {
|
|
3010
|
+
"type": "boolean",
|
|
3011
|
+
"description": "When true, the item cannot be interacted with."
|
|
3012
|
+
}
|
|
3013
|
+
}
|
|
2955
3014
|
},
|
|
2956
3015
|
"LinkItem": {
|
|
2957
3016
|
"name": "LinkItem",
|
|
2958
3017
|
"description": "LinkItem sub-component",
|
|
2959
|
-
"props": {
|
|
3018
|
+
"props": {
|
|
3019
|
+
"href": {
|
|
3020
|
+
"type": "string",
|
|
3021
|
+
"description": "URL to navigate to when clicked."
|
|
3022
|
+
},
|
|
3023
|
+
"icon": {
|
|
3024
|
+
"type": "Icon | ReactNode",
|
|
3025
|
+
"description": "Icon displayed before the label."
|
|
3026
|
+
},
|
|
3027
|
+
"variant": {
|
|
3028
|
+
"type": "\"default\" | \"danger\"",
|
|
3029
|
+
"description": "Visual style of the item.",
|
|
3030
|
+
"default": "\"default\""
|
|
3031
|
+
},
|
|
3032
|
+
"inset": {
|
|
3033
|
+
"type": "boolean",
|
|
3034
|
+
"description": "Adds left padding to align with items that have icons."
|
|
3035
|
+
},
|
|
3036
|
+
"target": {
|
|
3037
|
+
"type": "string",
|
|
3038
|
+
"description": "Link target attribute (e.g. \"_blank\" for new tab)."
|
|
3039
|
+
},
|
|
3040
|
+
"render": {
|
|
3041
|
+
"type": "ReactElement | ((props, state) => ReactElement)",
|
|
3042
|
+
"description": "Custom element to render as the link. Use to integrate with framework routers (e.g. Next.js Link)."
|
|
3043
|
+
}
|
|
3044
|
+
}
|
|
2960
3045
|
},
|
|
2961
3046
|
"CheckboxItem": {
|
|
2962
3047
|
"name": "CheckboxItem",
|
|
2963
3048
|
"description": "CheckboxItem sub-component",
|
|
2964
|
-
"props": {
|
|
3049
|
+
"props": {
|
|
3050
|
+
"checked": {
|
|
3051
|
+
"type": "boolean",
|
|
3052
|
+
"description": "Whether the item is checked."
|
|
3053
|
+
},
|
|
3054
|
+
"defaultChecked": {
|
|
3055
|
+
"type": "boolean",
|
|
3056
|
+
"description": "Whether the item is initially checked (uncontrolled).",
|
|
3057
|
+
"default": "false"
|
|
3058
|
+
},
|
|
3059
|
+
"onCheckedChange": {
|
|
3060
|
+
"type": "(checked: boolean, event: ChangeEventDetails) => void",
|
|
3061
|
+
"description": "Callback when the checked state changes."
|
|
3062
|
+
},
|
|
3063
|
+
"closeOnClick": {
|
|
3064
|
+
"type": "boolean",
|
|
3065
|
+
"description": "Whether the menu closes after clicking this item.",
|
|
3066
|
+
"default": "false"
|
|
3067
|
+
},
|
|
3068
|
+
"disabled": {
|
|
3069
|
+
"type": "boolean",
|
|
3070
|
+
"description": "When true, the item cannot be interacted with."
|
|
3071
|
+
}
|
|
3072
|
+
}
|
|
2965
3073
|
},
|
|
2966
3074
|
"RadioGroup": {
|
|
2967
3075
|
"name": "RadioGroup",
|
|
2968
3076
|
"description": "RadioGroup sub-component (wraps DropdownMenuPrimitive)",
|
|
2969
|
-
"props": {
|
|
3077
|
+
"props": {
|
|
3078
|
+
"value": {
|
|
3079
|
+
"type": "any",
|
|
3080
|
+
"description": "The controlled value of the currently selected radio item."
|
|
3081
|
+
},
|
|
3082
|
+
"defaultValue": {
|
|
3083
|
+
"type": "any",
|
|
3084
|
+
"description": "The initially selected value (uncontrolled)."
|
|
3085
|
+
},
|
|
3086
|
+
"onValueChange": {
|
|
3087
|
+
"type": "(value: any, event: ChangeEventDetails) => void",
|
|
3088
|
+
"description": "Callback when the selected value changes."
|
|
3089
|
+
},
|
|
3090
|
+
"disabled": {
|
|
3091
|
+
"type": "boolean",
|
|
3092
|
+
"description": "When true, all radio items in the group are disabled."
|
|
3093
|
+
}
|
|
3094
|
+
},
|
|
2970
3095
|
"isPassThrough": true,
|
|
2971
3096
|
"baseComponent": "DropdownMenuPrimitive.RadioGroup"
|
|
2972
3097
|
},
|
|
2973
3098
|
"RadioItem": {
|
|
2974
3099
|
"name": "RadioItem",
|
|
2975
3100
|
"description": "RadioItem sub-component",
|
|
2976
|
-
"props": {
|
|
3101
|
+
"props": {
|
|
3102
|
+
"value": {
|
|
3103
|
+
"type": "any",
|
|
3104
|
+
"required": true,
|
|
3105
|
+
"description": "The value of this radio item."
|
|
3106
|
+
},
|
|
3107
|
+
"icon": {
|
|
3108
|
+
"type": "Icon | ReactNode",
|
|
3109
|
+
"description": "Icon displayed before the label."
|
|
3110
|
+
},
|
|
3111
|
+
"inset": {
|
|
3112
|
+
"type": "boolean",
|
|
3113
|
+
"description": "Adds left padding to align with items that have icons."
|
|
3114
|
+
},
|
|
3115
|
+
"closeOnClick": {
|
|
3116
|
+
"type": "boolean",
|
|
3117
|
+
"description": "Whether the menu closes after clicking this item.",
|
|
3118
|
+
"default": "false"
|
|
3119
|
+
},
|
|
3120
|
+
"disabled": {
|
|
3121
|
+
"type": "boolean",
|
|
3122
|
+
"description": "When true, the item cannot be interacted with."
|
|
3123
|
+
}
|
|
3124
|
+
}
|
|
2977
3125
|
},
|
|
2978
3126
|
"RadioItemIndicator": {
|
|
2979
3127
|
"name": "RadioItemIndicator",
|
|
@@ -2983,7 +3131,12 @@
|
|
|
2983
3131
|
"Label": {
|
|
2984
3132
|
"name": "Label",
|
|
2985
3133
|
"description": "Label sub-component",
|
|
2986
|
-
"props": {
|
|
3134
|
+
"props": {
|
|
3135
|
+
"inset": {
|
|
3136
|
+
"type": "boolean",
|
|
3137
|
+
"description": "Adds left padding to align with items that have icons."
|
|
3138
|
+
}
|
|
3139
|
+
}
|
|
2987
3140
|
},
|
|
2988
3141
|
"Separator": {
|
|
2989
3142
|
"name": "Separator",
|
|
@@ -5897,7 +6050,19 @@
|
|
|
5897
6050
|
"description": "Child elements"
|
|
5898
6051
|
}
|
|
5899
6052
|
},
|
|
5900
|
-
"examples": [
|
|
6053
|
+
"examples": [
|
|
6054
|
+
"<Toasty>\n <ToastTriggerButton />\n </Toasty>",
|
|
6055
|
+
"<Toasty>\n <ToastTitleOnlyButton />\n </Toasty>",
|
|
6056
|
+
"<Toasty>\n <ToastDescriptionOnlyButton />\n </Toasty>",
|
|
6057
|
+
"<Toasty>\n <ToastSuccessButton />\n </Toasty>",
|
|
6058
|
+
"<Toasty>\n <ToastMultipleButton />\n </Toasty>",
|
|
6059
|
+
"<Toasty>\n <ToastErrorButton />\n </Toasty>",
|
|
6060
|
+
"<Toasty>\n <ToastWarningButton />\n </Toasty>",
|
|
6061
|
+
"<Toasty>\n <ToastInfoButton />\n </Toasty>",
|
|
6062
|
+
"<Toasty>\n <ToastCustomContentButton />\n </Toasty>",
|
|
6063
|
+
"<Toasty>\n <ToastActionsButton />\n </Toasty>",
|
|
6064
|
+
"<Toasty>\n <ToastPromiseButton />\n </Toasty>"
|
|
6065
|
+
],
|
|
5901
6066
|
"colors": [
|
|
5902
6067
|
"bg-kumo-base",
|
|
5903
6068
|
"bg-kumo-contrast",
|
|
@@ -6003,7 +6168,35 @@
|
|
|
6003
6168
|
"fill-kumo-tip-stroke",
|
|
6004
6169
|
"outline-kumo-fill",
|
|
6005
6170
|
"text-kumo-default"
|
|
6006
|
-
]
|
|
6171
|
+
],
|
|
6172
|
+
"subComponents": {
|
|
6173
|
+
"Provider": {
|
|
6174
|
+
"name": "Provider",
|
|
6175
|
+
"description": "Groups multiple tooltips so that after the first tooltip is shown, switching to another skips the open delay. Place once at your app root or layout.",
|
|
6176
|
+
"props": {
|
|
6177
|
+
"delay": {
|
|
6178
|
+
"type": "number",
|
|
6179
|
+
"description": "How long to wait (ms) before opening a tooltip once the pointer enters the trigger.",
|
|
6180
|
+
"default": "600"
|
|
6181
|
+
},
|
|
6182
|
+
"closeDelay": {
|
|
6183
|
+
"type": "number",
|
|
6184
|
+
"description": "How long to wait (ms) before closing a tooltip.",
|
|
6185
|
+
"default": "0"
|
|
6186
|
+
},
|
|
6187
|
+
"timeout": {
|
|
6188
|
+
"type": "number",
|
|
6189
|
+
"description": "Grace period (ms) during which a just-closed tooltip's delay is skipped when another tooltip opens.",
|
|
6190
|
+
"default": "400"
|
|
6191
|
+
}
|
|
6192
|
+
},
|
|
6193
|
+
"isPassThrough": true,
|
|
6194
|
+
"baseComponent": "TooltipBase.Provider",
|
|
6195
|
+
"usageExamples": [
|
|
6196
|
+
"<TooltipProvider>\n <App />\n</TooltipProvider>"
|
|
6197
|
+
]
|
|
6198
|
+
}
|
|
6199
|
+
}
|
|
6007
6200
|
},
|
|
6008
6201
|
"InputArea": {
|
|
6009
6202
|
"name": "InputArea",
|
|
@@ -6237,7 +6430,11 @@
|
|
|
6237
6430
|
"optional": true
|
|
6238
6431
|
}
|
|
6239
6432
|
},
|
|
6240
|
-
"examples": [
|
|
6433
|
+
"examples": [
|
|
6434
|
+
"<ResourceListPage\n title=\"Databases\"\n description=\"Manage your database instances and configurations\"\n icon={<DatabaseIcon size={32} className=\"text-kumo-subtle\" />}\n >\n <Surface className=\"p-6\">\n <p>Main content area - your resource list would go here</p>\n </Surface>\n </ResourceListPage>",
|
|
6435
|
+
"<ResourceListPage\n title=\"API Keys\"\n description=\"Create and manage API keys for your applications\"\n usage={\n <Surface className=\"p-4\">\n <h3 className=\"mb-2 font-semibold\">Quick Start</h3>\n <p className=\"mb-3 text-sm text-kumo-subtle\">\n Generate an API key to authenticate your requests\n </p>\n <Code\n lang=\"bash\"\n code='curl -H \"Authorization: Bearer YOUR_API_KEY\" https://api.example.com'\n />\n </Surface>\n }\n >\n <Surface className=\"p-6\">\n <p>API keys list would appear here</p>\n </Surface>\n </ResourceListPage>",
|
|
6436
|
+
"<ResourceListPage\n title=\"KV Namespaces\"\n description=\"Store key-value data globally with low-latency access\"\n icon={<DatabaseIcon size={32} className=\"text-kumo-subtle\" />}\n usage={\n <Surface className=\"p-4\">\n <h3 className=\"mb-2 font-semibold\">Usage Example</h3>\n <Code\n lang=\"ts\"\n code={`// Read from KV\nconst value = await KV.get('key');\n\n// Write to KV\nawait KV.put('key', 'value');`}\n />\n </Surface>\n }\n additionalContent={\n <Surface className=\"p-4\">\n <h3 className=\"mb-2 font-semibold\">Learn More</h3>\n <p className=\"text-sm text-kumo-subtle\">\n Check out our documentation to learn more about KV storage.\n </p>\n </Surface>\n }\n >\n <div className=\"space-y-4\">\n <Surface className=\"p-6\">\n <h4 className=\"mb-2 font-semibold\">production-kv</h4>\n <p className=\"text-sm text-kumo-subtle\">Created 2 days ago</p>\n </Surface>\n <Surface className=\"p-6\">\n <h4 className=\"mb-2 font-semibold\">staging-kv</h4>\n <p className=\"text-sm text-kumo-subtle\">Created 1 week ago</p>\n </Surface>\n </div>\n </ResourceListPage>"
|
|
6437
|
+
],
|
|
6241
6438
|
"colors": [
|
|
6242
6439
|
"bg-kumo-overlay",
|
|
6243
6440
|
"text-kumo-subtle"
|
package/ai/component-registry.md
CHANGED
|
@@ -1315,7 +1315,7 @@ Cloudflare logo component.
|
|
|
1315
1315
|
<DropdownMenu.Content>
|
|
1316
1316
|
<DropdownMenu.Item
|
|
1317
1317
|
icon={CloudIcon}
|
|
1318
|
-
|
|
1318
|
+
onClick={() =>
|
|
1319
1319
|
copyToClipboard(
|
|
1320
1320
|
generateCloudflareLogoSvg({ variant: "glyph" }),
|
|
1321
1321
|
"glyph",
|
|
@@ -1326,7 +1326,7 @@ Cloudflare logo component.
|
|
|
1326
1326
|
</DropdownMenu.Item>
|
|
1327
1327
|
<DropdownMenu.Item
|
|
1328
1328
|
icon={CodeIcon}
|
|
1329
|
-
|
|
1329
|
+
onClick={() =>
|
|
1330
1330
|
copyToClipboard(
|
|
1331
1331
|
generateCloudflareLogoSvg({ variant: "full" }),
|
|
1332
1332
|
"full",
|
|
@@ -1337,7 +1337,7 @@ Cloudflare logo component.
|
|
|
1337
1337
|
</DropdownMenu.Item>
|
|
1338
1338
|
<DropdownMenu.Item
|
|
1339
1339
|
icon={DownloadSimpleIcon}
|
|
1340
|
-
|
|
1340
|
+
onClick={() =>
|
|
1341
1341
|
window.open(
|
|
1342
1342
|
"https://www.cloudflare.com/press-kit/",
|
|
1343
1343
|
"_blank",
|
|
@@ -1350,7 +1350,7 @@ Cloudflare logo component.
|
|
|
1350
1350
|
<DropdownMenu.Separator />
|
|
1351
1351
|
<DropdownMenu.Item
|
|
1352
1352
|
icon={ArrowSquareOutIcon}
|
|
1353
|
-
|
|
1353
|
+
onClick={() =>
|
|
1354
1354
|
window.open(
|
|
1355
1355
|
"https://www.cloudflare.com/brand-assets/",
|
|
1356
1356
|
"_blank",
|
|
@@ -1560,6 +1560,21 @@ Props:
|
|
|
1560
1560
|
</div>
|
|
1561
1561
|
```
|
|
1562
1562
|
|
|
1563
|
+
```tsx
|
|
1564
|
+
<div className="w-full space-y-4">
|
|
1565
|
+
<Collapsible.Root open={isOpen} onOpenChange={setIsOpen}>
|
|
1566
|
+
<Collapsible.DefaultTrigger>Edit details</Collapsible.DefaultTrigger>
|
|
1567
|
+
<Collapsible.DefaultPanel keepMounted>
|
|
1568
|
+
<Text>
|
|
1569
|
+
Type something below, then collapse and re-open — your input is
|
|
1570
|
+
preserved because the panel stays mounted.
|
|
1571
|
+
</Text>
|
|
1572
|
+
<Input label="Name" placeholder="Type here…" />
|
|
1573
|
+
</Collapsible.DefaultPanel>
|
|
1574
|
+
</Collapsible.Root>
|
|
1575
|
+
</div>
|
|
1576
|
+
```
|
|
1577
|
+
|
|
1563
1578
|
```tsx
|
|
1564
1579
|
<div className="w-full space-y-2">
|
|
1565
1580
|
{items.map((item, i) => (
|
|
@@ -2932,6 +2947,10 @@ Sub sub-component (wraps DropdownMenuPrimitive)
|
|
|
2932
2947
|
|
|
2933
2948
|
SubTrigger sub-component
|
|
2934
2949
|
|
|
2950
|
+
Props:
|
|
2951
|
+
- `icon`: Icon - Icon displayed before the label.
|
|
2952
|
+
- `inset`: boolean - Adds left padding to align with items that have icons.
|
|
2953
|
+
|
|
2935
2954
|
#### DropdownMenu.SubContent
|
|
2936
2955
|
|
|
2937
2956
|
SubContent sub-component
|
|
@@ -2940,26 +2959,67 @@ SubContent sub-component
|
|
|
2940
2959
|
|
|
2941
2960
|
Content sub-component
|
|
2942
2961
|
|
|
2962
|
+
Props:
|
|
2963
|
+
- `sideOffset`: number [default: 8] - Distance in pixels from the trigger.
|
|
2964
|
+
- `container`: PortalContainer - Container element for the portal. Use this to render inside a Shadow DOM or custom container.
|
|
2965
|
+
|
|
2943
2966
|
#### DropdownMenu.Item
|
|
2944
2967
|
|
|
2945
2968
|
Item sub-component
|
|
2946
2969
|
|
|
2970
|
+
Props:
|
|
2971
|
+
- `icon`: Icon | ReactNode - Icon displayed before the label.
|
|
2972
|
+
- `variant`: "default" | "danger" [default: "default"] - Visual style of the item.
|
|
2973
|
+
- `selected`: boolean - Shows a check mark indicator when true.
|
|
2974
|
+
- `inset`: boolean - Adds left padding to align with items that have icons.
|
|
2975
|
+
- `onClick`: (event: React.MouseEvent) => void - Callback when the item is clicked.
|
|
2976
|
+
- `closeOnClick`: boolean [default: true] - Whether the menu closes after clicking this item.
|
|
2977
|
+
- `disabled`: boolean - When true, the item cannot be interacted with.
|
|
2978
|
+
|
|
2947
2979
|
#### DropdownMenu.LinkItem
|
|
2948
2980
|
|
|
2949
2981
|
LinkItem sub-component
|
|
2950
2982
|
|
|
2983
|
+
Props:
|
|
2984
|
+
- `href`: string - URL to navigate to when clicked.
|
|
2985
|
+
- `icon`: Icon | ReactNode - Icon displayed before the label.
|
|
2986
|
+
- `variant`: "default" | "danger" [default: "default"] - Visual style of the item.
|
|
2987
|
+
- `inset`: boolean - Adds left padding to align with items that have icons.
|
|
2988
|
+
- `target`: string - Link target attribute (e.g. "_blank" for new tab).
|
|
2989
|
+
- `render`: ReactElement | ((props, state) => ReactElement) - Custom element to render as the link. Use to integrate with framework routers (e.g. Next.js Link).
|
|
2990
|
+
|
|
2951
2991
|
#### DropdownMenu.CheckboxItem
|
|
2952
2992
|
|
|
2953
2993
|
CheckboxItem sub-component
|
|
2954
2994
|
|
|
2995
|
+
Props:
|
|
2996
|
+
- `checked`: boolean - Whether the item is checked.
|
|
2997
|
+
- `defaultChecked`: boolean [default: false] - Whether the item is initially checked (uncontrolled).
|
|
2998
|
+
- `onCheckedChange`: (checked: boolean, event: ChangeEventDetails) => void - Callback when the checked state changes.
|
|
2999
|
+
- `closeOnClick`: boolean [default: false] - Whether the menu closes after clicking this item.
|
|
3000
|
+
- `disabled`: boolean - When true, the item cannot be interacted with.
|
|
3001
|
+
|
|
2955
3002
|
#### DropdownMenu.RadioGroup
|
|
2956
3003
|
|
|
2957
3004
|
RadioGroup sub-component (wraps DropdownMenuPrimitive)
|
|
2958
3005
|
|
|
3006
|
+
Props:
|
|
3007
|
+
- `value`: any - The controlled value of the currently selected radio item.
|
|
3008
|
+
- `defaultValue`: any - The initially selected value (uncontrolled).
|
|
3009
|
+
- `onValueChange`: (value: any, event: ChangeEventDetails) => void - Callback when the selected value changes.
|
|
3010
|
+
- `disabled`: boolean - When true, all radio items in the group are disabled.
|
|
3011
|
+
|
|
2959
3012
|
#### DropdownMenu.RadioItem
|
|
2960
3013
|
|
|
2961
3014
|
RadioItem sub-component
|
|
2962
3015
|
|
|
3016
|
+
Props:
|
|
3017
|
+
- `value`: any (required) - The value of this radio item.
|
|
3018
|
+
- `icon`: Icon | ReactNode - Icon displayed before the label.
|
|
3019
|
+
- `inset`: boolean - Adds left padding to align with items that have icons.
|
|
3020
|
+
- `closeOnClick`: boolean [default: false] - Whether the menu closes after clicking this item.
|
|
3021
|
+
- `disabled`: boolean - When true, the item cannot be interacted with.
|
|
3022
|
+
|
|
2963
3023
|
#### DropdownMenu.RadioItemIndicator
|
|
2964
3024
|
|
|
2965
3025
|
RadioItemIndicator sub-component
|
|
@@ -2968,6 +3028,9 @@ RadioItemIndicator sub-component
|
|
|
2968
3028
|
|
|
2969
3029
|
Label sub-component
|
|
2970
3030
|
|
|
3031
|
+
Props:
|
|
3032
|
+
- `inset`: boolean - Adds left padding to align with items that have icons.
|
|
3033
|
+
|
|
2971
3034
|
#### DropdownMenu.Separator
|
|
2972
3035
|
|
|
2973
3036
|
Separator sub-component
|
|
@@ -2981,6 +3044,199 @@ Shortcut sub-component
|
|
|
2981
3044
|
Group sub-component (wraps DropdownMenuPrimitive)
|
|
2982
3045
|
|
|
2983
3046
|
|
|
3047
|
+
**Examples:**
|
|
3048
|
+
|
|
3049
|
+
```tsx
|
|
3050
|
+
<DropdownMenu>
|
|
3051
|
+
<DropdownMenu.Trigger render={<Button icon={PlusIcon}>Add</Button>} />
|
|
3052
|
+
<DropdownMenu.Content>
|
|
3053
|
+
<DropdownMenu.Item>Worker</DropdownMenu.Item>
|
|
3054
|
+
<DropdownMenu.Item>Pages</DropdownMenu.Item>
|
|
3055
|
+
<DropdownMenu.Item>KV Namespace</DropdownMenu.Item>
|
|
3056
|
+
</DropdownMenu.Content>
|
|
3057
|
+
</DropdownMenu>
|
|
3058
|
+
```
|
|
3059
|
+
|
|
3060
|
+
```tsx
|
|
3061
|
+
<DropdownMenu>
|
|
3062
|
+
<DropdownMenu.Trigger render={<Button>View Options</Button>} />
|
|
3063
|
+
<DropdownMenu.Content>
|
|
3064
|
+
<DropdownMenu.Group>
|
|
3065
|
+
<DropdownMenu.Label>Display</DropdownMenu.Label>
|
|
3066
|
+
<DropdownMenu.CheckboxItem
|
|
3067
|
+
checked={showSidebar}
|
|
3068
|
+
onCheckedChange={setShowSidebar}
|
|
3069
|
+
>
|
|
3070
|
+
Show sidebar
|
|
3071
|
+
</DropdownMenu.CheckboxItem>
|
|
3072
|
+
<DropdownMenu.CheckboxItem
|
|
3073
|
+
checked={showLineNumbers}
|
|
3074
|
+
onCheckedChange={setShowLineNumbers}
|
|
3075
|
+
>
|
|
3076
|
+
Show line numbers
|
|
3077
|
+
</DropdownMenu.CheckboxItem>
|
|
3078
|
+
<DropdownMenu.CheckboxItem
|
|
3079
|
+
checked={wordWrap}
|
|
3080
|
+
onCheckedChange={setWordWrap}
|
|
3081
|
+
>
|
|
3082
|
+
Word wrap
|
|
3083
|
+
</DropdownMenu.CheckboxItem>
|
|
3084
|
+
</DropdownMenu.Group>
|
|
3085
|
+
</DropdownMenu.Content>
|
|
3086
|
+
</DropdownMenu>
|
|
3087
|
+
```
|
|
3088
|
+
|
|
3089
|
+
```tsx
|
|
3090
|
+
<DropdownMenu>
|
|
3091
|
+
<DropdownMenu.Trigger render={<Button icon={UserIcon}>Account</Button>} />
|
|
3092
|
+
<DropdownMenu.Content>
|
|
3093
|
+
<DropdownMenu.Item icon={UserIcon}>Profile</DropdownMenu.Item>
|
|
3094
|
+
<DropdownMenu.Item icon={CreditCardIcon}>Billing</DropdownMenu.Item>
|
|
3095
|
+
<DropdownMenu.Item icon={MoonIcon}>Dark mode</DropdownMenu.Item>
|
|
3096
|
+
|
|
3097
|
+
{/* Language submenu with RadioGroup */}
|
|
3098
|
+
<DropdownMenu.Sub>
|
|
3099
|
+
<DropdownMenu.SubTrigger>Language</DropdownMenu.SubTrigger>
|
|
3100
|
+
<DropdownMenu.SubContent>
|
|
3101
|
+
<DropdownMenu.Group>
|
|
3102
|
+
<DropdownMenu.RadioGroup
|
|
3103
|
+
value={language}
|
|
3104
|
+
onValueChange={setLanguage}
|
|
3105
|
+
>
|
|
3106
|
+
{languages.map((lang) => (
|
|
3107
|
+
<DropdownMenu.RadioItem key={lang.code} value={lang.code}>
|
|
3108
|
+
{lang.label}
|
|
3109
|
+
<DropdownMenu.RadioItemIndicator />
|
|
3110
|
+
</DropdownMenu.RadioItem>
|
|
3111
|
+
))}
|
|
3112
|
+
</DropdownMenu.RadioGroup>
|
|
3113
|
+
</DropdownMenu.Group>
|
|
3114
|
+
</DropdownMenu.SubContent>
|
|
3115
|
+
</DropdownMenu.Sub>
|
|
3116
|
+
|
|
3117
|
+
{/* Timezone submenu with RadioGroup */}
|
|
3118
|
+
<DropdownMenu.Sub>
|
|
3119
|
+
<DropdownMenu.SubTrigger>Set Timezone</DropdownMenu.SubTrigger>
|
|
3120
|
+
<DropdownMenu.SubContent>
|
|
3121
|
+
<DropdownMenu.Group>
|
|
3122
|
+
<DropdownMenu.RadioGroup
|
|
3123
|
+
value={timezone}
|
|
3124
|
+
onValueChange={setTimezone}
|
|
3125
|
+
>
|
|
3126
|
+
{timezones.map((tz) => (
|
|
3127
|
+
<DropdownMenu.RadioItem key={tz.value} value={tz.value}>
|
|
3128
|
+
{tz.label}
|
|
3129
|
+
<DropdownMenu.RadioItemIndicator />
|
|
3130
|
+
</DropdownMenu.RadioItem>
|
|
3131
|
+
))}
|
|
3132
|
+
</DropdownMenu.RadioGroup>
|
|
3133
|
+
</DropdownMenu.Group>
|
|
3134
|
+
</DropdownMenu.SubContent>
|
|
3135
|
+
</DropdownMenu.Sub>
|
|
3136
|
+
|
|
3137
|
+
<DropdownMenu.Separator />
|
|
3138
|
+
<DropdownMenu.Item icon={SignOutIcon} variant="danger">
|
|
3139
|
+
Log out
|
|
3140
|
+
</DropdownMenu.Item>
|
|
3141
|
+
</DropdownMenu.Content>
|
|
3142
|
+
</DropdownMenu>
|
|
3143
|
+
```
|
|
3144
|
+
|
|
3145
|
+
```tsx
|
|
3146
|
+
<DropdownMenu>
|
|
3147
|
+
<DropdownMenu.Trigger render={<Button>Edit</Button>} />
|
|
3148
|
+
<DropdownMenu.Content>
|
|
3149
|
+
<DropdownMenu.Item icon={PencilSimpleIcon}>Rename</DropdownMenu.Item>
|
|
3150
|
+
<DropdownMenu.Item icon={CopyIcon}>Duplicate</DropdownMenu.Item>
|
|
3151
|
+
<DropdownMenu.Separator />
|
|
3152
|
+
<DropdownMenu.Item inset>Move to folder</DropdownMenu.Item>
|
|
3153
|
+
<DropdownMenu.Item inset>Add to favorites</DropdownMenu.Item>
|
|
3154
|
+
<DropdownMenu.Separator />
|
|
3155
|
+
<DropdownMenu.Item icon={TrashIcon} variant="danger">
|
|
3156
|
+
Delete
|
|
3157
|
+
</DropdownMenu.Item>
|
|
3158
|
+
</DropdownMenu.Content>
|
|
3159
|
+
</DropdownMenu>
|
|
3160
|
+
```
|
|
3161
|
+
|
|
3162
|
+
```tsx
|
|
3163
|
+
<div className="flex flex-col items-start gap-2">
|
|
3164
|
+
<DropdownMenu>
|
|
3165
|
+
<DropdownMenu.Trigger render={<Button>Actions</Button>} />
|
|
3166
|
+
<DropdownMenu.Content>
|
|
3167
|
+
<DropdownMenu.Item
|
|
3168
|
+
icon={CopyIcon}
|
|
3169
|
+
onClick={() => setLastAction("Duplicated")}
|
|
3170
|
+
>
|
|
3171
|
+
Duplicate
|
|
3172
|
+
</DropdownMenu.Item>
|
|
3173
|
+
<DropdownMenu.Item
|
|
3174
|
+
icon={PencilSimpleIcon}
|
|
3175
|
+
onClick={() => setLastAction("Renamed")}
|
|
3176
|
+
>
|
|
3177
|
+
Rename
|
|
3178
|
+
</DropdownMenu.Item>
|
|
3179
|
+
<DropdownMenu.Separator />
|
|
3180
|
+
<DropdownMenu.Item
|
|
3181
|
+
icon={TrashIcon}
|
|
3182
|
+
variant="danger"
|
|
3183
|
+
onClick={() => setLastAction("Deleted")}
|
|
3184
|
+
>
|
|
3185
|
+
Delete
|
|
3186
|
+
</DropdownMenu.Item>
|
|
3187
|
+
</DropdownMenu.Content>
|
|
3188
|
+
</DropdownMenu>
|
|
3189
|
+
{lastAction && (
|
|
3190
|
+
<p className="text-sm text-kumo-subtle">
|
|
3191
|
+
Last action: <span className="text-kumo-default">{lastAction}</span>
|
|
3192
|
+
</p>
|
|
3193
|
+
)}
|
|
3194
|
+
</div>
|
|
3195
|
+
```
|
|
3196
|
+
|
|
3197
|
+
```tsx
|
|
3198
|
+
<DropdownMenu>
|
|
3199
|
+
<DropdownMenu.Trigger
|
|
3200
|
+
render={<button type="button" className="rounded-full" />}
|
|
3201
|
+
>
|
|
3202
|
+
<span className="flex h-8 w-8 items-center justify-center rounded-full bg-kumo-brand text-sm font-medium text-white">
|
|
3203
|
+
MR
|
|
3204
|
+
</span>
|
|
3205
|
+
</DropdownMenu.Trigger>
|
|
3206
|
+
<DropdownMenu.Content>
|
|
3207
|
+
<DropdownMenu.Item icon={UserIcon}>Profile</DropdownMenu.Item>
|
|
3208
|
+
<DropdownMenu.Item icon={GearIcon}>Settings</DropdownMenu.Item>
|
|
3209
|
+
<DropdownMenu.Separator />
|
|
3210
|
+
<DropdownMenu.Item icon={SignOutIcon} variant="danger">
|
|
3211
|
+
Log out
|
|
3212
|
+
</DropdownMenu.Item>
|
|
3213
|
+
</DropdownMenu.Content>
|
|
3214
|
+
</DropdownMenu>
|
|
3215
|
+
```
|
|
3216
|
+
|
|
3217
|
+
```tsx
|
|
3218
|
+
<DropdownMenu>
|
|
3219
|
+
<DropdownMenu.Trigger render={<Button>Resources</Button>} />
|
|
3220
|
+
<DropdownMenu.Content>
|
|
3221
|
+
<DropdownMenu.LinkItem href="/settings" icon={GearIcon}>
|
|
3222
|
+
Settings
|
|
3223
|
+
</DropdownMenu.LinkItem>
|
|
3224
|
+
<DropdownMenu.LinkItem href="/docs" icon={BookOpenIcon}>
|
|
3225
|
+
Documentation
|
|
3226
|
+
</DropdownMenu.LinkItem>
|
|
3227
|
+
<DropdownMenu.Separator />
|
|
3228
|
+
<DropdownMenu.LinkItem
|
|
3229
|
+
href="https://developers.cloudflare.com"
|
|
3230
|
+
target="_blank"
|
|
3231
|
+
icon={ArrowSquareOutIcon}
|
|
3232
|
+
>
|
|
3233
|
+
Developer Docs
|
|
3234
|
+
</DropdownMenu.LinkItem>
|
|
3235
|
+
</DropdownMenu.Content>
|
|
3236
|
+
</DropdownMenu>
|
|
3237
|
+
```
|
|
3238
|
+
|
|
3239
|
+
|
|
2984
3240
|
---
|
|
2985
3241
|
|
|
2986
3242
|
### Empty
|
|
@@ -7382,6 +7638,15 @@ Toasty — toast notification provider and viewport. Renders a `Toast.Provider`
|
|
|
7382
7638
|
**Styling:**
|
|
7383
7639
|
|
|
7384
7640
|
|
|
7641
|
+
**Examples:**
|
|
7642
|
+
|
|
7643
|
+
```tsx
|
|
7644
|
+
<Toasty>
|
|
7645
|
+
<ToastTitleOnlyButton />
|
|
7646
|
+
</Toasty>
|
|
7647
|
+
```
|
|
7648
|
+
|
|
7649
|
+
|
|
7385
7650
|
---
|
|
7386
7651
|
|
|
7387
7652
|
### Tooltip
|
|
@@ -7412,6 +7677,27 @@ Accessible popup that shows additional information on hover/focus. Wrap your app
|
|
|
7412
7677
|
|
|
7413
7678
|
`bg-kumo-base`, `fill-kumo-base`, `fill-kumo-tip-shadow`, `fill-kumo-tip-stroke`, `outline-kumo-fill`, `text-kumo-default`
|
|
7414
7679
|
|
|
7680
|
+
**Sub-Components:**
|
|
7681
|
+
|
|
7682
|
+
This is a compound component. Use these sub-components:
|
|
7683
|
+
|
|
7684
|
+
#### Tooltip.Provider
|
|
7685
|
+
|
|
7686
|
+
Groups multiple tooltips so that after the first tooltip is shown, switching to another skips the open delay. Place once at your app root or layout.
|
|
7687
|
+
|
|
7688
|
+
Props:
|
|
7689
|
+
- `delay`: number [default: 600] - How long to wait (ms) before opening a tooltip once the pointer enters the trigger.
|
|
7690
|
+
- `closeDelay`: number [default: 0] - How long to wait (ms) before closing a tooltip.
|
|
7691
|
+
- `timeout`: number [default: 400] - Grace period (ms) during which a just-closed tooltip's delay is skipped when another tooltip opens.
|
|
7692
|
+
|
|
7693
|
+
Usage:
|
|
7694
|
+
```tsx
|
|
7695
|
+
<TooltipProvider>
|
|
7696
|
+
<App />
|
|
7697
|
+
</TooltipProvider>
|
|
7698
|
+
```
|
|
7699
|
+
|
|
7700
|
+
|
|
7415
7701
|
**Examples:**
|
|
7416
7702
|
|
|
7417
7703
|
```tsx
|
package/dist/.build-complete
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
1777656981695
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsx as o, jsxs as
|
|
3
|
-
import { CaretDownIcon as
|
|
2
|
+
import { jsx as o, jsxs as g } from "react/jsx-runtime";
|
|
3
|
+
import { CaretDownIcon as u } from "@phosphor-icons/react";
|
|
4
4
|
import { forwardRef as r } from "react";
|
|
5
5
|
import { c as t } from "./cn-ct4n7r74mh8y0f48.js";
|
|
6
|
-
import { aO as
|
|
6
|
+
import { aO as C, aP as i, aQ as n } from "./vendor-base-ui-ie71jahf0czyf58j.js";
|
|
7
7
|
function s({ className: e, ...l }) {
|
|
8
|
-
return /* @__PURE__ */ o(
|
|
8
|
+
return /* @__PURE__ */ o(C, { className: e, ...l });
|
|
9
9
|
}
|
|
10
10
|
s.displayName = "Collapsible.Root";
|
|
11
11
|
const p = r(
|
|
@@ -30,7 +30,7 @@ const m = r(
|
|
|
30
30
|
)
|
|
31
31
|
);
|
|
32
32
|
m.displayName = "Collapsible.Panel";
|
|
33
|
-
const c = r(({ children: e, className: l }, a) => /* @__PURE__ */
|
|
33
|
+
const c = r(({ children: e, className: l }, a) => /* @__PURE__ */ g(
|
|
34
34
|
n,
|
|
35
35
|
{
|
|
36
36
|
ref: a,
|
|
@@ -44,21 +44,22 @@ const c = r(({ children: e, className: l }, a) => /* @__PURE__ */ f(
|
|
|
44
44
|
children: [
|
|
45
45
|
e,
|
|
46
46
|
" ",
|
|
47
|
-
/* @__PURE__ */ o(
|
|
47
|
+
/* @__PURE__ */ o(u, { className: "h-4 w-4 transition-transform [[data-panel-open]_&]:rotate-180" })
|
|
48
48
|
]
|
|
49
49
|
}
|
|
50
50
|
));
|
|
51
51
|
c.displayName = "Collapsible.DefaultTrigger";
|
|
52
|
-
const b = r(({ children: e, className: l },
|
|
52
|
+
const b = r(({ children: e, className: l, ...a }, f) => /* @__PURE__ */ o(
|
|
53
53
|
i,
|
|
54
54
|
{
|
|
55
|
-
ref:
|
|
55
|
+
ref: f,
|
|
56
56
|
className: t("my-2 space-y-4 border-l-2 border-kumo-fill pl-4", l),
|
|
57
|
+
...a,
|
|
57
58
|
children: e
|
|
58
59
|
}
|
|
59
60
|
));
|
|
60
61
|
b.displayName = "Collapsible.DefaultPanel";
|
|
61
|
-
const
|
|
62
|
+
const T = Object.assign(s, {
|
|
62
63
|
Root: s,
|
|
63
64
|
Trigger: p,
|
|
64
65
|
Panel: m,
|
|
@@ -66,6 +67,6 @@ const D = Object.assign(s, {
|
|
|
66
67
|
DefaultPanel: b
|
|
67
68
|
});
|
|
68
69
|
export {
|
|
69
|
-
|
|
70
|
+
T as C
|
|
70
71
|
};
|
|
71
|
-
//# sourceMappingURL=collapsible-
|
|
72
|
+
//# sourceMappingURL=collapsible-nlp2jvcyuzxmq28o.js.map
|
package/dist/chunks/{collapsible-k8urhi16pg90jvxa.js.map → collapsible-nlp2jvcyuzxmq28o.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collapsible-k8urhi16pg90jvxa.js","sources":["../../src/components/collapsible/collapsible.tsx"],"sourcesContent":["import { Collapsible as CollapsibleBase } from \"@base-ui/react/collapsible\";\nimport { CaretDownIcon } from \"@phosphor-icons/react\";\nimport {\n forwardRef,\n type ComponentPropsWithoutRef,\n type ReactNode,\n} from \"react\";\nimport { cn } from \"../../utils/cn\";\n\n// =============================================================================\n// Variants\n// =============================================================================\n\nexport const KUMO_COLLAPSIBLE_VARIANTS = {} as const;\n\nexport const KUMO_COLLAPSIBLE_DEFAULT_VARIANTS = {} as const;\n\nexport interface KumoCollapsibleVariantsProps {}\n\nexport function collapsibleVariants(_props: KumoCollapsibleVariantsProps = {}) {\n return cn();\n}\n\n// =============================================================================\n// Collapsible Root\n// =============================================================================\n\ntype BaseRootProps = ComponentPropsWithoutRef<typeof CollapsibleBase.Root>;\n\nexport interface CollapsibleRootProps extends BaseRootProps {\n /** Additional CSS classes */\n className?: string;\n}\n\n/**\n * Root component that manages collapsible state.\n *\n * @example\n * ```tsx\n * <Collapsible.Root open={open} onOpenChange={setOpen}>\n * <Collapsible.Trigger>Toggle</Collapsible.Trigger>\n * <Collapsible.Panel>Content</Collapsible.Panel>\n * </Collapsible.Root>\n * ```\n */\nfunction CollapsibleRoot({ className, ...props }: CollapsibleRootProps) {\n return <CollapsibleBase.Root className={className} {...props} />;\n}\n\nCollapsibleRoot.displayName = \"Collapsible.Root\";\n\n// =============================================================================\n// Collapsible Trigger\n// =============================================================================\n\ntype BaseTriggerProps = ComponentPropsWithoutRef<\n typeof CollapsibleBase.Trigger\n>;\n\nexport interface CollapsibleTriggerProps extends BaseTriggerProps {\n /** Additional CSS classes */\n className?: string;\n}\n\n/**\n * Button that toggles the collapsible panel visibility.\n * Use the `render` prop to customize the trigger element.\n *\n * @example\n * ```tsx\n * // Default button\n * <Collapsible.Trigger>Show more</Collapsible.Trigger>\n *\n * // Custom trigger element\n * <Collapsible.Trigger render={<Button variant=\"ghost\" />}>\n * Toggle details\n * </Collapsible.Trigger>\n * ```\n */\nconst CollapsibleTrigger = forwardRef<HTMLButtonElement, CollapsibleTriggerProps>(\n ({ className, ...props }, ref) => {\n return (\n <CollapsibleBase.Trigger\n ref={ref}\n className={cn(\"cursor-pointer\", className)}\n {...props}\n />\n );\n },\n);\n\nCollapsibleTrigger.displayName = \"Collapsible.Trigger\";\n\n// =============================================================================\n// Collapsible Panel\n// =============================================================================\n\ntype BasePanelProps = ComponentPropsWithoutRef<typeof CollapsibleBase.Panel>;\n\nexport interface CollapsiblePanelProps extends BasePanelProps {\n /** Additional CSS classes */\n className?: string;\n}\n\n/**\n * Container for collapsible content. Renders when the collapsible is open.\n *\n * @example\n * ```tsx\n * <Collapsible.Panel className=\"mt-2 space-y-4\">\n * <Text>Revealed content here</Text>\n * </Collapsible.Panel>\n * ```\n */\nconst CollapsiblePanel = forwardRef<HTMLDivElement, CollapsiblePanelProps>(\n ({ className, ...props }, ref) => {\n return (\n <CollapsibleBase.Panel\n ref={ref}\n className={className}\n {...props}\n />\n );\n },\n);\n\nCollapsiblePanel.displayName = \"Collapsible.Panel\";\n\n// =============================================================================\n// Default Trigger (Migration Affordance)\n// =============================================================================\n\nexport interface CollapsibleDefaultTriggerProps {\n /** Label text displayed in the trigger */\n children: ReactNode;\n /** Additional CSS classes */\n className?: string;\n}\n\n/**\n * Pre-styled trigger with text label and animated caret icon.\n * Provides the same visual style as the previous Collapsible API.\n *\n * Use this for quick migration or when you want the default Kumo style.\n *\n * @example\n * ```tsx\n * <Collapsible.Root>\n * <Collapsible.DefaultTrigger>Show details</Collapsible.DefaultTrigger>\n * <Collapsible.Panel>Content</Collapsible.Panel>\n * </Collapsible.Root>\n * ```\n */\nconst CollapsibleDefaultTrigger = forwardRef<\n HTMLButtonElement,\n CollapsibleDefaultTriggerProps\n>(({ children, className }, ref) => {\n return (\n <CollapsibleBase.Trigger\n ref={ref}\n className={cn(\n // Defensive resets to prevent global button styles from polluting the trigger\n \"bg-transparent border-none shadow-none p-0 m-0\",\n // Base styles for the trigger\n \"flex cursor-pointer items-center gap-1 text-sm text-kumo-link select-none\",\n className,\n )}\n >\n {children}{\" \"}\n <CaretDownIcon className=\"h-4 w-4 transition-transform [[data-panel-open]_&]:rotate-180\" />\n </CollapsibleBase.Trigger>\n );\n});\n\nCollapsibleDefaultTrigger.displayName = \"Collapsible.DefaultTrigger\";\n\n// =============================================================================\n// Default Panel (Migration Affordance)\n// =============================================================================\n\nexport interface CollapsibleDefaultPanelProps {\n /** Panel content */\n children: ReactNode;\n /** Additional CSS classes */\n className?: string;\n}\n\n/**\n * Pre-styled panel with left border accent and standard spacing.\n * Provides the same visual style as the previous Collapsible API.\n *\n * @example\n * ```tsx\n * <Collapsible.Root>\n * <Collapsible.DefaultTrigger>Show details</Collapsible.DefaultTrigger>\n * <Collapsible.DefaultPanel>\n * <Text>Content with default styling</Text>\n * </Collapsible.DefaultPanel>\n * </Collapsible.Root>\n * ```\n */\nconst CollapsibleDefaultPanel = forwardRef<\n HTMLDivElement,\n CollapsibleDefaultPanelProps\n>(({ children, className }, ref) => {\n return (\n <CollapsibleBase.Panel\n ref={ref}\n className={cn(\"my-2 space-y-4 border-l-2 border-kumo-fill pl-4\", className)}\n >\n {children}\n </CollapsibleBase.Panel>\n );\n});\n\nCollapsibleDefaultPanel.displayName = \"Collapsible.DefaultPanel\";\n\n// =============================================================================\n// Compound Component Export\n// =============================================================================\n\n/**\n * Collapsible — a composable disclosure component for showing/hiding content.\n *\n * Built on Base UI's Collapsible with full composition support.\n *\n * ## Basic Usage\n *\n * ```tsx\n * const [open, setOpen] = useState(false);\n *\n * <Collapsible.Root open={open} onOpenChange={setOpen}>\n * <Collapsible.Trigger render={<Button variant=\"ghost\" />}>\n * Show details\n * </Collapsible.Trigger>\n * <Collapsible.Panel className=\"mt-2\">\n * <Text>Hidden content revealed when expanded.</Text>\n * </Collapsible.Panel>\n * </Collapsible.Root>\n * ```\n *\n * ## With Default Styling\n *\n * Use `DefaultTrigger` and `DefaultPanel` for the classic Kumo style:\n *\n * ```tsx\n * <Collapsible.Root>\n * <Collapsible.DefaultTrigger>Show details</Collapsible.DefaultTrigger>\n * <Collapsible.DefaultPanel>\n * <Text>Content with border-left accent</Text>\n * </Collapsible.DefaultPanel>\n * </Collapsible.Root>\n * ```\n *\n * ## Controlled Accordion Pattern\n *\n * ```tsx\n * const [activeIndex, setActiveIndex] = useState<number | null>(null);\n *\n * {items.map((item, i) => (\n * <Collapsible.Root\n * key={i}\n * open={activeIndex === i}\n * onOpenChange={(open) => setActiveIndex(open ? i : null)}\n * >\n * <Collapsible.DefaultTrigger>{item.title}</Collapsible.DefaultTrigger>\n * <Collapsible.DefaultPanel>{item.content}</Collapsible.DefaultPanel>\n * </Collapsible.Root>\n * ))}\n * ```\n */\nexport const Collapsible = Object.assign(CollapsibleRoot, {\n Root: CollapsibleRoot,\n Trigger: CollapsibleTrigger,\n Panel: CollapsiblePanel,\n DefaultTrigger: CollapsibleDefaultTrigger,\n DefaultPanel: CollapsibleDefaultPanel,\n});\n\n// =============================================================================\n// Type Exports\n// =============================================================================\n\nexport type CollapsibleProps = CollapsibleRootProps;\n"],"names":["CollapsibleRoot","className","props","CollapsibleBase.Root","CollapsibleTrigger","forwardRef","ref","jsx","CollapsibleBase.Trigger","cn","CollapsiblePanel","CollapsibleBase.Panel","CollapsibleDefaultTrigger","children","jsxs","CaretDownIcon","CollapsibleDefaultPanel","Collapsible"],"mappings":";;;;;;AA6CA,SAASA,EAAgB,EAAE,WAAAC,GAAW,GAAGC,KAA+B;AACtE,2BAAQC,GAAA,EAAqB,WAAAF,GAAuB,GAAGC,EAAA,CAAO;AAChE;AAEAF,EAAgB,cAAc;AA8B9B,MAAMI,IAAqBC;AAAA,EACzB,CAAC,EAAE,WAAAJ,GAAW,GAAGC,EAAA,GAASI,MAEtB,gBAAAC;AAAA,IAACC;AAAAA,IAAA;AAAA,MACC,KAAAF;AAAA,MACA,WAAWG,EAAG,kBAAkBR,CAAS;AAAA,MACxC,GAAGC;AAAA,IAAA;AAAA,EAAA;AAIZ;AAEAE,EAAmB,cAAc;AAuBjC,MAAMM,IAAmBL;AAAA,EACvB,CAAC,EAAE,WAAAJ,GAAW,GAAGC,EAAA,GAASI,MAEtB,gBAAAC;AAAA,IAACI;AAAAA,IAAA;AAAA,MACC,KAAAL;AAAA,MACA,WAAAL;AAAA,MACC,GAAGC;AAAA,IAAA;AAAA,EAAA;AAIZ;AAEAQ,EAAiB,cAAc;AA2B/B,MAAME,IAA4BP,EAGhC,CAAC,EAAE,UAAAQ,GAAU,WAAAZ,EAAA,GAAaK,MAExB,gBAAAQ;AAAA,EAACN;AAAAA,EAAA;AAAA,IACC,KAAAF;AAAA,IACA,WAAWG;AAAA;AAAA,MAET;AAAA;AAAA,MAEA;AAAA,MACAR;AAAA,IAAA;AAAA,IAGD,UAAA;AAAA,MAAAY;AAAA,MAAU;AAAA,MACX,gBAAAN,EAACQ,GAAA,EAAc,WAAU,gEAAA,CAAgE;AAAA,IAAA;AAAA,EAAA;AAAA,CAG9F;AAEDH,EAA0B,cAAc;AA2BxC,MAAMI,IAA0BX,EAG9B,CAAC,EAAE,UAAAQ,GAAU,WAAAZ,EAAA,GAAaK,MAExB,gBAAAC;AAAA,EAACI;AAAAA,EAAA;AAAA,IACC,KAAAL;AAAA,IACA,WAAWG,EAAG,mDAAmDR,CAAS;AAAA,IAEzE,UAAAY;AAAA,EAAA;AAAA,CAGN;AAEDG,EAAwB,cAAc;AAwD/B,MAAMC,IAAc,OAAO,OAAOjB,GAAiB;AAAA,EACxD,MAAMA;AAAA,EACN,SAASI;AAAA,EACT,OAAOM;AAAA,EACP,gBAAgBE;AAAA,EAChB,cAAcI;AAChB,CAAC;"}
|
|
1
|
+
{"version":3,"file":"collapsible-nlp2jvcyuzxmq28o.js","sources":["../../src/components/collapsible/collapsible.tsx"],"sourcesContent":["import { Collapsible as CollapsibleBase } from \"@base-ui/react/collapsible\";\nimport { CaretDownIcon } from \"@phosphor-icons/react\";\nimport {\n forwardRef,\n type ComponentPropsWithoutRef,\n type ReactNode,\n} from \"react\";\nimport { cn } from \"../../utils/cn\";\n\n// =============================================================================\n// Variants\n// =============================================================================\n\nexport const KUMO_COLLAPSIBLE_VARIANTS = {} as const;\n\nexport const KUMO_COLLAPSIBLE_DEFAULT_VARIANTS = {} as const;\n\nexport interface KumoCollapsibleVariantsProps {}\n\nexport function collapsibleVariants(_props: KumoCollapsibleVariantsProps = {}) {\n return cn();\n}\n\n// =============================================================================\n// Collapsible Root\n// =============================================================================\n\ntype BaseRootProps = ComponentPropsWithoutRef<typeof CollapsibleBase.Root>;\n\nexport interface CollapsibleRootProps extends BaseRootProps {\n /** Additional CSS classes */\n className?: string;\n}\n\n/**\n * Root component that manages collapsible state.\n *\n * @example\n * ```tsx\n * <Collapsible.Root open={open} onOpenChange={setOpen}>\n * <Collapsible.Trigger>Toggle</Collapsible.Trigger>\n * <Collapsible.Panel>Content</Collapsible.Panel>\n * </Collapsible.Root>\n * ```\n */\nfunction CollapsibleRoot({ className, ...props }: CollapsibleRootProps) {\n return <CollapsibleBase.Root className={className} {...props} />;\n}\n\nCollapsibleRoot.displayName = \"Collapsible.Root\";\n\n// =============================================================================\n// Collapsible Trigger\n// =============================================================================\n\ntype BaseTriggerProps = ComponentPropsWithoutRef<\n typeof CollapsibleBase.Trigger\n>;\n\nexport interface CollapsibleTriggerProps extends BaseTriggerProps {\n /** Additional CSS classes */\n className?: string;\n}\n\n/**\n * Button that toggles the collapsible panel visibility.\n * Use the `render` prop to customize the trigger element.\n *\n * @example\n * ```tsx\n * // Default button\n * <Collapsible.Trigger>Show more</Collapsible.Trigger>\n *\n * // Custom trigger element\n * <Collapsible.Trigger render={<Button variant=\"ghost\" />}>\n * Toggle details\n * </Collapsible.Trigger>\n * ```\n */\nconst CollapsibleTrigger = forwardRef<HTMLButtonElement, CollapsibleTriggerProps>(\n ({ className, ...props }, ref) => {\n return (\n <CollapsibleBase.Trigger\n ref={ref}\n className={cn(\"cursor-pointer\", className)}\n {...props}\n />\n );\n },\n);\n\nCollapsibleTrigger.displayName = \"Collapsible.Trigger\";\n\n// =============================================================================\n// Collapsible Panel\n// =============================================================================\n\ntype BasePanelProps = ComponentPropsWithoutRef<typeof CollapsibleBase.Panel>;\n\nexport interface CollapsiblePanelProps extends BasePanelProps {\n /** Additional CSS classes */\n className?: string;\n}\n\n/**\n * Container for collapsible content. Renders when the collapsible is open.\n *\n * @example\n * ```tsx\n * <Collapsible.Panel className=\"mt-2 space-y-4\">\n * <Text>Revealed content here</Text>\n * </Collapsible.Panel>\n * ```\n */\nconst CollapsiblePanel = forwardRef<HTMLDivElement, CollapsiblePanelProps>(\n ({ className, ...props }, ref) => {\n return (\n <CollapsibleBase.Panel\n ref={ref}\n className={className}\n {...props}\n />\n );\n },\n);\n\nCollapsiblePanel.displayName = \"Collapsible.Panel\";\n\n// =============================================================================\n// Default Trigger (Migration Affordance)\n// =============================================================================\n\nexport interface CollapsibleDefaultTriggerProps {\n /** Label text displayed in the trigger */\n children: ReactNode;\n /** Additional CSS classes */\n className?: string;\n}\n\n/**\n * Pre-styled trigger with text label and animated caret icon.\n * Provides the same visual style as the previous Collapsible API.\n *\n * Use this for quick migration or when you want the default Kumo style.\n *\n * @example\n * ```tsx\n * <Collapsible.Root>\n * <Collapsible.DefaultTrigger>Show details</Collapsible.DefaultTrigger>\n * <Collapsible.Panel>Content</Collapsible.Panel>\n * </Collapsible.Root>\n * ```\n */\nconst CollapsibleDefaultTrigger = forwardRef<\n HTMLButtonElement,\n CollapsibleDefaultTriggerProps\n>(({ children, className }, ref) => {\n return (\n <CollapsibleBase.Trigger\n ref={ref}\n className={cn(\n // Defensive resets to prevent global button styles from polluting the trigger\n \"bg-transparent border-none shadow-none p-0 m-0\",\n // Base styles for the trigger\n \"flex cursor-pointer items-center gap-1 text-sm text-kumo-link select-none\",\n className,\n )}\n >\n {children}{\" \"}\n <CaretDownIcon className=\"h-4 w-4 transition-transform [[data-panel-open]_&]:rotate-180\" />\n </CollapsibleBase.Trigger>\n );\n});\n\nCollapsibleDefaultTrigger.displayName = \"Collapsible.DefaultTrigger\";\n\n// =============================================================================\n// Default Panel (Migration Affordance)\n// =============================================================================\n\nexport interface CollapsibleDefaultPanelProps extends BasePanelProps {\n /** Panel content */\n children: ReactNode;\n /** Additional CSS classes */\n className?: string;\n}\n\n/**\n * Pre-styled panel with left border accent and standard spacing.\n * Provides the same visual style as the previous Collapsible API.\n *\n * @example\n * ```tsx\n * <Collapsible.Root>\n * <Collapsible.DefaultTrigger>Show details</Collapsible.DefaultTrigger>\n * <Collapsible.DefaultPanel>\n * <Text>Content with default styling</Text>\n * </Collapsible.DefaultPanel>\n * </Collapsible.Root>\n * ```\n */\nconst CollapsibleDefaultPanel = forwardRef<\n HTMLDivElement,\n CollapsibleDefaultPanelProps\n>(({ children, className, ...props }, ref) => {\n return (\n <CollapsibleBase.Panel\n ref={ref}\n className={cn(\"my-2 space-y-4 border-l-2 border-kumo-fill pl-4\", className)}\n {...props}\n >\n {children}\n </CollapsibleBase.Panel>\n );\n});\n\nCollapsibleDefaultPanel.displayName = \"Collapsible.DefaultPanel\";\n\n// =============================================================================\n// Compound Component Export\n// =============================================================================\n\n/**\n * Collapsible — a composable disclosure component for showing/hiding content.\n *\n * Built on Base UI's Collapsible with full composition support.\n *\n * ## Basic Usage\n *\n * ```tsx\n * const [open, setOpen] = useState(false);\n *\n * <Collapsible.Root open={open} onOpenChange={setOpen}>\n * <Collapsible.Trigger render={<Button variant=\"ghost\" />}>\n * Show details\n * </Collapsible.Trigger>\n * <Collapsible.Panel className=\"mt-2\">\n * <Text>Hidden content revealed when expanded.</Text>\n * </Collapsible.Panel>\n * </Collapsible.Root>\n * ```\n *\n * ## With Default Styling\n *\n * Use `DefaultTrigger` and `DefaultPanel` for the classic Kumo style:\n *\n * ```tsx\n * <Collapsible.Root>\n * <Collapsible.DefaultTrigger>Show details</Collapsible.DefaultTrigger>\n * <Collapsible.DefaultPanel>\n * <Text>Content with border-left accent</Text>\n * </Collapsible.DefaultPanel>\n * </Collapsible.Root>\n * ```\n *\n * ## Controlled Accordion Pattern\n *\n * ```tsx\n * const [activeIndex, setActiveIndex] = useState<number | null>(null);\n *\n * {items.map((item, i) => (\n * <Collapsible.Root\n * key={i}\n * open={activeIndex === i}\n * onOpenChange={(open) => setActiveIndex(open ? i : null)}\n * >\n * <Collapsible.DefaultTrigger>{item.title}</Collapsible.DefaultTrigger>\n * <Collapsible.DefaultPanel>{item.content}</Collapsible.DefaultPanel>\n * </Collapsible.Root>\n * ))}\n * ```\n */\nexport const Collapsible = Object.assign(CollapsibleRoot, {\n Root: CollapsibleRoot,\n Trigger: CollapsibleTrigger,\n Panel: CollapsiblePanel,\n DefaultTrigger: CollapsibleDefaultTrigger,\n DefaultPanel: CollapsibleDefaultPanel,\n});\n\n// =============================================================================\n// Type Exports\n// =============================================================================\n\nexport type CollapsibleProps = CollapsibleRootProps;\n"],"names":["CollapsibleRoot","className","props","CollapsibleBase.Root","CollapsibleTrigger","forwardRef","ref","jsx","CollapsibleBase.Trigger","cn","CollapsiblePanel","CollapsibleBase.Panel","CollapsibleDefaultTrigger","children","jsxs","CaretDownIcon","CollapsibleDefaultPanel","Collapsible"],"mappings":";;;;;;AA6CA,SAASA,EAAgB,EAAE,WAAAC,GAAW,GAAGC,KAA+B;AACtE,2BAAQC,GAAA,EAAqB,WAAAF,GAAuB,GAAGC,EAAA,CAAO;AAChE;AAEAF,EAAgB,cAAc;AA8B9B,MAAMI,IAAqBC;AAAA,EACzB,CAAC,EAAE,WAAAJ,GAAW,GAAGC,EAAA,GAASI,MAEtB,gBAAAC;AAAA,IAACC;AAAAA,IAAA;AAAA,MACC,KAAAF;AAAA,MACA,WAAWG,EAAG,kBAAkBR,CAAS;AAAA,MACxC,GAAGC;AAAA,IAAA;AAAA,EAAA;AAIZ;AAEAE,EAAmB,cAAc;AAuBjC,MAAMM,IAAmBL;AAAA,EACvB,CAAC,EAAE,WAAAJ,GAAW,GAAGC,EAAA,GAASI,MAEtB,gBAAAC;AAAA,IAACI;AAAAA,IAAA;AAAA,MACC,KAAAL;AAAA,MACA,WAAAL;AAAA,MACC,GAAGC;AAAA,IAAA;AAAA,EAAA;AAIZ;AAEAQ,EAAiB,cAAc;AA2B/B,MAAME,IAA4BP,EAGhC,CAAC,EAAE,UAAAQ,GAAU,WAAAZ,EAAA,GAAaK,MAExB,gBAAAQ;AAAA,EAACN;AAAAA,EAAA;AAAA,IACC,KAAAF;AAAA,IACA,WAAWG;AAAA;AAAA,MAET;AAAA;AAAA,MAEA;AAAA,MACAR;AAAA,IAAA;AAAA,IAGD,UAAA;AAAA,MAAAY;AAAA,MAAU;AAAA,MACX,gBAAAN,EAACQ,GAAA,EAAc,WAAU,gEAAA,CAAgE;AAAA,IAAA;AAAA,EAAA;AAAA,CAG9F;AAEDH,EAA0B,cAAc;AA2BxC,MAAMI,IAA0BX,EAG9B,CAAC,EAAE,UAAAQ,GAAU,WAAAZ,GAAW,GAAGC,EAAA,GAASI,MAElC,gBAAAC;AAAA,EAACI;AAAAA,EAAA;AAAA,IACC,KAAAL;AAAA,IACA,WAAWG,EAAG,mDAAmDR,CAAS;AAAA,IACzE,GAAGC;AAAA,IAEH,UAAAW;AAAA,EAAA;AAAA,CAGN;AAEDG,EAAwB,cAAc;AAwD/B,MAAMC,IAAc,OAAO,OAAOjB,GAAiB;AAAA,EACxD,MAAMA;AAAA,EACN,SAASI;AAAA,EACT,OAAOM;AAAA,EACP,gBAAgBE;AAAA,EAChB,cAAcI;AAChB,CAAC;"}
|
package/dist/index.js
CHANGED
|
@@ -12,7 +12,7 @@ import { C as Ta } from "./chunks/combobox-fq36ye0hstote16x.js";
|
|
|
12
12
|
import { a as M, D as U, c as N, e as u } from "./chunks/dialog-k3f1fbam6nt96k8x.js";
|
|
13
13
|
import { d as Aa, b as ba } from "./chunks/dialog-k3f1fbam6nt96k8x.js";
|
|
14
14
|
import { D as Sa } from "./chunks/dropdown-zbax0zowy6m9zhmt.js";
|
|
15
|
-
import { C as _a } from "./chunks/collapsible-
|
|
15
|
+
import { C as _a } from "./chunks/collapsible-nlp2jvcyuzxmq28o.js";
|
|
16
16
|
import { F as Ia, a as La, K as Ra, f as Ea } from "./chunks/field-c0wf94plit2gci59.js";
|
|
17
17
|
import { b as Ma, K as Ua, L as Na, a as Ka, l as ga } from "./chunks/label-c3h9i3y4wiccelt7.js";
|
|
18
18
|
import { I as K } from "./chunks/input-ncfowphv81yq7fyy.js";
|
|
@@ -41,7 +41,7 @@ export interface CollapsibleDefaultTriggerProps {
|
|
|
41
41
|
/** Additional CSS classes */
|
|
42
42
|
className?: string;
|
|
43
43
|
}
|
|
44
|
-
export interface CollapsibleDefaultPanelProps {
|
|
44
|
+
export interface CollapsibleDefaultPanelProps extends BasePanelProps {
|
|
45
45
|
/** Panel content */
|
|
46
46
|
children: ReactNode;
|
|
47
47
|
/** Additional CSS classes */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collapsible.d.ts","sourceRoot":"","sources":["../../../../src/components/collapsible/collapsible.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,IAAI,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAE5E,OAAO,EAEL,KAAK,wBAAwB,EAC7B,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAOf,eAAO,MAAM,yBAAyB,IAAc,CAAC;AAErD,eAAO,MAAM,iCAAiC,IAAc,CAAC;AAE7D,MAAM,WAAW,4BAA4B;CAAG;AAEhD,wBAAgB,mBAAmB,CAAC,MAAM,GAAE,4BAAiC,UAE5E;AAMD,KAAK,aAAa,GAAG,wBAAwB,CAAC,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC;AAE3E,MAAM,WAAW,oBAAqB,SAAQ,aAAa;IACzD,6BAA6B;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;GAUG;AACH,iBAAS,eAAe,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,oBAAoB,2CAErE;kBAFQ,eAAe;;;AAUxB,KAAK,gBAAgB,GAAG,wBAAwB,CAC9C,OAAO,eAAe,CAAC,OAAO,CAC/B,CAAC;AAEF,MAAM,WAAW,uBAAwB,SAAQ,gBAAgB;IAC/D,6BAA6B;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAmCD,KAAK,cAAc,GAAG,wBAAwB,CAAC,OAAO,eAAe,CAAC,KAAK,CAAC,CAAC;AAE7E,MAAM,WAAW,qBAAsB,SAAQ,cAAc;IAC3D,6BAA6B;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA8BD,MAAM,WAAW,8BAA8B;IAC7C,0CAA0C;IAC1C,QAAQ,EAAE,SAAS,CAAC;IACpB,6BAA6B;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA2CD,MAAM,WAAW,
|
|
1
|
+
{"version":3,"file":"collapsible.d.ts","sourceRoot":"","sources":["../../../../src/components/collapsible/collapsible.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,IAAI,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAE5E,OAAO,EAEL,KAAK,wBAAwB,EAC7B,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAOf,eAAO,MAAM,yBAAyB,IAAc,CAAC;AAErD,eAAO,MAAM,iCAAiC,IAAc,CAAC;AAE7D,MAAM,WAAW,4BAA4B;CAAG;AAEhD,wBAAgB,mBAAmB,CAAC,MAAM,GAAE,4BAAiC,UAE5E;AAMD,KAAK,aAAa,GAAG,wBAAwB,CAAC,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC;AAE3E,MAAM,WAAW,oBAAqB,SAAQ,aAAa;IACzD,6BAA6B;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;GAUG;AACH,iBAAS,eAAe,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,oBAAoB,2CAErE;kBAFQ,eAAe;;;AAUxB,KAAK,gBAAgB,GAAG,wBAAwB,CAC9C,OAAO,eAAe,CAAC,OAAO,CAC/B,CAAC;AAEF,MAAM,WAAW,uBAAwB,SAAQ,gBAAgB;IAC/D,6BAA6B;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAmCD,KAAK,cAAc,GAAG,wBAAwB,CAAC,OAAO,eAAe,CAAC,KAAK,CAAC,CAAC;AAE7E,MAAM,WAAW,qBAAsB,SAAQ,cAAc;IAC3D,6BAA6B;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA8BD,MAAM,WAAW,8BAA8B;IAC7C,0CAA0C;IAC1C,QAAQ,EAAE,SAAS,CAAC;IACpB,6BAA6B;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA2CD,MAAM,WAAW,4BAA6B,SAAQ,cAAc;IAClE,oBAAoB;IACpB,QAAQ,EAAE,SAAS,CAAC;IACpB,6BAA6B;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAqCD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;AACH,eAAO,MAAM,WAAW;;;;;;CAMtB,CAAC;AAMH,MAAM,MAAM,gBAAgB,GAAG,oBAAoB,CAAC"}
|
package/package.json
CHANGED
|
@@ -943,3 +943,45 @@ interface GroupProps extends BaseProps {
|
|
|
943
943
|
expect(props).toEqual({});
|
|
944
944
|
});
|
|
945
945
|
});
|
|
946
|
+
|
|
947
|
+
describe("SUB_COMPONENT_OVERRIDES", () => {
|
|
948
|
+
it("declares a Tooltip.Provider entry that passes through to TooltipBase.Provider", async () => {
|
|
949
|
+
const { SUB_COMPONENT_OVERRIDES, PASSTHROUGH_COMPONENT_DOCS } =
|
|
950
|
+
await import("./metadata.js");
|
|
951
|
+
|
|
952
|
+
expect(SUB_COMPONENT_OVERRIDES.Tooltip).toBeDefined();
|
|
953
|
+
const tooltipOverrides = SUB_COMPONENT_OVERRIDES.Tooltip;
|
|
954
|
+
expect(tooltipOverrides).toHaveLength(1);
|
|
955
|
+
|
|
956
|
+
const provider = tooltipOverrides[0];
|
|
957
|
+
expect(provider.name).toBe("Provider");
|
|
958
|
+
expect(provider.valueName).toBe("TooltipProvider");
|
|
959
|
+
expect(provider.isPassThrough).toBe(true);
|
|
960
|
+
expect(provider.baseComponent).toBe("TooltipBase.Provider");
|
|
961
|
+
expect(provider.propsType).toBeNull();
|
|
962
|
+
|
|
963
|
+
// The baseComponent must resolve to a documented passthrough entry so the
|
|
964
|
+
// merge + lookup path in index.ts produces real docs, not an empty stub.
|
|
965
|
+
expect(
|
|
966
|
+
PASSTHROUGH_COMPONENT_DOCS[provider.baseComponent as string],
|
|
967
|
+
).toBeDefined();
|
|
968
|
+
});
|
|
969
|
+
|
|
970
|
+
it("entries have the same shape as detectSubComponents() results", async () => {
|
|
971
|
+
const { SUB_COMPONENT_OVERRIDES } = await import("./metadata.js");
|
|
972
|
+
|
|
973
|
+
for (const overrides of Object.values(SUB_COMPONENT_OVERRIDES)) {
|
|
974
|
+
for (const entry of overrides) {
|
|
975
|
+
// Required fields of SubComponentConfig.
|
|
976
|
+
expect(typeof entry.name).toBe("string");
|
|
977
|
+
expect(typeof entry.valueName).toBe("string");
|
|
978
|
+
expect(typeof entry.description).toBe("string");
|
|
979
|
+
expect(typeof entry.isPassThrough).toBe("boolean");
|
|
980
|
+
// propsType may be a string or null.
|
|
981
|
+
expect(
|
|
982
|
+
entry.propsType === null || typeof entry.propsType === "string",
|
|
983
|
+
).toBe(true);
|
|
984
|
+
}
|
|
985
|
+
}
|
|
986
|
+
});
|
|
987
|
+
});
|
|
@@ -44,6 +44,7 @@ import {
|
|
|
44
44
|
createCacheEntry,
|
|
45
45
|
} from "./cache.js";
|
|
46
46
|
import {
|
|
47
|
+
toPascalCase,
|
|
47
48
|
toScreamingSnakeCase,
|
|
48
49
|
extractSemanticColors,
|
|
49
50
|
extractBlockDependencies,
|
|
@@ -62,6 +63,7 @@ import {
|
|
|
62
63
|
ADDITIONAL_COMPONENT_PROPS,
|
|
63
64
|
PROP_TYPE_OVERRIDES,
|
|
64
65
|
COMPONENT_STYLING_METADATA,
|
|
66
|
+
SUB_COMPONENT_OVERRIDES,
|
|
65
67
|
} from "./metadata.js";
|
|
66
68
|
|
|
67
69
|
// External imports - demo examples from kumo-docs-astro
|
|
@@ -585,11 +587,16 @@ async function processComponent(
|
|
|
585
587
|
const colors = extractSemanticColors(sourcePath);
|
|
586
588
|
|
|
587
589
|
// Determine examples
|
|
590
|
+
// Demo metadata keys are derived from file names (e.g. DropdownDemo.tsx → "Dropdown")
|
|
591
|
+
// which may differ from the component's export name (e.g. "DropdownMenu").
|
|
592
|
+
// Try the component name first, then fall back to the PascalCase directory name.
|
|
588
593
|
let examples: readonly string[];
|
|
589
594
|
if (config.examples !== undefined) {
|
|
590
595
|
examples = config.examples;
|
|
591
596
|
} else {
|
|
592
|
-
const extracted =
|
|
597
|
+
const extracted =
|
|
598
|
+
input.storyExamples.get(config.name) ??
|
|
599
|
+
input.storyExamples.get(toPascalCase(config.dirName));
|
|
593
600
|
examples = extracted?.aiExamples ?? [];
|
|
594
601
|
if (examples.length > 0 && CLI_FLAGS.verbose) {
|
|
595
602
|
console.log(
|
|
@@ -598,14 +605,21 @@ async function processComponent(
|
|
|
598
605
|
}
|
|
599
606
|
}
|
|
600
607
|
|
|
601
|
-
//
|
|
608
|
+
// Merge SUB_COMPONENT_OVERRIDES after source detection.
|
|
609
|
+
// Detected entries win on name conflict so source-level patterns aren't masked.
|
|
602
610
|
const detectedSubComponents = detectSubComponents(sourcePath);
|
|
611
|
+
const subComponentOverrides = SUB_COMPONENT_OVERRIDES[config.name] ?? [];
|
|
612
|
+
const detectedNames = new Set(detectedSubComponents.map((sc) => sc.name));
|
|
613
|
+
const mergedSubComponents = [
|
|
614
|
+
...detectedSubComponents,
|
|
615
|
+
...subComponentOverrides.filter((o) => !detectedNames.has(o.name)),
|
|
616
|
+
];
|
|
603
617
|
let subComponentSchemas: Record<string, SubComponentSchema> | undefined;
|
|
604
618
|
|
|
605
|
-
if (
|
|
619
|
+
if (mergedSubComponents.length > 0) {
|
|
606
620
|
subComponentSchemas = {};
|
|
607
621
|
|
|
608
|
-
for (const subComp of
|
|
622
|
+
for (const subComp of mergedSubComponents) {
|
|
609
623
|
let subProps = extractSubComponentProps(sourcePath, subComp, CLI_FLAGS);
|
|
610
624
|
let description = subComp.description;
|
|
611
625
|
let usageExamples: string[] | undefined;
|
|
@@ -8,7 +8,12 @@
|
|
|
8
8
|
* - Styling metadata for Figma plugin
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
import type {
|
|
11
|
+
import type {
|
|
12
|
+
PropSchema,
|
|
13
|
+
PassthroughDoc,
|
|
14
|
+
ComponentStyling,
|
|
15
|
+
SubComponentConfig,
|
|
16
|
+
} from "./types.js";
|
|
12
17
|
|
|
13
18
|
// =============================================================================
|
|
14
19
|
// Pass-through Component Documentation
|
|
@@ -158,6 +163,66 @@ export const PASSTHROUGH_COMPONENT_DOCS: Record<string, PassthroughDoc> = {
|
|
|
158
163
|
</Combobox.Collection>`,
|
|
159
164
|
],
|
|
160
165
|
},
|
|
166
|
+
|
|
167
|
+
// Tooltip sub-components
|
|
168
|
+
"TooltipBase.Provider": {
|
|
169
|
+
description:
|
|
170
|
+
"Groups multiple tooltips so that after the first tooltip is shown, switching to another skips the open delay. Place once at your app root or layout.",
|
|
171
|
+
props: {
|
|
172
|
+
delay: {
|
|
173
|
+
type: "number",
|
|
174
|
+
description:
|
|
175
|
+
"How long to wait (ms) before opening a tooltip once the pointer enters the trigger.",
|
|
176
|
+
default: "600",
|
|
177
|
+
},
|
|
178
|
+
closeDelay: {
|
|
179
|
+
type: "number",
|
|
180
|
+
description: "How long to wait (ms) before closing a tooltip.",
|
|
181
|
+
default: "0",
|
|
182
|
+
},
|
|
183
|
+
timeout: {
|
|
184
|
+
type: "number",
|
|
185
|
+
description:
|
|
186
|
+
"Grace period (ms) during which a just-closed tooltip's delay is skipped when another tooltip opens.",
|
|
187
|
+
default: "400",
|
|
188
|
+
},
|
|
189
|
+
},
|
|
190
|
+
usageExamples: ["<TooltipProvider>\n <App />\n</TooltipProvider>"],
|
|
191
|
+
},
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
// =============================================================================
|
|
195
|
+
// Sub-Component Overrides
|
|
196
|
+
// =============================================================================
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Manual sub-component entries that are merged into the registry alongside
|
|
200
|
+
* entries detected by `detectSubComponents()` in `sub-components.ts`.
|
|
201
|
+
*
|
|
202
|
+
* Use this when a component exposes a related API (e.g., a sibling named
|
|
203
|
+
* export like `TooltipProvider`) that we want documented as a sub-component
|
|
204
|
+
* (e.g., `Tooltip.Provider`) for the registry / docs, *without* changing the
|
|
205
|
+
* component's runtime shape (no `Object.assign`, no attached property).
|
|
206
|
+
*
|
|
207
|
+
* Detected sub-components take precedence over overrides with the same
|
|
208
|
+
* `name`, so a real source-level compound pattern will always win and
|
|
209
|
+
* prevent silent masking of detector regressions.
|
|
210
|
+
*
|
|
211
|
+
* Keyed by the parent component name (e.g., "Tooltip"). Values have the same
|
|
212
|
+
* shape as `detectSubComponents()` entries so they feed directly into the
|
|
213
|
+
* existing processing loop in `index.ts`.
|
|
214
|
+
*/
|
|
215
|
+
export const SUB_COMPONENT_OVERRIDES: Record<string, SubComponentConfig[]> = {
|
|
216
|
+
Tooltip: [
|
|
217
|
+
{
|
|
218
|
+
name: "Provider",
|
|
219
|
+
valueName: "TooltipProvider",
|
|
220
|
+
propsType: null,
|
|
221
|
+
description: "Provider sub-component (wraps TooltipBase)",
|
|
222
|
+
isPassThrough: true,
|
|
223
|
+
baseComponent: "TooltipBase.Provider",
|
|
224
|
+
},
|
|
225
|
+
],
|
|
161
226
|
};
|
|
162
227
|
|
|
163
228
|
// =============================================================================
|
|
@@ -254,6 +319,161 @@ export const ADDITIONAL_COMPONENT_PROPS: Record<
|
|
|
254
319
|
description: "Callback when collapsed state changes",
|
|
255
320
|
},
|
|
256
321
|
},
|
|
322
|
+
"DropdownMenu.Item": {
|
|
323
|
+
icon: {
|
|
324
|
+
type: "Icon | ReactNode",
|
|
325
|
+
description: "Icon displayed before the label.",
|
|
326
|
+
},
|
|
327
|
+
variant: {
|
|
328
|
+
type: '"default" | "danger"',
|
|
329
|
+
description: "Visual style of the item.",
|
|
330
|
+
default: '"default"',
|
|
331
|
+
},
|
|
332
|
+
selected: {
|
|
333
|
+
type: "boolean",
|
|
334
|
+
description: "Shows a check mark indicator when true.",
|
|
335
|
+
},
|
|
336
|
+
inset: {
|
|
337
|
+
type: "boolean",
|
|
338
|
+
description: "Adds left padding to align with items that have icons.",
|
|
339
|
+
},
|
|
340
|
+
onClick: {
|
|
341
|
+
type: "(event: React.MouseEvent) => void",
|
|
342
|
+
description: "Callback when the item is clicked.",
|
|
343
|
+
},
|
|
344
|
+
closeOnClick: {
|
|
345
|
+
type: "boolean",
|
|
346
|
+
description: "Whether the menu closes after clicking this item.",
|
|
347
|
+
default: "true",
|
|
348
|
+
},
|
|
349
|
+
disabled: {
|
|
350
|
+
type: "boolean",
|
|
351
|
+
description: "When true, the item cannot be interacted with.",
|
|
352
|
+
},
|
|
353
|
+
},
|
|
354
|
+
"DropdownMenu.LinkItem": {
|
|
355
|
+
href: {
|
|
356
|
+
type: "string",
|
|
357
|
+
description: "URL to navigate to when clicked.",
|
|
358
|
+
},
|
|
359
|
+
icon: {
|
|
360
|
+
type: "Icon | ReactNode",
|
|
361
|
+
description: "Icon displayed before the label.",
|
|
362
|
+
},
|
|
363
|
+
variant: {
|
|
364
|
+
type: '"default" | "danger"',
|
|
365
|
+
description: "Visual style of the item.",
|
|
366
|
+
default: '"default"',
|
|
367
|
+
},
|
|
368
|
+
inset: {
|
|
369
|
+
type: "boolean",
|
|
370
|
+
description: "Adds left padding to align with items that have icons.",
|
|
371
|
+
},
|
|
372
|
+
target: {
|
|
373
|
+
type: "string",
|
|
374
|
+
description: 'Link target attribute (e.g. "_blank" for new tab).',
|
|
375
|
+
},
|
|
376
|
+
render: {
|
|
377
|
+
type: "ReactElement | ((props, state) => ReactElement)",
|
|
378
|
+
description:
|
|
379
|
+
"Custom element to render as the link. Use to integrate with framework routers (e.g. Next.js Link).",
|
|
380
|
+
},
|
|
381
|
+
},
|
|
382
|
+
"DropdownMenu.Content": {
|
|
383
|
+
sideOffset: {
|
|
384
|
+
type: "number",
|
|
385
|
+
description: "Distance in pixels from the trigger.",
|
|
386
|
+
default: "8",
|
|
387
|
+
},
|
|
388
|
+
container: {
|
|
389
|
+
type: "PortalContainer",
|
|
390
|
+
description:
|
|
391
|
+
"Container element for the portal. Use this to render inside a Shadow DOM or custom container.",
|
|
392
|
+
},
|
|
393
|
+
},
|
|
394
|
+
"DropdownMenu.SubTrigger": {
|
|
395
|
+
icon: {
|
|
396
|
+
type: "Icon",
|
|
397
|
+
description: "Icon displayed before the label.",
|
|
398
|
+
},
|
|
399
|
+
inset: {
|
|
400
|
+
type: "boolean",
|
|
401
|
+
description: "Adds left padding to align with items that have icons.",
|
|
402
|
+
},
|
|
403
|
+
},
|
|
404
|
+
"DropdownMenu.CheckboxItem": {
|
|
405
|
+
checked: {
|
|
406
|
+
type: "boolean",
|
|
407
|
+
description: "Whether the item is checked.",
|
|
408
|
+
},
|
|
409
|
+
defaultChecked: {
|
|
410
|
+
type: "boolean",
|
|
411
|
+
description: "Whether the item is initially checked (uncontrolled).",
|
|
412
|
+
default: "false",
|
|
413
|
+
},
|
|
414
|
+
onCheckedChange: {
|
|
415
|
+
type: "(checked: boolean, event: ChangeEventDetails) => void",
|
|
416
|
+
description: "Callback when the checked state changes.",
|
|
417
|
+
},
|
|
418
|
+
closeOnClick: {
|
|
419
|
+
type: "boolean",
|
|
420
|
+
description: "Whether the menu closes after clicking this item.",
|
|
421
|
+
default: "false",
|
|
422
|
+
},
|
|
423
|
+
disabled: {
|
|
424
|
+
type: "boolean",
|
|
425
|
+
description: "When true, the item cannot be interacted with.",
|
|
426
|
+
},
|
|
427
|
+
},
|
|
428
|
+
"DropdownMenu.RadioGroup": {
|
|
429
|
+
value: {
|
|
430
|
+
type: "any",
|
|
431
|
+
description:
|
|
432
|
+
"The controlled value of the currently selected radio item.",
|
|
433
|
+
},
|
|
434
|
+
defaultValue: {
|
|
435
|
+
type: "any",
|
|
436
|
+
description: "The initially selected value (uncontrolled).",
|
|
437
|
+
},
|
|
438
|
+
onValueChange: {
|
|
439
|
+
type: "(value: any, event: ChangeEventDetails) => void",
|
|
440
|
+
description: "Callback when the selected value changes.",
|
|
441
|
+
},
|
|
442
|
+
disabled: {
|
|
443
|
+
type: "boolean",
|
|
444
|
+
description: "When true, all radio items in the group are disabled.",
|
|
445
|
+
},
|
|
446
|
+
},
|
|
447
|
+
"DropdownMenu.RadioItem": {
|
|
448
|
+
value: {
|
|
449
|
+
type: "any",
|
|
450
|
+
required: true,
|
|
451
|
+
description: "The value of this radio item.",
|
|
452
|
+
},
|
|
453
|
+
icon: {
|
|
454
|
+
type: "Icon | ReactNode",
|
|
455
|
+
description: "Icon displayed before the label.",
|
|
456
|
+
},
|
|
457
|
+
inset: {
|
|
458
|
+
type: "boolean",
|
|
459
|
+
description: "Adds left padding to align with items that have icons.",
|
|
460
|
+
},
|
|
461
|
+
closeOnClick: {
|
|
462
|
+
type: "boolean",
|
|
463
|
+
description: "Whether the menu closes after clicking this item.",
|
|
464
|
+
default: "false",
|
|
465
|
+
},
|
|
466
|
+
disabled: {
|
|
467
|
+
type: "boolean",
|
|
468
|
+
description: "When true, the item cannot be interacted with.",
|
|
469
|
+
},
|
|
470
|
+
},
|
|
471
|
+
"DropdownMenu.Label": {
|
|
472
|
+
inset: {
|
|
473
|
+
type: "boolean",
|
|
474
|
+
description: "Adds left padding to align with items that have icons.",
|
|
475
|
+
},
|
|
476
|
+
},
|
|
257
477
|
"InputGroup.Addon": {
|
|
258
478
|
align: {
|
|
259
479
|
type: '"start" | "end"',
|