fix: illegal button inside button is header

This commit is contained in:
2026-07-28 22:53:43 +02:00
parent 7ad2db9662
commit 55bffbe350
2 changed files with 58 additions and 50 deletions

View File

@ -134,11 +134,12 @@
gap: var(--space-3); gap: var(--space-3);
height: var(--tab-height); height: var(--tab-height);
padding: 0 var(--space-3); padding: 0 var(--space-3);
border: var(--border-width-active) solid transparent; border: var(--border-width-active) solid var(--border-hairline);
border-radius: var(--radius-lg); border-radius: var(--radius-lg);
background: transparent; background: transparent;
color: var(--text-muted); color: var(--text-muted);
font-family: var(--font-ui); font-family: var(--font-ui);
font-size: var(--font-md);
cursor: pointer; cursor: pointer;
box-sizing: border-box; box-sizing: border-box;
scroll-snap-align: start; scroll-snap-align: start;
@ -157,15 +158,19 @@
border-color: var(--accent-brand); border-color: var(--accent-brand);
} }
.tab span[title] { .tab-name {
flex: 1 1 auto;
min-width: 0;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;
min-width: 0;
user-select: none;
} }
.tab-led { .tab-led {
height: 40%; height: 50%;
aspect-ratio: 1 / 1; aspect-ratio: 1 / 1;
flex: 0 0 auto; flex: 0 0 auto;
@ -174,26 +179,33 @@
align-items: center; align-items: center;
justify-content: center; justify-content: center;
min-height: 0; border: 0;
min-width: 0;
border-radius: var(--radius-sm); border-radius: var(--radius-sm);
background: transparent;
padding: 0;
} }
.tab-close { .tab-close {
height: 50%; height: 50%;
aspect-ratio: 1 / 1; aspect-ratio: 1 / 1;
flex: 0 0 auto;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
flex: 0 0 auto;
border: 0;
border-radius: var(--radius-sm);
margin-left: auto; margin-left: auto;
padding: 0; padding: 0;
font-size: var(--tab-close-font); font-size: var(--tab-close-font);
line-height: 1;
color: var(--text-muted); color: var(--text-muted);
border-radius: var(--radius-sm);
background: transparent;
} }
.tab--active { .tab--active {
@ -249,4 +261,4 @@
(var(--space-3) * 2) + (var(--tab-height) * 0.5) + (var(--space-2) * 2) + 4ch + (var(--space-3) * 2) + (var(--tab-height) * 0.5) + (var(--space-2) * 2) + 4ch +
var(--tab-close-size) var(--tab-close-size)
); );
} }

View File

@ -34,72 +34,68 @@ function Tab({
onConnect: (dsp: DSP) => void; onConnect: (dsp: DSP) => void;
onDisconnect: (dsp: DSP) => void; onDisconnect: (dsp: DSP) => void;
}) { }) {
const handleLedClick = (e: React.MouseEvent) => { const isConnected = dsp.status === 'connected';
e.stopPropagation();
if (dsp.status === 'connected') { const handleTabKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {
onDisconnect(dsp); if (e.key === 'Enter' || e.key === ' ') {
} else { e.preventDefault();
onConnect(dsp); onSelect();
} }
}; };
return ( return (
<button <div
type="button" className={[
className={ 'tab',
'tab' + active && 'tab--active',
(active ? ' tab--active' : '') + dimmed && 'tab--dimmed',
(dimmed ? ' tab--dimmed' : '') ]
} .filter(Boolean)
.join(' ')}
data-step={step} data-step={step}
tabIndex={0}
role="tab"
aria-selected={active}
onClick={onSelect} onClick={onSelect}
onKeyDown={handleTabKeyDown}
> >
<span <button
type="button"
className="tab-led" className="tab-led"
role="button" aria-label={
tabIndex={0} isConnected
onClick={handleLedClick} ? `Disconnect ${dsp.name}`
onKeyDown={(e) => { : `Connect ${dsp.name}`
if (e.key === 'Enter' || e.key === ' ') { }
e.preventDefault(); onClick={(e) => {
e.stopPropagation(); e.stopPropagation();
if (dsp.status === 'connected') { if (isConnected) {
onDisconnect(dsp); onDisconnect(dsp);
} else { } else {
onConnect(dsp); onConnect(dsp);
}
} }
}} }}
> >
<Led status={dsp.status} /> <Led status={dsp.status} />
</span> </button>
<span className="tab-name" title={dsp.name}> <span className="tab-name" title={dsp.name}>
{dsp.name} {dsp.name}
</span> </span>
<span <button
type="button"
className="tab-close" className="tab-close"
role="button"
tabIndex={0}
aria-label={`Remove ${dsp.name}`} aria-label={`Remove ${dsp.name}`}
onClick={(e) => { onClick={(e) => {
e.stopPropagation(); e.stopPropagation();
onRemove(); onRemove();
}} }}
onKeyDown={(e) => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
e.stopPropagation();
onRemove();
}
}}
> >
<CloseIcon /> <CloseIcon />
</span> </button>
</button> </div>
); );
} }