Commit Graph
29 Commits
Author SHA1 Message Date
Philipinho 7e35936544 fix(base): align inline-embed AddRowButton to page-content edge like standalone
In embed mode the "+ New row" button rendered to the right of the
data columns instead of at the page-content edge (where it lives in
standalone). Two compounding causes:

  - position: sticky with inset-inline-start:
    var(--embed-grid-pad-left, 0). Sticky offsets are measured from
    the scroll-port, not the bodyGrid's outer edge — and the scroll-
    port already starts at the page-content edge (bodyGrid's negative
    margins and equal padding cancel out). With the variable set to
    ~200px in embed, sticky shifted the button 200px *into* the
    scroll-port. inset-inline-start: 0 keeps it at the scroll-port's
    start in both modes.
  - max-content grid item with default justify-self: stretch on a
    grid-column: 1 / -1 area has surprising placement; `justify-self:
    start` makes the inline-start anchoring explicit.

Standalone behavior is unchanged (the variable was 0 there anyway).
2026-04-28 11:51:06 +01:00
Philipinho cd8d1e0ed8 feat(base): make column headers sticky in standalone and inline contexts
Split the unified .gridWrapper into a sticky band (containing column
headers, plus banner + toolbar in inline) and a body grid that owns
horizontal scroll. The band's vertical sticky anchor is automatic CSS:
the table's scrollport in standalone, the page in inline. A small
useHorizontalScrollSync hook mirrors body scrollLeft onto the header
and turns wheel-on-header into pan-on-body.
2026-04-27 20:25:13 +01:00
Philipinho 1cfd0fb2c4 style(base): add tableScrollport / stickyBand / headerGrid / bodyGrid classes 2026-04-27 14:07:20 +01:00
Philipinho 00e9d1d724 feat(base): add right-side scroll headroom on inline embed grid
Mirror the leftward padding with --embed-grid-pad-right = extendRight,
applied as padding-right on .grid. The user can now pan past the last
column into empty space — same shape as Notion's behavior. Standalone
full-page bases are unaffected (var unset → 0).
2026-04-27 04:44:47 +01:00
Philipinho 583d2d37c4 fix(base): pull AddRowButton out of grid so sticky-left actually sticks
As a child of .grid with grid-column: 1/-1, the button took the full
row width and the sticky-left offset got swallowed by the grid layout
— it scrolled along with the cells instead of anchoring to the left.

Move it to a sibling of .grid inside .gridWrapper, restyle as a
small inline-flex chip with width: max-content. Sticky-left now
keeps it pinned to page-content-left while the user scrolls
horizontally, matching the toolbar.

Add padding-bottom: 6px on .gridWrapper and a small vertical margin
on the button so the horizontal scrollbar no longer overlaps it.
2026-04-27 04:39:29 +01:00
Philipinho a992fa8a63 feat(base): keep New row button sticky during horizontal scroll
Add position: sticky + inset-inline-start to .addRowButton so the
'New row' affordance stays at the page-content edge while the user
scrolls horizontally — same shape as the toolbar staying put. The
sticky offset uses the existing --embed-grid-pad-left var: in embed
mode that's the leftward extension distance (so it sticks at
page-content-left); in standalone mode the var is 0 (sticks at the
grid's natural left edge, no visible effect when there's no scroll).

Add a body-color background and z-index: 4 so cells don't bleed
through during scroll.
2026-04-27 04:30:04 +01:00
Philipinho 678c6f5f3f fix(base): drop outer panel border on inline embed grid
The .grid had a 1px outer border + small radius drawing a rounded
rectangle around the whole table. In standalone full-page mode that
reads as a panel and is fine. In an inline embed it looked like a
floating box, especially with the leftward padded area inside the
border.

Make the outer border and radius CSS vars; the embed wrapper sets
them to none/0 so inline databases get only cell-level gridlines,
matching Notion's document-style rendering. Standalone bases get
the default 1px panel frame as before.
2026-04-27 04:20:58 +01:00
Philipinho 030d3e878a feat(base): extend inline embed scroll viewport leftward, anchor first cell with grid padding
Bring back the leftward extension via negative margin-left so the
scroll viewport reaches AppShell.Main's left edge, then offset the
.grid with padding-left = extendLeft so the first cell still lines
up with page-content on load. The extended area becomes scrollable
empty space the user can pan into — same shape as Notion's inline
databases.

Done with one new CSS var (--embed-grid-pad-left) consumed by the
.grid in grid.module.css. Standalone full-page bases never set the
var, so it's a no-op there.
2026-04-27 04:13:34 +01:00
Philipinho 137c02a10f feat(base): sticky table header so columns stay visible while scrolling
Pins the header row to the top of the gridWrapper scroll viewport, with
the pinned-left corner cell stacking above pinned body cells at the
top-left intersection. The trailing add-column button gets the same
sticky treatment so it doesn't drift away from the row.

Subtle bit: `position: sticky` confines an element to its containing
block. The previous subgrid `.headerRow` wrapper was 34px tall, so
sticky cells could only travel 34px before scrolling out with the
wrapper. Switching the wrapper to `display: contents` lets the cells
become direct grid children of `.grid` (full table height) so sticky
travel matches the scroll range. role="row" survives display:contents
in modern browsers.
2026-04-25 01:05:20 +01:00
Philipinho 9ecf88511b page property 2026-04-20 21:27:29 +01:00
Philipinho cac4774641 fix(base): stop runaway pagination loop caused by browser scroll anchoring
Browser overflow-anchor silently bumped scrollTop by one page's worth
of pixels every time a new page of rows committed — anchoring on the
AddRowButton that sits below paddingBottom. This kept the near-bottom
threshold satisfied and re-fired onFetchNextPage indefinitely, even
after the user released the scrollbar. Disabling scroll anchoring on
the grid scroll container stops the browser from adjusting scrollTop
in response to content growth.
2026-04-19 02:05:30 +01:00
Philipinho 321184394d feat(base): show table skeleton instead of centered loader on load 2026-04-18 22:22:49 +01:00
Philipinho b01f6e9af9 feat(base): add layout-matching skeleton loading component 2026-04-18 22:22:11 +01:00
Philipinho 207c74427d style(base): unify hover state across selected row cells 2026-04-18 17:15:57 +01:00
Philipinho c53d70b64e style(base): darken select option hover for better visibility 2026-04-18 17:15:23 +01:00
Philipinho 9a1cbc8ea9 style(base): nudge row drag grip past left table border 2026-04-18 17:14:49 +01:00
Philipinho 8b343d25f0 style(base): push row drag grip flush to left table border 2026-04-18 17:13:03 +01:00
Philipinho 2d47ffb25a style(base): align row drag grip flush with cell left edge 2026-04-18 17:12:42 +01:00
Philipinho b6882d774b fix(base): widen row-number column so drag grip sits left of checkbox 2026-04-18 17:09:00 +01:00
Philipinho 4dc6d32e49 fix(base): absolutely position row-number content to eliminate layout shift 2026-04-18 17:03:06 +01:00
Philipinho 3f52e54207 fix(base): pin selection bar to viewport with Confluence-style dark pill 2026-04-18 16:54:49 +01:00
Philipinho 05406640f0 feat(base): floating selection action bar with bulk delete 2026-04-18 16:44:07 +01:00
Philipinho 4c4bbe9b15 feat(base): header select-all with tri-state checkbox 2026-04-18 16:42:06 +01:00
Philipinho 3fca962c9f feat(base): row-number cell renders checkbox + drag handle on hover 2026-04-18 16:40:21 +01:00
Philipinho 0f4a819ec5 style(base): add keyboard-active option style for cell dropdowns 2026-04-18 14:47:59 +01:00
Philipinho f5b19316af Base WIP 2026-04-18 13:13:53 +01:00
Philipinho eb0538b856 fix 2026-04-17 13:41:24 +01:00
Philipinho 2a6e604bf8 person cell 2026-03-08 03:36:57 +00:00
Philipinho 94ee1e80fb feat: bases - WIP 2026-03-08 00:56:24 +00:00