import { useState } from "react"; import { Meta, StoryObj } from "@storybook/react"; import { fn } from "@storybook/test"; import { Table } from "."; import { SearchDescriptor } from "../../../types"; import { getCssProps } from "@sb/cssprops"; import { Flex } from "../../Layout/Flex"; import { Button } from "@components/Buttons/Button"; import { MaterialIcon, Pagination, Text } from "@components/index"; import { RenderPropsArgTypes } from "@sb/helpers"; const meta: Meta = { title: "Content/Table", component: Table, parameters: { cssprops: getCssProps("Table"), }, argTypes: { ...RenderPropsArgTypes, isSticky: { description: "Whether the bottom content should be sticky", control: "boolean", }, hasBottom: { description: "Whether the table has a bottom content", control: "boolean", }, children: { control: false, }, sortDescriptor: { description: "The current sort descriptor, if any", }, onCellAction: { description: "Fires when the user interacts with a cell", table: { category: "Events", }, }, onRowAction: { description: "Fires when the user interacts with a row", table: { category: "Events", }, }, onSortChange: { description: "Fires when the user changes the sort descriptor", table: { category: "Events", }, }, onSearchChange: { description: "Fires when the user changes search descriptor", table: { category: "Events", }, }, striped: { description: "Whether the table should have striped rows", control: "select", options: ["even", "odd"], }, sortVisibility: { control: "select", options: ["always", "selected"], }, }, }; export default meta; type Story = StoryObj; export const Primary: Story = { args: { onCellAction: fn(), onRowAction: fn(), onSortChange: fn(), onSearchChange: fn(), children: [ Name Type Level , Charizard Fire, Flying 67 Blastoise Water 56 Venusaur Grass, Poison 83 Pikachu Electric 100 , ], }, }; export const MultipleSelection: Story = { args: { ...Primary.args, selectionMode: "multiple", }, }; export const SingleSelection: Story = { args: { ...Primary.args, selectionMode: "single", }, }; export const SortableHeaders: Story = { args: { sortDescriptor: { column: "name", direction: "descending", }, children: [ Name Type Level , Charizard Fire, Flying 67 Blastoise Water 56 Venusaur Grass, Poison 83 Pikachu Electric 100 , ], }, }; export const SearchableColumns: Story = { render: (props) => { const [searchDescriptor, setSearchDescriptor] = useState({ column: "name", search: "Chariz", }); const pokemons: Record[] = [ { name: "Charizard", type: "Fire, Flying", level: "67", }, { name: "Blastoise", type: "Water", level: "56", }, { name: "Venusaur", type: "Grass, Poison", level: "83", }, { name: "Pikachu", type: "Electric", level: "100", }, ]; const filteredPokemon = pokemons.filter((pokemon) => { if (!searchDescriptor.search || !searchDescriptor.column) return true; return pokemon[searchDescriptor.column] .toLowerCase() .includes(searchDescriptor.search.toLowerCase()); }); return ( Name Type Level {(pokemon) => ( {pokemon.name} {pokemon.type} {pokemon.level} )}
); }, args: { "aria-label": "Table with searching", }, }; export const CustomizeIcons: Story = { args: { sortDescriptor: { column: "name", direction: "descending", }, sortVisibility: "always", icons: { searchClose: "close", searchOpen: "search", sortAscending: "arrow_upward", sortDescending: "arrow_downward", sortNeutral: "sort", }, children: [ Name Type Level , Charizard Fire, Flying 67 Blastoise Water 56 Venusaur Grass, Poison 83 Pikachu Electric 100 , ], }, }; export const LoadingState: Story = { args: { ...Primary.args, children: [ Name Type Level , , ], }, }; export const TableSkeleton: StoryObj = { render: (args) => , args: { rows: 10, columns: 3, }, }; export const RenderEmptyTable: Story = { ...Primary, args: { children: [ Name Type Level , There are no rows available! } />, ], }, }; export const WithTableBottom: Story = { ...Primary, render: (args) => ( <> ), args: { ...Primary.args, hasBottom: true, }, }; export const WithPagination: Story = { ...Primary, render: (args) => ( <>
), args: { ...Primary.args, hasBottom: true, }, }; export const StickyRowHeader: Story = { ...Primary, decorators: [ (Story) => (
), ], args: { ...Primary.args, children: [ Name Type Level HP Attack Defense , Charizard Fire, Flying 67 78 84 78 Blastoise Water 56 79 83 100 Venusaur Grass, Poison 83 80 82 83 Pikachu Electric 100 35 55 40 , ], isSticky: true, style: { width: "1000px", }, }, }; export const WithStripedRows: Story = { ...Primary, args: { ...Primary.args, striped: "odd", }, }; export const WithRightAlignedColumns: Story = { ...Primary, args: { ...Primary.args, children: [ Name Type Level , Charizard Fire, Flying 67 Blastoise Water 56 Venusaur Grass, Poison 83 Pikachu Electric 100 , ], }, }; export const UpperCaseColumnHeaders: Story = { ...Primary, args: { ...Primary.args, children: [ Name Type Level , Charizard Fire, Flying 67 Blastoise Water 56 Venusaur Grass, Poison 83 Pikachu Electric 100 , ], }, };