// // Copyright 2024 DXOS.org // import '@dxos-theme'; import { type Meta, type StoryObj } from '@storybook/react'; import React, { type MouseEvent, type MutableRefObject, useCallback, useRef, useState } from 'react'; import { defaultRowSize } from '@dxos/lit-grid'; import { faker } from '@dxos/random'; import { DropdownMenu } from '@dxos/react-ui'; import { PopoverCombobox, type PopoverComboboxRootProps } from '@dxos/react-ui-searchlist'; import { withTheme } from '@dxos/storybook-utils'; import { Grid, type GridEditing, type GridContentProps, type GridRootProps } from './Grid'; const storybookItems = faker.helpers.uniqueArray(faker.commerce.productName, 16); type GridStoryProps = GridContentProps & Pick; const GridStory = ({ initialCells, ...props }: GridStoryProps) => { const triggerRef = useRef(null) as MutableRefObject; const [cells, setCells] = useState(initialCells); const [editing, setEditing] = useState(null); const handleEditingChange = useCallback>((event) => { // TODO(burdon): Not working? setEditing(event ? { index: event.index, initialContent: '', cellElement: event.cellElement } : null); }, []); // Multiselect const [popoverOpen, setPopoverOpen] = useState(false); const [multiSelectValue, setInternalMultiselectValue] = useState(''); const setMultiselectValue = useCallback>((nextValue) => { setInternalMultiselectValue(nextValue); setCells((cells) => { // TODO(burdon): How can we get the cell address to update? console.log('[setMultiselectValue]', nextValue); return cells; }); }, []); // Menu const [menuOpen, setMenuOpen] = useState(false); const handleClick = useCallback((event: MouseEvent) => { const closestStoryAction = (event.target as HTMLElement).closest('button[data-story-action]'); if (closestStoryAction) { triggerRef.current = closestStoryAction as HTMLButtonElement; return setMenuOpen(true); } const closestAccessory = (event.target as HTMLElement).closest('[data-dx-grid-accessory]'); if (closestAccessory) { const action = closestAccessory.getAttribute('data-dx-grid-accessory'); switch (action) { case 'invoke-multiselect': { triggerRef.current = closestAccessory as HTMLButtonElement; return setPopoverOpen(true); } } } }, []); return (
{/* TODO(burdon): Why is this property not just "cells" or "values" */} {/* Menu */} console.log('[Click on dropdown menu item]')}>Hello {/* Multiselect */} (value.includes(search) ? 1 : 0)}> {storybookItems.map((value) => ( {value} ))}
); }; const meta: Meta = { title: 'ui/react-ui-grid/Grid', component: GridStory, decorators: [withTheme], parameters: { layout: 'fullscreen' }, }; export default meta; type Story = StoryObj; export const Basic: Story = { args: { id: 'story', columnDefault: { grid: { size: 180, resizeable: true, }, }, rowDefault: { grid: { size: defaultRowSize, resizeable: true, }, }, columns: { grid: { 0: { size: 200 }, 1: { size: 210 }, 2: { size: 230 }, 3: { size: 250 }, 4: { size: 270 }, }, }, initialCells: { grid: { '1,1': { value: 'Demo decoration', accessoryHtml: ` `, }, '2,1': { // accessoryHtml: ``, accessoryHtml: '', }, }, }, onAxisResize: (event) => { console.log('[axis resize]', event); }, }, }; // TODO(burdon): How to make single-column? export const SingleColumn: Story = { args: { id: 'story', limitColumns: 1, columnDefault: { grid: { size: 180, }, }, rowDefault: { grid: { size: defaultRowSize, resizeable: false, }, }, columns: { grid: { 0: { size: 200 }, }, }, }, };