Features/Sheets
- Sheets
- Sheets turn ordinary outline branches into 2-D views — tables, boards, and grids. The same file still opens in Logseq as nested bullets with harmless
tine.*properties, in Markdown and Org alike. - This page starts with the easiest path — viewing bullets you already have — and adds fields, formulas, and query-backed views after.
- Start from bullets you already have
- Sheets never move your data: rows are child bullets, columns are their properties, cards are child bullets or blocks a query finds. Nothing is converted or copied.
- Right-click a parent bullet and choose Show children as → Grid or Table — or type
/Grid,/Table, or/Boardon that block. To view blocks a query finds instead, type/Query, then run/Tableor/Boardon the query block. - What Tine writes: plain block properties such as
tine.view:: tableon the view-owning block. Editing a sheet cell writes back into the underlying bullet, so the outline and the sheet always agree.
- Task tabletine.view:: tabletine.col-aggregates:: prop:estimate=sum
- SCHEDULED: 2026-07-08 Wedowner:: Martinestimate:: 2
- DOING Polish cell menus #sheets-demoowner:: Codexestimate:: 5
- DONE Add aggregate footer #sheets-demoDEADLINE: 2026-07-10 Friowner:: Codexestimate:: 1
- Create one yourself — table
- 1. On a block, type
/Tableand pick Table (or right-click an existing outline and choose Show children as → Table). - 2. Use the ghost + Add row and + Add column buttons to build it out. Each row is a child bullet; each column is a property such as
owner::orestimate::, edited right in the cells. - 3. Right-click a children-backed column header or double-click its name to rename the field and its dependent filter, group, aggregate, and formula references together. Ambiguous or colliding names are refused.
- 4. Drag the right edge of a column header to set its width; double-click that edge to reset the one column. Widths are remembered per field, so they survive a reload and follow the field if you reorder columns. A table wider than the pane scrolls sideways instead of crushing its text.
- 5. Press Tab after editing a cell to commit its value and move to the next cell.
- 6. What you should see: each child bullet becomes a row, and properties become editable table columns.
- 7. Under the hood: the block carries
tine.view:: table(with optionaltine.fields::to type columns andtine.col-aggregates:: prop:estimate=sumto total a numeric column in the footer). The ghost buttons write these for you.
- Typed reading listtine.view:: tabletine.fields:: status=enum:todo,reading,done;rating=number;done=checkbox;owner=reftine.formula.effort:: rating * 2
- Bases studystatus:: readingrating:: 5done:: falseowner:: [[Martin]]
- CSV import notesstatus:: todorating:: 3done:: falseowner:: [[Codex]]
- Create one yourself — formula
- 1. Start with a table that has a numeric or enum field, for example
rating=number. - 2. Right-click a column header and choose Add formula…, then build the value from the visual faces (or the
</> rawbox). - 3. What you should see: a read-only computed column — like
effortabove, which multiplies each row'sratingby 2 — whose values evaluate live and are not written onto the rows. - 4. For the full walkthrough — the value picker, IF / THEN / ELSE, transforms, and when to reach for
</> raw— see Features/Formulas.
- Task board
- Query 3
- SCHEDULED: 2026-07-08 Wedowner:: Martinestimate:: 2
- DOING Polish cell menus #sheets-demoowner:: Codexestimate:: 5
- DONE Add aggregate footer #sheets-demoDEADLINE: 2026-07-10 Friowner:: Codexestimate:: 1
tine.view:: boardtine.group-by:: state
- Create one yourself — query
- 1. Type
/Queryand create a query for the blocks you want, such as tasks tagged#sheets-demo. - 2. Keep the query in one block, then run
/Tableor/Boardon that same block to view the results. - 3. For a board, pick the column axis with the Group by dropdown (described in the board steps below).
- 4. What you should see: query results rendered as a live sheet view — the same demo tasks as in the table above — without copying the source blocks.
- Create one yourself — board
- 1. On a block, type
/Boardand pick Board (/Kanbanfinds it too). - 2. Choose the column axis with the Group by dropdown in the board header, or right-click and use Group by → to pick State, Tags, Priority, or any field.
- 3. Add child bullets, or run
/Boardon a query block to board over query results. - 4. Drag a card between columns (or press Ctrl+←/→) and the grouping field changes on the source block.
- 5. What you should see: cards group into columns while staying normal outline blocks underneath. Group by Tags and a card with several tags appears in each matching column — like the topic board below.
- 6. Under the hood: the dropdown just writes
tine.view:: boardandtine.group-by:: state(or your chosen axis) for you.
- Topic boardtine.view:: boardtine.group-by:: tags
- Schema menu polish #schema #sheets-demo
- CSV drop walkthrough #interop #sheets-demo
- Positional gridtine.view:: gridtine.header:: truetine.col-widths:: 0=140;1=130;2=220
- Area
- Owner
- Notes
- Specbackground-color:: yellow
- Martin
- Nested sub-gridtine.view:: grid
- Risk
- Mitigation
- Scope drift
- Keep v1 narrow
- Build
- Codex
- Ragged rows are fine
- Empty middle cell
- Still round-trips
- Create one yourself — grid
- 1. On an empty block, type
/Gridand pick Grid. Tine seeds one editable cell — just start typing. - 2. Grow it by its edges: hover the grid and click the
+on the right edge for a new column, or the+on the bottom edge for a new row. Drag row or cell bullets to reshape it; the grid follows the tree. - 3. What you should see: a live grid whose cells are still ordinary Logseq bullets — including ragged rows and, above, a whole grid nested in one cell.
- 4. Under the hood: the block just carries
tine.view:: grid(plus optionaltine.header:: truefor a label row andtine.col-widths::). You never have to type those by hand.
- Honest limits
- Formula columns are derived: computed live, never written onto the rows.
- Board cards move between columns, but not within one.
pagecolumns are read-only. - A board grouped by a formula axis is read-only — moving a card cannot rewrite a computed value.