📝 explanatory tooltips
This commit is contained in:
@@ -628,3 +628,33 @@
|
||||
text-align: right;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.pm-dim-info {
|
||||
display: inline-block;
|
||||
margin-left: 4px;
|
||||
font-size: 9px;
|
||||
opacity: 0.4;
|
||||
cursor: default;
|
||||
vertical-align: middle;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.pm-dim-info:hover {
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.pm-tooltip-fixed {
|
||||
position: fixed;
|
||||
transform: translate(-50%, -100%);
|
||||
width: 220px;
|
||||
background: var(--bg-panel, #1a1a1a);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 5px;
|
||||
padding: 7px 9px;
|
||||
font-size: 11px;
|
||||
line-height: 1.5;
|
||||
color: var(--text-primary);
|
||||
white-space: normal;
|
||||
z-index: 9999;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
@@ -274,8 +274,26 @@ function scoreColor(score: number): string {
|
||||
return 'var(--polish-low)'
|
||||
}
|
||||
|
||||
const DIM_DESCRIPTIONS: Record<string, string> = {
|
||||
passiveVoice: 'Flags "was/were + past participle" constructions. Penalises above 12 per 1,000 words.',
|
||||
weaselWords: 'Intensifiers like very, quite, clearly that weaken prose. Penalises above 10 per 1,000 words.',
|
||||
adverbDensity: '–ly adverbs per 1,000 words. Strong verbs rarely need adverb support. Penalises above 20 per 1,000.',
|
||||
filterWords: '"She felt", "he noticed" — constructions that put a layer between reader and action. Penalises above 8 per 1,000 words.',
|
||||
showTell: '"Was/were + emotion adjective" (was angry, were afraid). Suggests telling the reader rather than dramatising the moment.',
|
||||
sentenceRhythm: 'Coefficient of variation in sentence lengths. High variance = good pacing. Also flags runs of 3+ sentences within 2 words of each other in length.',
|
||||
paragraphRhythm: 'Variation in paragraph lengths. Flags walls of text over 150 words and measures overall length variance.',
|
||||
repeatedStarters: 'Penalises 3+ consecutive sentences opening with the same word, and chapters heavy with pronoun openers (he/she/they).',
|
||||
wordVariety: 'Type-token ratio over 100-word windows of content words. Low ratio = repetitive vocabulary. Also flags words repeated 3+ times within 50 words.',
|
||||
cliches: 'Matches against a list of common literary clichés (heart pounding, blood ran cold, etc.). Penalises above 6 per 1,000 words.',
|
||||
overusedWords: 'Drafting filler: just, suddenly, somehow, began to, started to. Penalises above 25 per 1,000 words.',
|
||||
dialogueTags: 'Said-bookisms (hissed, snarled, barked) and adverb-modified tags (said softly). Penalises above 8 per 1,000 words.',
|
||||
}
|
||||
|
||||
interface TooltipState { text: string; x: number; y: number }
|
||||
|
||||
function PolishMeter({ score }: { score: PolishScore }): JSX.Element {
|
||||
const [activeKey, setActiveKey] = useState<string | null>(null)
|
||||
const [tooltip, setTooltip] = useState<TooltipState | null>(null)
|
||||
const { setAnnotations, clearAnnotations } = useEditorStore()
|
||||
|
||||
const dims = Object.entries(score.dimensions) as [string, PolishDimension][]
|
||||
@@ -325,7 +343,20 @@ function PolishMeter({ score }: { score: PolishScore }): JSX.Element {
|
||||
onClick={() => clickable && handleDimClick(key, dim)}
|
||||
title={clickable ? `Click to highlight ${dim.issueCount} instance${dim.issueCount !== 1 ? 's' : ''}` : undefined}
|
||||
>
|
||||
<span className="pm-dim-label">{dim.label}</span>
|
||||
<span className="pm-dim-label">
|
||||
{dim.label}
|
||||
{DIM_DESCRIPTIONS[key] && (
|
||||
<span
|
||||
className="pm-dim-info"
|
||||
onClick={e => e.stopPropagation()}
|
||||
onMouseEnter={e => {
|
||||
const r = (e.currentTarget as HTMLElement).getBoundingClientRect()
|
||||
setTooltip({ text: DIM_DESCRIPTIONS[key], x: r.left + r.width / 2, y: r.top - 8 })
|
||||
}}
|
||||
onMouseLeave={() => setTooltip(null)}
|
||||
>ⓘ</span>
|
||||
)}
|
||||
</span>
|
||||
<div className="pm-bar-track">
|
||||
<div
|
||||
className="pm-bar-fill"
|
||||
@@ -337,6 +368,14 @@ function PolishMeter({ score }: { score: PolishScore }): JSX.Element {
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
{tooltip && (
|
||||
<div
|
||||
className="pm-tooltip-fixed"
|
||||
style={{ left: tooltip.x, top: tooltip.y }}
|
||||
>
|
||||
{tooltip.text}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user