@heyramzi/ui 2.8.0 → 2.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/COMPONENTS.md +1 -1
- package/README.md +1 -1
- package/dist/agents/helpers.js +52 -0
- package/dist/agents/index.js +3 -0
- package/dist/agents/page-state.js +65 -0
- package/dist/agents/types.js +1 -0
- package/dist/agents/vendor/color.js +149 -0
- package/dist/agents/vendor/draw.js +548 -0
- package/dist/agents/vendor/engine.js +632 -0
- package/dist/agents/vendor/mesh.js +727 -0
- package/dist/agents/vendor/plastic.js +3273 -0
- package/dist/agents/vendor/presets.js +171 -0
- package/dist/agents/vendor/shapes.js +24 -0
- package/dist/agents/vendor/ticker.js +56 -0
- package/dist/agents/vendor/types.js +0 -0
- package/dist/agents/vendor/wear.js +1525 -0
- package/dist/ai/ai-button/index.js +2 -0
- package/dist/ai/confirmation/confirmation-context.svelte.js +12 -0
- package/dist/ai/confirmation/index.js +9 -0
- package/dist/ai/generation-progress/index.js +2 -0
- package/dist/ai/index.js +11 -0
- package/dist/ai/loading-state/index.js +3 -0
- package/dist/ai/prompt-input/index.js +6 -0
- package/dist/ai/reasoning/index.js +4 -0
- package/dist/ai/reasoning/reasoning-context.svelte.js +12 -0
- package/dist/ai/response/index.js +3 -0
- package/dist/ai/suggestion/index.js +3 -0
- package/dist/ai/thinking-dots/index.js +3 -0
- package/dist/ai/typing-dots/index.js +2 -0
- package/dist/ai/voice-waveform/index.js +3 -0
- package/dist/animations/text-swap.js +30 -0
- package/dist/brand/index.js +65 -0
- package/dist/canvas/card/resize.js +10 -0
- package/dist/canvas/edges/edge-path.js +284 -0
- package/dist/canvas/editor/context-menu.js +42 -0
- package/dist/canvas/editor/dispatch.svelte.js +157 -0
- package/dist/canvas/editor/editor-context.js +8 -0
- package/dist/canvas/editor/editor-mode.js +0 -0
- package/dist/canvas/editor/frame.js +87 -0
- package/dist/canvas/editor/hand-context.js +8 -0
- package/dist/canvas/editor/history-core.js +221 -0
- package/dist/canvas/editor/keymap.js +193 -0
- package/dist/canvas/editor/layout-actions.js +170 -0
- package/dist/canvas/editor/lock.js +65 -0
- package/dist/canvas/editor/rebase.js +279 -0
- package/dist/canvas/editor/style.js +174 -0
- package/dist/canvas/editor/text-field-context.js +8 -0
- package/dist/canvas/editor/z-order.js +82 -0
- package/dist/canvas/headless/alignment.js +20 -0
- package/dist/canvas/headless/break-apart-find.js +324 -0
- package/dist/canvas/headless/break-apart-pieces.js +74 -0
- package/dist/canvas/headless/break-apart-plan.js +378 -0
- package/dist/canvas/headless/break-apart-style.js +93 -0
- package/dist/canvas/headless/break-apart.js +206 -0
- package/dist/canvas/headless/canvas-cleanup.js +70 -0
- package/dist/canvas/headless/edge-anchors.js +134 -0
- package/dist/canvas/headless/edge-memo.js +28 -0
- package/dist/canvas/headless/edge-serialization.js +31 -0
- package/dist/canvas/headless/figure-geometry.js +331 -0
- package/dist/canvas/headless/fit-viewport.js +82 -0
- package/dist/canvas/headless/grid.js +96 -0
- package/dist/canvas/headless/icon-node.js +45 -0
- package/dist/canvas/headless/index.js +1 -0
- package/dist/canvas/headless/linkify.js +25 -0
- package/dist/canvas/headless/pen-marks.js +115 -0
- package/dist/canvas/headless/sketch.js +250 -0
- package/dist/canvas/headless/snap-guides.js +100 -0
- package/dist/canvas/headless/svg-figure.js +137 -0
- package/dist/canvas/headless/table-layout.js +161 -0
- package/dist/canvas/index.js +25 -0
- package/dist/canvas/lod/lod-mode.svelte.js +22 -0
- package/dist/canvas/lod/render-all.svelte.js +45 -0
- package/dist/canvas/ops/arrange.js +83 -0
- package/dist/canvas/ops/ops.js +318 -0
- package/dist/canvas/pen/colors.js +41 -0
- package/dist/canvas/pen/eraser.js +35 -0
- package/dist/canvas/pen/geometry.js +143 -0
- package/dist/canvas/pen/index.js +9 -0
- package/dist/canvas/pen/ops.js +15 -0
- package/dist/canvas/pen/pen-session.js +171 -0
- package/dist/canvas/pen/plugin.js +129 -0
- package/dist/canvas/pen/shapes.js +80 -0
- package/dist/canvas/pen/stroke-path.js +37 -0
- package/dist/canvas/pen/types.js +30 -0
- package/dist/canvas/pen/ui.js +20 -0
- package/dist/canvas/plugin.js +51 -0
- package/dist/canvas/screen/glyphs.js +24 -0
- package/dist/canvas/screen/labels.js +24 -0
- package/dist/canvas/screen/parts.js +140 -0
- package/dist/canvas/screen/plugin.js +71 -0
- package/dist/canvas/screen/types.js +44 -0
- package/dist/canvas/screen/ui.js +13 -0
- package/dist/canvas/test-utils.js +18 -0
- package/dist/canvas/types.js +0 -0
- package/dist/canvas/ui/forward-wheel.js +27 -0
- package/dist/canvas/ui/icons.js +133 -0
- package/dist/canvas/ui/place-panel.js +57 -0
- package/dist/canvas/ui/shortcut-tip.js +18 -0
- package/dist/canvas/ui/tools.js +411 -0
- package/dist/charts/dashboard/chart.js +1 -0
- package/dist/charts/dashboard/data-table.js +7 -0
- package/dist/charts/dashboard/index.js +13 -0
- package/dist/charts/dashboard/windows.js +5 -0
- package/dist/charts/edge-fade.js +7 -0
- package/dist/charts/hover-band.js +13 -0
- package/dist/charts/index.js +19 -0
- package/dist/charts/motion.js +15 -0
- package/dist/charts/primitives/chart-utils.js +22 -0
- package/dist/charts/primitives/index.js +4 -0
- package/dist/components/copy/clipboard.js +38 -0
- package/dist/components/copy/copied.svelte.js +26 -0
- package/dist/components/copy/index.js +3 -0
- package/dist/components/data-table/data-table.js +55 -0
- package/dist/components/data-table/index.js +7 -0
- package/dist/components/docs/index.js +3 -0
- package/dist/components/docs/scroll-spy.svelte.js +71 -0
- package/dist/components/field-row/index.js +1 -0
- package/dist/components/hold-to-confirm/index.js +1 -0
- package/dist/components/icon/index.js +1 -0
- package/dist/components/language-flag/index.js +1 -0
- package/dist/components/list-page/filter-section.js +4 -0
- package/dist/components/list-page/index.js +25 -0
- package/dist/components/list-page/list-table.js +5 -0
- package/dist/components/list-page/queue-rail.js +3 -0
- package/dist/components/list-page/section-host.js +8 -0
- package/dist/components/list-page/step.js +5 -0
- package/dist/components/list-page/types.js +0 -0
- package/dist/components/locale-switch/index.js +1 -0
- package/dist/components/mark/index.js +1 -0
- package/dist/components/open-in/index.js +1 -0
- package/dist/components/picker/index.js +3 -0
- package/dist/components/picker/trigger.js +33 -0
- package/dist/components/picker/types.js +0 -0
- package/dist/components/section-card/index.js +1 -0
- package/dist/components/section-header/index.js +2 -0
- package/dist/components/segmented/collapse.js +32 -0
- package/dist/components/segmented/index.js +8 -0
- package/dist/components/segmented/segmented.js +50 -0
- package/dist/components/star-rating-input/index.js +2 -0
- package/dist/components/svg/index.js +1 -0
- package/dist/components/table-view/index.js +1 -0
- package/dist/components/table-view/types.js +0 -0
- package/dist/components/tags-input/index.js +2 -0
- package/dist/components/tags-input/tags.js +90 -0
- package/dist/components/theme/index.js +3 -0
- package/dist/components/toolbar/index.js +3 -0
- package/dist/components/toolbar/toolbar-trigger.js +4 -0
- package/dist/editor/anchors.js +17 -0
- package/dist/editor/block-id.js +62 -0
- package/dist/editor/block-ops.js +105 -0
- package/dist/editor/doc-blocks.js +181 -0
- package/dist/editor/extensions.js +200 -0
- package/dist/editor/index.js +4 -0
- package/dist/editor/markdown-test-helpers.js +6 -0
- package/dist/editor/markdown.js +486 -0
- package/dist/editor/serializer.js +268 -0
- package/dist/editor/slash-items.js +104 -0
- package/dist/editor/youtube-url.js +27 -0
- package/dist/effects/animated-beam/index.js +1 -0
- package/dist/effects/animated-beam/path-calculator.svelte.js +42 -0
- package/dist/effects/animated-beam/types.js +0 -0
- package/dist/effects/border-beam/css.js +420 -0
- package/dist/effects/border-beam/presets.js +1792 -0
- package/dist/effects/border-beam/register-properties.js +39 -0
- package/dist/effects/border-beam/types.js +0 -0
- package/dist/effects/image-comparison/compare.js +4 -0
- package/dist/effects/image-reveal/index.js +1 -0
- package/dist/effects/image-reveal/types.js +0 -0
- package/dist/effects/magnetic/magnetic.js +54 -0
- package/dist/effects/reveal/index.js +4 -0
- package/dist/effects/reveal/observe.js +43 -0
- package/dist/effects/reveal/types.js +0 -0
- package/dist/effects/shader-gradient/color.js +34 -0
- package/dist/effects/shader-gradient/index.js +1 -0
- package/dist/effects/shader-gradient/renderer.js +320 -0
- package/dist/effects/shader-gradient/shaders.js +280 -0
- package/dist/effects/shader-gradient/types.js +0 -0
- package/dist/icons/apple-symbol-exports.js +126 -0
- package/dist/icons/sf-symbols.js +465 -0
- package/dist/icons/trades.js +34 -0
- package/dist/inbox/index.js +4 -0
- package/dist/inbox/logic.js +156 -0
- package/dist/inbox/types.js +46 -0
- package/dist/index.js +18 -0
- package/dist/lib/arrive.js +13 -0
- package/dist/lib/icon-types.js +0 -0
- package/dist/lib/initials.js +17 -0
- package/dist/lib/layout.js +1 -0
- package/dist/lib/panel.js +3 -0
- package/dist/lib/result.js +26 -0
- package/dist/lib/sliding-pill.js +45 -0
- package/dist/lib/theme-transition.js +53 -0
- package/dist/lib/tone.js +32 -0
- package/dist/lib/utils.js +5 -0
- package/dist/onboarding/define-tours.js +28 -0
- package/dist/onboarding/index.js +4 -0
- package/dist/onboarding/onboarding.svelte.js +15 -0
- package/dist/onboarding/pick.js +16 -0
- package/dist/onboarding/stores.js +50 -0
- package/dist/onboarding/types.js +1 -0
- package/dist/onboarding/wait.js +25 -0
- package/dist/panel/index.js +1 -0
- package/dist/panel/side-panel-types.js +0 -0
- package/dist/record/demo-data.js +512 -0
- package/dist/record/fields.js +148 -0
- package/dist/record/format.js +97 -0
- package/dist/record/gutter.js +1 -0
- package/dist/record/index.js +15 -0
- package/dist/record/kinds.js +110 -0
- package/dist/record/logic.js +255 -0
- package/dist/record/types.js +52 -0
- package/dist/shadcn/accordion/index.js +5 -0
- package/dist/shadcn/alert/index.js +5 -0
- package/dist/shadcn/alert-dialog/index.js +12 -0
- package/dist/shadcn/attachment/index.js +10 -0
- package/dist/shadcn/avatar/index.js +7 -0
- package/dist/shadcn/badge/index.js +2 -0
- package/dist/shadcn/breadcrumb/index.js +8 -0
- package/dist/shadcn/bubble/index.js +5 -0
- package/dist/shadcn/button/index.js +2 -0
- package/dist/shadcn/calendar/index.js +19 -0
- package/dist/shadcn/card/index.js +8 -0
- package/dist/shadcn/checkbox/index.js +2 -0
- package/dist/shadcn/code-block/index.js +9 -0
- package/dist/shadcn/collapsible/index.js +4 -0
- package/dist/shadcn/command/index.js +13 -0
- package/dist/shadcn/context-menu/index.js +17 -0
- package/dist/shadcn/dialog/index.js +11 -0
- package/dist/shadcn/dropdown-menu/index.js +19 -0
- package/dist/shadcn/dropdown-menu/menu-item.js +23 -0
- package/dist/shadcn/empty/index.js +7 -0
- package/dist/shadcn/field/index.js +12 -0
- package/dist/shadcn/hooks/highlighter.js +92 -0
- package/dist/shadcn/hooks/is-mobile.svelte.js +7 -0
- package/dist/shadcn/hooks/use-highlighted-code.svelte.js +65 -0
- package/dist/shadcn/hover-card/index.js +5 -0
- package/dist/shadcn/input/index.js +3 -0
- package/dist/shadcn/input-otp/index.js +5 -0
- package/dist/shadcn/kbd/index.js +3 -0
- package/dist/shadcn/label/index.js +2 -0
- package/dist/shadcn/marker/index.js +4 -0
- package/dist/shadcn/message/index.js +7 -0
- package/dist/shadcn/message-scroller/index.js +8 -0
- package/dist/shadcn/popover/index.js +9 -0
- package/dist/shadcn/progress/index.js +2 -0
- package/dist/shadcn/progress/tone.js +11 -0
- package/dist/shadcn/radio-group/index.js +3 -0
- package/dist/shadcn/scroll-area/index.js +3 -0
- package/dist/shadcn/select/index.js +12 -0
- package/dist/shadcn/separator/index.js +2 -0
- package/dist/shadcn/sheet/index.js +11 -0
- package/dist/shadcn/sidebar/constants.js +6 -0
- package/dist/shadcn/sidebar/context.svelte.js +38 -0
- package/dist/shadcn/sidebar/index.js +25 -0
- package/dist/shadcn/skeleton/index.js +2 -0
- package/dist/shadcn/slider/index.js +2 -0
- package/dist/shadcn/sonner/index.js +1 -0
- package/dist/shadcn/spinner/index.js +1 -0
- package/dist/shadcn/switch/index.js +2 -0
- package/dist/shadcn/table/index.js +9 -0
- package/dist/shadcn/tabs/index.js +5 -0
- package/dist/shadcn/textarea/index.js +2 -0
- package/dist/shadcn/toggle/index.js +3 -0
- package/dist/shadcn/toggle-group/index.js +3 -0
- package/dist/shadcn/tooltip/context.js +8 -0
- package/dist/shadcn/tooltip/index.js +6 -0
- package/dist/shadcn/trace/index.js +9 -0
- package/dist/slides/bridges.js +66 -0
- package/dist/slides/deck-controller.svelte.js +221 -0
- package/dist/slides/export/capture.js +81 -0
- package/dist/slides/export/ffmpeg.js +85 -0
- package/dist/slides/export/index.js +4 -0
- package/dist/slides/export/launch.js +8 -0
- package/dist/slides/export/pdf.js +78 -0
- package/dist/slides/export/types.js +0 -0
- package/dist/slides/index.js +7 -0
- package/dist/slides/labels.js +26 -0
- package/dist/slides/layout.js +47 -0
- package/dist/slides/model.js +9 -0
- package/dist/slides/navigation.js +89 -0
- package/dist/slides/types.js +6 -0
- package/dist/status/define-statuses.js +16 -0
- package/dist/status/index.js +4 -0
- package/dist/status/status-types.js +0 -0
- package/dist/test-setup.js +26 -0
- package/dist/thread/index.js +3 -0
- package/dist/thread/logic.js +94 -0
- package/dist/thread/types.js +23 -0
- package/dist/work/board-order.js +109 -0
- package/dist/work/dates.js +19 -0
- package/dist/work/detail/detail-types.js +20 -0
- package/dist/work/docs/edited.js +39 -0
- package/dist/work/docs/index.js +7 -0
- package/dist/work/docs/labels.js +38 -0
- package/dist/work/docs/menu.js +121 -0
- package/dist/work/docs/outline.js +39 -0
- package/dist/work/gantt/logic.js +260 -0
- package/dist/work/inbox/inbox-logic.js +94 -0
- package/dist/work/inbox/inbox-statuses.js +86 -0
- package/dist/work/inbox/inbox-types.js +0 -0
- package/dist/work/inbox/index.js +1 -0
- package/dist/work/index.js +21 -0
- package/dist/work/kanban-drag.js +25 -0
- package/dist/work/kanban-types.js +0 -0
- package/dist/work/presets/sales.js +35 -0
- package/dist/work/reorder.js +10 -0
- package/dist/work/task-types.js +0 -0
- package/dist/work/time/duration.js +60 -0
- package/dist/work/time/time-types.js +25 -0
- package/dist/work/use-kanban-dnd.svelte.js +128 -0
- package/package.json +102 -76
- package/src/agents/vendor/draw.ts +4 -4
- package/src/canvas/headless/canvas-cleanup.test.ts +1 -1
- package/src/canvas/ops/ops.ts +1 -1
- package/src/charts/area-chart.svelte +11 -1
- package/src/charts/bar-chart.svelte +18 -3
- package/src/charts/line-chart.svelte +11 -1
- package/src/components/data-table/data-table.ts +4 -5
- package/src/components/data-table/pagination.svelte +5 -3
- package/src/components/docs/on-this-page.svelte +82 -5
- package/src/components/docs/scroll-spy.svelte.ts +6 -1
- package/src/components/list-page/detail-header.svelte +7 -3
- package/src/components/list-page/empty-state.svelte +3 -1
- package/src/components/list-page/filter-popover.svelte +2 -2
- package/src/components/list-page/rail-row.svelte +5 -2
- package/src/components/mark/mark.svelte +2 -1
- package/src/components/section-card/section-card.svelte +3 -1
- package/src/components/section-header/section-header.svelte +5 -5
- package/src/components/segmented/segment.svelte +1 -1
- package/src/components/table-view/table-view.svelte +6 -1
- package/src/components/tags-input/tags-input.svelte +1 -1
- package/src/components/toolbar/toolbar-trigger.ts +8 -2
- package/src/components/toolbar/toolbar.svelte +1 -1
- package/src/editor/anchors.ts +28 -0
- package/src/editor/doc-blocks.ts +168 -0
- package/src/editor/doc-page.css +389 -0
- package/src/editor/editor.svelte +47 -5
- package/src/editor/extensions.ts +26 -2
- package/src/editor/markdown.ts +27 -2
- package/src/editor/slash-items.ts +18 -0
- package/src/icons/trades.ts +1 -1
- package/src/inbox/README.md +6 -4
- package/src/inbox/inbox.test.ts +1 -1
- package/src/inbox/index.ts +2 -2
- package/src/inbox/logic.ts +29 -5
- package/src/inbox/thread-inbox.svelte +219 -92
- package/src/inbox/types.ts +27 -1
- package/src/lib/initials.test.ts +25 -0
- package/src/lib/initials.ts +29 -0
- package/src/modules.test.ts +4 -64
- package/src/panel/README.md +1 -1
- package/src/record/README.md +1 -1
- package/src/record/demo-data.ts +4 -4
- package/src/record/info-list.svelte +5 -4
- package/src/record/next-up.svelte +1 -1
- package/src/record/project-list.svelte +1 -1
- package/src/record/record-demo.svelte +2 -2
- package/src/record/steps-rail.svelte +3 -3
- package/src/shadcn/badge/badge.svelte +1 -1
- package/src/shadcn/card/card-title.svelte +1 -5
- package/src/shadcn/empty/empty-description.svelte +1 -1
- package/src/shadcn/progress/progress.svelte +8 -1
- package/src/shadcn/table/table-cell.svelte +10 -2
- package/src/status/README.md +1 -1
- package/src/thread/README.md +2 -0
- package/src/thread/index.ts +9 -1
- package/src/thread/logic.ts +33 -3
- package/src/thread/thread-body.svelte +37 -0
- package/src/thread/thread-events.svelte +30 -0
- package/src/thread/thread.svelte +74 -59
- package/src/thread/types.ts +21 -0
- package/src/{tasks → work}/README.md +11 -8
- package/src/{tasks → work}/detail/task-thread.svelte +8 -15
- package/src/work/docs/doc-editor-page.svelte +194 -0
- package/src/work/docs/doc-menu.svelte +333 -0
- package/src/work/docs/docs-demo.svelte +227 -0
- package/src/work/docs/edited-chip.svelte +125 -0
- package/src/work/docs/edited.ts +54 -0
- package/src/work/docs/index.ts +38 -0
- package/src/work/docs/labels.ts +70 -0
- package/src/work/docs/menu.ts +127 -0
- package/src/work/docs/outline.ts +60 -0
- package/src/{tasks → work}/gantt/gantt-group-row.svelte +1 -1
- package/src/{tasks → work}/inbox/inbox-card.svelte +113 -50
- package/src/work/inbox/inbox-logic.ts +98 -0
- package/src/work/inbox/inbox-trace.svelte +58 -0
- package/src/{tasks → work}/inbox/inbox-types.ts +2 -0
- package/src/{tasks → work}/index.ts +0 -10
- package/src/{tasks → work}/kanban-board.svelte +1 -1
- package/src/{tasks → work}/task-list.svelte +1 -1
- package/src/{tasks → work}/time/time-tracker.svelte +2 -5
- package/src/tasks/inbox/inbox-logic.ts +0 -21
- package/src/tasks/inbox/inbox-trace.svelte +0 -51
- /package/src/{tasks → work}/ambient.d.ts +0 -0
- /package/src/{tasks → work}/board-order.ts +0 -0
- /package/src/{tasks → work}/dates.ts +0 -0
- /package/src/{tasks → work}/demo.svelte +0 -0
- /package/src/{tasks → work}/detail/detail-demo.svelte +0 -0
- /package/src/{tasks → work}/detail/detail-types.ts +0 -0
- /package/src/{tasks → work}/detail/task-chip.svelte +0 -0
- /package/src/{tasks → work}/detail/task-detail.svelte +0 -0
- /package/src/{tasks → work}/detail/task-property.svelte +0 -0
- /package/src/{tasks → work}/gantt/gantt-bar.svelte +0 -0
- /package/src/{tasks → work}/gantt/gantt-grid.svelte +0 -0
- /package/src/{tasks → work}/gantt/gantt-header.svelte +0 -0
- /package/src/{tasks → work}/gantt/gantt-task-row.svelte +0 -0
- /package/src/{tasks → work}/gantt/gantt.css +0 -0
- /package/src/{tasks → work}/gantt/gantt.test.ts +0 -0
- /package/src/{tasks → work}/gantt/logic.test.ts +0 -0
- /package/src/{tasks → work}/gantt/logic.ts +0 -0
- /package/src/{tasks → work}/inbox/inbox-draft.svelte +0 -0
- /package/src/{tasks → work}/inbox/inbox-statuses.ts +0 -0
- /package/src/{tasks → work}/inbox/index.ts +0 -0
- /package/src/{tasks → work}/kanban-column.svelte +0 -0
- /package/src/{tasks → work}/kanban-drag.ts +0 -0
- /package/src/{tasks → work}/kanban-types.ts +0 -0
- /package/src/{tasks → work}/presets/sales.ts +0 -0
- /package/src/{tasks → work}/reorder.ts +0 -0
- /package/src/{tasks → work}/task-gantt.svelte +0 -0
- /package/src/{tasks → work}/task-types.ts +0 -0
- /package/src/{tasks → work}/time/duration.ts +0 -0
- /package/src/{tasks → work}/time/time-chip.svelte +0 -0
- /package/src/{tasks → work}/time/time-dot.svelte +0 -0
- /package/src/{tasks → work}/time/time-ring.svelte +0 -0
- /package/src/{tasks → work}/time/time-types.ts +0 -0
- /package/src/{tasks → work}/use-kanban-dnd.svelte.ts +0 -0
|
@@ -0,0 +1,389 @@
|
|
|
1
|
+
/* A document's type, scoped to `.doc-surface` so other editors keep theirs: 15/24 body,
|
|
2
|
+
19 and 17 for the two heading steps. */
|
|
3
|
+
|
|
4
|
+
.doc-surface .tiptap {
|
|
5
|
+
font-family: var(--font-sans);
|
|
6
|
+
font-size: 0.9375rem;
|
|
7
|
+
line-height: 1.6;
|
|
8
|
+
font-weight: 450;
|
|
9
|
+
letter-spacing: -0.003em;
|
|
10
|
+
color: var(--color-foreground);
|
|
11
|
+
caret-color: var(--color-brand);
|
|
12
|
+
-webkit-font-smoothing: antialiased;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/* The page is the writing surface, so it takes no ring of its own; the caret is the focus. */
|
|
16
|
+
.doc-surface .tiptap:focus-visible {
|
|
17
|
+
outline: none;
|
|
18
|
+
box-shadow: none;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.doc-surface .tiptap :is(h1, h2, h3, h4) {
|
|
22
|
+
font-family: var(--font-heading);
|
|
23
|
+
font-weight: 600;
|
|
24
|
+
letter-spacing: -0.012em;
|
|
25
|
+
color: var(--color-foreground);
|
|
26
|
+
scroll-margin-top: 1.5rem;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.doc-surface .tiptap h1 {
|
|
30
|
+
font-size: 1.375rem;
|
|
31
|
+
line-height: calc(28 / 22);
|
|
32
|
+
margin: 2.25rem 0 0.5rem;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.doc-surface .tiptap h2 {
|
|
36
|
+
font-size: 1.1875rem;
|
|
37
|
+
line-height: calc(26 / 19);
|
|
38
|
+
margin: 2rem 0 0.375rem;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.doc-surface .tiptap h3 {
|
|
42
|
+
font-size: 1.0625rem;
|
|
43
|
+
line-height: calc(24 / 17);
|
|
44
|
+
margin: 1.5rem 0 0.25rem;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.doc-surface .tiptap h4 {
|
|
48
|
+
font-size: 0.9375rem;
|
|
49
|
+
line-height: 1.6;
|
|
50
|
+
margin: 1.25rem 0 0.25rem;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.doc-surface .tiptap > :first-child {
|
|
54
|
+
margin-top: 0;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.doc-surface .tiptap p {
|
|
58
|
+
margin: 0 0 0.5rem;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.doc-surface .tiptap :is(ul, ol) {
|
|
62
|
+
margin: 0 0 0.5rem;
|
|
63
|
+
padding-left: 1.5rem;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.doc-surface .tiptap li {
|
|
67
|
+
margin: 0;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.doc-surface .tiptap li > p {
|
|
71
|
+
margin: 0;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.doc-surface .tiptap li::marker {
|
|
75
|
+
color: var(--color-muted-foreground);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.doc-surface .tiptap a {
|
|
79
|
+
color: var(--color-foreground);
|
|
80
|
+
text-decoration: underline;
|
|
81
|
+
text-decoration-color: color-mix(in oklab, var(--color-foreground) 35%, transparent);
|
|
82
|
+
text-underline-offset: 3px;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.doc-surface .tiptap :not(pre) > code {
|
|
86
|
+
font-family: var(--font-mono);
|
|
87
|
+
font-size: 0.85em;
|
|
88
|
+
padding: 0.1em 0.35em;
|
|
89
|
+
border-radius: var(--radius-xs);
|
|
90
|
+
background: color-mix(in oklab, var(--color-foreground) 7%, transparent);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
.doc-surface .tiptap blockquote {
|
|
94
|
+
margin: 0.75rem 0;
|
|
95
|
+
padding-left: 1rem;
|
|
96
|
+
font-style: normal;
|
|
97
|
+
color: var(--color-foreground);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
.doc-surface .tiptap blockquote::before {
|
|
101
|
+
top: 0;
|
|
102
|
+
bottom: 0;
|
|
103
|
+
width: 2px;
|
|
104
|
+
background: color-mix(in oklab, var(--color-foreground) 22%, transparent);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.doc-surface .tiptap hr {
|
|
108
|
+
border: 0;
|
|
109
|
+
border-top: 1px solid var(--color-border);
|
|
110
|
+
margin: 1.5rem 0;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/* ---- Checklist ---- */
|
|
114
|
+
.doc-surface .tiptap ul[data-type="taskList"] {
|
|
115
|
+
list-style: none;
|
|
116
|
+
padding-left: 0;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
.doc-surface .tiptap ul[data-type="taskList"] ul[data-type="taskList"] {
|
|
120
|
+
padding-left: 1.625rem;
|
|
121
|
+
margin-bottom: 0;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
.doc-surface .tiptap ul[data-type="taskList"] > li {
|
|
125
|
+
display: flex;
|
|
126
|
+
align-items: flex-start;
|
|
127
|
+
gap: 0.625rem;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
.doc-surface .tiptap ul[data-type="taskList"] > li > label {
|
|
131
|
+
position: relative;
|
|
132
|
+
display: flex;
|
|
133
|
+
height: 1.5rem;
|
|
134
|
+
align-items: center;
|
|
135
|
+
user-select: none;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
.doc-surface .tiptap ul[data-type="taskList"] > li > div {
|
|
139
|
+
min-width: 0;
|
|
140
|
+
flex: 1;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
.doc-surface .tiptap ul[data-type="taskList"] > li input[type="checkbox"] {
|
|
144
|
+
appearance: none;
|
|
145
|
+
margin: 0;
|
|
146
|
+
width: 1rem;
|
|
147
|
+
height: 1rem;
|
|
148
|
+
flex-shrink: 0;
|
|
149
|
+
cursor: pointer;
|
|
150
|
+
border-radius: var(--radius-xs);
|
|
151
|
+
border: 1.5px solid color-mix(in oklab, var(--color-foreground) 32%, transparent);
|
|
152
|
+
background-position: center;
|
|
153
|
+
background-repeat: no-repeat;
|
|
154
|
+
background-size: 0.75rem;
|
|
155
|
+
transition:
|
|
156
|
+
background-color var(--duration-fast) var(--ease-smooth-out),
|
|
157
|
+
border-color var(--duration-fast) var(--ease-smooth-out);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
.doc-surface .tiptap ul[data-type="taskList"] > li input[type="checkbox"]:checked {
|
|
161
|
+
border-color: var(--color-brand);
|
|
162
|
+
background-color: var(--color-brand);
|
|
163
|
+
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' fill='none' stroke='white' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M2.5 6.4 5 8.8l4.5-5'/%3E%3C/svg%3E");
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
.doc-surface .tiptap ul[data-type="taskList"] > li input[type="checkbox"]:focus-visible {
|
|
167
|
+
outline: 2px solid color-mix(in oklab, var(--color-brand) 55%, transparent);
|
|
168
|
+
outline-offset: 2px;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
.doc-surface .tiptap ul[data-type="taskList"] > li[data-checked="true"] > div {
|
|
172
|
+
color: var(--color-muted-foreground);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/* ---- Table ---- */
|
|
176
|
+
.doc-surface .tiptap .tableWrapper {
|
|
177
|
+
overflow-x: auto;
|
|
178
|
+
margin: 0.75rem 0 1rem;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
.doc-surface .tiptap table {
|
|
182
|
+
width: 100%;
|
|
183
|
+
margin: 0.75rem 0 1rem;
|
|
184
|
+
border-collapse: separate;
|
|
185
|
+
border-spacing: 0;
|
|
186
|
+
table-layout: fixed;
|
|
187
|
+
font-size: 0.875rem;
|
|
188
|
+
line-height: calc(20 / 14);
|
|
189
|
+
border: 1px solid var(--color-border);
|
|
190
|
+
border-radius: var(--radius-lg);
|
|
191
|
+
overflow: hidden;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
.doc-surface .tiptap .tableWrapper table {
|
|
195
|
+
margin: 0;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
.doc-surface .tiptap :is(th, td) {
|
|
199
|
+
position: relative;
|
|
200
|
+
padding: 0.5rem 0.75rem;
|
|
201
|
+
vertical-align: top;
|
|
202
|
+
text-align: left;
|
|
203
|
+
border-right: 1px solid var(--color-border);
|
|
204
|
+
border-bottom: 1px solid var(--color-border);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
.doc-surface .tiptap :is(th, td):last-child {
|
|
208
|
+
border-right: 0;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
.doc-surface .tiptap tr:last-child > :is(th, td) {
|
|
212
|
+
border-bottom: 0;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/* Beats the blog renderer's uppercase header row and bold first column. */
|
|
216
|
+
.doc-surface .tiptap table tr > :is(th, td) {
|
|
217
|
+
font-size: 0.875rem;
|
|
218
|
+
font-weight: 400;
|
|
219
|
+
text-transform: none;
|
|
220
|
+
letter-spacing: 0;
|
|
221
|
+
background: transparent;
|
|
222
|
+
color: var(--color-foreground);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
.doc-surface .tiptap table tr > th {
|
|
226
|
+
font-weight: 550;
|
|
227
|
+
background: color-mix(in oklab, var(--color-foreground) 3.5%, transparent);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
.doc-surface .tiptap table tr:not(:first-child) > td:first-child {
|
|
231
|
+
font-weight: 400;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
@media (hover: hover) and (pointer: fine) {
|
|
235
|
+
.doc-surface .tiptap table tr:hover > td {
|
|
236
|
+
background: transparent;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
.doc-surface .tiptap :is(th, td) > p {
|
|
241
|
+
margin: 0;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
.doc-surface .tiptap .selectedCell::after {
|
|
245
|
+
content: "";
|
|
246
|
+
position: absolute;
|
|
247
|
+
inset: 0;
|
|
248
|
+
pointer-events: none;
|
|
249
|
+
background: color-mix(in oklab, var(--color-brand) 14%, transparent);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/* ---- Code block: line numbers, language label ---- */
|
|
253
|
+
.doc-surface .tiptap pre {
|
|
254
|
+
position: relative;
|
|
255
|
+
margin: 0.75rem 0 1rem;
|
|
256
|
+
padding: 0.75rem 1rem 0.75rem 3.25rem;
|
|
257
|
+
overflow-x: auto;
|
|
258
|
+
border: 1px solid var(--color-border);
|
|
259
|
+
border-radius: var(--radius-lg);
|
|
260
|
+
background: color-mix(in oklab, var(--color-foreground) 3%, transparent);
|
|
261
|
+
font-family: var(--font-mono);
|
|
262
|
+
font-size: 0.8125rem;
|
|
263
|
+
line-height: calc(20 / 13);
|
|
264
|
+
font-weight: 400;
|
|
265
|
+
tab-size: 2;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
.doc-surface .tiptap pre::before {
|
|
269
|
+
content: attr(data-lines);
|
|
270
|
+
position: absolute;
|
|
271
|
+
top: 0.75rem;
|
|
272
|
+
left: 0;
|
|
273
|
+
width: 2.25rem;
|
|
274
|
+
white-space: pre;
|
|
275
|
+
text-align: right;
|
|
276
|
+
color: color-mix(in oklab, var(--color-muted-foreground) 70%, transparent);
|
|
277
|
+
font-variant-numeric: tabular-nums;
|
|
278
|
+
pointer-events: none;
|
|
279
|
+
user-select: none;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
.doc-surface .tiptap pre code {
|
|
283
|
+
display: block;
|
|
284
|
+
min-width: max-content;
|
|
285
|
+
font-size: inherit;
|
|
286
|
+
background: none;
|
|
287
|
+
padding: 0;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
.doc-surface .tiptap .code-language {
|
|
291
|
+
position: absolute;
|
|
292
|
+
top: 0.375rem;
|
|
293
|
+
right: 0.5rem;
|
|
294
|
+
appearance: none;
|
|
295
|
+
height: 1.375rem;
|
|
296
|
+
padding: 0 0.5rem;
|
|
297
|
+
border: 0;
|
|
298
|
+
border-radius: var(--radius-xs);
|
|
299
|
+
background: transparent;
|
|
300
|
+
color: var(--color-muted-foreground);
|
|
301
|
+
font-family: var(--font-sans);
|
|
302
|
+
font-size: 0.6875rem;
|
|
303
|
+
font-weight: 500;
|
|
304
|
+
cursor: pointer;
|
|
305
|
+
opacity: 0;
|
|
306
|
+
transition:
|
|
307
|
+
opacity var(--duration-fast) var(--ease-smooth-out),
|
|
308
|
+
background-color var(--duration-fast) var(--ease-smooth-out);
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
.doc-surface .tiptap pre:focus-within .code-language,
|
|
312
|
+
.doc-surface .tiptap .code-language:focus-visible {
|
|
313
|
+
opacity: 1;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
@media (hover: hover) and (pointer: fine) {
|
|
317
|
+
.doc-surface .tiptap pre:hover .code-language {
|
|
318
|
+
opacity: 1;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
.doc-surface .tiptap .code-language:hover {
|
|
322
|
+
background: color-mix(in oklab, var(--color-foreground) 7%, transparent);
|
|
323
|
+
color: var(--color-foreground);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
@media (hover: none) {
|
|
328
|
+
.doc-surface .tiptap .code-language {
|
|
329
|
+
opacity: 1;
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
/* ---- Heading anchor ---- */
|
|
334
|
+
.doc-surface .tiptap .heading-anchor {
|
|
335
|
+
display: inline-flex;
|
|
336
|
+
align-items: center;
|
|
337
|
+
gap: 0.3125rem;
|
|
338
|
+
margin-left: 0.625rem;
|
|
339
|
+
padding: 0 0.375rem;
|
|
340
|
+
height: 1.25rem;
|
|
341
|
+
border: 0;
|
|
342
|
+
border-radius: var(--radius-xs);
|
|
343
|
+
background: transparent;
|
|
344
|
+
color: var(--color-muted-foreground);
|
|
345
|
+
font-family: var(--font-sans);
|
|
346
|
+
font-size: 0.75rem;
|
|
347
|
+
line-height: 1;
|
|
348
|
+
font-weight: 450;
|
|
349
|
+
letter-spacing: 0;
|
|
350
|
+
vertical-align: 0.1em;
|
|
351
|
+
cursor: pointer;
|
|
352
|
+
opacity: 0;
|
|
353
|
+
user-select: none;
|
|
354
|
+
transition:
|
|
355
|
+
opacity var(--duration-fast) var(--ease-smooth-out),
|
|
356
|
+
color var(--duration-fast) var(--ease-smooth-out);
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
.doc-surface .tiptap .heading-anchor[data-copied="true"] {
|
|
360
|
+
color: var(--color-brand);
|
|
361
|
+
opacity: 1;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
.doc-surface .tiptap .heading-anchor:focus-visible {
|
|
365
|
+
opacity: 1;
|
|
366
|
+
outline: 2px solid color-mix(in oklab, var(--color-brand) 55%, transparent);
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
@media (hover: hover) and (pointer: fine) {
|
|
370
|
+
.doc-surface .tiptap .has-anchor:hover .heading-anchor {
|
|
371
|
+
opacity: 1;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
.doc-surface .tiptap .heading-anchor:hover {
|
|
375
|
+
color: var(--color-foreground);
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
@media (hover: none) {
|
|
380
|
+
.doc-surface .tiptap .heading-anchor {
|
|
381
|
+
display: none;
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
@media (prefers-reduced-motion: reduce) {
|
|
386
|
+
.doc-surface .tiptap :is(.heading-anchor, .code-language, input[type="checkbox"]) {
|
|
387
|
+
transition: none;
|
|
388
|
+
}
|
|
389
|
+
}
|
package/src/editor/editor.svelte
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
import { Editor } from "@tiptap/core";
|
|
6
6
|
import { untrack } from "svelte";
|
|
7
7
|
import "./content.css";
|
|
8
|
+
import "./doc-page.css";
|
|
8
9
|
import { buildExtensions } from "./extensions.js";
|
|
9
10
|
import { buildSlashItems, type SlashItem } from "./slash-items.js";
|
|
10
11
|
import { parseYoutubeUrl } from "./youtube-url.js";
|
|
@@ -22,6 +23,17 @@
|
|
|
22
23
|
minHeight?: string;
|
|
23
24
|
preset?: "full" | "notes";
|
|
24
25
|
blockIds?: boolean;
|
|
26
|
+
/**
|
|
27
|
+
* `box` is the framed editor with a toolbar. `page` is a document: no frame, no toolbar,
|
|
28
|
+
* type set by `.doc-surface` (see doc-page.css), heading anchors on.
|
|
29
|
+
*/
|
|
30
|
+
variant?: "box" | "page";
|
|
31
|
+
/** The word on a heading's hover button, for `page`. */
|
|
32
|
+
copyLinkLabel?: string;
|
|
33
|
+
/** A heading's link was copied. */
|
|
34
|
+
oncopylink?: (url: string, id: string) => void;
|
|
35
|
+
/** The live editor, for a host that needs focus or the document. */
|
|
36
|
+
instance?: Editor | null;
|
|
25
37
|
}
|
|
26
38
|
|
|
27
39
|
// =========================
|
|
@@ -34,6 +46,10 @@
|
|
|
34
46
|
minHeight = "28rem",
|
|
35
47
|
preset = "full",
|
|
36
48
|
blockIds = false,
|
|
49
|
+
variant = "box",
|
|
50
|
+
copyLinkLabel = "Copy link",
|
|
51
|
+
oncopylink,
|
|
52
|
+
instance = $bindable(null),
|
|
37
53
|
}: Props = $props();
|
|
38
54
|
|
|
39
55
|
// =========================
|
|
@@ -59,6 +75,11 @@
|
|
|
59
75
|
// DERIVED
|
|
60
76
|
// =========================
|
|
61
77
|
let editor: Editor | null = $derived(tick >= 0 ? editorInstance : null);
|
|
78
|
+
let isPage = $derived(variant === "page");
|
|
79
|
+
|
|
80
|
+
$effect(() => {
|
|
81
|
+
instance = editorInstance;
|
|
82
|
+
});
|
|
62
83
|
|
|
63
84
|
let slashItems = $derived.by((): SlashItem[] =>
|
|
64
85
|
editor
|
|
@@ -204,7 +225,12 @@
|
|
|
204
225
|
function mount() {
|
|
205
226
|
if (!editorElement || editorInstance) return;
|
|
206
227
|
|
|
207
|
-
const extensions = buildExtensions({
|
|
228
|
+
const extensions = buildExtensions({
|
|
229
|
+
preset,
|
|
230
|
+
placeholder,
|
|
231
|
+
blockIds,
|
|
232
|
+
anchors: variant === "page" ? { label: copyLinkLabel, oncopy: oncopylink } : false,
|
|
233
|
+
});
|
|
208
234
|
|
|
209
235
|
editorInstance = new Editor({
|
|
210
236
|
element: editorElement,
|
|
@@ -309,10 +335,14 @@
|
|
|
309
335
|
<!-- =========================== -->
|
|
310
336
|
<div
|
|
311
337
|
class="editor-wrapper"
|
|
312
|
-
class:focused={editor?.isFocused}
|
|
338
|
+
class:focused={editor?.isFocused && !isPage}
|
|
339
|
+
class:page={isPage}
|
|
340
|
+
class:doc-surface={isPage}
|
|
313
341
|
style="--editor-min-height: {minHeight};"
|
|
314
342
|
>
|
|
315
|
-
|
|
343
|
+
{#if !isPage}
|
|
344
|
+
<EditorToolbar {editor} {tick} {preset} onInsertYoutube={insertYoutubeVideo} />
|
|
345
|
+
{/if}
|
|
316
346
|
|
|
317
347
|
<!-- Editor surface -->
|
|
318
348
|
<div bind:this={editorElement} class="editor-surface tiptap-content"></div>
|
|
@@ -334,7 +364,7 @@
|
|
|
334
364
|
{/if}
|
|
335
365
|
|
|
336
366
|
<!-- Status bar -->
|
|
337
|
-
{#if editor}
|
|
367
|
+
{#if editor && !isPage}
|
|
338
368
|
<div class="status-bar">
|
|
339
369
|
<span class="status-hint">Type <kbd>/</kbd> for commands</span>
|
|
340
370
|
</div>
|
|
@@ -361,12 +391,24 @@
|
|
|
361
391
|
box-shadow: 0 0 0 3px oklch(from var(--color-brand) l c h / 0.06);
|
|
362
392
|
}
|
|
363
393
|
|
|
394
|
+
/* A document page owns its frame, so the editor draws none. */
|
|
395
|
+
.editor-wrapper.page {
|
|
396
|
+
border: 0;
|
|
397
|
+
border-radius: 0;
|
|
398
|
+
background: transparent;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
.editor-wrapper.page .editor-surface :global(.tiptap) {
|
|
402
|
+
outline: none;
|
|
403
|
+
min-height: var(--editor-min-height, 28rem);
|
|
404
|
+
}
|
|
405
|
+
|
|
364
406
|
/* ---- EDITOR SURFACE ---- */
|
|
365
407
|
.editor-surface {
|
|
366
408
|
min-height: var(--editor-min-height, 28rem);
|
|
367
409
|
}
|
|
368
410
|
|
|
369
|
-
.editor-surface :global(.tiptap) {
|
|
411
|
+
.editor-wrapper:not(.page) .editor-surface :global(.tiptap) {
|
|
370
412
|
padding: 2rem 2.5rem;
|
|
371
413
|
outline: none;
|
|
372
414
|
min-height: var(--editor-min-height, 28rem);
|
package/src/editor/extensions.ts
CHANGED
|
@@ -3,7 +3,10 @@ import { StarterKit } from "@tiptap/starter-kit";
|
|
|
3
3
|
import { Image } from "@tiptap/extension-image";
|
|
4
4
|
import { Placeholder } from "@tiptap/extension-placeholder";
|
|
5
5
|
import { DragHandle } from "@tiptap/extension-drag-handle";
|
|
6
|
+
import { TaskItem, TaskList } from "@tiptap/extension-list";
|
|
7
|
+
import { Table, TableCell, TableHeader, TableRow } from "@tiptap/extension-table";
|
|
6
8
|
import { BlockIdExtension } from "./block-id.js";
|
|
9
|
+
import { CodeBlockChrome, HeadingAnchors } from "./doc-blocks.js";
|
|
7
10
|
|
|
8
11
|
const CmsBlock = TiptapNode.create({
|
|
9
12
|
name: "cmsBlock",
|
|
@@ -127,17 +130,38 @@ export type ExtensionOptions = {
|
|
|
127
130
|
preset: "full" | "notes";
|
|
128
131
|
placeholder: string;
|
|
129
132
|
blockIds: boolean;
|
|
133
|
+
/** A document page: heading anchors with a hover "Copy link", and the label for it. */
|
|
134
|
+
anchors?: { label: string; oncopy?: (url: string, id: string) => void } | false;
|
|
130
135
|
};
|
|
131
136
|
|
|
132
137
|
/** The extension list for a preset: `full` adds CMS blocks, YouTube, images and H4. */
|
|
133
|
-
export function buildExtensions({
|
|
138
|
+
export function buildExtensions({
|
|
139
|
+
preset,
|
|
140
|
+
placeholder,
|
|
141
|
+
blockIds,
|
|
142
|
+
anchors = false,
|
|
143
|
+
}: ExtensionOptions): Extensions {
|
|
134
144
|
const full = preset === "full";
|
|
135
145
|
return dedupeExtensions([
|
|
136
146
|
StarterKit.configure({
|
|
137
147
|
heading: { levels: full ? [1, 2, 3, 4] : [1, 2, 3] },
|
|
138
148
|
link: { openOnClick: false },
|
|
139
149
|
}),
|
|
140
|
-
...(full
|
|
150
|
+
...(full
|
|
151
|
+
? [
|
|
152
|
+
CmsBlock,
|
|
153
|
+
Youtube,
|
|
154
|
+
Image.configure({ inline: false }),
|
|
155
|
+
TaskList,
|
|
156
|
+
TaskItem.configure({ nested: true }),
|
|
157
|
+
Table.configure({ resizable: false }),
|
|
158
|
+
TableRow,
|
|
159
|
+
TableHeader,
|
|
160
|
+
TableCell,
|
|
161
|
+
CodeBlockChrome,
|
|
162
|
+
]
|
|
163
|
+
: []),
|
|
164
|
+
...(anchors ? [HeadingAnchors.configure(anchors)] : []),
|
|
141
165
|
Placeholder.configure({ placeholder }),
|
|
142
166
|
dragHandle(),
|
|
143
167
|
...(blockIds ? [BlockIdExtension] : []),
|
package/src/editor/markdown.ts
CHANGED
|
@@ -392,6 +392,28 @@ function youtubeToMd(node: TiptapNode): string {
|
|
|
392
392
|
|
|
393
393
|
const dropped: MdWriter = () => "";
|
|
394
394
|
|
|
395
|
+
function taskBullet(item: TiptapNode): string {
|
|
396
|
+
return item.attrs?.checked === true ? "- [x]" : "- [ ]";
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
// GFM pipe table. The first row is the header; a cell holds its paragraphs on one line.
|
|
400
|
+
function tableToMd(node: TiptapNode): string {
|
|
401
|
+
const rows = (node.content ?? []).map((row) =>
|
|
402
|
+
(row.content ?? []).map((cell) =>
|
|
403
|
+
(cell.content ?? [])
|
|
404
|
+
.map((block) => inlineToMd(block.content ?? []))
|
|
405
|
+
.join(" ")
|
|
406
|
+
.replace(/\|/g, "\\|"),
|
|
407
|
+
),
|
|
408
|
+
);
|
|
409
|
+
if (rows.length === 0) return "";
|
|
410
|
+
const width = Math.max(...rows.map((row) => row.length));
|
|
411
|
+
const line = (cells: string[]) =>
|
|
412
|
+
`| ${Array.from({ length: width }, (_, i) => cells[i] ?? "").join(" | ")} |`;
|
|
413
|
+
const rule = `| ${Array.from({ length: width }, () => "---").join(" | ")} |`;
|
|
414
|
+
return [line(rows[0]), rule, ...rows.slice(1).map(line)].join("\n");
|
|
415
|
+
}
|
|
416
|
+
|
|
395
417
|
const MD_WRITERS: Record<string, MdWriter> = {
|
|
396
418
|
paragraph: (node) => inlineToMd(node.content ?? []),
|
|
397
419
|
heading: headingToMd,
|
|
@@ -405,10 +427,13 @@ const MD_WRITERS: Record<string, MdWriter> = {
|
|
|
405
427
|
horizontalRule: () => "---",
|
|
406
428
|
hardBreak: () => " \n",
|
|
407
429
|
youtube: youtubeToMd,
|
|
408
|
-
|
|
430
|
+
taskList: (node, listDepth) =>
|
|
431
|
+
(node.content ?? []).map((item) => listItemToMd(item, taskBullet(item), listDepth)).join("\n"),
|
|
432
|
+
taskItem: (node, listDepth) => listItemContentsToMd(node, listDepth),
|
|
433
|
+
table: tableToMd,
|
|
434
|
+
// WHY: images and cmsBlock are out of scope for the notes bridge.
|
|
409
435
|
image: dropped,
|
|
410
436
|
cmsBlock: dropped,
|
|
411
|
-
table: dropped,
|
|
412
437
|
tableRow: dropped,
|
|
413
438
|
tableCell: dropped,
|
|
414
439
|
tableHeader: dropped,
|
|
@@ -12,6 +12,8 @@ import {
|
|
|
12
12
|
ImageSquare,
|
|
13
13
|
Paragraph,
|
|
14
14
|
VideoCamera,
|
|
15
|
+
ListChecks,
|
|
16
|
+
Table,
|
|
15
17
|
} from "phosphor-svelte";
|
|
16
18
|
|
|
17
19
|
export type SlashItem = {
|
|
@@ -62,6 +64,22 @@ export function buildSlashItems(editor: Editor, query: string, options: SlashOpt
|
|
|
62
64
|
icon: ListNumbers,
|
|
63
65
|
command: () => run().toggleOrderedList().run(),
|
|
64
66
|
},
|
|
67
|
+
...(full
|
|
68
|
+
? [
|
|
69
|
+
{
|
|
70
|
+
label: "Checklist",
|
|
71
|
+
description: "Tasks with checkboxes",
|
|
72
|
+
icon: ListChecks,
|
|
73
|
+
command: () => run().toggleTaskList().run(),
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
label: "Table",
|
|
77
|
+
description: "Rows and columns",
|
|
78
|
+
icon: Table,
|
|
79
|
+
command: () => run().insertTable({ rows: 3, cols: 3, withHeaderRow: true }).run(),
|
|
80
|
+
},
|
|
81
|
+
]
|
|
82
|
+
: []),
|
|
65
83
|
{
|
|
66
84
|
label: "Quote",
|
|
67
85
|
description: "Blockquote",
|
package/src/icons/trades.ts
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
17
|
/*
|
|
18
|
-
* car-garage, hammer / wave-saw-tool, helmet, trowel, grid-dots, leaf, car, crane. Svelte 5 port is ` @tabler/icons-svelte-runes` (runes, not
|
|
18
|
+
* car-garage, hammer / wave-saw-tool, helmet, trowel, grid-dots, leaf, car, crane. Svelte 5 port is ` @tabler/icons-svelte-runes` (runes, not the Svelte 4 ` @tabler/icons-svelte`).
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
21
|
import {
|
package/src/inbox/README.md
CHANGED
|
@@ -21,7 +21,9 @@ One threaded inbox. Entries from any source (a comment, a status change, an assi
|
|
|
21
21
|
- **Grouping.** `threadsOf(entries, { unreadFirst })` keys on `subject.type` plus `subject.id`, sorts threads by their newest entry and entries oldest first. An entry with no subject id is dropped. A malformed timestamp sorts last. Each thread carries `unread`, `latestAt` and `pending`.
|
|
22
22
|
- **Needs you.** A `proposal` entry whose `proposal` (an `InboxItem`) is still open pins to the top of its thread, drawn with `InboxCard`. The "Needs you" filter keeps threads that hold one. Verdicts come out of `onDecide`.
|
|
23
23
|
- **Filters.** By subject type, by actor name and by Needs you. `filterThreads` runs them without the component.
|
|
24
|
-
- **Keys.** `j` and `k` move, `u` marks the thread read (or unread when nothing is unread), `h` opens the snooze row (`1`, `2`, `3` pick a time), and `a`, `d`, `s`, `e` act on the pinned proposal. A key does nothing while focus is in an input, a textarea, a select or an editable element, or while
|
|
25
|
-
- **
|
|
26
|
-
- **
|
|
27
|
-
- **
|
|
24
|
+
- **Keys.** `j` and `k` move, `u` marks the thread read (or unread when nothing is unread) and Alt+U marks everything read, `h` opens the snooze row (`1`, `2`, `3` pick a time) or brings a snoozed thread back, Shift+S unfollows, Backspace clears the thread and Shift+Backspace clears every read one, and `a`, `d`, `s`, `e` act on the pinned proposal. These are Linear's keys. A key does nothing while focus is in an input, a textarea, a select or an editable element, or while Cmd or Ctrl is held. `inboxKeyOf(event)` is the same check.
|
|
25
|
+
- **Clear.** `onClear(thread)` takes a thread out of the inbox and opens the next one. `onClearRead(threads)` gets every thread with nothing unread. A thread holding a pending proposal is never cleared. The host decides what cleared means (Linear archives, so it can be undone) and stops passing the entries. The buttons and the hint show only when the callback is passed.
|
|
26
|
+
- **Snooze.** `onSnooze({ thread, until })` gets a `Date`: 3 hours on, tomorrow 9:00 or next Monday 9:00 (`snoozeChoices(now)`). The host decides what snoozed means and stops passing the entries. With `onShowSnoozed` the filter offers "Show snoozed": the host sets `showSnoozed`, passes the snoozed entries with `subject.snoozedUntil`, and `onUnsnooze(thread)` brings one back.
|
|
27
|
+
- **Read.** `onRead(thread, read)` is true when the thread had unread entries, so the host marks them all read. `onReadAll()` marks every thread read.
|
|
28
|
+
- **Unfollow.** `onUnfollow(thread)` shows on a thread whose `subject.followed` is set. The host stops new notifications for it.
|
|
29
|
+
- **Words.** `labels` is a partial of `InboxLabels`. Status and assignment lines have `{from}`, `{to}` and `{assignee}` slots. `typeLabels` names the subject types. The `avatar` and `status` snippets let the app draw its own portrait and status badge. Below the pinned card the thread draws through `@heyramzi/ui/thread`: comments as comments, status moves and assignments as event lines. `threadLabels` gives that thread its words, and the `attachments` snippet draws under a comment.
|
package/src/inbox/inbox.test.ts
CHANGED
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
threadsOf,
|
|
10
10
|
} from "./logic.js";
|
|
11
11
|
import type { InboxEntry, InboxSubject } from "./types.js";
|
|
12
|
-
import type { InboxItem } from "../
|
|
12
|
+
import type { InboxItem } from "../work/inbox/inbox-types.js";
|
|
13
13
|
|
|
14
14
|
const tsk7: InboxSubject = { type: "task", id: "7", ref: "TSK-7", title: "Write the pricing page" };
|
|
15
15
|
const tsk9: InboxSubject = { type: "task", id: "9", ref: "TSK-9", title: "Fix the footer" };
|
package/src/inbox/index.ts
CHANGED
|
@@ -27,5 +27,5 @@ export type {
|
|
|
27
27
|
} from "./types.js";
|
|
28
28
|
|
|
29
29
|
// The approval card a pinned proposal is drawn with, and the types its `proposal` field carries.
|
|
30
|
-
export { default as InboxCard } from "../
|
|
31
|
-
export type { InboxItem, InboxVerdict } from "../
|
|
30
|
+
export { default as InboxCard } from "../work/inbox/inbox-card.svelte";
|
|
31
|
+
export type { InboxItem, InboxVerdict } from "../work/inbox/inbox-types.js";
|