pnpm dev
- 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 incellMenuItemIds—contentType(andcontentType:<type id>for one button within that row), the Format rowsalignment,padding,fill(the row of both colour pickers, Fill and Border color),borderStyle,borderWeightandcorners, thenpaintFormat(copyPropertiesandpastePropertiesin the Table menu) and the Cell menu'smergeandsplit. 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 onlycontentType,contentType:textandcontentType: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 ReactTableMenupanel 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
CellMenuItemsinside 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 MUIMenuItemrows 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 arecell(the cell whose menu this is),localize,closeMenuandrenderFormatControls. The items come already filtered bysetCellMenuItemFilter, and each acts on the cell it was given. Labels are English, because the library does not localize; passlocalize: (englishLabel, id) => stringto supply your own wording, whereidis the item's id,<choice id>:<option id>for one button of the Content Type row, ortableCellfor the heading.closeMenuis 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 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
- 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 withCellMenuItemsandopenCellMenuthis gives a host both routes to one menu whose cell items come from the library.