feat(notes): rich-text editor with tiptap (task 85)

Replace plain textarea with shared tiptap editor and sanitized html rendering.

Adds interactive checklists on read surfaces and mobile overflow fixes.
This commit is contained in:
ginnoir
2026-07-04 19:25:15 -05:00
parent 67f67525ff
commit a4be5d5061
23 changed files with 1942 additions and 206 deletions
+155
View File
@@ -0,0 +1,155 @@
.rich-text-content {
max-width: 100%;
overflow-wrap: anywhere;
word-break: break-word;
text-wrap: pretty;
color: var(--ink-2);
font-family: var(--serif);
font-size: 15px;
line-height: 1.65;
}
.rich-text-content > *:first-child {
margin-top: 0;
}
.rich-text-content > *:last-child {
margin-bottom: 0;
}
.rich-text-content h1,
.rich-text-content h2,
.rich-text-content h3,
.rich-text-content h4 {
color: var(--ink);
font-weight: 600;
line-height: 1.25;
margin: 1.1em 0 0.45em;
}
.rich-text-content h1 {
font-size: 1.6rem;
}
.rich-text-content h2 {
font-size: 1.35rem;
}
.rich-text-content h3 {
font-size: 1.15rem;
}
.rich-text-content p {
margin: 0.65em 0;
}
.rich-text-content ul,
.rich-text-content ol {
margin: 0.65em 0;
padding-left: 1.4rem;
}
.rich-text-content blockquote {
border-left: 3px solid var(--hair-2);
color: var(--ink-mute);
margin: 0.8em 0;
padding-left: 0.9rem;
}
.rich-text-content pre {
background: var(--shade);
border-radius: var(--r-md);
font-family: var(--mono);
font-size: 0.85em;
margin: 0.8em 0;
max-width: 100%;
overflow-x: auto;
padding: 0.75rem 0.9rem;
}
.rich-text-content code {
font-family: var(--mono);
font-size: 0.9em;
}
.rich-text-content a {
color: var(--accent);
text-decoration: underline;
overflow-wrap: anywhere;
}
.rich-text-content img {
border-radius: var(--r-md);
display: block;
height: auto;
margin: 0.8em 0;
max-width: 100%;
}
.rich-text-content table {
border-collapse: collapse;
display: block;
margin: 0.8em 0;
max-width: 100%;
overflow-x: auto;
width: max-content;
}
.rich-text-content th,
.rich-text-content td {
border: 0.5px solid var(--hair);
min-width: 4rem;
padding: 0.4rem 0.55rem;
text-align: left;
}
.rich-text-content ul[data-type="taskList"] {
list-style: none;
padding-left: 0;
}
.rich-text-content li[data-type="taskItem"] {
align-items: flex-start;
display: flex;
gap: 0.45rem;
margin: 0.25rem 0;
}
.rich-text-content li[data-type="taskItem"] > label {
flex-shrink: 0;
margin-top: 0.2rem;
}
.rich-text-content li[data-type="taskItem"] > label input[type="checkbox"] {
accent-color: var(--accent);
cursor: pointer;
height: 1rem;
width: 1rem;
}
.rich-text-content li[data-type="taskItem"] > div {
flex: 1;
min-width: 0;
}
.rich-text-editor .ProseMirror {
min-height: 18rem;
max-width: 100%;
outline: none;
overflow-wrap: anywhere;
word-break: break-word;
}
.rich-text-editor .ProseMirror p.is-editor-empty:first-child::before {
color: var(--ink-faint);
content: attr(data-placeholder);
float: left;
height: 0;
pointer-events: none;
}
.rich-text-toolbar {
display: flex;
flex-wrap: wrap;
gap: 0.25rem;
}