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,14 +4,21 @@
|
|||
"private": true,
|
||||
"license": "AGPL-3.0",
|
||||
"type": "module",
|
||||
"main": "./dist/index.mjs",
|
||||
"module": "./dist/index.mjs",
|
||||
"types": "./dist/index.d.mts",
|
||||
"exports": {
|
||||
".": "./dist/index.mjs",
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "tsdown --watch",
|
||||
"build": "tsdown",
|
||||
"check:lint": "eslint . --cache --cache-location node_modules/.cache/eslint/ --max-warnings=30",
|
||||
"check:types": "tsc --noEmit",
|
||||
"check:format": "prettier . --cache --check",
|
||||
"check:format": "oxfmt --check .",
|
||||
"fix:lint": "eslint . --cache --cache-location node_modules/.cache/eslint/ --fix --max-warnings=30",
|
||||
"fix:format": "prettier . --cache --write",
|
||||
"fix:format": "oxfmt .",
|
||||
"clean": "rm -rf .turbo && rm -rf .next && rm -rf node_modules && rm -rf dist"
|
||||
},
|
||||
"dependencies": {
|
||||
|
|
@ -23,12 +30,5 @@
|
|||
"@types/react": "catalog:",
|
||||
"tsdown": "catalog:",
|
||||
"typescript": "catalog:"
|
||||
},
|
||||
"main": "./dist/index.mjs",
|
||||
"module": "./dist/index.mjs",
|
||||
"types": "./dist/index.d.mts",
|
||||
"exports": {
|
||||
".": "./dist/index.mjs",
|
||||
"./package.json": "./package.json"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,13 @@
|
|||
{
|
||||
"name": "@plane/decorators",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"description": "Controller and route decorators for Express.js applications",
|
||||
"license": "AGPL-3.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"main": "./dist/index.mjs",
|
||||
"module": "./dist/index.mjs",
|
||||
"types": "./dist/index.d.mts",
|
||||
"exports": {
|
||||
".": "./dist/index.mjs",
|
||||
"./package.json": "./package.json"
|
||||
|
|
@ -14,9 +17,9 @@
|
|||
"dev": "tsdown --watch",
|
||||
"check:lint": "eslint . --cache --cache-location node_modules/.cache/eslint/ --max-warnings=29",
|
||||
"check:types": "tsc --noEmit",
|
||||
"check:format": "prettier . --cache --check",
|
||||
"check:format": "oxfmt --check .",
|
||||
"fix:lint": "eslint . --cache --cache-location node_modules/.cache/eslint/ --fix --max-warnings=29",
|
||||
"fix:format": "prettier . --cache --write",
|
||||
"fix:format": "oxfmt .",
|
||||
"clean": "rm -rf .turbo && rm -rf .next && rm -rf node_modules && rm -rf dist"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
@ -27,8 +30,5 @@
|
|||
"reflect-metadata": "^0.2.2",
|
||||
"tsdown": "catalog:",
|
||||
"typescript": "catalog:"
|
||||
},
|
||||
"main": "./dist/index.mjs",
|
||||
"module": "./dist/index.mjs",
|
||||
"types": "./dist/index.d.mts"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,16 @@
|
|||
{
|
||||
"name": "@plane/editor",
|
||||
"version": "1.2.0",
|
||||
"description": "Core Editor that powers Plane",
|
||||
"license": "AGPL-3.0",
|
||||
"private": true,
|
||||
"description": "Core Editor that powers Plane",
|
||||
"keywords": [
|
||||
"editor",
|
||||
"markdown",
|
||||
"nextjs",
|
||||
"react",
|
||||
"rich-text"
|
||||
],
|
||||
"license": "AGPL-3.0",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.js",
|
||||
|
|
@ -20,15 +27,11 @@
|
|||
"dev": "tsdown --watch",
|
||||
"check:lint": "eslint . --cache --cache-location node_modules/.cache/eslint/ --max-warnings=1435",
|
||||
"check:types": "tsc --noEmit",
|
||||
"check:format": "prettier . --cache --check",
|
||||
"check:format": "oxfmt --check .",
|
||||
"fix:lint": "eslint . --cache --cache-location node_modules/.cache/eslint/ --fix --max-warnings=1435",
|
||||
"fix:format": "prettier . --cache --write",
|
||||
"fix:format": "oxfmt .",
|
||||
"clean": "rm -rf .turbo && rm -rf .next && rm -rf node_modules && rm -rf dist"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "catalog:",
|
||||
"react-dom": "catalog:"
|
||||
},
|
||||
"dependencies": {
|
||||
"@floating-ui/dom": "^1.7.1",
|
||||
"@floating-ui/react": "^0.26.4",
|
||||
|
|
@ -62,13 +65,13 @@
|
|||
"@tiptap/react": "^2.22.3",
|
||||
"@tiptap/starter-kit": "^2.22.3",
|
||||
"@tiptap/suggestion": "^2.22.3",
|
||||
"lodash-es": "catalog:",
|
||||
"buffer": "^6.0.3",
|
||||
"emoji-regex": "^10.3.0",
|
||||
"highlight.js": "^11.8.0",
|
||||
"is-emoji-supported": "^0.0.5",
|
||||
"jsx-dom-cjs": "^8.0.3",
|
||||
"linkifyjs": "^4.3.2",
|
||||
"lodash-es": "catalog:",
|
||||
"lowlight": "^3.0.0",
|
||||
"lucide-react": "catalog:",
|
||||
"prosemirror-codemark": "^0.4.2",
|
||||
|
|
@ -83,19 +86,16 @@
|
|||
"devDependencies": {
|
||||
"@plane/tailwind-config": "workspace:*",
|
||||
"@plane/typescript-config": "workspace:*",
|
||||
"@types/lodash-es": "catalog:",
|
||||
"@types/node": "catalog:",
|
||||
"@types/react": "catalog:",
|
||||
"@types/react-dom": "catalog:",
|
||||
"@types/lodash-es": "catalog:",
|
||||
"postcss": "^8.4.38",
|
||||
"tsdown": "catalog:",
|
||||
"typescript": "catalog:"
|
||||
},
|
||||
"keywords": [
|
||||
"editor",
|
||||
"rich-text",
|
||||
"markdown",
|
||||
"nextjs",
|
||||
"react"
|
||||
]
|
||||
"peerDependencies": {
|
||||
"react": "catalog:",
|
||||
"react-dom": "catalog:"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ function CollaborativeDocumentEditorInner(props: ICollaborativeDocumentEditorPro
|
|||
<div
|
||||
className={cn(
|
||||
"transition-opacity duration-200",
|
||||
showContentSkeleton && !isLoading && "opacity-0 pointer-events-none"
|
||||
showContentSkeleton && !isLoading && "pointer-events-none opacity-0"
|
||||
)}
|
||||
>
|
||||
<PageRenderer
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ export function PageRenderer(props: Props) {
|
|||
} = props;
|
||||
return (
|
||||
<div
|
||||
className={cn("frame-renderer flex-grow w-full", {
|
||||
className={cn("frame-renderer w-full flex-grow", {
|
||||
"wide-layout": displayConfig.wideLayout,
|
||||
})}
|
||||
>
|
||||
|
|
@ -82,7 +82,7 @@ export function PageRenderer(props: Props) {
|
|||
editor={titleEditor}
|
||||
id={id + "-title"}
|
||||
tabIndex={tabIndex}
|
||||
className="no-scrollbar placeholder-placeholder bg-transparent tracking-[-2%] font-bold text-[2rem] leading-[2.375rem] w-full outline-none p-0 border-none resize-none rounded-none"
|
||||
className="no-scrollbar placeholder-placeholder w-full resize-none rounded-none border-none bg-transparent p-0 text-[2rem] leading-[2.375rem] font-bold tracking-[-2%] outline-none"
|
||||
/>
|
||||
</EditorContainer>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -168,7 +168,7 @@ export function EditorContainer(props: Props) {
|
|||
onClick={handleContainerClick}
|
||||
onMouseLeave={handleContainerMouseLeave}
|
||||
className={cn(
|
||||
`editor-container cursor-text relative line-spacing-${displayConfig.lineSpacing ?? DEFAULT_DISPLAY_CONFIG.lineSpacing}`,
|
||||
`editor-container relative cursor-text line-spacing-${displayConfig.lineSpacing ?? DEFAULT_DISPLAY_CONFIG.lineSpacing}`,
|
||||
{
|
||||
"active-editor": editor?.isFocused && editor?.isEditable,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -23,11 +23,11 @@ type InputViewProps = {
|
|||
function InputView({ label, value, placeholder, onChange, autoFocus }: InputViewProps) {
|
||||
return (
|
||||
<div className="flex flex-col gap-1">
|
||||
<label className="inline-block font-semibold text-11 text-placeholder">{label}</label>
|
||||
<label className="inline-block text-11 font-semibold text-placeholder">{label}</label>
|
||||
<input
|
||||
placeholder={placeholder}
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
className="w-[280px] outline-none bg-layer-1 text-primary text-13 border border-strong rounded-md p-2"
|
||||
className="w-[280px] rounded-md border border-strong bg-layer-1 p-2 text-13 text-primary outline-none"
|
||||
value={value}
|
||||
onChange={(e) => onChange(e.target.value)}
|
||||
autoFocus={autoFocus}
|
||||
|
|
@ -138,7 +138,7 @@ export function LinkEditView({ viewProps }: LinkEditViewProps) {
|
|||
return (
|
||||
<div
|
||||
onKeyDown={handleKeyDown}
|
||||
className="shadow-md rounded-sm p-2 flex flex-col gap-3 bg-layer-1 border-subtle border-2 animate-in fade-in translate-y-1"
|
||||
className="shadow-md animate-in fade-in flex translate-y-1 flex-col gap-3 rounded-sm border-2 border-subtle bg-layer-1 p-2"
|
||||
style={{
|
||||
transition: "all 0.1s cubic-bezier(.55, .085, .68, .53)",
|
||||
}}
|
||||
|
|
@ -146,10 +146,10 @@ export function LinkEditView({ viewProps }: LinkEditViewProps) {
|
|||
>
|
||||
<InputView label="URL" placeholder="Enter or paste URL" value={localUrl} onChange={setLocalUrl} autoFocus />
|
||||
<InputView label="Text" placeholder="Enter Text to display" value={localText} onChange={handleTextChange} />
|
||||
<div className="mb-1 bg-strong h-[1px] w-full gap-2" />
|
||||
<div className="flex text-13 text-secondary gap-2 items-center">
|
||||
<div className="bg-strong mb-1 h-[1px] w-full gap-2" />
|
||||
<div className="flex items-center gap-2 text-13 text-secondary">
|
||||
<Link2Off size={14} className="inline-block" />
|
||||
<button onClick={removeLink} className="cursor-pointer hover:text-placeholder transition-colors">
|
||||
<button onClick={removeLink} className="cursor-pointer transition-colors hover:text-placeholder">
|
||||
Remove Link
|
||||
</button>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -30,27 +30,27 @@ export function LinkPreview({
|
|||
|
||||
return (
|
||||
<div
|
||||
className="absolute left-0 top-0 max-w-max animate-in fade-in translate-y-1"
|
||||
className="animate-in fade-in absolute top-0 left-0 max-w-max translate-y-1"
|
||||
style={{
|
||||
transition: "all 0.2s cubic-bezier(.55, .085, .68, .53)",
|
||||
}}
|
||||
>
|
||||
<div className="shadow-md items-center rounded-sm p-2 flex gap-3 bg-layer-1 border-subtle border-2 text-tertiary text-11">
|
||||
<div className="shadow-md flex items-center gap-3 rounded-sm border-2 border-subtle bg-layer-1 p-2 text-11 text-tertiary">
|
||||
<GlobeIcon width={14} height={14} className="inline-block" />
|
||||
<p>{url?.length > 40 ? url.slice(0, 40) + "..." : url}</p>
|
||||
<div className="flex gap-2">
|
||||
<button onClick={copyLinkToClipboard} className="cursor-pointer hover:text-primary transition-colors">
|
||||
<button onClick={copyLinkToClipboard} className="cursor-pointer transition-colors hover:text-primary">
|
||||
<CopyIcon width={14} height={14} className="inline-block" />
|
||||
</button>
|
||||
{editor.isEditable && (
|
||||
<>
|
||||
<button
|
||||
onClick={() => switchView("LinkEditView")}
|
||||
className="cursor-pointer hover:text-primary transition-colors"
|
||||
className="cursor-pointer transition-colors hover:text-primary"
|
||||
>
|
||||
<EditIcon width={14} height={14} className="inline-block" />
|
||||
</button>
|
||||
<button onClick={removeLink} className="cursor-pointer hover:text-primary transition-colors">
|
||||
<button onClick={removeLink} className="cursor-pointer transition-colors hover:text-primary">
|
||||
<Link2Off size={14} className="inline-block" />
|
||||
</button>
|
||||
</>
|
||||
|
|
|
|||
|
|
@ -88,8 +88,8 @@ export function AIFeaturesMenu(props: Props) {
|
|||
|
||||
return (
|
||||
<div
|
||||
className={cn("opacity-0 pointer-events-none fixed inset-0 size-full z-10 transition-opacity", {
|
||||
"opacity-100 pointer-events-auto": isPopupVisible,
|
||||
className={cn("pointer-events-none fixed inset-0 z-10 size-full opacity-0 transition-opacity", {
|
||||
"pointer-events-auto opacity-100": isPopupVisible,
|
||||
})}
|
||||
>
|
||||
<div ref={menuRef} className="z-10">
|
||||
|
|
|
|||
|
|
@ -223,8 +223,8 @@ export function BlockMenu(props: Props) {
|
|||
}}
|
||||
className={cn(
|
||||
"max-h-60 min-w-[7rem] overflow-y-scroll rounded-lg border border-subtle bg-surface-1 p-1.5 shadow-raised-200",
|
||||
"transition-all duration-300 transform origin-top-right",
|
||||
isAnimatedIn ? "opacity-100 scale-100" : "opacity-0 scale-75"
|
||||
"origin-top-right transform transition-all duration-300",
|
||||
isAnimatedIn ? "scale-100 opacity-100" : "scale-75 opacity-0"
|
||||
)}
|
||||
{...getFloatingProps()}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ export function TextAlignmentSelector(props: Props) {
|
|||
item.command();
|
||||
}}
|
||||
className={cn(
|
||||
"size-7 grid place-items-center rounded-sm text-tertiary hover:bg-layer-1 active:bg-layer-1 transition-colors",
|
||||
"grid size-7 place-items-center rounded-sm text-tertiary transition-colors hover:bg-layer-1 active:bg-layer-1",
|
||||
{
|
||||
"bg-layer-1 text-primary": item.isActive(),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ export function BubbleMenuColorSelector(props: Props) {
|
|||
<>
|
||||
<span>Color</span>
|
||||
<span
|
||||
className={cn("flex-shrink-0 size-6 grid place-items-center rounded-sm border-[0.5px] border-strong", {
|
||||
className={cn("grid size-6 flex-shrink-0 place-items-center rounded-sm border-[0.5px] border-strong", {
|
||||
"bg-surface-1": !activeBackgroundColor,
|
||||
})}
|
||||
style={{
|
||||
|
|
@ -64,15 +64,15 @@ export function BubbleMenuColorSelector(props: Props) {
|
|||
getFloatingProps={getFloatingProps}
|
||||
getReferenceProps={getReferenceProps}
|
||||
>
|
||||
<section className="mt-1 rounded-md border-[0.5px] border-strong bg-surface-1 p-2 space-y-2 shadow-raised-200">
|
||||
<section className="mt-1 space-y-2 rounded-md border-[0.5px] border-strong bg-surface-1 p-2 shadow-raised-200">
|
||||
<div className="space-y-1.5">
|
||||
<p className="text-11 text-tertiary font-semibold">Text colors</p>
|
||||
<p className="text-11 font-semibold text-tertiary">Text colors</p>
|
||||
<div className="flex items-center gap-2">
|
||||
{COLORS_LIST.map((color) => (
|
||||
<button
|
||||
key={color.key}
|
||||
type="button"
|
||||
className="flex-shrink-0 size-6 rounded-sm border-[0.5px] border-strong-1 hover:opacity-60 transition-opacity"
|
||||
className="size-6 flex-shrink-0 rounded-sm border-[0.5px] border-strong-1 transition-opacity hover:opacity-60"
|
||||
style={{
|
||||
backgroundColor: color.textColor,
|
||||
}}
|
||||
|
|
@ -81,7 +81,7 @@ export function BubbleMenuColorSelector(props: Props) {
|
|||
))}
|
||||
<button
|
||||
type="button"
|
||||
className="flex-shrink-0 size-6 grid place-items-center rounded-sm text-tertiary border-[0.5px] border-strong-1 hover:bg-layer-1 transition-colors"
|
||||
className="grid size-6 flex-shrink-0 place-items-center rounded-sm border-[0.5px] border-strong-1 text-tertiary transition-colors hover:bg-layer-1"
|
||||
onClick={() => TextColorItem(editor).command({ color: undefined })}
|
||||
>
|
||||
<Ban className="size-4" />
|
||||
|
|
@ -89,13 +89,13 @@ export function BubbleMenuColorSelector(props: Props) {
|
|||
</div>
|
||||
</div>
|
||||
<div className="space-y-1.5">
|
||||
<p className="text-11 text-tertiary font-semibold">Background colors</p>
|
||||
<p className="text-11 font-semibold text-tertiary">Background colors</p>
|
||||
<div className="flex items-center gap-2">
|
||||
{COLORS_LIST.map((color) => (
|
||||
<button
|
||||
key={color.key}
|
||||
type="button"
|
||||
className="flex-shrink-0 size-6 rounded-sm border-[0.5px] border-strong-1 hover:opacity-60 transition-opacity"
|
||||
className="size-6 flex-shrink-0 rounded-sm border-[0.5px] border-strong-1 transition-opacity hover:opacity-60"
|
||||
style={{
|
||||
backgroundColor: color.backgroundColor,
|
||||
}}
|
||||
|
|
@ -104,7 +104,7 @@ export function BubbleMenuColorSelector(props: Props) {
|
|||
))}
|
||||
<button
|
||||
type="button"
|
||||
className="flex-shrink-0 size-6 grid place-items-center rounded-sm text-tertiary border-[0.5px] border-strong-1 hover:bg-layer-1 transition-colors"
|
||||
className="grid size-6 flex-shrink-0 place-items-center rounded-sm border-[0.5px] border-strong-1 text-tertiary transition-colors hover:bg-layer-1"
|
||||
onClick={() => BackgroundColorItem(editor).command({ color: undefined })}
|
||||
>
|
||||
<Ban className="size-4" />
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ export function BubbleMenuLinkSelector(props: Props) {
|
|||
classNames={{
|
||||
buttonContainer: "h-full",
|
||||
button: cn(
|
||||
"h-full flex items-center gap-1 px-3 text-13 font-medium text-tertiary hover:bg-layer-1 active:bg-layer-1 rounded-sm whitespace-nowrap transition-colors",
|
||||
"flex h-full items-center gap-1 rounded-sm px-3 text-13 font-medium whitespace-nowrap text-tertiary transition-colors hover:bg-layer-1 active:bg-layer-1",
|
||||
{
|
||||
"bg-layer-1": context.open,
|
||||
"text-primary": editor.isActive(CORE_EXTENSIONS.CUSTOM_LINK),
|
||||
|
|
@ -65,14 +65,14 @@ export function BubbleMenuLinkSelector(props: Props) {
|
|||
menuButton={
|
||||
<>
|
||||
Link
|
||||
<LinkIcon className="shrink-0 size-3" />
|
||||
<LinkIcon className="size-3 shrink-0" />
|
||||
</>
|
||||
}
|
||||
options={options}
|
||||
>
|
||||
<div className="w-60 mt-1 rounded-md bg-surface-1 shadow-raised-200">
|
||||
<div className="mt-1 w-60 rounded-md bg-surface-1 shadow-raised-200">
|
||||
<div
|
||||
className={cn("flex rounded-sm border-[0.5px] border-strong transition-colors", {
|
||||
className={cn("flex rounded-sm border-[0.5px] border-strong transition-colors", {
|
||||
"border-danger-strong": error,
|
||||
})}
|
||||
>
|
||||
|
|
@ -81,7 +81,7 @@ export function BubbleMenuLinkSelector(props: Props) {
|
|||
type="url"
|
||||
placeholder="Enter or paste a link"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
className="flex-1 border-r-[0.5px] border-strong bg-surface-1 py-2 px-1.5 text-11 outline-none placeholder:text-placeholder rounded-sm"
|
||||
className="flex-1 rounded-sm border-r-[0.5px] border-strong bg-surface-1 px-1.5 py-2 text-11 outline-none placeholder:text-placeholder"
|
||||
defaultValue={editor.getAttributes("link").href || ""}
|
||||
onKeyDown={(e) => {
|
||||
setError(false);
|
||||
|
|
@ -96,7 +96,7 @@ export function BubbleMenuLinkSelector(props: Props) {
|
|||
{editor.getAttributes("link").href ? (
|
||||
<button
|
||||
type="button"
|
||||
className="grid place-items-center rounded-xs p-1 text-danger-primary hover:bg-danger-subtle-hover transition-all"
|
||||
className="grid place-items-center rounded-xs p-1 text-danger-primary transition-all hover:bg-danger-subtle-hover"
|
||||
onClick={(e) => {
|
||||
unsetLinkEditor(editor);
|
||||
e.stopPropagation();
|
||||
|
|
@ -108,7 +108,7 @@ export function BubbleMenuLinkSelector(props: Props) {
|
|||
) : (
|
||||
<button
|
||||
type="button"
|
||||
className="h-full aspect-square grid place-items-center p-1 rounded-xs text-tertiary hover:bg-layer-1 transition-all"
|
||||
className="grid aspect-square h-full place-items-center rounded-xs p-1 text-tertiary transition-all hover:bg-layer-1"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
handleLinkSubmit();
|
||||
|
|
@ -119,7 +119,7 @@ export function BubbleMenuLinkSelector(props: Props) {
|
|||
)}
|
||||
</div>
|
||||
{error && (
|
||||
<p className="text-11 text-danger-primary my-1 px-2 pointer-events-none animate-in fade-in slide-in-from-top-0">
|
||||
<p className="animate-in fade-in slide-in-from-top-0 pointer-events-none my-1 px-2 text-11 text-danger-primary">
|
||||
Please enter a valid URL
|
||||
</p>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ export function BubbleMenuNodeSelector(props: Props) {
|
|||
classNames={{
|
||||
buttonContainer: "h-full",
|
||||
button: cn(
|
||||
"h-full flex items-center gap-1 px-3 text-13 font-medium text-tertiary hover:bg-layer-1 active:bg-layer-1 rounded-sm whitespace-nowrap transition-colors",
|
||||
"flex h-full items-center gap-1 rounded-sm px-3 text-13 font-medium whitespace-nowrap text-tertiary transition-colors hover:bg-layer-1 active:bg-layer-1",
|
||||
{
|
||||
"bg-layer-1": context.open,
|
||||
}
|
||||
|
|
@ -74,14 +74,14 @@ export function BubbleMenuNodeSelector(props: Props) {
|
|||
menuButton={
|
||||
<>
|
||||
<span>{activeItem?.name}</span>
|
||||
<ChevronDownIcon className="shrink-0 size-3" />
|
||||
<ChevronDownIcon className="size-3 shrink-0" />
|
||||
</>
|
||||
}
|
||||
options={options}
|
||||
getFloatingProps={getFloatingProps}
|
||||
getReferenceProps={getReferenceProps}
|
||||
>
|
||||
<section className="w-48 max-h-[90vh] mt-1 flex flex-col overflow-y-scroll rounded-md border-[0.5px] border-strong bg-surface-1 px-2 py-2.5 shadow-raised-200">
|
||||
<section className="mt-1 flex max-h-[90vh] w-48 flex-col overflow-y-scroll rounded-md border-[0.5px] border-strong bg-surface-1 px-2 py-2.5 shadow-raised-200">
|
||||
{items.map((item) => (
|
||||
<button
|
||||
key={item.name}
|
||||
|
|
@ -102,7 +102,7 @@ export function BubbleMenuNodeSelector(props: Props) {
|
|||
<item.icon className="size-3 flex-shrink-0" />
|
||||
<span>{item.name}</span>
|
||||
</div>
|
||||
{activeItem.name === item.name && <CheckIcon className="size-3 text-tertiary flex-shrink-0" />}
|
||||
{activeItem.name === item.name && <CheckIcon className="size-3 flex-shrink-0 text-tertiary" />}
|
||||
</button>
|
||||
))}
|
||||
</section>
|
||||
|
|
|
|||
|
|
@ -192,7 +192,7 @@ export function EditorBubbleMenu(props: Props) {
|
|||
{!isSelecting && (
|
||||
<div
|
||||
ref={menuRef}
|
||||
className="flex py-2 divide-x divide-subtle-1 rounded-lg border border-subtle bg-surface-1 shadow-raised-200 overflow-x-scroll horizontal-scrollbar scrollbar-xs"
|
||||
className="horizontal-scrollbar flex scrollbar-xs divide-x divide-subtle-1 overflow-x-scroll rounded-lg border border-subtle bg-surface-1 py-2 shadow-raised-200"
|
||||
>
|
||||
<div className="px-2">
|
||||
<BubbleMenuNodeSelector editor={editor} />
|
||||
|
|
@ -217,7 +217,7 @@ export function EditorBubbleMenu(props: Props) {
|
|||
e.stopPropagation();
|
||||
}}
|
||||
className={cn(
|
||||
"size-7 grid place-items-center rounded-sm text-tertiary hover:bg-layer-1 active:bg-layer-1 transition-colors",
|
||||
"grid size-7 place-items-center rounded-sm text-tertiary transition-colors hover:bg-layer-1 active:bg-layer-1",
|
||||
{
|
||||
"bg-layer-1 text-primary": editorState[item.key],
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ export function CustomCalloutBlock(props: CustomCalloutNodeViewProps) {
|
|||
return (
|
||||
<NodeViewWrapper
|
||||
key={node.attrs[ECalloutAttributeNames.ID]}
|
||||
className="editor-callout-component group/callout-node relative bg-layer-3 rounded-lg text-primary p-4 my-2 flex items-start gap-4 transition-colors duration-500 break-words"
|
||||
className="editor-callout-component group/callout-node relative my-2 flex items-start gap-4 rounded-lg bg-layer-3 p-4 break-words text-primary transition-colors duration-500"
|
||||
style={{
|
||||
backgroundColor: activeBackgroundColor,
|
||||
}}
|
||||
|
|
|
|||
|
|
@ -28,9 +28,9 @@ export function CalloutBlockColorSelector(props: Props) {
|
|||
|
||||
return (
|
||||
<div
|
||||
className={cn("opacity-0 pointer-events-none absolute top-2 right-2 z-10 transition-opacity", {
|
||||
"group-hover/callout-node:opacity-100 group-hover/callout-node:pointer-events-auto": !disabled,
|
||||
"opacity-100 pointer-events-auto": isOpen,
|
||||
className={cn("pointer-events-none absolute top-2 right-2 z-10 opacity-0 transition-opacity", {
|
||||
"group-hover/callout-node:pointer-events-auto group-hover/callout-node:opacity-100": !disabled,
|
||||
"pointer-events-auto opacity-100": isOpen,
|
||||
})}
|
||||
contentEditable={false}
|
||||
>
|
||||
|
|
@ -42,7 +42,7 @@ export function CalloutBlockColorSelector(props: Props) {
|
|||
e.stopPropagation();
|
||||
}}
|
||||
className={cn(
|
||||
"flex items-center gap-1 h-full whitespace-nowrap py-1 px-2.5 text-13 font-medium text-tertiary hover:bg-layer-1-hover active:bg-layer-1-active rounded-sm transition-colors",
|
||||
"flex h-full items-center gap-1 rounded-sm px-2.5 py-1 text-13 font-medium whitespace-nowrap text-tertiary transition-colors hover:bg-layer-1-hover active:bg-layer-1-active",
|
||||
{
|
||||
"bg-layer-1": isOpen,
|
||||
}
|
||||
|
|
@ -50,16 +50,16 @@ export function CalloutBlockColorSelector(props: Props) {
|
|||
disabled={disabled}
|
||||
>
|
||||
<span className="text-12">Color</span>
|
||||
<ChevronDownIcon className="flex-shrink-0 size-3" />
|
||||
<ChevronDownIcon className="size-3 flex-shrink-0" />
|
||||
</button>
|
||||
{isOpen && (
|
||||
<section className="absolute top-full right-0 z-10 mt-1 rounded-md border-[0.5px] border-strong bg-surface-1 p-2 shadow-raised-200 animate-in fade-in slide-in-from-top-1">
|
||||
<section className="animate-in fade-in slide-in-from-top-1 absolute top-full right-0 z-10 mt-1 rounded-md border-[0.5px] border-strong bg-surface-1 p-2 shadow-raised-200">
|
||||
<div className="flex items-center gap-2">
|
||||
{COLORS_LIST.map((color) => (
|
||||
<button
|
||||
key={color.key}
|
||||
type="button"
|
||||
className="flex-shrink-0 size-6 rounded-sm border-[0.5px] border-strong-1 hover:opacity-60 transition-opacity"
|
||||
className="size-6 flex-shrink-0 rounded-sm border-[0.5px] border-strong-1 transition-opacity hover:opacity-60"
|
||||
style={{
|
||||
backgroundColor: color.backgroundColor,
|
||||
}}
|
||||
|
|
@ -68,7 +68,7 @@ export function CalloutBlockColorSelector(props: Props) {
|
|||
))}
|
||||
<button
|
||||
type="button"
|
||||
className="flex-shrink-0 size-6 grid place-items-center rounded-sm text-tertiary border-[0.5px] border-strong-1 hover:bg-layer-1-hover transition-colors"
|
||||
className="grid size-6 flex-shrink-0 place-items-center rounded-sm border-[0.5px] border-strong-1 text-tertiary transition-colors hover:bg-layer-1-hover"
|
||||
onClick={() => handleColorSelect(null)}
|
||||
>
|
||||
<Ban className="size-4" />
|
||||
|
|
|
|||
|
|
@ -42,8 +42,8 @@ export function CalloutBlockLogoSelector(props: Props) {
|
|||
closeOnSelect={true}
|
||||
isOpen={isOpen}
|
||||
handleToggle={handleOpen}
|
||||
className="flex-shrink-0 grid place-items-center"
|
||||
buttonClassName={cn("flex-shrink-0 size-8 grid place-items-center rounded-lg text-primary", {
|
||||
className="grid flex-shrink-0 place-items-center"
|
||||
buttonClassName={cn("grid size-8 flex-shrink-0 place-items-center rounded-lg text-primary", {
|
||||
"hover:bg-layer-1-hover": !disabled,
|
||||
})}
|
||||
label={<Logo logo={logoValue} size={18} type="lucide" />}
|
||||
|
|
|
|||
|
|
@ -45,12 +45,12 @@ export function CodeBlockComponent({ node }: Props) {
|
|||
};
|
||||
|
||||
return (
|
||||
<NodeViewWrapper key={attrs[ECodeBlockAttributeNames.ID]} className="code-block relative group/code">
|
||||
<NodeViewWrapper key={attrs[ECodeBlockAttributeNames.ID]} className="code-block group/code relative">
|
||||
<Tooltip tooltipContent="Copy code">
|
||||
<button
|
||||
type="button"
|
||||
className={cn(
|
||||
"group/button hidden group-hover/code:flex items-center justify-center absolute top-2 right-2 z-10 size-8 rounded-md bg-layer-1 border border-subtle transition duration-150 ease-in-out backdrop-blur-sm",
|
||||
"group/button absolute top-2 right-2 z-10 hidden size-8 items-center justify-center rounded-md border border-subtle bg-layer-1 backdrop-blur-sm transition duration-150 ease-in-out group-hover/code:flex",
|
||||
{
|
||||
"bg-success-subtle hover:bg-success-subtle-1 active:bg-success-subtle-1": copied,
|
||||
}
|
||||
|
|
@ -65,7 +65,7 @@ export function CodeBlockComponent({ node }: Props) {
|
|||
</button>
|
||||
</Tooltip>
|
||||
|
||||
<pre className="bg-layer-3 text-primary rounded-lg p-4 my-2">
|
||||
<pre className="my-2 rounded-lg bg-layer-3 p-4 text-primary">
|
||||
<NodeViewContent as="code" className="whitespace-pre-wrap" />
|
||||
</pre>
|
||||
</NodeViewWrapper>
|
||||
|
|
|
|||
|
|
@ -245,7 +245,7 @@ export function CustomImageBlock(props: CustomImageBlockProps) {
|
|||
}}
|
||||
>
|
||||
{showImageLoader && (
|
||||
<div className="animate-pulse bg-layer-1 rounded-md" style={{ width: size.width, height: size.height }} />
|
||||
<div className="animate-pulse rounded-md bg-layer-1" style={{ width: size.width, height: size.height }} />
|
||||
)}
|
||||
<img
|
||||
ref={imageRef}
|
||||
|
|
@ -294,7 +294,7 @@ export function CustomImageBlock(props: CustomImageBlockProps) {
|
|||
// hide the image while the background calculations of the image loader are in progress (to avoid flickering) and show the loader until then
|
||||
hidden: showImageLoader,
|
||||
"read-only-image": !editor.isEditable,
|
||||
"blur-sm opacity-80 loading-image": !resolvedImageSrc,
|
||||
"loading-image opacity-80 blur-sm": !resolvedImageSrc,
|
||||
})}
|
||||
style={{
|
||||
width: size.width,
|
||||
|
|
@ -320,13 +320,13 @@ export function CustomImageBlock(props: CustomImageBlockProps) {
|
|||
/>
|
||||
)}
|
||||
{selected && displayedImageSrc === resolvedImageSrc && (
|
||||
<div className="absolute inset-0 size-full bg-accent-primary/30 pointer-events-none" />
|
||||
<div className="pointer-events-none absolute inset-0 size-full bg-accent-primary/30" />
|
||||
)}
|
||||
{showImageResizer && (
|
||||
<>
|
||||
<div
|
||||
className={cn(
|
||||
"absolute inset-0 border-2 border-accent-strong pointer-events-none rounded-md transition-opacity duration-100 ease-in-out",
|
||||
"pointer-events-none absolute inset-0 rounded-md border-2 border-accent-strong transition-opacity duration-100 ease-in-out",
|
||||
{
|
||||
"opacity-100": isResizing,
|
||||
"opacity-0 group-hover/image-component:opacity-100": !isResizing,
|
||||
|
|
@ -335,10 +335,10 @@ export function CustomImageBlock(props: CustomImageBlockProps) {
|
|||
/>
|
||||
<div
|
||||
className={cn(
|
||||
"absolute bottom-0 translate-y-1/2 size-4 rounded-full bg-accent-primary border-2 border-white transition-opacity duration-100 ease-in-out",
|
||||
"absolute bottom-0 size-4 translate-y-1/2 rounded-full border-2 border-white bg-accent-primary transition-opacity duration-100 ease-in-out",
|
||||
{
|
||||
"opacity-100 pointer-events-auto": isResizing,
|
||||
"opacity-0 pointer-events-none group-hover/image-component:opacity-100 group-hover/image-component:pointer-events-auto":
|
||||
"pointer-events-auto opacity-100": isResizing,
|
||||
"pointer-events-none opacity-0 group-hover/image-component:pointer-events-auto group-hover/image-component:opacity-100":
|
||||
!isResizing,
|
||||
"left-0 -translate-x-1/2 cursor-nesw-resize": nodeAlignment === "right",
|
||||
"right-0 translate-x-1/2 cursor-nwse-resize": nodeAlignment !== "right",
|
||||
|
|
|
|||
|
|
@ -138,7 +138,7 @@ export function CustomImageNodeView(props: CustomImageNodeViewProps) {
|
|||
|
||||
return (
|
||||
<NodeViewWrapper key={node.attrs[ECustomImageAttributeNames.ID]}>
|
||||
<div className="p-0 mx-0 my-2" data-drag-handle ref={imageComponentRef}>
|
||||
<div className="mx-0 my-2 p-0" data-drag-handle ref={imageComponentRef}>
|
||||
{shouldShowBlock && !hasDuplicationFailed ? (
|
||||
<CustomImageBlock
|
||||
editorContainer={editorContainer}
|
||||
|
|
|
|||
|
|
@ -36,24 +36,24 @@ export function ImageAlignmentAction(props: Props) {
|
|||
}, [isDropdownOpen, toggleToolbarViewStatus]);
|
||||
|
||||
return (
|
||||
<div ref={dropdownRef} className="h-full relative">
|
||||
<div ref={dropdownRef} className="relative h-full">
|
||||
<Tooltip disabled={isTouchDevice} tooltipContent="Align">
|
||||
<button
|
||||
type="button"
|
||||
className="h-full flex items-center gap-1 text-white/60 hover:text-white transition-colors"
|
||||
className="flex h-full items-center gap-1 text-white/60 transition-colors hover:text-white"
|
||||
onClick={() => setIsDropdownOpen((prev) => !prev)}
|
||||
>
|
||||
{activeAlignmentDetails && <activeAlignmentDetails.icon className="flex-shrink-0 size-3" />}
|
||||
<ChevronDownIcon className="flex-shrink-0 size-2" />
|
||||
{activeAlignmentDetails && <activeAlignmentDetails.icon className="size-3 flex-shrink-0" />}
|
||||
<ChevronDownIcon className="size-2 flex-shrink-0" />
|
||||
</button>
|
||||
</Tooltip>
|
||||
{isDropdownOpen && (
|
||||
<div className="absolute top-full left-1/2 -translate-x-1/2 mt-0.5 h-7 bg-black/80 flex items-center gap-2 px-2 rounded-sm">
|
||||
<div className="absolute top-full left-1/2 mt-0.5 flex h-7 -translate-x-1/2 items-center gap-2 rounded-sm bg-black/80 px-2">
|
||||
{IMAGE_ALIGNMENT_OPTIONS.map((option) => (
|
||||
<Tooltip disabled={isTouchDevice} key={option.value} tooltipContent={option.label}>
|
||||
<button
|
||||
type="button"
|
||||
className="flex-shrink-0 h-full grid place-items-center text-white/60 hover:text-white transition-colors"
|
||||
className="grid h-full flex-shrink-0 place-items-center text-white/60 transition-colors hover:text-white"
|
||||
onClick={() => {
|
||||
handleChange(option.value);
|
||||
setIsDropdownOpen(false);
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ export function ImageDownloadAction(props: Props) {
|
|||
<button
|
||||
type="button"
|
||||
onClick={() => window.open(src, "_blank")}
|
||||
className="flex-shrink-0 h-full grid place-items-center text-white/60 hover:text-white transition-colors"
|
||||
className="grid h-full flex-shrink-0 place-items-center text-white/60 transition-colors hover:text-white"
|
||||
aria-label="Download image"
|
||||
>
|
||||
<Download className="size-3" />
|
||||
|
|
|
|||
|
|
@ -199,8 +199,8 @@ function ImageFullScreenModalWithoutPortal(props: Props) {
|
|||
|
||||
return (
|
||||
<div
|
||||
className={cn("fixed inset-0 size-full z-50 bg-black/90 opacity-0 pointer-events-none transition-opacity", {
|
||||
"opacity-100 pointer-events-auto editor-image-full-screen-modal": isFullScreenEnabled,
|
||||
className={cn("pointer-events-none fixed inset-0 z-50 size-full bg-black/90 opacity-0 transition-opacity", {
|
||||
"editor-image-full-screen-modal pointer-events-auto opacity-100": isFullScreenEnabled,
|
||||
"cursor-default": !isDragging,
|
||||
"cursor-grabbing": isDragging,
|
||||
})}
|
||||
|
|
@ -211,15 +211,15 @@ function ImageFullScreenModalWithoutPortal(props: Props) {
|
|||
<div
|
||||
ref={modalRef}
|
||||
onMouseDown={(e) => e.target === modalRef.current && handleClose()}
|
||||
className="relative size-full grid place-items-center overflow-hidden"
|
||||
className="relative grid size-full place-items-center overflow-hidden"
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
onClick={handleClose}
|
||||
className="absolute top-10 right-10 size-8 grid place-items-center"
|
||||
className="absolute top-10 right-10 grid size-8 place-items-center"
|
||||
aria-label="Close image viewer"
|
||||
>
|
||||
<CloseIcon className="size-8 text-white/60 hover:text-white transition-colors" />
|
||||
<CloseIcon className="size-8 text-white/60 transition-colors hover:text-white" />
|
||||
</button>
|
||||
<img
|
||||
ref={setImageRef}
|
||||
|
|
@ -237,7 +237,7 @@ function ImageFullScreenModalWithoutPortal(props: Props) {
|
|||
}}
|
||||
onMouseDown={handleMouseDown}
|
||||
/>
|
||||
<div className="fixed bottom-10 left-1/2 -translate-x-1/2 flex items-center justify-center gap-1 rounded-md border border-subtle-1 py-2 divide-x divide-subtle-1 bg-black">
|
||||
<div className="fixed bottom-10 left-1/2 flex -translate-x-1/2 items-center justify-center gap-1 divide-x divide-subtle-1 rounded-md border border-subtle-1 bg-black py-2">
|
||||
<div className="flex items-center">
|
||||
<button
|
||||
type="button"
|
||||
|
|
@ -248,13 +248,13 @@ function ImageFullScreenModalWithoutPortal(props: Props) {
|
|||
}
|
||||
handleMagnification("decrease");
|
||||
}}
|
||||
className="size-6 grid place-items-center text-white/60 hover:text-white disabled:text-white/30 transition-colors duration-200"
|
||||
className="grid size-6 place-items-center text-white/60 transition-colors duration-200 hover:text-white disabled:text-white/30"
|
||||
disabled={magnification <= MIN_ZOOM}
|
||||
aria-label="Zoom out"
|
||||
>
|
||||
<Minus className="size-4" />
|
||||
</button>
|
||||
<span className="text-13 w-12 text-center text-white">{Math.round(100 * magnification)}%</span>
|
||||
<span className="w-12 text-center text-13 text-white">{Math.round(100 * magnification)}%</span>
|
||||
<button
|
||||
type="button"
|
||||
onClick={(e) => {
|
||||
|
|
@ -264,7 +264,7 @@ function ImageFullScreenModalWithoutPortal(props: Props) {
|
|||
}
|
||||
handleMagnification("increase");
|
||||
}}
|
||||
className="size-6 grid place-items-center text-white/60 hover:text-white disabled:text-white/30 transition-colors duration-200"
|
||||
className="grid size-6 place-items-center text-white/60 transition-colors duration-200 hover:text-white disabled:text-white/30"
|
||||
disabled={magnification >= MAX_ZOOM}
|
||||
aria-label="Zoom in"
|
||||
>
|
||||
|
|
@ -275,7 +275,7 @@ function ImageFullScreenModalWithoutPortal(props: Props) {
|
|||
<button
|
||||
type="button"
|
||||
onClick={() => window.open(downloadSrc, "_blank")}
|
||||
className="flex-shrink-0 size-8 grid place-items-center text-white/60 hover:text-white transition-colors duration-200"
|
||||
className="grid size-8 flex-shrink-0 place-items-center text-white/60 transition-colors duration-200 hover:text-white"
|
||||
aria-label="Download image"
|
||||
>
|
||||
<Download className="size-4" />
|
||||
|
|
@ -285,7 +285,7 @@ function ImageFullScreenModalWithoutPortal(props: Props) {
|
|||
<button
|
||||
type="button"
|
||||
onClick={() => window.open(src, "_blank")}
|
||||
className="flex-shrink-0 size-8 grid place-items-center text-white/60 hover:text-white transition-colors duration-200"
|
||||
className="grid size-8 flex-shrink-0 place-items-center text-white/60 transition-colors duration-200 hover:text-white"
|
||||
aria-label="Open image in new tab"
|
||||
>
|
||||
<NewTabIcon className="size-4" />
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ export function ImageFullScreenActionRoot(props: Props) {
|
|||
e.stopPropagation();
|
||||
setIsFullScreenEnabled(true);
|
||||
}}
|
||||
className="flex-shrink-0 h-full grid place-items-center text-on-color/60 hover:text-on-color transition-colors"
|
||||
className="grid h-full flex-shrink-0 place-items-center text-on-color/60 transition-colors hover:text-on-color"
|
||||
aria-label="View image in full screen"
|
||||
>
|
||||
<Maximize className="size-3" />
|
||||
|
|
|
|||
|
|
@ -37,9 +37,9 @@ export function ImageToolbarRoot(props: Props) {
|
|||
<>
|
||||
<div
|
||||
className={cn(
|
||||
"absolute top-1 right-1 h-7 z-20 bg-black/80 rounded-sm flex items-center gap-2 px-2 opacity-0 pointer-events-none group-hover/image-component:opacity-100 group-hover/image-component:pointer-events-auto transition-opacity",
|
||||
"pointer-events-none absolute top-1 right-1 z-20 flex h-7 items-center gap-2 rounded-sm bg-black/80 px-2 opacity-0 transition-opacity group-hover/image-component:pointer-events-auto group-hover/image-component:opacity-100",
|
||||
{
|
||||
"opacity-100 pointer-events-auto": shouldShowToolbar,
|
||||
"pointer-events-auto opacity-100": shouldShowToolbar,
|
||||
}
|
||||
)}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ export function ImageUploadStatus(props: Props) {
|
|||
if (uploadStatus === undefined) return null;
|
||||
|
||||
return (
|
||||
<div className="absolute top-1 right-1 z-20 bg-black/60 rounded-sm text-11 font-medium w-10 text-center">
|
||||
<div className="absolute top-1 right-1 z-20 w-10 rounded-sm bg-black/60 text-center text-11 font-medium">
|
||||
{displayStatus}%
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -211,15 +211,15 @@ export function CustomImageUploader(props: CustomImageUploaderProps) {
|
|||
return (
|
||||
<div
|
||||
className={cn(
|
||||
"image-upload-component flex items-center justify-start gap-2 py-3 px-2 rounded-lg text-tertiary bg-layer-3 border border-dashed transition-all duration-200 ease-in-out cursor-default",
|
||||
"image-upload-component flex cursor-default items-center justify-start gap-2 rounded-lg border border-dashed bg-layer-3 px-2 py-3 text-tertiary transition-all duration-200 ease-in-out",
|
||||
{
|
||||
"border-subtle": !(selected && editor.isEditable && !isErrorState),
|
||||
"hover:text-secondary hover:bg-layer-3-hover cursor-pointer": editor.isEditable && !isErrorState,
|
||||
"cursor-pointer hover:bg-layer-3-hover hover:text-secondary": editor.isEditable && !isErrorState,
|
||||
"bg-layer-3-hover text-secondary": draggedInside && editor.isEditable && !isErrorState,
|
||||
"text-accent-secondary bg-accent-primary/10 hover:bg-accent-primary/10 hover:text-accent-secondary":
|
||||
"bg-accent-primary/10 text-accent-secondary hover:bg-accent-primary/10 hover:text-accent-secondary":
|
||||
selected && editor.isEditable && !isErrorState,
|
||||
"text-danger-primary bg-danger-subtle cursor-default": isErrorState,
|
||||
"hover:text-danger-primary hover:bg-danger-subtle-hover": isErrorState && editor.isEditable,
|
||||
"cursor-default bg-danger-subtle text-danger-primary": isErrorState,
|
||||
"hover:bg-danger-subtle-hover hover:text-danger-primary": isErrorState && editor.isEditable,
|
||||
"bg-danger-subtle-selected": isErrorState && selected,
|
||||
"hover:bg-danger-subtle-active": isErrorState && selected && editor.isEditable,
|
||||
}
|
||||
|
|
@ -236,13 +236,13 @@ export function CustomImageUploader(props: CustomImageUploaderProps) {
|
|||
}}
|
||||
>
|
||||
<ImageIcon className="size-4" />
|
||||
<div className="text-14 font-medium flex-1">{getDisplayMessage()}</div>
|
||||
<div className="flex-1 text-14 font-medium">{getDisplayMessage()}</div>
|
||||
{hasDuplicationFailed && editor.isEditable && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={handleRetryClick}
|
||||
className={cn(
|
||||
"flex items-center gap-1 px-2 py-1 font-medium text-danger-primary rounded-md transition-all duration-200 ease-in-out hover:bg-danger-subtle-hover",
|
||||
"flex items-center gap-1 rounded-md px-2 py-1 font-medium text-danger-primary transition-all duration-200 ease-in-out hover:bg-danger-subtle-hover",
|
||||
{
|
||||
"hover:bg-danger-subtle-hover": selected,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -130,9 +130,9 @@ export const EmojisListDropdown = forwardRef(function EmojisListDropdown(
|
|||
<div
|
||||
ref={dropdownContainerRef}
|
||||
className={cn(
|
||||
"relative max-h-80 w-[14rem] overflow-y-auto rounded-md border-[0.5px] border-strong bg-surface-1 px-2 py-2.5 shadow-raised-200 space-y-2 opacity-0 invisible transition-opacity",
|
||||
"invisible relative max-h-80 w-[14rem] space-y-2 overflow-y-auto rounded-md border-[0.5px] border-strong bg-surface-1 px-2 py-2.5 opacity-0 shadow-raised-200 transition-opacity",
|
||||
{
|
||||
"opacity-100 visible": isVisible,
|
||||
"visible opacity-100": isVisible,
|
||||
}
|
||||
)}
|
||||
style={{
|
||||
|
|
@ -156,7 +156,7 @@ export const EmojisListDropdown = forwardRef(function EmojisListDropdown(
|
|||
id={`emoji-item-${index}`}
|
||||
type="button"
|
||||
className={cn(
|
||||
"flex items-center gap-2 w-full rounded-sm px-2 py-1.5 text-13 text-left truncate text-secondary hover:bg-layer-1-hover transition-colors duration-150",
|
||||
"flex w-full items-center gap-2 truncate rounded-sm px-2 py-1.5 text-left text-13 text-secondary transition-colors duration-150 hover:bg-layer-1-hover",
|
||||
{
|
||||
"bg-layer-1-hover": isSelected,
|
||||
}
|
||||
|
|
@ -164,7 +164,7 @@ export const EmojisListDropdown = forwardRef(function EmojisListDropdown(
|
|||
onClick={() => selectItem(index)}
|
||||
onMouseEnter={() => setSelectedIndex(index)}
|
||||
>
|
||||
<span className="size-5 grid place-items-center flex-shrink-0 text-14">{item.emoji}</span>
|
||||
<span className="grid size-5 flex-shrink-0 place-items-center text-14">{item.emoji}</span>
|
||||
<span className="flex-grow truncate">
|
||||
<span className="font-medium">:{item.name}:</span>
|
||||
</span>
|
||||
|
|
@ -172,7 +172,7 @@ export const EmojisListDropdown = forwardRef(function EmojisListDropdown(
|
|||
);
|
||||
})
|
||||
) : (
|
||||
<div className="text-center text-13 text-placeholder py-2">No emojis found</div>
|
||||
<div className="py-2 text-center text-13 text-placeholder">No emojis found</div>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
|
|
|
|||
|
|
@ -146,7 +146,7 @@ export const MentionsListDropdown = forwardRef(function MentionsListDropdown(pro
|
|||
/>
|
||||
<div
|
||||
ref={dropdownContainer}
|
||||
className="relative max-h-80 w-[14rem] overflow-y-auto rounded-md border-[0.5px] border-strong bg-surface-1 px-2 py-2.5 shadow-raised-200 space-y-2"
|
||||
className="relative max-h-80 w-[14rem] space-y-2 overflow-y-auto rounded-md border-[0.5px] border-strong bg-surface-1 px-2 py-2.5 shadow-raised-200"
|
||||
style={{
|
||||
zIndex: 100,
|
||||
}}
|
||||
|
|
@ -172,7 +172,7 @@ export const MentionsListDropdown = forwardRef(function MentionsListDropdown(pro
|
|||
id={`mention-item-${sectionIndex}-${itemIndex}`}
|
||||
type="button"
|
||||
className={cn(
|
||||
"flex items-center gap-2 w-full rounded-sm px-1 py-1.5 text-11 text-left truncate text-secondary hover:bg-layer-1-hover",
|
||||
"flex w-full items-center gap-2 truncate rounded-sm px-1 py-1.5 text-left text-11 text-secondary hover:bg-layer-1-hover",
|
||||
{
|
||||
"bg-layer-1-hover": isSelected,
|
||||
}
|
||||
|
|
@ -189,9 +189,9 @@ export const MentionsListDropdown = forwardRef(function MentionsListDropdown(pro
|
|||
})
|
||||
}
|
||||
>
|
||||
<span className="size-5 grid place-items-center flex-shrink-0">{item.icon}</span>
|
||||
<span className="grid size-5 flex-shrink-0 place-items-center">{item.icon}</span>
|
||||
{item.subTitle && (
|
||||
<h5 className="whitespace-nowrap text-11 text-tertiary flex-shrink-0">{item.subTitle}</h5>
|
||||
<h5 className="flex-shrink-0 text-11 whitespace-nowrap text-tertiary">{item.subTitle}</h5>
|
||||
)}
|
||||
<p className="flex-grow truncate">{item.title}</p>
|
||||
</button>
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ export function CommandMenuItem(props: Props) {
|
|||
type="button"
|
||||
id={`item-${sectionIndex}-${itemIndex}`}
|
||||
className={cn(
|
||||
"flex items-center gap-2 w-full rounded-sm px-1 py-1.5 text-13 text-left truncate text-secondary hover:bg-layer-1-hover",
|
||||
"flex w-full items-center gap-2 truncate rounded-sm px-1 py-1.5 text-left text-13 text-secondary hover:bg-layer-1-hover",
|
||||
{
|
||||
"bg-layer-1-hover": isSelected,
|
||||
}
|
||||
|
|
@ -62,7 +62,7 @@ export function CommandMenuItem(props: Props) {
|
|||
onClick={onClick}
|
||||
onMouseEnter={onMouseEnter}
|
||||
>
|
||||
<span className="size-5 grid place-items-center flex-shrink-0" style={item.iconContainerStyle}>
|
||||
<span className="grid size-5 flex-shrink-0 place-items-center" style={item.iconContainerStyle}>
|
||||
{item.icon}
|
||||
</span>
|
||||
<p className="flex-grow truncate text-12">{query ? highlightMatch(item.title, query) : item.title}</p>
|
||||
|
|
|
|||
|
|
@ -137,7 +137,7 @@ export const SlashCommandsMenu = forwardRef(function SlashCommandsMenu(props: Sl
|
|||
<div
|
||||
id="slash-command"
|
||||
ref={commandListContainer}
|
||||
className="relative max-h-80 min-w-[12rem] overflow-y-auto rounded-md border-[0.5px] border-strong bg-surface-1 px-2 py-2.5 shadow-raised-200 space-y-2"
|
||||
className="relative max-h-80 min-w-[12rem] space-y-2 overflow-y-auto rounded-md border-[0.5px] border-strong bg-surface-1 px-2 py-2.5 shadow-raised-200"
|
||||
style={{
|
||||
zIndex: 100,
|
||||
}}
|
||||
|
|
|
|||
|
|
@ -49,23 +49,23 @@ export function TableDragHandleDropdownColorSelector(props: Props) {
|
|||
<Disclosure.Button
|
||||
as="button"
|
||||
type="button"
|
||||
className="flex items-center justify-between gap-2 w-full rounded-sm px-1 py-1.5 text-11 text-left truncate text-secondary hover:bg-layer-1"
|
||||
className="flex w-full items-center justify-between gap-2 truncate rounded-sm px-1 py-1.5 text-left text-11 text-secondary hover:bg-layer-1"
|
||||
>
|
||||
{({ open }) => (
|
||||
<>
|
||||
<span className="flex items-center gap-2">
|
||||
<Palette className="shrink-0 size-3" />
|
||||
<Palette className="size-3 shrink-0" />
|
||||
Color
|
||||
</span>
|
||||
<ChevronRightIcon
|
||||
className={cn("shrink-0 size-3 transition-transform duration-200", {
|
||||
className={cn("size-3 shrink-0 transition-transform duration-200", {
|
||||
"rotate-90": open,
|
||||
})}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</Disclosure.Button>
|
||||
<Disclosure.Panel className="p-1 space-y-2 mb-1.5">
|
||||
<Disclosure.Panel className="mb-1.5 space-y-2 p-1">
|
||||
{/* <div className="space-y-1.5">
|
||||
<p className="text-11 text-tertiary font-semibold">Text colors</p>
|
||||
<div className="flex items-center flex-wrap gap-2">
|
||||
|
|
@ -90,13 +90,13 @@ export function TableDragHandleDropdownColorSelector(props: Props) {
|
|||
</div>
|
||||
</div> */}
|
||||
<div className="space-y-1">
|
||||
<p className="text-11 text-tertiary font-semibold">Background colors</p>
|
||||
<div className="flex items-center flex-wrap gap-2">
|
||||
<p className="text-11 font-semibold text-tertiary">Background colors</p>
|
||||
<div className="flex flex-wrap items-center gap-2">
|
||||
{COLORS_LIST.map((color) => (
|
||||
<button
|
||||
key={color.key}
|
||||
type="button"
|
||||
className="flex-shrink-0 size-6 rounded-sm border-[0.5px] border-strong-1 hover:opacity-60 transition-opacity"
|
||||
className="size-6 flex-shrink-0 rounded-sm border-[0.5px] border-strong-1 transition-opacity hover:opacity-60"
|
||||
style={{
|
||||
backgroundColor: color.backgroundColor,
|
||||
}}
|
||||
|
|
@ -108,7 +108,7 @@ export function TableDragHandleDropdownColorSelector(props: Props) {
|
|||
))}
|
||||
<button
|
||||
type="button"
|
||||
className="flex-shrink-0 size-6 grid place-items-center rounded-sm text-tertiary border-[0.5px] border-strong-1 hover:bg-layer-1-hover transition-colors"
|
||||
className="grid size-6 flex-shrink-0 place-items-center rounded-sm border-[0.5px] border-strong-1 text-tertiary transition-colors hover:bg-layer-1-hover"
|
||||
onClick={() => {
|
||||
handleBackgroundColorChange(editor, null);
|
||||
onSelect(null);
|
||||
|
|
|
|||
|
|
@ -224,14 +224,14 @@ export function ColumnDragHandle(props: ColumnDragHandleProps) {
|
|||
|
||||
return (
|
||||
<>
|
||||
<div className="table-col-handle-container absolute z-20 top-0 left-0 flex justify-center items-center w-full -translate-y-1/2">
|
||||
<div className="table-col-handle-container absolute top-0 left-0 z-20 flex w-full -translate-y-1/2 items-center justify-center">
|
||||
<button
|
||||
ref={refs.setReference}
|
||||
{...getReferenceProps()}
|
||||
type="button"
|
||||
onMouseDown={handleMouseDown}
|
||||
className={cn("px-1 bg-layer-1 border border-strong-1 rounded-sm outline-none transition-all duration-200", {
|
||||
"!opacity-100 bg-accent-primary border-accent-strong": isDropdownOpen,
|
||||
className={cn("rounded-sm border border-strong-1 bg-layer-1 px-1 transition-all duration-200 outline-none", {
|
||||
"border-accent-strong bg-accent-primary !opacity-100": isDropdownOpen,
|
||||
"hover:bg-layer-1-hover": !isDropdownOpen,
|
||||
})}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ export function ColumnOptionsDropdown(props: Props) {
|
|||
<>
|
||||
<button
|
||||
type="button"
|
||||
className="flex items-center justify-between gap-2 w-full rounded-sm px-1 py-1.5 text-11 text-left truncate text-secondary hover:bg-layer-1"
|
||||
className="flex w-full items-center justify-between gap-2 truncate rounded-sm px-1 py-1.5 text-left text-11 text-secondary hover:bg-layer-1"
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
|
@ -84,7 +84,7 @@ export function ColumnOptionsDropdown(props: Props) {
|
|||
}}
|
||||
>
|
||||
<div className="flex-grow truncate">Header column</div>
|
||||
<ToggleRight className="shrink-0 size-3" />
|
||||
<ToggleRight className="size-3 shrink-0" />
|
||||
</button>
|
||||
<hr className="my-2 border-subtle" />
|
||||
<TableDragHandleDropdownColorSelector editor={editor} onSelect={onClose} />
|
||||
|
|
@ -92,7 +92,7 @@ export function ColumnOptionsDropdown(props: Props) {
|
|||
<button
|
||||
key={item.key}
|
||||
type="button"
|
||||
className="flex items-center gap-2 w-full rounded-sm px-1 py-1.5 text-11 text-left truncate text-secondary hover:bg-layer-1"
|
||||
className="flex w-full items-center gap-2 truncate rounded-sm px-1 py-1.5 text-left text-11 text-secondary hover:bg-layer-1"
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
|
@ -100,7 +100,7 @@ export function ColumnOptionsDropdown(props: Props) {
|
|||
onClose();
|
||||
}}
|
||||
>
|
||||
<item.icon className="shrink-0 size-3" />
|
||||
<item.icon className="size-3 shrink-0" />
|
||||
<div className="flex-grow truncate">{item.label}</div>
|
||||
</button>
|
||||
))}
|
||||
|
|
|
|||
|
|
@ -223,18 +223,18 @@ export function RowDragHandle(props: RowDragHandleProps) {
|
|||
|
||||
return (
|
||||
<>
|
||||
<div className="table-row-handle-container absolute z-20 top-0 left-0 flex justify-center items-center h-full -translate-x-1/2">
|
||||
<div className="table-row-handle-container absolute top-0 left-0 z-20 flex h-full -translate-x-1/2 items-center justify-center">
|
||||
<button
|
||||
ref={refs.setReference}
|
||||
{...getReferenceProps()}
|
||||
type="button"
|
||||
onMouseDown={handleMouseDown}
|
||||
className={cn("py-1 bg-layer-1 border border-strong-1 rounded-sm outline-none transition-all duration-200", {
|
||||
"!opacity-100 bg-accent-primary border-accent-strong": isDropdownOpen,
|
||||
className={cn("rounded-sm border border-strong-1 bg-layer-1 py-1 transition-all duration-200 outline-none", {
|
||||
"border-accent-strong bg-accent-primary !opacity-100": isDropdownOpen,
|
||||
"hover:bg-layer-1-hover": !isDropdownOpen,
|
||||
})}
|
||||
>
|
||||
<Ellipsis className="size-4 text-primary rotate-90" />
|
||||
<Ellipsis className="size-4 rotate-90 text-primary" />
|
||||
</button>
|
||||
</div>
|
||||
{isDropdownOpen && (
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ export function RowOptionsDropdown(props: Props) {
|
|||
<>
|
||||
<button
|
||||
type="button"
|
||||
className="flex items-center justify-between gap-2 w-full rounded-sm px-1 py-1.5 text-11 text-left truncate text-secondary hover:bg-layer-1"
|
||||
className="flex w-full items-center justify-between gap-2 truncate rounded-sm px-1 py-1.5 text-left text-11 text-secondary hover:bg-layer-1"
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
|
@ -84,7 +84,7 @@ export function RowOptionsDropdown(props: Props) {
|
|||
}}
|
||||
>
|
||||
<div className="flex-grow truncate">Header row</div>
|
||||
<ToggleRight className="shrink-0 size-3" />
|
||||
<ToggleRight className="size-3 shrink-0" />
|
||||
</button>
|
||||
<hr className="my-2 border-subtle" />
|
||||
<TableDragHandleDropdownColorSelector editor={editor} onSelect={onClose} />
|
||||
|
|
@ -92,7 +92,7 @@ export function RowOptionsDropdown(props: Props) {
|
|||
<button
|
||||
key={item.key}
|
||||
type="button"
|
||||
className="flex items-center gap-2 w-full rounded-sm px-1 py-1.5 text-11 text-left truncate text-secondary hover:bg-layer-1"
|
||||
className="flex w-full items-center gap-2 truncate rounded-sm px-1 py-1.5 text-left text-11 text-secondary hover:bg-layer-1"
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
|
@ -100,7 +100,7 @@ export function RowOptionsDropdown(props: Props) {
|
|||
onClose();
|
||||
}}
|
||||
>
|
||||
<item.icon className="shrink-0 size-3" />
|
||||
<item.icon className="size-3 shrink-0" />
|
||||
<div className="flex-grow truncate">{item.label}</div>
|
||||
</button>
|
||||
))}
|
||||
|
|
|
|||
|
|
@ -19,10 +19,10 @@ type EditorClassNameArgs = {
|
|||
|
||||
export const getEditorClassNames = ({ noBorder, borderOnFocus, containerClassName }: EditorClassNameArgs) =>
|
||||
cn(
|
||||
"w-full max-w-full sm:rounded-lg focus:outline-none focus:border-0",
|
||||
"w-full max-w-full focus:border-0 focus:outline-none sm:rounded-lg",
|
||||
{
|
||||
"border border-subtle-1": !noBorder,
|
||||
"focus:border border-strong": borderOnFocus,
|
||||
"border-strong focus:border": borderOnFocus,
|
||||
},
|
||||
containerClassName
|
||||
);
|
||||
|
|
|
|||
|
|
@ -11,10 +11,7 @@ import { CORE_EXTENSIONS } from "@/constants/extension";
|
|||
|
||||
type Direction = "up" | "down";
|
||||
|
||||
export const insertEmptyParagraphAtNodeBoundaries: (
|
||||
direction: Direction,
|
||||
nodeType: string
|
||||
) => KeyboardShortcutCommand =
|
||||
export const insertEmptyParagraphAtNodeBoundaries: (direction: Direction, nodeType: string) => KeyboardShortcutCommand =
|
||||
(direction, nodeType) =>
|
||||
({ editor }) => {
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ export const CoreEditorProps = (props: TArgs): EditorProps => {
|
|||
return {
|
||||
attributes: {
|
||||
class: cn(
|
||||
"prose prose-brand max-w-full prose-headings:font-display font-default focus:outline-none",
|
||||
"prose-brand prose-headings:font-display font-default max-w-full prose focus:outline-none",
|
||||
editorClassName
|
||||
),
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,10 +1,13 @@
|
|||
{
|
||||
"name": "@plane/hooks",
|
||||
"version": "1.2.0",
|
||||
"license": "AGPL-3.0",
|
||||
"description": "React hooks that are shared across multiple apps internally",
|
||||
"private": true,
|
||||
"description": "React hooks that are shared across multiple apps internally",
|
||||
"license": "AGPL-3.0",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
|
|
@ -17,9 +20,9 @@
|
|||
"dev": "tsdown --watch",
|
||||
"check:lint": "eslint . --cache --cache-location node_modules/.cache/eslint/ --max-warnings=60",
|
||||
"check:types": "tsc --noEmit",
|
||||
"check:format": "prettier . --cache --check",
|
||||
"check:format": "oxfmt --check .",
|
||||
"fix:lint": "eslint . --cache --cache-location node_modules/.cache/eslint/ --fix --max-warnings=60",
|
||||
"fix:format": "prettier . --cache --write",
|
||||
"fix:format": "oxfmt .",
|
||||
"clean": "rm -rf .turbo && rm -rf .next && rm -rf node_modules && rm -rf dist"
|
||||
},
|
||||
"dependencies": {
|
||||
|
|
@ -31,8 +34,5 @@
|
|||
"@types/react": "catalog:",
|
||||
"tsdown": "catalog:",
|
||||
"typescript": "catalog:"
|
||||
},
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,13 @@
|
|||
{
|
||||
"name": "@plane/i18n",
|
||||
"version": "1.2.0",
|
||||
"license": "AGPL-3.0",
|
||||
"description": "I18n shared across multiple apps internally",
|
||||
"private": true,
|
||||
"description": "I18n shared across multiple apps internally",
|
||||
"license": "AGPL-3.0",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
|
|
@ -17,9 +20,9 @@
|
|||
"build": "tsdown",
|
||||
"check:lint": "eslint . --cache --cache-location node_modules/.cache/eslint/ --max-warnings=51",
|
||||
"check:types": "tsc --noEmit",
|
||||
"check:format": "prettier . --cache --check",
|
||||
"check:format": "oxfmt --check .",
|
||||
"fix:lint": "eslint . --cache --cache-location node_modules/.cache/eslint/ --fix --max-warnings=51",
|
||||
"fix:format": "prettier . --cache --write",
|
||||
"fix:format": "oxfmt .",
|
||||
"clean": "rm -rf .turbo && rm -rf .next && rm -rf node_modules && rm -rf dist"
|
||||
},
|
||||
"dependencies": {
|
||||
|
|
@ -37,8 +40,5 @@
|
|||
"@types/react": "catalog:",
|
||||
"tsdown": "catalog:",
|
||||
"typescript": "catalog:"
|
||||
},
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,13 @@
|
|||
{
|
||||
"name": "@plane/logger",
|
||||
"version": "1.2.0",
|
||||
"license": "AGPL-3.0",
|
||||
"description": "Logger shared across multiple apps internally",
|
||||
"private": true,
|
||||
"description": "Logger shared across multiple apps internally",
|
||||
"license": "AGPL-3.0",
|
||||
"type": "module",
|
||||
"main": "./dist/index.mjs",
|
||||
"module": "./dist/index.mjs",
|
||||
"types": "./dist/index.d.mts",
|
||||
"exports": {
|
||||
".": "./dist/index.mjs",
|
||||
"./package.json": "./package.json"
|
||||
|
|
@ -14,9 +17,9 @@
|
|||
"dev": "tsdown --watch",
|
||||
"check:lint": "eslint . --cache --cache-location node_modules/.cache/eslint/ --max-warnings=0",
|
||||
"check:types": "tsc --noEmit",
|
||||
"check:format": "prettier . --cache --check",
|
||||
"check:format": "oxfmt --check .",
|
||||
"fix:lint": "eslint . --cache --cache-location node_modules/.cache/eslint/ --fix --max-warnings=0",
|
||||
"fix:format": "prettier . --cache --write",
|
||||
"fix:format": "oxfmt .",
|
||||
"clean": "rm -rf .turbo && rm -rf .next && rm -rf node_modules && rm -rf dist"
|
||||
},
|
||||
"dependencies": {
|
||||
|
|
@ -29,8 +32,5 @@
|
|||
"@types/node": "catalog:",
|
||||
"tsdown": "catalog:",
|
||||
"typescript": "catalog:"
|
||||
},
|
||||
"main": "./dist/index.mjs",
|
||||
"module": "./dist/index.mjs",
|
||||
"types": "./dist/index.d.mts"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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]) => (
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue