Angular Spreadsheet Component | ng-hub-ui-spreadsheet

Editable Angular spreadsheet with Excel's keyboard, rectangular selection, a clipboard that round-trips with Excel, frozen panes and merged cells. MIT, accessible, no paid tier.

Styles

CSS variables

Theme every pixel with 61 CSS variables. Override them at :root or scope them to a wrapper.

Spreadsheet

Design tokens read by this component. Override them on the host element (or any ancestor) to customize; every default falls back to the ng-hub-ui-ds layer.

VariableDefaultTypeDescription
--hub-spreadsheet-bgvar(--hub-table-bg, var(--hub-sys-color-surface, #fff))color Sheet and cell background
--hub-spreadsheet-colorvar(--hub-table-color, var(--hub-sys-color-text, #212529))color Value text colour
--hub-spreadsheet-border-colorvar(--hub-table-border-color, var(--hub-sys-border-color-default, #dee2e6))color Grid lines and outer frame
--hub-spreadsheet-border-widthvar(--hub-table-border-width, 1px)length Thickness of the grid lines
--hub-spreadsheet-border-radiusvar(--hub-table-border-radius, var(--hub-sys-radius-lg, 0.5rem))length Rounding of the outer frame
--hub-spreadsheet-cell-padding-xvar(--hub-table-cell-padding-x, 0.6rem)length Horizontal padding inside a cell
--hub-spreadsheet-cell-padding-yvar(--hub-table-cell-padding-y, 0.4rem)length Vertical padding inside a cell
--hub-spreadsheet-header-bgvar(--hub-table-container-bg, var(--hub-sys-color-surface-subtle, #f8f9fa))color Header row background
--hub-spreadsheet-header-colorvar(--hub-sys-text-muted, #6a737b)color Header text colour
--hub-spreadsheet-header-font-size0.8125remlength Header text size
--hub-spreadsheet-header-font-weight600number Header text weight
--hub-spreadsheet-cell-line-height1.5emnumber The line one row of text stands on. Read only to hold a cell's height while its content is away in an editor — without it a row whose other cells are empty collapses the moment the reader opens one
--hub-spreadsheet-cursor-colorvar(--hub-sys-color-primary, #0d6efd)color Outline of the active cell, and the editor border
--hub-spreadsheet-cursor-width2pxlength Thickness of that outline
--hub-spreadsheet-selection-bgcolor-mix(in srgb, var(--hub-spreadsheet-cursor-color) 12%, transparent)color Tint over the selected range
--hub-spreadsheet-affordance-colorvar(--hub-select-arrow-color, var(--hub-sys-text-muted, #6a737b))color Colour of the caret or calendar mark that says the cell opens onto a list or a date, drawn on the cell in hand and on the one under the pointer
--hub-spreadsheet-affordance-sizevar(--hub-select-arrow-size, 5px)length How big that mark is. The select's own size where the design system has one, so the two arrows are the same arrow
--hub-spreadsheet-affordance-gapvar(--hub-select-arrow-gap, 0.5rem)length How far that mark is held off the cell's trailing edge — the select's own gap, so the caret of a cell and the caret of the field that opens over it sit in the same place
--hub-spreadsheet-affordance-field-bordervar(--hub-input-border-width, 1px)border How thick the frame is on the field that opens over the cell. The mark lines up with that field's content edge, or it moves by a pixel as the editor arrives
--hub-spreadsheet-placeholder-colorvar(--hub-sys-text-muted, #6a737b)color Colour of a column hint shown in an empty cell
--hub-spreadsheet-placeholder-opacity0.65number How strongly that hint shows while the pointer rests on the cell
--hub-spreadsheet-placeholder-transitionvar(--hub-sys-transition-fast, all 0.15s ease-in-out)transition How the hint fades in and out; the design system hands over a whole shorthand rather than a duration
--hub-spreadsheet-readonly-bgcolor-mix(in srgb, var(--hub-spreadsheet-header-bg) 55%, var(--hub-spreadsheet-bg))color Background of a cell that cannot be typed into
--hub-spreadsheet-readonly-colorvar(--hub-sys-text-muted, #6a737b)color Text of read-only and muted cells, and of the empty message
--hub-spreadsheet-editor-bgvar(--hub-spreadsheet-bg)color Background of the field that replaces a cell
--hub-spreadsheet-editor-colorvar(--hub-spreadsheet-color)color Text colour of that field
--hub-spreadsheet-editor-field-bgtransparentcolor Background a control supplied by the host takes inside a cell; the cell's own is behind it
--hub-spreadsheet-editor-field-border-colortransparentcolor Its border colour. Transparent rather than no border at all, so the box keeps its geometry and nothing shifts as the editor opens
--hub-spreadsheet-editor-field-border-radius0length Its corners. Square, because a rounded box inside a square cell reads as something laid on the sheet rather than part of it
--hub-spreadsheet-editor-field-focus-shadownoneshadow Its focus ring, dropped so the cell's mark is the only one the reader sees
--hub-spreadsheet-state-pending-colorvar(--hub-sys-color-warning, #cc8a00)color Bar of a cell written but not yet sent
--hub-spreadsheet-state-saving-colorvar(--hub-sys-color-info, #0a7ea4)color Bar of a cell being saved
--hub-spreadsheet-state-saved-colorvar(--hub-sys-color-success, #1a7f37)color Bar of a cell the server accepted
--hub-spreadsheet-state-error-colorvar(--hub-sys-color-danger, #b3261e)color Bar of a cell whose save failed
--hub-spreadsheet-state-conflict-colorvar(--hub-sys-color-danger, #b3261e)color Stripes of a cell somebody else also changed
--hub-spreadsheet-state-bar-width3pxlength Width of every save-state bar
--hub-spreadsheet-suggestions-bgvar(--hub-spreadsheet-menu-bg)color Background of the list of what can go into a formula
--hub-spreadsheet-suggestions-border-colorvar(--hub-spreadsheet-menu-border-color)color Its border
--hub-spreadsheet-suggestion-on-bgvar(--hub-spreadsheet-selection-bg)color The one the keyboard is on, or the pointer
--hub-spreadsheet-alias-bgcolor-mix(in srgb, var(--hub-spreadsheet-cursor-color) 12%, transparent)color Background of the chip on a header showing the name a formula calls that column by — its alias, which is never the header text
--hub-spreadsheet-alias-colorvar(--hub-spreadsheet-cursor-color)color Its text
--hub-spreadsheet-menu-bgvar(--hub-sys-color-surface, #fff)color Background of the structural menu
--hub-spreadsheet-menu-colorvar(--hub-spreadsheet-color)color Its text colour
--hub-spreadsheet-menu-border-colorvar(--hub-spreadsheet-border-color)color Its outline
--hub-spreadsheet-menu-radiusvar(--hub-sys-radius-sm, 0.25rem)length Its rounding
--hub-spreadsheet-menu-shadow0 6px 20px rgb(0 0 0 / 18%)shadow Shadow that lifts it off the sheet
--hub-spreadsheet-menu-item-padding-x0.85remlength Horizontal padding of a menu entry
--hub-spreadsheet-menu-item-padding-y0.4remlength Vertical padding of a menu entry
--hub-spreadsheet-menu-item-bg-hovervar(--hub-spreadsheet-selection-bg)color Background of the entry under the pointer
--hub-spreadsheet-resize-grip-width5pxlength Width of the target on a header's trailing edge, invisible until reached for
--hub-spreadsheet-resize-grip-colorvar(--hub-spreadsheet-cursor-color)color Colour that target takes while the pointer is on it
--hub-spreadsheet-moving-opacity0.5number How faint a header goes while it is being dragged elsewhere
--hub-spreadsheet-fill-handle-size7pxlength Side of the square grip at the corner of the selection
--hub-spreadsheet-fill-handle-colorvar(--hub-spreadsheet-cursor-color)color Colour of that grip; the cursor's, so the two read as one thing
--hub-spreadsheet-fill-preview-bgcolor-mix(in srgb, var(--hub-spreadsheet-cursor-color) 6%, transparent)color Tint over the area a released drag would write to
--hub-spreadsheet-invalid-colorvar(--hub-sys-color-danger, #b3261e)color Editor border and text when the typed value does not parse
--hub-spreadsheet-invalid-bgcolor-mix(in srgb, var(--hub-spreadsheet-invalid-color) 10%, transparent)color Tint of that cell while the editor holds it
--hub-spreadsheet-invalid-border-width1pxlength Outline drawn inside an invalid cell, so turning invalid never shifts its neighbours
--hub-spreadsheet-max-block-sizevar(--hub-table-container-max-block-size, none)length Height at which the sheet scrolls instead of growing
--hub-spreadsheet-frozen-divider-colorvar(--hub-spreadsheet-border-color, var(--hub-sys-border-color-default, #dee2e6))color Seam between a frozen pane and the rest
--hub-spreadsheet-frozen-divider-width2pxlength Thickness of that seam