Skip to content

Repository files navigation

bloom-table

Demo App

pnpm dev

Notes

  • Rendering is explicit and deterministic. The renderer reads data-* attributes (column widths, row heights, spans, borders, corners) and applies styles.
  • Call attachTable(gridElement) once after inserting demo HTML; it configures the renderer and triggers an initial render.
  • A host that lays some tables out itself can withhold the chrome that changes a table's structure — the row and column clusters (each a "..." pill and a "+" button) and the table menu pill — by calling setStructuralChromeGate((table) => boolean). The gate is asked about each table as that chrome is about to be shown or repositioned, and refusing one leaves the rest of that table's editing untouched, the right-click Cell menu included. Bloom uses it for a calendar month grid, whose seven columns and day rows its own layout code depends on.
  • The same host can filter a menu item by item, by calling setCellMenuItemFilter((itemId, cell, table) => boolean). There is one menu, and this decides what it offers: the composition asks the filter about each item as it builds, and leaves out the ones the host refuses. The ids are in cellMenuItemIdscontentType (and contentType:<type id> for one button within that row), the Format rows alignment, padding, fill (the row of both colour pickers, Fill and Border color), borderStyle, borderWeight and corners, then paintFormat (copyProperties and pasteProperties in the Table menu) and the Cell menu's merge and split. A section whose every item is refused disappears with its divider and its header, so a filter never leaves a stray rule behind. Install no filter and every menu offers everything, as before. Write the filter as a list of what to keep: a host that names what to remove silently gains any item a later version of the library adds. Bloom allows a calendar cell only contentType, contentType:text and contentType:image, because Merge would leave a month short of cells and the Format section's borders fight the edges its layout writes. This governs the DOM menus; the optional React TableMenu panel composes its own controls.
  • A host that wants that same menu on a button of its own calls openCellMenu(cell, { x, y }), which is the path a right-click takes. It returns false while Paint Format mode runs, and opens nothing.
  • A host that has to show a cell's items beside items of its own renders the exported React component CellMenuItems inside its own MUI menu. It is the component the library's own popup mounts, so there is one renderer of these items and the two menus cannot come to differ: the commands are MUI MenuItem rows with the library's icons, the Content Type row is its label on one line and the options below it as toggle buttons with the chosen one pressed, and a divider falls wherever the item group changes. It heads them with a "Table Cell" section heading, small, grey and upper case like the library's other section headings but starting at the left edge of the menu's content rather than at the icon gutter, so the same heading appears wherever the items do and the library's popup adds none of its own; a cell whose host filters every item away gets no heading either. The props are cell (the cell whose menu this is), localize, closeMenu and renderFormatControls. The items come already filtered by setCellMenuItemFilter, and each acts on the cell it was given. Labels are English, because the library does not localize; pass localize: (englishLabel, id) => string to supply your own wording, where id is the item's id, <choice id>:<option id> for one button of the Content Type row, or tableCell for the heading. closeMenu is called just before a command runs, so the host's menu is out of the way of whatever the command changes; choosing a content type leaves the menu open. Because the component is the menu's currency, react, react-dom, @mui/material, @mui/icons-material and @emotion/react are required peer dependencies, and a host must supply the one shared copy of React.
    • The Format rows are sliders and colour pickers, and they are still the library's own DOM widgets: the component draws them only where the host passes renderFormatControls: (container) => void, which the library's popup does and a host need not. A host that leaves it out gets no Format section, and gains one for free if those rows ever become part of the component.
  • The right-click reaches such a host through setCellMenuOpenHandler((cell, table, position) => boolean). A right-click on a cell asks the handler first; a handler that answers true has opened a menu of its own and the library opens none, and one that answers false leaves the menu to the library, as does having no handler. Bloom answers true for a picture in a calendar month grid, where the menu has to carry the image commands as well as the content type, and false everywhere else. Together with CellMenuItems and openCellMenu this gives a host both routes to one menu whose cell items come from the library.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages