Improve BUI manifest
Signed-off-by: Charles de Dreuille <charles.dedreuille@gmail.com>
This commit is contained in:
@@ -63,13 +63,13 @@
|
||||
"@types/react": "^18.0.0",
|
||||
"@types/react-dom": "^18.0.0",
|
||||
"@types/use-sync-external-store": "^0.0.6",
|
||||
"eslint-plugin-storybook": "^10.3.0-alpha.1",
|
||||
"eslint-plugin-storybook": "^10.3.3",
|
||||
"glob": "^11.0.1",
|
||||
"globals": "^17.0.0",
|
||||
"react": "^18.0.2",
|
||||
"react-dom": "^18.0.2",
|
||||
"react-router-dom": "^6.30.2",
|
||||
"storybook": "^10.3.0-alpha.1"
|
||||
"storybook": "^10.3.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "^18.0.0",
|
||||
|
||||
@@ -38,7 +38,11 @@ import {
|
||||
} from './definition';
|
||||
import { Flex } from '../Flex';
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* A collapsible section that reveals or hides its content when the trigger is activated.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const Accordion = forwardRef(
|
||||
(props: AccordionProps, ref: Ref<React.ElementRef<typeof RADisclosure>>) => {
|
||||
const { ownProps, restProps, dataAttributes } = useDefinition(
|
||||
@@ -62,7 +66,11 @@ export const Accordion = forwardRef(
|
||||
|
||||
Accordion.displayName = 'Accordion';
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* The clickable heading that toggles the visibility of an accordion panel.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const AccordionTrigger = forwardRef(
|
||||
(
|
||||
props: AccordionTriggerProps,
|
||||
@@ -100,7 +108,11 @@ export const AccordionTrigger = forwardRef(
|
||||
|
||||
AccordionTrigger.displayName = 'AccordionTrigger';
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* The content area of an accordion that is revealed when the trigger is activated.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const AccordionPanel = forwardRef(
|
||||
(
|
||||
props: AccordionPanelProps,
|
||||
@@ -125,7 +137,11 @@ export const AccordionPanel = forwardRef(
|
||||
|
||||
AccordionPanel.displayName = 'AccordionPanel';
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* A container that groups multiple Accordion items, optionally allowing several panels to be expanded at once.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const AccordionGroup = forwardRef(
|
||||
(
|
||||
props: AccordionGroupProps,
|
||||
|
||||
@@ -19,7 +19,11 @@ import { AvatarProps } from './types';
|
||||
import { useDefinition } from '../../hooks/useDefinition';
|
||||
import { AvatarDefinition } from './definition';
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* Displays a user's profile image with an automatic fallback to their initials when the image fails to load.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const Avatar = forwardRef<HTMLDivElement, AvatarProps>((props, ref) => {
|
||||
const { ownProps, restProps, dataAttributes } = useDefinition(
|
||||
AvatarDefinition,
|
||||
|
||||
@@ -19,7 +19,11 @@ import { BoxProps } from './types';
|
||||
import { useDefinition } from '../../hooks/useDefinition';
|
||||
import { BoxDefinition } from './definition';
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* A general-purpose layout primitive that can render as any HTML element and supports spacing, sizing, and background props.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const Box = forwardRef<HTMLDivElement, BoxProps>((props, ref) => {
|
||||
const { ownProps, restProps, dataAttributes, utilityStyle } = useDefinition(
|
||||
BoxDefinition,
|
||||
|
||||
@@ -21,7 +21,11 @@ import type { ButtonIconProps } from './types';
|
||||
import { useDefinition } from '../../hooks/useDefinition';
|
||||
import { ButtonIconDefinition } from './definition';
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* An icon-only button that supports a loading state and requires an accessible label.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const ButtonIcon = forwardRef(
|
||||
(props: ButtonIconProps, ref: Ref<HTMLButtonElement>) => {
|
||||
const { ownProps, restProps, dataAttributes } = useDefinition(
|
||||
|
||||
@@ -21,7 +21,11 @@ import { useDefinition } from '../../hooks/useDefinition';
|
||||
import { ButtonLinkDefinition } from './definition';
|
||||
import { getNodeText } from '../../analytics/getNodeText';
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* A button-styled anchor element for navigation, supporting optional start and end icon slots and analytics event tracking.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const ButtonLink = forwardRef(
|
||||
(props: ButtonLinkProps, ref: Ref<HTMLAnchorElement>) => {
|
||||
const { ownProps, restProps, dataAttributes, analytics } = useDefinition(
|
||||
|
||||
@@ -21,7 +21,11 @@ import { useDefinition } from '../../hooks/useDefinition';
|
||||
import { CheckboxDefinition } from './definition';
|
||||
import { RiCheckLine, RiSubtractLine } from '@remixicon/react';
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* A form checkbox input with support for indeterminate state and accessible labeling.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const Checkbox = forwardRef<HTMLLabelElement, CheckboxProps>(
|
||||
(props, ref) => {
|
||||
const { ownProps, restProps, dataAttributes } = useDefinition(
|
||||
|
||||
@@ -19,7 +19,11 @@ import type { ContainerProps } from './types';
|
||||
import { useDefinition } from '../../hooks/useDefinition';
|
||||
import { ContainerDefinition } from './definition';
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* A centered layout wrapper that constrains content to a maximum width and provides consistent page-level padding.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const Container = forwardRef<HTMLDivElement, ContainerProps>(
|
||||
(props, ref) => {
|
||||
const { ownProps, restProps, utilityStyle } = useDefinition(
|
||||
|
||||
@@ -41,12 +41,20 @@ import { Box } from '../Box';
|
||||
import { BgReset } from '../../hooks/useBg';
|
||||
import { Flex } from '../Flex';
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* A wrapper that connects a trigger element to a Dialog, controlling its open and close state.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const DialogTrigger = (props: DialogTriggerProps) => {
|
||||
return <RADialogTrigger {...props} />;
|
||||
};
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* A modal overlay that presents content requiring user interaction or acknowledgment, dismissible by clicking outside or pressing Escape.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const Dialog = forwardRef<React.ElementRef<typeof Modal>, DialogProps>(
|
||||
(props, ref) => {
|
||||
const { ownProps, restProps } = useDefinition(DialogDefinition, props, {
|
||||
@@ -89,7 +97,11 @@ export const Dialog = forwardRef<React.ElementRef<typeof Modal>, DialogProps>(
|
||||
|
||||
Dialog.displayName = 'Dialog';
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* The header section of a Dialog, containing the title and a close button.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const DialogHeader = forwardRef<
|
||||
React.ElementRef<'div'>,
|
||||
DialogHeaderProps
|
||||
@@ -110,7 +122,11 @@ export const DialogHeader = forwardRef<
|
||||
});
|
||||
DialogHeader.displayName = 'DialogHeader';
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* The main scrollable content area of a Dialog.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const DialogBody = forwardRef<React.ElementRef<'div'>, DialogBodyProps>(
|
||||
(props, ref) => {
|
||||
const { ownProps, restProps } = useDefinition(DialogBodyDefinition, props);
|
||||
@@ -126,7 +142,11 @@ export const DialogBody = forwardRef<React.ElementRef<'div'>, DialogBodyProps>(
|
||||
|
||||
DialogBody.displayName = 'DialogBody';
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* The footer section of a Dialog, typically used to place action buttons.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const DialogFooter = forwardRef<
|
||||
React.ElementRef<'div'>,
|
||||
DialogFooterProps
|
||||
|
||||
@@ -20,7 +20,11 @@ import type { FieldErrorProps } from './types';
|
||||
import { useDefinition } from '../../hooks/useDefinition';
|
||||
import { FieldErrorDefinition } from './definition';
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* Displays a validation error message associated with a form field.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const FieldError = forwardRef<HTMLDivElement, FieldErrorProps>(
|
||||
(props: FieldErrorProps, ref) => {
|
||||
const { ownProps, restProps } = useDefinition(FieldErrorDefinition, props);
|
||||
|
||||
@@ -19,7 +19,11 @@ import type { FieldLabelProps } from './types';
|
||||
import { useDefinition } from '../../hooks/useDefinition';
|
||||
import { FieldLabelDefinition } from './definition';
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* Renders a label for a form field with optional secondary label and description text.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const FieldLabel = forwardRef<HTMLDivElement, FieldLabelProps>(
|
||||
(props: FieldLabelProps, ref) => {
|
||||
const { ownProps, restProps } = useDefinition(FieldLabelDefinition, props);
|
||||
|
||||
@@ -19,7 +19,11 @@ import type { FlexProps } from './types';
|
||||
import { useDefinition } from '../../hooks/useDefinition';
|
||||
import { FlexDefinition } from './definition';
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* A flexbox layout container with props for controlling gap, alignment, justification, and direction.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const Flex = forwardRef<HTMLDivElement, FlexProps>((props, ref) => {
|
||||
const { ownProps, dataAttributes, utilityStyle, restProps } = useDefinition(
|
||||
FlexDefinition,
|
||||
|
||||
@@ -61,7 +61,11 @@ const LinkInternal = forwardRef<HTMLAnchorElement, LinkProps>((props, ref) => {
|
||||
|
||||
LinkInternal.displayName = 'LinkInternal';
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* A styled anchor element that supports analytics event tracking on click.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const Link = forwardRef<HTMLAnchorElement, LinkProps>((props, ref) => {
|
||||
return <LinkInternal {...props} ref={ref} />;
|
||||
});
|
||||
|
||||
@@ -76,7 +76,11 @@ const MenuEmptyState = () => {
|
||||
return <div className={ownProps.classes.root}>No results found.</div>;
|
||||
};
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* A wrapper that connects a trigger element to a dropdown menu, controlling its open and close state.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const MenuTrigger = (props: MenuTriggerProps) => {
|
||||
return <RAMenuTrigger {...props} />;
|
||||
};
|
||||
|
||||
@@ -28,7 +28,11 @@ import { useDefinition } from '../../hooks/useDefinition';
|
||||
import { PasswordFieldDefinition } from './definition';
|
||||
import { RiEyeLine, RiEyeOffLine } from '@remixicon/react';
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* A text input for password entry with a toggleable visibility button, integrated label, and inline error display.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const PasswordField = forwardRef<HTMLDivElement, PasswordFieldProps>(
|
||||
(props, ref) => {
|
||||
const { ownProps, restProps, dataAttributes } = useDefinition(
|
||||
|
||||
@@ -26,7 +26,11 @@ import { RadioGroupDefinition, RadioDefinition } from './definition';
|
||||
|
||||
import type { RadioGroupProps, RadioProps } from './types';
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* A group of radio buttons for selecting a single option from a set, with an integrated label, description, and error display.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const RadioGroup = forwardRef<HTMLDivElement, RadioGroupProps>(
|
||||
(props, ref) => {
|
||||
const { ownProps, restProps } = useDefinition(RadioGroupDefinition, props);
|
||||
@@ -70,7 +74,11 @@ export const RadioGroup = forwardRef<HTMLDivElement, RadioGroupProps>(
|
||||
|
||||
RadioGroup.displayName = 'RadioGroup';
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* A single radio button for use within a RadioGroup.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const Radio = forwardRef<HTMLLabelElement, RadioProps>((props, ref) => {
|
||||
const { ownProps, restProps } = useDefinition(RadioDefinition, props);
|
||||
|
||||
|
||||
@@ -47,7 +47,11 @@ const SearchAutocompleteEmptyState = () => {
|
||||
return <div className={ownProps.classes.emptyState}>No results found.</div>;
|
||||
};
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* A search input that shows a dropdown list of suggestions as the user types, with loading and empty states.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export function SearchAutocomplete(props: SearchAutocompleteProps) {
|
||||
const { ownProps, dataAttributes } = useDefinition(
|
||||
SearchAutocompleteDefinition,
|
||||
@@ -184,7 +188,11 @@ export function SearchAutocomplete(props: SearchAutocompleteProps) {
|
||||
);
|
||||
}
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* An individual option item within a SearchAutocomplete dropdown.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export function SearchAutocompleteItem(props: SearchAutocompleteItemProps) {
|
||||
const { ownProps, restProps } = useDefinition(
|
||||
SearchAutocompleteItemDefinition,
|
||||
|
||||
@@ -28,7 +28,11 @@ import { SearchFieldDefinition } from './definition';
|
||||
|
||||
import type { SearchFieldProps } from './types';
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* A text input optimized for search queries, with a built-in clear button, optional icon, and support for a collapsible mode.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const SearchField = forwardRef<HTMLDivElement, SearchFieldProps>(
|
||||
(props, ref) => {
|
||||
const { ownProps, restProps, dataAttributes } = useDefinition(
|
||||
|
||||
@@ -26,7 +26,11 @@ import { FieldError } from '../FieldError';
|
||||
import { SelectTrigger } from './SelectTrigger';
|
||||
import { SelectContent } from './SelectContent';
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* A dropdown picker for selecting one or multiple options from a list, with optional search filtering and inline error display.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const Select = forwardRef<
|
||||
HTMLDivElement,
|
||||
SelectProps<'single' | 'multiple'>
|
||||
|
||||
@@ -18,7 +18,11 @@ import type { SkeletonProps } from './types';
|
||||
import { useDefinition } from '../../hooks/useDefinition';
|
||||
import { SkeletonDefinition } from './definition';
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* A placeholder shape displayed while content is loading, matching the size and layout of the content it replaces.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const Skeleton = (props: SkeletonProps) => {
|
||||
const { ownProps, restProps, dataAttributes } = useDefinition(
|
||||
SkeletonDefinition,
|
||||
|
||||
@@ -115,7 +115,11 @@ function SliderImpl<T extends number | number[]>(
|
||||
);
|
||||
}
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* A draggable input for selecting a numeric value or range within a defined interval, with an integrated label and value output.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const Slider = forwardRef(SliderImpl) as (<T extends number | number[]>(
|
||||
props: SliderProps<T> & { ref?: React.ForwardedRef<HTMLDivElement> },
|
||||
) => JSX.Element) & { displayName: string };
|
||||
|
||||
@@ -20,7 +20,11 @@ import type { SwitchProps } from './types';
|
||||
import { useDefinition } from '../../hooks/useDefinition';
|
||||
import { SwitchDefinition } from './definition';
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* A toggle control for switching between on and off states, with an optional visible label.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const Switch = forwardRef<HTMLLabelElement, SwitchProps>(
|
||||
(props, ref) => {
|
||||
const { ownProps, restProps } = useDefinition(SwitchDefinition, props);
|
||||
|
||||
@@ -19,7 +19,12 @@ import type { CellProps } from '../types';
|
||||
import { useDefinition } from '../../../hooks/useDefinition';
|
||||
import { CellDefinition } from '../definition';
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* A low-level table cell primitive for building custom cell content.
|
||||
* For standard use cases, prefer `CellText` or `CellProfile`.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
const Cell = (props: CellProps) => {
|
||||
const { ownProps, restProps } = useDefinition(CellDefinition, props);
|
||||
|
||||
|
||||
@@ -22,7 +22,11 @@ import { useDefinition } from '../../../hooks/useDefinition';
|
||||
import { CellProfileDefinition } from '../definition';
|
||||
import { Cell as ReactAriaCell } from 'react-aria-components';
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* A table cell that renders an avatar image alongside a name, with an optional description and link.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const CellProfile = (props: CellProfileProps) => {
|
||||
const { ownProps, restProps } = useDefinition(CellProfileDefinition, props);
|
||||
const { classes, src, name, href, description, color } = ownProps;
|
||||
|
||||
@@ -21,7 +21,11 @@ import type { CellTextProps } from '../types';
|
||||
import { useDefinition } from '../../../hooks/useDefinition';
|
||||
import { CellTextDefinition } from '../definition';
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* A table cell that renders a primary text title with an optional secondary description, leading icon, and link.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
const CellText = (props: CellTextProps) => {
|
||||
const { ownProps, restProps } = useDefinition(CellTextDefinition, props);
|
||||
const { classes, title, description, color, leadingIcon, href } = ownProps;
|
||||
|
||||
@@ -20,7 +20,11 @@ import { ColumnDefinition } from '../definition';
|
||||
import { ColumnProps } from '../types';
|
||||
import { RiArrowUpLine } from '@remixicon/react';
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* A table column header cell with an optional sort toggle and support for resizable widths.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const Column = (props: ColumnProps) => {
|
||||
const { ownProps, restProps } = useDefinition(ColumnDefinition, props);
|
||||
const { classes, children } = ownProps;
|
||||
|
||||
@@ -28,7 +28,11 @@ import { isExternalLink } from '../../../utils/linkUtils';
|
||||
import clsx from 'clsx';
|
||||
import { Flex } from '../../Flex';
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* A table row that can optionally act as a navigation link or trigger an action when clicked, with analytics tracking.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export function Row<T extends object>(props: RowProps<T>) {
|
||||
const { ownProps, restProps, dataAttributes, analytics } = useDefinition(
|
||||
RowDefinition,
|
||||
|
||||
@@ -98,7 +98,12 @@ function useLiveRegionLabel(
|
||||
return liveRegionLabel;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* A full-featured data table with built-in pagination, sorting, row selection, loading and error states, and optional virtualization.
|
||||
* Pair with `useTable` to manage data fetching and state, or pass `data` and `pagination` directly for manual control.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export function Table<T extends TableItem>({
|
||||
columnConfig,
|
||||
data,
|
||||
|
||||
@@ -19,7 +19,11 @@ import { useDefinition } from '../../../hooks/useDefinition';
|
||||
import { TableBodyDefinition } from '../definition';
|
||||
import type { TableBodyProps } from '../types';
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* The body section of a table that renders data rows from the provided items collection.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const TableBody = <T extends object>(props: TableBodyProps<T>) => {
|
||||
const { ownProps, restProps } = useDefinition(TableBodyDefinition, props);
|
||||
|
||||
|
||||
@@ -26,7 +26,11 @@ import { TableHeaderDefinition } from '../definition';
|
||||
import type { TableHeaderProps } from '../types';
|
||||
import { Flex } from '../../Flex';
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* The header row of a table, rendering column labels and an optional select-all checkbox for toggle selection mode.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const TableHeader = <T extends object>(props: TableHeaderProps<T>) => {
|
||||
let { selectionBehavior, selectionMode } = useTableOptions();
|
||||
|
||||
|
||||
@@ -19,7 +19,12 @@ import { TableDefinition } from '../definition';
|
||||
import { Table as ReactAriaTable } from 'react-aria-components';
|
||||
import { TableRootProps } from '../types';
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* The low-level table root element for building custom table layouts from atomic components.
|
||||
* For most use cases, prefer the `Table` convenience wrapper.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const TableRoot = (props: TableRootProps) => {
|
||||
const { ownProps, restProps, dataAttributes } = useDefinition(
|
||||
TableDefinition,
|
||||
|
||||
@@ -121,7 +121,12 @@ function useTableProps<T extends TableItem>(
|
||||
);
|
||||
}
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* A hook that manages table data fetching, pagination, sorting, search, and filtering.
|
||||
* Supports three modes: `complete` for client-side data, `offset` for server-side offset pagination, and `cursor` for server-side cursor pagination.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export function useTable<T extends TableItem, TFilter = unknown>(
|
||||
options: UseTableCompleteOptions<T, TFilter>,
|
||||
): UseTableResult<T, TFilter>;
|
||||
|
||||
@@ -1,202 +0,0 @@
|
||||
/* eslint-disable no-restricted-syntax */
|
||||
/*
|
||||
* Copyright 2025 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { useState } from 'react';
|
||||
import type { Meta, StoryObj } from '@storybook/react-vite';
|
||||
import { Table, CellText, CellProfile, useTable, type ColumnConfig } from '..';
|
||||
import { Flex } from '../../Flex';
|
||||
import { Text } from '../../Text';
|
||||
import { RadioGroup, Radio } from '../../RadioGroup';
|
||||
import { data as data4 } from './mocked-data4';
|
||||
import { selectionData, selectionColumns, tableStoriesMeta } from './utils';
|
||||
|
||||
const meta = {
|
||||
title: 'Backstage UI/Table/docs',
|
||||
...tableStoriesMeta,
|
||||
} satisfies Meta;
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof meta>;
|
||||
type Data4Item = (typeof data4)[0];
|
||||
|
||||
export const TableRockBand: Story = {
|
||||
render: () => {
|
||||
const columns: ColumnConfig<Data4Item>[] = [
|
||||
{
|
||||
id: 'name',
|
||||
label: 'Band name',
|
||||
isRowHeader: true,
|
||||
defaultWidth: '4fr',
|
||||
cell: item => (
|
||||
<CellProfile name={item.name} src={item.image} href={item.website} />
|
||||
),
|
||||
},
|
||||
{
|
||||
id: 'genre',
|
||||
label: 'Genre',
|
||||
defaultWidth: '4fr',
|
||||
cell: item => <CellText title={item.genre} />,
|
||||
},
|
||||
{
|
||||
id: 'yearFormed',
|
||||
label: 'Year formed',
|
||||
defaultWidth: '1fr',
|
||||
cell: item => <CellText title={item.yearFormed.toString()} />,
|
||||
},
|
||||
{
|
||||
id: 'albums',
|
||||
label: 'Albums',
|
||||
defaultWidth: '1fr',
|
||||
cell: item => <CellText title={item.albums.toString()} />,
|
||||
},
|
||||
];
|
||||
|
||||
const { tableProps } = useTable({
|
||||
mode: 'complete',
|
||||
getData: () => data4,
|
||||
paginationOptions: { pageSize: 5 },
|
||||
});
|
||||
|
||||
return <Table columnConfig={columns} {...tableProps} />;
|
||||
},
|
||||
};
|
||||
|
||||
export const SelectionToggleWithActions: Story = {
|
||||
render: () => {
|
||||
const [selected, setSelected] = useState<Set<string | number> | 'all'>(
|
||||
new Set(),
|
||||
);
|
||||
|
||||
const { tableProps } = useTable({
|
||||
mode: 'complete',
|
||||
getData: () => selectionData,
|
||||
paginationOptions: { pageSize: 10 },
|
||||
});
|
||||
|
||||
return (
|
||||
<Table
|
||||
{...tableProps}
|
||||
columnConfig={selectionColumns}
|
||||
selection={{
|
||||
mode: 'multiple',
|
||||
behavior: 'toggle',
|
||||
selected,
|
||||
onSelectionChange: setSelected,
|
||||
}}
|
||||
rowConfig={{ onClick: item => alert(`Clicked: ${item.name}`) }}
|
||||
/>
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
export const SelectionModePlayground: Story = {
|
||||
render: () => {
|
||||
const [selectionMode, setSelectionMode] = useState<'single' | 'multiple'>(
|
||||
'multiple',
|
||||
);
|
||||
const [selected, setSelected] = useState<Set<string | number> | 'all'>(
|
||||
new Set(),
|
||||
);
|
||||
|
||||
const { tableProps } = useTable({
|
||||
mode: 'complete',
|
||||
getData: () => selectionData,
|
||||
paginationOptions: { pageSize: 10 },
|
||||
});
|
||||
|
||||
return (
|
||||
<Flex direction="column" gap="8">
|
||||
<Table
|
||||
{...tableProps}
|
||||
columnConfig={selectionColumns}
|
||||
selection={{
|
||||
mode: selectionMode,
|
||||
behavior: 'toggle',
|
||||
selected,
|
||||
onSelectionChange: setSelected,
|
||||
}}
|
||||
/>
|
||||
<div>
|
||||
<Text as="h4" style={{ marginBottom: 'var(--bui-space-2)' }}>
|
||||
Selection mode:
|
||||
</Text>
|
||||
<RadioGroup
|
||||
aria-label="Selection mode"
|
||||
orientation="horizontal"
|
||||
value={selectionMode}
|
||||
onChange={value => {
|
||||
setSelectionMode(value as 'single' | 'multiple');
|
||||
setSelected(new Set());
|
||||
}}
|
||||
>
|
||||
<Radio value="single">single</Radio>
|
||||
<Radio value="multiple">multiple</Radio>
|
||||
</RadioGroup>
|
||||
</div>
|
||||
</Flex>
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
export const SelectionBehaviorPlayground: Story = {
|
||||
render: () => {
|
||||
const [selectionBehavior, setSelectionBehavior] = useState<
|
||||
'toggle' | 'replace'
|
||||
>('toggle');
|
||||
const [selected, setSelected] = useState<Set<string | number> | 'all'>(
|
||||
new Set(),
|
||||
);
|
||||
|
||||
const { tableProps } = useTable({
|
||||
mode: 'complete',
|
||||
getData: () => selectionData,
|
||||
paginationOptions: { pageSize: 10 },
|
||||
});
|
||||
|
||||
return (
|
||||
<Flex direction="column" gap="8">
|
||||
<Table
|
||||
{...tableProps}
|
||||
columnConfig={selectionColumns}
|
||||
selection={{
|
||||
mode: 'multiple',
|
||||
behavior: selectionBehavior,
|
||||
selected,
|
||||
onSelectionChange: setSelected,
|
||||
}}
|
||||
/>
|
||||
<div>
|
||||
<Text as="h4" style={{ marginBottom: 'var(--bui-space-2)' }}>
|
||||
Selection behavior:
|
||||
</Text>
|
||||
<RadioGroup
|
||||
aria-label="Selection behavior"
|
||||
orientation="horizontal"
|
||||
value={selectionBehavior}
|
||||
onChange={value => {
|
||||
setSelectionBehavior(value as 'toggle' | 'replace');
|
||||
setSelected(new Set());
|
||||
}}
|
||||
>
|
||||
<Radio value="toggle">toggle</Radio>
|
||||
<Radio value="replace">replace</Radio>
|
||||
</RadioGroup>
|
||||
</div>
|
||||
</Flex>
|
||||
);
|
||||
},
|
||||
};
|
||||
@@ -47,7 +47,11 @@ function TextComponent<T extends ElementType = 'span'>(
|
||||
|
||||
TextComponent.displayName = 'Text';
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* A typographic primitive that renders text with design system variants, weights, and colors, and can render as any HTML element.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const Text = forwardRef(TextComponent) as {
|
||||
<T extends ElementType = 'p'>(
|
||||
props: TextProps<T> & { ref?: React.ComponentPropsWithRef<T>['ref'] },
|
||||
|
||||
@@ -22,7 +22,11 @@ import type { TextFieldProps } from './types';
|
||||
import { useDefinition } from '../../hooks/useDefinition';
|
||||
import { TextFieldDefinition } from './definition';
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* A single-line text input with an integrated label, optional icon, and inline error display.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const TextField = forwardRef<HTMLDivElement, TextFieldProps>(
|
||||
(props, ref) => {
|
||||
const { ownProps, restProps, dataAttributes } = useDefinition(
|
||||
|
||||
@@ -20,7 +20,11 @@ import type { ToggleButtonProps } from './types';
|
||||
import { useDefinition } from '../../hooks/useDefinition';
|
||||
import { ToggleButtonDefinition } from './definition';
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* A button that maintains a pressed or unpressed state, with optional start and end icon slots.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const ToggleButton = forwardRef(
|
||||
(props: ToggleButtonProps, ref: Ref<HTMLButtonElement>) => {
|
||||
const { ownProps, restProps, dataAttributes } = useDefinition(
|
||||
|
||||
@@ -20,7 +20,11 @@ import type { ToggleButtonGroupProps } from './types';
|
||||
import { useDefinition } from '../../hooks/useDefinition';
|
||||
import { ToggleButtonGroupDefinition } from './definition';
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* A container that groups ToggleButton items and manages their collective selection state.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const ToggleButtonGroup = forwardRef(
|
||||
(props: ToggleButtonGroupProps, ref: Ref<HTMLDivElement>) => {
|
||||
const { ownProps, restProps } = useDefinition(
|
||||
|
||||
@@ -28,14 +28,22 @@ import { TooltipDefinition } from './definition';
|
||||
import { Box } from '../Box';
|
||||
import { BgReset } from '../../hooks/useBg';
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* A wrapper that connects a trigger element to a Tooltip, controlling its show and hide behavior with a configurable delay.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const TooltipTrigger = (props: TooltipTriggerComponentProps) => {
|
||||
const { delay = 600 } = props;
|
||||
|
||||
return <AriaTooltipTrigger delay={delay} {...props} />;
|
||||
};
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* A floating label that provides contextual information about an element when it receives hover or focus.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const Tooltip = forwardRef<HTMLDivElement, TooltipProps>(
|
||||
(props, ref) => {
|
||||
const { ownProps, restProps } = useDefinition(TooltipDefinition, props);
|
||||
|
||||
@@ -20,6 +20,7 @@ import { Text } from '../components/Text';
|
||||
|
||||
const meta = preview.meta({
|
||||
title: 'Backstage UI/Colors',
|
||||
tags: ['!manifest'],
|
||||
});
|
||||
|
||||
export const Default = meta.story({
|
||||
|
||||
Reference in New Issue
Block a user