feat(text-tool): add comprehensive text formatting controls
Enhanced the text tool toolbar with professional formatting options:
- Font style controls: Bold and Italic toggle buttons
- Text alignment: Left, Center, Right buttons with visual feedback
- Line height slider: Range 0.5-3.0 with 0.1 step precision
- Letter spacing slider: Range -10px to 50px
- Expanded font family: Added 10 more fonts (16 total)
- Added: Trebuchet MS, Impact, Comic Sans MS, Palatino, Garamond,
Bookman, Tahoma, Lucida Console, Monaco, Consolas
All controls have active state highlighting and smooth transitions
for better user experience.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -9,7 +9,17 @@ export function ToolOptions() {
|
|||||||
const { activeTool, settings, setSize, setOpacity, setHardness, setColor, setFlow } = useToolStore();
|
const { activeTool, settings, setSize, setOpacity, setHardness, setColor, setFlow } = useToolStore();
|
||||||
const { settings: shapeSettings, setShapeType } = useShapeStore();
|
const { settings: shapeSettings, setShapeType } = useShapeStore();
|
||||||
const { selectionType, setSelectionType } = useSelectionStore();
|
const { selectionType, setSelectionType } = useSelectionStore();
|
||||||
const { settings: textSettings, setFontFamily, setFontSize, setColor: setTextColor } = useTextStore();
|
const {
|
||||||
|
settings: textSettings,
|
||||||
|
setFontFamily,
|
||||||
|
setFontSize,
|
||||||
|
setFontStyle,
|
||||||
|
setFontWeight,
|
||||||
|
setAlign,
|
||||||
|
setLineHeight,
|
||||||
|
setLetterSpacing,
|
||||||
|
setColor: setTextColor,
|
||||||
|
} = useTextStore();
|
||||||
|
|
||||||
// Drawing tools: brush, pencil, eraser
|
// Drawing tools: brush, pencil, eraser
|
||||||
const isDrawingTool = ['brush', 'eraser', 'pencil'].includes(activeTool);
|
const isDrawingTool = ['brush', 'eraser', 'pencil'].includes(activeTool);
|
||||||
@@ -232,6 +242,16 @@ export function ToolOptions() {
|
|||||||
<option value="Georgia">Georgia</option>
|
<option value="Georgia">Georgia</option>
|
||||||
<option value="Courier New">Courier New</option>
|
<option value="Courier New">Courier New</option>
|
||||||
<option value="Verdana">Verdana</option>
|
<option value="Verdana">Verdana</option>
|
||||||
|
<option value="Trebuchet MS">Trebuchet MS</option>
|
||||||
|
<option value="Impact">Impact</option>
|
||||||
|
<option value="Comic Sans MS">Comic Sans MS</option>
|
||||||
|
<option value="Palatino">Palatino</option>
|
||||||
|
<option value="Garamond">Garamond</option>
|
||||||
|
<option value="Bookman">Bookman</option>
|
||||||
|
<option value="Tahoma">Tahoma</option>
|
||||||
|
<option value="Lucida Console">Lucida Console</option>
|
||||||
|
<option value="Monaco">Monaco</option>
|
||||||
|
<option value="Consolas">Consolas</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -250,6 +270,69 @@ export function ToolOptions() {
|
|||||||
<span className="text-sm text-muted-foreground">px</span>
|
<span className="text-sm text-muted-foreground">px</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Font Style: Bold/Italic */}
|
||||||
|
<div className="flex items-center gap-1">
|
||||||
|
<button
|
||||||
|
onClick={() => setFontWeight(textSettings.fontWeight === 'bold' ? 'normal' : 'bold')}
|
||||||
|
className={`px-3 py-1.5 text-sm font-bold rounded-md border transition-colors ${
|
||||||
|
textSettings.fontWeight === 'bold'
|
||||||
|
? 'bg-primary text-primary-foreground border-primary'
|
||||||
|
: 'bg-background text-foreground border-border hover:bg-accent'
|
||||||
|
}`}
|
||||||
|
title="Bold"
|
||||||
|
>
|
||||||
|
B
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={() => setFontStyle(textSettings.fontStyle === 'italic' ? 'normal' : 'italic')}
|
||||||
|
className={`px-3 py-1.5 text-sm italic rounded-md border transition-colors ${
|
||||||
|
textSettings.fontStyle === 'italic'
|
||||||
|
? 'bg-primary text-primary-foreground border-primary'
|
||||||
|
: 'bg-background text-foreground border-border hover:bg-accent'
|
||||||
|
}`}
|
||||||
|
title="Italic"
|
||||||
|
>
|
||||||
|
I
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Text Alignment */}
|
||||||
|
<div className="flex items-center gap-1">
|
||||||
|
<button
|
||||||
|
onClick={() => setAlign('left')}
|
||||||
|
className={`px-3 py-1.5 text-sm rounded-md border transition-colors ${
|
||||||
|
textSettings.align === 'left'
|
||||||
|
? 'bg-primary text-primary-foreground border-primary'
|
||||||
|
: 'bg-background text-foreground border-border hover:bg-accent'
|
||||||
|
}`}
|
||||||
|
title="Align Left"
|
||||||
|
>
|
||||||
|
≡
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={() => setAlign('center')}
|
||||||
|
className={`px-3 py-1.5 text-sm rounded-md border transition-colors ${
|
||||||
|
textSettings.align === 'center'
|
||||||
|
? 'bg-primary text-primary-foreground border-primary'
|
||||||
|
: 'bg-background text-foreground border-border hover:bg-accent'
|
||||||
|
}`}
|
||||||
|
title="Align Center"
|
||||||
|
>
|
||||||
|
≣
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={() => setAlign('right')}
|
||||||
|
className={`px-3 py-1.5 text-sm rounded-md border transition-colors ${
|
||||||
|
textSettings.align === 'right'
|
||||||
|
? 'bg-primary text-primary-foreground border-primary'
|
||||||
|
: 'bg-background text-foreground border-border hover:bg-accent'
|
||||||
|
}`}
|
||||||
|
title="Align Right"
|
||||||
|
>
|
||||||
|
≣
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<label className="text-sm font-medium text-card-foreground whitespace-nowrap">
|
<label className="text-sm font-medium text-card-foreground whitespace-nowrap">
|
||||||
Color:
|
Color:
|
||||||
@@ -268,8 +351,40 @@ export function ToolOptions() {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="text-sm text-muted-foreground italic">
|
<div className="flex items-center gap-2">
|
||||||
Click on canvas to add text
|
<label className="text-sm font-medium text-card-foreground whitespace-nowrap">
|
||||||
|
Line Height:
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="range"
|
||||||
|
min="0.5"
|
||||||
|
max="3"
|
||||||
|
step="0.1"
|
||||||
|
value={textSettings.lineHeight}
|
||||||
|
onChange={(e) => setLineHeight(Number(e.target.value))}
|
||||||
|
className="w-24"
|
||||||
|
/>
|
||||||
|
<span className="text-sm text-muted-foreground w-8">
|
||||||
|
{textSettings.lineHeight.toFixed(1)}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<label className="text-sm font-medium text-card-foreground whitespace-nowrap">
|
||||||
|
Letter Spacing:
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="range"
|
||||||
|
min="-10"
|
||||||
|
max="50"
|
||||||
|
step="1"
|
||||||
|
value={textSettings.letterSpacing}
|
||||||
|
onChange={(e) => setLetterSpacing(Number(e.target.value))}
|
||||||
|
className="w-24"
|
||||||
|
/>
|
||||||
|
<span className="text-sm text-muted-foreground w-10">
|
||||||
|
{textSettings.letterSpacing}px
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|||||||
Reference in New Issue
Block a user