Skip to content

Commit 7a88c2a

Browse files
committed
fix: static-text fields should not show expression toggles
1 parent 8786599 commit 7a88c2a

4 files changed

Lines changed: 71 additions & 2 deletions

File tree

‎webui/src/Components/ListInputField.tsx‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,8 @@ export const ListInputField = observer(function ListInputField({
224224
const cellRaw = row[field.id]
225225
const cell = normaliseCell(cellRaw)
226226
const inputId = `${baseId}-${rowIndex}-${field.id}`
227-
const canExpression = fieldSupportsExpression && !field.disableAutoExpression
227+
const canExpression =
228+
fieldSupportsExpression && !field.disableAutoExpression && field.type !== 'static-text'
228229

229230
const setCell = (newCell: ExpressionOrValue<JsonValue | undefined>) =>
230231
updateCell(rowIndex, field.id, newCell)

‎webui/src/Components/__tests__/ListInputField.test.tsx‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,23 @@ describe('ListInputField', () => {
392392
expect(screen.getAllByRole('button', { name: /expression mode|value mode/i })).toHaveLength(2)
393393
})
394394

395+
it('does not render an expression toggle for static-text fields', () => {
396+
render(
397+
<Controlled
398+
definition={{
399+
...definition,
400+
fields: [
401+
{ id: 'note', type: 'static-text', label: 'Attention', value: 'Read me' },
402+
{ id: 'value', type: 'number', label: 'Value', min: 0, max: 100, step: 1, default: 0 },
403+
],
404+
}}
405+
initialValue={[{ value: val(50) }]}
406+
fieldSupportsExpression={true}
407+
/>
408+
)
409+
expect(screen.getAllByRole('button', { name: /expression mode|value mode/i })).toHaveLength(1)
410+
})
411+
395412
it('calls setValue with an expression cell when the toggle is activated', async () => {
396413
const setValue = vi.fn()
397414
const user = userEvent.setup()

‎webui/src/Controls/OptionsInputField.tsx‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,8 @@ export const OptionsInputField = observer(function OptionsInputField({
130130
/>
131131
)
132132

133-
if (fieldSupportsExpression && option.type !== 'expression') {
133+
// Static text has no value to drive with an expression
134+
if (fieldSupportsExpression && option.type !== 'expression' && option.type !== 'static-text') {
134135
const rawExpressionValue = rawValue || { isExpression: false, value: undefined }
135136

136137
control = (
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import { render, screen } from '@testing-library/react'
2+
import { describe, expect, it } from 'vitest'
3+
import type { SomeCompanionInputField } from '@companion-app/shared/Model/Options.js'
4+
import { Grid } from '~/Components/Grid.js'
5+
import { MenuPortalContext } from '~/Components/MenuPortalContext.js'
6+
import { RootAppStoreContext, type RootAppStore } from '~/Stores/RootAppStore.js'
7+
import { OptionsInputField } from '../OptionsInputField.js'
8+
9+
const mockStore: Partial<RootAppStore> = {
10+
variablesStore: {
11+
allVariableDefinitions: { get: () => [] },
12+
} as unknown as RootAppStore['variablesStore'],
13+
}
14+
15+
function renderField(option: SomeCompanionInputField, fieldSupportsExpression: boolean) {
16+
return render(
17+
<RootAppStoreContext.Provider value={mockStore as RootAppStore}>
18+
<MenuPortalContext.Provider value={document.body}>
19+
<Grid.Row>
20+
<OptionsInputField
21+
allowInternalFields={false}
22+
isLocatedInGrid={false}
23+
entityType={null}
24+
option={option}
25+
value={undefined}
26+
setValue={() => {}}
27+
visibility={true}
28+
localVariablesStore={null}
29+
fieldSupportsExpression={fieldSupportsExpression}
30+
/>
31+
</Grid.Row>
32+
</MenuPortalContext.Provider>
33+
</RootAppStoreContext.Provider>
34+
)
35+
}
36+
37+
const toggleName = /expression mode|value mode/i
38+
39+
describe('OptionsInputField', () => {
40+
it('renders an expression toggle for a value field when expressions are supported', () => {
41+
renderField({ id: 'text', type: 'textinput', label: 'Text', default: '' }, true)
42+
expect(screen.getByRole('button', { name: toggleName })).toBeInTheDocument()
43+
})
44+
45+
it('does not render an expression toggle for a static-text field', () => {
46+
renderField({ id: 'note', type: 'static-text', label: 'Attention', value: 'Read me' }, true)
47+
expect(screen.getByText('Read me')).toBeInTheDocument()
48+
expect(screen.queryByRole('button', { name: toggleName })).toBeNull()
49+
})
50+
})

0 commit comments

Comments
 (0)