@neynar/ui 1.0.5 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/ui/resizable.js +2 -2
- package/dist/components/ui/resizable.js.map +1 -1
- package/dist/lib/variants.js +2 -2
- package/dist/lib/variants.js.map +1 -1
- package/llm/components/resizable.llm.md +47 -22
- package/package.json +2 -2
- package/src/components/neynar/typography/stories/title.stories.tsx +33 -0
- package/src/components/ui/resizable.tsx +2 -2
- package/src/lib/variants.ts +2 -2
|
@@ -32,11 +32,11 @@ function ResizableHandle({
|
|
|
32
32
|
{
|
|
33
33
|
"data-slot": "resizable-handle",
|
|
34
34
|
className: cn(
|
|
35
|
-
"bg-border focus-visible:ring-
|
|
35
|
+
"group bg-border focus-visible:ring-primary/50 focus-visible:bg-primary/50 relative flex w-px items-center justify-center after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 focus-visible:ring-1 focus-visible:ring-offset-1 focus-visible:ring-offset-background focus-visible:outline-hidden data-[resize-handle-state=hover]:bg-primary/50 data-[resize-handle-state=drag]:bg-primary/50 data-[resize-handle-state=active]:bg-primary/50 aria-[orientation=horizontal]:h-px aria-[orientation=horizontal]:w-full aria-[orientation=horizontal]:after:left-0 aria-[orientation=horizontal]:after:h-1 aria-[orientation=horizontal]:after:w-full aria-[orientation=horizontal]:after:translate-x-0 aria-[orientation=horizontal]:after:-translate-y-1/2 [&[aria-orientation=horizontal]>div]:rotate-90",
|
|
36
36
|
className
|
|
37
37
|
),
|
|
38
38
|
...props,
|
|
39
|
-
children: withHandle && /* @__PURE__ */ jsx("div", { className: "bg-border h-6 w-1 rounded-lg z-10 flex shrink-0" })
|
|
39
|
+
children: withHandle && /* @__PURE__ */ jsx("div", { className: "bg-border group-focus-visible:bg-primary/50 group-data-[resize-handle-state=hover]:bg-primary/50 group-data-[resize-handle-state=drag]:bg-primary/50 group-data-[resize-handle-state=active]:bg-primary/50 h-6 w-1 rounded-lg z-10 flex shrink-0" })
|
|
40
40
|
}
|
|
41
41
|
);
|
|
42
42
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resizable.js","sources":["../../../src/components/ui/resizable.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport {\n Group as PanelGroup,\n Panel,\n Separator as PanelResizeHandle,\n} from \"react-resizable-panels\";\n\nimport { cn } from \"@/lib/utils\";\n\ntype ResizablePanelGroupProps = React.ComponentProps<typeof PanelGroup>;\n\n/**\n * Container for resizable panels. Manages layout orientation and panel resizing behavior.\n * Supports both horizontal and vertical layouts with optional persistence via `id` prop.\n */\nfunction ResizablePanelGroup({\n className,\n ...props\n}: ResizablePanelGroupProps) {\n return (\n <PanelGroup\n data-slot=\"resizable-panel-group\"\n className={cn(\n \"flex h-full w-full aria-[orientation=vertical]:flex-col\",\n className,\n )}\n {...props}\n />\n );\n}\n\ntype ResizablePanelProps = React.ComponentProps<typeof Panel>;\n\n/**\n * Individual resizable panel within a ResizablePanelGroup.\n * Supports size constraints (minSize, maxSize), default sizing, and collapse behavior.\n */\nfunction ResizablePanel({ ...props }: ResizablePanelProps) {\n return <Panel data-slot=\"resizable-panel\" {...props} />;\n}\n\ntype ResizableHandleProps = React.ComponentProps<typeof PanelResizeHandle> & {\n /** Display a visible grip indicator on the resize handle. @default false */\n withHandle?: boolean;\n};\n\n/**\n * Resize handle between panels. Appears as a thin line with optional visible grip indicator.\n * Supports keyboard navigation and focus states.\n */\nfunction ResizableHandle({\n withHandle,\n className,\n ...props\n}: ResizableHandleProps) {\n return (\n <PanelResizeHandle\n data-slot=\"resizable-handle\"\n className={cn(\n \"bg-border focus-visible:ring-
|
|
1
|
+
{"version":3,"file":"resizable.js","sources":["../../../src/components/ui/resizable.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport {\n Group as PanelGroup,\n Panel,\n Separator as PanelResizeHandle,\n} from \"react-resizable-panels\";\n\nimport { cn } from \"@/lib/utils\";\n\ntype ResizablePanelGroupProps = React.ComponentProps<typeof PanelGroup>;\n\n/**\n * Container for resizable panels. Manages layout orientation and panel resizing behavior.\n * Supports both horizontal and vertical layouts with optional persistence via `id` prop.\n */\nfunction ResizablePanelGroup({\n className,\n ...props\n}: ResizablePanelGroupProps) {\n return (\n <PanelGroup\n data-slot=\"resizable-panel-group\"\n className={cn(\n \"flex h-full w-full aria-[orientation=vertical]:flex-col\",\n className,\n )}\n {...props}\n />\n );\n}\n\ntype ResizablePanelProps = React.ComponentProps<typeof Panel>;\n\n/**\n * Individual resizable panel within a ResizablePanelGroup.\n * Supports size constraints (minSize, maxSize), default sizing, and collapse behavior.\n */\nfunction ResizablePanel({ ...props }: ResizablePanelProps) {\n return <Panel data-slot=\"resizable-panel\" {...props} />;\n}\n\ntype ResizableHandleProps = React.ComponentProps<typeof PanelResizeHandle> & {\n /** Display a visible grip indicator on the resize handle. @default false */\n withHandle?: boolean;\n};\n\n/**\n * Resize handle between panels. Appears as a thin line with optional visible grip indicator.\n * Supports keyboard navigation and focus states.\n */\nfunction ResizableHandle({\n withHandle,\n className,\n ...props\n}: ResizableHandleProps) {\n return (\n <PanelResizeHandle\n data-slot=\"resizable-handle\"\n className={cn(\n \"group bg-border focus-visible:ring-primary/50 focus-visible:bg-primary/50 relative flex w-px items-center justify-center after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 focus-visible:ring-1 focus-visible:ring-offset-1 focus-visible:ring-offset-background focus-visible:outline-hidden data-[resize-handle-state=hover]:bg-primary/50 data-[resize-handle-state=drag]:bg-primary/50 data-[resize-handle-state=active]:bg-primary/50 aria-[orientation=horizontal]:h-px aria-[orientation=horizontal]:w-full aria-[orientation=horizontal]:after:left-0 aria-[orientation=horizontal]:after:h-1 aria-[orientation=horizontal]:after:w-full aria-[orientation=horizontal]:after:translate-x-0 aria-[orientation=horizontal]:after:-translate-y-1/2 [&[aria-orientation=horizontal]>div]:rotate-90\",\n className,\n )}\n {...props}\n >\n {withHandle && (\n <div className=\"bg-border group-focus-visible:bg-primary/50 group-data-[resize-handle-state=hover]:bg-primary/50 group-data-[resize-handle-state=drag]:bg-primary/50 group-data-[resize-handle-state=active]:bg-primary/50 h-6 w-1 rounded-lg z-10 flex shrink-0\" />\n )}\n </PanelResizeHandle>\n );\n}\n\nexport {\n ResizablePanelGroup,\n ResizablePanel,\n ResizableHandle,\n type ResizablePanelGroupProps,\n type ResizablePanelProps,\n type ResizableHandleProps,\n};\n"],"names":["PanelGroup","PanelResizeHandle"],"mappings":";;;;;AAiBA;AAA6B;AAC3B;AAEF;AACE;AACE;AAACA;AAAA;AACW;AACC;AACT;AACA;AAAA;AAEE;AAAA;AAGV;AAQA;AACE;AACF;AAWA;AAAyB;AACvB;AACA;AAEF;AACE;AACE;AAACC;AAAA;AACW;AACC;AACT;AACA;AAAA;AAEE;AAGgQ;AAAA;AAI1Q;;;;;;"}
|
package/dist/lib/variants.js
CHANGED
|
@@ -75,8 +75,8 @@ const titleVariants = cva("", {
|
|
|
75
75
|
"2xl": "text-2xl leading-8 tracking-tight",
|
|
76
76
|
"3xl": "text-3xl leading-9 tracking-tight",
|
|
77
77
|
"4xl": "text-4xl leading-10 tracking-tighter",
|
|
78
|
-
"5xl": "text-5xl leading-
|
|
79
|
-
"6xl": "text-6xl leading-
|
|
78
|
+
"5xl": "text-5xl leading-[1.1] tracking-tighter",
|
|
79
|
+
"6xl": "text-6xl leading-[1.1] tracking-tighter"
|
|
80
80
|
},
|
|
81
81
|
weight: {
|
|
82
82
|
normal: "font-normal",
|
package/dist/lib/variants.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"variants.js","sources":["../../src/lib/variants.ts"],"sourcesContent":["/**\n * @internal\n * Shared CVA variants used by menu and typography components.\n * Not exported publicly - use component props instead:\n * - Menu styling: <DropdownMenuItem variant=\"destructive\">\n * - Typography: <Text color=\"muted\" size=\"sm\">\n */\n\nimport { cva } from \"class-variance-authority\";\n\n/**\n * Shared menu item variants for DropdownMenuItem, ContextMenuItem, and MenubarItem.\n * Provides consistent styling across all menu-style components.\n */\nexport const menuItemVariants = cva(\n \"gap-2 rounded-sm px-2 py-1.5 text-sm [&_svg:not([class*='size-'])]:size-4 relative flex cursor-default items-center outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0\",\n {\n variants: {\n variant: {\n default:\n \"focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground\",\n destructive:\n \"text-destructive focus:bg-destructive/10 dark:focus:bg-destructive/20 focus:text-destructive *:[svg]:text-destructive\",\n success:\n \"text-success focus:bg-success/10 dark:focus:bg-success/20 focus:text-success *:[svg]:text-success\",\n warning:\n \"text-warning focus:bg-warning/10 dark:focus:bg-warning/20 focus:text-warning *:[svg]:text-warning\",\n info: \"text-info focus:bg-info/10 dark:focus:bg-info/20 focus:text-info *:[svg]:text-info\",\n },\n inset: {\n true: \"pl-8\",\n false: \"\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n inset: false,\n },\n },\n);\n\n/** Variant options for menu items: default, destructive, success, warning, info */\nexport type MenuItemVariant =\n | \"default\"\n | \"destructive\"\n | \"success\"\n | \"warning\"\n | \"info\";\n\n/**\n * Typography color variants shared across Title, Text, Code, and Blockquote components.\n * Provides semantic color options for consistent text styling.\n *\n * @example\n * ```tsx\n * import { typographyColorVariants } from \"@neynar/ui/lib/variants\"\n * import { cn } from \"@neynar/ui/lib/utils\"\n *\n * <span className={cn(typographyColorVariants({ color: \"muted\" }))}>\n * Secondary text\n * </span>\n * ```\n */\nexport const typographyColorVariants = cva(\"\", {\n variants: {\n color: {\n default: \"text-foreground\",\n muted: \"text-muted-foreground\",\n subtle: \"text-subtle-foreground\",\n destructive: \"text-destructive\",\n success: \"text-success\",\n warning: \"text-warning\",\n info: \"text-info\",\n },\n },\n defaultVariants: {\n color: \"default\",\n },\n});\n\n/** Semantic color options for typography: default, muted, subtle, destructive, success, warning, info */\nexport type TypographyColor =\n | \"default\"\n | \"muted\"\n | \"subtle\"\n | \"destructive\"\n | \"success\"\n | \"warning\"\n | \"info\";\n\n/**\n * Title order-based size defaults (only used when size prop is not specified).\n * Maps heading levels (h1-h6) to responsive font sizes.\n *\n * @example\n * ```tsx\n * // order: 1 → \"text-3xl md:text-4xl lg:text-5xl\"\n * // order: 6 → \"text-sm md:text-base lg:text-lg\"\n * ```\n */\nexport const titleOrderSizeVariants = cva(\"\", {\n variants: {\n order: {\n 1: \"text-3xl md:text-4xl lg:text-5xl\",\n 2: \"text-2xl md:text-3xl lg:text-4xl\",\n 3: \"text-xl md:text-2xl lg:text-3xl\",\n 4: \"text-lg md:text-xl lg:text-2xl\",\n 5: \"text-base md:text-lg lg:text-xl\",\n 6: \"text-sm md:text-base lg:text-lg\",\n },\n },\n});\n\n/**\n * Title order-based style defaults (weight, tracking, leading).\n * Provides appropriate font-weight and line-height for each heading level.\n *\n * @example\n * ```tsx\n * // order: 1 → \"font-bold tracking-tight leading-[1.1]\"\n * // order: 6 → \"font-medium leading-normal\"\n * ```\n */\nexport const titleOrderStyleVariants = cva(\"\", {\n variants: {\n order: {\n 1: \"font-bold tracking-tight leading-[1.1]\",\n 2: \"font-semibold tracking-tight leading-[1.2]\",\n 3: \"font-semibold tracking-tight leading-[1.25]\",\n 4: \"font-semibold leading-[1.3]\",\n 5: \"font-medium leading-[1.4]\",\n 6: \"font-medium leading-normal\",\n },\n },\n defaultVariants: {\n order: 2,\n },\n});\n\n/**\n * Title component variants for explicit size and weight overrides.\n * Use when you need to override the order-based defaults.\n *\n * @example\n * ```tsx\n * import { titleVariants } from \"@neynar/ui/lib/variants\"\n * import { cn } from \"@neynar/ui/lib/utils\"\n *\n * <h2 className={cn(titleVariants({ size: \"4xl\", weight: \"bold\" }))}>\n * Large Bold Title\n * </h2>\n * ```\n */\nexport const titleVariants = cva(\"\", {\n variants: {\n size: {\n xs: \"text-xs leading-4\",\n sm: \"text-sm leading-5\",\n base: \"text-base leading-6\",\n lg: \"text-lg leading-7\",\n xl: \"text-xl leading-7 tracking-tight\",\n \"2xl\": \"text-2xl leading-8 tracking-tight\",\n \"3xl\": \"text-3xl leading-9 tracking-tight\",\n \"4xl\": \"text-4xl leading-10 tracking-tighter\",\n \"5xl\": \"text-5xl leading-
|
|
1
|
+
{"version":3,"file":"variants.js","sources":["../../src/lib/variants.ts"],"sourcesContent":["/**\n * @internal\n * Shared CVA variants used by menu and typography components.\n * Not exported publicly - use component props instead:\n * - Menu styling: <DropdownMenuItem variant=\"destructive\">\n * - Typography: <Text color=\"muted\" size=\"sm\">\n */\n\nimport { cva } from \"class-variance-authority\";\n\n/**\n * Shared menu item variants for DropdownMenuItem, ContextMenuItem, and MenubarItem.\n * Provides consistent styling across all menu-style components.\n */\nexport const menuItemVariants = cva(\n \"gap-2 rounded-sm px-2 py-1.5 text-sm [&_svg:not([class*='size-'])]:size-4 relative flex cursor-default items-center outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0\",\n {\n variants: {\n variant: {\n default:\n \"focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground\",\n destructive:\n \"text-destructive focus:bg-destructive/10 dark:focus:bg-destructive/20 focus:text-destructive *:[svg]:text-destructive\",\n success:\n \"text-success focus:bg-success/10 dark:focus:bg-success/20 focus:text-success *:[svg]:text-success\",\n warning:\n \"text-warning focus:bg-warning/10 dark:focus:bg-warning/20 focus:text-warning *:[svg]:text-warning\",\n info: \"text-info focus:bg-info/10 dark:focus:bg-info/20 focus:text-info *:[svg]:text-info\",\n },\n inset: {\n true: \"pl-8\",\n false: \"\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n inset: false,\n },\n },\n);\n\n/** Variant options for menu items: default, destructive, success, warning, info */\nexport type MenuItemVariant =\n | \"default\"\n | \"destructive\"\n | \"success\"\n | \"warning\"\n | \"info\";\n\n/**\n * Typography color variants shared across Title, Text, Code, and Blockquote components.\n * Provides semantic color options for consistent text styling.\n *\n * @example\n * ```tsx\n * import { typographyColorVariants } from \"@neynar/ui/lib/variants\"\n * import { cn } from \"@neynar/ui/lib/utils\"\n *\n * <span className={cn(typographyColorVariants({ color: \"muted\" }))}>\n * Secondary text\n * </span>\n * ```\n */\nexport const typographyColorVariants = cva(\"\", {\n variants: {\n color: {\n default: \"text-foreground\",\n muted: \"text-muted-foreground\",\n subtle: \"text-subtle-foreground\",\n destructive: \"text-destructive\",\n success: \"text-success\",\n warning: \"text-warning\",\n info: \"text-info\",\n },\n },\n defaultVariants: {\n color: \"default\",\n },\n});\n\n/** Semantic color options for typography: default, muted, subtle, destructive, success, warning, info */\nexport type TypographyColor =\n | \"default\"\n | \"muted\"\n | \"subtle\"\n | \"destructive\"\n | \"success\"\n | \"warning\"\n | \"info\";\n\n/**\n * Title order-based size defaults (only used when size prop is not specified).\n * Maps heading levels (h1-h6) to responsive font sizes.\n *\n * @example\n * ```tsx\n * // order: 1 → \"text-3xl md:text-4xl lg:text-5xl\"\n * // order: 6 → \"text-sm md:text-base lg:text-lg\"\n * ```\n */\nexport const titleOrderSizeVariants = cva(\"\", {\n variants: {\n order: {\n 1: \"text-3xl md:text-4xl lg:text-5xl\",\n 2: \"text-2xl md:text-3xl lg:text-4xl\",\n 3: \"text-xl md:text-2xl lg:text-3xl\",\n 4: \"text-lg md:text-xl lg:text-2xl\",\n 5: \"text-base md:text-lg lg:text-xl\",\n 6: \"text-sm md:text-base lg:text-lg\",\n },\n },\n});\n\n/**\n * Title order-based style defaults (weight, tracking, leading).\n * Provides appropriate font-weight and line-height for each heading level.\n *\n * @example\n * ```tsx\n * // order: 1 → \"font-bold tracking-tight leading-[1.1]\"\n * // order: 6 → \"font-medium leading-normal\"\n * ```\n */\nexport const titleOrderStyleVariants = cva(\"\", {\n variants: {\n order: {\n 1: \"font-bold tracking-tight leading-[1.1]\",\n 2: \"font-semibold tracking-tight leading-[1.2]\",\n 3: \"font-semibold tracking-tight leading-[1.25]\",\n 4: \"font-semibold leading-[1.3]\",\n 5: \"font-medium leading-[1.4]\",\n 6: \"font-medium leading-normal\",\n },\n },\n defaultVariants: {\n order: 2,\n },\n});\n\n/**\n * Title component variants for explicit size and weight overrides.\n * Use when you need to override the order-based defaults.\n *\n * @example\n * ```tsx\n * import { titleVariants } from \"@neynar/ui/lib/variants\"\n * import { cn } from \"@neynar/ui/lib/utils\"\n *\n * <h2 className={cn(titleVariants({ size: \"4xl\", weight: \"bold\" }))}>\n * Large Bold Title\n * </h2>\n * ```\n */\nexport const titleVariants = cva(\"\", {\n variants: {\n size: {\n xs: \"text-xs leading-4\",\n sm: \"text-sm leading-5\",\n base: \"text-base leading-6\",\n lg: \"text-lg leading-7\",\n xl: \"text-xl leading-7 tracking-tight\",\n \"2xl\": \"text-2xl leading-8 tracking-tight\",\n \"3xl\": \"text-3xl leading-9 tracking-tight\",\n \"4xl\": \"text-4xl leading-10 tracking-tighter\",\n \"5xl\": \"text-5xl leading-[1.1] tracking-tighter\",\n \"6xl\": \"text-6xl leading-[1.1] tracking-tighter\",\n },\n weight: {\n normal: \"font-normal\",\n medium: \"font-medium\",\n semibold: \"font-semibold\",\n bold: \"font-bold\",\n },\n },\n});\n\n/** Heading level 1-6, maps to h1-h6 elements */\nexport type TitleOrder = 1 | 2 | 3 | 4 | 5 | 6;\n\n/** Font size options from xs to 6xl */\nexport type TitleSize =\n | \"xs\"\n | \"sm\"\n | \"base\"\n | \"lg\"\n | \"xl\"\n | \"2xl\"\n | \"3xl\"\n | \"4xl\"\n | \"5xl\"\n | \"6xl\";\n\n/** Font weight options: normal, medium, semibold, bold */\nexport type TitleWeight = \"normal\" | \"medium\" | \"semibold\" | \"bold\";\n\n/**\n * Text component variants with auto-scaling line-height and letter-spacing.\n * Provides consistent paragraph and body text styling.\n *\n * @example\n * ```tsx\n * import { textVariants } from \"@neynar/ui/lib/variants\"\n * import { cn } from \"@neynar/ui/lib/utils\"\n *\n * <p className={cn(textVariants({ size: \"lg\", weight: \"medium\", align: \"center\" }))}>\n * Centered large text\n * </p>\n * ```\n */\nexport const textVariants = cva(\"\", {\n variants: {\n size: {\n xs: \"text-xs leading-4\",\n sm: \"text-sm leading-5\",\n base: \"text-base leading-6\",\n lg: \"text-lg leading-7\",\n xl: \"text-xl leading-7 tracking-tight\",\n \"2xl\": \"text-2xl leading-8 tracking-tighter\",\n },\n weight: {\n normal: \"font-normal\",\n medium: \"font-medium\",\n semibold: \"font-semibold\",\n bold: \"font-bold\",\n },\n align: {\n left: \"text-left\",\n center: \"text-center\",\n right: \"text-right\",\n },\n transform: {\n uppercase: \"uppercase tracking-wider\",\n lowercase: \"lowercase\",\n capitalize: \"capitalize\",\n },\n },\n defaultVariants: {\n size: \"base\",\n },\n});\n"],"names":[],"mappings":";AAcO,MAAM,mBAAmB;AAAA,EAC9B;AAAA,EACA;AAAA,IACE,UAAU;AAAA,MACR,SAAS;AAAA,QACP,SACE;AAAA,QACF,aACE;AAAA,QACF,SACE;AAAA,QACF,SACE;AAAA,QACF,MAAM;AAAA,MAAA;AAAA,MAER,OAAO;AAAA,QACL,MAAM;AAAA,QACN,OAAO;AAAA,MAAA;AAAA,IACT;AAAA,IAEF,iBAAiB;AAAA,MACf,SAAS;AAAA,MACT,OAAO;AAAA,IAAA;AAAA,EACT;AAEJ;AAwBO,MAAM,0BAA0B,IAAI,IAAI;AAAA,EAC7C,UAAU;AAAA,IACR,OAAO;AAAA,MACL,SAAS;AAAA,MACT,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,SAAS;AAAA,MACT,SAAS;AAAA,MACT,MAAM;AAAA,IAAA;AAAA,EACR;AAAA,EAEF,iBAAiB;AAAA,IACf,OAAO;AAAA,EAAA;AAEX,CAAC;AAsBM,MAAM,yBAAyB,IAAI,IAAI;AAAA,EAC5C,UAAU;AAAA,IACR,OAAO;AAAA,MACL,GAAG;AAAA,MACH,GAAG;AAAA,MACH,GAAG;AAAA,MACH,GAAG;AAAA,MACH,GAAG;AAAA,MACH,GAAG;AAAA,IAAA;AAAA,EACL;AAEJ,CAAC;AAYM,MAAM,0BAA0B,IAAI,IAAI;AAAA,EAC7C,UAAU;AAAA,IACR,OAAO;AAAA,MACL,GAAG;AAAA,MACH,GAAG;AAAA,MACH,GAAG;AAAA,MACH,GAAG;AAAA,MACH,GAAG;AAAA,MACH,GAAG;AAAA,IAAA;AAAA,EACL;AAAA,EAEF,iBAAiB;AAAA,IACf,OAAO;AAAA,EAAA;AAEX,CAAC;AAgBM,MAAM,gBAAgB,IAAI,IAAI;AAAA,EACnC,UAAU;AAAA,IACR,MAAM;AAAA,MACJ,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,OAAO;AAAA,MACP,OAAO;AAAA,MACP,OAAO;AAAA,MACP,OAAO;AAAA,MACP,OAAO;AAAA,IAAA;AAAA,IAET,QAAQ;AAAA,MACN,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,MAAM;AAAA,IAAA;AAAA,EACR;AAEJ,CAAC;AAmCM,MAAM,eAAe,IAAI,IAAI;AAAA,EAClC,UAAU;AAAA,IACR,MAAM;AAAA,MACJ,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,OAAO;AAAA,IAAA;AAAA,IAET,QAAQ;AAAA,MACN,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,MAAM;AAAA,IAAA;AAAA,IAER,OAAO;AAAA,MACL,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,OAAO;AAAA,IAAA;AAAA,IAET,WAAW;AAAA,MACT,WAAW;AAAA,MACX,WAAW;AAAA,MACX,YAAY;AAAA,IAAA;AAAA,EACd;AAAA,EAEF,iBAAiB;AAAA,IACf,MAAM;AAAA,EAAA;AAEV,CAAC;"}
|
|
@@ -16,16 +16,20 @@ import {
|
|
|
16
16
|
|
|
17
17
|
```tsx
|
|
18
18
|
<ResizablePanelGroup orientation="horizontal">
|
|
19
|
-
<ResizablePanel defaultSize=
|
|
19
|
+
<ResizablePanel defaultSize="50%">
|
|
20
20
|
Content 1
|
|
21
21
|
</ResizablePanel>
|
|
22
22
|
<ResizableHandle />
|
|
23
|
-
<ResizablePanel defaultSize=
|
|
23
|
+
<ResizablePanel defaultSize="50%">
|
|
24
24
|
Content 2
|
|
25
25
|
</ResizablePanel>
|
|
26
26
|
</ResizablePanelGroup>
|
|
27
27
|
```
|
|
28
28
|
|
|
29
|
+
**Important:** Size values have different meanings based on type:
|
|
30
|
+
- **Numbers are pixels:** `defaultSize={300}` = 300px
|
|
31
|
+
- **Strings are percentages:** `defaultSize="25%"` or `defaultSize="25"` = 25%
|
|
32
|
+
|
|
29
33
|
## Components
|
|
30
34
|
|
|
31
35
|
| Component | Description |
|
|
@@ -51,14 +55,21 @@ import {
|
|
|
51
55
|
|
|
52
56
|
All panels inherit props from react-resizable-panels Panel component.
|
|
53
57
|
|
|
58
|
+
**Size Value Formats:**
|
|
59
|
+
- **number** (e.g., `500`) → Pixels
|
|
60
|
+
- **string without unit** (e.g., `"25"`) → Percentage (0-100)
|
|
61
|
+
- **string with %** (e.g., `"25%"`) → Percentage
|
|
62
|
+
- **string with px** (e.g., `"300px"`) → Pixels
|
|
63
|
+
- **string with other units** (e.g., `"1rem"`, `"50vh"`) → CSS units
|
|
64
|
+
|
|
54
65
|
| Prop | Type | Default | Description |
|
|
55
66
|
|------|------|---------|-------------|
|
|
56
67
|
| id | string | - | Panel identifier (required for persistence) |
|
|
57
|
-
| defaultSize | number | - | Initial size
|
|
58
|
-
| minSize | number | 0 | Minimum size
|
|
59
|
-
| maxSize | number | 100 | Maximum size
|
|
68
|
+
| defaultSize | number \| string | - | Initial size (number=pixels, string=percentage or CSS unit) |
|
|
69
|
+
| minSize | number \| string | 0 | Minimum size (number=pixels, string=percentage or CSS unit) |
|
|
70
|
+
| maxSize | number \| string | 100 | Maximum size (number=pixels, string=percentage or CSS unit) |
|
|
60
71
|
| collapsible | boolean | false | Allow panel to collapse below minSize |
|
|
61
|
-
| collapsedSize | number | 0 | Size when collapsed |
|
|
72
|
+
| collapsedSize | number \| string | 0 | Size when collapsed |
|
|
62
73
|
| onResize | (size: { asPercentage: number; inPixels: number }) => void | - | Called when panel is resized |
|
|
63
74
|
| className | string | - | Additional CSS classes |
|
|
64
75
|
|
|
@@ -80,29 +91,43 @@ All panels inherit props from react-resizable-panels Panel component.
|
|
|
80
91
|
|
|
81
92
|
## Examples
|
|
82
93
|
|
|
83
|
-
### Basic Horizontal Layout
|
|
94
|
+
### Basic Horizontal Layout (Percentages)
|
|
84
95
|
|
|
85
96
|
```tsx
|
|
86
97
|
<ResizablePanelGroup orientation="horizontal">
|
|
87
|
-
<ResizablePanel defaultSize=
|
|
98
|
+
<ResizablePanel defaultSize="40%">
|
|
88
99
|
<div className="p-4">Sidebar</div>
|
|
89
100
|
</ResizablePanel>
|
|
90
101
|
<ResizableHandle />
|
|
91
|
-
<ResizablePanel defaultSize=
|
|
102
|
+
<ResizablePanel defaultSize="60%">
|
|
92
103
|
<div className="p-4">Main Content</div>
|
|
93
104
|
</ResizablePanel>
|
|
94
105
|
</ResizablePanelGroup>
|
|
95
106
|
```
|
|
96
107
|
|
|
108
|
+
### Fixed Pixel Sidebar
|
|
109
|
+
|
|
110
|
+
```tsx
|
|
111
|
+
<ResizablePanelGroup orientation="horizontal">
|
|
112
|
+
<ResizablePanel defaultSize={300} minSize={200} maxSize={500}>
|
|
113
|
+
<div className="p-4">Fixed width sidebar (300px default)</div>
|
|
114
|
+
</ResizablePanel>
|
|
115
|
+
<ResizableHandle withHandle />
|
|
116
|
+
<ResizablePanel>
|
|
117
|
+
<div className="p-4">Main content fills remaining space</div>
|
|
118
|
+
</ResizablePanel>
|
|
119
|
+
</ResizablePanelGroup>
|
|
120
|
+
```
|
|
121
|
+
|
|
97
122
|
### Vertical Split with Handle
|
|
98
123
|
|
|
99
124
|
```tsx
|
|
100
125
|
<ResizablePanelGroup orientation="vertical">
|
|
101
|
-
<ResizablePanel defaultSize=
|
|
126
|
+
<ResizablePanel defaultSize="70%">
|
|
102
127
|
<div className="p-4">Editor</div>
|
|
103
128
|
</ResizablePanel>
|
|
104
129
|
<ResizableHandle withHandle />
|
|
105
|
-
<ResizablePanel defaultSize=
|
|
130
|
+
<ResizablePanel defaultSize="30%">
|
|
106
131
|
<div className="p-4">Terminal Output</div>
|
|
107
132
|
</ResizablePanel>
|
|
108
133
|
</ResizablePanelGroup>
|
|
@@ -112,15 +137,15 @@ All panels inherit props from react-resizable-panels Panel component.
|
|
|
112
137
|
|
|
113
138
|
```tsx
|
|
114
139
|
<ResizablePanelGroup orientation="horizontal">
|
|
115
|
-
<ResizablePanel defaultSize=
|
|
140
|
+
<ResizablePanel defaultSize="25%" minSize="15%" maxSize="40%">
|
|
116
141
|
<div className="p-4">Navigation</div>
|
|
117
142
|
</ResizablePanel>
|
|
118
143
|
<ResizableHandle withHandle />
|
|
119
|
-
<ResizablePanel defaultSize=
|
|
144
|
+
<ResizablePanel defaultSize="50%" minSize="30%">
|
|
120
145
|
<div className="p-4">Content</div>
|
|
121
146
|
</ResizablePanel>
|
|
122
147
|
<ResizableHandle withHandle />
|
|
123
|
-
<ResizablePanel defaultSize=
|
|
148
|
+
<ResizablePanel defaultSize="25%" minSize="15%" maxSize="40%">
|
|
124
149
|
<div className="p-4">Inspector</div>
|
|
125
150
|
</ResizablePanel>
|
|
126
151
|
</ResizablePanelGroup>
|
|
@@ -130,17 +155,17 @@ All panels inherit props from react-resizable-panels Panel component.
|
|
|
130
155
|
|
|
131
156
|
```tsx
|
|
132
157
|
<ResizablePanelGroup orientation="horizontal">
|
|
133
|
-
<ResizablePanel defaultSize={
|
|
134
|
-
<div className="p-4">File Explorer</div>
|
|
158
|
+
<ResizablePanel defaultSize={250} minSize={150}>
|
|
159
|
+
<div className="p-4">File Explorer (250px)</div>
|
|
135
160
|
</ResizablePanel>
|
|
136
161
|
<ResizableHandle withHandle />
|
|
137
|
-
<ResizablePanel
|
|
162
|
+
<ResizablePanel>
|
|
138
163
|
<ResizablePanelGroup orientation="vertical">
|
|
139
|
-
<ResizablePanel defaultSize=
|
|
164
|
+
<ResizablePanel defaultSize="70%">
|
|
140
165
|
<div className="p-4">Code Editor</div>
|
|
141
166
|
</ResizablePanel>
|
|
142
167
|
<ResizableHandle withHandle />
|
|
143
|
-
<ResizablePanel defaultSize=
|
|
168
|
+
<ResizablePanel defaultSize="30%" minSize="20%">
|
|
144
169
|
<div className="p-4">Terminal</div>
|
|
145
170
|
</ResizablePanel>
|
|
146
171
|
</ResizablePanelGroup>
|
|
@@ -157,11 +182,11 @@ function Dashboard() {
|
|
|
157
182
|
id="dashboard-layout"
|
|
158
183
|
orientation="horizontal"
|
|
159
184
|
>
|
|
160
|
-
<ResizablePanel id="sidebar" defaultSize=
|
|
185
|
+
<ResizablePanel id="sidebar" defaultSize="25%">
|
|
161
186
|
<div className="p-4">Sidebar</div>
|
|
162
187
|
</ResizablePanel>
|
|
163
188
|
<ResizableHandle />
|
|
164
|
-
<ResizablePanel id="main" defaultSize=
|
|
189
|
+
<ResizablePanel id="main" defaultSize="75%">
|
|
165
190
|
<div className="p-4">Main Content</div>
|
|
166
191
|
</ResizablePanel>
|
|
167
192
|
</ResizablePanelGroup>
|
|
@@ -185,7 +210,7 @@ function MonitoredPanels() {
|
|
|
185
210
|
})
|
|
186
211
|
}}
|
|
187
212
|
>
|
|
188
|
-
<ResizablePanel id="left" defaultSize=
|
|
213
|
+
<ResizablePanel id="left" defaultSize="30%">
|
|
189
214
|
<div className="p-4">Left: {sizes.left.toFixed(1)}%</div>
|
|
190
215
|
</ResizablePanel>
|
|
191
216
|
<ResizableHandle withHandle />
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@neynar/ui",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": "Neynar Inc.",
|
|
6
6
|
"description": "AI-first React component library for coding agents. LLM-optimized docs, sensible defaults, zero config. Built on shadcn patterns, Base UI, and Tailwind CSS v4.",
|
|
@@ -272,7 +272,7 @@
|
|
|
272
272
|
"clean": "rm -rf dist",
|
|
273
273
|
"docs:generate": "tsx scripts/llm-tsdoc-generator/index.ts llm-tsdoc-generator.config.json",
|
|
274
274
|
"storybook": "storybook dev --no-open -p 6006",
|
|
275
|
-
"build-storybook": "storybook build"
|
|
275
|
+
"build-storybook": "STORYBOOK_BASE_PATH=/ui/ storybook build"
|
|
276
276
|
},
|
|
277
277
|
"devDependencies": {
|
|
278
278
|
"@eslint/js": "^9.39.2",
|
|
@@ -331,6 +331,39 @@ export const Variants: Story = {
|
|
|
331
331
|
),
|
|
332
332
|
};
|
|
333
333
|
|
|
334
|
+
/**
|
|
335
|
+
* Large multi-line titles demonstrating proper line-height for 5xl and 6xl sizes.
|
|
336
|
+
* These sizes use leading-[1.1] to prevent text overlap on wrapped lines.
|
|
337
|
+
*/
|
|
338
|
+
export const LargeMultiLine: Story = {
|
|
339
|
+
parameters: {
|
|
340
|
+
layout: "padded",
|
|
341
|
+
},
|
|
342
|
+
render: () => (
|
|
343
|
+
<div className="w-full max-w-2xl space-y-8">
|
|
344
|
+
<section className="space-y-4">
|
|
345
|
+
<div>
|
|
346
|
+
<h3 className="text-lg font-semibold">Large Sizes with Multi-line Text</h3>
|
|
347
|
+
<p className="text-muted-foreground text-sm">
|
|
348
|
+
5xl and 6xl sizes with proper line-height to prevent text overlap.
|
|
349
|
+
</p>
|
|
350
|
+
</div>
|
|
351
|
+
<div className="space-y-6 border rounded-lg p-6">
|
|
352
|
+
<Title order={1} size="6xl">
|
|
353
|
+
Building the Future of Social Networks Together
|
|
354
|
+
</Title>
|
|
355
|
+
<Title order={1} size="5xl">
|
|
356
|
+
Decentralized Identity for the Next Generation of Apps
|
|
357
|
+
</Title>
|
|
358
|
+
<Title order={1} size="4xl">
|
|
359
|
+
Create, Connect, and Collaborate on Farcaster
|
|
360
|
+
</Title>
|
|
361
|
+
</div>
|
|
362
|
+
</section>
|
|
363
|
+
</div>
|
|
364
|
+
),
|
|
365
|
+
};
|
|
366
|
+
|
|
334
367
|
/**
|
|
335
368
|
* Interactive playground for testing Title props.
|
|
336
369
|
*/
|
|
@@ -59,13 +59,13 @@ function ResizableHandle({
|
|
|
59
59
|
<PanelResizeHandle
|
|
60
60
|
data-slot="resizable-handle"
|
|
61
61
|
className={cn(
|
|
62
|
-
"bg-border focus-visible:ring-
|
|
62
|
+
"group bg-border focus-visible:ring-primary/50 focus-visible:bg-primary/50 relative flex w-px items-center justify-center after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 focus-visible:ring-1 focus-visible:ring-offset-1 focus-visible:ring-offset-background focus-visible:outline-hidden data-[resize-handle-state=hover]:bg-primary/50 data-[resize-handle-state=drag]:bg-primary/50 data-[resize-handle-state=active]:bg-primary/50 aria-[orientation=horizontal]:h-px aria-[orientation=horizontal]:w-full aria-[orientation=horizontal]:after:left-0 aria-[orientation=horizontal]:after:h-1 aria-[orientation=horizontal]:after:w-full aria-[orientation=horizontal]:after:translate-x-0 aria-[orientation=horizontal]:after:-translate-y-1/2 [&[aria-orientation=horizontal]>div]:rotate-90",
|
|
63
63
|
className,
|
|
64
64
|
)}
|
|
65
65
|
{...props}
|
|
66
66
|
>
|
|
67
67
|
{withHandle && (
|
|
68
|
-
<div className="bg-border h-6 w-1 rounded-lg z-10 flex shrink-0" />
|
|
68
|
+
<div className="bg-border group-focus-visible:bg-primary/50 group-data-[resize-handle-state=hover]:bg-primary/50 group-data-[resize-handle-state=drag]:bg-primary/50 group-data-[resize-handle-state=active]:bg-primary/50 h-6 w-1 rounded-lg z-10 flex shrink-0" />
|
|
69
69
|
)}
|
|
70
70
|
</PanelResizeHandle>
|
|
71
71
|
);
|
package/src/lib/variants.ts
CHANGED
|
@@ -162,8 +162,8 @@ export const titleVariants = cva("", {
|
|
|
162
162
|
"2xl": "text-2xl leading-8 tracking-tight",
|
|
163
163
|
"3xl": "text-3xl leading-9 tracking-tight",
|
|
164
164
|
"4xl": "text-4xl leading-10 tracking-tighter",
|
|
165
|
-
"5xl": "text-5xl leading-
|
|
166
|
-
"6xl": "text-6xl leading-
|
|
165
|
+
"5xl": "text-5xl leading-[1.1] tracking-tighter",
|
|
166
|
+
"6xl": "text-6xl leading-[1.1] tracking-tighter",
|
|
167
167
|
},
|
|
168
168
|
weight: {
|
|
169
169
|
normal: "font-normal",
|