From 2277fbfa187aaf76117d40a1460cf7ea334c94e8 Mon Sep 17 00:00:00 2001 From: Max Mykal Date: Wed, 10 Sep 2025 15:22:35 -0700 Subject: [PATCH 1/4] export components wityh types --- .../MessageContainer.stories.tsx | 2 +- .../MessageContainer/MessageContainer.tsx | 16 ++++++---- web/common/src/components/Tooltip/Tooltip.tsx | 24 +++++++------- .../src/components/Typography/Description.tsx | 10 +++--- .../src/components/Typography/Headline.tsx | 12 ++++--- .../src/components/Typography/Information.tsx | 24 +++++++------- .../src/components/Typography/Tagline.tsx | 10 +++--- web/common/src/components/Typography/Text.tsx | 10 +++--- .../components/VirtualList/FilterableList.tsx | 22 +++++++------ .../components/VirtualList/VirtualList.tsx | 16 ++++++---- web/common/src/index.ts | 32 ++++++++++++++++++- 11 files changed, 107 insertions(+), 71 deletions(-) diff --git a/web/common/src/components/MessageContainer/MessageContainer.stories.tsx b/web/common/src/components/MessageContainer/MessageContainer.stories.tsx index 554fe4b0cd..395361bea7 100644 --- a/web/common/src/components/MessageContainer/MessageContainer.stories.tsx +++ b/web/common/src/components/MessageContainer/MessageContainer.stories.tsx @@ -1,5 +1,5 @@ import type { Meta, StoryObj } from '@storybook/react-vite' -import MessageContainer from './MessageContainer' +import { MessageContainer } from './MessageContainer' const meta = { title: 'Components/Containers/MessageContainer', diff --git a/web/common/src/components/MessageContainer/MessageContainer.tsx b/web/common/src/components/MessageContainer/MessageContainer.tsx index 2a1b4783a3..d51213bfaf 100644 --- a/web/common/src/components/MessageContainer/MessageContainer.tsx +++ b/web/common/src/components/MessageContainer/MessageContainer.tsx @@ -2,17 +2,19 @@ import { cn } from '@/utils' import { LoadingContainer } from '../LoadingContainer/LoadingContainer' import { HorizontalContainer } from '../HorizontalContainer/HorizontalContainer' -export default function MessageContainer({ - children, - className, - wrap = false, - isLoading = false, -}: { +export interface MessageContainerProps { children: React.ReactNode className?: string wrap?: boolean isLoading?: boolean -}) { +} + +export function MessageContainer({ + children, + className, + wrap = false, + isLoading = false, +}: MessageContainerProps) { return ( -export type TooltipAlign = Extract +export interface TooltipProps { + trigger: React.ReactNode + children: React.ReactNode + side?: 'top' | 'bottom' | 'left' | 'right' + align?: 'center' | 'start' | 'end' + delayDuration?: number + sideOffset?: number + alignOffset?: number + className?: string +} export function Tooltip({ delayDuration = 200, @@ -24,16 +31,7 @@ export function Tooltip({ trigger, children, className, -}: { - trigger: React.ReactNode - children: React.ReactNode - side?: TooltipSide - align?: TooltipAlign - delayDuration?: number - sideOffset?: number - alignOffset?: number - className?: string -}) { +}: TooltipProps) { return ( diff --git a/web/common/src/components/Typography/Description.tsx b/web/common/src/components/Typography/Description.tsx index 62047b4a03..512a216fac 100644 --- a/web/common/src/components/Typography/Description.tsx +++ b/web/common/src/components/Typography/Description.tsx @@ -1,14 +1,16 @@ import { cn } from '@/utils' import React from 'react' +export interface DescriptionProps { + children?: React.ReactNode + className?: string +} + export function Description({ children, className, ...props -}: { - children?: React.ReactNode - className?: string -}) { +}: DescriptionProps) { return (
), ...props -}: { - children?: React.ReactNode - className?: string - classNameTooltip?: string - side?: 'right' | 'left' - size?: Size - sideOffset?: number - delayDuration?: number - info?: React.ReactNode - infoIcon?: React.ReactNode -}) { +}: InformationProps) { return (
{ + items: TItem[] + filterOptions?: IFuseOptions + disabled?: boolean + placeholder?: string + autoFocus?: boolean + className?: string + children: (options: TItem[], resetSearch: () => void) => React.ReactNode +} + export function FilterableList({ items, disabled, @@ -16,15 +26,7 @@ export function FilterableList({ filterOptions, className, children, -}: { - items: TItem[] - filterOptions?: IFuseOptions - disabled?: boolean - placeholder?: string - autoFocus?: boolean - className?: string - children: (options: TItem[], resetSearch: () => void) => React.ReactNode -}) { +}: FilterableListProps) { const [search, setSearch] = React.useState('') const fuse = new Fuse(items, filterOptions) diff --git a/web/common/src/components/VirtualList/VirtualList.tsx b/web/common/src/components/VirtualList/VirtualList.tsx index daec45fe16..94e5d93c05 100644 --- a/web/common/src/components/VirtualList/VirtualList.tsx +++ b/web/common/src/components/VirtualList/VirtualList.tsx @@ -6,19 +6,21 @@ import { Button } from '../Button/Button' import { ScrollContainer } from '../ScrollContainer/ScrollContainer' import { VerticalContainer } from '../VerticalContainer/VerticalContainer' +export interface VirtualListProps { + items: TItem[] + estimatedListItemHeight: number + renderListItem: (item: TItem) => React.ReactNode + isSelected?: (item: TItem) => boolean + className?: string +} + export function VirtualList({ items, estimatedListItemHeight, renderListItem, isSelected, className, -}: { - items: TItem[] - estimatedListItemHeight: number - renderListItem: (item: TItem) => React.ReactNode - isSelected?: (item: TItem) => boolean - className?: string -}) { +}: VirtualListProps) { const scrollableAreaRef = React.useRef(null) const [activeItemIndex] = React.useMemo(() => { diff --git a/web/common/src/index.ts b/web/common/src/index.ts index dce05a9c83..8ab37f7cff 100644 --- a/web/common/src/index.ts +++ b/web/common/src/index.ts @@ -25,7 +25,36 @@ export { ModelName, type ModelNameProps, } from '@/components/ModelName/ModelName' -export { Tooltip } from '@/components/Tooltip/Tooltip' +export { Tooltip, type TooltipProps } from '@/components/Tooltip/Tooltip' +export { + VirtualList, + type VirtualListProps, +} from '@/components/VirtualList/VirtualList' +export { + FilterableList, + type FilterableListProps, +} from '@/components/VirtualList/FilterableList' +export { + MessageContainer, + type MessageContainerProps, +} from '@/components/MessageContainer/MessageContainer' +export { Input, type InputProps } from '@/components/Input/Input' +export { + LoadingContainer, + type LoadingContainerProps, +} from '@/components/LoadingContainer/LoadingContainer' +export { Metadata, type MetadataProps } from '@/components/Metadata/Metadata' +export { + Description, + type DescriptionProps, +} from '@/components/Typography/Description' +export { Headline, type HeadlineProps } from '@/components/Typography/Headline' +export { + Information, + type InformationProps, +} from '@/components/Typography/Information' +export { Tagline, type TaglineProps } from '@/components/Typography/Tagline' +export { Text, type TextProps } from '@/components/Typography/Text' // Utils export { cn, truncate } from '@/utils' @@ -40,4 +69,5 @@ export type { LayoutDirection, Shape, Position, + Callback, } from '@/types' From e9cf88f5c3f8eddf08411fe9ec6831d3ae72bafb Mon Sep 17 00:00:00 2001 From: Max Mykal Date: Wed, 10 Sep 2025 15:41:04 -0700 Subject: [PATCH 2/4] fix --- web/common/src/components/LoadingContainer/LoadingContainer.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/common/src/components/LoadingContainer/LoadingContainer.tsx b/web/common/src/components/LoadingContainer/LoadingContainer.tsx index af9250b729..af21ddd04c 100644 --- a/web/common/src/components/LoadingContainer/LoadingContainer.tsx +++ b/web/common/src/components/LoadingContainer/LoadingContainer.tsx @@ -6,7 +6,7 @@ import { LoadingIcon } from './LoadingIcon' export interface LoadingContainerProps extends React.HTMLAttributes { isLoading?: boolean - message?: string + message?: React.ReactNode side?: Side className?: string } From 3db5164f21d8a6c8fc7b25df7bb47f3b3d5c82df Mon Sep 17 00:00:00 2001 From: Max Mykal Date: Thu, 11 Sep 2025 09:43:22 -0700 Subject: [PATCH 3/4] export hooks --- .../src/components/CopyButton/CopyButton.tsx | 31 ++++++------------- web/common/src/hooks/useCopyClipboard.ts | 16 ++++++++++ web/common/src/index.ts | 3 ++ 3 files changed, 28 insertions(+), 22 deletions(-) create mode 100644 web/common/src/hooks/useCopyClipboard.ts diff --git a/web/common/src/components/CopyButton/CopyButton.tsx b/web/common/src/components/CopyButton/CopyButton.tsx index e6a8bc446d..45aae3d817 100644 --- a/web/common/src/components/CopyButton/CopyButton.tsx +++ b/web/common/src/components/CopyButton/CopyButton.tsx @@ -1,8 +1,7 @@ -import React, { useState } from 'react' +import React from 'react' import { Button, type ButtonProps } from '@/components/Button/Button' - -type TimerID = ReturnType +import { useCopyClipboard } from '@/hooks/useCopyClipboard' export interface CopyButtonProps extends Omit { text: string @@ -25,22 +24,7 @@ export const CopyButton = React.forwardRef( }, ref, ) => { - const [copied, setCopied] = useState(null) - - const copy = (e: React.MouseEvent) => { - e.preventDefault() - e.stopPropagation() - - if (copied) { - clearTimeout(copied) - } - - navigator.clipboard.writeText(text).then(() => { - setCopied(setTimeout(() => setCopied(null), delay)) - }) - - onClick?.(e) - } + const [copyToClipboard, isCopied] = useCopyClipboard(delay) return ( ) }, diff --git a/web/common/src/hooks/useCopyClipboard.ts b/web/common/src/hooks/useCopyClipboard.ts new file mode 100644 index 0000000000..e961d3e094 --- /dev/null +++ b/web/common/src/hooks/useCopyClipboard.ts @@ -0,0 +1,16 @@ +import { useState } from 'react' + +type TimerID = ReturnType + +export function useCopyClipboard( + delay: number = 2000, +): [(text: string) => void, TimerID | null] { + const [isCopied, setIsCopied] = useState(null) + + const copyToClipboard = (text: string) => { + navigator.clipboard.writeText(text) + setIsCopied(setTimeout(() => setIsCopied(null), delay)) + } + + return [copyToClipboard, isCopied] +} diff --git a/web/common/src/index.ts b/web/common/src/index.ts index 8ab37f7cff..0748a6c78e 100644 --- a/web/common/src/index.ts +++ b/web/common/src/index.ts @@ -56,6 +56,9 @@ export { export { Tagline, type TaglineProps } from '@/components/Typography/Tagline' export { Text, type TextProps } from '@/components/Typography/Text' +// Hooks +export { useCopyClipboard } from '@/hooks/useCopyClipboard' + // Utils export { cn, truncate } from '@/utils' From f968dc7f8d5c3c88af60461a951399e4e75dca6c Mon Sep 17 00:00:00 2001 From: Max Mykal Date: Thu, 11 Sep 2025 09:55:59 -0700 Subject: [PATCH 4/4] small fix --- web/common/src/components/ModelName/ModelName.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/web/common/src/components/ModelName/ModelName.tsx b/web/common/src/components/ModelName/ModelName.tsx index 7777dee5ce..1c902018a1 100644 --- a/web/common/src/components/ModelName/ModelName.tsx +++ b/web/common/src/components/ModelName/ModelName.tsx @@ -106,7 +106,7 @@ export const ModelName = React.forwardRef( return ( {catalog && ( <> @@ -138,6 +138,7 @@ export const ModelName = React.forwardRef( )}