chore: replace prettier with oxfmt (#8676)
This commit is contained in:
parent
9ee73d57ef
commit
41abaffc6e
1008 changed files with 4046 additions and 4027 deletions
|
|
@ -4,18 +4,6 @@
|
|||
"private": true,
|
||||
"license": "AGPL-3.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "tsdown --watch",
|
||||
"build": "tsdown",
|
||||
"check:lint": "eslint . --cache --cache-location node_modules/.cache/eslint/ --max-warnings=1306",
|
||||
"check:types": "tsc --noEmit",
|
||||
"check:format": "prettier . --cache --check",
|
||||
"fix:lint": "eslint . --cache --cache-location node_modules/.cache/eslint/ --fix --max-warnings=1306",
|
||||
"fix:format": "prettier . --cache --write",
|
||||
"clean": "rm -rf .turbo && rm -rf .next && rm -rf node_modules && rm -rf dist",
|
||||
"storybook": "storybook dev -p 6006",
|
||||
"build-storybook": "storybook build"
|
||||
},
|
||||
"exports": {
|
||||
"./accordion": "./dist/accordion/index.js",
|
||||
"./animated-counter": "./dist/animated-counter/index.js",
|
||||
|
|
@ -61,6 +49,18 @@
|
|||
"./styles/react-day-picker.css": "./dist/styles/react-day-picker.css",
|
||||
"./styles/react-day-picker": "./dist/styles/react-day-picker.css"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "tsdown --watch",
|
||||
"build": "tsdown",
|
||||
"check:lint": "eslint . --cache --cache-location node_modules/.cache/eslint/ --max-warnings=1306",
|
||||
"check:types": "tsc --noEmit",
|
||||
"check:format": "oxfmt --check .",
|
||||
"fix:lint": "eslint . --cache --cache-location node_modules/.cache/eslint/ --fix --max-warnings=1306",
|
||||
"fix:format": "oxfmt .",
|
||||
"clean": "rm -rf .turbo && rm -rf .next && rm -rf node_modules && rm -rf dist",
|
||||
"storybook": "storybook dev -p 6006",
|
||||
"build-storybook": "storybook build"
|
||||
},
|
||||
"dependencies": {
|
||||
"@base-ui-components/react": "1.0.0-beta.3",
|
||||
"@plane/constants": "workspace:*",
|
||||
|
|
|
|||
|
|
@ -182,7 +182,7 @@ export const AsChildTrigger: Story = {
|
|||
<Accordion.Root className="w-96">
|
||||
<Accordion.Item value="item-1">
|
||||
<Accordion.Trigger asChild>
|
||||
<button className="w-full rounded-md bg-blue-500 px-4 py-2 text-left text-on-color hover:bg-blue-600">
|
||||
<button className="bg-blue-500 hover:bg-blue-600 w-full rounded-md px-4 py-2 text-left text-on-color">
|
||||
Custom Button Trigger
|
||||
</button>
|
||||
</Accordion.Trigger>
|
||||
|
|
@ -192,7 +192,7 @@ export const AsChildTrigger: Story = {
|
|||
</Accordion.Item>
|
||||
<Accordion.Item value="item-2">
|
||||
<Accordion.Trigger asChild>
|
||||
<button className="w-full rounded-md bg-green-500 px-4 py-2 text-left text-on-color hover:bg-green-600">
|
||||
<button className="bg-green-500 hover:bg-green-600 w-full rounded-md px-4 py-2 text-left text-on-color">
|
||||
Another Custom Trigger
|
||||
</button>
|
||||
</Accordion.Trigger>
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ function AccordionItem({ value, disabled, className = "", children }: AccordionI
|
|||
|
||||
function AccordionTrigger({
|
||||
className = "",
|
||||
icon = <PlusIcon aria-hidden="true" className="transition-all ease-out group-data-[panel-open]:rotate-45" />,
|
||||
icon = <PlusIcon aria-hidden="true" className="transition-all ease-out group-data-[panel-open]:rotate-45" />,
|
||||
iconClassName = "",
|
||||
children,
|
||||
asChild = false,
|
||||
|
|
|
|||
|
|
@ -32,16 +32,16 @@ export const Default: Story = {
|
|||
<div className="space-y-6 p-4">
|
||||
<div className="flex items-center justify-center gap-6">
|
||||
<button
|
||||
className="px-4 py-2 bg-red-500 text-on-color font-medium rounded-lg hover:bg-red-600 focus:outline-none focus:ring-2 focus:ring-danger-strong focus:ring-offset-2 transition-colors shadow-md"
|
||||
className="bg-red-500 hover:bg-red-600 shadow-md rounded-lg px-4 py-2 font-medium text-on-color transition-colors focus:ring-2 focus:ring-danger-strong focus:ring-offset-2 focus:outline-none"
|
||||
onClick={() => setCount((prev) => Math.max(0, prev - 1))}
|
||||
>
|
||||
-1
|
||||
</button>
|
||||
<div className="flex items-center justify-center min-w-[60px] h-12 bg-gray-50 border border-gray-200 rounded-lg">
|
||||
<div className="bg-gray-50 border-gray-200 flex h-12 min-w-[60px] items-center justify-center rounded-lg border">
|
||||
<AnimatedCounter {...args} count={count} />
|
||||
</div>
|
||||
<button
|
||||
className="px-4 py-2 bg-green-500 text-on-color font-medium rounded-lg hover:bg-green-600 focus:outline-none focus:ring-2 focus:ring-success-strong focus:ring-offset-2 transition-colors shadow-md"
|
||||
className="bg-green-500 hover:bg-green-600 shadow-md rounded-lg px-4 py-2 font-medium text-on-color transition-colors focus:ring-2 focus:ring-success-strong focus:ring-offset-2 focus:outline-none"
|
||||
onClick={() => setCount((prev) => prev + 1)}
|
||||
>
|
||||
+1
|
||||
|
|
@ -60,13 +60,13 @@ export const Sizes: Story = {
|
|||
<div className="space-y-6 p-4">
|
||||
<div className="flex items-center gap-4">
|
||||
<button
|
||||
className="px-3 py-1 bg-layer-1 text-13 rounded-sm hover:bg-surface-2"
|
||||
className="rounded-sm bg-layer-1 px-3 py-1 text-13 hover:bg-surface-2"
|
||||
onClick={() => setCount((prev) => Math.max(0, prev - 1))}
|
||||
>
|
||||
-1
|
||||
</button>
|
||||
<button
|
||||
className="px-3 py-1 bg-layer-1 text-13 rounded-sm hover:bg-surface-2"
|
||||
className="rounded-sm bg-layer-1 px-3 py-1 text-13 hover:bg-surface-2"
|
||||
onClick={() => setCount((prev) => prev + 1)}
|
||||
>
|
||||
+1
|
||||
|
|
@ -74,20 +74,20 @@ export const Sizes: Story = {
|
|||
</div>
|
||||
<div className="flex flex-col gap-4">
|
||||
<div className="flex items-center gap-4">
|
||||
<span className="text-13 text-placeholder w-20">Small:</span>
|
||||
<div className="flex items-center justify-center min-w-[40px] h-8 bg-layer-1 border border-subtle rounded-sm">
|
||||
<span className="w-20 text-13 text-placeholder">Small:</span>
|
||||
<div className="flex h-8 min-w-[40px] items-center justify-center rounded-sm border border-subtle bg-layer-1">
|
||||
<AnimatedCounter count={count} size="sm" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center gap-4">
|
||||
<span className="text-13 text-placeholder w-20">Medium:</span>
|
||||
<div className="flex items-center justify-center min-w-[50px] h-10 bg-layer-1 border border-subtle rounded-sm">
|
||||
<span className="w-20 text-13 text-placeholder">Medium:</span>
|
||||
<div className="flex h-10 min-w-[50px] items-center justify-center rounded-sm border border-subtle bg-layer-1">
|
||||
<AnimatedCounter count={count} size="md" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center gap-4">
|
||||
<span className="text-13 text-placeholder w-20">Large:</span>
|
||||
<div className="flex items-center justify-center min-w-[60px] h-12 bg-layer-1 border border-subtle rounded-sm">
|
||||
<span className="w-20 text-13 text-placeholder">Large:</span>
|
||||
<div className="flex h-12 min-w-[60px] items-center justify-center rounded-sm border border-subtle bg-layer-1">
|
||||
<AnimatedCounter count={count} size="lg" />
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -105,19 +105,19 @@ export const LargeNumbers: Story = {
|
|||
<div className="space-y-6 p-4">
|
||||
<div className="flex items-center gap-4">
|
||||
<button
|
||||
className="px-3 py-1 bg-red-500 text-on-color text-13 rounded-sm hover:bg-red-600"
|
||||
className="bg-red-500 hover:bg-red-600 rounded-sm px-3 py-1 text-13 text-on-color"
|
||||
onClick={() => setCount((prev) => Math.max(0, prev - 1000))}
|
||||
>
|
||||
-1000
|
||||
</button>
|
||||
<button
|
||||
className="px-3 py-1 bg-green-500 text-on-color text-13 rounded-sm hover:bg-green-600"
|
||||
className="bg-green-500 hover:bg-green-600 rounded-sm px-3 py-1 text-13 text-on-color"
|
||||
onClick={() => setCount((prev) => prev + 1000)}
|
||||
>
|
||||
+1000
|
||||
</button>
|
||||
</div>
|
||||
<div className="flex items-center justify-center min-w-[100px] h-12 bg-layer-1 border border-subtle rounded-lg">
|
||||
<div className="flex h-12 min-w-[100px] items-center justify-center rounded-lg border border-subtle bg-layer-1">
|
||||
<AnimatedCounter count={count} size="lg" />
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -148,11 +148,11 @@ export const Countdown: Story = {
|
|||
return (
|
||||
<div className="space-y-6 p-4">
|
||||
<div className="flex flex-col items-center gap-4">
|
||||
<div className="flex items-center justify-center min-w-[60px] h-16 bg-layer-1 border-2 border-subtle rounded-lg">
|
||||
<div className="flex h-16 min-w-[60px] items-center justify-center rounded-lg border-2 border-subtle bg-layer-1">
|
||||
<AnimatedCounter count={count} size="lg" className="text-20" />
|
||||
</div>
|
||||
<button
|
||||
className="px-6 py-2 bg-accent-primary text-on-color font-medium rounded-lg hover:bg-accent-primary/80"
|
||||
className="rounded-lg bg-accent-primary px-6 py-2 font-medium text-on-color hover:bg-accent-primary/80"
|
||||
onClick={handleStart}
|
||||
disabled={isRunning}
|
||||
>
|
||||
|
|
@ -179,26 +179,26 @@ export const LiveCounter: Story = {
|
|||
return (
|
||||
<div className="space-y-6 p-4">
|
||||
<div className="flex flex-col items-center gap-4">
|
||||
<div className="flex items-center justify-center min-w-[80px] h-16 bg-layer-1 border-2 border-subtle rounded-lg">
|
||||
<div className="flex h-16 min-w-[80px] items-center justify-center rounded-lg border-2 border-subtle bg-layer-1">
|
||||
<AnimatedCounter count={count} size="lg" className="text-20" />
|
||||
</div>
|
||||
<div className="flex gap-2">
|
||||
<button
|
||||
className="px-4 py-2 bg-green-500 text-on-color font-medium rounded-sm hover:bg-green-600"
|
||||
className="bg-green-500 hover:bg-green-600 rounded-sm px-4 py-2 font-medium text-on-color"
|
||||
onClick={() => setIsRunning(true)}
|
||||
disabled={isRunning}
|
||||
>
|
||||
Start
|
||||
</button>
|
||||
<button
|
||||
className="px-4 py-2 bg-red-500 text-on-color font-medium rounded-sm hover:bg-red-600"
|
||||
className="bg-red-500 hover:bg-red-600 rounded-sm px-4 py-2 font-medium text-on-color"
|
||||
onClick={() => setIsRunning(false)}
|
||||
disabled={!isRunning}
|
||||
>
|
||||
Stop
|
||||
</button>
|
||||
<button
|
||||
className="px-4 py-2 bg-gray-500 text-on-color font-medium rounded-sm hover:bg-gray-600"
|
||||
className="bg-gray-500 hover:bg-gray-600 rounded-sm px-4 py-2 font-medium text-on-color"
|
||||
onClick={() => {
|
||||
setIsRunning(false);
|
||||
setCount(0);
|
||||
|
|
@ -221,49 +221,49 @@ export const MultipleCounters: Story = {
|
|||
|
||||
return (
|
||||
<div className="space-y-6 p-4">
|
||||
<div className="max-w-md border border-subtle rounded-lg p-4">
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<div className="max-w-md rounded-lg border border-subtle p-4">
|
||||
<div className="mb-4 flex items-center justify-between">
|
||||
<h3 className="font-medium">Engagement Stats</h3>
|
||||
</div>
|
||||
<div className="flex gap-4">
|
||||
<div className="flex-1 flex flex-col items-center gap-2">
|
||||
<div className="text-placeholder text-13">Likes</div>
|
||||
<div className="flex flex-1 flex-col items-center gap-2">
|
||||
<div className="text-13 text-placeholder">Likes</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<button
|
||||
className="w-8 h-8 flex items-center justify-center bg-layer-1 rounded-sm hover:bg-surface-2"
|
||||
className="flex h-8 w-8 items-center justify-center rounded-sm bg-layer-1 hover:bg-surface-2"
|
||||
onClick={() => setLikes((prev) => prev + 1)}
|
||||
>
|
||||
+
|
||||
</button>
|
||||
<div className="flex items-center justify-center min-w-[40px] h-10 bg-layer-1 border border-subtle rounded-sm">
|
||||
<div className="flex h-10 min-w-[40px] items-center justify-center rounded-sm border border-subtle bg-layer-1">
|
||||
<AnimatedCounter count={likes} size="md" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex-1 flex flex-col items-center gap-2">
|
||||
<div className="text-placeholder text-13">Comments</div>
|
||||
<div className="flex flex-1 flex-col items-center gap-2">
|
||||
<div className="text-13 text-placeholder">Comments</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<button
|
||||
className="w-8 h-8 flex items-center justify-center bg-layer-1 rounded-sm hover:bg-surface-2"
|
||||
className="flex h-8 w-8 items-center justify-center rounded-sm bg-layer-1 hover:bg-surface-2"
|
||||
onClick={() => setComments((prev) => prev + 1)}
|
||||
>
|
||||
+
|
||||
</button>
|
||||
<div className="flex items-center justify-center min-w-[40px] h-10 bg-layer-1 border border-subtle rounded-sm">
|
||||
<div className="flex h-10 min-w-[40px] items-center justify-center rounded-sm border border-subtle bg-layer-1">
|
||||
<AnimatedCounter count={comments} size="md" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex-1 flex flex-col items-center gap-2">
|
||||
<div className="text-placeholder text-13">Shares</div>
|
||||
<div className="flex flex-1 flex-col items-center gap-2">
|
||||
<div className="text-13 text-placeholder">Shares</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<button
|
||||
className="w-8 h-8 flex items-center justify-center bg-layer-1 rounded-sm hover:bg-surface-2"
|
||||
className="flex h-8 w-8 items-center justify-center rounded-sm bg-layer-1 hover:bg-surface-2"
|
||||
onClick={() => setShares((prev) => prev + 1)}
|
||||
>
|
||||
+
|
||||
</button>
|
||||
<div className="flex items-center justify-center min-w-[40px] h-10 bg-layer-1 border border-subtle rounded-sm">
|
||||
<div className="flex h-10 min-w-[40px] items-center justify-center rounded-sm border border-subtle bg-layer-1">
|
||||
<AnimatedCounter count={shares} size="md" />
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -283,13 +283,13 @@ export const InBadge: Story = {
|
|||
<div className="space-y-6 p-4">
|
||||
<div className="flex flex-col items-center gap-4">
|
||||
<div className="relative">
|
||||
<button className="px-4 py-2 bg-layer-1 border border-subtle rounded-lg">Notifications</button>
|
||||
<div className="absolute -top-2 -right-2 min-w-[24px] h-6 flex items-center justify-center bg-red-500 text-on-color rounded-full px-1.5">
|
||||
<button className="rounded-lg border border-subtle bg-layer-1 px-4 py-2">Notifications</button>
|
||||
<div className="bg-red-500 absolute -top-2 -right-2 flex h-6 min-w-[24px] items-center justify-center rounded-full px-1.5 text-on-color">
|
||||
<AnimatedCounter count={notifications} size="sm" className="text-11 font-medium" />
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
className="px-4 py-2 bg-accent-primary text-on-color rounded-sm hover:bg-accent-primary/80"
|
||||
className="rounded-sm bg-accent-primary px-4 py-2 text-on-color hover:bg-accent-primary/80"
|
||||
onClick={() => setNotifications((prev) => prev + 1)}
|
||||
>
|
||||
Add Notification
|
||||
|
|
@ -313,17 +313,17 @@ export const FastAnimation: Story = {
|
|||
return (
|
||||
<div className="space-y-6 p-4">
|
||||
<div className="flex flex-col items-center gap-4">
|
||||
<div className="flex items-center justify-center min-w-[60px] h-12 bg-layer-1 border border-subtle rounded-lg">
|
||||
<div className="flex h-12 min-w-[60px] items-center justify-center rounded-lg border border-subtle bg-layer-1">
|
||||
<AnimatedCounter count={count} size="lg" />
|
||||
</div>
|
||||
<div className="flex gap-2">
|
||||
<button
|
||||
className="px-4 py-2 bg-accent-primary text-on-color rounded-sm hover:bg-accent-primary/80"
|
||||
className="rounded-sm bg-accent-primary px-4 py-2 text-on-color hover:bg-accent-primary/80"
|
||||
onClick={incrementFast}
|
||||
>
|
||||
+10 Fast
|
||||
</button>
|
||||
<button className="px-4 py-2 bg-layer-1 rounded-sm hover:bg-surface-2" onClick={() => setCount(0)}>
|
||||
<button className="rounded-sm bg-layer-1 px-4 py-2 hover:bg-surface-2" onClick={() => setCount(0)}>
|
||||
Reset
|
||||
</button>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ export function AnimatedCounter({ count, className, size = "md" }: AnimatedCount
|
|||
const sizeClass = sizeClasses[size];
|
||||
|
||||
return (
|
||||
<div className={cn("relative inline-flex items-center justify-center overflow-hidden min-w-2", sizeClass)}>
|
||||
<div className={cn("relative inline-flex min-w-2 items-center justify-center overflow-hidden", sizeClass)}>
|
||||
{/* Previous number sliding out */}
|
||||
{isAnimating && (
|
||||
<span
|
||||
|
|
@ -62,8 +62,8 @@ export function AnimatedCounter({ count, className, size = "md" }: AnimatedCount
|
|||
direction === "down" && "[--slide-out-dir:100%]",
|
||||
sizeClass,
|
||||
{
|
||||
"animate-slide-out animate-fade-out": isAnimating && direction === "up",
|
||||
"animate-slide-out-down animate-fade-out": isAnimating && direction === "down",
|
||||
"animate-fade-out animate-slide-out": isAnimating && direction === "up",
|
||||
"animate-fade-out animate-slide-out-down": isAnimating && direction === "down",
|
||||
}
|
||||
)}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -17,9 +17,9 @@ export const badgeVariants = cva("inline-flex items-center justify-center gap-1
|
|||
danger: "bg-danger-subtle text-danger-primary",
|
||||
},
|
||||
size: {
|
||||
sm: "h-4 px-1 text-caption-sm-medium rounded-sm",
|
||||
base: "h-5 px-1.5 text-caption-sm-medium rounded-md",
|
||||
lg: "h-6 px-2 text-caption-md-medium rounded-md",
|
||||
sm: "h-4 rounded-sm px-1 text-caption-sm-medium",
|
||||
base: "h-5 rounded-md px-1.5 text-caption-sm-medium",
|
||||
lg: "h-6 rounded-md px-2 text-caption-md-medium",
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
|
|
|
|||
|
|
@ -122,7 +122,7 @@ function CloseButton({ onClick }: { onClick?: () => void }) {
|
|||
return (
|
||||
<button
|
||||
onClick={onClick}
|
||||
className="rounded-sm p-1 hover:bg-black/5 dark:hover:bg-white/5 transition-colors"
|
||||
className="rounded-sm p-1 transition-colors hover:bg-black/5 dark:hover:bg-white/5"
|
||||
aria-label="Dismiss"
|
||||
>
|
||||
<svg
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ export const Banner = React.forwardRef(function Banner(
|
|||
{...props}
|
||||
>
|
||||
{/* Left side: Icon and Title */}
|
||||
<div className="flex items-center gap-3 flex-1 min-w-0">
|
||||
<div className="flex min-w-0 flex-1 items-center gap-3">
|
||||
{renderIcon()}
|
||||
{title && <div className={cn(titleStyling)}>{title}</div>}
|
||||
{children}
|
||||
|
|
|
|||
|
|
@ -13,24 +13,24 @@ export const buttonVariants = cva(
|
|||
variants: {
|
||||
variant: {
|
||||
primary:
|
||||
"bg-accent-primary hover:bg-accent-primary-hover active:bg-accent-primary-active disabled:bg-layer-disabled text-on-color disabled:text-on-color-disabled",
|
||||
"bg-accent-primary text-on-color hover:bg-accent-primary-hover active:bg-accent-primary-active disabled:bg-layer-disabled disabled:text-on-color-disabled",
|
||||
"error-fill":
|
||||
"bg-danger-primary hover:bg-danger-primary-hover active:bg-danger-primary-active disabled:bg-layer-disabled text-on-color disabled:text-disabled",
|
||||
"bg-danger-primary text-on-color hover:bg-danger-primary-hover active:bg-danger-primary-active disabled:bg-layer-disabled disabled:text-disabled",
|
||||
"error-outline":
|
||||
"bg-layer-2 hover:bg-danger-subtle active:bg-danger-subtle-hover disabled:bg-layer-2 text-danger-primary disabled:text-disabled border border-danger-strong disabled:border-subtle-1",
|
||||
"border border-danger-strong bg-layer-2 text-danger-primary hover:bg-danger-subtle active:bg-danger-subtle-hover disabled:border-subtle-1 disabled:bg-layer-2 disabled:text-disabled",
|
||||
secondary:
|
||||
"bg-layer-2 hover:bg-layer-2-hover active:bg-layer-2-active disabled:bg-layer-transparent text-secondary disabled:text-disabled border border-strong disabled:border-subtle-1 shadow-raised-100",
|
||||
"border border-strong bg-layer-2 text-secondary shadow-raised-100 hover:bg-layer-2-hover active:bg-layer-2-active disabled:border-subtle-1 disabled:bg-layer-transparent disabled:text-disabled",
|
||||
tertiary:
|
||||
"bg-layer-3 hover:bg-layer-3-hover active:bg-layer-3-active disabled:bg-layer-transparent text-secondary disabled:text-disabled",
|
||||
"bg-layer-3 text-secondary hover:bg-layer-3-hover active:bg-layer-3-active disabled:bg-layer-transparent disabled:text-disabled",
|
||||
ghost:
|
||||
"bg-layer-transparent hover:bg-layer-transparent-hover active:bg-layer-transparent-active focus:bg-layer-transparent-active disabled:bg-layer-transparent text-secondary disabled:text-disabled",
|
||||
link: "px-0 underline text-link-primary hover:text-link-primary-hover active:text-link-primary-hover focus:text-link-primary-hover disabled:text-disabled",
|
||||
"bg-layer-transparent text-secondary hover:bg-layer-transparent-hover focus:bg-layer-transparent-active active:bg-layer-transparent-active disabled:bg-layer-transparent disabled:text-disabled",
|
||||
link: "px-0 text-link-primary underline hover:text-link-primary-hover focus:text-link-primary-hover active:text-link-primary-hover disabled:text-disabled",
|
||||
},
|
||||
size: {
|
||||
sm: "h-5 px-1.5 text-caption-md-medium rounded-sm",
|
||||
base: "h-6 px-2 text-body-xs-medium rounded-md",
|
||||
lg: "h-7 px-2 text-body-xs-medium rounded-md",
|
||||
xl: "h-8 px-2 text-body-sm-medium rounded-md",
|
||||
sm: "h-5 rounded-sm px-1.5 text-caption-md-medium",
|
||||
base: "h-6 rounded-md px-2 text-body-xs-medium",
|
||||
lg: "h-7 rounded-md px-2 text-body-xs-medium",
|
||||
xl: "h-8 rounded-md px-2 text-body-sm-medium",
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ const meta = {
|
|||
children: (
|
||||
<>
|
||||
<h3 className="text-16 font-semibold">Card Title</h3>
|
||||
<p className="text-13 text-gray-600">This is a default card with shadow and large spacing.</p>
|
||||
<p className="text-gray-600 text-13">This is a default card with shadow and large spacing.</p>
|
||||
</>
|
||||
),
|
||||
},
|
||||
|
|
@ -35,7 +35,7 @@ export const WithShadow: Story = {
|
|||
children: (
|
||||
<>
|
||||
<h3 className="text-16 font-semibold">Card with Shadow</h3>
|
||||
<p className="text-13 text-gray-600">Hover over this card to see the shadow effect.</p>
|
||||
<p className="text-gray-600 text-13">Hover over this card to see the shadow effect.</p>
|
||||
</>
|
||||
),
|
||||
},
|
||||
|
|
@ -47,7 +47,7 @@ export const WithoutShadow: Story = {
|
|||
children: (
|
||||
<>
|
||||
<h3 className="text-16 font-semibold">Card without Shadow</h3>
|
||||
<p className="text-13 text-gray-600">This card has no shadow effect on hover.</p>
|
||||
<p className="text-gray-600 text-13">This card has no shadow effect on hover.</p>
|
||||
</>
|
||||
),
|
||||
},
|
||||
|
|
@ -59,7 +59,7 @@ export const SmallSpacing: Story = {
|
|||
children: (
|
||||
<>
|
||||
<h3 className="text-16 font-semibold">Small Spacing</h3>
|
||||
<p className="text-13 text-gray-600">This card uses small spacing (p-4).</p>
|
||||
<p className="text-gray-600 text-13">This card uses small spacing (p-4).</p>
|
||||
</>
|
||||
),
|
||||
},
|
||||
|
|
@ -71,7 +71,7 @@ export const LargeSpacing: Story = {
|
|||
children: (
|
||||
<>
|
||||
<h3 className="text-16 font-semibold">Large Spacing</h3>
|
||||
<p className="text-13 text-gray-600">This card uses large spacing (p-6).</p>
|
||||
<p className="text-gray-600 text-13">This card uses large spacing (p-6).</p>
|
||||
</>
|
||||
),
|
||||
},
|
||||
|
|
@ -83,8 +83,8 @@ export const ColumnDirection: Story = {
|
|||
children: (
|
||||
<>
|
||||
<h3 className="text-16 font-semibold">Column Direction</h3>
|
||||
<p className="text-13 text-gray-600">Content is arranged vertically.</p>
|
||||
<button className="rounded-sm bg-blue-500 px-4 py-2 text-on-color">Action</button>
|
||||
<p className="text-gray-600 text-13">Content is arranged vertically.</p>
|
||||
<button className="bg-blue-500 rounded-sm px-4 py-2 text-on-color">Action</button>
|
||||
</>
|
||||
),
|
||||
},
|
||||
|
|
@ -96,11 +96,11 @@ export const RowDirection: Story = {
|
|||
children: (
|
||||
<>
|
||||
<div className="flex-shrink-0">
|
||||
<div className="h-12 w-12 rounded-sm bg-blue-500" />
|
||||
<div className="bg-blue-500 h-12 w-12 rounded-sm" />
|
||||
</div>
|
||||
<div className="flex-1">
|
||||
<h3 className="text-16 font-semibold">Row Direction</h3>
|
||||
<p className="text-13 text-gray-600">Content is arranged horizontally.</p>
|
||||
<p className="text-gray-600 text-13">Content is arranged horizontally.</p>
|
||||
</div>
|
||||
</>
|
||||
),
|
||||
|
|
@ -114,12 +114,12 @@ export const ProductCard: Story = {
|
|||
direction: ECardDirection.COLUMN,
|
||||
children: (
|
||||
<>
|
||||
<div className="h-48 w-full rounded-sm bg-gray-200" />
|
||||
<div className="bg-gray-200 h-48 w-full rounded-sm" />
|
||||
<h3 className="text-18 font-bold">Product Name</h3>
|
||||
<p className="text-13 text-gray-600">A brief description of the product goes here.</p>
|
||||
<p className="text-gray-600 text-13">A brief description of the product goes here.</p>
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="text-16 font-semibold">$99.99</span>
|
||||
<button className="rounded-sm bg-blue-500 px-4 py-2 text-on-color hover:bg-blue-600">Add to Cart</button>
|
||||
<button className="bg-blue-500 hover:bg-blue-600 rounded-sm px-4 py-2 text-on-color">Add to Cart</button>
|
||||
</div>
|
||||
</>
|
||||
),
|
||||
|
|
@ -133,11 +133,11 @@ export const UserCard: Story = {
|
|||
direction: ECardDirection.ROW,
|
||||
children: (
|
||||
<>
|
||||
<div className="h-16 w-16 flex-shrink-0 rounded-full bg-blue-500" />
|
||||
<div className="bg-blue-500 h-16 w-16 flex-shrink-0 rounded-full" />
|
||||
<div className="flex-1">
|
||||
<h3 className="text-16 font-semibold">John Doe</h3>
|
||||
<p className="text-13 text-gray-600">Software Engineer</p>
|
||||
<p className="text-11 text-gray-500">john.doe@example.com</p>
|
||||
<p className="text-gray-600 text-13">Software Engineer</p>
|
||||
<p className="text-gray-500 text-11">john.doe@example.com</p>
|
||||
</div>
|
||||
</>
|
||||
),
|
||||
|
|
@ -153,9 +153,9 @@ export const NotificationCard: Story = {
|
|||
<>
|
||||
<div className="flex items-start justify-between">
|
||||
<h4 className="font-semibold">New Message</h4>
|
||||
<span className="text-11 text-gray-500">2m ago</span>
|
||||
<span className="text-gray-500 text-11">2m ago</span>
|
||||
</div>
|
||||
<p className="text-13 text-gray-600">You have received a new message from Alice.</p>
|
||||
<p className="text-gray-600 text-13">You have received a new message from Alice.</p>
|
||||
</>
|
||||
),
|
||||
},
|
||||
|
|
@ -167,11 +167,11 @@ export const AllVariants: Story = {
|
|||
<div className="space-y-4">
|
||||
<Card variant={ECardVariant.WITH_SHADOW}>
|
||||
<h3 className="font-semibold">With Shadow</h3>
|
||||
<p className="text-13 text-gray-600">Hover to see the shadow effect</p>
|
||||
<p className="text-gray-600 text-13">Hover to see the shadow effect</p>
|
||||
</Card>
|
||||
<Card variant={ECardVariant.WITHOUT_SHADOW}>
|
||||
<h3 className="font-semibold">Without Shadow</h3>
|
||||
<p className="text-13 text-gray-600">No shadow on hover</p>
|
||||
<p className="text-gray-600 text-13">No shadow on hover</p>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
|
|
@ -184,11 +184,11 @@ export const AllSpacings: Story = {
|
|||
<div className="space-y-4">
|
||||
<Card spacing={ECardSpacing.SM}>
|
||||
<h3 className="font-semibold">Small Spacing (p-4)</h3>
|
||||
<p className="text-13 text-gray-600">Compact padding</p>
|
||||
<p className="text-gray-600 text-13">Compact padding</p>
|
||||
</Card>
|
||||
<Card spacing={ECardSpacing.LG}>
|
||||
<h3 className="font-semibold">Large Spacing (p-6)</h3>
|
||||
<p className="text-13 text-gray-600">More generous padding</p>
|
||||
<p className="text-gray-600 text-13">More generous padding</p>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
|
|
@ -201,14 +201,14 @@ export const AllDirections: Story = {
|
|||
<div className="space-y-4">
|
||||
<Card direction={ECardDirection.COLUMN}>
|
||||
<h3 className="font-semibold">Column Direction</h3>
|
||||
<p className="text-13 text-gray-600">Vertical layout</p>
|
||||
<button className="w-fit rounded-sm bg-blue-500 px-4 py-2 text-on-color">Button</button>
|
||||
<p className="text-gray-600 text-13">Vertical layout</p>
|
||||
<button className="bg-blue-500 w-fit rounded-sm px-4 py-2 text-on-color">Button</button>
|
||||
</Card>
|
||||
<Card direction={ECardDirection.ROW}>
|
||||
<div className="h-12 w-12 flex-shrink-0 rounded-sm bg-blue-500" />
|
||||
<div className="bg-blue-500 h-12 w-12 flex-shrink-0 rounded-sm" />
|
||||
<div>
|
||||
<h3 className="font-semibold">Row Direction</h3>
|
||||
<p className="text-13 text-gray-600">Horizontal layout</p>
|
||||
<p className="text-gray-600 text-13">Horizontal layout</p>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -50,17 +50,17 @@ const CustomLegend = React.forwardRef(function CustomLegend(
|
|||
return (
|
||||
<div
|
||||
ref={ref}
|
||||
className={cn("flex items-center px-4 overflow-scroll vertical-scrollbar scrollbar-sm", {
|
||||
className={cn("vertical-scrollbar flex scrollbar-sm items-center overflow-scroll px-4", {
|
||||
"max-h-full flex-col items-start py-4": layout === "vertical",
|
||||
})}
|
||||
>
|
||||
{payload.map((item, index) => (
|
||||
<div
|
||||
key={item.value}
|
||||
className={cn("flex items-center gap-1.5 text-tertiary text-13 font-medium whitespace-nowrap", {
|
||||
className={cn("flex items-center gap-1.5 text-13 font-medium whitespace-nowrap text-tertiary", {
|
||||
"px-2": layout === "horizontal",
|
||||
"py-2": layout === "vertical",
|
||||
"pl-0 pt-0": index === 0,
|
||||
"pt-0 pl-0": index === 0,
|
||||
"pr-0 pb-0": index === payload.length - 1,
|
||||
"cursor-pointer": !!props.onClick,
|
||||
})}
|
||||
|
|
@ -69,7 +69,7 @@ const CustomLegend = React.forwardRef(function CustomLegend(
|
|||
onMouseLeave={(e) => onMouseLeave?.(item, index, e)}
|
||||
>
|
||||
<div
|
||||
className="flex-shrink-0 size-2 rounded-xs"
|
||||
className="size-2 flex-shrink-0 rounded-xs"
|
||||
style={{
|
||||
backgroundColor: item.color,
|
||||
}}
|
||||
|
|
|
|||
|
|
@ -28,10 +28,10 @@ export const CustomTooltip = React.memo(function CustomTooltip(props: Props) {
|
|||
|
||||
return (
|
||||
<Card
|
||||
className="flex flex-col max-h-[40vh] w-[12rem] overflow-y-scroll vertical-scrollbar scrollbar-sm"
|
||||
className="vertical-scrollbar flex scrollbar-sm max-h-[40vh] w-[12rem] flex-col overflow-y-scroll"
|
||||
spacing={ECardSpacing.SM}
|
||||
>
|
||||
<p className="flex-shrink-0 text-11 text-primary font-medium border-b border-subtle pb-2 truncate">{label}</p>
|
||||
<p className="flex-shrink-0 truncate border-b border-subtle pb-2 text-11 font-medium text-primary">{label}</p>
|
||||
{filteredPayload.map((item) => {
|
||||
if (!item.dataKey) return null;
|
||||
|
||||
|
|
@ -45,13 +45,13 @@ export const CustomTooltip = React.memo(function CustomTooltip(props: Props) {
|
|||
<div className="flex items-center gap-2 truncate">
|
||||
{itemDotColors[item?.dataKey] && (
|
||||
<div
|
||||
className="flex-shrink-0 size-2 rounded-xs"
|
||||
className="size-2 flex-shrink-0 rounded-xs"
|
||||
style={{
|
||||
backgroundColor: itemDotColors[item?.dataKey],
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
<span className="text-tertiary truncate">{itemLabels[item?.dataKey]}:</span>
|
||||
<span className="truncate text-tertiary">{itemLabels[item?.dataKey]}:</span>
|
||||
</div>
|
||||
<span className="flex-shrink-0 font-medium text-secondary">{item?.value}</span>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -20,20 +20,20 @@ export const CustomPieChartTooltip = React.memo(function CustomPieChartTooltip(p
|
|||
|
||||
return (
|
||||
<Card
|
||||
className="flex flex-col max-h-[40vh] w-[12rem] overflow-y-scroll vertical-scrollbar scrollbar-sm"
|
||||
className="vertical-scrollbar flex scrollbar-sm max-h-[40vh] w-[12rem] flex-col overflow-y-scroll"
|
||||
spacing={ECardSpacing.SM}
|
||||
>
|
||||
<p className="flex-shrink-0 text-11 text-primary font-medium border-b border-subtle pb-2 truncate">{label}</p>
|
||||
<p className="flex-shrink-0 truncate border-b border-subtle pb-2 text-11 font-medium text-primary">{label}</p>
|
||||
{payload?.map((item) => (
|
||||
<div key={item?.dataKey} className="flex items-center gap-2 text-11 capitalize">
|
||||
<div className="flex items-center gap-2 truncate">
|
||||
<div
|
||||
className="flex-shrink-0 size-2 rounded-xs"
|
||||
className="size-2 flex-shrink-0 rounded-xs"
|
||||
style={{
|
||||
backgroundColor: dotColor,
|
||||
}}
|
||||
/>
|
||||
<span className="text-tertiary truncate">{item?.name}:</span>
|
||||
<span className="truncate text-tertiary">{item?.name}:</span>
|
||||
</div>
|
||||
<span className="flex-shrink-0 font-medium text-secondary">{item?.value}</span>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -227,7 +227,7 @@ export function CustomTreeMapContent({
|
|||
x={pX + LAYOUT.TEXT.PADDING_LEFT + iconSpace}
|
||||
y={pY + LAYOUT.TEXT.VERTICAL_OFFSET}
|
||||
textAnchor="start"
|
||||
className={cn("text-13 font-light tracking-wider select-none", textClassName || "text-tertiary")}
|
||||
className={cn("tracking-wider text-13 font-light select-none", textClassName || "text-tertiary")}
|
||||
fill="currentColor"
|
||||
>
|
||||
{top.nameTruncated ? truncateText(name, availableTextWidth, LAYOUT.TEXT.FONT_SIZES.SM, iconSpace) : name}
|
||||
|
|
@ -243,7 +243,7 @@ export function CustomTreeMapContent({
|
|||
x={pX + LAYOUT.TEXT.PADDING_LEFT}
|
||||
y={pY + pHeight - LAYOUT.TEXT.PADDING_LEFT}
|
||||
textAnchor="start"
|
||||
className={cn("text-13 font-light tracking-wider select-none", textClassName || "text-tertiary")}
|
||||
className={cn("tracking-wider text-13 font-light select-none", textClassName || "text-tertiary")}
|
||||
fill="currentColor"
|
||||
>
|
||||
{value.toLocaleString()}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ export const TreeMapChart = React.memo(function TreeMapChart(props: TreeMapChart
|
|||
nameKey="name"
|
||||
dataKey="value"
|
||||
stroke="transparent"
|
||||
className="bg-layer-1 cursor-pointer"
|
||||
className="cursor-pointer bg-layer-1"
|
||||
content={<CustomTreeMapContent />}
|
||||
animationEasing="ease-out"
|
||||
isUpdateAnimationActive={isAnimationActive}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ export const TreeMapTooltip = React.memo(function TreeMapTooltip({ active, paylo
|
|||
<Card className="flex flex-col space-y-1.5" spacing={ECardSpacing.SM}>
|
||||
<div className="flex items-center gap-2 border-b border-subtle pb-2.5">
|
||||
{data?.icon}
|
||||
<p className="text-11 text-primary font-medium capitalize">{data?.name}</p>
|
||||
<p className="text-11 font-medium text-primary capitalize">{data?.name}</p>
|
||||
</div>
|
||||
<span className="text-11 font-medium text-secondary">
|
||||
{data?.value.toLocaleString()}
|
||||
|
|
|
|||
|
|
@ -32,12 +32,12 @@ const meta = {
|
|||
|
||||
return (
|
||||
<Collapsible.CollapsibleRoot {...args} isOpen={isOpen} onToggle={toggleOpen} className="w-96">
|
||||
<Collapsible.CollapsibleTrigger className="flex w-full items-center justify-between rounded-md bg-gray-100 px-4 py-2 hover:bg-gray-200">
|
||||
<Collapsible.CollapsibleTrigger className="bg-gray-100 hover:bg-gray-200 flex w-full items-center justify-between rounded-md px-4 py-2">
|
||||
<span className="font-semibold">Click to toggle</span>
|
||||
<ChevronDownIcon className="h-4 w-4 transition-transform group-data-[panel-open]:rotate-180" />
|
||||
</Collapsible.CollapsibleTrigger>
|
||||
<Collapsible.CollapsibleContent className="mt-2">
|
||||
<div className="rounded-md border border-gray-200 p-4">
|
||||
<div className="border-gray-200 rounded-md border p-4">
|
||||
<p className="text-13">This is the collapsible content that can be shown or hidden.</p>
|
||||
</div>
|
||||
</Collapsible.CollapsibleContent>
|
||||
|
|
@ -62,26 +62,26 @@ export const Controlled: Story = {
|
|||
return (
|
||||
<div className="space-y-4">
|
||||
<div className="flex gap-2">
|
||||
<button onClick={() => setIsOpen(true)} className="rounded-sm bg-blue-500 px-4 py-2 text-13 text-on-color">
|
||||
<button onClick={() => setIsOpen(true)} className="bg-blue-500 rounded-sm px-4 py-2 text-13 text-on-color">
|
||||
Open
|
||||
</button>
|
||||
<button onClick={() => setIsOpen(false)} className="rounded-sm bg-gray-500 px-4 py-2 text-13 text-on-color">
|
||||
<button onClick={() => setIsOpen(false)} className="bg-gray-500 rounded-sm px-4 py-2 text-13 text-on-color">
|
||||
Close
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setIsOpen(!isOpen)}
|
||||
className="rounded-sm bg-green-500 px-4 py-2 text-13 text-on-color"
|
||||
className="bg-green-500 rounded-sm px-4 py-2 text-13 text-on-color"
|
||||
>
|
||||
Toggle
|
||||
</button>
|
||||
</div>
|
||||
<Collapsible.CollapsibleRoot isOpen={isOpen} onToggle={() => setIsOpen(!isOpen)} className="w-96">
|
||||
<Collapsible.CollapsibleTrigger className="flex w-full items-center justify-between rounded-md bg-gray-100 px-4 py-2 hover:bg-gray-200">
|
||||
<Collapsible.CollapsibleTrigger className="bg-gray-100 hover:bg-gray-200 flex w-full items-center justify-between rounded-md px-4 py-2">
|
||||
<span className="font-semibold">Controlled Collapsible</span>
|
||||
<ChevronDownIcon className="h-4 w-4 transition-transform group-data-[panel-open]:rotate-180" />
|
||||
</Collapsible.CollapsibleTrigger>
|
||||
<Collapsible.CollapsibleContent className="mt-2">
|
||||
<div className="rounded-md border border-gray-200 p-4">
|
||||
<div className="border-gray-200 rounded-md border p-4">
|
||||
<p className="text-13">This collapsible is controlled by external state.</p>
|
||||
<p className="mt-2 text-13">Current state: {isOpen ? "Open" : "Closed"}</p>
|
||||
</div>
|
||||
|
|
@ -97,12 +97,12 @@ export const NestedContent: Story = {
|
|||
const [isOpen, setIsOpen] = useState(args.isOpen);
|
||||
return (
|
||||
<Collapsible.CollapsibleRoot {...args} isOpen={isOpen} onToggle={() => setIsOpen(!isOpen)} className="w-96">
|
||||
<Collapsible.CollapsibleTrigger className="flex w-full items-center justify-between rounded-md bg-gray-100 px-4 py-2 hover:bg-gray-200">
|
||||
<Collapsible.CollapsibleTrigger className="bg-gray-100 hover:bg-gray-200 flex w-full items-center justify-between rounded-md px-4 py-2">
|
||||
<span className="font-semibold">Collapsible with Nested Content</span>
|
||||
<ChevronDownIcon className="h-4 w-4 transition-transform group-data-[panel-open]:rotate-180" />
|
||||
</Collapsible.CollapsibleTrigger>
|
||||
<Collapsible.CollapsibleContent className="mt-2">
|
||||
<div className="space-y-2 rounded-md border border-gray-200 p-4">
|
||||
<div className="border-gray-200 space-y-2 rounded-md border p-4">
|
||||
<h4 className="font-semibold">Section 1</h4>
|
||||
<p className="text-13">This is some content in the first section.</p>
|
||||
<h4 className="font-semibold">Section 2</h4>
|
||||
|
|
@ -124,12 +124,12 @@ export const CustomStyling: Story = {
|
|||
const [isOpen, setIsOpen] = useState(args.isOpen);
|
||||
return (
|
||||
<Collapsible.CollapsibleRoot {...args} isOpen={isOpen} onToggle={() => setIsOpen(!isOpen)} className="w-96">
|
||||
<Collapsible.CollapsibleTrigger className="flex w-full items-center justify-between rounded-lg bg-gradient-to-r from-purple-500 to-pink-500 px-6 py-3 text-on-color shadow-lg transition-all hover:shadow-xl">
|
||||
<Collapsible.CollapsibleTrigger className="from-purple-500 to-pink-500 shadow-lg hover:shadow-xl flex w-full items-center justify-between rounded-lg bg-gradient-to-r px-6 py-3 text-on-color transition-all">
|
||||
<span className="text-16 font-bold">Custom Styled Trigger</span>
|
||||
<ChevronDownIcon className="h-5 w-5 transition-transform group-data-[panel-open]:rotate-180" />
|
||||
</Collapsible.CollapsibleTrigger>
|
||||
<Collapsible.CollapsibleContent className="mt-4">
|
||||
<div className="rounded-lg bg-gradient-to-br from-purple-100 to-pink-100 p-6 shadow-md">
|
||||
<div className="from-purple-100 to-pink-100 shadow-md rounded-lg bg-gradient-to-br p-6">
|
||||
<p className="text-purple-900">This collapsible has custom styling with gradients, shadows, and colors.</p>
|
||||
</div>
|
||||
</Collapsible.CollapsibleContent>
|
||||
|
|
@ -143,36 +143,36 @@ export const MultipleCollapsibles: Story = {
|
|||
return (
|
||||
<div className="w-96 space-y-2">
|
||||
<Collapsible.CollapsibleRoot>
|
||||
<Collapsible.CollapsibleTrigger className="flex w-full items-center justify-between rounded-md bg-gray-100 px-4 py-2 hover:bg-gray-200">
|
||||
<Collapsible.CollapsibleTrigger className="bg-gray-100 hover:bg-gray-200 flex w-full items-center justify-between rounded-md px-4 py-2">
|
||||
<span className="font-semibold">First Item</span>
|
||||
<ChevronDownIcon className="h-4 w-4 transition-transform group-data-[panel-open]:rotate-180" />
|
||||
</Collapsible.CollapsibleTrigger>
|
||||
<Collapsible.CollapsibleContent className="mt-2">
|
||||
<div className="rounded-md border border-gray-200 p-4">
|
||||
<div className="border-gray-200 rounded-md border p-4">
|
||||
<p className="text-13">Content for the first item.</p>
|
||||
</div>
|
||||
</Collapsible.CollapsibleContent>
|
||||
</Collapsible.CollapsibleRoot>
|
||||
|
||||
<Collapsible.CollapsibleRoot>
|
||||
<Collapsible.CollapsibleTrigger className="flex w-full items-center justify-between rounded-md bg-gray-100 px-4 py-2 hover:bg-gray-200">
|
||||
<Collapsible.CollapsibleTrigger className="bg-gray-100 hover:bg-gray-200 flex w-full items-center justify-between rounded-md px-4 py-2">
|
||||
<span className="font-semibold">Second Item</span>
|
||||
<ChevronDownIcon className="h-4 w-4 transition-transform group-data-[panel-open]:rotate-180" />
|
||||
</Collapsible.CollapsibleTrigger>
|
||||
<Collapsible.CollapsibleContent className="mt-2">
|
||||
<div className="rounded-md border border-gray-200 p-4">
|
||||
<div className="border-gray-200 rounded-md border p-4">
|
||||
<p className="text-13">Content for the second item.</p>
|
||||
</div>
|
||||
</Collapsible.CollapsibleContent>
|
||||
</Collapsible.CollapsibleRoot>
|
||||
|
||||
<Collapsible.CollapsibleRoot>
|
||||
<Collapsible.CollapsibleTrigger className="flex w-full items-center justify-between rounded-md bg-gray-100 px-4 py-2 hover:bg-gray-200">
|
||||
<Collapsible.CollapsibleTrigger className="bg-gray-100 hover:bg-gray-200 flex w-full items-center justify-between rounded-md px-4 py-2">
|
||||
<span className="font-semibold">Third Item</span>
|
||||
<ChevronDownIcon className="h-4 w-4 transition-transform group-data-[panel-open]:rotate-180" />
|
||||
</Collapsible.CollapsibleTrigger>
|
||||
<Collapsible.CollapsibleContent className="mt-2">
|
||||
<div className="rounded-md border border-gray-200 p-4">
|
||||
<div className="border-gray-200 rounded-md border p-4">
|
||||
<p className="text-13">Content for the third item.</p>
|
||||
</div>
|
||||
</Collapsible.CollapsibleContent>
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ const meta = {
|
|||
const setValue = (newValue: string | string[]) => updateArgs({ value: newValue });
|
||||
return (
|
||||
<Combobox {...args} value={value} onValueChange={(v) => setValue(v as string)}>
|
||||
<Combobox.Button className="flex w-72 items-center justify-between rounded-md border border-gray-300 bg-white px-4 py-2 hover:bg-gray-50">
|
||||
<Combobox.Button className="border-gray-300 hover:bg-gray-50 flex w-72 items-center justify-between rounded-md border bg-white px-4 py-2">
|
||||
<span>{value ? frameworks.find((f) => f.value === value)?.label : "Select framework..."}</span>
|
||||
<ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
|
||||
</Combobox.Button>
|
||||
|
|
@ -75,7 +75,7 @@ export const WithoutSearch: Story = {
|
|||
const [value, setValue] = useState("");
|
||||
return (
|
||||
<Combobox value={value} onValueChange={(v) => setValue(v as string)}>
|
||||
<Combobox.Button className="flex w-72 items-center justify-between rounded-md border border-gray-300 bg-white px-4 py-2 hover:bg-gray-50">
|
||||
<Combobox.Button className="border-gray-300 hover:bg-gray-50 flex w-72 items-center justify-between rounded-md border bg-white px-4 py-2">
|
||||
<span>{value ? frameworks.find((f) => f.value === value)?.label : "Select framework..."}</span>
|
||||
<ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
|
||||
</Combobox.Button>
|
||||
|
|
@ -102,7 +102,7 @@ export const MultiSelect: Story = {
|
|||
|
||||
return (
|
||||
<Combobox multiSelect value={value} onValueChange={(v) => setValue(v as string[])}>
|
||||
<Combobox.Button className="flex w-72 items-center justify-between rounded-md border border-gray-300 bg-white px-4 py-2 hover:bg-gray-50">
|
||||
<Combobox.Button className="border-gray-300 hover:bg-gray-50 flex w-72 items-center justify-between rounded-md border bg-white px-4 py-2">
|
||||
<span className="truncate">{value.length > 0 ? `${value.length} selected` : "Select frameworks..."}</span>
|
||||
<ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
|
||||
</Combobox.Button>
|
||||
|
|
@ -130,7 +130,7 @@ export const MultiSelectWithLimit: Story = {
|
|||
return (
|
||||
<div className="space-y-2">
|
||||
<Combobox multiSelect maxSelections={3} value={value} onValueChange={(v) => setValue(v as string[])}>
|
||||
<Combobox.Button className="flex w-72 items-center justify-between rounded-md border border-gray-300 bg-white px-4 py-2 hover:bg-gray-50">
|
||||
<Combobox.Button className="border-gray-300 hover:bg-gray-50 flex w-72 items-center justify-between rounded-md border bg-white px-4 py-2">
|
||||
<span className="truncate">
|
||||
{value.length > 0 ? `${value.length}/3 selected` : "Select up to 3 frameworks..."}
|
||||
</span>
|
||||
|
|
@ -149,7 +149,7 @@ export const MultiSelectWithLimit: Story = {
|
|||
))}
|
||||
</Combobox.Options>
|
||||
</Combobox>
|
||||
<p className="text-11 text-gray-500">Maximum 3 selections allowed</p>
|
||||
<p className="text-gray-500 text-11">Maximum 3 selections allowed</p>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
|
|
@ -161,7 +161,7 @@ export const Disabled: Story = {
|
|||
const [value, setValue] = useState("");
|
||||
return (
|
||||
<Combobox disabled value={value} onValueChange={(v) => setValue(v as string)}>
|
||||
<Combobox.Button className="flex w-72 items-center justify-between rounded-md border border-gray-300 bg-gray-100 px-4 py-2 opacity-50">
|
||||
<Combobox.Button className="border-gray-300 bg-gray-100 flex w-72 items-center justify-between rounded-md border px-4 py-2 opacity-50">
|
||||
<span>{value ? frameworks.find((f) => f.value === value)?.label : "Select framework..."}</span>
|
||||
<ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
|
||||
</Combobox.Button>
|
||||
|
|
@ -187,7 +187,7 @@ export const DisabledOptions: Story = {
|
|||
const [value, setValue] = useState("");
|
||||
return (
|
||||
<Combobox value={value} onValueChange={(v) => setValue(v as string)}>
|
||||
<Combobox.Button className="flex w-72 items-center justify-between rounded-md border border-gray-300 bg-white px-4 py-2 hover:bg-gray-50">
|
||||
<Combobox.Button className="border-gray-300 hover:bg-gray-50 flex w-72 items-center justify-between rounded-md border bg-white px-4 py-2">
|
||||
<span>{value ? frameworks.find((f) => f.value === value)?.label : "Select framework..."}</span>
|
||||
<ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
|
||||
</Combobox.Button>
|
||||
|
|
@ -214,7 +214,7 @@ export const CustomMaxHeight: Story = {
|
|||
const [value, setValue] = useState("");
|
||||
return (
|
||||
<Combobox value={value} onValueChange={(v) => setValue(v as string)}>
|
||||
<Combobox.Button className="flex w-72 items-center justify-between rounded-md border border-gray-300 bg-white px-4 py-2 hover:bg-gray-50">
|
||||
<Combobox.Button className="border-gray-300 hover:bg-gray-50 flex w-72 items-center justify-between rounded-md border bg-white px-4 py-2">
|
||||
<span>{value ? frameworks.find((f) => f.value === value)?.label : "Select framework..."}</span>
|
||||
<ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
|
||||
</Combobox.Button>
|
||||
|
|
@ -240,7 +240,7 @@ export const CustomEmptyMessage: Story = {
|
|||
const [value, setValue] = useState("");
|
||||
return (
|
||||
<Combobox value={value} onValueChange={(v) => setValue(v as string)}>
|
||||
<Combobox.Button className="flex w-72 items-center justify-between rounded-md border border-gray-300 bg-white px-4 py-2 hover:bg-gray-50">
|
||||
<Combobox.Button className="border-gray-300 hover:bg-gray-50 flex w-72 items-center justify-between rounded-md border bg-white px-4 py-2">
|
||||
<span>{value ? frameworks.find((f) => f.value === value)?.label : "Select framework..."}</span>
|
||||
<ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
|
||||
</Combobox.Button>
|
||||
|
|
|
|||
|
|
@ -174,13 +174,13 @@ function ComboboxOptions({
|
|||
<BaseCombobox.Portal>
|
||||
<BaseCombobox.Positioner sideOffset={8} className={positionerClassName}>
|
||||
<BaseCombobox.Popup
|
||||
className={cn("rounded-md border border-subtle bg-surface-1 p-1 shadow-lg", className)}
|
||||
className={cn("shadow-lg rounded-md border border-subtle bg-surface-1 p-1", className)}
|
||||
data-prevent-outside-click={dataPreventOutsideClick}
|
||||
>
|
||||
<div className="flex flex-col gap-1">
|
||||
{showSearch && (
|
||||
<div className="relative">
|
||||
<SearchIcon className="absolute left-2 top-1/2 h-4 w-4 -translate-y-1/2 text-placeholder" />
|
||||
<SearchIcon className="absolute top-1/2 left-2 h-4 w-4 -translate-y-1/2 text-placeholder" />
|
||||
<input
|
||||
type="text"
|
||||
placeholder={searchPlaceholder}
|
||||
|
|
@ -188,7 +188,7 @@ function ComboboxOptions({
|
|||
onChange={(e) => setSearchQuery(e.target.value)}
|
||||
onKeyDown={onSearchQueryKeyDown}
|
||||
className={cn(
|
||||
"w-full rounded-sm border border-subtle bg-surface-2 py-1.5 pl-8 pr-2 text-13 outline-none placeholder:text-placeholder",
|
||||
"w-full rounded-sm border border-subtle bg-surface-2 py-1.5 pr-2 pl-8 text-13 outline-none placeholder:text-placeholder",
|
||||
inputClassName
|
||||
)}
|
||||
/>
|
||||
|
|
@ -219,7 +219,7 @@ function ComboboxOption({ value, children, disabled, className }: ComboboxOption
|
|||
<BaseCombobox.Item
|
||||
value={value}
|
||||
disabled={disabled}
|
||||
className={cn("cursor-pointer rounded-sm px-2 py-1.5 text-13 outline-none transition-colors", className)}
|
||||
className={cn("cursor-pointer rounded-sm px-2 py-1.5 text-13 transition-colors outline-none", className)}
|
||||
>
|
||||
{children}
|
||||
</BaseCombobox.Item>
|
||||
|
|
|
|||
|
|
@ -29,14 +29,14 @@ type Story = StoryObj<typeof meta>;
|
|||
export const Default: Story = {
|
||||
render() {
|
||||
return (
|
||||
<Command className="w-96 rounded-lg border border-gray-200 p-2">
|
||||
<Command className="border-gray-200 w-96 rounded-lg border p-2">
|
||||
<Command.Input placeholder="Search..." className="h-9 w-full bg-transparent py-3 text-13 outline-none" />
|
||||
<Command.List className="max-h-80 overflow-auto py-2">
|
||||
<Command.Item className="cursor-pointer rounded-sm px-3 py-2 hover:bg-gray-100">Item 1</Command.Item>
|
||||
<Command.Item className="cursor-pointer rounded-sm px-3 py-2 hover:bg-gray-100">Item 2</Command.Item>
|
||||
<Command.Item className="cursor-pointer rounded-sm px-3 py-2 hover:bg-gray-100">Item 3</Command.Item>
|
||||
<Command.Item className="hover:bg-gray-100 cursor-pointer rounded-sm px-3 py-2">Item 1</Command.Item>
|
||||
<Command.Item className="hover:bg-gray-100 cursor-pointer rounded-sm px-3 py-2">Item 2</Command.Item>
|
||||
<Command.Item className="hover:bg-gray-100 cursor-pointer rounded-sm px-3 py-2">Item 3</Command.Item>
|
||||
</Command.List>
|
||||
<Command.Empty className="py-6 text-center text-13 text-gray-500">No results found.</Command.Empty>
|
||||
<Command.Empty className="text-gray-500 py-6 text-center text-13">No results found.</Command.Empty>
|
||||
</Command>
|
||||
);
|
||||
},
|
||||
|
|
@ -45,30 +45,30 @@ export const Default: Story = {
|
|||
export const WithIcons: Story = {
|
||||
render() {
|
||||
return (
|
||||
<Command className="w-96 rounded-lg border border-gray-200 p-2">
|
||||
<Command className="border-gray-200 w-96 rounded-lg border p-2">
|
||||
<Command.Input
|
||||
placeholder="Search files and folders..."
|
||||
className="h-9 w-full bg-transparent py-3 text-13 outline-none"
|
||||
/>
|
||||
<Command.List className="max-h-80 overflow-auto py-2">
|
||||
<Command.Item className="flex cursor-pointer items-center gap-2 rounded-sm px-3 py-2 hover:bg-gray-100">
|
||||
<Command.Item className="hover:bg-gray-100 flex cursor-pointer items-center gap-2 rounded-sm px-3 py-2">
|
||||
<Folder className="h-4 w-4" />
|
||||
<span>Documents</span>
|
||||
</Command.Item>
|
||||
<Command.Item className="flex cursor-pointer items-center gap-2 rounded-sm px-3 py-2 hover:bg-gray-100">
|
||||
<Command.Item className="hover:bg-gray-100 flex cursor-pointer items-center gap-2 rounded-sm px-3 py-2">
|
||||
<Folder className="h-4 w-4" />
|
||||
<span>Downloads</span>
|
||||
</Command.Item>
|
||||
<Command.Item className="flex cursor-pointer items-center gap-2 rounded-sm px-3 py-2 hover:bg-gray-100">
|
||||
<Command.Item className="hover:bg-gray-100 flex cursor-pointer items-center gap-2 rounded-sm px-3 py-2">
|
||||
<File className="h-4 w-4" />
|
||||
<span>README.md</span>
|
||||
</Command.Item>
|
||||
<Command.Item className="flex cursor-pointer items-center gap-2 rounded-sm px-3 py-2 hover:bg-gray-100">
|
||||
<Command.Item className="hover:bg-gray-100 flex cursor-pointer items-center gap-2 rounded-sm px-3 py-2">
|
||||
<File className="h-4 w-4" />
|
||||
<span>package.json</span>
|
||||
</Command.Item>
|
||||
</Command.List>
|
||||
<Command.Empty className="py-6 text-center text-13 text-gray-500">No files or folders found.</Command.Empty>
|
||||
<Command.Empty className="text-gray-500 py-6 text-center text-13">No files or folders found.</Command.Empty>
|
||||
</Command>
|
||||
);
|
||||
},
|
||||
|
|
@ -77,33 +77,33 @@ export const WithIcons: Story = {
|
|||
export const WithCategories: Story = {
|
||||
render() {
|
||||
return (
|
||||
<Command className="w-96 rounded-lg border border-gray-200 p-2">
|
||||
<Command className="border-gray-200 w-96 rounded-lg border p-2">
|
||||
<Command.Input
|
||||
placeholder="Search commands..."
|
||||
className="h-9 w-full bg-transparent py-3 text-13 outline-none"
|
||||
/>
|
||||
<Command.List className="max-h-80 overflow-auto py-2">
|
||||
<div className="px-2 py-1.5 text-11 font-semibold text-gray-500">User</div>
|
||||
<Command.Item className="flex cursor-pointer items-center gap-2 rounded-sm px-3 py-2 hover:bg-gray-100">
|
||||
<div className="text-gray-500 px-2 py-1.5 text-11 font-semibold">User</div>
|
||||
<Command.Item className="hover:bg-gray-100 flex cursor-pointer items-center gap-2 rounded-sm px-3 py-2">
|
||||
<User className="h-4 w-4" />
|
||||
<span>Profile</span>
|
||||
</Command.Item>
|
||||
<Command.Item className="flex cursor-pointer items-center gap-2 rounded-sm px-3 py-2 hover:bg-gray-100">
|
||||
<Command.Item className="hover:bg-gray-100 flex cursor-pointer items-center gap-2 rounded-sm px-3 py-2">
|
||||
<Settings className="h-4 w-4" />
|
||||
<span>Settings</span>
|
||||
</Command.Item>
|
||||
|
||||
<div className="mt-2 px-2 py-1.5 text-11 font-semibold text-gray-500">Files</div>
|
||||
<Command.Item className="flex cursor-pointer items-center gap-2 rounded-sm px-3 py-2 hover:bg-gray-100">
|
||||
<div className="text-gray-500 mt-2 px-2 py-1.5 text-11 font-semibold">Files</div>
|
||||
<Command.Item className="hover:bg-gray-100 flex cursor-pointer items-center gap-2 rounded-sm px-3 py-2">
|
||||
<Folder className="h-4 w-4" />
|
||||
<span>Open Folder</span>
|
||||
</Command.Item>
|
||||
<Command.Item className="flex cursor-pointer items-center gap-2 rounded-sm px-3 py-2 hover:bg-gray-100">
|
||||
<Command.Item className="hover:bg-gray-100 flex cursor-pointer items-center gap-2 rounded-sm px-3 py-2">
|
||||
<File className="h-4 w-4" />
|
||||
<span>New File</span>
|
||||
</Command.Item>
|
||||
</Command.List>
|
||||
<Command.Empty className="py-6 text-center text-13 text-gray-500">No commands found.</Command.Empty>
|
||||
<Command.Empty className="text-gray-500 py-6 text-center text-13">No commands found.</Command.Empty>
|
||||
</Command>
|
||||
);
|
||||
},
|
||||
|
|
@ -112,10 +112,10 @@ export const WithCategories: Story = {
|
|||
export const EmptyState: Story = {
|
||||
render() {
|
||||
return (
|
||||
<Command className="w-96 rounded-lg border border-gray-200 p-2">
|
||||
<Command className="border-gray-200 w-96 rounded-lg border p-2">
|
||||
<Command.Input placeholder="Search..." className="h-9 w-full bg-transparent py-3 text-13 outline-none" />
|
||||
<Command.List className="max-h-80 overflow-auto py-2">{/* No items - will show empty state */}</Command.List>
|
||||
<Command.Empty className="py-6 text-center text-13 text-gray-500">
|
||||
<Command.Empty className="text-gray-500 py-6 text-center text-13">
|
||||
<p className="font-semibold">No results found</p>
|
||||
<p className="mt-1 text-11">Try searching for something else</p>
|
||||
</Command.Empty>
|
||||
|
|
@ -127,16 +127,16 @@ export const EmptyState: Story = {
|
|||
export const LongList: Story = {
|
||||
render() {
|
||||
return (
|
||||
<Command className="w-96 rounded-lg border border-gray-200 p-2">
|
||||
<Command className="border-gray-200 w-96 rounded-lg border p-2">
|
||||
<Command.Input placeholder="Search items..." className="h-9 w-full bg-transparent py-3 text-13 outline-none" />
|
||||
<Command.List className="max-h-60 overflow-auto py-2">
|
||||
{Array.from({ length: 20 }, (_, i) => (
|
||||
<Command.Item key={i} className="cursor-pointer rounded-sm px-3 py-2 hover:bg-gray-100">
|
||||
<Command.Item key={i} className="hover:bg-gray-100 cursor-pointer rounded-sm px-3 py-2">
|
||||
Item {i + 1}
|
||||
</Command.Item>
|
||||
))}
|
||||
</Command.List>
|
||||
<Command.Empty className="py-6 text-center text-13 text-gray-500">No results found.</Command.Empty>
|
||||
<Command.Empty className="text-gray-500 py-6 text-center text-13">No results found.</Command.Empty>
|
||||
</Command>
|
||||
);
|
||||
},
|
||||
|
|
@ -145,17 +145,17 @@ export const LongList: Story = {
|
|||
export const WithoutSearch: Story = {
|
||||
render() {
|
||||
return (
|
||||
<Command className="w-96 rounded-lg border border-gray-200 p-2">
|
||||
<Command className="border-gray-200 w-96 rounded-lg border p-2">
|
||||
<Command.List className="max-h-80 overflow-auto py-2">
|
||||
<Command.Item className="flex cursor-pointer items-center gap-2 rounded-sm px-3 py-2 hover:bg-gray-100">
|
||||
<Command.Item className="hover:bg-gray-100 flex cursor-pointer items-center gap-2 rounded-sm px-3 py-2">
|
||||
<User className="h-4 w-4" />
|
||||
<span>Profile</span>
|
||||
</Command.Item>
|
||||
<Command.Item className="flex cursor-pointer items-center gap-2 rounded-sm px-3 py-2 hover:bg-gray-100">
|
||||
<Command.Item className="hover:bg-gray-100 flex cursor-pointer items-center gap-2 rounded-sm px-3 py-2">
|
||||
<Settings className="h-4 w-4" />
|
||||
<span>Settings</span>
|
||||
</Command.Item>
|
||||
<Command.Item className="flex cursor-pointer items-center gap-2 rounded-sm px-3 py-2 hover:bg-gray-100">
|
||||
<Command.Item className="hover:bg-gray-100 flex cursor-pointer items-center gap-2 rounded-sm px-3 py-2">
|
||||
<Folder className="h-4 w-4" />
|
||||
<span>Files</span>
|
||||
</Command.Item>
|
||||
|
|
@ -168,23 +168,23 @@ export const WithoutSearch: Story = {
|
|||
export const CustomStyling: Story = {
|
||||
render() {
|
||||
return (
|
||||
<Command className="w-96 rounded-lg border-2 border-blue-300 bg-blue-50 p-2 shadow-lg">
|
||||
<Command className="border-blue-300 bg-blue-50 shadow-lg w-96 rounded-lg border-2 p-2">
|
||||
<Command.Input
|
||||
placeholder="Search with custom styling..."
|
||||
className="h-9 w-full bg-transparent py-3 text-13 text-blue-900 outline-none placeholder:text-blue-400"
|
||||
className="text-blue-900 placeholder:text-blue-400 h-9 w-full bg-transparent py-3 text-13 outline-none"
|
||||
/>
|
||||
<Command.List className="max-h-80 overflow-auto py-2">
|
||||
<Command.Item className="cursor-pointer rounded-sm px-3 py-2 text-blue-900 hover:bg-blue-200">
|
||||
<Command.Item className="text-blue-900 hover:bg-blue-200 cursor-pointer rounded-sm px-3 py-2">
|
||||
Custom Item 1
|
||||
</Command.Item>
|
||||
<Command.Item className="cursor-pointer rounded-sm px-3 py-2 text-blue-900 hover:bg-blue-200">
|
||||
<Command.Item className="text-blue-900 hover:bg-blue-200 cursor-pointer rounded-sm px-3 py-2">
|
||||
Custom Item 2
|
||||
</Command.Item>
|
||||
<Command.Item className="cursor-pointer rounded-sm px-3 py-2 text-blue-900 hover:bg-blue-200">
|
||||
<Command.Item className="text-blue-900 hover:bg-blue-200 cursor-pointer rounded-sm px-3 py-2">
|
||||
Custom Item 3
|
||||
</Command.Item>
|
||||
</Command.List>
|
||||
<Command.Empty className="py-6 text-center text-13 text-blue-500">No matching items found.</Command.Empty>
|
||||
<Command.Empty className="text-blue-500 py-6 text-center text-13">No matching items found.</Command.Empty>
|
||||
</Command>
|
||||
);
|
||||
},
|
||||
|
|
@ -193,16 +193,16 @@ export const CustomStyling: Story = {
|
|||
export const DisabledItems: Story = {
|
||||
render() {
|
||||
return (
|
||||
<Command className="w-96 rounded-lg border border-gray-200 p-2">
|
||||
<Command className="border-gray-200 w-96 rounded-lg border p-2">
|
||||
<Command.Input placeholder="Search..." className="h-9 w-full bg-transparent py-3 text-13 outline-none" />
|
||||
<Command.List className="max-h-80 overflow-auto py-2">
|
||||
<Command.Item className="cursor-pointer rounded-sm px-3 py-2 hover:bg-gray-100">Active Item 1</Command.Item>
|
||||
<Command.Item className="hover:bg-gray-100 cursor-pointer rounded-sm px-3 py-2">Active Item 1</Command.Item>
|
||||
<Command.Item disabled className="cursor-not-allowed rounded-sm px-3 py-2 opacity-50">
|
||||
Disabled Item
|
||||
</Command.Item>
|
||||
<Command.Item className="cursor-pointer rounded-sm px-3 py-2 hover:bg-gray-100">Active Item 2</Command.Item>
|
||||
<Command.Item className="hover:bg-gray-100 cursor-pointer rounded-sm px-3 py-2">Active Item 2</Command.Item>
|
||||
</Command.List>
|
||||
<Command.Empty className="py-6 text-center text-13 text-gray-500">No results found.</Command.Empty>
|
||||
<Command.Empty className="text-gray-500 py-6 text-center text-13">No results found.</Command.Empty>
|
||||
</Command>
|
||||
);
|
||||
},
|
||||
|
|
|
|||
|
|
@ -187,9 +187,9 @@ export const OnFileCard: Story = {
|
|||
return (
|
||||
<ContextMenu>
|
||||
<ContextMenu.Trigger>
|
||||
<div className="w-64 p-4 border border-subtle rounded-lg hover:bg-layer-1 cursor-pointer">
|
||||
<div className="w-64 cursor-pointer rounded-lg border border-subtle p-4 hover:bg-layer-1">
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="w-12 h-12 bg-accent-primary rounded-sm flex items-center justify-center text-on-color text-16">
|
||||
<div className="flex h-12 w-12 items-center justify-center rounded-sm bg-accent-primary text-16 text-on-color">
|
||||
📄
|
||||
</div>
|
||||
<div className="flex-1">
|
||||
|
|
@ -234,7 +234,7 @@ export const OnImage: Story = {
|
|||
return (
|
||||
<ContextMenu>
|
||||
<ContextMenu.Trigger>
|
||||
<div className="relative w-80 h-56 bg-layer-1 rounded-lg overflow-hidden cursor-pointer">
|
||||
<div className="relative h-56 w-80 cursor-pointer overflow-hidden rounded-lg bg-layer-1">
|
||||
<div className="absolute inset-0 flex items-center justify-center text-placeholder">Image Placeholder</div>
|
||||
</div>
|
||||
</ContextMenu.Trigger>
|
||||
|
|
@ -266,8 +266,8 @@ export const OnText: Story = {
|
|||
return (
|
||||
<ContextMenu>
|
||||
<ContextMenu.Trigger>
|
||||
<div className="w-96 p-6 border border-subtle rounded-lg">
|
||||
<h3 className="text-16 font-semibold mb-2">Context Menu on Text</h3>
|
||||
<div className="w-96 rounded-lg border border-subtle p-6">
|
||||
<h3 className="mb-2 text-16 font-semibold">Context Menu on Text</h3>
|
||||
<p className="text-tertiary">
|
||||
Right click anywhere on this text area to see the context menu. This demonstrates how context menus can be
|
||||
applied to text content areas.
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ const ContextMenuContent = React.forwardRef(function ContextMenuContent(
|
|||
>
|
||||
<ContextMenuPrimitive.Popup
|
||||
className={cn(
|
||||
"z-50 min-w-32 overflow-hidden rounded-md border border-subtle bg-surface-1 p-1 shadow-md",
|
||||
"shadow-md z-50 min-w-32 overflow-hidden rounded-md border border-subtle bg-surface-1 p-1",
|
||||
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
|
||||
"data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",
|
||||
"data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2",
|
||||
|
|
@ -87,7 +87,7 @@ const ContextMenuItem = React.forwardRef(function ContextMenuItem(
|
|||
<ContextMenuPrimitive.Item
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"relative flex cursor-default select-none items-center rounded-xs px-2 py-1.5 text-13 outline-none",
|
||||
"relative flex cursor-default items-center rounded-xs px-2 py-1.5 text-13 outline-none select-none",
|
||||
"focus:bg-surface-2 focus:text-primary",
|
||||
"data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
||||
className
|
||||
|
|
@ -105,7 +105,7 @@ const ContextMenuSeparator = React.forwardRef(function ContextMenuSeparator(
|
|||
ref: React.ForwardedRef<React.ElementRef<typeof ContextMenuPrimitive.Separator>>
|
||||
) {
|
||||
return (
|
||||
<ContextMenuPrimitive.Separator ref={ref} className={cn("-mx-1 my-1 h-px bg-subtle-1", className)} {...props} />
|
||||
<ContextMenuPrimitive.Separator ref={ref} className={cn("bg-subtle-1 -mx-1 my-1 h-px", className)} {...props} />
|
||||
);
|
||||
});
|
||||
|
||||
|
|
@ -119,7 +119,7 @@ const ContextMenuSubmenuTrigger = React.forwardRef(function ContextMenuSubmenuTr
|
|||
<ContextMenuPrimitive.SubmenuTrigger
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"flex cursor-default select-none items-center rounded-xs px-2 py-1.5 text-13 outline-none focus:outline-none",
|
||||
"flex cursor-default items-center rounded-xs px-2 py-1.5 text-13 outline-none select-none focus:outline-none",
|
||||
"focus:bg-surface-2 data-[state=open]:bg-surface-2",
|
||||
className
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -48,10 +48,10 @@ const Info: React.FC<{ title: string; children?: React.ReactNode; tone?: "info"
|
|||
tone = "info",
|
||||
}) => (
|
||||
<div
|
||||
className={`mb-4 rounded-md border ${tone === "warn" ? "border-danger-strong bg-red-50 p-4" : "border-subtle bg-layer-1 p-4"}`}
|
||||
className={`mb-4 rounded-md border ${tone === "warn" ? "bg-red-50 border-danger-strong p-4" : "border-subtle bg-layer-1 p-4"}`}
|
||||
>
|
||||
<h3 className={`text-primary mb-2 text-16 font-semibold`}>{title}</h3>
|
||||
<div className="text-secondary text-13">{children}</div>
|
||||
<h3 className={`mb-2 text-16 font-semibold text-primary`}>{title}</h3>
|
||||
<div className="text-13 text-secondary">{children}</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
|
|
@ -82,8 +82,8 @@ export const ApplicationRoot: Story = {
|
|||
</Info>
|
||||
|
||||
<Surface>
|
||||
<h4 className="text-primary mb-2 font-semibold">Page Content (bg-surface-1)</h4>
|
||||
<p className="text-secondary text-13">Pages use surfaces, not canvas. This is a typical page layout.</p>
|
||||
<h4 className="mb-2 font-semibold text-primary">Page Content (bg-surface-1)</h4>
|
||||
<p className="text-13 text-secondary">Pages use surfaces, not canvas. This is a typical page layout.</p>
|
||||
</Surface>
|
||||
</DemoRoot>
|
||||
),
|
||||
|
|
@ -98,13 +98,13 @@ export const SurfaceSiblings: Story = {
|
|||
|
||||
<TwoColGrid>
|
||||
<Surface>
|
||||
<h4 className="text-primary mb-2 font-semibold">Surface 1</h4>
|
||||
<p className="text-secondary text-13">This is bg-surface-1 - a primary surface</p>
|
||||
<h4 className="mb-2 font-semibold text-primary">Surface 1</h4>
|
||||
<p className="text-13 text-secondary">This is bg-surface-1 - a primary surface</p>
|
||||
</Surface>
|
||||
|
||||
<Surface className="bg-surface-2 rounded-md p-6">
|
||||
<h4 className="text-primary mb-2 font-semibold">Surface 2</h4>
|
||||
<p className="text-secondary text-13">This is bg-surface-2 - a secondary surface (sibling to surface-1)</p>
|
||||
<Surface className="rounded-md bg-surface-2 p-6">
|
||||
<h4 className="mb-2 font-semibold text-primary">Surface 2</h4>
|
||||
<p className="text-13 text-secondary">This is bg-surface-2 - a secondary surface (sibling to surface-1)</p>
|
||||
</Surface>
|
||||
</TwoColGrid>
|
||||
</DemoRoot>
|
||||
|
|
@ -117,19 +117,19 @@ export const LayerStacking: Story = {
|
|||
<Info title="✅ Layer Stacking Pattern">Layers stack to create depth: Surface → Layer 1 → Layer 2 → Layer 3</Info>
|
||||
|
||||
<Surface>
|
||||
<h4 className="text-primary mb-3 font-semibold">Surface 1</h4>
|
||||
<h4 className="mb-3 font-semibold text-primary">Surface 1</h4>
|
||||
|
||||
<Layer className="bg-layer-1 hover:bg-layer-1-hover mb-4 rounded-md p-4">
|
||||
<h5 className="text-primary mb-2 font-medium">Layer 1 (First level of depth)</h5>
|
||||
<p className="text-secondary mb-3 text-13">Hover over me to see the hover state</p>
|
||||
<Layer className="mb-4 rounded-md bg-layer-1 p-4 hover:bg-layer-1-hover">
|
||||
<h5 className="mb-2 font-medium text-primary">Layer 1 (First level of depth)</h5>
|
||||
<p className="mb-3 text-13 text-secondary">Hover over me to see the hover state</p>
|
||||
|
||||
<Layer className="bg-layer-2 hover:bg-layer-2-hover rounded-md p-3">
|
||||
<h6 className="text-primary mb-2 text-13 font-medium">Layer 2 (Second level)</h6>
|
||||
<p className="text-secondary mb-2 text-13">Nested within Layer 1</p>
|
||||
<Layer className="rounded-md bg-layer-2 p-3 hover:bg-layer-2-hover">
|
||||
<h6 className="mb-2 text-13 font-medium text-primary">Layer 2 (Second level)</h6>
|
||||
<p className="mb-2 text-13 text-secondary">Nested within Layer 1</p>
|
||||
|
||||
<Layer className="bg-layer-3 hover:bg-layer-3-hover rounded-md p-2" hover>
|
||||
<p className="text-primary text-11 font-medium">Layer 3 (Third level)</p>
|
||||
<p className="text-secondary text-11">Deepest nesting level</p>
|
||||
<Layer className="rounded-md bg-layer-3 p-2 hover:bg-layer-3-hover" hover>
|
||||
<p className="text-11 font-medium text-primary">Layer 3 (Third level)</p>
|
||||
<p className="text-11 text-secondary">Deepest nesting level</p>
|
||||
</Layer>
|
||||
</Layer>
|
||||
</Layer>
|
||||
|
|
@ -148,18 +148,18 @@ export const SurfaceLayerAssociation: Story = {
|
|||
|
||||
<TwoColGrid>
|
||||
<Surface>
|
||||
<h4 className="text-primary mb-3 font-semibold">Surface 1</h4>
|
||||
<Layer className="bg-layer-1 hover:bg-layer-1-hover rounded-md p-4">
|
||||
<h5 className="text-primary mb-1 font-medium">Layer 1</h5>
|
||||
<p className="text-secondary text-13">Correctly using layer-1 with surface-1</p>
|
||||
<h4 className="mb-3 font-semibold text-primary">Surface 1</h4>
|
||||
<Layer className="rounded-md bg-layer-1 p-4 hover:bg-layer-1-hover">
|
||||
<h5 className="mb-1 font-medium text-primary">Layer 1</h5>
|
||||
<p className="text-13 text-secondary">Correctly using layer-1 with surface-1</p>
|
||||
</Layer>
|
||||
</Surface>
|
||||
|
||||
<Surface className="bg-surface-2 rounded-md p-6">
|
||||
<h4 className="text-primary mb-3 font-semibold">Surface 2</h4>
|
||||
<Layer className="bg-layer-2 hover:bg-layer-2-hover rounded-md p-4">
|
||||
<h5 className="text-primary mb-1 font-medium">Layer 2</h5>
|
||||
<p className="text-secondary text-13">Correctly using layer-2 with surface-2</p>
|
||||
<Surface className="rounded-md bg-surface-2 p-6">
|
||||
<h4 className="mb-3 font-semibold text-primary">Surface 2</h4>
|
||||
<Layer className="rounded-md bg-layer-2 p-4 hover:bg-layer-2-hover">
|
||||
<h5 className="mb-1 font-medium text-primary">Layer 2</h5>
|
||||
<p className="text-13 text-secondary">Correctly using layer-2 with surface-2</p>
|
||||
</Layer>
|
||||
</Surface>
|
||||
</TwoColGrid>
|
||||
|
|
@ -169,18 +169,18 @@ export const SurfaceLayerAssociation: Story = {
|
|||
In very rare cases, form elements (inputs, buttons, switches) can use one level above for visual separation.
|
||||
</Info>
|
||||
<Surface>
|
||||
<h4 className="text-primary mb-3 font-semibold">Modal with Input (Rare Exception)</h4>
|
||||
<h4 className="mb-3 font-semibold text-primary">Modal with Input (Rare Exception)</h4>
|
||||
<div className="space-y-3">
|
||||
<div>
|
||||
<label htmlFor="example-input" className="text-secondary text-13">
|
||||
<label htmlFor="example-input" className="text-13 text-secondary">
|
||||
Name
|
||||
</label>
|
||||
<input
|
||||
id="example-input"
|
||||
className="w-full bg-layer-2 border border-subtle rounded-md px-3 py-2 text-primary mt-1"
|
||||
className="mt-1 w-full rounded-md border border-subtle bg-layer-2 px-3 py-2 text-primary"
|
||||
placeholder="Input uses layer-2 for visual separation"
|
||||
/>
|
||||
<p className="text-tertiary text-11 mt-1">
|
||||
<p className="mt-1 text-11 text-tertiary">
|
||||
Input uses bg-layer-2 (one level above) for visual separation from modal surface
|
||||
</p>
|
||||
</div>
|
||||
|
|
@ -200,21 +200,21 @@ export const ModalException: Story = {
|
|||
</Info>
|
||||
|
||||
<Surface>
|
||||
<h4 className="text-primary mb-2 font-semibold">Main Page Content</h4>
|
||||
<p className="text-secondary text-13">This is the main page using bg-surface-1</p>
|
||||
<h4 className="mb-2 font-semibold text-primary">Main Page Content</h4>
|
||||
<p className="text-13 text-secondary">This is the main page using bg-surface-1</p>
|
||||
</Surface>
|
||||
|
||||
<div className="fixed inset-0 z-50 flex items-center justify-center">
|
||||
<div className="bg-backdrop absolute inset-0" />
|
||||
<div className="bg-surface-1 relative z-10 max-w-md rounded-lg p-6 shadow-lg">
|
||||
<h4 className="text-primary mb-3 font-semibold">Modal Dialog</h4>
|
||||
<p className="text-secondary mb-4 text-13">
|
||||
<div className="absolute inset-0 bg-backdrop" />
|
||||
<div className="shadow-lg relative z-10 max-w-md rounded-lg bg-surface-1 p-6">
|
||||
<h4 className="mb-3 font-semibold text-primary">Modal Dialog</h4>
|
||||
<p className="mb-4 text-13 text-secondary">
|
||||
This modal uses bg-surface-1 even though the page below also uses bg-surface-1. This is allowed because
|
||||
they're on different planes.
|
||||
</p>
|
||||
|
||||
<Layer className="bg-layer-1 hover:bg-layer-1-hover rounded-md p-3">
|
||||
<p className="text-primary text-13">Modal content can use layers as normal</p>
|
||||
<Layer className="rounded-md bg-layer-1 p-3 hover:bg-layer-1-hover">
|
||||
<p className="text-13 text-primary">Modal content can use layers as normal</p>
|
||||
</Layer>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -228,12 +228,12 @@ export const CardListPattern: Story = {
|
|||
<Info title="✅ Card List Pattern">Common pattern: Surface containing multiple layer-1 cards</Info>
|
||||
|
||||
<Surface>
|
||||
<h4 className="text-primary mb-4 font-semibold">Task List</h4>
|
||||
<h4 className="mb-4 font-semibold text-primary">Task List</h4>
|
||||
<div className="space-y-3">
|
||||
{[1, 2, 3].map((item) => (
|
||||
<Layer key={item} className="bg-layer-1 hover:bg-layer-1-hover rounded-md p-4">
|
||||
<h5 className="text-primary mb-1 font-medium">Task {item}</h5>
|
||||
<p className="text-secondary text-13">This is a task card using bg-layer-1 with hover state</p>
|
||||
<Layer key={item} className="rounded-md bg-layer-1 p-4 hover:bg-layer-1-hover">
|
||||
<h5 className="mb-1 font-medium text-primary">Task {item}</h5>
|
||||
<p className="text-13 text-secondary">This is a task card using bg-layer-1 with hover state</p>
|
||||
</Layer>
|
||||
))}
|
||||
</div>
|
||||
|
|
@ -250,21 +250,21 @@ export const SidebarLayoutPattern: Story = {
|
|||
hover states.
|
||||
</Info>
|
||||
|
||||
<Surface className="bg-surface-1 flex rounded-md">
|
||||
<aside className="border-subtle w-64 border-r p-4">
|
||||
<h4 className="text-primary mb-3 font-semibold">Sidebar</h4>
|
||||
<Surface className="flex rounded-md bg-surface-1">
|
||||
<aside className="w-64 border-r border-subtle p-4">
|
||||
<h4 className="mb-3 font-semibold text-primary">Sidebar</h4>
|
||||
<div className="space-y-2">
|
||||
{["Home", "Projects", "Settings"].map((item) => (
|
||||
<div key={item} className="hover:bg-layer-1-hover rounded-md p-2 transition-colors">
|
||||
<p className="text-primary text-13">{item}</p>
|
||||
<div key={item} className="rounded-md p-2 transition-colors hover:bg-layer-1-hover">
|
||||
<p className="text-13 text-primary">{item}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<main className="flex-1 p-6">
|
||||
<h4 className="text-primary mb-3 font-semibold">Main Content</h4>
|
||||
<Layer className="bg-layer-1 hover:bg-layer-1-hover rounded-md p-4">
|
||||
<h4 className="mb-3 font-semibold text-primary">Main Content</h4>
|
||||
<Layer className="rounded-md bg-layer-1 p-4 hover:bg-layer-1-hover">
|
||||
<p className="text-primary">Content card using layer-1</p>
|
||||
</Layer>
|
||||
</main>
|
||||
|
|
@ -280,19 +280,19 @@ export const StateVariants: Story = {
|
|||
|
||||
<Surface>
|
||||
<div className="space-y-4">
|
||||
<Layer className="bg-layer-1 hover:bg-layer-1-hover rounded-md p-4">
|
||||
<h5 className="text-primary mb-1 font-medium">Hover State</h5>
|
||||
<p className="text-secondary text-13">Hover over me to see bg-layer-1-hover</p>
|
||||
<Layer className="rounded-md bg-layer-1 p-4 hover:bg-layer-1-hover">
|
||||
<h5 className="mb-1 font-medium text-primary">Hover State</h5>
|
||||
<p className="text-13 text-secondary">Hover over me to see bg-layer-1-hover</p>
|
||||
</Layer>
|
||||
|
||||
<div className="bg-layer-1-active rounded-md p-4">
|
||||
<h5 className="text-primary mb-1 font-medium">Active State</h5>
|
||||
<p className="text-secondary text-13">Using bg-layer-1-active (pressed/active)</p>
|
||||
<div className="rounded-md bg-layer-1-active p-4">
|
||||
<h5 className="mb-1 font-medium text-primary">Active State</h5>
|
||||
<p className="text-13 text-secondary">Using bg-layer-1-active (pressed/active)</p>
|
||||
</div>
|
||||
|
||||
<div className="bg-layer-1-selected rounded-md p-4">
|
||||
<h5 className="text-primary mb-1 font-medium">Selected State</h5>
|
||||
<p className="text-secondary text-13">Using bg-layer-1-selected (when selected)</p>
|
||||
<div className="rounded-md bg-layer-1-selected p-4">
|
||||
<h5 className="mb-1 font-medium text-primary">Selected State</h5>
|
||||
<p className="text-13 text-secondary">Using bg-layer-1-selected (when selected)</p>
|
||||
</div>
|
||||
</div>
|
||||
</Surface>
|
||||
|
|
@ -306,12 +306,12 @@ export const TextColorHierarchy: Story = {
|
|||
<Info title="✅ Text Color Hierarchy">Semantic text colors for different importance levels</Info>
|
||||
|
||||
<Surface>
|
||||
<div className="bg-layer-1 rounded-md p-4">
|
||||
<h4 className="text-primary mb-3 text-16 font-semibold">Primary Text</h4>
|
||||
<p className="text-secondary mb-3">Secondary text for descriptions and supporting content</p>
|
||||
<p className="text-tertiary mb-3 text-13">Tertiary text for labels and metadata</p>
|
||||
<div className="rounded-md bg-layer-1 p-4">
|
||||
<h4 className="mb-3 text-16 font-semibold text-primary">Primary Text</h4>
|
||||
<p className="mb-3 text-secondary">Secondary text for descriptions and supporting content</p>
|
||||
<p className="mb-3 text-13 text-tertiary">Tertiary text for labels and metadata</p>
|
||||
<input
|
||||
className="placeholder-(--text-color-placeholder) border-subtle rounded border px-3 py-2"
|
||||
className="rounded border border-subtle px-3 py-2 placeholder-(--text-color-placeholder)"
|
||||
placeholder="Placeholder text for inputs"
|
||||
/>
|
||||
</div>
|
||||
|
|
@ -325,9 +325,9 @@ export const CompleteExample: Story = {
|
|||
<DemoRoot>
|
||||
<Info title="✅ Complete Example">A realistic dashboard layout using all design system concepts</Info>
|
||||
|
||||
<div className="bg-surface-1 mb-6 rounded-md">
|
||||
<div className="border-subtle border-b p-4">
|
||||
<h1 className="text-primary text-18 font-bold">Dashboard</h1>
|
||||
<div className="mb-6 rounded-md bg-surface-1">
|
||||
<div className="border-b border-subtle p-4">
|
||||
<h1 className="text-18 font-bold text-primary">Dashboard</h1>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -338,9 +338,9 @@ export const CompleteExample: Story = {
|
|||
{ label: "Completed Tasks", value: "856" },
|
||||
].map((stat, idx) => (
|
||||
<Surface key={idx}>
|
||||
<Layer className="bg-layer-1 hover:bg-layer-1-hover rounded-md p-4">
|
||||
<p className="text-tertiary mb-1 text-13">{stat.label}</p>
|
||||
<p className="text-primary text-20 font-bold">{stat.value}</p>
|
||||
<Layer className="rounded-md bg-layer-1 p-4 hover:bg-layer-1-hover">
|
||||
<p className="mb-1 text-13 text-tertiary">{stat.label}</p>
|
||||
<p className="text-20 font-bold text-primary">{stat.value}</p>
|
||||
</Layer>
|
||||
</Surface>
|
||||
))}
|
||||
|
|
@ -348,23 +348,23 @@ export const CompleteExample: Story = {
|
|||
|
||||
<div className="mt-6 grid grid-cols-2 gap-6">
|
||||
<Surface>
|
||||
<h3 className="text-primary mb-4 font-semibold">Recent Activity</h3>
|
||||
<h3 className="mb-4 font-semibold text-primary">Recent Activity</h3>
|
||||
<div className="space-y-2">
|
||||
{[1, 2, 3].map((item) => (
|
||||
<Layer key={item} className="bg-layer-1 hover:bg-layer-1-hover rounded-md p-3">
|
||||
<p className="text-primary mb-1 text-13 font-medium">Activity {item}</p>
|
||||
<p className="text-secondary text-11">Description of the activity</p>
|
||||
<Layer key={item} className="rounded-md bg-layer-1 p-3 hover:bg-layer-1-hover">
|
||||
<p className="mb-1 text-13 font-medium text-primary">Activity {item}</p>
|
||||
<p className="text-11 text-secondary">Description of the activity</p>
|
||||
</Layer>
|
||||
))}
|
||||
</div>
|
||||
</Surface>
|
||||
|
||||
<Surface className="bg-surface-2 rounded-md p-6">
|
||||
<h3 className="text-primary mb-4 font-semibold">Quick Actions</h3>
|
||||
<Surface className="rounded-md bg-surface-2 p-6">
|
||||
<h3 className="mb-4 font-semibold text-primary">Quick Actions</h3>
|
||||
<div className="space-y-2">
|
||||
{["Create Project", "Invite Team", "View Reports"].map((action) => (
|
||||
<Layer key={action} className="bg-layer-2 hover:bg-layer-2-hover rounded-md p-3">
|
||||
<p className="text-primary text-13">{action}</p>
|
||||
<Layer key={action} className="rounded-md bg-layer-2 p-3 hover:bg-layer-2-hover">
|
||||
<p className="text-13 text-primary">{action}</p>
|
||||
</Layer>
|
||||
))}
|
||||
</div>
|
||||
|
|
@ -382,49 +382,49 @@ export const CommonMistakes: Story = {
|
|||
</Info>
|
||||
|
||||
<div className="space-y-6">
|
||||
<div className="border-2 border-danger-strong rounded-md p-4">
|
||||
<h4 className="text-primary mb-2 font-semibold">❌ Mistake 1: Nested Surfaces (Same Plane)</h4>
|
||||
<div className="rounded-md border-2 border-danger-strong p-4">
|
||||
<h4 className="mb-2 font-semibold text-primary">❌ Mistake 1: Nested Surfaces (Same Plane)</h4>
|
||||
<Surface>
|
||||
<p className="text-secondary mb-2 text-13">Surface 1</p>
|
||||
<div className="bg-surface-2 rounded-md p-4">
|
||||
<p className="text-secondary text-13">Surface 2 nested inside Surface 1 - WRONG!</p>
|
||||
<p className="mb-2 text-13 text-secondary">Surface 1</p>
|
||||
<div className="rounded-md bg-surface-2 p-4">
|
||||
<p className="text-13 text-secondary">Surface 2 nested inside Surface 1 - WRONG!</p>
|
||||
</div>
|
||||
</Surface>
|
||||
<p className="text-tertiary mt-2 text-11">
|
||||
<p className="mt-2 text-11 text-tertiary">
|
||||
✅ Fix: Use bg-layer-1 for nested elements, or make them sibling surfaces
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="border-2 border-danger-strong rounded-md p-4">
|
||||
<h4 className="text-primary mb-2 font-semibold">❌ Mistake 2: Wrong Layer-Surface Association</h4>
|
||||
<div className="rounded-md border-2 border-danger-strong p-4">
|
||||
<h4 className="mb-2 font-semibold text-primary">❌ Mistake 2: Wrong Layer-Surface Association</h4>
|
||||
<Surface>
|
||||
<p className="text-secondary mb-2 text-13">Surface 1</p>
|
||||
<div className="bg-layer-2 rounded-md p-4">
|
||||
<p className="text-secondary text-13">Using layer-2 with surface-1 for content box - WRONG!</p>
|
||||
<p className="mb-2 text-13 text-secondary">Surface 1</p>
|
||||
<div className="rounded-md bg-layer-2 p-4">
|
||||
<p className="text-13 text-secondary">Using layer-2 with surface-1 for content box - WRONG!</p>
|
||||
</div>
|
||||
</Surface>
|
||||
<p className="text-tertiary mt-2 text-11">
|
||||
<p className="mt-2 text-11 text-tertiary">
|
||||
✅ Fix: Use bg-layer-1 with bg-surface-1 for content boxes. Exception: Very rare cases for inputs/buttons
|
||||
that need visual separation (e.g., input in modal can use bg-layer-2 for separation).
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="border-2 border-danger-strong rounded-md p-4">
|
||||
<h4 className="text-primary mb-2 font-semibold">❌ Mistake 3: Mismatched Hover State</h4>
|
||||
<div className="rounded-md border-2 border-danger-strong p-4">
|
||||
<h4 className="mb-2 font-semibold text-primary">❌ Mistake 3: Mismatched Hover State</h4>
|
||||
<Surface>
|
||||
<div className="bg-layer-1 hover:bg-layer-2-hover rounded-md p-4 transition-colors">
|
||||
<p className="text-secondary text-13">bg-layer-1 with hover:bg-layer-2-hover - WRONG!</p>
|
||||
<div className="rounded-md bg-layer-1 p-4 transition-colors hover:bg-layer-2-hover">
|
||||
<p className="text-13 text-secondary">bg-layer-1 with hover:bg-layer-2-hover - WRONG!</p>
|
||||
</div>
|
||||
</Surface>
|
||||
<p className="text-tertiary mt-2 text-11">✅ Fix: Use bg-layer-1 hover:bg-layer-1-hover</p>
|
||||
<p className="mt-2 text-11 text-tertiary">✅ Fix: Use bg-layer-1 hover:bg-layer-1-hover</p>
|
||||
</div>
|
||||
|
||||
<div className="border-2 border-danger-strong rounded-md p-4">
|
||||
<h4 className="text-primary mb-2 font-semibold">❌ Mistake 4: Canvas for Pages</h4>
|
||||
<div className="bg-canvas rounded-md p-4">
|
||||
<p className="text-secondary text-13">Using bg-canvas for a page or component - WRONG!</p>
|
||||
<div className="rounded-md border-2 border-danger-strong p-4">
|
||||
<h4 className="mb-2 font-semibold text-primary">❌ Mistake 4: Canvas for Pages</h4>
|
||||
<div className="rounded-md bg-canvas p-4">
|
||||
<p className="text-13 text-secondary">Using bg-canvas for a page or component - WRONG!</p>
|
||||
</div>
|
||||
<p className="text-tertiary mt-2 text-11">
|
||||
<p className="mt-2 text-11 text-tertiary">
|
||||
✅ Fix: Canvas should only be at application root. Use bg-surface-1 for pages
|
||||
</p>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ const meta = {
|
|||
<>
|
||||
<button
|
||||
onClick={() => setOpen(true)}
|
||||
className="rounded-sm bg-blue-500 px-4 py-2 text-on-color hover:bg-blue-600"
|
||||
className="bg-blue-500 hover:bg-blue-600 rounded-sm px-4 py-2 text-on-color"
|
||||
>
|
||||
Open Dialog
|
||||
</button>
|
||||
|
|
@ -44,18 +44,18 @@ const meta = {
|
|||
<div className="p-6">
|
||||
<Dialog.Title>Dialog Title</Dialog.Title>
|
||||
<div className="mt-4">
|
||||
<p className="text-13 text-gray-600">This is the dialog content. You can put any content here.</p>
|
||||
<p className="text-gray-600 text-13">This is the dialog content. You can put any content here.</p>
|
||||
</div>
|
||||
<div className="mt-6 flex justify-end gap-2">
|
||||
<button
|
||||
onClick={() => setOpen(false)}
|
||||
className="rounded-sm bg-gray-200 px-4 py-2 text-13 hover:bg-gray-300"
|
||||
className="bg-gray-200 hover:bg-gray-300 rounded-sm px-4 py-2 text-13"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setOpen(false)}
|
||||
className="rounded-sm bg-blue-500 px-4 py-2 text-13 text-on-color hover:bg-blue-600"
|
||||
className="bg-blue-500 hover:bg-blue-600 rounded-sm px-4 py-2 text-13 text-on-color"
|
||||
>
|
||||
Confirm
|
||||
</button>
|
||||
|
|
@ -85,7 +85,7 @@ export const TopPosition: Story = {
|
|||
<>
|
||||
<button
|
||||
onClick={() => setOpen(true)}
|
||||
className="rounded-sm bg-blue-500 px-4 py-2 text-on-color hover:bg-blue-600"
|
||||
className="bg-blue-500 hover:bg-blue-600 rounded-sm px-4 py-2 text-on-color"
|
||||
>
|
||||
Open Dialog (Top)
|
||||
</button>
|
||||
|
|
@ -95,14 +95,14 @@ export const TopPosition: Story = {
|
|||
<div className="p-6">
|
||||
<Dialog.Title>Top Positioned Dialog</Dialog.Title>
|
||||
<div className="mt-4">
|
||||
<p className="text-13 text-gray-600">
|
||||
<p className="text-gray-600 text-13">
|
||||
This dialog appears at the top of the screen instead of centered.
|
||||
</p>
|
||||
</div>
|
||||
<div className="mt-6 flex justify-end gap-2">
|
||||
<button
|
||||
onClick={() => setOpen(false)}
|
||||
className="rounded-sm bg-gray-200 px-4 py-2 text-13 hover:bg-gray-300"
|
||||
className="bg-gray-200 hover:bg-gray-300 rounded-sm px-4 py-2 text-13"
|
||||
>
|
||||
Close
|
||||
</button>
|
||||
|
|
@ -123,7 +123,7 @@ export const SmallWidth: Story = {
|
|||
<>
|
||||
<button
|
||||
onClick={() => setOpen(true)}
|
||||
className="rounded-sm bg-blue-500 px-4 py-2 text-on-color hover:bg-blue-600"
|
||||
className="bg-blue-500 hover:bg-blue-600 rounded-sm px-4 py-2 text-on-color"
|
||||
>
|
||||
Open Small Dialog
|
||||
</button>
|
||||
|
|
@ -133,12 +133,12 @@ export const SmallWidth: Story = {
|
|||
<div className="p-6">
|
||||
<Dialog.Title>Small Dialog</Dialog.Title>
|
||||
<div className="mt-4">
|
||||
<p className="text-13 text-gray-600">This is a small dialog.</p>
|
||||
<p className="text-gray-600 text-13">This is a small dialog.</p>
|
||||
</div>
|
||||
<div className="mt-6 flex justify-end">
|
||||
<button
|
||||
onClick={() => setOpen(false)}
|
||||
className="rounded-sm bg-blue-500 px-4 py-2 text-13 text-on-color hover:bg-blue-600"
|
||||
className="bg-blue-500 hover:bg-blue-600 rounded-sm px-4 py-2 text-13 text-on-color"
|
||||
>
|
||||
Close
|
||||
</button>
|
||||
|
|
@ -159,7 +159,7 @@ export const LargeWidth: Story = {
|
|||
<>
|
||||
<button
|
||||
onClick={() => setOpen(true)}
|
||||
className="rounded-sm bg-blue-500 px-4 py-2 text-on-color hover:bg-blue-600"
|
||||
className="bg-blue-500 hover:bg-blue-600 rounded-sm px-4 py-2 text-on-color"
|
||||
>
|
||||
Open Large Dialog
|
||||
</button>
|
||||
|
|
@ -169,14 +169,14 @@ export const LargeWidth: Story = {
|
|||
<div className="p-6">
|
||||
<Dialog.Title>Large Dialog</Dialog.Title>
|
||||
<div className="mt-4">
|
||||
<p className="text-13 text-gray-600">
|
||||
<p className="text-gray-600 text-13">
|
||||
This is a large dialog with more horizontal space for content.
|
||||
</p>
|
||||
</div>
|
||||
<div className="mt-6 flex justify-end">
|
||||
<button
|
||||
onClick={() => setOpen(false)}
|
||||
className="rounded-sm bg-blue-500 px-4 py-2 text-13 text-on-color hover:bg-blue-600"
|
||||
className="bg-blue-500 hover:bg-blue-600 rounded-sm px-4 py-2 text-13 text-on-color"
|
||||
>
|
||||
Close
|
||||
</button>
|
||||
|
|
@ -197,7 +197,7 @@ export const WithCloseButton: Story = {
|
|||
<>
|
||||
<button
|
||||
onClick={() => setOpen(true)}
|
||||
className="rounded-sm bg-blue-500 px-4 py-2 text-on-color hover:bg-blue-600"
|
||||
className="bg-blue-500 hover:bg-blue-600 rounded-sm px-4 py-2 text-on-color"
|
||||
>
|
||||
Open Dialog with Close Button
|
||||
</button>
|
||||
|
|
@ -207,12 +207,12 @@ export const WithCloseButton: Story = {
|
|||
<div className="p-6">
|
||||
<div className="flex items-start justify-between">
|
||||
<Dialog.Title>Dialog with Close Button</Dialog.Title>
|
||||
<button onClick={() => setOpen(false)} className="rounded-full p-1 hover:bg-gray-100">
|
||||
<button onClick={() => setOpen(false)} className="hover:bg-gray-100 rounded-full p-1">
|
||||
<CloseIcon className="h-4 w-4" />
|
||||
</button>
|
||||
</div>
|
||||
<div className="mt-4">
|
||||
<p className="text-13 text-gray-600">This dialog has a close button in the header.</p>
|
||||
<p className="text-gray-600 text-13">This dialog has a close button in the header.</p>
|
||||
</div>
|
||||
</div>
|
||||
</Dialog.Panel>
|
||||
|
|
@ -234,7 +234,7 @@ export const ConfirmationDialog: Story = {
|
|||
<>
|
||||
<button
|
||||
onClick={() => setOpen(true)}
|
||||
className="rounded-sm bg-red-500 px-4 py-2 text-on-color hover:bg-red-600"
|
||||
className="bg-red-500 hover:bg-red-600 rounded-sm px-4 py-2 text-on-color"
|
||||
>
|
||||
Delete Item
|
||||
</button>
|
||||
|
|
@ -244,20 +244,20 @@ export const ConfirmationDialog: Story = {
|
|||
<div className="p-6">
|
||||
<Dialog.Title>Confirm Deletion</Dialog.Title>
|
||||
<div className="mt-4">
|
||||
<p className="text-13 text-gray-600">
|
||||
<p className="text-gray-600 text-13">
|
||||
Are you sure you want to delete this item? This action cannot be undone.
|
||||
</p>
|
||||
</div>
|
||||
<div className="mt-6 flex justify-end gap-2">
|
||||
<button
|
||||
onClick={() => setOpen(false)}
|
||||
className="rounded-sm bg-gray-200 px-4 py-2 text-13 hover:bg-gray-300"
|
||||
className="bg-gray-200 hover:bg-gray-300 rounded-sm px-4 py-2 text-13"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
<button
|
||||
onClick={handleConfirm}
|
||||
className="rounded-sm bg-red-500 px-4 py-2 text-13 text-on-color hover:bg-red-600"
|
||||
className="bg-red-500 hover:bg-red-600 rounded-sm px-4 py-2 text-13 text-on-color"
|
||||
>
|
||||
Delete
|
||||
</button>
|
||||
|
|
@ -283,7 +283,7 @@ export const FormDialog: Story = {
|
|||
<>
|
||||
<button
|
||||
onClick={() => setOpen(true)}
|
||||
className="rounded-sm bg-blue-500 px-4 py-2 text-on-color hover:bg-blue-600"
|
||||
className="bg-blue-500 hover:bg-blue-600 rounded-sm px-4 py-2 text-on-color"
|
||||
>
|
||||
Open Form
|
||||
</button>
|
||||
|
|
@ -294,24 +294,24 @@ export const FormDialog: Story = {
|
|||
<Dialog.Title>Create New Item</Dialog.Title>
|
||||
<div className="mt-4 space-y-4">
|
||||
<div>
|
||||
<label htmlFor="name" className="block text-13 font-medium text-gray-700">
|
||||
<label htmlFor="name" className="text-gray-700 block text-13 font-medium">
|
||||
Name
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
id="name"
|
||||
className="mt-1 w-full rounded-sm border border-gray-300 px-3 py-2 text-13"
|
||||
className="border-gray-300 mt-1 w-full rounded-sm border px-3 py-2 text-13"
|
||||
placeholder="Enter name"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label htmlFor="description" className="block text-13 font-medium text-gray-700">
|
||||
<label htmlFor="description" className="text-gray-700 block text-13 font-medium">
|
||||
Description
|
||||
</label>
|
||||
<textarea
|
||||
id="description"
|
||||
rows={3}
|
||||
className="mt-1 w-full rounded-sm border border-gray-300 px-3 py-2 text-13"
|
||||
className="border-gray-300 mt-1 w-full rounded-sm border px-3 py-2 text-13"
|
||||
placeholder="Enter description"
|
||||
/>
|
||||
</div>
|
||||
|
|
@ -320,13 +320,13 @@ export const FormDialog: Story = {
|
|||
<button
|
||||
type="button"
|
||||
onClick={() => setOpen(false)}
|
||||
className="rounded-sm bg-gray-200 px-4 py-2 text-13 hover:bg-gray-300"
|
||||
className="bg-gray-200 hover:bg-gray-300 rounded-sm px-4 py-2 text-13"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
<button
|
||||
type="submit"
|
||||
className="rounded-sm bg-blue-500 px-4 py-2 text-13 text-on-color hover:bg-blue-600"
|
||||
className="bg-blue-500 hover:bg-blue-600 rounded-sm px-4 py-2 text-13 text-on-color"
|
||||
>
|
||||
Create
|
||||
</button>
|
||||
|
|
@ -347,7 +347,7 @@ export const ScrollableContent: Story = {
|
|||
<>
|
||||
<button
|
||||
onClick={() => setOpen(true)}
|
||||
className="rounded-sm bg-blue-500 px-4 py-2 text-on-color hover:bg-blue-600"
|
||||
className="bg-blue-500 hover:bg-blue-600 rounded-sm px-4 py-2 text-on-color"
|
||||
>
|
||||
Open Scrollable Dialog
|
||||
</button>
|
||||
|
|
@ -358,7 +358,7 @@ export const ScrollableContent: Story = {
|
|||
<Dialog.Title>Scrollable Content</Dialog.Title>
|
||||
<div className="mt-4 max-h-96 overflow-y-auto">
|
||||
{Array.from({ length: 20 }, (_, i) => (
|
||||
<p key={i} className="mb-2 text-13 text-gray-600">
|
||||
<p key={i} className="text-gray-600 mb-2 text-13">
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut
|
||||
labore et dolore magna aliqua.
|
||||
</p>
|
||||
|
|
@ -367,7 +367,7 @@ export const ScrollableContent: Story = {
|
|||
<div className="mt-6 flex justify-end">
|
||||
<button
|
||||
onClick={() => setOpen(false)}
|
||||
className="rounded-sm bg-blue-500 px-4 py-2 text-13 text-on-color hover:bg-blue-600"
|
||||
className="bg-blue-500 hover:bg-blue-600 rounded-sm px-4 py-2 text-13 text-on-color"
|
||||
>
|
||||
Close
|
||||
</button>
|
||||
|
|
@ -401,7 +401,7 @@ export const AllWidths: Story = {
|
|||
<button
|
||||
key={width}
|
||||
onClick={() => setOpenWidth(width)}
|
||||
className="rounded-sm bg-blue-500 px-4 py-2 text-13 text-on-color hover:bg-blue-600"
|
||||
className="bg-blue-500 hover:bg-blue-600 rounded-sm px-4 py-2 text-13 text-on-color"
|
||||
>
|
||||
{label}
|
||||
</button>
|
||||
|
|
@ -412,12 +412,12 @@ export const AllWidths: Story = {
|
|||
<div className="p-6">
|
||||
<Dialog.Title>{label} Dialog</Dialog.Title>
|
||||
<div className="mt-4">
|
||||
<p className="text-13 text-gray-600">This dialog uses the {label} width variant.</p>
|
||||
<p className="text-gray-600 text-13">This dialog uses the {label} width variant.</p>
|
||||
</div>
|
||||
<div className="mt-6 flex justify-end">
|
||||
<button
|
||||
onClick={() => setOpenWidth(null)}
|
||||
className="rounded-sm bg-blue-500 px-4 py-2 text-13 text-on-color hover:bg-blue-600"
|
||||
className="bg-blue-500 hover:bg-blue-600 rounded-sm px-4 py-2 text-13 text-on-color"
|
||||
>
|
||||
Close
|
||||
</button>
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ const BASE_CLASSNAME = "relative text-left bg-surface-1 rounded-lg shadow-md w-f
|
|||
|
||||
// Utility functions
|
||||
const getPositionClassNames = (position: DialogPosition) =>
|
||||
cn("isolate fixed z-100", {
|
||||
cn("fixed isolate z-100", {
|
||||
"top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2": position === "center",
|
||||
"top-8 left-1/2 -translate-x-1/2": position === "top",
|
||||
});
|
||||
|
|
|
|||
|
|
@ -44,8 +44,8 @@ export const Default: Story = {
|
|||
closeOnSelect
|
||||
/>
|
||||
{selectedValue && (
|
||||
<div className="text-13 p-4 bg-layer-1 rounded-sm border border-subtle">
|
||||
<div className="font-medium mb-2">Selected:</div>
|
||||
<div className="rounded-sm border border-subtle bg-layer-1 p-4 text-13">
|
||||
<div className="mb-2 font-medium">Selected:</div>
|
||||
<pre className="text-11">{JSON.stringify(selectedValue, null, 2)}</pre>
|
||||
</div>
|
||||
)}
|
||||
|
|
@ -140,8 +140,8 @@ export const LucideIcons: Story = {
|
|||
iconType="lucide"
|
||||
/>
|
||||
{selectedValue && (
|
||||
<div className="text-13 p-4 bg-layer-1 rounded-sm border border-subtle">
|
||||
<div className="font-medium mb-2">Selected Icon:</div>
|
||||
<div className="rounded-sm border border-subtle bg-layer-1 p-4 text-13">
|
||||
<div className="mb-2 font-medium">Selected Icon:</div>
|
||||
<pre className="text-11">{JSON.stringify(selectedValue, null, 2)}</pre>
|
||||
</div>
|
||||
)}
|
||||
|
|
@ -173,8 +173,8 @@ export const MaterialIcons: Story = {
|
|||
iconType="material"
|
||||
/>
|
||||
{selectedValue && (
|
||||
<div className="text-13 p-4 bg-layer-1 rounded-sm border border-subtle">
|
||||
<div className="font-medium mb-2">Selected Icon:</div>
|
||||
<div className="rounded-sm border border-subtle bg-layer-1 p-4 text-13">
|
||||
<div className="mb-2 font-medium">Selected Icon:</div>
|
||||
<pre className="text-11">{JSON.stringify(selectedValue, null, 2)}</pre>
|
||||
</div>
|
||||
)}
|
||||
|
|
@ -200,7 +200,7 @@ export const CloseOnSelectDisabled: Story = {
|
|||
|
||||
return (
|
||||
<div className="space-y-4 p-4">
|
||||
<div className="flex gap-2 items-center">
|
||||
<div className="flex items-center gap-2">
|
||||
<EmojiPicker
|
||||
isOpen={isOpen}
|
||||
handleToggle={setIsOpen}
|
||||
|
|
@ -210,16 +210,16 @@ export const CloseOnSelectDisabled: Story = {
|
|||
closeOnSelect={false}
|
||||
/>
|
||||
<button
|
||||
className="px-3 py-1.5 text-13 bg-layer-1 rounded-sm hover:bg-surface-2"
|
||||
className="rounded-sm bg-layer-1 px-3 py-1.5 text-13 hover:bg-surface-2"
|
||||
onClick={() => setSelectedValues([])}
|
||||
>
|
||||
Clear
|
||||
</button>
|
||||
</div>
|
||||
{selectedValues.length > 0 && (
|
||||
<div className="text-13 p-4 bg-layer-1 rounded-sm border border-subtle">
|
||||
<div className="font-medium mb-2">Selected ({selectedValues.length}):</div>
|
||||
<div className="flex gap-2 flex-wrap">
|
||||
<div className="rounded-sm border border-subtle bg-layer-1 p-4 text-13">
|
||||
<div className="mb-2 font-medium">Selected ({selectedValues.length}):</div>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{selectedValues.map((val, idx) => (
|
||||
<span key={idx} className="text-16">
|
||||
{val.type === "emoji" ? val.value : "🎨"}
|
||||
|
|
@ -312,7 +312,7 @@ export const CustomIconColor: Story = {
|
|||
defaultIconColor="#FF5733"
|
||||
/>
|
||||
{selectedValue && (
|
||||
<div className="text-13 p-4 bg-layer-1 rounded-sm border border-subtle">
|
||||
<div className="rounded-sm border border-subtle bg-layer-1 p-4 text-13">
|
||||
<pre className="text-11">{JSON.stringify(selectedValue, null, 2)}</pre>
|
||||
</div>
|
||||
)}
|
||||
|
|
@ -335,9 +335,9 @@ export const DifferentPlacements: Story = {
|
|||
const [isOpen4, setIsOpen4] = useState(false);
|
||||
|
||||
return (
|
||||
<div className="p-8 space-y-8">
|
||||
<div className="flex gap-4 items-center">
|
||||
<span className="text-13 w-32">Bottom Start:</span>
|
||||
<div className="space-y-8 p-8">
|
||||
<div className="flex items-center gap-4">
|
||||
<span className="w-32 text-13">Bottom Start:</span>
|
||||
<EmojiPicker
|
||||
isOpen={isOpen1}
|
||||
handleToggle={setIsOpen1}
|
||||
|
|
@ -346,8 +346,8 @@ export const DifferentPlacements: Story = {
|
|||
placement="bottom-start"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex gap-4 items-center">
|
||||
<span className="text-13 w-32">Bottom End:</span>
|
||||
<div className="flex items-center gap-4">
|
||||
<span className="w-32 text-13">Bottom End:</span>
|
||||
<EmojiPicker
|
||||
isOpen={isOpen2}
|
||||
handleToggle={setIsOpen2}
|
||||
|
|
@ -356,8 +356,8 @@ export const DifferentPlacements: Story = {
|
|||
placement="bottom-end"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex gap-4 items-center">
|
||||
<span className="text-13 w-32">Top Start:</span>
|
||||
<div className="flex items-center gap-4">
|
||||
<span className="w-32 text-13">Top Start:</span>
|
||||
<EmojiPicker
|
||||
isOpen={isOpen3}
|
||||
handleToggle={setIsOpen3}
|
||||
|
|
@ -366,8 +366,8 @@ export const DifferentPlacements: Story = {
|
|||
placement="top-start"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex gap-4 items-center">
|
||||
<span className="text-13 w-32">Top End:</span>
|
||||
<div className="flex items-center gap-4">
|
||||
<span className="w-32 text-13">Top End:</span>
|
||||
<EmojiPicker
|
||||
isOpen={isOpen4}
|
||||
handleToggle={setIsOpen4}
|
||||
|
|
@ -406,19 +406,19 @@ export const InFormContext: Story = {
|
|||
|
||||
return (
|
||||
<div className="max-w-md p-4">
|
||||
<form onSubmit={handleSubmit} className="space-y-4 p-6 border border-subtle rounded-lg">
|
||||
<form onSubmit={handleSubmit} className="space-y-4 rounded-lg border border-subtle p-6">
|
||||
<div>
|
||||
<label className="block text-13 font-medium mb-2">Project Title</label>
|
||||
<label className="mb-2 block text-13 font-medium">Project Title</label>
|
||||
<input
|
||||
type="text"
|
||||
value={formData.title}
|
||||
onChange={(e) => setFormData((prev) => ({ ...prev, title: e.target.value }))}
|
||||
className="w-full px-3 py-2 bg-layer-1 border border-subtle rounded-sm"
|
||||
className="w-full rounded-sm border border-subtle bg-layer-1 px-3 py-2"
|
||||
placeholder="Enter project title"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label className="block text-13 font-medium mb-2">Project Icon</label>
|
||||
<label className="mb-2 block text-13 font-medium">Project Icon</label>
|
||||
<EmojiPicker
|
||||
isOpen={isOpen}
|
||||
handleToggle={setIsOpen}
|
||||
|
|
@ -431,7 +431,7 @@ export const InFormContext: Story = {
|
|||
</div>
|
||||
<button
|
||||
type="submit"
|
||||
className="w-full px-4 py-2 bg-accent-primary text-on-color rounded-sm hover:bg-accent-primary/80"
|
||||
className="w-full rounded-sm bg-accent-primary px-4 py-2 text-on-color hover:bg-accent-primary/80"
|
||||
>
|
||||
Create Project
|
||||
</button>
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@ export function EmojiPicker(props: TCustomEmojiPicker) {
|
|||
</Popover.Button>
|
||||
<Popover.Panel
|
||||
positionerClassName="z-50"
|
||||
className={cn("w-80 bg-surface-1 rounded-md border-[0.5px] border-strong overflow-hidden", dropdownClassName)}
|
||||
className={cn("w-80 overflow-hidden rounded-md border-[0.5px] border-strong bg-surface-1", dropdownClassName)}
|
||||
side={finalSide}
|
||||
align={finalAlign}
|
||||
sideOffset={8}
|
||||
|
|
@ -132,9 +132,9 @@ export function EmojiPicker(props: TCustomEmojiPicker) {
|
|||
key={tab.key}
|
||||
value={tab.key}
|
||||
className={({ selected }) =>
|
||||
cn("py-1 text-13 rounded-sm border border-subtle bg-layer-1", {
|
||||
cn("rounded-sm border border-subtle bg-layer-1 py-1 text-13", {
|
||||
"bg-surface-1 text-primary": selected,
|
||||
"text-placeholder hover:text-tertiary hover:bg-layer-1/60": !selected,
|
||||
"text-placeholder hover:bg-layer-1/60 hover:text-tertiary": !selected,
|
||||
})
|
||||
}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -34,20 +34,20 @@ export function EmojiRoot(props: EmojiRootProps) {
|
|||
return (
|
||||
<EmojiPicker.Root
|
||||
data-slot="emoji-picker"
|
||||
className="isolate flex flex-col rounded-md h-full w-full border-none p-2"
|
||||
className="isolate flex h-full w-full flex-col rounded-md border-none p-2"
|
||||
onEmojiSelect={(val) => onChange(val.emoji)}
|
||||
>
|
||||
<div className="flex items-center gap-2 justify-between [&>[data-slot='emoji-picker-search-wrapper']]:flex-grow [&>[data-slot='emoji-picker-search-wrapper']]:p-0 px-1.5 py-2 sticky top-0 z-10 bg-surface-1">
|
||||
<div className="sticky top-0 z-10 flex items-center justify-between gap-2 bg-surface-1 px-1.5 py-2 [&>[data-slot='emoji-picker-search-wrapper']]:flex-grow [&>[data-slot='emoji-picker-search-wrapper']]:p-0">
|
||||
<div ref={searchWrapperRef} data-slot="emoji-picker-search-wrapper" className="p-2">
|
||||
<EmojiPicker.Search
|
||||
placeholder={searchPlaceholder}
|
||||
disabled={searchDisabled}
|
||||
className="block rounded-md bg-transparent placeholder-(--text-color-placeholder) focus:outline-none px-3 py-2 border-[0.5px] border-subtle text-16 p-0 h-full w-full flex-grow-0 focus:border-accent-strong"
|
||||
className="block h-full w-full flex-grow-0 rounded-md border-[0.5px] border-subtle bg-transparent p-0 px-3 py-2 text-16 placeholder-(--text-color-placeholder) focus:border-accent-strong focus:outline-none"
|
||||
/>
|
||||
</div>
|
||||
<EmojiPicker.SkinToneSelector
|
||||
data-slot="emoji-picker-skin-tone-selector"
|
||||
className="bg-surface-1 hover:bg-accent mx-2 mb-1.5 size-8 rounded-md text-16 flex-shrink-0"
|
||||
className="hover:bg-accent mx-2 mb-1.5 size-8 flex-shrink-0 rounded-md bg-surface-1 text-16"
|
||||
/>
|
||||
</div>
|
||||
<EmojiPicker.Viewport data-slot="emoji-picker-content" className={cn("relative flex-1 outline-none")}>
|
||||
|
|
@ -58,7 +58,7 @@ export function EmojiRoot(props: EmojiRootProps) {
|
|||
CategoryHeader: ({ category, ...props }) => (
|
||||
<div
|
||||
data-slot="emoji-picker-list-category-header"
|
||||
className="bg-surface-1 text-tertiary px-3 pb-1.5 text-11 font-medium"
|
||||
className="bg-surface-1 px-3 pb-1.5 text-11 font-medium text-tertiary"
|
||||
{...props}
|
||||
>
|
||||
{category.label}
|
||||
|
|
|
|||
|
|
@ -38,39 +38,39 @@ export function IconRoot(props: IconRootProps) {
|
|||
|
||||
return (
|
||||
<>
|
||||
<div className="flex flex-col sticky top-0 bg-surface-1">
|
||||
<div className="sticky top-0 flex flex-col bg-surface-1">
|
||||
{!searchDisabled && (
|
||||
<div className="flex items-center px-2 py-[15px] w-full ">
|
||||
<div className="flex w-full items-center px-2 py-[15px]">
|
||||
<div
|
||||
className={cn("relative flex items-center gap-2 bg-surface-2 h-10 rounded-lg w-full px-[30px] border", {
|
||||
className={cn("relative flex h-10 w-full items-center gap-2 rounded-lg border bg-surface-2 px-[30px]", {
|
||||
"border-accent-strong": isInputFocused,
|
||||
"border-transparent": !isInputFocused,
|
||||
})}
|
||||
onFocus={() => setIsInputFocused(true)}
|
||||
onBlur={() => setIsInputFocused(false)}
|
||||
>
|
||||
<SearchIcon className="absolute left-2.5 bottom-3 h-3.5 w-3.5 text-placeholder" />
|
||||
<SearchIcon className="absolute bottom-3 left-2.5 h-3.5 w-3.5 text-placeholder" />
|
||||
|
||||
<input
|
||||
placeholder="Search"
|
||||
value={query}
|
||||
onChange={(e) => setQuery(e.target.value)}
|
||||
className="block rounded-md bg-transparent placeholder-(--text-color-placeholder) focus:outline-none px-3 py-2 border-[0.5px] border-subtle text-16 border-none p-0 h-full w-full"
|
||||
className="block h-full w-full rounded-md border-[0.5px] border-none border-subtle bg-transparent p-0 px-3 py-2 text-16 placeholder-(--text-color-placeholder) focus:outline-none"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<div className="grid grid-cols-9 gap-2 items-center justify-items-center px-2.5 py-1 h-9">
|
||||
<div className="grid h-9 grid-cols-9 items-center justify-items-center gap-2 px-2.5 py-1">
|
||||
{showHexInput ? (
|
||||
<div className="col-span-8 flex items-center gap-1 justify-self-stretch ml-2">
|
||||
<div className="col-span-8 ml-2 flex items-center gap-1 justify-self-stretch">
|
||||
<span
|
||||
className="h-4 w-4 flex-shrink-0 rounded-full mr-1"
|
||||
className="mr-1 h-4 w-4 flex-shrink-0 rounded-full"
|
||||
style={{
|
||||
backgroundColor: `#${hexValue}`,
|
||||
}}
|
||||
/>
|
||||
<span className="text-11 text-tertiary flex-shrink-0">HEX</span>
|
||||
<span className="text-11 text-secondary flex-shrink-0 -mr-1">#</span>
|
||||
<span className="flex-shrink-0 text-11 text-tertiary">HEX</span>
|
||||
<span className="-mr-1 flex-shrink-0 text-11 text-secondary">#</span>
|
||||
<input
|
||||
type="text"
|
||||
value={hexValue}
|
||||
|
|
@ -79,7 +79,7 @@ export function IconRoot(props: IconRootProps) {
|
|||
setHexValue(value);
|
||||
if (/^[0-9A-Fa-f]{6}$/.test(value)) setActiveColor(adjustColorForContrast(`#${value}`));
|
||||
}}
|
||||
className="block placeholder-(--text-color-placeholder) focus:outline-none px-3 py-2 border-[0.5px] border-subtle flex-grow pl-0 text-11 text-secondary rounded-sm border-none bg-transparent ring-0"
|
||||
className="block flex-grow rounded-sm border-[0.5px] border-none border-subtle bg-transparent px-3 py-2 pl-0 text-11 text-secondary placeholder-(--text-color-placeholder) ring-0 focus:outline-none"
|
||||
autoFocus
|
||||
/>
|
||||
</div>
|
||||
|
|
@ -88,7 +88,7 @@ export function IconRoot(props: IconRootProps) {
|
|||
<button
|
||||
key={curCol}
|
||||
type="button"
|
||||
className="grid place-items-center size-5"
|
||||
className="grid size-5 place-items-center"
|
||||
onClick={() => {
|
||||
setActiveColor(curCol);
|
||||
setHexValue(curCol.slice(1, 7));
|
||||
|
|
@ -100,7 +100,7 @@ export function IconRoot(props: IconRootProps) {
|
|||
)}
|
||||
<button
|
||||
type="button"
|
||||
className={cn("grid place-items-center h-4 w-4 rounded-full border border-transparent", {
|
||||
className={cn("grid h-4 w-4 place-items-center rounded-full border border-transparent", {
|
||||
"border-strong-1": !showHexInput,
|
||||
})}
|
||||
onClick={() => {
|
||||
|
|
@ -109,18 +109,18 @@ export function IconRoot(props: IconRootProps) {
|
|||
}}
|
||||
>
|
||||
{showHexInput ? (
|
||||
<span className="conical-gradient h-4 w-4 rounded-full" />
|
||||
<span className="h-4 w-4 rounded-full conical-gradient" />
|
||||
) : (
|
||||
<span className="text-tertiary text-10 grid place-items-center">#</span>
|
||||
<span className="grid place-items-center text-10 text-tertiary">#</span>
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
<div className="flex items-center gap-2 w-full pl-4 pr-3 py-1 h-6">
|
||||
<div className="flex h-6 w-full items-center gap-2 py-1 pr-3 pl-4">
|
||||
<InfoIcon className="h-3 w-3" />
|
||||
<p className="text-11"> Colors will be adjusted to ensure sufficient contrast.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid grid-cols-8 gap-1 px-2.5 justify-items-center mt-2">
|
||||
<div className="mt-2 grid grid-cols-8 justify-items-center gap-1 px-2.5">
|
||||
{iconType === "material" ? (
|
||||
<MaterialIconList query={query} onChange={onChange} activeColor={activeColor} />
|
||||
) : (
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ export function LucideIconsList(props: LucideIconsListProps) {
|
|||
<button
|
||||
key={icon.name}
|
||||
type="button"
|
||||
className="h-9 w-9 select-none text-16 grid place-items-center rounded-sm hover:bg-layer-1"
|
||||
className="grid h-9 w-9 place-items-center rounded-sm text-16 select-none hover:bg-layer-1"
|
||||
onClick={() => {
|
||||
onChange({
|
||||
name: icon.name,
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ export function MaterialIconList(props: MaterialIconListProps) {
|
|||
<button
|
||||
key={icon.name}
|
||||
type="button"
|
||||
className="h-9 w-9 select-none text-16 grid place-items-center rounded-sm hover:bg-layer-1"
|
||||
className="grid h-9 w-9 place-items-center rounded-sm text-16 select-none hover:bg-layer-1"
|
||||
onClick={() => {
|
||||
onChange({
|
||||
name: icon.name,
|
||||
|
|
@ -46,7 +46,7 @@ export function MaterialIconList(props: MaterialIconListProps) {
|
|||
{icon.name}
|
||||
</span>
|
||||
) : (
|
||||
<span className="size-5 rounded-sm animate-pulse bg-layer-1" />
|
||||
<span className="size-5 animate-pulse rounded-sm bg-layer-1" />
|
||||
)}
|
||||
</button>
|
||||
))}
|
||||
|
|
|
|||
|
|
@ -43,13 +43,13 @@ export const Default: Story = {
|
|||
onChange={setSelectedEmoji}
|
||||
closeOnSelect
|
||||
label={
|
||||
<span className="flex items-center justify-center rounded-md px-2 size-8 text-18">
|
||||
<span className="flex size-8 items-center justify-center rounded-md px-2 text-18">
|
||||
{selectedEmoji ? stringToEmoji(selectedEmoji) : <SmilePlus className="h-6 text-primary" />}
|
||||
</span>
|
||||
}
|
||||
/>
|
||||
{selectedEmoji && (
|
||||
<div className="text-13 p-4 bg-layer-1 rounded-sm border border-subtle">Selected: {selectedEmoji}</div>
|
||||
<div className="rounded-sm border border-subtle bg-layer-1 p-4 text-13">Selected: {selectedEmoji}</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
|
@ -75,7 +75,7 @@ export const WithCustomLabel: Story = {
|
|||
onChange={setSelectedEmoji}
|
||||
closeOnSelect
|
||||
label={
|
||||
<button className="px-4 py-2 bg-layer-1 border border-subtle rounded-sm hover:bg-surface-2 flex items-center gap-2">
|
||||
<button className="flex items-center gap-2 rounded-sm border border-subtle bg-layer-1 px-4 py-2 hover:bg-surface-2">
|
||||
{selectedEmoji ? stringToEmoji(selectedEmoji) : <SmilePlus className="h-4 w-4" />}
|
||||
<span className="text-13">Add Reaction</span>
|
||||
</button>
|
||||
|
|
@ -140,7 +140,7 @@ export const InlineReactions: Story = {
|
|||
onChange={handleReactionAdd}
|
||||
closeOnSelect
|
||||
label={
|
||||
<button className="inline-flex items-center justify-center rounded-full border border-dashed border-strong bg-surface-1 text-placeholder transition-all duration-200 hover:border-accent-strong hover:text-accent-primary hover:bg-accent-primary/5 h-7 w-7">
|
||||
<button className="inline-flex h-7 w-7 items-center justify-center rounded-full border border-dashed border-strong bg-surface-1 text-placeholder transition-all duration-200 hover:border-accent-strong hover:bg-accent-primary/5 hover:text-accent-primary">
|
||||
<SmilePlus className="h-3.5 w-3.5" />
|
||||
</button>
|
||||
}
|
||||
|
|
@ -164,9 +164,9 @@ export const DifferentPlacements: Story = {
|
|||
const [isOpen4, setIsOpen4] = useState(false);
|
||||
|
||||
return (
|
||||
<div className="p-8 space-y-8">
|
||||
<div className="flex gap-4 items-center">
|
||||
<span className="text-13 w-32">Bottom Start:</span>
|
||||
<div className="space-y-8 p-8">
|
||||
<div className="flex items-center gap-4">
|
||||
<span className="w-32 text-13">Bottom Start:</span>
|
||||
<EmojiReactionPicker
|
||||
isOpen={isOpen1}
|
||||
handleToggle={setIsOpen1}
|
||||
|
|
@ -175,8 +175,8 @@ export const DifferentPlacements: Story = {
|
|||
label={<SmilePlus className="h-6 w-6" />}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex gap-4 items-center">
|
||||
<span className="text-13 w-32">Bottom End:</span>
|
||||
<div className="flex items-center gap-4">
|
||||
<span className="w-32 text-13">Bottom End:</span>
|
||||
<EmojiReactionPicker
|
||||
isOpen={isOpen2}
|
||||
handleToggle={setIsOpen2}
|
||||
|
|
@ -185,8 +185,8 @@ export const DifferentPlacements: Story = {
|
|||
label={<SmilePlus className="h-6 w-6" />}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex gap-4 items-center">
|
||||
<span className="text-13 w-32">Top Start:</span>
|
||||
<div className="flex items-center gap-4">
|
||||
<span className="w-32 text-13">Top Start:</span>
|
||||
<EmojiReactionPicker
|
||||
isOpen={isOpen3}
|
||||
handleToggle={setIsOpen3}
|
||||
|
|
@ -195,8 +195,8 @@ export const DifferentPlacements: Story = {
|
|||
label={<SmilePlus className="h-6 w-6" />}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex gap-4 items-center">
|
||||
<span className="text-13 w-32">Top End:</span>
|
||||
<div className="flex items-center gap-4">
|
||||
<span className="w-32 text-13">Top End:</span>
|
||||
<EmojiReactionPicker
|
||||
isOpen={isOpen4}
|
||||
handleToggle={setIsOpen4}
|
||||
|
|
@ -230,7 +230,7 @@ export const SearchDisabled: Story = {
|
|||
closeOnSelect
|
||||
searchDisabled
|
||||
label={
|
||||
<button className="px-4 py-2 bg-layer-1 border border-subtle rounded-sm hover:bg-surface-2">
|
||||
<button className="rounded-sm border border-subtle bg-layer-1 px-4 py-2 hover:bg-surface-2">
|
||||
No Search
|
||||
</button>
|
||||
}
|
||||
|
|
@ -261,7 +261,7 @@ export const CustomSearchPlaceholder: Story = {
|
|||
closeOnSelect
|
||||
searchPlaceholder="Find your emoji..."
|
||||
label={
|
||||
<button className="px-4 py-2 bg-layer-1 border border-subtle rounded-sm hover:bg-surface-2">
|
||||
<button className="rounded-sm border border-subtle bg-layer-1 px-4 py-2 hover:bg-surface-2">
|
||||
Custom Search
|
||||
</button>
|
||||
}
|
||||
|
|
@ -289,29 +289,29 @@ export const CloseOnSelectDisabled: Story = {
|
|||
|
||||
return (
|
||||
<div className="space-y-4 p-4">
|
||||
<div className="flex gap-2 items-center">
|
||||
<div className="flex items-center gap-2">
|
||||
<EmojiReactionPicker
|
||||
isOpen={isOpen}
|
||||
handleToggle={setIsOpen}
|
||||
onChange={handleChange}
|
||||
closeOnSelect={false}
|
||||
label={
|
||||
<button className="px-4 py-2 bg-layer-1 border border-subtle rounded-sm hover:bg-surface-2">
|
||||
<button className="rounded-sm border border-subtle bg-layer-1 px-4 py-2 hover:bg-surface-2">
|
||||
Select Multiple (Stays Open)
|
||||
</button>
|
||||
}
|
||||
/>
|
||||
<button
|
||||
className="px-3 py-1.5 text-13 bg-layer-1 rounded-sm hover:bg-surface-2"
|
||||
className="rounded-sm bg-layer-1 px-3 py-1.5 text-13 hover:bg-surface-2"
|
||||
onClick={() => setSelectedEmojis([])}
|
||||
>
|
||||
Clear
|
||||
</button>
|
||||
</div>
|
||||
{selectedEmojis.length > 0 && (
|
||||
<div className="text-13 p-4 bg-layer-1 rounded-sm border border-subtle">
|
||||
<div className="font-medium mb-2">Selected ({selectedEmojis.length}):</div>
|
||||
<div className="flex gap-2 flex-wrap">
|
||||
<div className="rounded-sm border border-subtle bg-layer-1 p-4 text-13">
|
||||
<div className="mb-2 font-medium">Selected ({selectedEmojis.length}):</div>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{selectedEmojis.map((emoji, idx) => (
|
||||
<span key={idx} className="text-18">
|
||||
{emoji}
|
||||
|
|
@ -364,14 +364,14 @@ export const InMessageContext: Story = {
|
|||
};
|
||||
|
||||
return (
|
||||
<div className="max-w-md border border-subtle rounded-lg p-4 space-y-3">
|
||||
<div className="max-w-md space-y-3 rounded-lg border border-subtle p-4">
|
||||
<div className="flex items-start gap-3">
|
||||
<div className="w-8 h-8 rounded-full bg-accent-primary flex items-center justify-center text-on-color text-13">
|
||||
<div className="flex h-8 w-8 items-center justify-center rounded-full bg-accent-primary text-13 text-on-color">
|
||||
AB
|
||||
</div>
|
||||
<div className="flex-1">
|
||||
<div className="font-medium text-13">Alice Brown</div>
|
||||
<div className="text-13 text-tertiary mt-1">
|
||||
<div className="text-13 font-medium">Alice Brown</div>
|
||||
<div className="mt-1 text-13 text-tertiary">
|
||||
Just finished the design for the new dashboard! Would love to hear your thoughts.
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -384,7 +384,7 @@ export const InMessageContext: Story = {
|
|||
onChange={handleReactionAdd}
|
||||
closeOnSelect
|
||||
label={
|
||||
<button className="inline-flex items-center justify-center rounded-full border border-dashed border-strong bg-surface-1 text-placeholder transition-all duration-200 hover:border-accent-strong hover:text-accent-primary hover:bg-accent-primary/5 h-7 w-7">
|
||||
<button className="inline-flex h-7 w-7 items-center justify-center rounded-full border border-dashed border-strong bg-surface-1 text-placeholder transition-all duration-200 hover:border-accent-strong hover:bg-accent-primary/5 hover:text-accent-primary">
|
||||
<SmilePlus className="h-3.5 w-3.5" />
|
||||
</button>
|
||||
}
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ export function EmojiReactionPicker(props: EmojiReactionPickerProps) {
|
|||
</Popover.Button>
|
||||
<Popover.Panel
|
||||
positionerClassName="z-50"
|
||||
className={cn("w-80 bg-surface-1 rounded-md border-[0.5px] border-strong overflow-hidden", dropdownClassName)}
|
||||
className={cn("w-80 overflow-hidden rounded-md border-[0.5px] border-strong bg-surface-1", dropdownClassName)}
|
||||
side={finalSide}
|
||||
align={finalAlign}
|
||||
sideOffset={8}
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ export const Interactive: Story = {
|
|||
};
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-4 items-center">
|
||||
<div className="flex flex-col items-center gap-4">
|
||||
<EmojiReaction
|
||||
emoji="👍"
|
||||
count={count}
|
||||
|
|
@ -213,14 +213,14 @@ export const InMessageContext: Story = {
|
|||
};
|
||||
|
||||
return (
|
||||
<div className="max-w-md border border-subtle rounded-lg p-4 space-y-3">
|
||||
<div className="max-w-md space-y-3 rounded-lg border border-subtle p-4">
|
||||
<div className="flex items-start gap-3">
|
||||
<div className="w-8 h-8 rounded-full bg-accent-primary flex items-center justify-center text-on-color text-13">
|
||||
<div className="flex h-8 w-8 items-center justify-center rounded-full bg-accent-primary text-13 text-on-color">
|
||||
AB
|
||||
</div>
|
||||
<div className="flex-1">
|
||||
<div className="font-medium text-13">Alice Brown</div>
|
||||
<div className="text-13 text-tertiary mt-1">
|
||||
<div className="text-13 font-medium">Alice Brown</div>
|
||||
<div className="mt-1 text-13 text-tertiary">
|
||||
Hey everyone! Just wanted to share some exciting news about our project launch next week!
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ const EmojiReaction = React.forwardRef(function EmojiReaction(
|
|||
|
||||
return (
|
||||
<div className="text-11">
|
||||
<div className="font-medium mb-1">{stringToEmoji(emoji)}</div>
|
||||
<div className="mb-1 font-medium">{stringToEmoji(emoji)}</div>
|
||||
<div>
|
||||
{displayUsers.join(", ")}
|
||||
{remainingCount > 0 && ` and ${remainingCount} more`}
|
||||
|
|
@ -82,15 +82,15 @@ const EmojiReaction = React.forwardRef(function EmojiReaction(
|
|||
ref={ref}
|
||||
onClick={handleClick}
|
||||
className={cn(
|
||||
"inline-flex items-center rounded-full border px-1.5 text-11 gap-0.5 transition-all duration-200",
|
||||
"inline-flex items-center gap-0.5 rounded-full border px-1.5 text-11 transition-all duration-200",
|
||||
reacted
|
||||
? "bg-accent-primary/10 border-accent-strong text-accent-primary"
|
||||
: "bg-surface-1 border-subtle text-tertiary hover:border-strong hover:bg-surface-2",
|
||||
? "border-accent-strong bg-accent-primary/10 text-accent-primary"
|
||||
: "border-subtle bg-surface-1 text-tertiary hover:border-strong hover:bg-surface-2",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
<span className="text-14 leading-unset">{emoji}</span>
|
||||
<span className="leading-unset text-14">{emoji}</span>
|
||||
{showCount && count > 0 && <AnimatedCounter count={count} size="sm" className="text-11 leading-normal" />}
|
||||
</button>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -29,83 +29,83 @@ import {
|
|||
|
||||
export const HorizontalStackAssetsMap = [
|
||||
{
|
||||
asset: <CustomerHorizontalStackIllustration className="w-20 h-20" />,
|
||||
asset: <CustomerHorizontalStackIllustration className="h-20 w-20" />,
|
||||
title: "Customer",
|
||||
},
|
||||
{
|
||||
asset: <EpicHorizontalStackIllustration className="w-20 h-20" />,
|
||||
asset: <EpicHorizontalStackIllustration className="h-20 w-20" />,
|
||||
title: "Epic",
|
||||
},
|
||||
{
|
||||
asset: <EstimateHorizontalStackIllustration className="w-20 h-20" />,
|
||||
asset: <EstimateHorizontalStackIllustration className="h-20 w-20" />,
|
||||
title: "Estimate",
|
||||
},
|
||||
{
|
||||
asset: <ExportHorizontalStackIllustration className="w-20 h-20" />,
|
||||
asset: <ExportHorizontalStackIllustration className="h-20 w-20" />,
|
||||
title: "Export",
|
||||
},
|
||||
{
|
||||
asset: <IntakeHorizontalStackIllustration className="w-20 h-20" />,
|
||||
asset: <IntakeHorizontalStackIllustration className="h-20 w-20" />,
|
||||
title: "Intake",
|
||||
},
|
||||
{
|
||||
asset: <LabelHorizontalStackIllustration className="w-20 h-20" />,
|
||||
asset: <LabelHorizontalStackIllustration className="h-20 w-20" />,
|
||||
title: "Label",
|
||||
},
|
||||
{
|
||||
asset: <LinkHorizontalStackIllustration className="w-20 h-20" />,
|
||||
asset: <LinkHorizontalStackIllustration className="h-20 w-20" />,
|
||||
title: "Link",
|
||||
},
|
||||
{
|
||||
asset: <MembersHorizontalStackIllustration className="w-20 h-20" />,
|
||||
asset: <MembersHorizontalStackIllustration className="h-20 w-20" />,
|
||||
title: "Members",
|
||||
},
|
||||
{
|
||||
asset: <NoteHorizontalStackIllustration className="w-20 h-20" />,
|
||||
asset: <NoteHorizontalStackIllustration className="h-20 w-20" />,
|
||||
title: "Note",
|
||||
},
|
||||
{
|
||||
asset: <PriorityHorizontalStackIllustration className="w-20 h-20" />,
|
||||
asset: <PriorityHorizontalStackIllustration className="h-20 w-20" />,
|
||||
title: "Priority",
|
||||
},
|
||||
{
|
||||
asset: <ProjectHorizontalStackIllustration className="w-20 h-20" />,
|
||||
asset: <ProjectHorizontalStackIllustration className="h-20 w-20" />,
|
||||
title: "Project",
|
||||
},
|
||||
{
|
||||
asset: <SettingsHorizontalStackIllustration className="w-20 h-20" />,
|
||||
asset: <SettingsHorizontalStackIllustration className="h-20 w-20" />,
|
||||
title: "Settings",
|
||||
},
|
||||
{
|
||||
asset: <StateHorizontalStackIllustration className="w-20 h-20" />,
|
||||
asset: <StateHorizontalStackIllustration className="h-20 w-20" />,
|
||||
title: "State",
|
||||
},
|
||||
{
|
||||
asset: <TemplateHorizontalStackIllustration className="w-20 h-20" />,
|
||||
asset: <TemplateHorizontalStackIllustration className="h-20 w-20" />,
|
||||
title: "Template",
|
||||
},
|
||||
{
|
||||
asset: <TokenHorizontalStackIllustration className="w-20 h-20" />,
|
||||
asset: <TokenHorizontalStackIllustration className="h-20 w-20" />,
|
||||
title: "Token",
|
||||
},
|
||||
{
|
||||
asset: <UnknownHorizontalStackIllustration className="w-20 h-20" />,
|
||||
asset: <UnknownHorizontalStackIllustration className="h-20 w-20" />,
|
||||
title: "Unknown",
|
||||
},
|
||||
{
|
||||
asset: <UpdateHorizontalStackIllustration className="w-20 h-20" />,
|
||||
asset: <UpdateHorizontalStackIllustration className="h-20 w-20" />,
|
||||
title: "Update",
|
||||
},
|
||||
{
|
||||
asset: <WebhookHorizontalStackIllustration className="w-20 h-20" />,
|
||||
asset: <WebhookHorizontalStackIllustration className="h-20 w-20" />,
|
||||
title: "Webhook",
|
||||
},
|
||||
{
|
||||
asset: <WorkItemHorizontalStackIllustration className="w-20 h-20" />,
|
||||
asset: <WorkItemHorizontalStackIllustration className="h-20 w-20" />,
|
||||
title: "WorkItem",
|
||||
},
|
||||
{
|
||||
asset: <WorklogHorizontalStackIllustration className="w-20 h-20" />,
|
||||
asset: <WorklogHorizontalStackIllustration className="h-20 w-20" />,
|
||||
title: "Worklog",
|
||||
},
|
||||
];
|
||||
|
|
|
|||
|
|
@ -8,11 +8,11 @@ import { InboxIllustration, SearchIllustration } from "./";
|
|||
|
||||
export const IllustrationMap = [
|
||||
{
|
||||
asset: <InboxIllustration className="w-20 h-20" />,
|
||||
asset: <InboxIllustration className="h-20 w-20" />,
|
||||
title: "Inbox",
|
||||
},
|
||||
{
|
||||
asset: <SearchIllustration className="w-20 h-20" />,
|
||||
asset: <SearchIllustration className="h-20 w-20" />,
|
||||
title: "Search",
|
||||
},
|
||||
];
|
||||
|
|
|
|||
|
|
@ -32,14 +32,14 @@ export function EmptyStateCompact({
|
|||
return (
|
||||
<div className={cn("flex size-full items-center justify-center", rootAlignClasses, rootClassName)}>
|
||||
<div
|
||||
className={cn("flex max-w-[25rem] size-full flex-col justify-center gap-3", containerAlignClasses, className)}
|
||||
className={cn("flex size-full max-w-[25rem] flex-col justify-center gap-3", containerAlignClasses, className)}
|
||||
>
|
||||
{resolvedAsset && <div className="flex max-w-40 items-center">{resolvedAsset}</div>}
|
||||
|
||||
<div className="flex flex-col gap-4">
|
||||
{title && description ? (
|
||||
<div className="flex flex-col gap-2">
|
||||
{title && <h3 className="text-16 font-semibold leading-7 text-primary">{title}</h3>}
|
||||
{title && <h3 className="text-16 leading-7 font-semibold text-primary">{title}</h3>}
|
||||
{description && <p className="text-13 leading-5 text-tertiary">{description}</p>}
|
||||
</div>
|
||||
) : (
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ export function EmptyStateDetailed({
|
|||
<div className={cn("flex size-full items-center justify-center", rootClassName)}>
|
||||
<div
|
||||
className={cn(
|
||||
"flex max-w-[25rem] size-full flex-col justify-center gap-6 text-left",
|
||||
"flex size-full max-w-[25rem] flex-col justify-center gap-6 text-left",
|
||||
{
|
||||
"items-center text-center": align === "center",
|
||||
},
|
||||
|
|
@ -46,7 +46,7 @@ export function EmptyStateDetailed({
|
|||
>
|
||||
{(title || description) && (
|
||||
<div className="flex flex-col gap-2">
|
||||
{title && <h3 className="text-16 font-semibold leading-7 text-primary">{title}</h3>}
|
||||
{title && <h3 className="text-16 leading-7 font-semibold text-primary">{title}</h3>}
|
||||
{description && <p className="text-13 leading-5 text-tertiary">{description}</p>}
|
||||
</div>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -9,22 +9,22 @@ import { cva } from "class-variance-authority";
|
|||
import type React from "react";
|
||||
|
||||
export const iconButtonVariants = cva(
|
||||
"inline-flex items-center justify-center gap-1 aspect-square whitespace-nowrap transition-colors focus-visible:outline-none disabled:pointer-events-none",
|
||||
"inline-flex aspect-square items-center justify-center gap-1 whitespace-nowrap transition-colors focus-visible:outline-none disabled:pointer-events-none",
|
||||
{
|
||||
variants: {
|
||||
variant: {
|
||||
primary:
|
||||
"bg-accent-primary hover:bg-accent-primary-hover active:bg-accent-primary-active focus:bg-accent-primary-active disabled:bg-layer-disabled text-on-color disabled:text-on-color-disabled",
|
||||
"bg-accent-primary text-on-color hover:bg-accent-primary-hover focus:bg-accent-primary-active active:bg-accent-primary-active disabled:bg-layer-disabled disabled:text-on-color-disabled",
|
||||
"error-fill":
|
||||
"bg-danger-primary hover:bg-danger-primary-hover active:bg-danger-primary-active focus:bg-danger-primary-active disabled:bg-layer-disabled text-on-color disabled:text-disabled",
|
||||
"bg-danger-primary text-on-color hover:bg-danger-primary-hover focus:bg-danger-primary-active active:bg-danger-primary-active disabled:bg-layer-disabled disabled:text-disabled",
|
||||
"error-outline":
|
||||
"bg-layer-2 hover:bg-danger-subtle active:bg-danger-subtle-hover focus:bg-danger-subtle-hover disabled:bg-layer-2 text-danger-primary disabled:text-disabled border border-danger-strong disabled:border-subtle-1",
|
||||
"border border-danger-strong bg-layer-2 text-danger-primary hover:bg-danger-subtle focus:bg-danger-subtle-hover active:bg-danger-subtle-hover disabled:border-subtle-1 disabled:bg-layer-2 disabled:text-disabled",
|
||||
secondary:
|
||||
"bg-layer-2 hover:bg-layer-2-hover active:bg-layer-2-active focus:bg-layer-2-active disabled:bg-layer-transparent text-secondary disabled:text-disabled border border-strong disabled:border-subtle-1 shadow-raised-100",
|
||||
"border border-strong bg-layer-2 text-secondary shadow-raised-100 hover:bg-layer-2-hover focus:bg-layer-2-active active:bg-layer-2-active disabled:border-subtle-1 disabled:bg-layer-transparent disabled:text-disabled",
|
||||
tertiary:
|
||||
"bg-layer-3 hover:bg-layer-3-hover active:bg-layer-3-active focus:bg-layer-3-active disabled:bg-layer-transparent text-secondary disabled:text-disabled",
|
||||
"bg-layer-3 text-secondary hover:bg-layer-3-hover focus:bg-layer-3-active active:bg-layer-3-active disabled:bg-layer-transparent disabled:text-disabled",
|
||||
ghost:
|
||||
"bg-layer-transparent hover:bg-layer-transparent-hover active:bg-layer-transparent-active focus:bg-layer-transparent-active disabled:bg-layer-transparent text-secondary disabled:text-disabled",
|
||||
"bg-layer-transparent text-secondary hover:bg-layer-transparent-hover focus:bg-layer-transparent-active active:bg-layer-transparent-active disabled:bg-layer-transparent disabled:text-disabled",
|
||||
},
|
||||
size: {
|
||||
sm: "size-5 rounded-sm",
|
||||
|
|
|
|||
|
|
@ -41,11 +41,11 @@ export const AllIcons: Story = {
|
|||
<div className="space-y-12">
|
||||
<div className="space-y-4">
|
||||
<h3 className="text-16 font-semibold text-primary">Sub-Brand Icons</h3>
|
||||
<div className="grid grid-cols-12 gap-6 w-full">
|
||||
<div className="grid w-full grid-cols-12 gap-6">
|
||||
{SubBrandIconsMap.map((item) => (
|
||||
<div key={item.title} className="flex flex-col items-center justify-center gap-3 p-4 col-span-2">
|
||||
<div key={item.title} className="col-span-2 flex flex-col items-center justify-center gap-3 p-4">
|
||||
<div className="text-secondary">{item.icon}</div>
|
||||
<p className="text-11 text-tertiary text-center">{item.title}</p>
|
||||
<p className="text-center text-11 text-tertiary">{item.title}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
|
@ -53,11 +53,11 @@ export const AllIcons: Story = {
|
|||
|
||||
<div className="space-y-4">
|
||||
<h3 className="text-16 font-semibold text-primary">Workspace Icons</h3>
|
||||
<div className="grid grid-cols-12 gap-6 w-full">
|
||||
<div className="grid w-full grid-cols-12 gap-6">
|
||||
{WorkspaceIconsMap.map((item) => (
|
||||
<div key={item.title} className="flex flex-col items-center justify-center gap-3 p-4 col-span-2">
|
||||
<div key={item.title} className="col-span-2 flex flex-col items-center justify-center gap-3 p-4">
|
||||
<div className="text-secondary">{item.icon}</div>
|
||||
<p className="text-11 text-tertiary text-center">{item.title}</p>
|
||||
<p className="text-center text-11 text-tertiary">{item.title}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
|
@ -65,11 +65,11 @@ export const AllIcons: Story = {
|
|||
|
||||
<div className="space-y-4">
|
||||
<h3 className="text-16 font-semibold text-primary">Project Icons</h3>
|
||||
<div className="grid grid-cols-12 gap-6 w-full">
|
||||
<div className="grid w-full grid-cols-12 gap-6">
|
||||
{ProjectIconsMap.map((item) => (
|
||||
<div key={item.title} className="flex flex-col items-center justify-center gap-3 p-4 col-span-2">
|
||||
<div key={item.title} className="col-span-2 flex flex-col items-center justify-center gap-3 p-4">
|
||||
<div className="text-secondary">{item.icon}</div>
|
||||
<p className="text-11 text-tertiary text-center">{item.title}</p>
|
||||
<p className="text-center text-11 text-tertiary">{item.title}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
|
@ -77,11 +77,11 @@ export const AllIcons: Story = {
|
|||
|
||||
<div className="space-y-4">
|
||||
<h3 className="text-16 font-semibold text-primary">Layout Icons</h3>
|
||||
<div className="grid grid-cols-12 gap-6 w-full">
|
||||
<div className="grid w-full grid-cols-12 gap-6">
|
||||
{LayoutIconsMap.map((item) => (
|
||||
<div key={item.title} className="flex flex-col items-center justify-center gap-3 p-4 col-span-2">
|
||||
<div key={item.title} className="col-span-2 flex flex-col items-center justify-center gap-3 p-4">
|
||||
<div className="text-secondary">{item.icon}</div>
|
||||
<p className="text-11 text-tertiary text-center">{item.title}</p>
|
||||
<p className="text-center text-11 text-tertiary">{item.title}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
|
@ -89,11 +89,11 @@ export const AllIcons: Story = {
|
|||
|
||||
<div className="space-y-4">
|
||||
<h3 className="text-16 font-semibold text-primary">Property Icons</h3>
|
||||
<div className="grid grid-cols-12 gap-6 w-full">
|
||||
<div className="grid w-full grid-cols-12 gap-6">
|
||||
{PropertyIconsMap.map((item) => (
|
||||
<div key={item.title} className="flex flex-col items-center justify-center gap-3 p-4 col-span-2">
|
||||
<div key={item.title} className="col-span-2 flex flex-col items-center justify-center gap-3 p-4">
|
||||
<div className="text-secondary">{item.icon}</div>
|
||||
<p className="text-11 text-tertiary text-center">{item.title}</p>
|
||||
<p className="text-center text-11 text-tertiary">{item.title}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
|
@ -101,11 +101,11 @@ export const AllIcons: Story = {
|
|||
|
||||
<div className="space-y-4">
|
||||
<h3 className="text-16 font-semibold text-primary">Actions Icons</h3>
|
||||
<div className="grid grid-cols-12 gap-6 w-full">
|
||||
<div className="grid w-full grid-cols-12 gap-6">
|
||||
{ActionsIconsMap.map((item) => (
|
||||
<div key={item.title} className="flex flex-col items-center justify-center gap-3 p-4 col-span-2">
|
||||
<div key={item.title} className="col-span-2 flex flex-col items-center justify-center gap-3 p-4">
|
||||
<div className="text-secondary">{item.icon}</div>
|
||||
<p className="text-11 text-tertiary text-center">{item.title}</p>
|
||||
<p className="text-center text-11 text-tertiary">{item.title}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
|
@ -113,21 +113,21 @@ export const AllIcons: Story = {
|
|||
|
||||
<div className="space-y-4">
|
||||
<h3 className="text-16 font-semibold text-primary">Arrows Icons</h3>
|
||||
<div className="grid grid-cols-12 gap-6 w-full">
|
||||
<div className="grid w-full grid-cols-12 gap-6">
|
||||
{ArrowsIconsMap.map((item) => (
|
||||
<div key={item.title} className="flex flex-col items-center justify-center gap-3 p-4 col-span-2">
|
||||
<div key={item.title} className="col-span-2 flex flex-col items-center justify-center gap-3 p-4">
|
||||
<div className="text-secondary">{item.icon}</div>
|
||||
<p className="text-11 text-tertiary text-center">{item.title}</p>
|
||||
<p className="text-center text-11 text-tertiary">{item.title}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="space-y-4">
|
||||
<h3 className="text-lg font-semibold text-custom-text-100">Misc Icons</h3>
|
||||
<div className="grid grid-cols-12 gap-6 w-full">
|
||||
<h3 className="text-lg text-custom-text-100 font-semibold">Misc Icons</h3>
|
||||
<div className="grid w-full grid-cols-12 gap-6">
|
||||
{MiscIconsMap.map((item) => (
|
||||
<div key={item.title} className="flex flex-col items-center justify-center gap-3 p-4 col-span-2">
|
||||
<div key={item.title} className="col-span-2 flex flex-col items-center justify-center gap-3 p-4">
|
||||
<div className="text-custom-text-200">{item.icon}</div>
|
||||
<p className="text-xs text-custom-text-300 text-center">{item.title}</p>
|
||||
</div>
|
||||
|
|
@ -144,25 +144,25 @@ export const RegistryUsage: Story = {
|
|||
<div className="space-y-4">
|
||||
<h3 className="text-16 font-semibold text-primary">Registry-Based Usage</h3>
|
||||
<p className="text-13 text-tertiary">
|
||||
Use the <code className="px-1 py-0.5 bg-layer-1 rounded-sm">Icon</code> component with{" "}
|
||||
<code className="px-1 py-0.5 bg-layer-1 rounded-sm">name</code> prop for dynamic icon selection.
|
||||
Use the <code className="rounded-sm bg-layer-1 px-1 py-0.5">Icon</code> component with{" "}
|
||||
<code className="rounded-sm bg-layer-1 px-1 py-0.5">name</code> prop for dynamic icon selection.
|
||||
</p>
|
||||
<div className="grid grid-cols-12 gap-6 w-full">
|
||||
<div className="flex flex-col items-center justify-center gap-3 p-4 col-span-2">
|
||||
<div className="grid w-full grid-cols-12 gap-6">
|
||||
<div className="col-span-2 flex flex-col items-center justify-center gap-3 p-4">
|
||||
<Icon name="workspace.home" className="text-secondary" />
|
||||
<p className="text-11 text-tertiary text-center">workspace.home</p>
|
||||
<p className="text-center text-11 text-tertiary">workspace.home</p>
|
||||
</div>
|
||||
<div className="flex flex-col items-center justify-center gap-3 p-4 col-span-2">
|
||||
<div className="col-span-2 flex flex-col items-center justify-center gap-3 p-4">
|
||||
<Icon name="project.cycle" className="text-secondary" />
|
||||
<p className="text-11 text-tertiary text-center">project.cycle</p>
|
||||
<p className="text-center text-11 text-tertiary">project.cycle</p>
|
||||
</div>
|
||||
<div className="flex flex-col items-center justify-center gap-3 p-4 col-span-2">
|
||||
<div className="col-span-2 flex flex-col items-center justify-center gap-3 p-4">
|
||||
<Icon name="layout.board" className="text-secondary" />
|
||||
<p className="text-11 text-tertiary text-center">layout.board</p>
|
||||
<p className="text-center text-11 text-tertiary">layout.board</p>
|
||||
</div>
|
||||
<div className="flex flex-col items-center justify-center gap-3 p-4 col-span-2">
|
||||
<div className="col-span-2 flex flex-col items-center justify-center gap-3 p-4">
|
||||
<Icon name="property.priority" className="text-secondary" />
|
||||
<p className="text-11 text-tertiary text-center">property.priority</p>
|
||||
<p className="text-center text-11 text-tertiary">property.priority</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -172,18 +172,18 @@ export const RegistryUsage: Story = {
|
|||
<p className="text-13 text-tertiary">
|
||||
Import icon components directly for better tree-shaking and type safety.
|
||||
</p>
|
||||
<div className="grid grid-cols-12 gap-6 w-full">
|
||||
<div className="flex flex-col items-center justify-center gap-3 p-4 col-span-2">
|
||||
<div className="grid w-full grid-cols-12 gap-6">
|
||||
<div className="col-span-2 flex flex-col items-center justify-center gap-3 p-4">
|
||||
<HomeIcon className="text-secondary" />
|
||||
<p className="text-11 text-tertiary text-center">HomeIcon</p>
|
||||
<p className="text-center text-11 text-tertiary">HomeIcon</p>
|
||||
</div>
|
||||
<div className="flex flex-col items-center justify-center gap-3 p-4 col-span-2">
|
||||
<div className="col-span-2 flex flex-col items-center justify-center gap-3 p-4">
|
||||
<CycleIcon className="text-secondary" />
|
||||
<p className="text-11 text-tertiary text-center">CycleIcon</p>
|
||||
<p className="text-center text-11 text-tertiary">CycleIcon</p>
|
||||
</div>
|
||||
<div className="flex flex-col items-center justify-center gap-3 p-4 col-span-2">
|
||||
<div className="col-span-2 flex flex-col items-center justify-center gap-3 p-4">
|
||||
<ProjectIcon className="text-secondary" />
|
||||
<p className="text-11 text-tertiary text-center">ProjectIcon</p>
|
||||
<p className="text-center text-11 text-tertiary">ProjectIcon</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ export function PriorityIcon(props: IPriorityIcon) {
|
|||
{withContainer ? (
|
||||
<div
|
||||
className={cn(
|
||||
"flex items-center justify-center border rounded-sm p-0.5 flex-shrink-0",
|
||||
"flex flex-shrink-0 items-center justify-center rounded-sm border p-0.5",
|
||||
priorityClasses[priority ?? "none"],
|
||||
containerClassName
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -52,13 +52,13 @@ const createShowcaseStory = (
|
|||
sections: Array<{ label: string; props: Partial<React.ComponentProps<typeof Input>> }>
|
||||
): Story => ({
|
||||
render: () => (
|
||||
<div className="space-y-4 w-[400px]">
|
||||
<div className="w-[400px] space-y-4">
|
||||
<div className="space-y-2">
|
||||
<h3 className="text-13 font-medium">{title}</h3>
|
||||
<div className="space-y-2">
|
||||
{sections.map(({ label, props }, index) => (
|
||||
<div key={index} className="w-full">
|
||||
<label className="text-11 text-gray-500">{label}</label>
|
||||
<label className="text-gray-500 text-11">{label}</label>
|
||||
<Input className="w-full" {...props} />
|
||||
</div>
|
||||
))}
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ const Input = React.forwardRef(function Input(props: InputProps, ref: React.Forw
|
|||
type={type}
|
||||
name={name}
|
||||
className={cn(
|
||||
"block rounded-md bg-layer-2 text-13 placeholder-tertiary border-subtle-1 focus:outline-none",
|
||||
"placeholder-tertiary block rounded-md border-subtle-1 bg-layer-2 text-13 focus:outline-none",
|
||||
{
|
||||
"rounded-md border-[0.5px]": mode === "primary",
|
||||
"rounded-sm border-none bg-transparent ring-0 transition-all focus:ring-1 focus:ring-accent-strong":
|
||||
|
|
|
|||
|
|
@ -148,7 +148,7 @@ export const CustomButton: Story = {
|
|||
return (
|
||||
<Menu
|
||||
customButton={
|
||||
<button className="rounded-sm bg-blue-500 px-4 py-2 text-on-color hover:bg-blue-600">Custom Button</button>
|
||||
<button className="bg-blue-500 hover:bg-blue-600 rounded-sm px-4 py-2 text-on-color">Custom Button</button>
|
||||
}
|
||||
>
|
||||
<Menu.MenuItem onClick={() => alert("Option 1")}>Option 1</Menu.MenuItem>
|
||||
|
|
@ -215,7 +215,7 @@ export const ComplexMenu: Story = {
|
|||
<div className="flex items-center gap-2">
|
||||
<Bell className="h-4 w-4" />
|
||||
<span>Notifications</span>
|
||||
<span className="ml-auto rounded-sm bg-red-500 px-2 py-0.5 text-11 text-on-color">3</span>
|
||||
<span className="bg-red-500 ml-auto rounded-sm px-2 py-0.5 text-11 text-on-color">3</span>
|
||||
</div>
|
||||
</Menu.MenuItem>
|
||||
<Menu.MenuItem onClick={() => alert("Help")}>
|
||||
|
|
@ -232,7 +232,7 @@ export const ComplexMenu: Story = {
|
|||
<Menu.MenuItem onClick={() => alert("Privacy Settings")}>Privacy</Menu.MenuItem>
|
||||
<Menu.MenuItem onClick={() => alert("Security Settings")}>Security</Menu.MenuItem>
|
||||
</Menu.SubMenu>
|
||||
<div className="my-1 border-t border-gray-200" />
|
||||
<div className="border-gray-200 my-1 border-t" />
|
||||
<Menu.MenuItem onClick={() => alert("Logout")}>
|
||||
<div className="flex items-center gap-2 text-danger-primary">
|
||||
<LogOut className="h-4 w-4" />
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ function MenuItem(props: TMenuItemProps) {
|
|||
<BaseMenu.Item
|
||||
disabled={disabled}
|
||||
className={cn(
|
||||
"w-full select-none truncate rounded-sm px-1 py-1.5 text-left text-secondary hover:bg-layer-1 cursor-pointer outline-none",
|
||||
"w-full cursor-pointer truncate rounded-sm px-1 py-1.5 text-left text-secondary outline-none select-none hover:bg-layer-1",
|
||||
{
|
||||
"text-placeholder": disabled,
|
||||
},
|
||||
|
|
@ -159,9 +159,9 @@ function Menu(props: TMenuProps) {
|
|||
) : (
|
||||
<BaseMenu.Trigger
|
||||
type="button"
|
||||
className={`flex items-center justify-between gap-1 whitespace-nowrap rounded-md px-2.5 py-1 text-11 duration-300 outline-none ${
|
||||
className={`flex items-center justify-between gap-1 rounded-md px-2.5 py-1 text-11 whitespace-nowrap duration-300 outline-none ${
|
||||
isOpen ? "bg-surface-2 text-primary" : "text-secondary"
|
||||
} ${noBorder ? "" : "border border-strong shadow-sm focus:outline-none"} ${
|
||||
} ${noBorder ? "" : "shadow-sm border border-strong focus:outline-none"} ${
|
||||
disabled ? "cursor-not-allowed text-secondary" : "cursor-pointer hover:bg-layer-1"
|
||||
} ${buttonClassName}`}
|
||||
onClick={handleMenuButtonClick}
|
||||
|
|
@ -186,7 +186,7 @@ function Menu(props: TMenuProps) {
|
|||
<BaseMenu.Popup
|
||||
tabIndex={tabIndex}
|
||||
className={cn(
|
||||
"my-1 overflow-y-scroll rounded-md border-[0.5px] border-strong bg-surface-1 px-2 py-2.5 text-11 shadow-raised-200 focus:outline-none min-w-[12rem] whitespace-nowrap",
|
||||
"my-1 min-w-[12rem] overflow-y-scroll rounded-md border-[0.5px] border-strong bg-surface-1 px-2 py-2.5 text-11 whitespace-nowrap shadow-raised-200 focus:outline-none",
|
||||
{
|
||||
"max-h-60": maxHeight === "lg",
|
||||
"max-h-48": maxHeight === "md",
|
||||
|
|
|
|||
|
|
@ -33,12 +33,12 @@ const meta: Meta<typeof Popover> = {
|
|||
|
||||
return (
|
||||
<Popover {...args} open={open} onOpenChange={setOpen}>
|
||||
<Popover.Button className="rounded-sm bg-blue-500 px-4 py-2 text-on-color hover:bg-blue-600">
|
||||
<Popover.Button className="bg-blue-500 hover:bg-blue-600 rounded-sm px-4 py-2 text-on-color">
|
||||
Open Popover
|
||||
</Popover.Button>
|
||||
<Popover.Panel className="w-64 rounded-lg border border-gray-200 bg-white p-4 shadow-lg">
|
||||
<Popover.Panel className="border-gray-200 shadow-lg w-64 rounded-lg border bg-white p-4">
|
||||
<h3 className="text-13 font-semibold">Popover Title</h3>
|
||||
<p className="mt-2 text-13 text-gray-600">This is the popover content. You can put any content here.</p>
|
||||
<p className="text-gray-600 mt-2 text-13">This is the popover content. You can put any content here.</p>
|
||||
</Popover.Panel>
|
||||
</Popover>
|
||||
);
|
||||
|
|
@ -61,25 +61,25 @@ export const Controlled: Story = {
|
|||
return (
|
||||
<div className="space-y-4">
|
||||
<div className="flex gap-2">
|
||||
<button onClick={() => setOpen(true)} className="rounded-sm bg-blue-500 px-3 py-1.5 text-13 text-on-color">
|
||||
<button onClick={() => setOpen(true)} className="bg-blue-500 rounded-sm px-3 py-1.5 text-13 text-on-color">
|
||||
Open
|
||||
</button>
|
||||
<button onClick={() => setOpen(false)} className="rounded-sm bg-gray-500 px-3 py-1.5 text-13 text-on-color">
|
||||
<button onClick={() => setOpen(false)} className="bg-gray-500 rounded-sm px-3 py-1.5 text-13 text-on-color">
|
||||
Close
|
||||
</button>
|
||||
</div>
|
||||
<Popover open={open} onOpenChange={setOpen}>
|
||||
<Popover.Button className="rounded-sm bg-blue-500 px-4 py-2 text-on-color hover:bg-blue-600">
|
||||
<Popover.Button className="bg-blue-500 hover:bg-blue-600 rounded-sm px-4 py-2 text-on-color">
|
||||
Controlled Popover
|
||||
</Popover.Button>
|
||||
<Popover.Panel className="w-64 rounded-lg border border-gray-200 bg-white p-4 shadow-lg">
|
||||
<Popover.Panel className="border-gray-200 shadow-lg w-64 rounded-lg border bg-white p-4">
|
||||
<div className="flex items-start justify-between">
|
||||
<h3 className="text-13 font-semibold">Controlled State</h3>
|
||||
<button onClick={() => setOpen(false)} className="rounded-full p-1 hover:bg-gray-100">
|
||||
<button onClick={() => setOpen(false)} className="hover:bg-gray-100 rounded-full p-1">
|
||||
<CloseIcon className="h-4 w-4" />
|
||||
</button>
|
||||
</div>
|
||||
<p className="mt-2 text-13 text-gray-600">Current state: {open ? "Open" : "Closed"}</p>
|
||||
<p className="text-gray-600 mt-2 text-13">Current state: {open ? "Open" : "Closed"}</p>
|
||||
</Popover.Panel>
|
||||
</Popover>
|
||||
</div>
|
||||
|
|
@ -92,12 +92,12 @@ export const SideTop: Story = {
|
|||
const [open, setOpen] = useState(args.open);
|
||||
return (
|
||||
<Popover {...args} open={open} onOpenChange={setOpen}>
|
||||
<Popover.Button className="rounded-sm bg-blue-500 px-4 py-2 text-on-color hover:bg-blue-600">
|
||||
<Popover.Button className="bg-blue-500 hover:bg-blue-600 rounded-sm px-4 py-2 text-on-color">
|
||||
Open Above
|
||||
</Popover.Button>
|
||||
<Popover.Panel side="top" className="w-64 rounded-lg border border-gray-200 bg-white p-4 shadow-lg">
|
||||
<Popover.Panel side="top" className="border-gray-200 shadow-lg w-64 rounded-lg border bg-white p-4">
|
||||
<h3 className="text-13 font-semibold">Top Positioned</h3>
|
||||
<p className="mt-2 text-13 text-gray-600">This popover appears above the button.</p>
|
||||
<p className="text-gray-600 mt-2 text-13">This popover appears above the button.</p>
|
||||
</Popover.Panel>
|
||||
</Popover>
|
||||
);
|
||||
|
|
@ -109,12 +109,12 @@ export const SideBottom: Story = {
|
|||
const [open, setOpen] = useState(args.open);
|
||||
return (
|
||||
<Popover {...args} open={open} onOpenChange={setOpen}>
|
||||
<Popover.Button className="rounded-sm bg-blue-500 px-4 py-2 text-on-color hover:bg-blue-600">
|
||||
<Popover.Button className="bg-blue-500 hover:bg-blue-600 rounded-sm px-4 py-2 text-on-color">
|
||||
Open Below
|
||||
</Popover.Button>
|
||||
<Popover.Panel side="bottom" className="w-64 rounded-lg border border-gray-200 bg-white p-4 shadow-lg">
|
||||
<Popover.Panel side="bottom" className="border-gray-200 shadow-lg w-64 rounded-lg border bg-white p-4">
|
||||
<h3 className="text-13 font-semibold">Bottom Positioned</h3>
|
||||
<p className="mt-2 text-13 text-gray-600">This popover appears below the button.</p>
|
||||
<p className="text-gray-600 mt-2 text-13">This popover appears below the button.</p>
|
||||
</Popover.Panel>
|
||||
</Popover>
|
||||
);
|
||||
|
|
@ -126,12 +126,12 @@ export const SideLeft: Story = {
|
|||
const [open, setOpen] = useState(args.open);
|
||||
return (
|
||||
<Popover {...args} open={open} onOpenChange={setOpen}>
|
||||
<Popover.Button className="rounded-sm bg-blue-500 px-4 py-2 text-on-color hover:bg-blue-600">
|
||||
<Popover.Button className="bg-blue-500 hover:bg-blue-600 rounded-sm px-4 py-2 text-on-color">
|
||||
Open Left
|
||||
</Popover.Button>
|
||||
<Popover.Panel side="left" className="w-64 rounded-lg border border-gray-200 bg-white p-4 shadow-lg">
|
||||
<Popover.Panel side="left" className="border-gray-200 shadow-lg w-64 rounded-lg border bg-white p-4">
|
||||
<h3 className="text-13 font-semibold">Left Positioned</h3>
|
||||
<p className="mt-2 text-13 text-gray-600">This popover appears to the left of the button.</p>
|
||||
<p className="text-gray-600 mt-2 text-13">This popover appears to the left of the button.</p>
|
||||
</Popover.Panel>
|
||||
</Popover>
|
||||
);
|
||||
|
|
@ -143,12 +143,12 @@ export const SideRight: Story = {
|
|||
const [open, setOpen] = useState(args.open);
|
||||
return (
|
||||
<Popover {...args} open={open} onOpenChange={setOpen}>
|
||||
<Popover.Button className="rounded-sm bg-blue-500 px-4 py-2 text-on-color hover:bg-blue-600">
|
||||
<Popover.Button className="bg-blue-500 hover:bg-blue-600 rounded-sm px-4 py-2 text-on-color">
|
||||
Open Right
|
||||
</Popover.Button>
|
||||
<Popover.Panel side="right" className="w-64 rounded-lg border border-gray-200 bg-white p-4 shadow-lg">
|
||||
<Popover.Panel side="right" className="border-gray-200 shadow-lg w-64 rounded-lg border bg-white p-4">
|
||||
<h3 className="text-13 font-semibold">Right Positioned</h3>
|
||||
<p className="mt-2 text-13 text-gray-600">This popover appears to the right of the button.</p>
|
||||
<p className="text-gray-600 mt-2 text-13">This popover appears to the right of the button.</p>
|
||||
</Popover.Panel>
|
||||
</Popover>
|
||||
);
|
||||
|
|
@ -160,12 +160,12 @@ export const AlignStart: Story = {
|
|||
const [open, setOpen] = useState(args.open);
|
||||
return (
|
||||
<Popover {...args} open={open} onOpenChange={setOpen}>
|
||||
<Popover.Button className="rounded-sm bg-blue-500 px-4 py-2 text-on-color hover:bg-blue-600">
|
||||
<Popover.Button className="bg-blue-500 hover:bg-blue-600 rounded-sm px-4 py-2 text-on-color">
|
||||
Align Start
|
||||
</Popover.Button>
|
||||
<Popover.Panel align="start" className="w-64 rounded-lg border border-gray-200 bg-white p-4 shadow-lg">
|
||||
<Popover.Panel align="start" className="border-gray-200 shadow-lg w-64 rounded-lg border bg-white p-4">
|
||||
<h3 className="text-13 font-semibold">Start Aligned</h3>
|
||||
<p className="mt-2 text-13 text-gray-600">This popover is aligned to the start.</p>
|
||||
<p className="text-gray-600 mt-2 text-13">This popover is aligned to the start.</p>
|
||||
</Popover.Panel>
|
||||
</Popover>
|
||||
);
|
||||
|
|
@ -177,12 +177,12 @@ export const AlignEnd: Story = {
|
|||
const [open, setOpen] = useState(args.open);
|
||||
return (
|
||||
<Popover {...args} open={open} onOpenChange={setOpen}>
|
||||
<Popover.Button className="rounded-sm bg-blue-500 px-4 py-2 text-on-color hover:bg-blue-600">
|
||||
<Popover.Button className="bg-blue-500 hover:bg-blue-600 rounded-sm px-4 py-2 text-on-color">
|
||||
Align End
|
||||
</Popover.Button>
|
||||
<Popover.Panel align="end" className="w-64 rounded-lg border border-gray-200 bg-white p-4 shadow-lg">
|
||||
<Popover.Panel align="end" className="border-gray-200 shadow-lg w-64 rounded-lg border bg-white p-4">
|
||||
<h3 className="text-13 font-semibold">End Aligned</h3>
|
||||
<p className="mt-2 text-13 text-gray-600">This popover is aligned to the end.</p>
|
||||
<p className="text-gray-600 mt-2 text-13">This popover is aligned to the end.</p>
|
||||
</Popover.Panel>
|
||||
</Popover>
|
||||
);
|
||||
|
|
@ -194,12 +194,12 @@ export const CustomOffset: Story = {
|
|||
const [open, setOpen] = useState(args.open);
|
||||
return (
|
||||
<Popover {...args} open={open} onOpenChange={setOpen}>
|
||||
<Popover.Button className="rounded-sm bg-blue-500 px-4 py-2 text-on-color hover:bg-blue-600">
|
||||
<Popover.Button className="bg-blue-500 hover:bg-blue-600 rounded-sm px-4 py-2 text-on-color">
|
||||
Custom Offset
|
||||
</Popover.Button>
|
||||
<Popover.Panel sideOffset={20} className="w-64 rounded-lg border border-gray-200 bg-white p-4 shadow-lg">
|
||||
<Popover.Panel sideOffset={20} className="border-gray-200 shadow-lg w-64 rounded-lg border bg-white p-4">
|
||||
<h3 className="text-13 font-semibold">Custom Side Offset</h3>
|
||||
<p className="mt-2 text-13 text-gray-600">This popover has a custom side offset of 20px.</p>
|
||||
<p className="text-gray-600 mt-2 text-13">This popover has a custom side offset of 20px.</p>
|
||||
</Popover.Panel>
|
||||
</Popover>
|
||||
);
|
||||
|
|
@ -216,31 +216,31 @@ export const WithForm: Story = {
|
|||
};
|
||||
return (
|
||||
<Popover {...args} open={open} onOpenChange={setOpen}>
|
||||
<Popover.Button className="rounded-sm bg-blue-500 px-4 py-2 text-on-color hover:bg-blue-600">
|
||||
<Popover.Button className="bg-blue-500 hover:bg-blue-600 rounded-sm px-4 py-2 text-on-color">
|
||||
Open Form
|
||||
</Popover.Button>
|
||||
<Popover.Panel className="w-72 rounded-lg border border-gray-200 bg-white p-4 shadow-lg">
|
||||
<Popover.Panel className="border-gray-200 shadow-lg w-72 rounded-lg border bg-white p-4">
|
||||
<h3 className="text-13 font-semibold">Quick Form</h3>
|
||||
<form onSubmit={handleSubmit} className="mt-3 space-y-3">
|
||||
<div>
|
||||
<label htmlFor="name" className="block text-11 font-medium text-gray-700">
|
||||
<label htmlFor="name" className="text-gray-700 block text-11 font-medium">
|
||||
Name
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
id="name"
|
||||
className="mt-1 w-full rounded-sm border border-gray-300 px-2 py-1.5 text-13"
|
||||
className="border-gray-300 mt-1 w-full rounded-sm border px-2 py-1.5 text-13"
|
||||
placeholder="Enter name"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label htmlFor="email" className="block text-11 font-medium text-gray-700">
|
||||
<label htmlFor="email" className="text-gray-700 block text-11 font-medium">
|
||||
Email
|
||||
</label>
|
||||
<input
|
||||
type="email"
|
||||
id="email"
|
||||
className="mt-1 w-full rounded-sm border border-gray-300 px-2 py-1.5 text-13"
|
||||
className="border-gray-300 mt-1 w-full rounded-sm border px-2 py-1.5 text-13"
|
||||
placeholder="Enter email"
|
||||
/>
|
||||
</div>
|
||||
|
|
@ -248,13 +248,13 @@ export const WithForm: Story = {
|
|||
<button
|
||||
type="button"
|
||||
onClick={() => setOpen(false)}
|
||||
className="rounded-sm bg-gray-200 px-3 py-1.5 text-11 hover:bg-gray-300"
|
||||
className="bg-gray-200 hover:bg-gray-300 rounded-sm px-3 py-1.5 text-11"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
<button
|
||||
type="submit"
|
||||
className="rounded-sm bg-blue-500 px-3 py-1.5 text-11 text-on-color hover:bg-blue-600"
|
||||
className="bg-blue-500 hover:bg-blue-600 rounded-sm px-3 py-1.5 text-11 text-on-color"
|
||||
>
|
||||
Submit
|
||||
</button>
|
||||
|
|
@ -271,15 +271,15 @@ export const WithList: Story = {
|
|||
const [open, setOpen] = useState(args.open);
|
||||
return (
|
||||
<Popover {...args} open={open} onOpenChange={setOpen}>
|
||||
<Popover.Button className="rounded-sm bg-blue-500 px-4 py-2 text-on-color hover:bg-blue-600">
|
||||
<Popover.Button className="bg-blue-500 hover:bg-blue-600 rounded-sm px-4 py-2 text-on-color">
|
||||
Show Options
|
||||
</Popover.Button>
|
||||
<Popover.Panel className="w-56 rounded-lg border border-gray-200 bg-white shadow-lg">
|
||||
<Popover.Panel className="border-gray-200 shadow-lg w-56 rounded-lg border bg-white">
|
||||
<div className="p-2">
|
||||
<h3 className="px-2 py-1.5 text-11 font-semibold text-gray-500">Options</h3>
|
||||
<button className="w-full rounded-sm px-2 py-1.5 text-left text-13 hover:bg-gray-100">Option 1</button>
|
||||
<button className="w-full rounded-sm px-2 py-1.5 text-left text-13 hover:bg-gray-100">Option 2</button>
|
||||
<button className="w-full rounded-sm px-2 py-1.5 text-left text-13 hover:bg-gray-100">Option 3</button>
|
||||
<h3 className="text-gray-500 px-2 py-1.5 text-11 font-semibold">Options</h3>
|
||||
<button className="hover:bg-gray-100 w-full rounded-sm px-2 py-1.5 text-left text-13">Option 1</button>
|
||||
<button className="hover:bg-gray-100 w-full rounded-sm px-2 py-1.5 text-left text-13">Option 2</button>
|
||||
<button className="hover:bg-gray-100 w-full rounded-sm px-2 py-1.5 text-left text-13">Option 3</button>
|
||||
</div>
|
||||
</Popover.Panel>
|
||||
</Popover>
|
||||
|
|
@ -294,11 +294,11 @@ export const ColorPicker: Story = {
|
|||
|
||||
return (
|
||||
<Popover>
|
||||
<Popover.Button className="flex items-center gap-2 rounded-sm border border-gray-300 bg-white px-4 py-2 hover:bg-gray-50">
|
||||
<Popover.Button className="border-gray-300 hover:bg-gray-50 flex items-center gap-2 rounded-sm border bg-white px-4 py-2">
|
||||
<div className="h-4 w-4 rounded-sm" style={{ backgroundColor: selectedColor }} />
|
||||
<span className="text-13">Pick Color</span>
|
||||
</Popover.Button>
|
||||
<Popover.Panel className="w-48 rounded-lg border border-gray-200 bg-white p-3 shadow-lg">
|
||||
<Popover.Panel className="border-gray-200 shadow-lg w-48 rounded-lg border bg-white p-3">
|
||||
<h3 className="mb-2 text-11 font-semibold">Select Color</h3>
|
||||
<div className="grid grid-cols-5 gap-2">
|
||||
{colors.map((color) => (
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ export function ModalPortal({
|
|||
const positionClass = fullScreen ? "" : PORTAL_POSITION_CLASSES[position];
|
||||
|
||||
return cn(
|
||||
"top-0 h-full bg-white shadow-lg absolute transition-transform duration-300 ease-out",
|
||||
"shadow-lg absolute top-0 h-full bg-white transition-transform duration-300 ease-out",
|
||||
widthClass,
|
||||
positionClass,
|
||||
contentClassName
|
||||
|
|
|
|||
|
|
@ -81,11 +81,11 @@ function ModalContent({
|
|||
onClose?: () => void;
|
||||
}) {
|
||||
return (
|
||||
<div className="flex flex-col h-full bg-white">
|
||||
<div className="flex items-center justify-between p-6 border-b border-gray-200">
|
||||
<div className="flex h-full flex-col bg-white">
|
||||
<div className="border-gray-200 flex items-center justify-between border-b p-6">
|
||||
<div>
|
||||
<h2 className="text-18 font-semibold text-gray-900">{title}</h2>
|
||||
<p className="text-13 text-gray-500 mt-1">Modal demonstration</p>
|
||||
<h2 className="text-gray-900 text-18 font-semibold">{title}</h2>
|
||||
<p className="text-gray-500 mt-1 text-13">Modal demonstration</p>
|
||||
</div>
|
||||
{showCloseButton && onClose && (
|
||||
<Button variant="ghost" onClick={onClose} aria-label="Close modal">
|
||||
|
|
@ -93,13 +93,13 @@ function ModalContent({
|
|||
</Button>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex-1 p-6 overflow-y-auto">
|
||||
<div className="flex-1 overflow-y-auto p-6">
|
||||
<p className="text-gray-600 mb-6">{description}</p>
|
||||
|
||||
<div className="space-y-4">
|
||||
<div className="bg-gray-50 p-4 rounded-lg">
|
||||
<h3 className="font-medium text-gray-900 mb-2">Feature Highlights</h3>
|
||||
<ul className="text-13 text-gray-600 space-y-1">
|
||||
<div className="bg-gray-50 rounded-lg p-4">
|
||||
<h3 className="text-gray-900 mb-2 font-medium">Feature Highlights</h3>
|
||||
<ul className="text-gray-600 space-y-1 text-13">
|
||||
<li>• ESC key closes the modal</li>
|
||||
<li>• Click outside overlay to close</li>
|
||||
</ul>
|
||||
|
|
@ -180,7 +180,7 @@ export const BasicPortal: Story = {
|
|||
<div className="relative">
|
||||
<p>This content renders in the normal document flow.</p>
|
||||
<PortalWrapper portalId="storybook-portal">
|
||||
<div className="fixed top-4 right-4 p-4 bg-blue-500 text-on-color rounded-sm shadow-lg z-50">
|
||||
<div className="bg-blue-500 shadow-lg fixed top-4 right-4 z-50 rounded-sm p-4 text-on-color">
|
||||
This content is rendered in a portal!
|
||||
</div>
|
||||
</PortalWrapper>
|
||||
|
|
|
|||
|
|
@ -32,8 +32,8 @@ type Story = StoryObj<typeof meta>;
|
|||
export const Default: Story = {
|
||||
render(args) {
|
||||
return (
|
||||
<ScrollArea {...args} className="h-64 w-80 border rounded-lg">
|
||||
<div className="p-4 space-y-4">
|
||||
<ScrollArea {...args} className="h-64 w-80 rounded-lg border">
|
||||
<div className="space-y-4 p-4">
|
||||
<h3 className="text-16 font-semibold">Long Text Content</h3>
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et
|
||||
|
|
@ -62,7 +62,7 @@ export const Default: Story = {
|
|||
export const Sizes: Story = {
|
||||
render() {
|
||||
const content = (
|
||||
<div className="p-4 space-y-2">
|
||||
<div className="space-y-2 p-4">
|
||||
{[...Array(10)].map((_, i) => (
|
||||
<p key={i}>Line {i + 1}: This is some scrollable content to demonstrate different sizes.</p>
|
||||
))}
|
||||
|
|
@ -73,19 +73,19 @@ export const Sizes: Story = {
|
|||
<div className="flex flex-col gap-6">
|
||||
<div className="space-y-2">
|
||||
<div className="text-13 font-medium">Small</div>
|
||||
<ScrollArea className="h-48 w-80 border rounded-lg" size="sm">
|
||||
<ScrollArea className="h-48 w-80 rounded-lg border" size="sm">
|
||||
{content}
|
||||
</ScrollArea>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<div className="text-13 font-medium">Medium</div>
|
||||
<ScrollArea className="h-48 w-80 border rounded-lg" size="md">
|
||||
<ScrollArea className="h-48 w-80 rounded-lg border" size="md">
|
||||
{content}
|
||||
</ScrollArea>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<div className="text-13 font-medium">Large</div>
|
||||
<ScrollArea className="h-48 w-80 border rounded-lg" size="lg">
|
||||
<ScrollArea className="h-48 w-80 rounded-lg border" size="lg">
|
||||
{content}
|
||||
</ScrollArea>
|
||||
</div>
|
||||
|
|
@ -97,8 +97,8 @@ export const Sizes: Story = {
|
|||
export const ScrollTypeAlways: Story = {
|
||||
render() {
|
||||
return (
|
||||
<ScrollArea className="h-64 w-80 border rounded-lg" scrollType="always">
|
||||
<div className="p-4 space-y-2">
|
||||
<ScrollArea className="h-64 w-80 rounded-lg border" scrollType="always">
|
||||
<div className="space-y-2 p-4">
|
||||
<h3 className="text-16 font-semibold">Always Visible Scrollbar</h3>
|
||||
{[...Array(15)].map((_, i) => (
|
||||
<p key={i}>Line {i + 1}: The scrollbar is always visible.</p>
|
||||
|
|
@ -112,8 +112,8 @@ export const ScrollTypeAlways: Story = {
|
|||
export const ScrollTypeScroll: Story = {
|
||||
render() {
|
||||
return (
|
||||
<ScrollArea className="h-64 w-80 border rounded-lg" scrollType="scroll">
|
||||
<div className="p-4 space-y-2">
|
||||
<ScrollArea className="h-64 w-80 rounded-lg border" scrollType="scroll">
|
||||
<div className="space-y-2 p-4">
|
||||
<h3 className="text-16 font-semibold">Scroll to Show</h3>
|
||||
<p className="text-13 text-placeholder">Scrollbar appears when scrolling</p>
|
||||
{[...Array(15)].map((_, i) => (
|
||||
|
|
@ -128,8 +128,8 @@ export const ScrollTypeScroll: Story = {
|
|||
export const ScrollTypeHover: Story = {
|
||||
render() {
|
||||
return (
|
||||
<ScrollArea className="h-64 w-80 border rounded-lg" scrollType="hover">
|
||||
<div className="p-4 space-y-2">
|
||||
<ScrollArea className="h-64 w-80 rounded-lg border" scrollType="hover">
|
||||
<div className="space-y-2 p-4">
|
||||
<h3 className="text-16 font-semibold">Hover to Show</h3>
|
||||
<p className="text-13 text-placeholder">Scrollbar appears on hover</p>
|
||||
{[...Array(15)].map((_, i) => (
|
||||
|
|
@ -144,10 +144,10 @@ export const ScrollTypeHover: Story = {
|
|||
export const HorizontalScroll: Story = {
|
||||
render() {
|
||||
return (
|
||||
<ScrollArea className="h-32 w-96 border rounded-lg" orientation="horizontal">
|
||||
<div className="flex gap-4 p-4 w-[1200px]">
|
||||
<ScrollArea className="h-32 w-96 rounded-lg border" orientation="horizontal">
|
||||
<div className="flex w-[1200px] gap-4 p-4">
|
||||
{[...Array(12)].map((_, i) => (
|
||||
<div key={i} className="flex-shrink-0 w-32 h-20 bg-layer-1 rounded-sm flex items-center justify-center">
|
||||
<div key={i} className="flex h-20 w-32 flex-shrink-0 items-center justify-center rounded-sm bg-layer-1">
|
||||
Item {i + 1}
|
||||
</div>
|
||||
))}
|
||||
|
|
@ -160,8 +160,8 @@ export const HorizontalScroll: Story = {
|
|||
export const BothDirections: Story = {
|
||||
render() {
|
||||
return (
|
||||
<ScrollArea className="h-64 w-96 border rounded-lg">
|
||||
<div className="w-[800px] p-4 space-y-2">
|
||||
<ScrollArea className="h-64 w-96 rounded-lg border">
|
||||
<div className="w-[800px] space-y-2 p-4">
|
||||
<h3 className="text-16 font-semibold">Both Directions</h3>
|
||||
<p className="text-13 text-placeholder">Content scrolls both vertically and horizontally</p>
|
||||
{[...Array(20)].map((_, i) => (
|
||||
|
|
@ -179,16 +179,16 @@ export const BothDirections: Story = {
|
|||
export const ListExample: Story = {
|
||||
render() {
|
||||
return (
|
||||
<ScrollArea className="h-80 w-96 border rounded-lg">
|
||||
<ScrollArea className="h-80 w-96 rounded-lg border">
|
||||
<div className="p-4">
|
||||
<h3 className="text-16 font-semibold mb-4">User List</h3>
|
||||
<h3 className="mb-4 text-16 font-semibold">User List</h3>
|
||||
<div className="space-y-2">
|
||||
{[...Array(25)].map((_, i) => (
|
||||
<div
|
||||
key={i}
|
||||
className="flex items-center gap-3 p-3 bg-layer-1 rounded-sm hover:bg-surface-2 cursor-pointer"
|
||||
className="flex cursor-pointer items-center gap-3 rounded-sm bg-layer-1 p-3 hover:bg-surface-2"
|
||||
>
|
||||
<div className="w-10 h-10 rounded-full bg-accent-primary flex items-center justify-center text-on-color font-medium">
|
||||
<div className="flex h-10 w-10 items-center justify-center rounded-full bg-accent-primary font-medium text-on-color">
|
||||
{String.fromCharCode(65 + (i % 26))}
|
||||
</div>
|
||||
<div>
|
||||
|
|
@ -238,7 +238,7 @@ async function fetchData() {
|
|||
}`;
|
||||
|
||||
return (
|
||||
<ScrollArea className="h-96 w-full max-w-2xl border rounded-lg bg-surface-1">
|
||||
<ScrollArea className="h-96 w-full max-w-2xl rounded-lg border bg-surface-1">
|
||||
<pre className="p-4 text-13">
|
||||
<code>{code}</code>
|
||||
</pre>
|
||||
|
|
@ -250,12 +250,12 @@ async function fetchData() {
|
|||
export const ChatMessages: Story = {
|
||||
render() {
|
||||
return (
|
||||
<ScrollArea className="h-96 w-full max-w-md border rounded-lg">
|
||||
<div className="p-4 space-y-4">
|
||||
<ScrollArea className="h-96 w-full max-w-md rounded-lg border">
|
||||
<div className="space-y-4 p-4">
|
||||
{[...Array(20)].map((_, i) => (
|
||||
<div key={i} className={`flex ${i % 3 === 0 ? "justify-end" : "justify-start"}`}>
|
||||
<div
|
||||
className={`max-w-[70%] p-3 rounded-lg ${i % 3 === 0 ? "bg-accent-primary text-on-color" : "bg-layer-1"}`}
|
||||
className={`max-w-[70%] rounded-lg p-3 ${i % 3 === 0 ? "bg-accent-primary text-on-color" : "bg-layer-1"}`}
|
||||
>
|
||||
<div className="text-13">{i % 3 === 0 ? "You" : `User ${i + 1}`}</div>
|
||||
<div className="mt-1">Message content for message number {i + 1}</div>
|
||||
|
|
@ -271,9 +271,9 @@ export const ChatMessages: Story = {
|
|||
export const DataTable: Story = {
|
||||
render() {
|
||||
return (
|
||||
<ScrollArea className="h-96 w-full max-w-3xl border rounded-lg">
|
||||
<ScrollArea className="h-96 w-full max-w-3xl rounded-lg border">
|
||||
<table className="w-full">
|
||||
<thead className="bg-layer-1 sticky top-0">
|
||||
<thead className="sticky top-0 bg-layer-1">
|
||||
<tr>
|
||||
<th className="px-4 py-2 text-left">ID</th>
|
||||
<th className="px-4 py-2 text-left">Name</th>
|
||||
|
|
@ -289,7 +289,7 @@ export const DataTable: Story = {
|
|||
<td className="px-4 py-2">user{i + 1}@example.com</td>
|
||||
<td className="px-4 py-2">
|
||||
<span
|
||||
className={`px-2 py-1 rounded-sm text-11 ${i % 3 === 0 ? "bg-success-primary text-success-primary" : "bg-gray-500/20 text-gray-500"}`}
|
||||
className={`rounded-sm px-2 py-1 text-11 ${i % 3 === 0 ? "bg-success-primary text-success-primary" : "bg-gray-500/20 text-gray-500"}`}
|
||||
>
|
||||
{i % 3 === 0 ? "Active" : "Inactive"}
|
||||
</span>
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ const ScrollBar = React.memo(function ScrollBar({
|
|||
data-slot="scroll-area-scrollbar"
|
||||
orientation={orientation}
|
||||
className={cn(
|
||||
"group/track mr-1 flex justify-center rounded-sm bg-transparent opacity-0 transition-opacity delay-300 ",
|
||||
"group/track mr-1 flex justify-center rounded-sm bg-transparent opacity-0 transition-opacity delay-300",
|
||||
orientation === "vertical" && verticalSizeStyles[size],
|
||||
orientation === "horizontal" && horizontalSizeStyles[size],
|
||||
scrollType === "always" && "opacity-100",
|
||||
|
|
|
|||
|
|
@ -46,15 +46,15 @@ export const Vertical: Story = {
|
|||
export const WithinContainer: Story = {
|
||||
render() {
|
||||
return (
|
||||
<div className="w-[300px] rounded-lg border p-6 space-y-4">
|
||||
<div className="w-[300px] space-y-4 rounded-lg border p-6">
|
||||
<div className="space-y-2">
|
||||
<h4 className="font-medium leading-none">Section 1</h4>
|
||||
<p className="text-13 text-muted-foreground">Description for section 1</p>
|
||||
<h4 className="leading-none font-medium">Section 1</h4>
|
||||
<p className="text-muted-foreground text-13">Description for section 1</p>
|
||||
</div>
|
||||
<Separator />
|
||||
<div className="space-y-2">
|
||||
<h4 className="font-medium leading-none">Section 2</h4>
|
||||
<p className="text-13 text-muted-foreground">Description for section 2</p>
|
||||
<h4 className="leading-none font-medium">Section 2</h4>
|
||||
<p className="text-muted-foreground text-13">Description for section 2</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ type Story = StoryObj<typeof meta>;
|
|||
export const Default: Story = {
|
||||
render() {
|
||||
return (
|
||||
<Skeleton className="w-80 flex flex-col gap-2">
|
||||
<Skeleton className="flex w-80 flex-col gap-2">
|
||||
<Skeleton.Item height="40px" width="100%" />
|
||||
</Skeleton>
|
||||
);
|
||||
|
|
@ -34,7 +34,7 @@ export const Default: Story = {
|
|||
export const Card: Story = {
|
||||
render() {
|
||||
return (
|
||||
<Skeleton className="w-80 flex flex-col gap-4">
|
||||
<Skeleton className="flex w-80 flex-col gap-4">
|
||||
<Skeleton.Item height="200px" width="100%" />
|
||||
<div className="flex flex-col gap-2">
|
||||
<Skeleton.Item height="20px" width="60%" />
|
||||
|
|
@ -48,11 +48,11 @@ export const Card: Story = {
|
|||
export const List: Story = {
|
||||
render() {
|
||||
return (
|
||||
<Skeleton className="w-96 flex flex-col gap-3">
|
||||
<Skeleton className="flex w-96 flex-col gap-3">
|
||||
{[...Array(5)].map((_, i) => (
|
||||
<div key={i} className="flex gap-3">
|
||||
<Skeleton.Item height="40px" width="40px" className="rounded-full" />
|
||||
<div className="flex-1 flex flex-col gap-2">
|
||||
<div className="flex flex-1 flex-col gap-2">
|
||||
<Skeleton.Item height="16px" width="70%" />
|
||||
<Skeleton.Item height="12px" width="50%" />
|
||||
</div>
|
||||
|
|
@ -66,7 +66,7 @@ export const List: Story = {
|
|||
export const Table: Story = {
|
||||
render() {
|
||||
return (
|
||||
<Skeleton className="w-full flex flex-col gap-3">
|
||||
<Skeleton className="flex w-full flex-col gap-3">
|
||||
<div className="flex gap-4">
|
||||
<Skeleton.Item height="20px" width="150px" />
|
||||
<Skeleton.Item height="20px" width="200px" />
|
||||
|
|
@ -87,10 +87,10 @@ export const Table: Story = {
|
|||
export const Profile: Story = {
|
||||
render() {
|
||||
return (
|
||||
<Skeleton className="w-80 flex flex-col gap-4">
|
||||
<Skeleton className="flex w-80 flex-col gap-4">
|
||||
<div className="flex items-center gap-4">
|
||||
<Skeleton.Item height="80px" width="80px" className="rounded-full" />
|
||||
<div className="flex-1 flex flex-col gap-2">
|
||||
<div className="flex flex-1 flex-col gap-2">
|
||||
<Skeleton.Item height="20px" width="60%" />
|
||||
<Skeleton.Item height="16px" width="40%" />
|
||||
</div>
|
||||
|
|
@ -130,7 +130,7 @@ export const AvatarGroup: Story = {
|
|||
export const Text: Story = {
|
||||
render() {
|
||||
return (
|
||||
<Skeleton className="w-96 flex flex-col gap-2">
|
||||
<Skeleton className="flex w-96 flex-col gap-2">
|
||||
<Skeleton.Item height="16px" width="100%" />
|
||||
<Skeleton.Item height="16px" width="95%" />
|
||||
<Skeleton.Item height="16px" width="90%" />
|
||||
|
|
@ -153,7 +153,7 @@ export const Button: Story = {
|
|||
export const Input: Story = {
|
||||
render() {
|
||||
return (
|
||||
<Skeleton className="w-80 flex flex-col gap-2">
|
||||
<Skeleton className="flex w-80 flex-col gap-2">
|
||||
<Skeleton.Item height="14px" width="80px" />
|
||||
<Skeleton.Item height="40px" width="100%" className="rounded-md" />
|
||||
</Skeleton>
|
||||
|
|
@ -164,7 +164,7 @@ export const Input: Story = {
|
|||
export const Form: Story = {
|
||||
render() {
|
||||
return (
|
||||
<Skeleton className="w-96 flex flex-col gap-4">
|
||||
<Skeleton className="flex w-96 flex-col gap-4">
|
||||
<div className="flex flex-col gap-2">
|
||||
<Skeleton.Item height="14px" width="80px" />
|
||||
<Skeleton.Item height="40px" width="100%" className="rounded-md" />
|
||||
|
|
@ -186,7 +186,7 @@ export const Form: Story = {
|
|||
export const ProductCard: Story = {
|
||||
render() {
|
||||
return (
|
||||
<Skeleton className="w-72 flex flex-col gap-3 p-4 border rounded-lg">
|
||||
<Skeleton className="flex w-72 flex-col gap-3 rounded-lg border p-4">
|
||||
<Skeleton.Item height="200px" width="100%" className="rounded-md" />
|
||||
<div className="flex flex-col gap-2">
|
||||
<Skeleton.Item height="20px" width="80%" />
|
||||
|
|
|
|||
|
|
@ -65,23 +65,23 @@ export const AllSizes: Story = {
|
|||
<div className="flex items-center gap-6">
|
||||
<div className="text-center">
|
||||
<CircularBarSpinner height="12px" width="12px" />
|
||||
<p className="mt-2 text-11 text-gray-600">Small</p>
|
||||
<p className="text-gray-600 mt-2 text-11">Small</p>
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<CircularBarSpinner height="16px" width="16px" />
|
||||
<p className="mt-2 text-11 text-gray-600">Default</p>
|
||||
<p className="text-gray-600 mt-2 text-11">Default</p>
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<CircularBarSpinner height="24px" width="24px" />
|
||||
<p className="mt-2 text-11 text-gray-600">Medium</p>
|
||||
<p className="text-gray-600 mt-2 text-11">Medium</p>
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<CircularBarSpinner height="32px" width="32px" />
|
||||
<p className="mt-2 text-11 text-gray-600">Large</p>
|
||||
<p className="text-gray-600 mt-2 text-11">Large</p>
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<CircularBarSpinner height="48px" width="48px" />
|
||||
<p className="mt-2 text-11 text-gray-600">XL</p>
|
||||
<p className="text-gray-600 mt-2 text-11">XL</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
@ -94,23 +94,23 @@ export const ColorVariations: Story = {
|
|||
<div className="flex items-center gap-6">
|
||||
<div className="text-center">
|
||||
<CircularBarSpinner className="text-blue-500" height="24px" width="24px" />
|
||||
<p className="mt-2 text-11 text-gray-600">Blue</p>
|
||||
<p className="text-gray-600 mt-2 text-11">Blue</p>
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<CircularBarSpinner className="text-success-primary" height="24px" width="24px" />
|
||||
<p className="mt-2 text-11 text-gray-600">Green</p>
|
||||
<p className="text-gray-600 mt-2 text-11">Green</p>
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<CircularBarSpinner className="text-danger-primary" height="24px" width="24px" />
|
||||
<p className="mt-2 text-11 text-gray-600">Red</p>
|
||||
<p className="text-gray-600 mt-2 text-11">Red</p>
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<CircularBarSpinner className="text-purple-500" height="24px" width="24px" />
|
||||
<p className="mt-2 text-11 text-gray-600">Purple</p>
|
||||
<p className="text-gray-600 mt-2 text-11">Purple</p>
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<CircularBarSpinner className="text-orange-500" height="24px" width="24px" />
|
||||
<p className="mt-2 text-11 text-gray-600">Orange</p>
|
||||
<p className="text-gray-600 mt-2 text-11">Orange</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
@ -120,7 +120,7 @@ export const ColorVariations: Story = {
|
|||
export const InButton: Story = {
|
||||
render() {
|
||||
return (
|
||||
<button className="flex items-center gap-2 rounded-sm bg-green-500 px-4 py-2 text-on-color">
|
||||
<button className="bg-green-500 flex items-center gap-2 rounded-sm px-4 py-2 text-on-color">
|
||||
<CircularBarSpinner height="16px" width="16px" />
|
||||
<span>Processing...</span>
|
||||
</button>
|
||||
|
|
@ -131,10 +131,10 @@ export const InButton: Story = {
|
|||
export const CenteredInCard: Story = {
|
||||
render() {
|
||||
return (
|
||||
<div className="w-96 rounded-lg border border-gray-200 bg-white p-8 shadow-md">
|
||||
<div className="border-gray-200 shadow-md w-96 rounded-lg border bg-white p-8">
|
||||
<div className="flex flex-col items-center justify-center space-y-4">
|
||||
<CircularBarSpinner height="48px" width="48px" />
|
||||
<p className="text-13 text-gray-600">Processing data...</p>
|
||||
<p className="text-gray-600 text-13">Processing data...</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -65,23 +65,23 @@ export const AllSizes: Story = {
|
|||
<div className="flex items-center gap-6">
|
||||
<div className="text-center">
|
||||
<Spinner height="16px" width="16px" />
|
||||
<p className="mt-2 text-11 text-gray-600">Small</p>
|
||||
<p className="text-gray-600 mt-2 text-11">Small</p>
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<Spinner height="24px" width="24px" />
|
||||
<p className="mt-2 text-11 text-gray-600">Medium</p>
|
||||
<p className="text-gray-600 mt-2 text-11">Medium</p>
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<Spinner height="32px" width="32px" />
|
||||
<p className="mt-2 text-11 text-gray-600">Default</p>
|
||||
<p className="text-gray-600 mt-2 text-11">Default</p>
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<Spinner height="48px" width="48px" />
|
||||
<p className="mt-2 text-11 text-gray-600">Large</p>
|
||||
<p className="text-gray-600 mt-2 text-11">Large</p>
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<Spinner height="64px" width="64px" />
|
||||
<p className="mt-2 text-11 text-gray-600">XL</p>
|
||||
<p className="text-gray-600 mt-2 text-11">XL</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
@ -94,23 +94,23 @@ export const ColorVariations: Story = {
|
|||
<div className="flex items-center gap-6">
|
||||
<div className="text-center">
|
||||
<Spinner className="text-blue-500" />
|
||||
<p className="mt-2 text-11 text-gray-600">Blue</p>
|
||||
<p className="text-gray-600 mt-2 text-11">Blue</p>
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<Spinner className="text-success-primary" />
|
||||
<p className="mt-2 text-11 text-gray-600">Green</p>
|
||||
<p className="text-gray-600 mt-2 text-11">Green</p>
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<Spinner className="text-danger-primary" />
|
||||
<p className="mt-2 text-11 text-gray-600">Red</p>
|
||||
<p className="text-gray-600 mt-2 text-11">Red</p>
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<Spinner className="text-purple-500" />
|
||||
<p className="mt-2 text-11 text-gray-600">Purple</p>
|
||||
<p className="text-gray-600 mt-2 text-11">Purple</p>
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<Spinner className="text-orange-500" />
|
||||
<p className="mt-2 text-11 text-gray-600">Orange</p>
|
||||
<p className="text-gray-600 mt-2 text-11">Orange</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
@ -120,7 +120,7 @@ export const ColorVariations: Story = {
|
|||
export const InButton: Story = {
|
||||
render() {
|
||||
return (
|
||||
<button className="flex items-center gap-2 rounded-sm bg-blue-500 px-4 py-2 text-on-color">
|
||||
<button className="bg-blue-500 flex items-center gap-2 rounded-sm px-4 py-2 text-on-color">
|
||||
<Spinner height="16px" width="16px" />
|
||||
<span>Loading...</span>
|
||||
</button>
|
||||
|
|
@ -131,10 +131,10 @@ export const InButton: Story = {
|
|||
export const CenteredInCard: Story = {
|
||||
render() {
|
||||
return (
|
||||
<div className="w-96 rounded-lg border border-gray-200 bg-white p-8 shadow-md">
|
||||
<div className="border-gray-200 shadow-md w-96 rounded-lg border bg-white p-8">
|
||||
<div className="flex flex-col items-center justify-center space-y-4">
|
||||
<Spinner height="48px" width="48px" />
|
||||
<p className="text-13 text-gray-600">Loading content...</p>
|
||||
<p className="text-gray-600 text-13">Loading content...</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ function Switch({ value, onChange, label, size = "sm", disabled, className }: IT
|
|||
<BaseSwitch.Thumb
|
||||
aria-hidden="true"
|
||||
className={cn(
|
||||
"inline-block self-center rounded-full shadow ring-0 transition-transform duration-200 ease-in-out",
|
||||
"shadow inline-block self-center rounded-full ring-0 transition-transform duration-200 ease-in-out",
|
||||
// size
|
||||
size === "sm" ? "h-3 w-3" : size === "md" ? "h-4 w-4" : "h-5 w-5",
|
||||
// position + color by state
|
||||
|
|
|
|||
|
|
@ -75,15 +75,15 @@ export const AllSizes: Story = {
|
|||
<div className="flex items-center gap-6">
|
||||
<div className="text-center">
|
||||
<Switch value={small} onChange={setSmall} size="sm" />
|
||||
<p className="mt-2 text-11 text-gray-600">Small</p>
|
||||
<p className="text-gray-600 mt-2 text-11">Small</p>
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<Switch value={medium} onChange={setMedium} size="md" />
|
||||
<p className="mt-2 text-11 text-gray-600">Medium</p>
|
||||
<p className="text-gray-600 mt-2 text-11">Medium</p>
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<Switch value={large} onChange={setLarge} size="lg" />
|
||||
<p className="mt-2 text-11 text-gray-600">Large</p>
|
||||
<p className="text-gray-600 mt-2 text-11">Large</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
@ -101,19 +101,19 @@ export const AllStates: Story = {
|
|||
<div className="space-y-4">
|
||||
<div className="flex items-center gap-4">
|
||||
<Switch value={unchecked} onChange={setUnchecked} />
|
||||
<span className="text-13 text-gray-600">Unchecked</span>
|
||||
<span className="text-gray-600 text-13">Unchecked</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-4">
|
||||
<Switch value={checked} onChange={setChecked} />
|
||||
<span className="text-13 text-gray-600">Checked</span>
|
||||
<span className="text-gray-600 text-13">Checked</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-4">
|
||||
<Switch value={disabledUnchecked} onChange={() => {}} disabled />
|
||||
<span className="text-13 text-gray-600">Disabled Unchecked</span>
|
||||
<span className="text-gray-600 text-13">Disabled Unchecked</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-4">
|
||||
<Switch value={disabledChecked} onChange={() => {}} disabled />
|
||||
<span className="text-13 text-gray-600">Disabled Checked</span>
|
||||
<span className="text-gray-600 text-13">Disabled Checked</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
@ -127,27 +127,27 @@ export const InForm: Story = {
|
|||
const [updates, setUpdates] = useState(true);
|
||||
|
||||
return (
|
||||
<div className="w-80 rounded-lg border border-gray-200 bg-white p-6 shadow-md">
|
||||
<div className="border-gray-200 shadow-md w-80 rounded-lg border bg-white p-6">
|
||||
<h3 className="text-16 font-semibold">Notification Settings</h3>
|
||||
<div className="mt-4 space-y-4">
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<p className="text-13 font-medium">Push Notifications</p>
|
||||
<p className="text-11 text-gray-500">Receive push notifications on your device</p>
|
||||
<p className="text-gray-500 text-11">Receive push notifications on your device</p>
|
||||
</div>
|
||||
<Switch value={notifications} onChange={setNotifications} size="md" />
|
||||
</div>
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<p className="text-13 font-medium">Marketing Emails</p>
|
||||
<p className="text-11 text-gray-500">Receive emails about new features</p>
|
||||
<p className="text-gray-500 text-11">Receive emails about new features</p>
|
||||
</div>
|
||||
<Switch value={marketing} onChange={setMarketing} size="md" />
|
||||
</div>
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<p className="text-13 font-medium">Product Updates</p>
|
||||
<p className="text-11 text-gray-500">Get notified about product updates</p>
|
||||
<p className="text-gray-500 text-11">Get notified about product updates</p>
|
||||
</div>
|
||||
<Switch value={updates} onChange={setUpdates} size="md" />
|
||||
</div>
|
||||
|
|
@ -162,11 +162,11 @@ export const WithDescription: Story = {
|
|||
const [enabled, setEnabled] = useState(false);
|
||||
|
||||
return (
|
||||
<div className="w-96 rounded-lg border border-gray-200 bg-white p-6">
|
||||
<div className="border-gray-200 w-96 rounded-lg border bg-white p-6">
|
||||
<div className="flex items-start justify-between">
|
||||
<div className="flex-1">
|
||||
<h4 className="text-13 font-semibold">Enable Two-Factor Authentication</h4>
|
||||
<p className="mt-1 text-11 text-gray-500">
|
||||
<p className="text-gray-500 mt-1 text-11">
|
||||
Add an extra layer of security to your account by enabling two-factor authentication.
|
||||
</p>
|
||||
</div>
|
||||
|
|
@ -182,13 +182,13 @@ export const Interactive: Story = {
|
|||
const [enabled, setEnabled] = useState(false);
|
||||
|
||||
return (
|
||||
<div className="w-80 space-y-4 rounded-lg border border-gray-200 bg-white p-6">
|
||||
<div className="border-gray-200 w-80 space-y-4 rounded-lg border bg-white p-6">
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="text-13 font-medium">Feature Toggle</span>
|
||||
<Switch value={enabled} onChange={setEnabled} size="md" />
|
||||
</div>
|
||||
<div className="rounded-sm bg-gray-50 p-4">
|
||||
<p className="text-13 text-gray-700">
|
||||
<div className="bg-gray-50 rounded-sm p-4">
|
||||
<p className="text-gray-700 text-13">
|
||||
Status: <span className="font-semibold">{enabled ? "Enabled" : "Disabled"}</span>
|
||||
</p>
|
||||
{enabled && <p className="mt-2 text-11 text-success-primary">Feature is now active and ready to use!</p>}
|
||||
|
|
@ -208,7 +208,7 @@ export const CustomStyles: Story = {
|
|||
value={value}
|
||||
onChange={setValue}
|
||||
size="lg"
|
||||
className="border-2 border-purple-300 data-[state=checked]:bg-purple-500"
|
||||
className="border-purple-300 data-[state=checked]:bg-purple-500 border-2"
|
||||
/>
|
||||
<span className="text-13">Custom styled switch</span>
|
||||
</div>
|
||||
|
|
@ -231,7 +231,7 @@ export const MultipleControls: Story = {
|
|||
};
|
||||
|
||||
return (
|
||||
<div className="w-96 rounded-lg border border-gray-200 bg-white p-6">
|
||||
<div className="border-gray-200 w-96 rounded-lg border bg-white p-6">
|
||||
<h3 className="mb-4 text-16 font-semibold">Feature Flags</h3>
|
||||
<div className="space-y-3">
|
||||
{Object.entries(settings).map(([key, value]) => (
|
||||
|
|
|
|||
|
|
@ -12,15 +12,15 @@ export function TabNavigationItem({ children, isActive, className }: TTabNavigat
|
|||
return (
|
||||
<div
|
||||
className={cn(
|
||||
"relative flex items-center gap-2 rounded-md px-2 py-1.5 text-13 font-medium transition-colors z-10",
|
||||
isActive ? "text-primary" : "text-secondary hover:text-primary hover:bg-layer-transparent-hover",
|
||||
"relative z-10 flex items-center gap-2 rounded-md px-2 py-1.5 text-13 font-medium transition-colors",
|
||||
isActive ? "text-primary" : "text-secondary hover:bg-layer-transparent-hover hover:text-primary",
|
||||
className
|
||||
)}
|
||||
>
|
||||
<AnimatePresence>
|
||||
{isActive && (
|
||||
<motion.div
|
||||
className="absolute inset-0 bg-layer-transparent-active rounded-md -z-10"
|
||||
className="absolute inset-0 -z-10 rounded-md bg-layer-transparent-active"
|
||||
initial={{ opacity: 0, scale: 0.9 }}
|
||||
animate={{ opacity: 1, scale: 1 }}
|
||||
exit={{ opacity: 0, scale: 0.9 }}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ const meta: Meta<typeof TabNavigationList> = {
|
|||
},
|
||||
decorators: [
|
||||
(Story) => (
|
||||
<div className="w-[900px] p-8 bg-surface-1">
|
||||
<div className="w-[900px] bg-surface-1 p-8">
|
||||
<Story />
|
||||
</div>
|
||||
),
|
||||
|
|
@ -55,7 +55,7 @@ export const Default: Story = {
|
|||
<div className="space-y-8">
|
||||
{/* Example 1: Navigation with anchor tags (simulating React Router Link) */}
|
||||
<div className="space-y-3">
|
||||
<div className="text-11 font-medium text-tertiary uppercase tracking-wide">
|
||||
<div className="text-11 font-medium tracking-wide text-tertiary uppercase">
|
||||
With Navigation Links (e.g., React Router)
|
||||
</div>
|
||||
<TabNavigationList>
|
||||
|
|
@ -69,7 +69,7 @@ export const Default: Story = {
|
|||
}}
|
||||
>
|
||||
<TabNavigationItem isActive={activeNavTab === item.key}>
|
||||
<div className="flex items-center gap-2 z-10">
|
||||
<div className="z-10 flex items-center gap-2">
|
||||
<item.icon className="h-4 w-4" />
|
||||
<span>{item.name}</span>
|
||||
</div>
|
||||
|
|
@ -83,9 +83,9 @@ export const Default: Story = {
|
|||
</div>
|
||||
|
||||
{/* Code example */}
|
||||
<div className="mt-6 p-4 bg-layer-1 rounded-md">
|
||||
<div className="text-11 font-medium text-secondary mb-2">Example Code:</div>
|
||||
<pre className="text-11 text-tertiary overflow-x-auto">
|
||||
<div className="mt-6 rounded-md bg-layer-1 p-4">
|
||||
<div className="mb-2 text-11 font-medium text-secondary">Example Code:</div>
|
||||
<pre className="overflow-x-auto text-11 text-tertiary">
|
||||
{`// With React Router Link
|
||||
<TabNavigationList>
|
||||
{items.map(item => (
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ const TableHeader = React.forwardRef(function TableHeader(
|
|||
{ className, ...props }: React.ComponentPropsWithoutRef<"thead">,
|
||||
ref: React.ForwardedRef<React.ComponentRef<"thead">>
|
||||
) {
|
||||
return <thead ref={ref} className={cn("bg-layer-1 py-4 border-y border-subtle", className)} {...props} />;
|
||||
return <thead ref={ref} className={cn("border-y border-subtle bg-layer-1 py-4", className)} {...props} />;
|
||||
});
|
||||
TableHeader.displayName = "TableHeader";
|
||||
|
||||
|
|
|
|||
|
|
@ -144,7 +144,7 @@ export const WithActions: Story = {
|
|||
<TableCell>john@example.com</TableCell>
|
||||
<TableCell>Admin</TableCell>
|
||||
<TableCell className="text-right">
|
||||
<button className="mr-2 text-blue-500 hover:underline">Edit</button>
|
||||
<button className="text-blue-500 mr-2 hover:underline">Edit</button>
|
||||
<button className="text-danger-primary hover:underline">Delete</button>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
|
|
@ -153,7 +153,7 @@ export const WithActions: Story = {
|
|||
<TableCell>jane@example.com</TableCell>
|
||||
<TableCell>User</TableCell>
|
||||
<TableCell className="text-right">
|
||||
<button className="mr-2 text-blue-500 hover:underline">Edit</button>
|
||||
<button className="text-blue-500 mr-2 hover:underline">Edit</button>
|
||||
<button className="text-danger-primary hover:underline">Delete</button>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
|
|
@ -179,30 +179,30 @@ export const WithBadges: Story = {
|
|||
<TableRow>
|
||||
<TableCell>Website Redesign</TableCell>
|
||||
<TableCell>
|
||||
<span className="rounded-full bg-green-100 px-2 py-1 text-11 text-success-primary">In Progress</span>
|
||||
<span className="bg-green-100 rounded-full px-2 py-1 text-11 text-success-primary">In Progress</span>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<span className="rounded-full bg-red-100 px-2 py-1 text-11 text-danger-primary">High</span>
|
||||
<span className="bg-red-100 rounded-full px-2 py-1 text-11 text-danger-primary">High</span>
|
||||
</TableCell>
|
||||
<TableCell>John Doe</TableCell>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableCell>Mobile App</TableCell>
|
||||
<TableCell>
|
||||
<span className="rounded-full bg-blue-100 px-2 py-1 text-11 text-blue-800">Planned</span>
|
||||
<span className="bg-blue-100 text-blue-800 rounded-full px-2 py-1 text-11">Planned</span>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<span className="rounded-full bg-yellow-100 px-2 py-1 text-11 text-yellow-800">Medium</span>
|
||||
<span className="bg-yellow-100 text-yellow-800 rounded-full px-2 py-1 text-11">Medium</span>
|
||||
</TableCell>
|
||||
<TableCell>Jane Smith</TableCell>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableCell>API Integration</TableCell>
|
||||
<TableCell>
|
||||
<span className="rounded-full bg-gray-100 px-2 py-1 text-11 text-gray-800">Completed</span>
|
||||
<span className="bg-gray-100 text-gray-800 rounded-full px-2 py-1 text-11">Completed</span>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<span className="rounded-full bg-green-100 px-2 py-1 text-11 text-success-primary">Low</span>
|
||||
<span className="bg-green-100 rounded-full px-2 py-1 text-11 text-success-primary">Low</span>
|
||||
</TableCell>
|
||||
<TableCell>Bob Wilson</TableCell>
|
||||
</TableRow>
|
||||
|
|
@ -320,7 +320,7 @@ export const LargeDataset: Story = {
|
|||
export const CustomStyling: Story = {
|
||||
render() {
|
||||
return (
|
||||
<Table className="border-2 border-blue-200">
|
||||
<Table className="border-blue-200 border-2">
|
||||
<TableHeader>
|
||||
<TableRow className="bg-blue-100">
|
||||
<TableHead className="text-blue-900">Name</TableHead>
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ export const Basic: Story = {
|
|||
{tabOptions.map((option) => (
|
||||
<Tabs.Content key={option.value} value={option.value} className="p-4">
|
||||
<div className="text-13">
|
||||
<h3 className="font-medium mb-2">{option.label}</h3>
|
||||
<h3 className="mb-2 font-medium">{option.label}</h3>
|
||||
<p className="text-tertiary">Content for the {option.label.toLowerCase()} tab.</p>
|
||||
</div>
|
||||
</Tabs.Content>
|
||||
|
|
@ -78,7 +78,7 @@ export const Sizes: Story = {
|
|||
lg: "Large",
|
||||
};
|
||||
return (
|
||||
<div className="w-[400px] grid gap-4">
|
||||
<div className="grid w-[400px] gap-4">
|
||||
{sizes.map((size) => (
|
||||
<div key={size} className="flex flex-col gap-2">
|
||||
<div className="text-13 font-medium">{sizeLabels[size]}</div>
|
||||
|
|
@ -171,7 +171,7 @@ export const WithIcons: Story = {
|
|||
<Tabs.List>
|
||||
{tabsWithIcons.map((tab) => (
|
||||
<Tabs.Trigger key={tab.value} value={tab.value}>
|
||||
<tab.icon className="w-4 h-4 mr-2" />
|
||||
<tab.icon className="mr-2 h-4 w-4" />
|
||||
{tab.label}
|
||||
</Tabs.Trigger>
|
||||
))}
|
||||
|
|
@ -203,7 +203,7 @@ export const IconsOnly: Story = {
|
|||
<Tabs.List>
|
||||
{iconTabs.map((tab) => (
|
||||
<Tabs.Trigger key={tab.value} value={tab.value}>
|
||||
<tab.icon className="w-4 h-4" />
|
||||
<tab.icon className="h-4 w-4" />
|
||||
</Tabs.Trigger>
|
||||
))}
|
||||
<Tabs.Indicator />
|
||||
|
|
@ -243,7 +243,7 @@ export const DynamicTabs: Story = {
|
|||
return (
|
||||
<div className="w-[500px]">
|
||||
<div className="mb-4">
|
||||
<button onClick={addTab} className="px-3 py-1.5 text-13 bg-layer-1 rounded-sm hover:bg-surface-2">
|
||||
<button onClick={addTab} className="rounded-sm bg-layer-1 px-3 py-1.5 text-13 hover:bg-surface-2">
|
||||
Add Tab
|
||||
</button>
|
||||
</div>
|
||||
|
|
@ -323,11 +323,11 @@ export const WithComplexContent: Story = {
|
|||
<div className="space-y-4">
|
||||
<div>
|
||||
<label className="text-13 font-medium">Username</label>
|
||||
<input type="text" className="mt-1 w-full px-3 py-2 bg-layer-1 rounded-sm" />
|
||||
<input type="text" className="mt-1 w-full rounded-sm bg-layer-1 px-3 py-2" />
|
||||
</div>
|
||||
<div>
|
||||
<label className="text-13 font-medium">Email</label>
|
||||
<input type="email" className="mt-1 w-full px-3 py-2 bg-layer-1 rounded-sm" />
|
||||
<input type="email" className="mt-1 w-full rounded-sm bg-layer-1 px-3 py-2" />
|
||||
</div>
|
||||
</div>
|
||||
</Tabs.Content>
|
||||
|
|
@ -335,11 +335,11 @@ export const WithComplexContent: Story = {
|
|||
<div className="space-y-4">
|
||||
<div>
|
||||
<label className="text-13 font-medium">Current Password</label>
|
||||
<input type="password" className="mt-1 w-full px-3 py-2 bg-layer-1 rounded-sm" />
|
||||
<input type="password" className="mt-1 w-full rounded-sm bg-layer-1 px-3 py-2" />
|
||||
</div>
|
||||
<div>
|
||||
<label className="text-13 font-medium">New Password</label>
|
||||
<input type="password" className="mt-1 w-full px-3 py-2 bg-layer-1 rounded-sm" />
|
||||
<input type="password" className="mt-1 w-full rounded-sm bg-layer-1 px-3 py-2" />
|
||||
</div>
|
||||
</div>
|
||||
</Tabs.Content>
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ const TabsRoot = React.forwardRef(function TabsRoot(
|
|||
<TabsContext.Provider value={{ variant }}>
|
||||
<TabsPrimitive.Root
|
||||
data-slot="tabs"
|
||||
className={cn("flex flex-col w-full h-full", className)}
|
||||
className={cn("flex h-full w-full flex-col", className)}
|
||||
{...props}
|
||||
ref={ref}
|
||||
/>
|
||||
|
|
@ -68,7 +68,7 @@ const TabsList = React.forwardRef(function TabsList(
|
|||
<TabsPrimitive.List
|
||||
data-slot="tabs-list"
|
||||
className={cn(
|
||||
"flex w-full items-center justify-between gap-1.5 rounded-lg text-13 p-0.5 relative overflow-auto",
|
||||
"relative flex w-full items-center justify-between gap-1.5 overflow-auto rounded-lg p-0.5 text-13",
|
||||
{
|
||||
"bg-layer-3": background === "contained",
|
||||
},
|
||||
|
|
@ -92,10 +92,10 @@ const TabsTrigger = React.forwardRef(function TabsTrigger(
|
|||
<TabsPrimitive.Tab
|
||||
data-slot="tabs-trigger"
|
||||
className={cn(
|
||||
"flex items-center justify-center p-1 min-w-fit w-full font-medium text-primary outline-none focus:outline-none cursor-pointer transition-all duration-200 ease-in-out rounded-md border border-transparent",
|
||||
" data-[selected]:text-primary data-[selected]:shadow-sm data-[selected]:bg-layer-2 data-[selected]:border data-[selected]:border-subtle-1 data-[selected]:raised-200",
|
||||
"text-placeholder hover:text-tertiary hover:bg-layer-transparent-hover",
|
||||
"disabled:text-placeholder disabled:cursor-not-allowed",
|
||||
"flex w-full min-w-fit cursor-pointer items-center justify-center rounded-md border border-transparent p-1 font-medium text-primary transition-all duration-200 ease-in-out outline-none focus:outline-none",
|
||||
"data-[selected]:shadow-sm data-[selected]:raised-200 data-[selected]:border data-[selected]:border-subtle-1 data-[selected]:bg-layer-2 data-[selected]:text-primary",
|
||||
"text-placeholder hover:bg-layer-transparent-hover hover:text-tertiary",
|
||||
"disabled:cursor-not-allowed disabled:text-placeholder",
|
||||
{
|
||||
"text-11": size === "sm",
|
||||
"text-13": size === "md",
|
||||
|
|
@ -129,7 +129,7 @@ const TabsIndicator = React.forwardRef(function TabsIndicator(
|
|||
return (
|
||||
<div
|
||||
className={cn(
|
||||
"absolute left-0 top-[50%] z-[-1] h-6 w-[var(--active-tab-width)] translate-x-[var(--active-tab-left)] -translate-y-[50%] rounded-xs bg-surface-1 shadow-sm transition-[width,transform] duration-200 ease-in-out",
|
||||
"shadow-sm absolute top-[50%] left-0 z-[-1] h-6 w-[var(--active-tab-width)] translate-x-[var(--active-tab-left)] -translate-y-[50%] rounded-xs bg-surface-1 transition-[width,transform] duration-200 ease-in-out",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
|
|
|
|||
|
|
@ -28,10 +28,10 @@ export const Provider: Story = {
|
|||
<div>
|
||||
<Toast theme="light" />
|
||||
<div className="space-y-2">
|
||||
<p className="text-13 text-gray-600">
|
||||
<p className="text-gray-600 text-13">
|
||||
Toast provider is required to display toasts. It should be added to your app root.
|
||||
</p>
|
||||
<code className="block rounded-sm bg-gray-100 p-2 text-11">{`<Toast theme="light" />`}</code>
|
||||
<code className="bg-gray-100 block rounded-sm p-2 text-11">{`<Toast theme="light" />`}</code>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
@ -138,7 +138,7 @@ export const Loading: Story = {
|
|||
title: "Loading...",
|
||||
})
|
||||
}
|
||||
className="rounded-sm bg-layer-2 border border-subtle px-4 py-2 text-13 text-primary hover:bg-layer-1"
|
||||
className="rounded-sm border border-subtle bg-layer-2 px-4 py-2 text-13 text-primary hover:bg-layer-1"
|
||||
>
|
||||
Show Loading Toast
|
||||
</button>
|
||||
|
|
@ -303,7 +303,7 @@ export const AllTypes: Story = {
|
|||
title: "Loading",
|
||||
})
|
||||
}
|
||||
className="rounded-sm bg-layer-2 border border-subtle px-3 py-2 text-13 text-primary hover:bg-layer-1"
|
||||
className="rounded-sm border border-subtle bg-layer-2 px-3 py-2 text-13 text-primary hover:bg-layer-1"
|
||||
>
|
||||
Loading
|
||||
</button>
|
||||
|
|
@ -400,7 +400,7 @@ export const StaticVariants: Story = {
|
|||
return (
|
||||
<div className="grid grid-cols-1 gap-4">
|
||||
<div>
|
||||
<p className="text-13 text-secondary mb-2 font-medium">All toast variants (static):</p>
|
||||
<p className="mb-2 text-13 font-medium text-secondary">All toast variants (static):</p>
|
||||
</div>
|
||||
<div className="flex flex-col gap-3">
|
||||
<ToastStatic type={TOAST_TYPE.SUCCESS} title="Success" message="Your changes have been saved successfully." />
|
||||
|
|
@ -483,8 +483,8 @@ export const StaticWithActions: Story = {
|
|||
export const StaticDarkMode: Story = {
|
||||
render() {
|
||||
return (
|
||||
<div className="flex flex-col gap-3 p-6 bg-canvas rounded-lg" data-theme="dark">
|
||||
<p className="text-13 text-secondary mb-2 font-medium">Toast variants in dark mode:</p>
|
||||
<div className="flex flex-col gap-3 rounded-lg bg-canvas p-6" data-theme="dark">
|
||||
<p className="mb-2 text-13 font-medium text-secondary">Toast variants in dark mode:</p>
|
||||
<ToastStatic
|
||||
type={TOAST_TYPE.SUCCESS}
|
||||
title="Success"
|
||||
|
|
@ -507,99 +507,99 @@ export const DesignTokens: Story = {
|
|||
return (
|
||||
<div className="space-y-6">
|
||||
<div>
|
||||
<h2 className="text-16 font-semibold text-primary mb-2">Toast Design Tokens</h2>
|
||||
<h2 className="mb-2 text-16 font-semibold text-primary">Toast Design Tokens</h2>
|
||||
<p className="text-13 text-secondary">
|
||||
The toast component uses semantic design tokens from the Plane design system.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 className="text-14 font-semibold text-primary mb-3">Token Mapping by Variant</h3>
|
||||
<h3 className="mb-3 text-14 font-semibold text-primary">Token Mapping by Variant</h3>
|
||||
<div className="overflow-x-auto">
|
||||
<table className="w-full text-11 border border-subtle rounded-lg">
|
||||
<table className="w-full rounded-lg border border-subtle text-11">
|
||||
<thead>
|
||||
<tr className="bg-layer-1">
|
||||
<th className="text-left px-3 py-2 font-semibold text-primary border-b border-subtle">Variant</th>
|
||||
<th className="text-left px-3 py-2 font-semibold text-primary border-b border-subtle">Title Text</th>
|
||||
<th className="text-left px-3 py-2 font-semibold text-primary border-b border-subtle">Icon BG</th>
|
||||
<th className="text-left px-3 py-2 font-semibold text-primary border-b border-subtle">Toast BG</th>
|
||||
<th className="text-left px-3 py-2 font-semibold text-primary border-b border-subtle">Border</th>
|
||||
<th className="border-b border-subtle px-3 py-2 text-left font-semibold text-primary">Variant</th>
|
||||
<th className="border-b border-subtle px-3 py-2 text-left font-semibold text-primary">Title Text</th>
|
||||
<th className="border-b border-subtle px-3 py-2 text-left font-semibold text-primary">Icon BG</th>
|
||||
<th className="border-b border-subtle px-3 py-2 text-left font-semibold text-primary">Toast BG</th>
|
||||
<th className="border-b border-subtle px-3 py-2 text-left font-semibold text-primary">Border</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr className="border-b border-subtle">
|
||||
<td className="px-3 py-2 font-medium text-primary">Success</td>
|
||||
<td className="px-3 py-2">
|
||||
<code className="text-10 bg-layer-1 px-1.5 py-0.5 rounded">text-primary</code>
|
||||
<code className="rounded bg-layer-1 px-1.5 py-0.5 text-10">text-primary</code>
|
||||
</td>
|
||||
<td className="px-3 py-2">
|
||||
<code className="text-10 bg-layer-1 px-1.5 py-0.5 rounded">bg-success-primary</code>
|
||||
<code className="rounded bg-layer-1 px-1.5 py-0.5 text-10">bg-success-primary</code>
|
||||
</td>
|
||||
<td className="px-3 py-2">
|
||||
<code className="text-10 bg-layer-1 px-1.5 py-0.5 rounded">bg-surface-1</code>
|
||||
<code className="rounded bg-layer-1 px-1.5 py-0.5 text-10">bg-surface-1</code>
|
||||
</td>
|
||||
<td className="px-3 py-2">
|
||||
<code className="text-10 bg-layer-1 px-1.5 py-0.5 rounded">border-subtle</code>
|
||||
<code className="rounded bg-layer-1 px-1.5 py-0.5 text-10">border-subtle</code>
|
||||
</td>
|
||||
</tr>
|
||||
<tr className="border-b border-subtle">
|
||||
<td className="px-3 py-2 font-medium text-primary">Error</td>
|
||||
<td className="px-3 py-2">
|
||||
<code className="text-10 bg-layer-1 px-1.5 py-0.5 rounded">text-primary</code>
|
||||
<code className="rounded bg-layer-1 px-1.5 py-0.5 text-10">text-primary</code>
|
||||
</td>
|
||||
<td className="px-3 py-2">
|
||||
<code className="text-10 bg-layer-1 px-1.5 py-0.5 rounded">bg-danger-primary</code>
|
||||
<code className="rounded bg-layer-1 px-1.5 py-0.5 text-10">bg-danger-primary</code>
|
||||
</td>
|
||||
<td className="px-3 py-2">
|
||||
<code className="text-10 bg-layer-1 px-1.5 py-0.5 rounded">bg-surface-1</code>
|
||||
<code className="rounded bg-layer-1 px-1.5 py-0.5 text-10">bg-surface-1</code>
|
||||
</td>
|
||||
<td className="px-3 py-2">
|
||||
<code className="text-10 bg-layer-1 px-1.5 py-0.5 rounded">border-subtle</code>
|
||||
<code className="rounded bg-layer-1 px-1.5 py-0.5 text-10">border-subtle</code>
|
||||
</td>
|
||||
</tr>
|
||||
<tr className="border-b border-subtle">
|
||||
<td className="px-3 py-2 font-medium text-primary">Warning</td>
|
||||
<td className="px-3 py-2">
|
||||
<code className="text-10 bg-layer-1 px-1.5 py-0.5 rounded">text-primary</code>
|
||||
<code className="rounded bg-layer-1 px-1.5 py-0.5 text-10">text-primary</code>
|
||||
</td>
|
||||
<td className="px-3 py-2">
|
||||
<code className="text-10 bg-layer-1 px-1.5 py-0.5 rounded">bg-warning-primary</code>
|
||||
<code className="rounded bg-layer-1 px-1.5 py-0.5 text-10">bg-warning-primary</code>
|
||||
</td>
|
||||
<td className="px-3 py-2">
|
||||
<code className="text-10 bg-layer-1 px-1.5 py-0.5 rounded">bg-surface-1</code>
|
||||
<code className="rounded bg-layer-1 px-1.5 py-0.5 text-10">bg-surface-1</code>
|
||||
</td>
|
||||
<td className="px-3 py-2">
|
||||
<code className="text-10 bg-layer-1 px-1.5 py-0.5 rounded">border-subtle</code>
|
||||
<code className="rounded bg-layer-1 px-1.5 py-0.5 text-10">border-subtle</code>
|
||||
</td>
|
||||
</tr>
|
||||
<tr className="border-b border-subtle">
|
||||
<td className="px-3 py-2 font-medium text-primary">Info</td>
|
||||
<td className="px-3 py-2">
|
||||
<code className="text-10 bg-layer-1 px-1.5 py-0.5 rounded">text-primary</code>
|
||||
<code className="rounded bg-layer-1 px-1.5 py-0.5 text-10">text-primary</code>
|
||||
</td>
|
||||
<td className="px-3 py-2">
|
||||
<code className="text-10 bg-layer-1 px-1.5 py-0.5 rounded">bg-accent-primary</code>
|
||||
<code className="rounded bg-layer-1 px-1.5 py-0.5 text-10">bg-accent-primary</code>
|
||||
</td>
|
||||
<td className="px-3 py-2">
|
||||
<code className="text-10 bg-layer-1 px-1.5 py-0.5 rounded">bg-surface-1</code>
|
||||
<code className="rounded bg-layer-1 px-1.5 py-0.5 text-10">bg-surface-1</code>
|
||||
</td>
|
||||
<td className="px-3 py-2">
|
||||
<code className="text-10 bg-layer-1 px-1.5 py-0.5 rounded">border-subtle</code>
|
||||
<code className="rounded bg-layer-1 px-1.5 py-0.5 text-10">border-subtle</code>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="px-3 py-2 font-medium text-primary">Loading</td>
|
||||
<td className="px-3 py-2">
|
||||
<code className="text-10 bg-layer-1 px-1.5 py-0.5 rounded">text-primary</code>
|
||||
<code className="rounded bg-layer-1 px-1.5 py-0.5 text-10">text-primary</code>
|
||||
</td>
|
||||
<td className="px-3 py-2">
|
||||
<code className="text-10 bg-layer-1 px-1.5 py-0.5 rounded">bg-layer-2</code>
|
||||
<code className="rounded bg-layer-1 px-1.5 py-0.5 text-10">bg-layer-2</code>
|
||||
</td>
|
||||
<td className="px-3 py-2">
|
||||
<code className="text-10 bg-layer-1 px-1.5 py-0.5 rounded">bg-surface-1</code>
|
||||
<code className="rounded bg-layer-1 px-1.5 py-0.5 text-10">bg-surface-1</code>
|
||||
</td>
|
||||
<td className="px-3 py-2">
|
||||
<code className="text-10 bg-layer-1 px-1.5 py-0.5 rounded">border-subtle</code>
|
||||
<code className="rounded bg-layer-1 px-1.5 py-0.5 text-10">border-subtle</code>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
|
@ -609,29 +609,29 @@ export const DesignTokens: Story = {
|
|||
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
<div>
|
||||
<h3 className="text-14 font-semibold text-primary mb-3">Typography</h3>
|
||||
<h3 className="mb-3 text-14 font-semibold text-primary">Typography</h3>
|
||||
<ul className="space-y-2 text-12 text-secondary">
|
||||
<li>
|
||||
<span className="font-medium text-primary">Title:</span>{" "}
|
||||
<code className="text-10 bg-layer-1 px-1.5 py-0.5 rounded">text-14 font-semibold</code>
|
||||
<code className="rounded bg-layer-1 px-1.5 py-0.5 text-10">text-14 font-semibold</code>
|
||||
</li>
|
||||
<li>
|
||||
<span className="font-medium text-primary">Message:</span>{" "}
|
||||
<code className="text-10 bg-layer-1 px-1.5 py-0.5 rounded">text-13</code>
|
||||
<code className="rounded bg-layer-1 px-1.5 py-0.5 text-10">text-13</code>
|
||||
</li>
|
||||
<li>
|
||||
<span className="font-medium text-primary">Message Color:</span>{" "}
|
||||
<code className="text-10 bg-layer-1 px-1.5 py-0.5 rounded">text-secondary</code>
|
||||
<code className="rounded bg-layer-1 px-1.5 py-0.5 text-10">text-secondary</code>
|
||||
</li>
|
||||
<li>
|
||||
<span className="font-medium text-primary">Action Button:</span>{" "}
|
||||
<code className="text-10 bg-layer-1 px-1.5 py-0.5 rounded">text-13 font-medium</code>
|
||||
<code className="rounded bg-layer-1 px-1.5 py-0.5 text-10">text-13 font-medium</code>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 className="text-14 font-semibold text-primary mb-3">Dimensions & Styling</h3>
|
||||
<h3 className="mb-3 text-14 font-semibold text-primary">Dimensions & Styling</h3>
|
||||
<ul className="space-y-2 text-12 text-secondary">
|
||||
<li>
|
||||
<span className="font-medium text-primary">Width:</span> 350px
|
||||
|
|
@ -644,7 +644,7 @@ export const DesignTokens: Story = {
|
|||
</li>
|
||||
<li>
|
||||
<span className="font-medium text-primary">Shadow:</span>{" "}
|
||||
<code className="text-10 bg-layer-1 px-1.5 py-0.5 rounded">shadow-raised-200</code>
|
||||
<code className="rounded bg-layer-1 px-1.5 py-0.5 text-10">shadow-raised-200</code>
|
||||
</li>
|
||||
<li>
|
||||
<span className="font-medium text-primary">Border Width:</span> 1px
|
||||
|
|
@ -654,7 +654,7 @@ export const DesignTokens: Story = {
|
|||
</div>
|
||||
|
||||
<div>
|
||||
<h3 className="text-14 font-semibold text-primary mb-3">Icon Specifications</h3>
|
||||
<h3 className="mb-3 text-14 font-semibold text-primary">Icon Specifications</h3>
|
||||
<ul className="space-y-2 text-12 text-secondary">
|
||||
<li>
|
||||
<span className="font-medium text-primary">Icon Size:</span> 20x20px
|
||||
|
|
@ -668,11 +668,11 @@ export const DesignTokens: Story = {
|
|||
</li>
|
||||
<li>
|
||||
<span className="font-medium text-primary">Icon Color:</span>{" "}
|
||||
<code className="text-10 bg-layer-1 px-1.5 py-0.5 rounded">text-on-color</code>
|
||||
<code className="rounded bg-layer-1 px-1.5 py-0.5 text-10">text-on-color</code>
|
||||
</li>
|
||||
<li>
|
||||
<span className="font-medium text-primary">Icon Background:</span>{" "}
|
||||
<code className="text-10 bg-layer-1 px-1.5 py-0.5 rounded">
|
||||
<code className="rounded bg-layer-1 px-1.5 py-0.5 text-10">
|
||||
bg-{"{"}variant{"}"}-primary
|
||||
</code>
|
||||
</li>
|
||||
|
|
@ -681,16 +681,16 @@ export const DesignTokens: Story = {
|
|||
</li>
|
||||
<li>
|
||||
<span className="font-medium text-primary">Close Icon Color:</span>{" "}
|
||||
<code className="text-10 bg-layer-1 px-1.5 py-0.5 rounded">
|
||||
<code className="rounded bg-layer-1 px-1.5 py-0.5 text-10">
|
||||
text-icon-secondary hover:text-icon-tertiary
|
||||
</code>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div className="bg-layer-1 p-4 rounded-lg">
|
||||
<h3 className="text-14 font-semibold text-primary mb-2">Visual Examples</h3>
|
||||
<p className="text-12 text-secondary mb-4">See how the tokens are applied across all toast variants:</p>
|
||||
<div className="rounded-lg bg-layer-1 p-4">
|
||||
<h3 className="mb-2 text-14 font-semibold text-primary">Visual Examples</h3>
|
||||
<p className="mb-4 text-12 text-secondary">See how the tokens are applied across all toast variants:</p>
|
||||
<div className="flex flex-col gap-3">
|
||||
<ToastStatic
|
||||
type={TOAST_TYPE.SUCCESS}
|
||||
|
|
|
|||
|
|
@ -122,9 +122,9 @@ function ToastRender({ id, toast }: { id: React.Key; toast: BaseToast.Root.Toast
|
|||
key={id}
|
||||
className={cn(
|
||||
// Base layout and positioning
|
||||
"flex group items-center rounded-lg border shadow-raised-200 w-[350px]",
|
||||
"group flex w-[350px] items-center rounded-lg border shadow-raised-200",
|
||||
"absolute right-3 bottom-3 z-[calc(1000-var(--toast-index))]",
|
||||
"select-none transition-[opacity,transform] duration-500 ease-[cubic-bezier(0.22,1,0.36,1)]",
|
||||
"ease-[cubic-bezier(0.22,1,0.36,1)] transition-[opacity,transform] duration-500 select-none",
|
||||
|
||||
// Default transform with stacking and scaling
|
||||
"[transform:translateX(var(--toast-swipe-movement-x))_translateY(calc(var(--toast-swipe-movement-y)+calc(min(var(--toast-index),10)*-10px)))_scale(calc(max(0,1-(var(--toast-index)*0.1))))]",
|
||||
|
|
@ -163,20 +163,20 @@ function ToastRender({ id, toast }: { id: React.Key; toast: BaseToast.Root.Toast
|
|||
e.preventDefault();
|
||||
}}
|
||||
>
|
||||
<BaseToast.Close className="absolute top-3 right-3 text-icon-secondary hover:text-icon-tertiary cursor-pointer">
|
||||
<BaseToast.Close className="absolute top-3 right-3 cursor-pointer text-icon-secondary hover:text-icon-tertiary">
|
||||
<CloseIcon strokeWidth={1.5} width={16} height={16} />
|
||||
</BaseToast.Close>
|
||||
<div className="flex items-start gap-2 w-full p-4">
|
||||
<div className="flex w-full items-start gap-2 p-4">
|
||||
<div className="py-1">
|
||||
{data.icon && (
|
||||
<div
|
||||
className={cn("flex items-center justify-center rounded-full size-4 flex-shrink-0", data.iconBgClassName)}
|
||||
className={cn("flex size-4 flex-shrink-0 items-center justify-center rounded-full", data.iconBgClassName)}
|
||||
>
|
||||
{data.icon}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex flex-col gap-1 flex-1 min-w-0">
|
||||
<div className="flex min-w-0 flex-1 flex-col gap-1">
|
||||
<BaseToast.Title className="text-h6-medium text-primary">
|
||||
{toastData.type === TOAST_TYPE.LOADING ? (toastData.title ?? "Loading...") : toastData.title}
|
||||
</BaseToast.Title>
|
||||
|
|
@ -211,21 +211,21 @@ export function ToastStatic({ type, title, message, actionItems, theme = "light"
|
|||
<div
|
||||
className={cn(
|
||||
// Base layout and positioning
|
||||
"flex group items-start rounded-lg border border-subtle-1 rounded-lg shadow-overlay-100 w-[350px]",
|
||||
"group flex w-[350px] items-start rounded-lg border border-subtle-1 shadow-overlay-100",
|
||||
"relative",
|
||||
data.backgroundColorClassName,
|
||||
data.borderColorClassName
|
||||
)}
|
||||
>
|
||||
<div className="absolute top-1 right-1 text-icon-tertiary cursor-default">
|
||||
<div className="absolute top-1 right-1 cursor-default text-icon-tertiary">
|
||||
<CloseIcon strokeWidth={1.5} width={14} height={14} />
|
||||
</div>
|
||||
<div className="flex items-start gap-3 w-full p-4">
|
||||
<div className="flex w-full items-start gap-3 p-4">
|
||||
<div className="py-1">
|
||||
{data.icon && (
|
||||
<div
|
||||
className={cn(
|
||||
"flex items-center justify-center rounded-full size-4 flex-shrink-0",
|
||||
"flex size-4 flex-shrink-0 items-center justify-center rounded-full",
|
||||
data.iconBgClassName
|
||||
)}
|
||||
>
|
||||
|
|
@ -233,7 +233,7 @@ export function ToastStatic({ type, title, message, actionItems, theme = "light"
|
|||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex flex-col gap-1 flex-1 min-w-0">
|
||||
<div className="flex min-w-0 flex-1 flex-col gap-1">
|
||||
<div className="text-h6-medium text-primary">
|
||||
{type === TOAST_TYPE.LOADING ? (title ?? "Loading...") : title}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -41,8 +41,8 @@ type Story = StoryObj<typeof meta>;
|
|||
export const Default: Story = {
|
||||
render() {
|
||||
return (
|
||||
<div className="p-4 space-y-4">
|
||||
<div className="w-96 border rounded-sm">
|
||||
<div className="space-y-4 p-4">
|
||||
<div className="w-96 rounded-sm border">
|
||||
<Toolbar>
|
||||
<Toolbar.Group isFirst>
|
||||
<Toolbar.Item icon={Undo} tooltip="Undo" />
|
||||
|
|
@ -104,7 +104,7 @@ export const WithActiveStates: Story = {
|
|||
export const CommentToolbar: Story = {
|
||||
render() {
|
||||
return (
|
||||
<div className="p-4 space-y-4">
|
||||
<div className="space-y-4 p-4">
|
||||
<h3 className="text-13 font-medium">Comment Toolbar with Access Control</h3>
|
||||
<div className="rounded-sm border-[0.5px] border-subtle p-1">
|
||||
<Toolbar>
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ const ToolbarRoot = React.forwardRef(function ToolbarRoot(
|
|||
return (
|
||||
<div
|
||||
ref={ref}
|
||||
className={cn("flex h-9 w-full items-stretch gap-1.5 bg-surface-2 overflow-x-scroll", className)}
|
||||
className={cn("flex h-9 w-full items-stretch gap-1.5 overflow-x-scroll bg-surface-2", className)}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
|
|
@ -86,7 +86,7 @@ const ToolbarItem = React.forwardRef(function ToolbarItem(
|
|||
ref={ref}
|
||||
type="button"
|
||||
className={cn(
|
||||
"grid place-items-center aspect-square rounded-xs p-0.5 text-placeholder hover:bg-layer-1 transition-colors",
|
||||
"grid aspect-square place-items-center rounded-xs p-0.5 text-placeholder transition-colors hover:bg-layer-1",
|
||||
{
|
||||
"bg-layer-1 text-primary": isActive,
|
||||
},
|
||||
|
|
@ -126,7 +126,7 @@ const ToolbarSeparator = React.forwardRef(function ToolbarSeparator(
|
|||
{ className, ...props }: ToolbarSeparatorProps,
|
||||
ref: React.ForwardedRef<HTMLDivElement>
|
||||
) {
|
||||
return <div ref={ref} className={cn("h-full w-px bg-subtle-1 mx-1", className)} {...props} />;
|
||||
return <div ref={ref} className={cn("bg-subtle-1 mx-1 h-full w-px", className)} {...props} />;
|
||||
});
|
||||
|
||||
const buttonVariants = {
|
||||
|
|
@ -148,8 +148,8 @@ const ToolbarSubmitButton = React.forwardRef(function ToolbarSubmitButton(
|
|||
ref={ref}
|
||||
className={cn(
|
||||
"inline-flex items-center justify-center gap-2 rounded-md px-2.5 py-1.5 text-11 font-medium transition-colors duration-200",
|
||||
"focus:outline-none focus:ring-2 focus:ring-accent-strong/20 focus:ring-offset-2",
|
||||
"disabled:opacity-50 disabled:pointer-events-none",
|
||||
"focus:ring-2 focus:ring-accent-strong/20 focus:ring-offset-2 focus:outline-none",
|
||||
"disabled:pointer-events-none disabled:opacity-50",
|
||||
buttonVariants[variant],
|
||||
className
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ export function Tooltip(props: ITooltipProps) {
|
|||
<BaseTooltip.Portal>
|
||||
<BaseTooltip.Positioner
|
||||
className={cn(
|
||||
"z-50 max-w-xs gap-1 overflow-hidden break-words rounded-lg border border-subtle-1 bg-layer-2 px-2 py-1.5 shadow-overlay-200",
|
||||
"z-50 max-w-xs gap-1 overflow-hidden rounded-lg border border-subtle-1 bg-layer-2 px-2 py-1.5 break-words shadow-overlay-200",
|
||||
{
|
||||
hidden: isMobile,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ type Story = StoryObj<typeof meta>;
|
|||
export const Default: Story = {
|
||||
args: {
|
||||
tooltipContent: "This is a tooltip",
|
||||
children: <button className="rounded-sm bg-blue-500 px-4 py-2 text-on-color">Hover me</button>,
|
||||
children: <button className="bg-blue-500 rounded-sm px-4 py-2 text-on-color">Hover me</button>,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
@ -31,7 +31,7 @@ export const WithHeading: Story = {
|
|||
args: {
|
||||
tooltipHeading: "Tooltip Title",
|
||||
tooltipContent: "This is the tooltip content with a heading.",
|
||||
children: <button className="rounded-sm bg-blue-500 px-4 py-2 text-on-color">Hover me</button>,
|
||||
children: <button className="bg-blue-500 rounded-sm px-4 py-2 text-on-color">Hover me</button>,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
@ -39,7 +39,7 @@ export const PositionTop: Story = {
|
|||
args: {
|
||||
tooltipContent: "Tooltip on top",
|
||||
position: "top",
|
||||
children: <button className="rounded-sm bg-blue-500 px-4 py-2 text-on-color">Top</button>,
|
||||
children: <button className="bg-blue-500 rounded-sm px-4 py-2 text-on-color">Top</button>,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
@ -47,7 +47,7 @@ export const PositionBottom: Story = {
|
|||
args: {
|
||||
tooltipContent: "Tooltip on bottom",
|
||||
position: "bottom",
|
||||
children: <button className="rounded-sm bg-blue-500 px-4 py-2 text-on-color">Bottom</button>,
|
||||
children: <button className="bg-blue-500 rounded-sm px-4 py-2 text-on-color">Bottom</button>,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
@ -55,7 +55,7 @@ export const PositionLeft: Story = {
|
|||
args: {
|
||||
tooltipContent: "Tooltip on left",
|
||||
position: "left",
|
||||
children: <button className="rounded-sm bg-blue-500 px-4 py-2 text-on-color">Left</button>,
|
||||
children: <button className="bg-blue-500 rounded-sm px-4 py-2 text-on-color">Left</button>,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
@ -63,7 +63,7 @@ export const PositionRight: Story = {
|
|||
args: {
|
||||
tooltipContent: "Tooltip on right",
|
||||
position: "right",
|
||||
children: <button className="rounded-sm bg-blue-500 px-4 py-2 text-on-color">Right</button>,
|
||||
children: <button className="bg-blue-500 rounded-sm px-4 py-2 text-on-color">Right</button>,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
@ -71,8 +71,8 @@ export const WithIcon: Story = {
|
|||
args: {
|
||||
tooltipContent: "Click here for help",
|
||||
children: (
|
||||
<button className="rounded-full p-2 hover:bg-gray-100">
|
||||
<HelpCircle className="h-5 w-5 text-gray-600" />
|
||||
<button className="hover:bg-gray-100 rounded-full p-2">
|
||||
<HelpCircle className="text-gray-600 h-5 w-5" />
|
||||
</button>
|
||||
),
|
||||
},
|
||||
|
|
@ -82,7 +82,7 @@ export const Disabled: Story = {
|
|||
args: {
|
||||
tooltipContent: "This tooltip is disabled",
|
||||
disabled: true,
|
||||
children: <button className="rounded-sm bg-gray-400 px-4 py-2 text-on-color">Hover me (disabled)</button>,
|
||||
children: <button className="bg-gray-400 rounded-sm px-4 py-2 text-on-color">Hover me (disabled)</button>,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
@ -91,7 +91,7 @@ export const LongContent: Story = {
|
|||
tooltipHeading: "Important Information",
|
||||
tooltipContent:
|
||||
"This is a longer tooltip with more detailed information that wraps to multiple lines. It provides comprehensive details about the element.",
|
||||
children: <button className="rounded-sm bg-blue-500 px-4 py-2 text-on-color">Long content</button>,
|
||||
children: <button className="bg-blue-500 rounded-sm px-4 py-2 text-on-color">Long content</button>,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
@ -99,7 +99,7 @@ export const CustomDelay: Story = {
|
|||
args: {
|
||||
tooltipContent: "This tooltip has a custom delay",
|
||||
openDelay: 1000,
|
||||
children: <button className="rounded-sm bg-blue-500 px-4 py-2 text-on-color">Custom delay (1s)</button>,
|
||||
children: <button className="bg-blue-500 rounded-sm px-4 py-2 text-on-color">Custom delay (1s)</button>,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
@ -107,7 +107,7 @@ export const CustomOffset: Story = {
|
|||
args: {
|
||||
tooltipContent: "Custom offset tooltip",
|
||||
sideOffset: 20,
|
||||
children: <button className="rounded-sm bg-blue-500 px-4 py-2 text-on-color">Custom offset</button>,
|
||||
children: <button className="bg-blue-500 rounded-sm px-4 py-2 text-on-color">Custom offset</button>,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
@ -119,18 +119,18 @@ export const AllPositions: Story = {
|
|||
return (
|
||||
<div className="flex flex-col items-center gap-4">
|
||||
<Tooltip tooltipContent="Top position" position="top">
|
||||
<button className="rounded-sm bg-blue-500 px-4 py-2 text-13 text-on-color">Top</button>
|
||||
<button className="bg-blue-500 rounded-sm px-4 py-2 text-13 text-on-color">Top</button>
|
||||
</Tooltip>
|
||||
<div className="flex gap-4">
|
||||
<Tooltip tooltipContent="Left position" position="left">
|
||||
<button className="rounded-sm bg-blue-500 px-4 py-2 text-13 text-on-color">Left</button>
|
||||
<button className="bg-blue-500 rounded-sm px-4 py-2 text-13 text-on-color">Left</button>
|
||||
</Tooltip>
|
||||
<Tooltip tooltipContent="Right position" position="right">
|
||||
<button className="rounded-sm bg-blue-500 px-4 py-2 text-13 text-on-color">Right</button>
|
||||
<button className="bg-blue-500 rounded-sm px-4 py-2 text-13 text-on-color">Right</button>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<Tooltip tooltipContent="Bottom position" position="bottom">
|
||||
<button className="rounded-sm bg-blue-500 px-4 py-2 text-13 text-on-color">Bottom</button>
|
||||
<button className="bg-blue-500 rounded-sm px-4 py-2 text-13 text-on-color">Bottom</button>
|
||||
</Tooltip>
|
||||
</div>
|
||||
);
|
||||
|
|
@ -143,10 +143,10 @@ export const OnText: Story = {
|
|||
},
|
||||
render() {
|
||||
return (
|
||||
<p className="text-13 text-gray-700">
|
||||
<p className="text-gray-700 text-13">
|
||||
This is some text with a{" "}
|
||||
<Tooltip tooltipContent="Additional information about this word" position="top">
|
||||
<span className="cursor-help border-b border-dashed border-blue-500 text-blue-500">tooltip</span>
|
||||
<span className="border-blue-500 text-blue-500 cursor-help border-b border-dashed">tooltip</span>
|
||||
</Tooltip>{" "}
|
||||
in it.
|
||||
</p>
|
||||
|
|
@ -161,7 +161,7 @@ export const OnDisabledButton: Story = {
|
|||
render() {
|
||||
return (
|
||||
<Tooltip tooltipContent="This feature is currently unavailable" position="top">
|
||||
<button className="cursor-not-allowed rounded-sm bg-gray-300 px-4 py-2 text-gray-500" disabled>
|
||||
<button className="bg-gray-300 text-gray-500 cursor-not-allowed rounded-sm px-4 py-2" disabled>
|
||||
Disabled Button
|
||||
</button>
|
||||
</Tooltip>
|
||||
|
|
@ -176,10 +176,10 @@ export const ComplexContent: Story = {
|
|||
<div className="space-y-1">
|
||||
<p className="font-semibold">John Doe</p>
|
||||
<p className="text-11">john@example.com</p>
|
||||
<p className="text-11 text-gray-400">Last seen: 2 hours ago</p>
|
||||
<p className="text-gray-400 text-11">Last seen: 2 hours ago</p>
|
||||
</div>
|
||||
),
|
||||
children: <button className="rounded-sm bg-blue-500 px-4 py-2 text-on-color">View User</button>,
|
||||
children: <button className="bg-blue-500 rounded-sm px-4 py-2 text-on-color">View User</button>,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
@ -187,7 +187,7 @@ export const WithCustomStyling: Story = {
|
|||
args: {
|
||||
tooltipContent: "Custom styled tooltip",
|
||||
className: "bg-purple-500 text-on-color",
|
||||
children: <button className="rounded-sm bg-purple-500 px-4 py-2 text-on-color">Custom style</button>,
|
||||
children: <button className="bg-purple-500 rounded-sm px-4 py-2 text-on-color">Custom style</button>,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
@ -199,16 +199,16 @@ export const MultipleTooltips: Story = {
|
|||
return (
|
||||
<div className="flex gap-4">
|
||||
<Tooltip tooltipContent="Save your work" position="top">
|
||||
<button className="rounded-sm bg-green-500 px-4 py-2 text-13 text-on-color">Save</button>
|
||||
<button className="bg-green-500 rounded-sm px-4 py-2 text-13 text-on-color">Save</button>
|
||||
</Tooltip>
|
||||
<Tooltip tooltipContent="Discard changes" position="top">
|
||||
<button className="rounded-sm bg-red-500 px-4 py-2 text-13 text-on-color">Cancel</button>
|
||||
<button className="bg-red-500 rounded-sm px-4 py-2 text-13 text-on-color">Cancel</button>
|
||||
</Tooltip>
|
||||
<Tooltip tooltipContent="Export to PDF" position="top">
|
||||
<button className="rounded-sm bg-blue-500 px-4 py-2 text-13 text-on-color">Export</button>
|
||||
<button className="bg-blue-500 rounded-sm px-4 py-2 text-13 text-on-color">Export</button>
|
||||
</Tooltip>
|
||||
<Tooltip tooltipContent="Share with team" position="top">
|
||||
<button className="rounded-sm bg-purple-500 px-4 py-2 text-13 text-on-color">Share</button>
|
||||
<button className="bg-purple-500 rounded-sm px-4 py-2 text-13 text-on-color">Share</button>
|
||||
</Tooltip>
|
||||
</div>
|
||||
);
|
||||
|
|
@ -223,9 +223,9 @@ export const IconButtons: Story = {
|
|||
return (
|
||||
<div className="flex gap-2">
|
||||
<Tooltip tooltipContent="Edit" position="top">
|
||||
<button className="rounded-sm p-2 hover:bg-gray-100">
|
||||
<button className="hover:bg-gray-100 rounded-sm p-2">
|
||||
<svg
|
||||
className="h-5 w-5 text-gray-600"
|
||||
className="text-gray-600 h-5 w-5"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
|
|
@ -241,7 +241,7 @@ export const IconButtons: Story = {
|
|||
</button>
|
||||
</Tooltip>
|
||||
<Tooltip tooltipContent="Delete" position="top">
|
||||
<button className="rounded-sm p-2 hover:bg-gray-100">
|
||||
<button className="hover:bg-gray-100 rounded-sm p-2">
|
||||
<svg
|
||||
className="h-5 w-5 text-danger-primary"
|
||||
fill="none"
|
||||
|
|
@ -259,9 +259,9 @@ export const IconButtons: Story = {
|
|||
</button>
|
||||
</Tooltip>
|
||||
<Tooltip tooltipContent="Share" position="top">
|
||||
<button className="rounded-sm p-2 hover:bg-gray-100">
|
||||
<button className="hover:bg-gray-100 rounded-sm p-2">
|
||||
<svg
|
||||
className="h-5 w-5 text-blue-600"
|
||||
className="text-blue-600 h-5 w-5"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
|
|
@ -288,19 +288,19 @@ export const InFormField: Story = {
|
|||
render() {
|
||||
return (
|
||||
<div className="w-80">
|
||||
<label className="mb-1 flex items-center gap-2 text-13 font-medium text-gray-700">
|
||||
<label className="text-gray-700 mb-1 flex items-center gap-2 text-13 font-medium">
|
||||
Email Address
|
||||
<Tooltip
|
||||
tooltipHeading="Email Requirements"
|
||||
tooltipContent="Enter a valid email address that you have access to. We'll send a verification link."
|
||||
position="right"
|
||||
>
|
||||
<HelpCircle className="h-4 w-4 cursor-help text-gray-400" />
|
||||
<HelpCircle className="text-gray-400 h-4 w-4 cursor-help" />
|
||||
</Tooltip>
|
||||
</label>
|
||||
<input
|
||||
type="email"
|
||||
className="w-full rounded-sm border border-gray-300 px-3 py-2 text-13"
|
||||
className="border-gray-300 w-full rounded-sm border px-3 py-2 text-13"
|
||||
placeholder="you@example.com"
|
||||
/>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue