feat: restyle email block with Gmail-style layout and avatar

This commit is contained in:
Gagancreates 2026-05-05 00:37:57 +05:30
parent 93feee15a0
commit 9356edb84a
3 changed files with 511 additions and 277 deletions

View file

@ -1,6 +1,6 @@
import { mergeAttributes, Node } from '@tiptap/react'
import { ReactNodeViewRenderer, NodeViewWrapper } from '@tiptap/react'
import { X, Mail, ChevronDown, ExternalLink, Copy, Check, MessageSquare } from 'lucide-react'
import { X, ExternalLink, Copy, Check, MessageSquare, ChevronDown } from 'lucide-react'
import { blocks } from '@x/shared'
import { useState, useEffect, useRef, useCallback } from 'react'
import { useTheme } from '@/contexts/theme-context'
@ -11,17 +11,57 @@ function formatEmailDate(dateStr: string): string {
try {
const d = new Date(dateStr)
if (isNaN(d.getTime())) return dateStr
return d.toLocaleDateString([], { month: 'short', day: 'numeric', year: 'numeric' }) +
' ' + d.toLocaleTimeString([], { hour: 'numeric', minute: '2-digit' })
const now = new Date()
const isToday = d.getDate() === now.getDate() && d.getMonth() === now.getMonth() && d.getFullYear() === now.getFullYear()
if (isToday) return d.toLocaleTimeString([], { hour: 'numeric', minute: '2-digit' })
return d.toLocaleDateString([], { month: 'short', day: 'numeric' })
} catch {
return dateStr
}
}
/** Extract just the name part from "Name <email>" format */
function senderFirstName(from: string): string {
const name = from.replace(/<.*>/, '').trim()
return name.split(/\s+/)[0] || name
function formatFullDate(dateStr: string): string {
try {
const d = new Date(dateStr)
if (isNaN(d.getTime())) return dateStr
return d.toLocaleDateString([], { weekday: 'short', month: 'short', day: 'numeric', year: 'numeric' }) +
', ' + d.toLocaleTimeString([], { hour: 'numeric', minute: '2-digit' })
} catch {
return dateStr
}
}
/** Extract display name from "Name <email>" or plain email */
function extractName(from: string): string {
const match = from.match(/^([^<]+)</)
if (match) return match[1].trim()
return from.replace(/@.*/, '').replace(/[._+]/g, ' ').trim()
}
/** Get first initial for avatar */
function getInitial(from: string): string {
const name = extractName(from)
return (name[0] || '?').toUpperCase()
}
// Gmail-style deterministic avatar colors based on sender
const GMAIL_AVATAR_COLORS = [
'#1a73e8', // blue
'#e8453c', // red
'#34a853', // green
'#8430ce', // purple
'#f29900', // orange
'#00796b', // teal
'#c62828', // dark red
'#1565c0', // dark blue
'#6a1b9a', // deep purple
'#2e7d32', // dark green
]
function avatarColor(from: string): string {
let hash = 0
for (let i = 0; i < from.length; i++) hash = (hash * 31 + from.charCodeAt(i)) >>> 0
return GMAIL_AVATAR_COLORS[hash % GMAIL_AVATAR_COLORS.length]
}
declare global {
@ -51,13 +91,11 @@ function EmailBlockView({ node, deleteNode, updateAttributes }: {
const { resolvedTheme } = useTheme()
// Local draft state for editing
const [draftBody, setDraftBody] = useState(config?.draft_response || '')
const [emailExpanded, setEmailExpanded] = useState(false)
const [expanded, setExpanded] = useState(false)
const [copied, setCopied] = useState(false)
const bodyRef = useRef<HTMLTextAreaElement>(null)
// Sync draft from external changes
useEffect(() => {
try {
const parsed = blocks.EmailBlockSchema.parse(JSON.parse(raw))
@ -65,7 +103,6 @@ function EmailBlockView({ node, deleteNode, updateAttributes }: {
} catch { /* ignore */ }
}, [raw])
// Auto-resize textarea
useEffect(() => {
if (bodyRef.current) {
bodyRef.current.style.height = 'auto'
@ -102,7 +139,6 @@ function EmailBlockView({ node, deleteNode, updateAttributes }: {
return (
<NodeViewWrapper className="email-block-wrapper" data-type="email-block">
<div className="email-block-card email-block-error">
<Mail size={16} />
<span>Invalid email block</span>
</div>
</NodeViewWrapper>
@ -113,11 +149,13 @@ function EmailBlockView({ node, deleteNode, updateAttributes }: {
? `https://mail.google.com/mail/u/0/#all/${config.threadId}`
: null
// Build summary: use explicit summary, or auto-generate from sender + subject
const summary = config.summary
|| (config.from && config.subject
? `${senderFirstName(config.from)} reached out about ${config.subject}`
: config.subject || 'New email')
const senderName = config.from ? extractName(config.from) : 'Unknown'
const initial = config.from ? getInitial(config.from) : '?'
const color = config.from ? avatarColor(config.from) : '#5f6368'
// Snippet: use summary if present, else truncate latest_email
const snippet = config.summary
|| (config.latest_email ? config.latest_email.slice(0, 120).replace(/\s+/g, ' ').trim() : '')
return (
<NodeViewWrapper className="email-block-wrapper" data-type="email-block">
@ -126,110 +164,168 @@ function EmailBlockView({ node, deleteNode, updateAttributes }: {
<X size={14} />
</button>
{/* Header: Email badge */}
<div className="email-block-badge">
<Mail size={13} />
Email
</div>
{/* Summary */}
<div className="email-block-summary">{summary}</div>
{/* Expandable email details */}
<button
className="email-block-expand-btn"
onClick={(e) => { e.stopPropagation(); setEmailExpanded(!emailExpanded) }}
{/* Gmail-style two-column row */}
<div
className={`email-gmail-row${expanded ? ' email-gmail-row-expanded' : ''}`}
onClick={(e) => { e.stopPropagation(); setExpanded(!expanded) }}
onMouseDown={(e) => e.stopPropagation()}
>
<ChevronDown size={13} className={`email-block-toggle-chevron ${emailExpanded ? 'email-block-toggle-chevron-open' : ''}`} />
{emailExpanded ? 'Hide email' : 'Show email'}
{config.from && <span className="email-block-expand-meta">· From {senderFirstName(config.from)}</span>}
{config.date && <span className="email-block-expand-meta">· {formatEmailDate(config.date)}</span>}
</button>
{/* Avatar */}
<div
className="email-gmail-avatar"
style={{ backgroundColor: color }}
aria-hidden="true"
>
{initial}
</div>
{emailExpanded && (
<div className="email-block-email-details">
<div className="email-block-message">
<div className="email-block-message-header">
<div className="email-block-sender-info">
<div className="email-block-sender-row">
<div className="email-block-sender-name">{config.from || 'Unknown'}</div>
{config.date && <div className="email-block-sender-date">{formatEmailDate(config.date)}</div>}
</div>
{config.subject && <div className="email-block-subject-line">Subject: {config.subject}</div>}
{/* Content */}
<div className="email-gmail-content">
<div className="email-gmail-top-row">
<span className="email-gmail-sender">{senderName}</span>
{config.date && (
<span className="email-gmail-date">{formatEmailDate(config.date)}</span>
)}
</div>
<div className="email-gmail-bottom-row">
{config.subject && (
<span className="email-gmail-subject">{config.subject}</span>
)}
{snippet && (
<span className="email-gmail-snippet">
{config.subject ? `${snippet}` : snippet}
</span>
)}
</div>
</div>
{/* Chevron */}
<ChevronDown
size={15}
className={`email-gmail-chevron${expanded ? ' email-gmail-chevron-open' : ''}`}
/>
</div>
{/* Expanded email detail */}
{expanded && (
<div className="email-gmail-expanded">
{/* Subject heading */}
{config.subject && (
<div className="email-gmail-exp-subject">{config.subject}</div>
)}
{/* Metadata strip */}
<div className="email-gmail-exp-meta">
<div
className="email-gmail-exp-avatar"
style={{ backgroundColor: color }}
>
{initial}
</div>
<div className="email-gmail-exp-meta-right">
<div className="email-gmail-exp-sender">{config.from || 'Unknown'}</div>
<div className="email-gmail-exp-to-date">
{config.to && <span>to {config.to}</span>}
{config.date && <span className="email-gmail-exp-fulldate">{formatFullDate(config.date)}</span>}
</div>
</div>
<div className="email-block-message-body">{config.latest_email}</div>
{gmailUrl && (
<button
className="email-gmail-open-btn"
onClick={(e) => { e.stopPropagation(); window.open(gmailUrl, '_blank') }}
onMouseDown={(e) => e.stopPropagation()}
title="Open in Gmail"
>
<ExternalLink size={14} />
</button>
)}
</div>
{/* Email body */}
<div className="email-gmail-exp-body">{config.latest_email}</div>
{/* Earlier conversation */}
{hasPastSummary && (
<div className="email-block-context-section">
<div className="email-block-context-label">Earlier conversation</div>
<div className="email-block-context-summary">{config.past_summary}</div>
<div className="email-gmail-exp-history">
<div className="email-gmail-exp-history-label">Earlier conversation</div>
<div className="email-gmail-exp-history-body">{config.past_summary}</div>
</div>
)}
{/* Draft compose area */}
{hasDraft && (
<div className="email-gmail-compose">
<div className="email-gmail-compose-to">
<span className="email-gmail-compose-to-label">Reply</span>
{config.from && (
<span className="email-gmail-compose-to-addr">{config.from}</span>
)}
</div>
<textarea
key={resolvedTheme}
ref={bodyRef}
className="email-gmail-compose-body"
value={draftBody}
onChange={(e) => setDraftBody(e.target.value)}
onBlur={() => commitDraft(draftBody)}
onMouseDown={(e) => e.stopPropagation()}
onClick={(e) => e.stopPropagation()}
placeholder="Write your reply..."
rows={3}
/>
<div className="email-gmail-compose-footer">
<button
className="email-gmail-btn email-gmail-btn-primary"
onMouseDown={(e) => e.stopPropagation()}
onClick={(e) => { e.stopPropagation(); draftWithAssistant() }}
>
<MessageSquare size={13} />
{hasDraft ? 'Refine with Rowboat' : 'Draft with Rowboat'}
</button>
{hasDraft && (
<button
className="email-gmail-btn"
onMouseDown={(e) => e.stopPropagation()}
onClick={(e) => {
e.stopPropagation()
navigator.clipboard.writeText(draftBody).then(() => {
setCopied(true)
setTimeout(() => setCopied(false), 2000)
}).catch(() => {
const textarea = document.createElement('textarea')
textarea.value = draftBody
document.body.appendChild(textarea)
textarea.select()
document.execCommand('copy')
document.body.removeChild(textarea)
setCopied(true)
setTimeout(() => setCopied(false), 2000)
})
}}
>
{copied ? <Check size={13} /> : <Copy size={13} />}
{copied ? 'Copied!' : 'Copy draft'}
</button>
)}
</div>
</div>
)}
{/* Actions when no draft yet */}
{!hasDraft && (
<div className="email-gmail-actions">
<button
className="email-gmail-btn email-gmail-btn-primary"
onMouseDown={(e) => e.stopPropagation()}
onClick={(e) => { e.stopPropagation(); draftWithAssistant() }}
>
<MessageSquare size={13} />
Draft with Rowboat
</button>
</div>
)}
</div>
)}
{/* Draft section */}
{hasDraft && (
<div className="email-block-draft-section">
<div className="email-block-draft-label">Draft reply</div>
<textarea
key={resolvedTheme}
ref={bodyRef}
className="email-draft-block-body-input"
value={draftBody}
onChange={(e) => setDraftBody(e.target.value)}
onBlur={() => commitDraft(draftBody)}
placeholder="Write your reply..."
rows={3}
/>
</div>
)}
{/* Action buttons */}
<div className="email-block-actions">
<button
className="email-block-gmail-btn email-block-gmail-btn-primary"
onClick={draftWithAssistant}
>
<MessageSquare size={13} />
{hasDraft ? 'Refine with Rowboat' : 'Draft with Rowboat'}
</button>
{hasDraft && (
<button
className="email-block-gmail-btn email-block-gmail-btn-primary"
onClick={() => {
navigator.clipboard.writeText(draftBody).then(() => {
setCopied(true)
setTimeout(() => setCopied(false), 2000)
}).catch(() => {
// Fallback for Electron contexts where clipboard API may fail
const textarea = document.createElement('textarea')
textarea.value = draftBody
document.body.appendChild(textarea)
textarea.select()
document.execCommand('copy')
document.body.removeChild(textarea)
setCopied(true)
setTimeout(() => setCopied(false), 2000)
})
}}
>
{copied ? <Check size={13} /> : <Copy size={13} />}
{copied ? 'Copied!' : 'Copy draft'}
</button>
)}
{gmailUrl && (
<button
className="email-block-gmail-btn"
onClick={() => window.open(gmailUrl, '_blank')}
>
<ExternalLink size={13} />
Open in Gmail
</button>
)}
</div>
</div>
</NodeViewWrapper>
)

View file

@ -1428,131 +1428,205 @@
background-color: var(--background);
}
/* Email badge */
.tiptap-editor .ProseMirror .email-block-badge {
display: inline-flex;
/* Gmail-style two-column row */
.tiptap-editor .ProseMirror .email-gmail-row {
display: flex;
align-items: center;
gap: 5px;
font-size: 11px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.06em;
color: color-mix(in srgb, var(--foreground) 45%, transparent);
margin-bottom: 8px;
gap: 12px;
cursor: pointer;
padding: 2px 0;
border-radius: 4px;
transition: background 0.1s ease;
user-select: none;
}
/* Summary */
.tiptap-editor .ProseMirror .email-block-summary {
.tiptap-editor .ProseMirror .email-gmail-row:hover {
background: color-mix(in srgb, var(--foreground) 4%, transparent);
}
.tiptap-editor .ProseMirror .email-gmail-row.email-gmail-row-expanded {
padding-bottom: 12px;
border-bottom: 1px solid color-mix(in srgb, var(--foreground) 8%, transparent);
margin-bottom: 2px;
}
/* Sender avatar circle */
.tiptap-editor .ProseMirror .email-gmail-avatar {
width: 36px;
height: 36px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 15px;
font-weight: 500;
color: var(--foreground);
line-height: 1.4;
margin-bottom: 10px;
color: #fff;
flex-shrink: 0;
letter-spacing: 0;
}
/* Expand button */
.tiptap-editor .ProseMirror .email-block-expand-btn {
display: inline-flex;
align-items: center;
gap: 4px;
padding: 0;
font-size: 13px;
font-weight: 400;
color: color-mix(in srgb, var(--foreground) 50%, transparent);
background: none;
border: none;
cursor: pointer;
transition: color 0.12s ease;
margin-bottom: 4px;
}
.tiptap-editor .ProseMirror .email-block-expand-btn:hover {
color: var(--foreground);
}
.tiptap-editor .ProseMirror .email-block-expand-meta {
color: color-mix(in srgb, var(--foreground) 35%, transparent);
}
.tiptap-editor .ProseMirror .email-block-toggle-chevron {
transition: transform 0.15s ease;
}
.tiptap-editor .ProseMirror .email-block-toggle-chevron-open {
transform: rotate(180deg);
}
/* Email details (expanded) */
.tiptap-editor .ProseMirror .email-block-email-details {
margin-top: 10px;
padding: 12px;
background: color-mix(in srgb, var(--foreground) 4%, transparent);
border-radius: 6px;
display: flex;
flex-direction: column;
gap: 12px;
}
.tiptap-editor .ProseMirror .email-block-message {
padding: 0;
}
.tiptap-editor .ProseMirror .email-block-message-header {
display: flex;
align-items: flex-start;
gap: 12px;
margin-bottom: 10px;
}
.tiptap-editor .ProseMirror .email-block-sender-info {
display: flex;
flex-direction: column;
min-width: 0;
/* Content column */
.tiptap-editor .ProseMirror .email-gmail-content {
flex: 1;
min-width: 0;
display: flex;
flex-direction: column;
gap: 2px;
}
.tiptap-editor .ProseMirror .email-block-sender-row {
.tiptap-editor .ProseMirror .email-gmail-top-row {
display: flex;
align-items: baseline;
justify-content: space-between;
gap: 8px;
}
.tiptap-editor .ProseMirror .email-block-sender-name {
.tiptap-editor .ProseMirror .email-gmail-sender {
font-size: 14px;
font-weight: 500;
font-weight: 600;
color: var(--foreground);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.tiptap-editor .ProseMirror .email-block-sender-date {
.tiptap-editor .ProseMirror .email-gmail-date {
font-size: 12px;
color: color-mix(in srgb, var(--foreground) 50%, transparent);
white-space: nowrap;
flex-shrink: 0;
}
.tiptap-editor .ProseMirror .email-block-subject-line {
font-size: 12px;
.tiptap-editor .ProseMirror .email-gmail-bottom-row {
font-size: 13px;
color: color-mix(in srgb, var(--foreground) 55%, transparent);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
line-height: 1.4;
}
.tiptap-editor .ProseMirror .email-gmail-subject {
color: color-mix(in srgb, var(--foreground) 80%, transparent);
font-weight: 500;
}
.tiptap-editor .ProseMirror .email-gmail-snippet {
color: color-mix(in srgb, var(--foreground) 45%, transparent);
}
.tiptap-editor .ProseMirror .email-block-message-body {
/* Chevron */
.tiptap-editor .ProseMirror .email-gmail-chevron {
flex-shrink: 0;
color: color-mix(in srgb, var(--foreground) 40%, transparent);
transition: transform 0.15s ease;
}
.tiptap-editor .ProseMirror .email-gmail-chevron.email-gmail-chevron-open {
transform: rotate(180deg);
}
/* Expanded area */
.tiptap-editor .ProseMirror .email-gmail-expanded {
padding-top: 14px;
display: flex;
flex-direction: column;
gap: 12px;
}
.tiptap-editor .ProseMirror .email-gmail-exp-subject {
font-size: 18px;
font-weight: 400;
color: var(--foreground);
line-height: 1.35;
letter-spacing: -0.01em;
}
/* Metadata strip (avatar + from/to/date + open button) */
.tiptap-editor .ProseMirror .email-gmail-exp-meta {
display: flex;
align-items: flex-start;
gap: 10px;
}
.tiptap-editor .ProseMirror .email-gmail-exp-avatar {
width: 40px;
height: 40px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 16px;
font-weight: 500;
color: #fff;
flex-shrink: 0;
}
.tiptap-editor .ProseMirror .email-gmail-exp-meta-right {
flex: 1;
min-width: 0;
display: flex;
flex-direction: column;
gap: 2px;
}
.tiptap-editor .ProseMirror .email-gmail-exp-sender {
font-size: 14px;
font-weight: 500;
color: var(--foreground);
}
.tiptap-editor .ProseMirror .email-gmail-exp-to-date {
font-size: 12px;
color: color-mix(in srgb, var(--foreground) 50%, transparent);
display: flex;
flex-wrap: wrap;
gap: 4px;
align-items: center;
}
.tiptap-editor .ProseMirror .email-gmail-exp-fulldate {
color: color-mix(in srgb, var(--foreground) 40%, transparent);
}
.tiptap-editor .ProseMirror .email-gmail-open-btn {
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: center;
width: 32px;
height: 32px;
border-radius: 50%;
border: none;
background: none;
color: color-mix(in srgb, var(--foreground) 50%, transparent);
cursor: pointer;
transition: background 0.12s ease, color 0.12s ease;
}
.tiptap-editor .ProseMirror .email-gmail-open-btn:hover {
background: color-mix(in srgb, var(--foreground) 8%, transparent);
color: var(--foreground);
}
/* Email body */
.tiptap-editor .ProseMirror .email-gmail-exp-body {
font-size: 14px;
color: color-mix(in srgb, var(--foreground) 80%, transparent);
white-space: pre-wrap;
line-height: 1.58;
line-height: 1.6;
padding-left: 50px;
}
.tiptap-editor .ProseMirror .email-block-context-section {
/* Earlier conversation */
.tiptap-editor .ProseMirror .email-gmail-exp-history {
display: flex;
flex-direction: column;
gap: 4px;
padding-top: 10px;
border-top: 1px solid color-mix(in srgb, var(--foreground) 10%, transparent);
padding-left: 50px;
}
.tiptap-editor .ProseMirror .email-block-context-label {
.tiptap-editor .ProseMirror .email-gmail-exp-history-label {
font-size: 11px;
font-weight: 500;
text-transform: uppercase;
@ -1560,68 +1634,88 @@
color: color-mix(in srgb, var(--foreground) 40%, transparent);
}
.tiptap-editor .ProseMirror .email-block-context-summary {
font-size: 14px;
color: color-mix(in srgb, var(--foreground) 65%, transparent);
line-height: 1.58;
.tiptap-editor .ProseMirror .email-gmail-exp-history-body {
font-size: 13px;
color: color-mix(in srgb, var(--foreground) 55%, transparent);
line-height: 1.55;
white-space: pre-wrap;
padding-left: 12px;
border-left: 3px solid color-mix(in srgb, var(--foreground) 12%, transparent);
}
/* Draft section */
.tiptap-editor .ProseMirror .email-block-draft-section {
margin-top: 10px;
padding: 10px 12px;
border: 1px solid color-mix(in srgb, var(--foreground) 12%, transparent);
border-radius: 6px;
/* Compose / draft box */
.tiptap-editor .ProseMirror .email-gmail-compose {
margin-top: 4px;
border: 1px solid color-mix(in srgb, var(--foreground) 15%, transparent);
border-radius: 8px;
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.08);
overflow: hidden;
}
.tiptap-editor .ProseMirror .email-block-draft-label {
font-size: 11px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.06em;
color: color-mix(in srgb, var(--foreground) 40%, transparent);
margin-bottom: 4px;
.tiptap-editor .ProseMirror .email-gmail-compose-to {
display: flex;
align-items: center;
gap: 6px;
padding: 8px 12px 6px;
border-bottom: 1px solid color-mix(in srgb, var(--foreground) 8%, transparent);
}
.tiptap-editor .ProseMirror .email-draft-block-body-input {
.tiptap-editor .ProseMirror .email-gmail-compose-to-label {
font-size: 12px;
font-weight: 500;
color: color-mix(in srgb, var(--foreground) 45%, transparent);
}
.tiptap-editor .ProseMirror .email-gmail-compose-to-addr {
font-size: 13px;
color: color-mix(in srgb, var(--foreground) 70%, transparent);
}
.tiptap-editor .ProseMirror .email-gmail-compose-body {
width: 100%;
font-size: 14px;
color: var(--foreground);
background: none;
border: none;
outline: none;
padding: 4px 0;
padding: 10px 12px;
font-family: inherit;
line-height: 1.58;
resize: none;
overflow: hidden;
box-sizing: border-box;
}
.tiptap-editor .ProseMirror .email-draft-block-body-input::placeholder {
.tiptap-editor .ProseMirror .email-gmail-compose-body::placeholder {
color: color-mix(in srgb, var(--foreground) 35%, transparent);
}
/* Action buttons */
.tiptap-editor .ProseMirror .email-block-actions {
.tiptap-editor .ProseMirror .email-gmail-compose-footer {
display: flex;
align-items: center;
gap: 8px;
margin-top: 12px;
padding: 8px 12px;
border-top: 1px solid color-mix(in srgb, var(--foreground) 8%, transparent);
}
.tiptap-editor .ProseMirror .email-block-gmail-btn {
/* Action buttons */
.tiptap-editor .ProseMirror .email-gmail-actions {
display: flex;
align-items: center;
gap: 8px;
padding-left: 50px;
}
.tiptap-editor .ProseMirror .email-gmail-btn {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 7px 16px;
font-size: 14px;
font-size: 13px;
font-weight: 500;
color: color-mix(in srgb, var(--foreground) 60%, transparent);
background: transparent;
border: 1px solid var(--border);
border: 1px solid color-mix(in srgb, var(--foreground) 20%, transparent);
border-radius: 18px;
cursor: pointer;
transition: background-color 0.15s ease, box-shadow 0.15s ease;
@ -1629,24 +1723,19 @@
letter-spacing: 0.01em;
}
.tiptap-editor .ProseMirror .email-block-gmail-btn:hover {
background: color-mix(in srgb, var(--foreground) 8%, transparent);
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.1), 0 1px 3px 1px rgba(0, 0, 0, 0.06);
.tiptap-editor .ProseMirror .email-gmail-btn:hover {
background: color-mix(in srgb, var(--foreground) 6%, transparent);
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.1);
color: var(--foreground);
}
.tiptap-editor .ProseMirror .email-block-gmail-btn:disabled {
opacity: 0.6;
cursor: default;
}
.tiptap-editor .ProseMirror .email-block-gmail-btn-primary {
.tiptap-editor .ProseMirror .email-gmail-btn-primary {
color: #fff;
background: #1a73e8;
border-color: #1a73e8;
}
.tiptap-editor .ProseMirror .email-block-gmail-btn-primary:hover:not(:disabled) {
.tiptap-editor .ProseMirror .email-gmail-btn-primary:hover {
background: #1765cc;
box-shadow: 0 1px 2px 0 rgba(26, 115, 232, 0.45), 0 1px 3px 1px rgba(26, 115, 232, 0.3);
color: #fff;

141
apps/x/pnpm-lock.yaml generated
View file

@ -177,28 +177,28 @@ importers:
version: 4.1.18(vite@7.3.0(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(yaml@2.8.2))
'@tiptap/extension-image':
specifier: ^3.16.0
version: 3.16.0(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))
version: 3.16.0(@tiptap/core@3.22.4(@tiptap/pm@3.15.3))
'@tiptap/extension-link':
specifier: ^3.15.3
version: 3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3)
version: 3.15.3(@tiptap/core@3.22.4(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3)
'@tiptap/extension-placeholder':
specifier: ^3.15.3
version: 3.15.3(@tiptap/extensions@3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3))
version: 3.15.3(@tiptap/extensions@3.15.3(@tiptap/core@3.22.4(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3))
'@tiptap/extension-table':
specifier: ^3.22.4
version: 3.22.4(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3)
version: 3.22.4(@tiptap/core@3.22.4(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3)
'@tiptap/extension-task-item':
specifier: ^3.15.3
version: 3.15.3(@tiptap/extension-list@3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3))
version: 3.15.3(@tiptap/extension-list@3.15.3(@tiptap/core@3.22.4(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3))
'@tiptap/extension-task-list':
specifier: ^3.15.3
version: 3.15.3(@tiptap/extension-list@3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3))
version: 3.15.3(@tiptap/extension-list@3.15.3(@tiptap/core@3.22.4(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3))
'@tiptap/pm':
specifier: ^3.15.3
version: 3.15.3
'@tiptap/react':
specifier: ^3.15.3
version: 3.15.3(@floating-ui/dom@1.7.4)(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3)(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
version: 3.15.3(@floating-ui/dom@1.7.4)(@tiptap/core@3.22.4(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3)(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
'@tiptap/starter-kit':
specifier: ^3.15.3
version: 3.15.3
@ -264,7 +264,7 @@ importers:
version: 4.1.18
tiptap-markdown:
specifier: ^0.9.0
version: 0.9.0(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))
version: 0.9.0(@tiptap/core@3.22.4(@tiptap/pm@3.15.3))
tokenlens:
specifier: ^1.3.1
version: 1.3.1
@ -1479,30 +1479,35 @@ packages:
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
libc: [glibc]
'@napi-rs/canvas-linux-arm64-musl@0.1.80':
resolution: {integrity: sha512-1XbCOz/ymhj24lFaIXtWnwv/6eFHXDrjP0jYkc6iHQ9q8oXKzUX1Lc6bu+wuGiLhGh2GS/2JlfORC5ZcXimRcg==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
libc: [musl]
'@napi-rs/canvas-linux-riscv64-gnu@0.1.80':
resolution: {integrity: sha512-XTzR125w5ZMs0lJcxRlS1K3P5RaZ9RmUsPtd1uGt+EfDyYMu4c6SEROYsxyatbbu/2+lPe7MPHOO/0a0x7L/gw==}
engines: {node: '>= 10'}
cpu: [riscv64]
os: [linux]
libc: [glibc]
'@napi-rs/canvas-linux-x64-gnu@0.1.80':
resolution: {integrity: sha512-BeXAmhKg1kX3UCrJsYbdQd3hIMDH/K6HnP/pG2LuITaXhXBiNdh//TVVVVCBbJzVQaV5gK/4ZOCMrQW9mvuTqA==}
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
libc: [glibc]
'@napi-rs/canvas-linux-x64-musl@0.1.80':
resolution: {integrity: sha512-x0XvZWdHbkgdgucJsRxprX/4o4sEed7qo9rCQA9ugiS9qE2QvP0RIiEugtZhfLH3cyI+jIRFJHV4Fuz+1BHHMg==}
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
libc: [musl]
'@napi-rs/canvas-win32-x64-msvc@0.1.80':
resolution: {integrity: sha512-Z8jPsM6df5V8B1HrCHB05+bDiCxjE9QA//3YrkKIdVDEwn5RKaqOxCJDRJkl48cJbylcrJbW4HxZbTte8juuPg==}
@ -2628,56 +2633,67 @@ packages:
resolution: {integrity: sha512-EHMUcDwhtdRGlXZsGSIuXSYwD5kOT9NVnx9sqzYiwAc91wfYOE1g1djOEDseZJKKqtHAHGwnGPQu3kytmfaXLQ==}
cpu: [arm]
os: [linux]
libc: [glibc]
'@rollup/rollup-linux-arm-musleabihf@4.54.0':
resolution: {integrity: sha512-+pBrqEjaakN2ySv5RVrj/qLytYhPKEUwk+e3SFU5jTLHIcAtqh2rLrd/OkbNuHJpsBgxsD8ccJt5ga/SeG0JmA==}
cpu: [arm]
os: [linux]
libc: [musl]
'@rollup/rollup-linux-arm64-gnu@4.54.0':
resolution: {integrity: sha512-NSqc7rE9wuUaRBsBp5ckQ5CVz5aIRKCwsoa6WMF7G01sX3/qHUw/z4pv+D+ahL1EIKy6Enpcnz1RY8pf7bjwng==}
cpu: [arm64]
os: [linux]
libc: [glibc]
'@rollup/rollup-linux-arm64-musl@4.54.0':
resolution: {integrity: sha512-gr5vDbg3Bakga5kbdpqx81m2n9IX8M6gIMlQQIXiLTNeQW6CucvuInJ91EuCJ/JYvc+rcLLsDFcfAD1K7fMofg==}
cpu: [arm64]
os: [linux]
libc: [musl]
'@rollup/rollup-linux-loong64-gnu@4.54.0':
resolution: {integrity: sha512-gsrtB1NA3ZYj2vq0Rzkylo9ylCtW/PhpLEivlgWe0bpgtX5+9j9EZa0wtZiCjgu6zmSeZWyI/e2YRX1URozpIw==}
cpu: [loong64]
os: [linux]
libc: [glibc]
'@rollup/rollup-linux-ppc64-gnu@4.54.0':
resolution: {integrity: sha512-y3qNOfTBStmFNq+t4s7Tmc9hW2ENtPg8FeUD/VShI7rKxNW7O4fFeaYbMsd3tpFlIg1Q8IapFgy7Q9i2BqeBvA==}
cpu: [ppc64]
os: [linux]
libc: [glibc]
'@rollup/rollup-linux-riscv64-gnu@4.54.0':
resolution: {integrity: sha512-89sepv7h2lIVPsFma8iwmccN7Yjjtgz0Rj/Ou6fEqg3HDhpCa+Et+YSufy27i6b0Wav69Qv4WBNl3Rs6pwhebQ==}
cpu: [riscv64]
os: [linux]
libc: [glibc]
'@rollup/rollup-linux-riscv64-musl@4.54.0':
resolution: {integrity: sha512-ZcU77ieh0M2Q8Ur7D5X7KvK+UxbXeDHwiOt/CPSBTI1fBmeDMivW0dPkdqkT4rOgDjrDDBUed9x4EgraIKoR2A==}
cpu: [riscv64]
os: [linux]
libc: [musl]
'@rollup/rollup-linux-s390x-gnu@4.54.0':
resolution: {integrity: sha512-2AdWy5RdDF5+4YfG/YesGDDtbyJlC9LHmL6rZw6FurBJ5n4vFGupsOBGfwMRjBYH7qRQowT8D/U4LoSvVwOhSQ==}
cpu: [s390x]
os: [linux]
libc: [glibc]
'@rollup/rollup-linux-x64-gnu@4.54.0':
resolution: {integrity: sha512-WGt5J8Ij/rvyqpFexxk3ffKqqbLf9AqrTBbWDk7ApGUzaIs6V+s2s84kAxklFwmMF/vBNGrVdYgbblCOFFezMQ==}
cpu: [x64]
os: [linux]
libc: [glibc]
'@rollup/rollup-linux-x64-musl@4.54.0':
resolution: {integrity: sha512-JzQmb38ATzHjxlPHuTH6tE7ojnMKM2kYNzt44LO/jJi8BpceEC8QuXYA908n8r3CNuG/B3BV8VR3Hi1rYtmPiw==}
cpu: [x64]
os: [linux]
libc: [musl]
'@rollup/rollup-openharmony-arm64@4.54.0':
resolution: {integrity: sha512-huT3fd0iC7jigGh7n3q/+lfPcXxBi+om/Rs3yiFxjvSxbSB6aohDFXbWvlspaqjeOh+hx7DDHS+5Es5qRkWkZg==}
@ -2996,24 +3012,28 @@ packages:
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
libc: [glibc]
'@tailwindcss/oxide-linux-arm64-musl@4.1.18':
resolution: {integrity: sha512-1px92582HkPQlaaCkdRcio71p8bc8i/ap5807tPRDK/uw953cauQBT8c5tVGkOwrHMfc2Yh6UuxaH4vtTjGvHg==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
libc: [musl]
'@tailwindcss/oxide-linux-x64-gnu@4.1.18':
resolution: {integrity: sha512-v3gyT0ivkfBLoZGF9LyHmts0Isc8jHZyVcbzio6Wpzifg/+5ZJpDiRiUhDLkcr7f/r38SWNe7ucxmGW3j3Kb/g==}
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
libc: [glibc]
'@tailwindcss/oxide-linux-x64-musl@4.1.18':
resolution: {integrity: sha512-bhJ2y2OQNlcRwwgOAGMY0xTFStt4/wyU6pvI6LSuZpRgKQwxTec0/3Scu91O8ir7qCR3AuepQKLU/kX99FouqQ==}
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
libc: [musl]
'@tailwindcss/oxide-wasm32-wasi@4.1.18':
resolution: {integrity: sha512-LffYTvPjODiP6PT16oNeUQJzNVyJl1cjIebq/rWWBF+3eDst5JGEFSc5cWxyRCJ0Mxl+KyIkqRxk1XPEs9x8TA==}
@ -3053,6 +3073,11 @@ packages:
peerDependencies:
'@tiptap/pm': ^3.15.3
'@tiptap/core@3.22.4':
resolution: {integrity: sha512-vGIGm/HpqLg8EAAQXQ+koV+/S828OEpzocfWcPOwo1u2QUVf9dQG47Yy6JJ8zFFaJwfv4dBcOXli+7BrJwsxDQ==}
peerDependencies:
'@tiptap/pm': 3.22.4
'@tiptap/extension-blockquote@3.15.3':
resolution: {integrity: sha512-13x5UsQXtttFpoS/n1q173OeurNxppsdWgP3JfsshzyxIghhC141uL3H6SGYQLPU31AizgDs2OEzt6cSUevaZg==}
peerDependencies:
@ -5602,24 +5627,28 @@ packages:
engines: {node: '>= 12.0.0'}
cpu: [arm64]
os: [linux]
libc: [glibc]
lightningcss-linux-arm64-musl@1.30.2:
resolution: {integrity: sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==}
engines: {node: '>= 12.0.0'}
cpu: [arm64]
os: [linux]
libc: [musl]
lightningcss-linux-x64-gnu@1.30.2:
resolution: {integrity: sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==}
engines: {node: '>= 12.0.0'}
cpu: [x64]
os: [linux]
libc: [glibc]
lightningcss-linux-x64-musl@1.30.2:
resolution: {integrity: sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==}
engines: {node: '>= 12.0.0'}
cpu: [x64]
os: [linux]
libc: [musl]
lightningcss-win32-arm64-msvc@1.30.2:
resolution: {integrity: sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ==}
@ -11073,6 +11102,10 @@ snapshots:
dependencies:
'@tiptap/pm': 3.15.3
'@tiptap/core@3.22.4(@tiptap/pm@3.15.3)':
dependencies:
'@tiptap/pm': 3.15.3
'@tiptap/extension-blockquote@3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))':
dependencies:
'@tiptap/core': 3.15.3(@tiptap/pm@3.15.3)
@ -11081,16 +11114,16 @@ snapshots:
dependencies:
'@tiptap/core': 3.15.3(@tiptap/pm@3.15.3)
'@tiptap/extension-bubble-menu@3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3)':
'@tiptap/extension-bubble-menu@3.15.3(@tiptap/core@3.22.4(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3)':
dependencies:
'@floating-ui/dom': 1.7.4
'@tiptap/core': 3.15.3(@tiptap/pm@3.15.3)
'@tiptap/core': 3.22.4(@tiptap/pm@3.15.3)
'@tiptap/pm': 3.15.3
optional: true
'@tiptap/extension-bullet-list@3.15.3(@tiptap/extension-list@3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3))':
'@tiptap/extension-bullet-list@3.15.3(@tiptap/extension-list@3.15.3(@tiptap/core@3.22.4(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3))':
dependencies:
'@tiptap/extension-list': 3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3)
'@tiptap/extension-list': 3.15.3(@tiptap/core@3.22.4(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3)
'@tiptap/extension-code-block@3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3)':
dependencies:
@ -11105,20 +11138,20 @@ snapshots:
dependencies:
'@tiptap/core': 3.15.3(@tiptap/pm@3.15.3)
'@tiptap/extension-dropcursor@3.15.3(@tiptap/extensions@3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3))':
'@tiptap/extension-dropcursor@3.15.3(@tiptap/extensions@3.15.3(@tiptap/core@3.22.4(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3))':
dependencies:
'@tiptap/extensions': 3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3)
'@tiptap/extensions': 3.15.3(@tiptap/core@3.22.4(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3)
'@tiptap/extension-floating-menu@3.15.3(@floating-ui/dom@1.7.4)(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3)':
'@tiptap/extension-floating-menu@3.15.3(@floating-ui/dom@1.7.4)(@tiptap/core@3.22.4(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3)':
dependencies:
'@floating-ui/dom': 1.7.4
'@tiptap/core': 3.15.3(@tiptap/pm@3.15.3)
'@tiptap/core': 3.22.4(@tiptap/pm@3.15.3)
'@tiptap/pm': 3.15.3
optional: true
'@tiptap/extension-gapcursor@3.15.3(@tiptap/extensions@3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3))':
'@tiptap/extension-gapcursor@3.15.3(@tiptap/extensions@3.15.3(@tiptap/core@3.22.4(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3))':
dependencies:
'@tiptap/extensions': 3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3)
'@tiptap/extensions': 3.15.3(@tiptap/core@3.22.4(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3)
'@tiptap/extension-hard-break@3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))':
dependencies:
@ -11133,9 +11166,9 @@ snapshots:
'@tiptap/core': 3.15.3(@tiptap/pm@3.15.3)
'@tiptap/pm': 3.15.3
'@tiptap/extension-image@3.16.0(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))':
'@tiptap/extension-image@3.16.0(@tiptap/core@3.22.4(@tiptap/pm@3.15.3))':
dependencies:
'@tiptap/core': 3.15.3(@tiptap/pm@3.15.3)
'@tiptap/core': 3.22.4(@tiptap/pm@3.15.3)
'@tiptap/extension-italic@3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))':
dependencies:
@ -11147,47 +11180,58 @@ snapshots:
'@tiptap/pm': 3.15.3
linkifyjs: 4.3.2
'@tiptap/extension-list-item@3.15.3(@tiptap/extension-list@3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3))':
'@tiptap/extension-link@3.15.3(@tiptap/core@3.22.4(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3)':
dependencies:
'@tiptap/extension-list': 3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3)
'@tiptap/core': 3.22.4(@tiptap/pm@3.15.3)
'@tiptap/pm': 3.15.3
linkifyjs: 4.3.2
'@tiptap/extension-list-keymap@3.15.3(@tiptap/extension-list@3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3))':
'@tiptap/extension-list-item@3.15.3(@tiptap/extension-list@3.15.3(@tiptap/core@3.22.4(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3))':
dependencies:
'@tiptap/extension-list': 3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3)
'@tiptap/extension-list': 3.15.3(@tiptap/core@3.22.4(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3)
'@tiptap/extension-list-keymap@3.15.3(@tiptap/extension-list@3.15.3(@tiptap/core@3.22.4(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3))':
dependencies:
'@tiptap/extension-list': 3.15.3(@tiptap/core@3.22.4(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3)
'@tiptap/extension-list@3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3)':
dependencies:
'@tiptap/core': 3.15.3(@tiptap/pm@3.15.3)
'@tiptap/pm': 3.15.3
'@tiptap/extension-ordered-list@3.15.3(@tiptap/extension-list@3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3))':
'@tiptap/extension-list@3.15.3(@tiptap/core@3.22.4(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3)':
dependencies:
'@tiptap/extension-list': 3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3)
'@tiptap/core': 3.22.4(@tiptap/pm@3.15.3)
'@tiptap/pm': 3.15.3
'@tiptap/extension-ordered-list@3.15.3(@tiptap/extension-list@3.15.3(@tiptap/core@3.22.4(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3))':
dependencies:
'@tiptap/extension-list': 3.15.3(@tiptap/core@3.22.4(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3)
'@tiptap/extension-paragraph@3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))':
dependencies:
'@tiptap/core': 3.15.3(@tiptap/pm@3.15.3)
'@tiptap/extension-placeholder@3.15.3(@tiptap/extensions@3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3))':
'@tiptap/extension-placeholder@3.15.3(@tiptap/extensions@3.15.3(@tiptap/core@3.22.4(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3))':
dependencies:
'@tiptap/extensions': 3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3)
'@tiptap/extensions': 3.15.3(@tiptap/core@3.22.4(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3)
'@tiptap/extension-strike@3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))':
dependencies:
'@tiptap/core': 3.15.3(@tiptap/pm@3.15.3)
'@tiptap/extension-table@3.22.4(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3)':
'@tiptap/extension-table@3.22.4(@tiptap/core@3.22.4(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3)':
dependencies:
'@tiptap/core': 3.15.3(@tiptap/pm@3.15.3)
'@tiptap/core': 3.22.4(@tiptap/pm@3.15.3)
'@tiptap/pm': 3.15.3
'@tiptap/extension-task-item@3.15.3(@tiptap/extension-list@3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3))':
'@tiptap/extension-task-item@3.15.3(@tiptap/extension-list@3.15.3(@tiptap/core@3.22.4(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3))':
dependencies:
'@tiptap/extension-list': 3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3)
'@tiptap/extension-list': 3.15.3(@tiptap/core@3.22.4(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3)
'@tiptap/extension-task-list@3.15.3(@tiptap/extension-list@3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3))':
'@tiptap/extension-task-list@3.15.3(@tiptap/extension-list@3.15.3(@tiptap/core@3.22.4(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3))':
dependencies:
'@tiptap/extension-list': 3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3)
'@tiptap/extension-list': 3.15.3(@tiptap/core@3.22.4(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3)
'@tiptap/extension-text@3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))':
dependencies:
@ -11202,6 +11246,11 @@ snapshots:
'@tiptap/core': 3.15.3(@tiptap/pm@3.15.3)
'@tiptap/pm': 3.15.3
'@tiptap/extensions@3.15.3(@tiptap/core@3.22.4(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3)':
dependencies:
'@tiptap/core': 3.22.4(@tiptap/pm@3.15.3)
'@tiptap/pm': 3.15.3
'@tiptap/pm@3.15.3':
dependencies:
prosemirror-changeset: 2.3.1
@ -11223,9 +11272,9 @@ snapshots:
prosemirror-transform: 1.10.5
prosemirror-view: 1.41.4
'@tiptap/react@3.15.3(@floating-ui/dom@1.7.4)(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3)(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
'@tiptap/react@3.15.3(@floating-ui/dom@1.7.4)(@tiptap/core@3.22.4(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3)(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
dependencies:
'@tiptap/core': 3.15.3(@tiptap/pm@3.15.3)
'@tiptap/core': 3.22.4(@tiptap/pm@3.15.3)
'@tiptap/pm': 3.15.3
'@types/react': 19.2.7
'@types/react-dom': 19.2.3(@types/react@19.2.7)
@ -11235,8 +11284,8 @@ snapshots:
react-dom: 19.2.3(react@19.2.3)
use-sync-external-store: 1.6.0(react@19.2.3)
optionalDependencies:
'@tiptap/extension-bubble-menu': 3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3)
'@tiptap/extension-floating-menu': 3.15.3(@floating-ui/dom@1.7.4)(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3)
'@tiptap/extension-bubble-menu': 3.15.3(@tiptap/core@3.22.4(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3)
'@tiptap/extension-floating-menu': 3.15.3(@floating-ui/dom@1.7.4)(@tiptap/core@3.22.4(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3)
transitivePeerDependencies:
- '@floating-ui/dom'
@ -11245,21 +11294,21 @@ snapshots:
'@tiptap/core': 3.15.3(@tiptap/pm@3.15.3)
'@tiptap/extension-blockquote': 3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))
'@tiptap/extension-bold': 3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))
'@tiptap/extension-bullet-list': 3.15.3(@tiptap/extension-list@3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3))
'@tiptap/extension-bullet-list': 3.15.3(@tiptap/extension-list@3.15.3(@tiptap/core@3.22.4(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3))
'@tiptap/extension-code': 3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))
'@tiptap/extension-code-block': 3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3)
'@tiptap/extension-document': 3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))
'@tiptap/extension-dropcursor': 3.15.3(@tiptap/extensions@3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3))
'@tiptap/extension-gapcursor': 3.15.3(@tiptap/extensions@3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3))
'@tiptap/extension-dropcursor': 3.15.3(@tiptap/extensions@3.15.3(@tiptap/core@3.22.4(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3))
'@tiptap/extension-gapcursor': 3.15.3(@tiptap/extensions@3.15.3(@tiptap/core@3.22.4(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3))
'@tiptap/extension-hard-break': 3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))
'@tiptap/extension-heading': 3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))
'@tiptap/extension-horizontal-rule': 3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3)
'@tiptap/extension-italic': 3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))
'@tiptap/extension-link': 3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3)
'@tiptap/extension-list': 3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3)
'@tiptap/extension-list-item': 3.15.3(@tiptap/extension-list@3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3))
'@tiptap/extension-list-keymap': 3.15.3(@tiptap/extension-list@3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3))
'@tiptap/extension-ordered-list': 3.15.3(@tiptap/extension-list@3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3))
'@tiptap/extension-list-item': 3.15.3(@tiptap/extension-list@3.15.3(@tiptap/core@3.22.4(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3))
'@tiptap/extension-list-keymap': 3.15.3(@tiptap/extension-list@3.15.3(@tiptap/core@3.22.4(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3))
'@tiptap/extension-ordered-list': 3.15.3(@tiptap/extension-list@3.15.3(@tiptap/core@3.22.4(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3))
'@tiptap/extension-paragraph': 3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))
'@tiptap/extension-strike': 3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))
'@tiptap/extension-text': 3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))
@ -16221,9 +16270,9 @@ snapshots:
fdir: 6.5.0(picomatch@4.0.3)
picomatch: 4.0.3
tiptap-markdown@0.9.0(@tiptap/core@3.15.3(@tiptap/pm@3.15.3)):
tiptap-markdown@0.9.0(@tiptap/core@3.22.4(@tiptap/pm@3.15.3)):
dependencies:
'@tiptap/core': 3.15.3(@tiptap/pm@3.15.3)
'@tiptap/core': 3.22.4(@tiptap/pm@3.15.3)
'@types/markdown-it': 13.0.9
markdown-it: 14.1.0
markdown-it-task-lists: 2.1.1