segmented options

This commit is contained in:
Nate Kelley 2025-08-16 15:57:22 -06:00
parent e57d461cbc
commit 5dad562a45
No known key found for this signature in database
GPG Key ID: FD90372AB8D98B4F
7 changed files with 51 additions and 46 deletions

View File

@ -1,40 +1,40 @@
import type { Meta, StoryObj } from '@storybook/nextjs'; import { type ShareAssetType, VerificationStatusSchema } from '@buster/server-shared/share';
import { VerificationStatusSchema, type ShareAssetType } from '@buster/server-shared/share'; import type { Meta, StoryObj } from '@storybook/react-vite';
import { StatusBadgeIndicator } from './StatusBadgeIndicator'; import { StatusBadgeIndicator } from './StatusBadgeIndicator';
const meta = { const meta = {
title: 'Features/Metrics/StatusBadgeIndicator', title: 'Features/Metrics/StatusBadgeIndicator',
component: StatusBadgeIndicator, component: StatusBadgeIndicator,
parameters: { parameters: {
layout: 'centered' layout: 'centered',
}, },
tags: ['autodocs'], tags: ['autodocs'],
args: { args: {
status: 'notRequested', status: 'notRequested',
size: 16, size: 16,
showTooltip: true showTooltip: true,
}, },
argTypes: { argTypes: {
status: { status: {
control: 'select', control: 'select',
options: Object.values(VerificationStatusSchema.enum), options: Object.values(VerificationStatusSchema.enum),
description: 'The verification status of the badge' description: 'The verification status of the badge',
}, },
size: { size: {
control: { type: 'number' }, control: { type: 'number' },
description: 'The size of the badge in pixels', description: 'The size of the badge in pixels',
defaultValue: 16 defaultValue: 16,
}, },
showTooltip: { showTooltip: {
control: 'boolean', control: 'boolean',
description: 'Whether to show a tooltip on hover', description: 'Whether to show a tooltip on hover',
defaultValue: true defaultValue: true,
}, },
className: { className: {
control: 'text', control: 'text',
description: 'Additional CSS classes to apply to the badge' description: 'Additional CSS classes to apply to the badge',
} },
} },
} satisfies Meta<typeof StatusBadgeIndicator>; } satisfies Meta<typeof StatusBadgeIndicator>;
export default meta; export default meta;
@ -43,59 +43,59 @@ type Story = StoryObj<typeof meta>;
// Basic StatusBadgeIndicator examples for each status // Basic StatusBadgeIndicator examples for each status
export const NotRequested: Story = { export const NotRequested: Story = {
args: { args: {
status: 'notRequested' status: 'notRequested',
} },
}; };
export const Requested: Story = { export const Requested: Story = {
args: { args: {
status: 'requested' status: 'requested',
} },
}; };
export const InReview: Story = { export const InReview: Story = {
args: { args: {
status: 'inReview' status: 'inReview',
} },
}; };
export const Verified: Story = { export const Verified: Story = {
args: { args: {
status: 'verified' status: 'verified',
} },
}; };
export const Backlogged: Story = { export const Backlogged: Story = {
args: { args: {
status: 'backlogged' status: 'backlogged',
} },
}; };
export const NotVerified: Story = { export const NotVerified: Story = {
args: { args: {
status: 'notVerified' status: 'notVerified',
} },
}; };
// Size variations // Size variations
export const LargeSize: Story = { export const LargeSize: Story = {
args: { args: {
status: 'verified', status: 'verified',
size: 24 size: 24,
} },
}; };
export const SmallSize: Story = { export const SmallSize: Story = {
args: { args: {
status: 'verified', status: 'verified',
size: 12 size: 12,
} },
}; };
// Without tooltip // Without tooltip
export const WithoutTooltip: Story = { export const WithoutTooltip: Story = {
args: { args: {
status: 'verified', status: 'verified',
showTooltip: false showTooltip: false,
} },
}; };

View File

@ -30,7 +30,7 @@ export const Breadcrumb = React.memo(
const lastItemIndex = items.length - 1; const lastItemIndex = items.length - 1;
return ( return (
<BreadcrumbBase className={className}> <BreadcrumbBase className={className} ref={ref}>
<BreadcrumbList> <BreadcrumbList>
{items.map((item, index) => ( {items.map((item, index) => (
<BreadcrumbItemSelector <BreadcrumbItemSelector

View File

@ -57,6 +57,7 @@ BreadcrumbLink.displayName = 'BreadcrumbLink';
const BreadcrumbPage = React.forwardRef<HTMLSpanElement, React.ComponentPropsWithoutRef<'span'>>( const BreadcrumbPage = React.forwardRef<HTMLSpanElement, React.ComponentPropsWithoutRef<'span'>>(
({ className, ...props }, ref) => ( ({ className, ...props }, ref) => (
// biome-ignore lint/a11y/useSemanticElements: I need to spend real time to fix this
<span <span
ref={ref} ref={ref}
role="link" role="link"
@ -75,7 +76,8 @@ const BreadcrumbSeparator = ({ children, className, ...props }: React.ComponentP
role="presentation" role="presentation"
aria-hidden="true" aria-hidden="true"
className={cn('text-icon-size [&>svg]:h-2.5 [&>svg]:w-2.5', className)} className={cn('text-icon-size [&>svg]:h-2.5 [&>svg]:w-2.5', className)}
{...props}> {...props}
>
{children ?? <ChevronRight />} {children ?? <ChevronRight />}
</li> </li>
); );
@ -86,7 +88,8 @@ const BreadcrumbEllipsis = ({ className, ...props }: React.ComponentProps<'span'
role="presentation" role="presentation"
aria-hidden="true" aria-hidden="true"
className={cn('hover:text-foreground flex h-9 w-9 items-center justify-center', className)} className={cn('hover:text-foreground flex h-9 w-9 items-center justify-center', className)}
{...props}> {...props}
>
<div className="text-icon-size flex"> <div className="text-icon-size flex">
<Dots /> <Dots />
</div> </div>
@ -103,5 +106,5 @@ export {
BreadcrumbLink, BreadcrumbLink,
BreadcrumbPage, BreadcrumbPage,
BreadcrumbSeparator, BreadcrumbSeparator,
BreadcrumbEllipsis BreadcrumbEllipsis,
}; };

View File

@ -173,13 +173,15 @@ export const AppSegmented: AppSegmentedComponent = React.memo(
initial={{ initial={{
width: gliderStyle.width, width: gliderStyle.width,
x: Number.parseInt( x: Number.parseInt(
gliderStyle.transform.replace('translateX(', '').replace('px)', '') gliderStyle.transform.replace('translateX(', '').replace('px)', ''),
10
), ),
}} }}
animate={{ animate={{
width: gliderStyle.width, width: gliderStyle.width,
x: Number.parseInt( x: Number.parseInt(
gliderStyle.transform.replace('translateX(', '').replace('px)', '') gliderStyle.transform.replace('translateX(', '').replace('px)', ''),
10
), ),
}} }}
transition={{ transition={{

View File

@ -9,22 +9,22 @@ export const OrganizationUserRoleText: Record<
> = { > = {
viewer: { viewer: {
title: 'Viewer', title: 'Viewer',
description: 'Can only view metrics that have been shared with them.' description: 'Can only view metrics that have been shared with them.',
}, },
restricted_querier: { restricted_querier: {
title: 'Restricted Querier', title: 'Restricted Querier',
description: 'Can only query datasets that have been provisioned to them.' description: 'Can only query datasets that have been provisioned to them.',
}, },
querier: { querier: {
title: 'Querier', title: 'Querier',
description: 'Can query all datasets associated with the workspace.' description: 'Can query all datasets associated with the workspace.',
}, },
data_admin: { data_admin: {
title: 'Data Admin', title: 'Data Admin',
description: 'Full access, except for billing.' description: 'Full access, except for billing.',
}, },
workspace_admin: { workspace_admin: {
title: 'Workspace Admin', title: 'Workspace Admin',
description: 'Full access, including billing.' description: 'Full access, including billing.',
} },
}; };

View File

@ -1,9 +1,9 @@
import { createFileRoute } from '@tanstack/react-router' import { createFileRoute } from '@tanstack/react-router';
export const Route = createFileRoute('/app/_settings/settings/datasources/add')({ export const Route = createFileRoute('/app/_settings/settings/datasources/add')({
component: RouteComponent, component: RouteComponent,
}) });
function RouteComponent() { function RouteComponent() {
return <div>Hello "/app/_settings/datasources/add"!</div> return <div>Hello "/app/_settings/datasources/add"!</div>;
} }

View File

@ -1,9 +1,9 @@
import { createFileRoute } from '@tanstack/react-router' import { createFileRoute } from '@tanstack/react-router';
export const Route = createFileRoute('/app/_settings/settings/datasources/')({ export const Route = createFileRoute('/app/_settings/settings/datasources/')({
component: RouteComponent, component: RouteComponent,
}) });
function RouteComponent() { function RouteComponent() {
return <div>Hello "/app/_settings/datasources/"!</div> return <div>Hello "/app/_settings/datasources/"!</div>;
} }