fix(zone-modal): center slider thumb on track, drop dead code, cover a11y
- Center webkit slider thumb on 4px track (margin-top: -4.5px) so the opacity bullet no longer sits below the bar. - Drop redundant inline accentColor; CSS module owns track color. - Remove dead ::-ms-* prefix rules. - Tests: assert aria-labels on grid/select triggers, cover getFontLabel happy path + unknown-value fallback via the Font selector DOM.
This commit is contained in:
@@ -1,4 +1,15 @@
|
|||||||
/* Custom colored slider track for accent color */
|
/* Slider container: strip native chrome so custom track/thumb align cleanly */
|
||||||
|
.slider-thumb {
|
||||||
|
-webkit-appearance: none;
|
||||||
|
appearance: none;
|
||||||
|
background: transparent;
|
||||||
|
height: 13px; /* match thumb height so vertical centering is the input's box center */
|
||||||
|
}
|
||||||
|
.slider-thumb:focus {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Track */
|
||||||
.slider-accent::-webkit-slider-runnable-track {
|
.slider-accent::-webkit-slider-runnable-track {
|
||||||
height: 4px;
|
height: 4px;
|
||||||
background: #00d4ff;
|
background: #00d4ff;
|
||||||
@@ -9,23 +20,17 @@
|
|||||||
background: #00d4ff;
|
background: #00d4ff;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
}
|
}
|
||||||
.slider-accent::-ms-fill-lower,
|
|
||||||
.slider-accent::-ms-fill-upper {
|
|
||||||
background: #00d4ff;
|
|
||||||
border-radius: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Ensure the slider bar is visible on dark backgrounds */
|
/* Thumb — must offset on webkit so it centers on the 4px track */
|
||||||
.slider-thumb {
|
|
||||||
background: transparent;
|
|
||||||
}
|
|
||||||
/* Custom slider thumb for smaller circle */
|
|
||||||
.slider-thumb::-webkit-slider-thumb {
|
.slider-thumb::-webkit-slider-thumb {
|
||||||
|
-webkit-appearance: none;
|
||||||
|
appearance: none;
|
||||||
width: 13px;
|
width: 13px;
|
||||||
height: 13px;
|
height: 13px;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
background: #00d4ff;
|
background: #00d4ff;
|
||||||
border: 2px solid #21262d;
|
border: 2px solid #21262d;
|
||||||
|
margin-top: -4.5px; /* (13 - 4) / 2 */
|
||||||
}
|
}
|
||||||
.slider-thumb::-moz-range-thumb {
|
.slider-thumb::-moz-range-thumb {
|
||||||
width: 13px;
|
width: 13px;
|
||||||
@@ -34,10 +39,3 @@
|
|||||||
background: #00d4ff;
|
background: #00d4ff;
|
||||||
border: 2px solid #21262d;
|
border: 2px solid #21262d;
|
||||||
}
|
}
|
||||||
.slider-thumb::-ms-thumb {
|
|
||||||
width: 13px;
|
|
||||||
height: 13px;
|
|
||||||
border-radius: 50%;
|
|
||||||
background: #00d4ff;
|
|
||||||
border: 2px solid #21262d;
|
|
||||||
}
|
|
||||||
@@ -235,9 +235,8 @@ export function GroupRectModal({ open, onClose, onSubmit, onDelete, initial, tit
|
|||||||
max={100}
|
max={100}
|
||||||
value={alpha}
|
value={alpha}
|
||||||
onChange={(e) => set(key, rgbaToHex8(hex6, Number(e.target.value)))}
|
onChange={(e) => set(key, rgbaToHex8(hex6, Number(e.target.value)))}
|
||||||
className={`w-full h-1 cursor-pointer mt-2 ${styles['slider-thumb']} ${styles['slider-accent']}`}
|
className={`w-full cursor-pointer mt-2 ${styles['slider-thumb']} ${styles['slider-accent']}`}
|
||||||
title={`Opacity: ${alpha}%`}
|
title={`Opacity: ${alpha}%`}
|
||||||
style={{ accentColor: '#00d4ff' }}
|
|
||||||
/>
|
/>
|
||||||
<span className="text-[9px] text-muted-foreground/60">{label} {alpha}%</span>
|
<span className="text-[9px] text-muted-foreground/60">{label} {alpha}%</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -37,6 +37,16 @@ describe('GroupRectModal', () => {
|
|||||||
expect(submitted.z_order).toBe(1)
|
expect(submitted.z_order).toBe(1)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('exposes aria-labels on grid buttons and select triggers', () => {
|
||||||
|
render(<GroupRectModal open onClose={vi.fn()} onSubmit={vi.fn()} />)
|
||||||
|
expect(screen.getByLabelText('Font selector')).toBeDefined()
|
||||||
|
expect(screen.getByLabelText('Z-order selector')).toBeDefined()
|
||||||
|
expect(screen.getByLabelText('Text position ↘')).toBeDefined()
|
||||||
|
expect(screen.getByLabelText('Label position Inside')).toBeDefined()
|
||||||
|
expect(screen.getByLabelText('Border style Solid')).toBeDefined()
|
||||||
|
expect(screen.getByLabelText('Border width 1px')).toBeDefined()
|
||||||
|
})
|
||||||
|
|
||||||
it('calls onClose when Cancel is clicked', () => {
|
it('calls onClose when Cancel is clicked', () => {
|
||||||
const onClose = vi.fn()
|
const onClose = vi.fn()
|
||||||
render(<GroupRectModal open onClose={onClose} onSubmit={vi.fn()} />)
|
render(<GroupRectModal open onClose={onClose} onSubmit={vi.fn()} />)
|
||||||
@@ -308,3 +318,24 @@ describe('GroupRectModal', () => {
|
|||||||
expect(screen.getByText(/Background 5%/)).toBeInTheDocument()
|
expect(screen.getByText(/Background 5%/)).toBeInTheDocument()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('GroupRectModal font label rendering', () => {
|
||||||
|
it('renders the human font label in the Select trigger (default inter)', () => {
|
||||||
|
render(<GroupRectModal open onClose={vi.fn()} onSubmit={vi.fn()} />)
|
||||||
|
const trigger = screen.getByLabelText('Font selector')
|
||||||
|
expect(trigger.textContent).toContain('Inter (sans-serif)')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('falls back to raw value when font is unknown', () => {
|
||||||
|
render(
|
||||||
|
<GroupRectModal
|
||||||
|
open
|
||||||
|
onClose={vi.fn()}
|
||||||
|
onSubmit={vi.fn()}
|
||||||
|
initial={{ font: 'comic-sans-9000' }}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
const trigger = screen.getByLabelText('Font selector')
|
||||||
|
expect(trigger.textContent).toContain('comic-sans-9000')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user