Skip to content

Commit 4b244f7

Browse files
Bill LeoutsakosBill Leoutsakos
authored andcommitted
fix(design): apply Studio states only to enabled variants
1 parent 3e1f864 commit 4b244f7

5 files changed

Lines changed: 54 additions & 6 deletions

File tree

‎scripts/design-studio/README.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
- `variants` lists the axes that the adapter forwards to that export. New values on a covered axis appear automatically. A new axis requires review and a mapping; spreading variant props does not establish coverage. Axes requiring different data shapes need their own fixture data before being listed.
1212
- `states` lists supported focus, disabled, error, and open states. Open captures require a visible popup or dialog.
13+
- Disabled variant values retain their default preview but omit open and focus states; combined live selections apply the same restriction.
1314
- `defaultStates` opens otherwise hidden exports, such as tooltip content or a wizard step, for their default specimen.
1415
- `requiredElements` identifies a visible element belonging to a hidden or nested export. Use a unique fixture marker when a generic role could match its parent.
1516

‎scripts/design-studio/refresh.mjs‎

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -291,12 +291,21 @@ function componentInventory() {
291291
const supportsVariant = Boolean(
292292
fixture && fixtureContracts.variants?.[item.name]?.includes(axis.name)
293293
)
294+
const disabled = axis.name === 'disabled' && value === 'true'
295+
const variantFixture = supportsVariant
296+
? { ...fixture, variant: { axis: axis.name, value } }
297+
: null
298+
if (disabled && ['open', 'focus'].includes(variantFixture?.defaultState))
299+
variantFixture.defaultState = undefined
294300
entries.push({
295301
...base,
296302
id: `component:${item.name}:${axis.name}=${value}`,
297303
name: `${item.name} · ${axis.name}: ${value}`,
298304
variant: { axis: axis.name, value, defaultValue: axis.defaultValue },
299-
fixture: supportsVariant ? { ...fixture, variant: { axis: axis.name, value } } : null,
305+
fixture: variantFixture,
306+
states: disabled
307+
? base.states.filter((state) => state !== 'open' && state !== 'focus')
308+
: base.states,
300309
status: supportsVariant ? 'pending-capture' : 'needs-fixture',
301310
images: {},
302311
})

‎scripts/design-studio/refresh.test.mjs‎

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,38 @@ test('refresh requires a fixture mapping for each variant axis', () => {
139139
)
140140
}, 60000)
141141

142+
test('refresh keeps disabled variant previews without impossible interaction captures', () => {
143+
const { repo, refresh } = guardedRefresh()
144+
write(
145+
repo,
146+
'packages/emcn/src/components/example/example.tsx',
147+
'export const Example = ({disabled}: {disabled?: boolean}) => <button disabled={disabled} />\n'
148+
)
149+
write(
150+
repo,
151+
'tools/design-studio/_components/fixture-contracts.json',
152+
JSON.stringify({
153+
variants: { Example: ['disabled'] },
154+
states: { Example: ['open', 'focus', 'disabled'] },
155+
defaultStates: { Example: 'open' },
156+
})
157+
)
158+
const manifest = refresh()
159+
const enabled = manifest.components.find(
160+
(entry) => entry.id === 'component:Example:disabled=false'
161+
)
162+
const disabled = manifest.components.find(
163+
(entry) => entry.id === 'component:Example:disabled=true'
164+
)
165+
assert.deepEqual(enabled.states, ['open', 'focus', 'disabled'])
166+
assert.equal(enabled.fixture.defaultState, 'open')
167+
assert.deepEqual(disabled.states, ['disabled'])
168+
assert.equal(disabled.fixture.defaultState, undefined)
169+
assert.deepEqual(disabled.fixture.variant, { axis: 'disabled', value: 'true' })
170+
assert.equal(disabled.status, 'pending-capture')
171+
assert.deepEqual(disabled.images, {})
172+
}, 60000)
173+
142174
test('refresh publishes unresolved analysis and scanner limits separately from inspection failures', () => {
143175
const { refresh } = guardedRefresh()
144176
const manifest = refresh()

‎tools/design-studio/_components/fixture-contracts.json‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,6 @@
9090
"ChipSelect": ["open"],
9191
"Combobox": ["open"],
9292
"TimePicker": ["open"],
93-
"ChipTimePicker": ["open"],
9493
"ChipCombobox": ["open"]
9594
},
9695
"defaultStates": {

‎tools/design-studio/_components/generated-gallery.tsx‎

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -607,8 +607,11 @@ function TreatmentDetail({
607607
activeVariants[axis] = value
608608
}
609609
}
610-
const stateAvailable =
611-
requestedState === 'default' || Boolean(entry.states?.includes(requestedState))
610+
const disabled = activeVariants.disabled === 'true'
611+
const effectiveStates = disabled
612+
? (entry.states ?? []).filter((state) => state !== 'open' && state !== 'focus')
613+
: (entry.states ?? [])
614+
const stateAvailable = requestedState === 'default' || effectiveStates.includes(requestedState)
612615
const previewState = stateAvailable ? requestedState : 'default'
613616
const selectedKey = `${theme}-${size}${previewState === 'default' ? '' : `-${previewState}`}`
614617
const failedCount = entries.filter((item) => item.status !== 'ready').length
@@ -626,13 +629,17 @@ function TreatmentDetail({
626629
theme,
627630
size: String(size),
628631
state:
629-
previewState === 'default' ? (entry.fixture.defaultState ?? previewState) : previewState,
632+
previewState === 'default'
633+
? disabled && ['open', 'focus'].includes(entry.fixture.defaultState ?? '')
634+
? previewState
635+
: (entry.fixture.defaultState ?? previewState)
636+
: previewState,
630637
...(entry.kind === 'component' ? { interactive: '1' } : {}),
631638
...(Object.keys(activeVariants).length ? { variants: JSON.stringify(activeVariants) } : {}),
632639
...(entry.fixture.sample ? { sample: JSON.stringify(entry.fixture.sample) } : {}),
633640
...(entry.fixture.action ? { action: entry.fixture.action } : {}),
634641
...(entry.fixture.requiredElement ? { required: entry.fixture.requiredElement } : {}),
635-
...(entry.states?.includes('open') ? { 'open-surface': '1' } : {}),
642+
...(effectiveStates.includes('open') ? { 'open-surface': '1' } : {}),
636643
}).toString()
637644
: null
638645

0 commit comments

Comments
 (0)