diff --git a/web/src/components/ui/charts/stories/BusterChart.PieChart.stories.tsx b/web/src/components/ui/charts/stories/BusterChart.PieChart.stories.tsx index 3cc235a86..81b2aaf92 100644 --- a/web/src/components/ui/charts/stories/BusterChart.PieChart.stories.tsx +++ b/web/src/components/ui/charts/stories/BusterChart.PieChart.stories.tsx @@ -330,3 +330,35 @@ export const ManyValuesWithDataLabels: Story = { pieDonutWidth: 0 } }; + +export const DataLabelsOutside: Story = { + args: { + selectedChartType: ChartType.Pie, + data: Array.from({ length: 5 }, () => ({ + segment: faker.word.adjective(), + value: faker.number.int({ min: 10, max: 100 }) + })), + pieChartAxis: { + x: ['segment'], + y: ['value'] + }, + columnLabelFormats: { + segment: { + columnType: 'text', + style: 'string' + } satisfies IColumnLabelFormat, + value: { + columnType: 'number', + style: 'number', + + numberSeparatorStyle: ',' + } satisfies IColumnLabelFormat, + value2: { + columnType: 'number', + style: 'number', + numberSeparatorStyle: ',' + } satisfies IColumnLabelFormat + } satisfies Record, + pieLabelPosition: 'outside' + } +}; diff --git a/web/src/components/ui/color-picker/ColorPicker.stories.tsx b/web/src/components/ui/color-picker/ColorPicker.stories.tsx new file mode 100644 index 000000000..13a760fd1 --- /dev/null +++ b/web/src/components/ui/color-picker/ColorPicker.stories.tsx @@ -0,0 +1,90 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { ColorPicker } from './ColorPicker'; + +const meta: Meta = { + title: 'UI/ColorPicker/ColorPicker', + component: ColorPicker, + tags: ['autodocs'], + args: { + value: '#000000', + size: 'default', + variant: 'default' + }, + argTypes: { + value: { + control: 'color', + description: 'The color value in hex format' + }, + onChange: { + description: 'Callback function when color changes' + }, + onChangeComplete: { + description: 'Callback function when color selection is complete' + }, + size: { + control: 'select', + options: ['small', 'default', 'tall'], + description: 'The size of the color picker button' + }, + variant: { + control: 'select', + options: ['default', 'outline', 'secondary', 'ghost', 'link'], + description: 'The variant style of the color picker button' + }, + className: { + control: 'text', + description: 'Additional CSS classes to apply' + } + } +}; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + value: '#FF0000' + } +}; + +export const Small: Story = { + args: { + value: '#00FF00', + size: 'small' + } +}; + +export const Tall: Story = { + args: { + value: '#0000FF', + size: 'tall' + } +}; + +export const OutlineVariant: Story = { + args: { + value: '#800080', + variant: 'outline' + } +}; + +export const SecondaryVariant: Story = { + args: { + value: '#FFA500', + variant: 'secondary' + } +}; + +export const GhostVariant: Story = { + args: { + value: '#008080', + variant: 'ghost' + } +}; + +export const LinkVariant: Story = { + args: { + value: '#4B0082', + variant: 'link' + } +}; diff --git a/web/src/components/ui/color-picker/ColorPicker.tsx b/web/src/components/ui/color-picker/ColorPicker.tsx index 0c97b1c57..f83a6ca38 100644 --- a/web/src/components/ui/color-picker/ColorPicker.tsx +++ b/web/src/components/ui/color-picker/ColorPicker.tsx @@ -3,7 +3,8 @@ import { PopoverRoot, PopoverContent, PopoverTrigger } from '@/components/ui/pop import { cva } from 'class-variance-authority'; import { cn } from '@/lib/utils'; import { Button } from '@/components/ui/buttons'; -import { ChromePicker } from 'react-color'; +import { ChromePicker, ColorResult } from 'react-color'; +import { useMemoizedFn } from '@/hooks'; const colorPickerVariants = cva( 'rounded border bg-background transition-colors hover:bg-item-hover hover:text-text-default', @@ -17,9 +18,9 @@ const colorPickerVariants = cva( link: 'text-primary underline-offset-4 hover:underline' }, size: { - default: 'h-6 min-h-6 max-h-6 px-4', - tall: 'h-7 min-h-7 max-h-7 px-4', - small: 'h-5 min-h-5 max-h-5 px-3 text-xs' + default: 'h-6 min-h-6 max-h-6 px-1', + tall: 'h-7 min-h-7 max-h-7 px-0.5', + small: 'h-5 min-h-5 max-h-5 px-0.5 text-xs' } }, defaultVariants: { @@ -50,13 +51,17 @@ const ColorPicker = React.forwardRef( }, ref ) => { - const handleChange = (color: any) => { - onChange?.(color.hex); - }; + const handleChange = useMemoizedFn( + (color: ColorResult, event: React.ChangeEvent) => { + onChange?.(color.hex); + } + ); - const handleChangeComplete = (color: any) => { - onChangeComplete?.(color.hex); - }; + const handleChangeComplete = useMemoizedFn( + (color: ColorResult, event: React.ChangeEvent) => { + onChangeComplete?.(color.hex); + } + ); return ( diff --git a/web/src/components/ui/segmented/AppSegmented.stories.tsx b/web/src/components/ui/segmented/AppSegmented.stories.tsx index b7c15cc03..71c0d6735 100644 --- a/web/src/components/ui/segmented/AppSegmented.stories.tsx +++ b/web/src/components/ui/segmented/AppSegmented.stories.tsx @@ -2,32 +2,9 @@ import type { Meta, StoryObj } from '@storybook/react'; import { AppSegmented } from './AppSegmented'; import { BottleChampagne, Grid, HouseModern, PaintRoller } from '../icons'; import { PreventNavigation } from '../layouts/PreventNavigation'; -import { useRouter } from 'next/navigation'; -import { usePathname, useSearchParams } from 'next/navigation'; import { useState } from 'react'; import { Checkbox } from '../checkbox'; -// Mock the Next.js router -const MockNextRouter = ({ children }: { children: React.ReactNode }) => { - const mockRouter = { - back: () => {}, - forward: () => {}, - push: () => {}, - replace: () => {}, - refresh: () => {}, - prefetch: () => Promise.resolve() - }; - - // @ts-ignore - we're mocking the router - useRouter.mockImplementation(() => mockRouter); - // @ts-ignore - we're mocking the pathname - usePathname.mockImplementation(() => '/'); - // @ts-ignore - we're mocking the search params - useSearchParams.mockImplementation(() => new URLSearchParams()); - - return <>{children}; -}; - const meta: Meta = { title: 'UI/Segmented/AppSegmented', component: AppSegmented, @@ -37,9 +14,9 @@ const meta: Meta = { tags: ['autodocs'], decorators: [ (Story) => ( - + <> - + ) ], argTypes: { diff --git a/web/src/components/ui/select/SelectBase.tsx b/web/src/components/ui/select/SelectBase.tsx index c059e02c9..4dae49bc7 100644 --- a/web/src/components/ui/select/SelectBase.tsx +++ b/web/src/components/ui/select/SelectBase.tsx @@ -13,7 +13,7 @@ const SelectGroup = SelectPrimitive.Group; const SelectValue = SelectPrimitive.Value; export const selectVariants = cva( - 'flex w-full gap-x-1.5 transition-colors transition-border text-foreground duration-200 items-center justify-between rounded border px-3 py-1 text-sm focus:outline-none cursor-pointer disabled:cursor-not-allowed disabled:opacity-60 [&>span]:line-clamp-1', + 'flex w-full gap-x-1.5 transition-colors transition-border text-foreground duration-200 items-center justify-between rounded border px-3 py-1 text-sm focus:outline-none cursor-pointer disabled:cursor-not-allowed disabled:opacity-60 [&>span]:line-clamp-1 ', { variants: { variant: {