openpencil/packages/dom-css/tests/behaviours/controls.test.ts
Danila Poyarkov b5a5b41523
feat(storybook): give components with behaviours their own story controls (#961)
* feat(storybook): give components with behaviours their own story controls

A Switch exported to Storybook showed a State select with On and Off. A variant property drawn by a behaviour's boolean value now becomes a boolean control named as Reka and Radix name the prop (checked, pressed, open, disabled), the interaction-state property leaves the controls, and each state stays a story. behaviourArgs in dom-css reads these props, so generated components can take the same API later.

* fix(dom-css): import behaviour args by module so packed builds resolve it

The #dom-css/* import maps to dist files when packed, which have no directory index, so #dom-css/behaviours failed to load in a consumer install.
2026-10-07 20:06:17 +00:00

63 lines
2.1 KiB
TypeScript

import { describe, expect, test } from 'bun:test'
import { behaviourControls, booleanOf } from '#dom-css/behaviours/controls'
import { controlRoles } from '#dom-css/behaviours/roles'
import { emptyBehaviour, SceneGraph, withBehaviour } from '@open-pencil/scene-graph'
/** A Switch set (State) and a card frame holding an On instance named Wifi. */
function switchCard() {
const graph = new SceneGraph()
const pageId = graph.getPages()[0].id
const set = graph.createNode('COMPONENT_SET', pageId, {
name: 'Switch',
componentPropertyDefinitions: [
{
id: 'state',
name: 'State',
type: 'VARIANT',
defaultValue: 'Off',
variantOptions: ['Off', 'On']
}
]
})
graph.createNode('COMPONENT', set.id, {
name: 'State=Off',
componentPropertyValues: { State: 'Off' }
})
const on = graph.createNode('COMPONENT', set.id, {
name: 'State=On',
componentPropertyValues: { State: 'On' }
})
graph.updateNode(set.id, {
pluginData: withBehaviour(set, {
...emptyBehaviour('switch'),
booleans: { value: { propertyId: 'state', on: 'On', off: 'Off' } }
})
})
const card = graph.createNode('FRAME', pageId, { name: 'Card' })
const instance = graph.createInstance(on.id, card.id)
if (!instance) throw new Error('No instance')
graph.updateNode(instance.id, { name: 'Wifi' })
return { graph, card }
}
describe('behaviour controls', () => {
test('finds the controls below a root by layer path with the values their design shows', () => {
const { graph, card } = switchCard()
const controls = behaviourControls(graph, card.id)
expect([...controls.keys()]).toEqual(['Wifi'])
const control = controls.get('Wifi')
expect(control?.kind).toBe('switch')
expect(control && booleanOf(control, 'value')?.designed).toBe(true)
expect(control && booleanOf(control, 'open')).toBeUndefined()
})
test('gives a control root its role by layer path', () => {
const { graph, card } = switchCard()
const roles = controlRoles(behaviourControls(graph, card.id))
expect(roles.get('Wifi')?.type).toBe('root')
expect(roles.size).toBe(1)
})
})