Skip to content

Commit

Permalink
✨ [#52] Implement the preview of a selectboxes component
Browse files Browse the repository at this point in the history
When manual values are available, they are rendered as is and
their default value is taken into account.

When the variable data source is specified, a single option
is rendered to at least inform the form builder of the
expression being used.

In the future, we can possibly provide a 'variable' box so
that they can try out the preview with a realistic form
variable state.
  • Loading branch information
sergei-maertens committed Nov 17, 2023
1 parent 0d82260 commit 96eb381
Show file tree
Hide file tree
Showing 2 changed files with 120 additions and 1 deletion.
71 changes: 70 additions & 1 deletion src/components/ComponentPreview.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {expect} from '@storybook/jest';
import {Meta, StoryFn, StoryObj} from '@storybook/react';
import {userEvent, within} from '@storybook/testing-library';
import {fireEvent, userEvent, within} from '@storybook/testing-library';

import ComponentPreview from './ComponentPreview';

Expand Down Expand Up @@ -615,3 +615,72 @@ export const File: Story = {
await canvas.findByText('A preview of the file Formio component');
},
};

export const SelectBoxes: Story = {
name: 'Selectboxes manual values',
render: Template,

args: {
component: {
type: 'selectboxes',
id: 'selectboxes',
key: 'selectboxesPreview',
label: 'Selectboxes preview',
description: 'A preview of the selectboxes Formio component',
openForms: {
dataSrc: 'manual',
translations: {},
},
values: [
{
value: 'option1',
label: 'Option 1',
},
{
value: 'option2',
label: 'Option 2',
},
],
},
},

play: async ({canvasElement, args}) => {
const canvas = within(canvasElement);

// check that the user-controlled content is visible
await canvas.findByText('Selectboxes preview');
await canvas.findByText('A preview of the selectboxes Formio component');

// check that the input name is set correctly
const firstOptionInput = canvas.getByLabelText<HTMLInputElement>('Option 1');
// @ts-ignore
await expect(firstOptionInput.getAttribute('name').startsWith(args.component.key)).toBe(true);

// check the toggle state of a checkbox
await expect(firstOptionInput).not.toBeChecked();
// https://github.com/testing-library/user-event/issues/1149 applies to radio and
// checkbox inputs
fireEvent.click(canvas.getByText('Option 1'));
await expect(firstOptionInput).toBeChecked();
},
};

export const SelectBoxesVariable: Story = {
name: 'Selectboxes variable for values',
render: Template,

args: {
component: {
type: 'selectboxes',
id: 'selectboxes',
key: 'selectboxesPreview',
label: 'Selectboxes preview',
description: 'A preview of the selectboxes Formio component',
openForms: {
dataSrc: 'variable',
itemsExpression: {var: 'foo'},
translations: {},
},
},
},
};
50 changes: 50 additions & 0 deletions src/registry/selectboxes/preview.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import {SelectboxesComponentSchema} from '@open-formulieren/types';
import {useIntl} from 'react-intl';

import {SelectBoxes} from '@/components/formio';

import {ComponentPreviewProps} from '../types';
import {checkIsManualOptions} from './helpers';

/**
* Show a formio selectboxes component preview.
*
* NOTE: for the time being, this is rendered in the default Formio bootstrap style,
* however at some point this should use the components of
* @open-formulieren/formio-renderer instead for a more accurate preview.
*/
const Preview: React.FC<ComponentPreviewProps<SelectboxesComponentSchema>> = ({component}) => {
const intl = useIntl();
const {key, label, description, tooltip, validate} = component;
const {required = false} = validate || {};
const isManualOptions = checkIsManualOptions(component);
const options = isManualOptions
? component.values || []
: [
{
value: 'itemsExpression',
label: intl.formatMessage(
{
description: 'Selectboxes dummy option for itemsExpression',
defaultMessage: 'Options from expression: <code>{expression}</code>',
},
{
expression: JSON.stringify(component.openForms.itemsExpression),
code: chunks => <code>{chunks}</code>,
}
),
},
];
return (
<SelectBoxes
name={key}
options={options}
label={label}
tooltip={tooltip}
required={required}
description={description}
/>
);
};

export default Preview;

0 comments on commit 96eb381

Please sign in to comment.