Commit Graph
215 Commits
Author SHA1 Message Date
Philipinho c8086b33e4 fix(base): show skeleton while inline embed is being created, anchor at slash position
The Database slash command deleted the trigger text and then awaited
the create-base API before inserting the embed. During the wait the
editor sat empty (no visible state), and by the time the embed was
inserted the editor's selection had often drifted — so the new node
landed in the wrong place and the page appeared to "jump up" when the
response arrived.

Insert a placeholder baseEmbed node synchronously at the slash position
with pageId: null and a unique pendingKey. BaseEmbedView renders
BaseTableSkeleton while pendingKey is set — same skeleton BaseTable
shows on its own initial load, so the swap to the real table is a
visual no-op. Once the API responds, look up the placeholder by its
pendingKey and patch in the real pageId via setNodeMarkup. On API
failure, remove the placeholder and surface a toast. The pendingKey
attribute is non-serializing (parseHTML returns null, renderHTML
returns {}) so a placeholder can't survive a page reload as orphan.
2026-04-27 22:02:42 +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 a645ab947b style: introduce --page-header-height variable 2026-04-27 13:52:49 +01:00
Philipinho 6a89212e32 fix(base): strip global ProseMirror 3rem horizontal padding from full-page base title
core.css globally pads .ProseMirror with 3rem on each side, so the
TitleEditor's content sat 48px further in than the table below. Add
a .base-page-title scope that resets the padding to 0 (only on the
full-page base title wrapper), so the outer 24px paddingInline is
the single source of horizontal positioning. Doc pages and the
embedded BaseTable are unaffected — neither uses the new class.
2026-04-27 11:29:17 +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 7a119010c7 fix(base): suppress ProseMirror atom-node selection outline on inline embed 2026-04-27 04:23:16 +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 a7105267ed fix(base): keep inline embed left edge at page-content, extend right only
Removing the leftward extension. With negative margin-left, the
grid grew leftward past page-content and the first column appeared
near the sidebar edge on load — wrong; Notion keeps the first column
aligned with page text. Drop margin-left and the extendLeft
calculation; only extend rightward toward AppShell.Main's right edge.

Leftward viewport extension (so frozen columns can lock at the
sidebar edge during scroll) becomes meaningful once we add frozen
columns. Deferred until that feature lands.
2026-04-27 04:05:18 +01:00
Philipinho 67f45ee61b fix(base): anchor inline embed extension to AppShell main, not first wider parent
The findWiderAncestor walk often stopped at a slightly-larger
intermediate (NodeViewWrapper, drag-handle wrapper, etc.) whose
left edge was almost the same as the wrapper's, so the leftward
extension came out as ~0 and the grid only grew to the right.

Use closest('main') instead — that's AppShell.Main, the layout
container whose bounds already reflect the navbar width and
sidebar collapse state. Both sides now extend to its edges.
2026-04-27 03:57:45 +01:00
Philipinho d73ac010af feat(base): use negative margin to extend inline grid past parent
The previous approach (position: relative + explicit width +
inset-inline-start) didn't physically grow the box in some flex
contexts, so the grid stayed at the parent's width. Switch to
negative margin-left / margin-right on the grid wrapper only —
with width: auto, the rendered width becomes parent + |margin|,
extending the box past the parent without any positioning hacks.

The toolbar keeps its natural parent-constrained width (no extension)
so it stays aligned with the page text above. Two CSS vars,
--embed-extend-l / --embed-extend-r, are computed on mount + on
ResizeObserver from the wrapper and the closest wider ancestor.
2026-04-27 03:51:21 +01:00
Philipinho 8132b171f4 fix(base): apply embed width-extension after base loads, not just on mount
useEffect ran once on mount with empty deps, but the wrapper div was
inside a conditional branch that only renders after the base query
resolves. Result: the ref was null when the effect ran, so nothing
extended. Move the wrapper outside the conditional so the ref is
always set, and re-run the effect when isLoading / isError / pageId
change so the extension applies once the table mounts.
2026-04-27 03:43:38 +01:00
Philipinho e0e87329f4 feat(base): inline embed extends grid + toolbar beyond page width
When a base is embedded inline in a doc page, measure the parent
container's available area and extend toolbar + grid sections to fill
it via CSS variables (--embed-width / --embed-shift / --embed-pad).
Inner content is re-padded so toolbar buttons and the first column
visually align with the page text, while the box itself reaches the
viewport edges for horizontal scroll headroom on wide databases.
Sticky inset-inline-start keeps the toolbar pinned to the page-content
edge during horizontal scroll. Standalone full-page bases are
unaffected (the embedded prop defaults to false).
2026-04-27 03:39:03 +01:00
Philipinho 7f8ed733a3 feat(base): inline base embed — node registration, slash command, and renderer view 2026-04-27 01:54:59 +01:00
Philipinho 66c70c0e76 fix print 2026-04-14 00:40:17 +01:00
Philip Okugbe bd68e47e03 feat(ee): page verification workflow (#2102)
* feat: page verification workflow

* feat: refactor page-verification

* sync

* fix type

* fix

* fix

* notification icon

* use full word

* accept .license file

* - update templates
- update migration and notification

* fix copy

* update audit labels

* sync

* add space name
2026-04-13 20:20:34 +01:00
Philip Okugbe d42091ccb1 feat: favorites (#2103)
* feat: favorites and templates(ee)

* rename migrations

* fix sidebar

* cleanup tabs

* fix

* turn off templates

* cleanup

* uuid validation
2026-04-12 22:06:25 +01:00
Philip Okugbe 57efb91bd3 feat(ee): ai chat (#2098)
* feat: ai chat

* feat: ai chat

* sync

* cleanup

* view space button
2026-04-10 19:23:47 +01:00
Philip Okugbe 895c1817ae feat: bug fixes (#2084)
* handle enter in inline code

* fix: duplicate comment cache

* track link nodes (backlinks)

* fix en-US translation

* fix internal a-links

* overrides

* 0.71.1
2026-04-05 13:45:36 +01:00
Philip Okugbe 879aa2c3d8 feat: page update notifications (#2074)
* feat: watchers notification and email preferences

* fix: email copy

* digests

* clean up

* fix

* clean up

* move backlinks queue-up to history processor

* fix

* fix keys

* feat: group notifications

* filter

* adjust email digest window
2026-03-31 16:03:59 +01:00
Philip Okugbe a062f7a165 fix: enhance confluence importer (#2072)
* fix placeholder

* min resize dimensions

* fix media links

* fix
2026-03-30 13:16:40 +01:00
Philipinho 5cea30cc5c fix markdown paste 2026-03-29 16:11:21 +01:00
Philip Okugbe 412962204c fix: editor fixes (#2067)
* autojoiner

* fix marked

* return clipboardTextSerializer as markdown

* fix clipboardTextSerializer for single lines

* cleanup two preceeding spaces in ordered lists item

* fix extra paragraph in task list

* don't zip sinple page exports
2026-03-29 02:19:09 +01:00
Olivier Lambert a42ac3d450 fix: strip trailing whitespace-only paragraphs from pasted content (#2050) 2026-03-28 22:26:47 +00:00
Philip Okugbe 3829b6cbef feat(ee): viewer comments (#2060) 2026-03-28 19:32:52 +00:00
Philipinho 859f16740b tooltip portal 2026-03-28 19:19:00 +00:00
Philip Okugbe 7981ef462e feat(editor): audio and PDF nodes (#2064)
* use local resizable

* feat: aduio

* support audio imports

* feat: use confluence real file names

* cleanup

* error handling

* hide notice

* add audio

* fix pulse

* Fix import and export

* unify pulse

* hide in readonly mode

* keywords

* keyword

* translations

* better sort

* feat: PDF embed

* cleanup

* remove audio menu

* open active

* hide focus on readonly mode

* increase iframe default dimension
2026-03-28 17:33:29 +00:00
Philip Okugbe fa4872e89e fix(deps): package updates (#2041)
* update
* overrides
* override
* fix page update mutation
* fix
* cleanup
* loader
* fix excalidraw package
* override
* fix regex
2026-03-25 10:07:01 +00:00
Philipinho 2678c4e279 fix 2026-03-16 00:32:30 +00:00
Philipinho b0bde4b375 feat: replace link popover with dedicated bubble menu 2026-03-16 00:26:03 +00:00
Philipinho 724e37d5b7 revert 2026-03-15 23:03:32 +00:00
Philip Okugbe 7520c329d0 fix notion importer (#2027)
* fix notion importer

* fix link selector on mobile
2026-03-15 22:06:40 +00:00
Philip Okugbe 89b94e5d19 feat: refactor link menu (#2025)
* link markview - WIP

* WIP

* feat: refactor links

* cleanup
2026-03-15 17:08:59 +00:00
Philip Okugbe 1fdee33206 feat(editor): add auto-save and unsaved changes protection for diagrams (#2011)
* feat(editor): add auto-save and unsaved changes protection for diagrams
* 30 seconds
2026-03-13 17:58:29 +00:00
Philip Okugbe 7b69727a30 fix shared page mention view for non-logged in users (#2008) 2026-03-11 19:25:27 +00:00
Philipinho fcffa3dfa0 fix media 2026-03-04 12:08:08 +00:00
Philip Okugbe bea1637519 fix: image fallback regression (#1989)
* fix: image fallback regression

* fix image preview on upload

* fix image loading
2026-03-04 11:51:43 +00:00
Olivier Lambert f5d794220e fix: resolve keystroke input being swallowed after link in Firefox (#1922)
* fix: resolve keystroke input being swallowed after link in Firefox

In Firefox, when the cursor is at the right boundary of a link mark,
contenteditable inserts new text inside the <a> element. ProseMirror
then rejects the DOM mutation because the link mark has inclusive: false,
causing keystrokes to be silently swallowed. Unlike Chrome, Firefox also
does not fire ProseMirror's handleTextInput callback in this state.

This adds a ProseMirror plugin that intercepts printable character
keydowns at link mark boundaries and programmatically inserts the text
without the link mark, bypassing Firefox's native contenteditable
behavior entirely.

Fixes #1773

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: resolve keystroke input being swallowed before a link in Firefox

Extend the linkBoundaryInput plugin to also handle the left boundary
of links, where the cursor is just before a link (e.g. at the start
of a line). Firefox inserts text inside the <a> element in this case
too, causing ProseMirror to reject the mutation.

Fixes #1748
2026-03-03 17:19:03 +00:00
faruk-agentiqus a3c1c6cccd fix(editor): disable slash and emoji menus inside code blocks (#1897)
The slash command menu (/) and emoji menu (:) were incorrectly
triggering when typing inside code blocks, breaking keyboard
navigation and confusing users who type paths like /work or
symbols like := in their code.

Added an `allow` function to both SlashCommand and EmojiCommand
extensions that checks if the cursor is inside a code block and
disables the menu accordingly.

Closes #1730
2026-03-03 16:51:00 +00:00
Philipinho 568dd4c321 fix headings 2026-03-03 14:17:51 +00:00
Philipinho 9f4728e279 fix 2026-03-03 00:08:20 +00:00
Philip Okugbe a3fd79dae8 fix: spreadsheets paste (#1982) 2026-03-02 17:37:56 +00:00
Philipinho cf43e2b4fe feat: enhance embed resizer 2026-03-02 02:45:13 +00:00
Philipinho 614baf153b fix: show resize handle if node is selected 2026-03-02 01:57:06 +00:00
Philipinho d5e4b8bb59 fix ui 2026-03-01 20:58:04 +00:00
Philip Okugbe 60848ea903 feat(ee): mcp (#1976)
* feat: MCP
* sync
* sync
2026-03-01 18:37:39 +00:00
Philip Okugbe 2309d1434b feat: support cross-space page mentions (#1979) 2026-03-01 17:14:10 +00:00
Philip Okugbe fc0997fd90 feat: editor attachment paste handling (#1975)
* reupload attachments if uploaded to a different page
* use image dimensions on paste/DnD

* tooltips withinPortal:false

* isolating attribute
2026-02-28 01:24:19 +00:00
Philipinho df64de5306 fix focus 2026-02-27 01:38:43 +00:00
Philip Okugbe ea44468fad feat: editor inline status node (#1973)
* inline status node

* fix alignment

* fix

* typed storage

* fix math block popup on select all
2026-02-27 01:34:03 +00:00