File size: 4,529 Bytes
25fd6e4 fd666e2 25fd6e4 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 | import React from 'react';
// DisplayMenu — display preferences popover.
// Mirrors AnnotatorPanel chrome: ap-pop-backdrop + ap-settings panel.
// Controls four settings exposed to the user:
// 1. Palette (three swatch chips)
// 2. Body size (range slider)
// 3. Justify (checkbox)
// 4. Notes side (two chips: left / right)
//
// All other tweak fields (dropCaps, showScores) are preserved in the parent
// tweaks object but not exposed here.
export const PALETTES = [
{ label: 'Parchment', value: ['#f6f1e6', '#2b2418', '#9a3b20'] },
{ label: 'Ivory', value: ['#fbf8f1', '#231f17', '#8a5a18'] },
{ label: 'Chalk', value: ['#f3f2ee', '#22241f', '#3f5a96'] },
];
export default function DisplayMenu({ tweaks, onChange, onClose }) {
const set = (patch) => onChange({ ...tweaks, ...patch });
React.useEffect(() => {
const onKey = (e) => { if (e.key === 'Escape') onClose(); };
window.addEventListener('keydown', onKey);
return () => window.removeEventListener('keydown', onKey);
}, [onClose]);
// Determine which palette is active by matching all three colour values.
const activePalIdx = PALETTES.findIndex(
(p) =>
p.value[0] === tweaks.paperPalette[0] &&
p.value[1] === tweaks.paperPalette[1] &&
p.value[2] === tweaks.paperPalette[2],
);
return (
<div>
<div className="ap-pop-backdrop" onClick={onClose}></div>
<div className="ap-settings" data-screen-label="Display settings">
<div className="ap-settings-title">Display</div>
<div className="ap-settings-sub">paper, type, and margin layout</div>
{/* Palette */}
<div className="ap-field">
<label className="ap-field-label">Palette</label>
<div className="ap-provider-row">
{PALETTES.map((pal, i) => (
<button
key={pal.label}
className={'ap-provider' + (activePalIdx === i ? ' is-active' : '')}
onClick={() => set({ paperPalette: pal.value })}
title={pal.value.join(' · ')}
style={{
background: activePalIdx === i ? undefined : pal.value[0],
color: activePalIdx === i ? undefined : pal.value[1],
borderColor: activePalIdx === i ? undefined : pal.value[1] + '44',
}}
>
{pal.label}
</button>
))}
</div>
</div>
{/* Body size */}
<div className="ap-field">
<label className="ap-field-label">
Body size — {tweaks.bodySize}px
</label>
<input
type="range"
min={16}
max={23}
step={0.5}
value={tweaks.bodySize}
onChange={(e) => set({ bodySize: Number(e.target.value) })}
style={{ width: '100%', marginTop: '6px' }}
/>
</div>
{/* Retrieved works */}
<div className="ap-field">
<label className="ap-field-label">
Retrieved works — {tweaks.litCount ?? 3}
</label>
<input
type="range"
min={3}
max={10}
step={1}
value={tweaks.litCount ?? 3}
onChange={(e) => set({ litCount: Number(e.target.value) })}
style={{ width: '100%', marginTop: '6px' }}
/>
</div>
{/* Justify */}
<div className="ap-field">
<label className="ap-field-label" style={{ display: 'flex', alignItems: 'center', gap: '8px', cursor: 'pointer' }}>
<input
type="checkbox"
checked={tweaks.justify}
onChange={(e) => set({ justify: e.target.checked })}
/>
Justified text
</label>
</div>
{/* Notes side */}
<div className="ap-field">
<label className="ap-field-label">Notes side</label>
<div className="ap-provider-row">
{['right', 'left'].map((side) => (
<button
key={side}
className={'ap-provider' + (tweaks.notesSide === side ? ' is-active' : '')}
onClick={() => set({ notesSide: side })}
>
{side}
</button>
))}
</div>
</div>
<div className="ap-settings-foot">
<button className="ap-textbtn" onClick={onClose}>done</button>
</div>
</div>
</div>
);
}
|