Merge pull request #1009 from RooVetGit/cte/additional-shadcn-components

This commit is contained in:
Chris Estreich 2025-02-15 08:36:47 -08:00 committed by GitHub
commit 38f1092b5a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
26 changed files with 1435 additions and 282 deletions

View file

@ -2,7 +2,7 @@ import type { StorybookConfig } from "@storybook/react-vite"
const config: StorybookConfig = {
stories: ["../src/**/*.mdx", "../src/**/*.stories.@(js|jsx|mjs|ts|tsx)"],
addons: ["@storybook/addon-essentials", "@storybook/addon-interactions"],
addons: ["@storybook/addon-essentials", "storybook-dark-mode"],
framework: {
name: "@storybook/react-vite",
options: {},

View file

@ -1,7 +1,7 @@
import type { Preview } from "@storybook/react"
import "../src/index.css"
import "./vscode.css"
import "../src/index.css"
const preview: Preview = {
parameters: {

View file

@ -6,27 +6,51 @@
*/
:root {
--vscode-editor-background: #1f1f1f; /* "editor.background" */
--vscode-editor-foreground: #cccccc; /* "editor.foreground" */
--vscode-menu-background: #1f1f1f; /* "menu.background" */
--vscode-menu-foreground: #cccccc; /* "menu.foreground" */
--vscode-button-background: #0078d4; /* "button.background" */
--vscode-button-foreground: #ffffff; /* "button.foreground" */
--vscode-button-secondaryBackground: #313131; /* "button.secondaryBackground" */
--vscode-button-secondaryForeground: #cccccc; /* "button.secondaryForeground" */
--vscode-disabledForeground: #313131; /* "disabledForeground" */
--vscode-descriptionForeground: #9d9d9d; /* "descriptionForeground" */
--vscode-focusBorder: #0078d4; /* "focusBorder" */
--vscode-errorForeground: #f85149; /* "errorForeground" */
--vscode-widget-border: #313131; /* "widget.border" */
--vscode-input-background: #313131; /* "input.background" */
--vscode-input-foreground: #cccccc; /* "input.foreground" */
--vscode-input-border: #3c3c3c; /* "input.border" */
/**
* The styles below have been defined for Tailwind.
*/
/* I can't find these in the output of `Developer: Generate Color Theme From Current Settings` */
--vscode-charts-red: red;
--vscode-charts-blue: blue;
--vscode-charts-yellow: yellow;
--vscode-charts-orange: orange;
--vscode-charts-green: green;
--vscode-foreground: #d1d5da; /* "foreground" */
--vscode-editor-foreground: #e1e4e8; /* "editor.foreground" */
--vscode-editor-background: #24292e; /* "editor.background" */
--vscode-button-foreground: #dcffe4; /* "button.foreground" */
--vscode-button-background: #176f2c; /* "button.background" */
--vscode-button-secondaryForeground: #ffffff; /* "button.secondaryForeground" */
--vscode-button-secondaryBackground: #444d56; /* "button.secondaryBackground" */
--vscode-dropdown-foreground: #e1e4e8; /* "dropdown.foreground" */
--vscode-dropdown-background: #2f363d; /* "dropdown.background" */
--vscode-dropdown-border: #1b1f23; /* "dropdown.border" */
--vscode-input-foreground: #e1e4e8; /* "input.foreground" */
--vscode-input-background: #2f363d; /* "input.background" */
--vscode-input-border: #1b1f23; /* "input.border" */
--vscode-focusBorder: #005cc5; /* "focusBorder" */
--vscode-badge-foreground: #c8e1ff; /* "badge.foreground" */
--vscode-badge-background: #044289; /* "badge.background" */
--vscode-notifications-foreground: #e1e4e8; /* "notifications.foreground" */
--vscode-notifications-background: #2f363d; /* "notifications.background" */
--vscode-notifications-border: #1b1f23; /* "notifications.border" */
--vscode-descriptionForeground: #959da5; /* "descriptionForeground" */
--vscode-errorForeground: #f97583; /* "errorForeground" */
--vscode-list-hoverForeground: #e1e4e8; /* "list.hoverForeground" */
--vscode-list-hoverBackground: #282e34; /* "list.hoverBackground" */
--vscode-list-focusBackground: #044289; /* "list.focusBackground" */
/**
* The styles below are used in the @shadcn/ui + Tailwind theme but are
* not exposed as `--color-vscode-*` variables.
*/
--vscode-menu-background: #2f363d; /* "menu.background" [MISSING] */
--vscode-menu-foreground: #e1e4e8; /* "menu.foreground" [MISSING] */
--vscode-disabledForeground: #cccccc; /* "disabledForeground" [MISSING] */
}

File diff suppressed because it is too large Load diff

View file

@ -15,10 +15,14 @@
"build-storybook": "storybook build"
},
"dependencies": {
"@radix-ui/react-collapsible": "^1.1.3",
"@radix-ui/react-dialog": "^1.1.6",
"@radix-ui/react-dropdown-menu": "^2.1.5",
"@radix-ui/react-icons": "^1.3.2",
"@radix-ui/react-popover": "^1.1.6",
"@radix-ui/react-progress": "^1.1.2",
"@radix-ui/react-separator": "^1.1.2",
"@radix-ui/react-slider": "^1.2.3",
"@radix-ui/react-slot": "^1.1.1",
"@radix-ui/react-tooltip": "^1.1.8",
"@tailwindcss/vite": "^4.0.0",
@ -29,6 +33,7 @@
"debounce": "^2.1.1",
"fast-deep-equal": "^3.1.3",
"fzf": "^0.5.2",
"lucide-react": "^0.475.0",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-remark": "^2.1.0",
@ -44,12 +49,10 @@
"vscrui": "^0.2.0"
},
"devDependencies": {
"@storybook/addon-essentials": "^8.5.2",
"@storybook/addon-interactions": "^8.5.2",
"@storybook/blocks": "^8.5.2",
"@storybook/react": "^8.5.2",
"@storybook/react-vite": "^8.5.2",
"@storybook/test": "^8.5.2",
"@storybook/addon-essentials": "^8.5.6",
"@storybook/blocks": "^8.5.6",
"@storybook/react": "^8.5.6",
"@storybook/react-vite": "^8.5.6",
"@testing-library/jest-dom": "^6.6.3",
"@testing-library/react": "^16.2.0",
"@testing-library/user-event": "^14.6.1",
@ -72,7 +75,8 @@
"jest": "^27.5.1",
"jest-environment-jsdom": "^27.5.1",
"jest-simple-dot-reporter": "^1.0.5",
"storybook": "^8.5.2",
"storybook": "^8.5.6",
"storybook-dark-mode": "^4.0.2",
"ts-jest": "^27.1.5",
"typescript": "^4.9.5",
"vite": "6.0.11"

View file

@ -0,0 +1,105 @@
import * as React from "react"
import { cn } from "@/lib/utils"
interface UseAutosizeTextAreaProps {
textAreaRef: React.MutableRefObject<HTMLTextAreaElement | null>
minHeight?: number
maxHeight?: number
triggerAutoSize: string
}
export const useAutosizeTextArea = ({
textAreaRef,
triggerAutoSize,
maxHeight = Number.MAX_SAFE_INTEGER,
minHeight = 0,
}: UseAutosizeTextAreaProps) => {
const [init, setInit] = React.useState(true)
React.useEffect(() => {
// We need to reset the height momentarily to get the correct scrollHeight
// for the textarea.
const offsetBorder = 6
const textAreaElement = textAreaRef.current
if (textAreaElement) {
if (init) {
textAreaElement.style.minHeight = `${minHeight + offsetBorder}px`
if (maxHeight > minHeight) {
textAreaElement.style.maxHeight = `${maxHeight}px`
}
setInit(false)
}
textAreaElement.style.height = `${minHeight + offsetBorder}px`
const scrollHeight = textAreaElement.scrollHeight
// We then set the height directly, outside of the render loop
// Trying to set this with state or a ref will product an incorrect value.
if (scrollHeight > maxHeight) {
textAreaElement.style.height = `${maxHeight}px`
} else {
textAreaElement.style.height = `${scrollHeight + offsetBorder}px`
}
}
}, [init, minHeight, maxHeight, textAreaRef, triggerAutoSize])
}
export type AutosizeTextAreaRef = {
textArea: HTMLTextAreaElement
minHeight: number
maxHeight: number
}
type AutosizeTextAreaProps = {
minHeight: number
maxHeight: number
} & React.TextareaHTMLAttributes<HTMLTextAreaElement>
export const AutosizeTextarea = React.forwardRef<AutosizeTextAreaRef, AutosizeTextAreaProps>(
(
{ minHeight, maxHeight, className, onChange, value, ...props }: AutosizeTextAreaProps,
ref: React.Ref<AutosizeTextAreaRef>,
) => {
const textAreaRef = React.useRef<HTMLTextAreaElement | null>(null)
const [triggerAutoSize, setTriggerAutoSize] = React.useState("")
useAutosizeTextArea({
textAreaRef,
triggerAutoSize: triggerAutoSize,
maxHeight,
minHeight,
})
React.useImperativeHandle(ref, () => ({
textArea: textAreaRef.current as HTMLTextAreaElement,
focus: () => textAreaRef?.current?.focus(),
maxHeight,
minHeight,
}))
React.useEffect(() => {
setTriggerAutoSize(value as string)
}, [props?.defaultValue, value])
return (
<textarea
{...props}
value={value}
ref={textAreaRef}
className={cn(
"flex w-full text-vscode-input-foreground border border-vscode-input-border bg-vscode-input-background rounded-xs ring-offset-background placeholder:text-muted-foreground focus:outline-0 focus-visible:outline-none focus-visible:border-vscode-focusBorder disabled:cursor-not-allowed disabled:opacity-50 scrollbar-hide",
className,
)}
onChange={(e) => {
setTriggerAutoSize(e.target.value)
onChange?.(e)
}}
/>
)
},
)
AutosizeTextarea.displayName = "AutosizeTextarea"

View file

@ -0,0 +1,29 @@
import * as React from "react"
import { cva, type VariantProps } from "class-variance-authority"
import { cn } from "@/lib/utils"
const badgeVariants = cva(
"inline-flex items-center rounded-xs border border-transparent shadow px-2 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
{
variants: {
variant: {
default: "bg-primary text-primary-foreground hover:bg-primary/80",
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/80",
outline: "text-muted-foreground border-vscode-input-border",
},
},
defaultVariants: {
variant: "default",
},
},
)
export interface BadgeProps extends React.HTMLAttributes<HTMLDivElement>, VariantProps<typeof badgeVariants> {}
function Badge({ className, variant, ...props }: BadgeProps) {
return <div className={cn(badgeVariants({ variant }), className)} {...props} />
}
export { Badge, badgeVariants }

View file

@ -9,15 +9,15 @@ const buttonVariants = cva(
{
variants: {
variant: {
default: "bg-primary text-primary-foreground shadow hover:bg-primary/90",
secondary: "bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",
default: "text-primary-foreground bg-primary shadow hover:bg-primary/90",
secondary: "text-secondary-foreground bg-secondary shadow-sm hover:bg-secondary/80",
outline:
"border border-vscode-dropdown-border bg-vscode-background shadow-sm hover:border-vscode-dropdown-border/80",
ghost: "hover:bg-accent hover:text-accent-foreground",
"text-secondary-foreground bg-vscode-editor-background border border-vscode-dropdown-border shadow-sm hover:bg-vscode-editor-background/50",
ghost: "text-secondary-foreground hover:bg-accent hover:text-accent-foreground",
link: "text-primary underline-offset-4 hover:underline",
destructive: "bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90",
destructive: "text-destructive-foreground bg-destructive shadow-sm hover:bg-destructive/90",
combobox:
"bg-vscode-dropdown-background text-vscode-dropdown-foreground border border-vscode-dropdown-border",
"text-secondary-foreground bg-vscode-input-background border border-vscode-input-border hover:bg-vscode-input-background/80",
},
size: {
default: "h-7 px-3",

View file

@ -0,0 +1,9 @@
import * as CollapsiblePrimitive from "@radix-ui/react-collapsible"
const Collapsible = CollapsiblePrimitive.Root
const CollapsibleTrigger = CollapsiblePrimitive.CollapsibleTrigger
const CollapsibleContent = CollapsiblePrimitive.CollapsibleContent
export { Collapsible, CollapsibleTrigger, CollapsibleContent }

View file

@ -151,7 +151,11 @@ const DropdownMenuSeparator = React.forwardRef<
React.ElementRef<typeof DropdownMenuPrimitive.Separator>,
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Separator>
>(({ className, ...props }, ref) => (
<DropdownMenuPrimitive.Separator ref={ref} className={cn("-mx-1 my-1 h-px bg-muted", className)} {...props} />
<DropdownMenuPrimitive.Separator
ref={ref}
className={cn("-mx-1 my-1 h-px bg-vscode-input-border", className)}
{...props}
/>
))
DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName

View file

@ -1,6 +1,14 @@
export * from "./autosize-textarea"
export * from "./badge"
export * from "./button"
export * from "./collapsible"
export * from "./command"
export * from "./dialog"
export * from "./dropdown-menu"
export * from "./input"
export * from "./popover"
export * from "./progress"
export * from "./separator"
export * from "./slider"
export * from "./textarea"
export * from "./tooltip"

View file

@ -0,0 +1,22 @@
import * as React from "react"
import { cn } from "@/lib/utils"
const Input = React.forwardRef<HTMLInputElement, React.ComponentProps<"input">>(
({ className, type, ...props }, ref) => {
return (
<input
type={type}
className={cn(
"flex w-full text-vscode-input-foreground border border-vscode-input-border bg-vscode-input-background rounded-xs px-3 py-1 text-base transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus:outline-0 focus-visible:outline-none focus-visible:border-vscode-focusBorder disabled:cursor-not-allowed disabled:opacity-50",
className,
)}
ref={ref}
{...props}
/>
)
},
)
Input.displayName = "Input"
export { Input }

View file

@ -0,0 +1,22 @@
import * as React from "react"
import * as ProgressPrimitive from "@radix-ui/react-progress"
import { cn } from "@/lib/utils"
const Progress = React.forwardRef<
React.ElementRef<typeof ProgressPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof ProgressPrimitive.Root>
>(({ className, value, ...props }, ref) => (
<ProgressPrimitive.Root
ref={ref}
className={cn("relative h-2 w-full overflow-hidden rounded-full bg-vscode-editor-background", className)}
{...props}>
<ProgressPrimitive.Indicator
className="h-full w-full flex-1 bg-vscode-badge-background transition-all"
style={{ transform: `translateX(-${100 - (value || 0)}%)` }}
/>
</ProgressPrimitive.Root>
))
Progress.displayName = ProgressPrimitive.Root.displayName
export { Progress }

View file

@ -0,0 +1,24 @@
import * as React from "react"
import * as SeparatorPrimitive from "@radix-ui/react-separator"
import { cn } from "@/lib/utils"
const Separator = React.forwardRef<
React.ElementRef<typeof SeparatorPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof SeparatorPrimitive.Root>
>(({ className, orientation = "horizontal", decorative = true, ...props }, ref) => (
<SeparatorPrimitive.Root
ref={ref}
decorative={decorative}
orientation={orientation}
className={cn(
"shrink-0 bg-vscode-editor-background my-5",
orientation === "horizontal" ? "h-[1px] w-full" : "h-full w-[1px]",
className,
)}
{...props}
/>
))
Separator.displayName = SeparatorPrimitive.Root.displayName
export { Separator }

View file

@ -0,0 +1,22 @@
import * as React from "react"
import * as SliderPrimitive from "@radix-ui/react-slider"
import { cn } from "@/lib/utils"
const Slider = React.forwardRef<
React.ElementRef<typeof SliderPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof SliderPrimitive.Root>
>(({ className, ...props }, ref) => (
<SliderPrimitive.Root
ref={ref}
className={cn("relative flex w-full touch-none select-none items-center", className)}
{...props}>
<SliderPrimitive.Track className="relative h-1 w-full grow overflow-hidden bg-primary/20">
<SliderPrimitive.Range className="absolute h-full bg-primary" />
</SliderPrimitive.Track>
<SliderPrimitive.Thumb className="block h-3 w-3 rounded-full border border-primary/50 bg-primary shadow transition-colors cursor-pointer focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50" />
</SliderPrimitive.Root>
))
Slider.displayName = SliderPrimitive.Root.displayName
export { Slider }

View file

@ -0,0 +1,21 @@
import * as React from "react"
import { cn } from "@/lib/utils"
const Textarea = React.forwardRef<HTMLTextAreaElement, React.ComponentProps<"textarea">>(
({ className, ...props }, ref) => {
return (
<textarea
className={cn(
"flex min-h-[60px] w-full text-vscode-input-foreground border border-vscode-input-border bg-vscode-input-background rounded-xs px-3 py-2 text-base shadow-sm placeholder:text-muted-foreground focus:outline-0 focus-visible:outline-none focus-visible:border-vscode-focusBorder disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
className,
)}
ref={ref}
{...props}
/>
)
},
)
Textarea.displayName = "Textarea"
export { Textarea }

View file

@ -60,7 +60,6 @@
*/
--color-vscode-foreground: var(--vscode-foreground);
--color-vscode-background: var(--vscode-background);
--color-vscode-editor-foreground: var(--vscode-editor-foreground);
--color-vscode-editor-background: var(--vscode-editor-background);
@ -74,17 +73,25 @@
--color-vscode-dropdown-background: var(--vscode-dropdown-background);
--color-vscode-dropdown-border: var(--vscode-dropdown-border);
--color-vscode-input-foreground: var(--vscode-input-foreground);
--color-vscode-input-background: var(--vscode-input-background);
--color-vscode-input-border: var(--vscode-input-border);
--color-vscode-focusBorder: var(--vscode-focusBorder);
--color-vscode-badge-foreground: var(--vscode-badge-foreground);
--color-vscode-badge-background: var(--vscode-badge-background);
--color-vscode-notifications-foreground: var(--vscode-notifications-foreground);
--color-vscode-notifications-background: var(--vscode-notifications-background);
--color-vscode-notifications-border: var(--vscode-notifications-border);
--color-vscode-descriptionForeground: var(--vscode-descriptionForeground);
--color-vscode-errorForeground: var(--vscode-errorForeground);
--color-vscode-list-hoverForeground: var(--vscode-list-hoverForeground);
--color-vscode-list-hoverBackground: var(--vscode-list-hoverBackground);
--color-vscode-list-focusBackground: var(--vscode-list-focusBackground);
}
@layer base {
@ -137,10 +144,15 @@
}
/* Form Element Focus States */
textarea:focus {
outline: 1.5px solid var(--vscode-focusBorder, #007fd4);
}
.focus\:outline-0 {
outline: 0 !important; /* Allow tailwind to override the `textarea:focus` rule */
}
vscode-button::part(control):focus {
outline: none;
}
@ -201,19 +213,19 @@ body:focus-within .code-block-scrollable {
border-color: var(--vscode-scrollbarSlider-activeBackground);
}
/*
Fix VSCode ignoring webkit scrollbar modifiers
https://github.com/microsoft/vscode/issues/213045
*/
/**
* Fix VSCode ignoring webkit scrollbar modifiers
* https://github.com/microsoft/vscode/issues/213045
*/
@supports selector(::-webkit-scrollbar) {
html {
scrollbar-color: unset;
}
}
/*
The above scrollbar styling uses some transparent background color magic to accomplish its animation. However this doesn't play nicely with SyntaxHighlighter, so we need to set a background color for the code blocks' horizontal scrollbar. This actually has the unintended consequence of always showing the scrollbar which I prefer since it makes it more obvious that there is more content to scroll to.
*/
/**
* The above scrollbar styling uses some transparent background color magic to accomplish its animation. However this doesn't play nicely with SyntaxHighlighter, so we need to set a background color for the code blocks' horizontal scrollbar. This actually has the unintended consequence of always showing the scrollbar which I prefer since it makes it more obvious that there is more content to scroll to.
*/
.code-block-scrollable::-webkit-scrollbar-track {
background: transparent;
@ -238,6 +250,19 @@ The above scrollbar styling uses some transparent background color magic to acco
background-color: transparent;
}
/**
* Add a way to hide scrollbars.
*/
.scrollbar-hide {
-ms-overflow-style: none; /* IE and Edge */
scrollbar-width: none; /* Firefox */
}
.scrollbar-hide::-webkit-scrollbar {
display: none; /* Chrome, Safari and Opera */
}
/**
* Dropdown label
* https://github.com/microsoft/vscode-webview-ui-toolkit/tree/main/src/dropdown#with-label

View file

@ -0,0 +1,22 @@
import type { Meta, StoryObj } from "@storybook/react"
import { AutosizeTextarea } from "../components/ui/autosize-textarea"
const meta: Meta<typeof AutosizeTextarea> = {
title: "Primitives/AutosizeTextarea",
component: AutosizeTextarea,
tags: ["autodocs"],
args: {
minHeight: 40,
maxHeight: 400,
placeholder: "This textarea will expand as you type.",
className: "p-2",
},
}
export default meta
type Story = StoryObj<typeof AutosizeTextarea>
export const Default: Story = {
args: {},
}

View file

@ -0,0 +1,43 @@
import type { Meta, StoryObj } from "@storybook/react"
import { Badge } from "@/components/ui"
const meta: Meta<typeof Badge> = {
title: "Primitives/Badge",
component: Badge,
tags: ["autodocs"],
args: {
children: "Badge",
},
}
export default meta
type Story = StoryObj<typeof Badge>
export const Default: Story = {
args: {
children: "Default",
},
}
export const Secondary: Story = {
args: {
variant: "secondary",
children: "Secondary",
},
}
export const Destructive: Story = {
args: {
variant: "destructive",
children: "Destructive",
},
}
export const Outline: Story = {
args: {
variant: "outline",
children: "Outline",
},
}

View file

@ -3,7 +3,7 @@ import type { Meta, StoryObj } from "@storybook/react"
import { Button } from "@/components/ui"
const meta = {
title: "@shadcn/Button",
title: "primitives/Button",
component: Button,
parameters: { layout: "centered" },
tags: ["autodocs"],
@ -49,5 +49,47 @@ export default meta
type Story = StoryObj<typeof meta>
export const Default: Story = {
name: "Button",
name: "Default",
}
export const Secondary: Story = {
name: "Secondary",
args: {
variant: "secondary",
},
}
export const Destructive: Story = {
name: "Destructive",
args: {
variant: "destructive",
},
}
export const Outline: Story = {
name: "Outline",
args: {
variant: "outline",
},
}
export const Ghost: Story = {
name: "Ghost",
args: {
variant: "ghost",
},
}
export const Link: Story = {
name: "Link",
args: {
variant: "link",
},
}
export const Combobox: Story = {
name: "Combobox",
args: {
variant: "combobox",
},
}

View file

@ -0,0 +1,36 @@
import type { Meta, StoryObj } from "@storybook/react"
import { useState } from "react"
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "../components/ui/collapsible"
import { Button } from "../components/ui/button"
import { ChevronsUpDown } from "lucide-react"
const meta: Meta<typeof Collapsible> = {
title: "Primitives/Collapsible",
component: Collapsible,
tags: ["autodocs"],
}
export default meta
type Story = StoryObj<typeof Collapsible>
export const Default: Story = {
render: () => <CollapsibleDemo />,
}
const CollapsibleDemo = () => {
const [isOpen, setIsOpen] = useState(false)
return (
<Collapsible open={isOpen} onOpenChange={setIsOpen}>
<CollapsibleTrigger asChild>
<Button variant="ghost">
Hello
<ChevronsUpDown className="size-4" />
</Button>
</CollapsibleTrigger>
<CollapsibleContent className="p-2">👋</CollapsibleContent>
</Collapsible>
)
}

View file

@ -17,7 +17,7 @@ import {
} from "@/components/ui"
const meta = {
title: "@shadcn/Combobox",
title: "primitives/Combobox",
component: Combobox,
parameters: { layout: "centered" },
tags: ["autodocs"],
@ -62,7 +62,7 @@ function Combobox() {
return (
<Popover open={open} onOpenChange={setOpen}>
<PopoverTrigger asChild>
<Button variant="secondary" role="combobox" aria-expanded={open} className="w-[200px] justify-between">
<Button variant="combobox" role="combobox" aria-expanded={open} className="w-[200px] justify-between">
{value ? frameworks.find((framework) => framework.value === value)?.label : "Select framework..."}
<CaretSortIcon className="opacity-50" />
</Button>

View file

@ -27,7 +27,7 @@ import {
} from "@/components/ui"
const meta = {
title: "@shadcn/DropdownMenu",
title: "primitives/DropdownMenu",
component: DropdownMenu,
parameters: { layout: "centered" },
tags: ["autodocs"],

View file

@ -0,0 +1,25 @@
import type { Meta, StoryObj } from "@storybook/react"
import { Progress } from "@/components/ui"
const meta: Meta<typeof Progress> = {
title: "Primitives/Progress",
component: Progress,
parameters: {
layout: "centered",
},
args: {
className: "w-[300px]",
},
tags: ["autodocs"],
}
export default meta
type Story = StoryObj<typeof Progress>
export const Default: Story = {
args: {
value: 50,
},
}

View file

@ -0,0 +1,32 @@
import type { Meta, StoryObj } from "@storybook/react"
import { Slider } from "@/components/ui"
const meta: Meta<typeof Slider> = {
title: "Primitives/Slider",
component: Slider,
parameters: {
layout: "centered",
},
args: {
defaultValue: [50],
max: 100,
min: 0,
step: 1,
className: "w-[300px]",
},
tags: ["autodocs"],
}
export default meta
type Story = StoryObj<typeof Slider>
export const Default: Story = {
args: {
defaultValue: [50],
max: 100,
min: 0,
step: 1,
},
}

View file

@ -1,47 +0,0 @@
import type { Meta, StoryObj } from "@storybook/react"
import { Dropdown } from "vscrui"
const meta = {
title: "@vscrui/Dropdown",
component: () => (
<Dropdown
value="foo"
role="combobox"
options={[
{ value: "foo", label: "Foo" },
{ value: "bar", label: "Bar" },
{ value: "baz", label: "Baz" },
]}
/>
),
parameters: { layout: "centered" },
tags: ["autodocs"],
argTypes: {},
args: {},
} satisfies Meta<typeof Dropdown>
export default meta
type Story = StoryObj<typeof meta>
export const Default: Story = {
args: {},
parameters: {
docs: {
source: {
code: `
<Dropdown
value="foo"
role="combobox"
options={[
{ value: "foo", label: "Foo" },
{ value: "bar", label: "Bar" },
{ value: "baz", label: "Baz" }
]}
/>`,
language: "tsx",
},
},
},
}