Skip to content

Commit f962a1c

Browse files
committed
fix(options): spread all option's presentation properties into option's root
1 parent 2c3a6c2 commit f962a1c

File tree

2 files changed

+75
-8
lines changed

2 files changed

+75
-8
lines changed

src/field/schema.ts

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -160,8 +160,7 @@ function convertToOptions(nodeOptions: JsfSchema[]): Array<FieldOption> {
160160
.map((schemaOption) => {
161161
const title = schemaOption.title
162162
const value = schemaOption.const
163-
const presentation = schemaOption['x-jsf-presentation']
164-
const meta = presentation?.meta
163+
const presentation = typeof schemaOption['x-jsf-presentation'] === 'object' ? schemaOption['x-jsf-presentation'] : {}
165164

166165
const result: {
167166
label: string
@@ -172,15 +171,10 @@ function convertToOptions(nodeOptions: JsfSchema[]): Array<FieldOption> {
172171
value,
173172
}
174173

175-
// Add meta if it exists
176-
if (meta) {
177-
result.meta = meta
178-
}
179-
180174
// Add other properties, without known ones we already handled above
181175
const { title: _, const: __, 'x-jsf-presentation': ___, ...rest } = schemaOption
182176

183-
return { ...result, ...rest }
177+
return { ...result, ...presentation, ...rest }
184178
})
185179
}
186180

test/fields.test.ts

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -441,6 +441,79 @@ describe('fields', () => {
441441
},
442442
])
443443
})
444+
445+
it('supports x-jsf-presentation properties inside options', () => {
446+
const schema: JsfSchema = {
447+
type: 'object',
448+
properties: {
449+
plan: {
450+
'type': 'string',
451+
'oneOf': [
452+
{ const: 'free', title: 'Free' },
453+
{ 'const': 'basic', 'title': 'Basic', 'x-jsf-presentation': { meta: { displayCost: '$30.00/mo', originalCost: '$35.00/mo' } } },
454+
{ 'const': 'standard', 'title': 'Standard', 'x-jsf-presentation': { meta: { displayCost: '$50.00/mo' }, recommended: true } },
455+
],
456+
'x-jsf-presentation': {
457+
inputType: 'radio',
458+
},
459+
},
460+
},
461+
}
462+
463+
const fields = buildFieldSchema(schema, 'root', true)!.fields!
464+
465+
expect(fields).toEqual([
466+
{
467+
inputType: 'radio',
468+
type: 'radio',
469+
jsonType: 'string',
470+
isVisible: true,
471+
name: 'plan',
472+
required: false,
473+
options: [
474+
{ label: 'Free', value: 'free' },
475+
{ label: 'Basic', value: 'basic', meta: { displayCost: '$30.00/mo', originalCost: '$35.00/mo' } },
476+
{ label: 'Standard', value: 'standard', meta: { displayCost: '$50.00/mo' }, recommended: true },
477+
],
478+
},
479+
])
480+
})
481+
482+
it('ignores a non-object x-jsf-presentation', () => {
483+
const schema: JsfSchema = {
484+
type: 'object',
485+
properties: {
486+
plan: {
487+
'type': 'string',
488+
'oneOf': [
489+
{ const: 'free', title: 'Free' },
490+
// @ts-expect-error - using an invalid value on purpose
491+
{ 'const': 'basic', 'title': 'Basic', 'x-jsf-presentation': '$30.00/mo' },
492+
],
493+
'x-jsf-presentation': {
494+
inputType: 'radio',
495+
},
496+
},
497+
},
498+
}
499+
500+
const fields = buildFieldSchema(schema, 'root', true)!.fields!
501+
502+
expect(fields).toEqual([
503+
{
504+
inputType: 'radio',
505+
type: 'radio',
506+
jsonType: 'string',
507+
isVisible: true,
508+
name: 'plan',
509+
required: false,
510+
options: [
511+
{ label: 'Free', value: 'free' },
512+
{ label: 'Basic', value: 'basic' },
513+
],
514+
},
515+
])
516+
})
444517
})
445518

446519
describe('input type calculation', () => {

0 commit comments

Comments
 (0)