From 479d4a8c5b56cd1b4714bb3203f4ff8fb0dd2dd1 Mon Sep 17 00:00:00 2001 From: Alex Skrypnyk Date: Tue, 18 Jun 2024 00:16:39 +1000 Subject: [PATCH] Added `suffix`, `prefix` and `description_display` to `Fieldset`. --- .../__snapshots__/fieldset.test.js.snap | 391 ++++++++++++++++++ .../01-atoms/fieldset/fieldset.stories.js | 15 + components/01-atoms/fieldset/fieldset.test.js | 100 +++++ components/01-atoms/fieldset/fieldset.twig | 26 +- tests/jest.helpers.js | 6 +- 5 files changed, 533 insertions(+), 5 deletions(-) create mode 100644 components/01-atoms/fieldset/__snapshots__/fieldset.test.js.snap create mode 100644 components/01-atoms/fieldset/fieldset.test.js diff --git a/components/01-atoms/fieldset/__snapshots__/fieldset.test.js.snap b/components/01-atoms/fieldset/__snapshots__/fieldset.test.js.snap new file mode 100644 index 00000000..4837768d --- /dev/null +++ b/components/01-atoms/fieldset/__snapshots__/fieldset.test.js.snap @@ -0,0 +1,391 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Fieldset Component renders with additional attributes and classes 1`] = ` +
+ + + + +
+ + + +
+ + + + + + + +
+ + +
+ + +
+`; + +exports[`Fieldset Component renders with default values 1`] = ` +
+ + + + +
+ + + +
+ + + + + + + +
+ + +
+ + +
+`; + +exports[`Fieldset Component renders with description after 1`] = ` +
+ + + + +
+ + + +
+ + + + + + + + + +
+ + Test Description + +
+ +
+ + +
+ + +
+`; + +exports[`Fieldset Component renders with description before 1`] = ` +
+ + + + +
+ + + +
+ + + + +
+ + Test Description + +
+ + + + + + +
+ + +
+ + +
+`; + +exports[`Fieldset Component renders with fields 1`] = ` +
+ + + + +
+ + + +
+ + + + + +
+ + +
+ Test Field +
+ + +
+ + + + +
+ + +
+ + +
+`; + +exports[`Fieldset Component renders with invisible description 1`] = ` +
+ + + + +
+ + + +
+ + + + +
+ + Test Description + +
+ + + + + + +
+ + +
+ + +
+`; + +exports[`Fieldset Component renders with legend 1`] = ` +
+ + + + +
+ + + + + + + Test Legend + + + + +
+ + + + + + + +
+ + +
+ + +
+`; + +exports[`Fieldset Component renders with message 1`] = ` +
+ + + + +
+ + + +
+ + + + + +
+ + + + + + + + + Test Message + +
+ + + + + +
+ + +
+ + +
+`; + +exports[`Fieldset Component renders with prefix and suffix 1`] = ` +
+ + + + +
+ + + +
+ + + + +
+
+ Prefix +
+
+ + + + +
+
+ Suffix +
+
+ + + +
+ + +
+ + +
+`; diff --git a/components/01-atoms/fieldset/fieldset.stories.js b/components/01-atoms/fieldset/fieldset.stories.js index 4d5790ee..6330e233 100644 --- a/components/01-atoms/fieldset/fieldset.stories.js +++ b/components/01-atoms/fieldset/fieldset.stories.js @@ -6,6 +6,7 @@ export default { title: 'Atoms/Form Controls/Fieldset', parameters: { layout: 'centered', + storyLayoutSize: 'medium', }, }; @@ -23,6 +24,17 @@ export const Fieldset = (parentKnobs = {}) => { ), legend: knobText('Legend', 'Fieldset legend', parentKnobs.legend, parentKnobs.knobTab), description: knobText('Description', 'Fieldset example description', parentKnobs.description, parentKnobs.knobTab), + description_display: knobRadios( + 'Description display', + { + Before: 'before', + After: 'after', + Invisible: 'invisible', + }, + 'before', + parentKnobs.description_display, + parentKnobs.knobTab, + ), message: knobText('Message', 'Example message', parentKnobs.message, parentKnobs.knobTab), message_type: knobRadios( 'Type', @@ -36,8 +48,11 @@ export const Fieldset = (parentKnobs = {}) => { parentKnobs.message_type, parentKnobs.knobTab, ), + prefix: knobText('Prefix', '', parentKnobs.prefix, parentKnobs.knobTab), + suffix: knobText('Suffix', '', parentKnobs.suffix, parentKnobs.knobTab), is_required: knobBoolean('Required', true, parentKnobs.is_required, parentKnobs.knobTab), modifier_class: knobText('Additional class', '', parentKnobs.modifier_class, parentKnobs.knobTab), + attributes: knobText('Additional attributes', '', parentKnobs.attributes, parentKnobs.knobTab), }; const numberFields = knobNumber( diff --git a/components/01-atoms/fieldset/fieldset.test.js b/components/01-atoms/fieldset/fieldset.test.js new file mode 100644 index 00000000..256b7dbd --- /dev/null +++ b/components/01-atoms/fieldset/fieldset.test.js @@ -0,0 +1,100 @@ +const template = 'components/01-atoms/fieldset/fieldset.twig'; + +describe('Fieldset Component', () => { + test('renders with default values', async () => { + const c = await dom(template); + + expect(c.querySelectorAll('.ct-fieldset.ct-theme-light')).toHaveLength(1); + assertUniqueCssClasses(c); + }); + + test('renders with legend', async () => { + const c = await dom(template, { + legend: 'Test Legend', + }); + + expect(c.querySelectorAll('.ct-fieldset .ct-fieldset__legend')).toHaveLength(1); + expect(c.querySelector('.ct-fieldset .ct-fieldset__legend').textContent.trim()).toEqual('Test Legend'); + assertUniqueCssClasses(c); + }); + + test('renders with description before', async () => { + const c = await dom(template, { + description: 'Test Description', + description_display: 'before', + }); + + expect(c.querySelectorAll('.ct-fieldset .ct-fieldset__description--before')).toHaveLength(1); + expect(c.querySelector('.ct-fieldset .ct-fieldset__description--before').textContent.trim()).toEqual('Test Description'); + assertUniqueCssClasses(c); + }); + + test('renders with description after', async () => { + const c = await dom(template, { + description: 'Test Description', + description_display: 'after', + }); + + expect(c.querySelectorAll('.ct-fieldset .ct-fieldset__description--after')).toHaveLength(1); + expect(c.querySelector('.ct-fieldset .ct-fieldset__description--after').textContent.trim()).toEqual('Test Description'); + assertUniqueCssClasses(c); + }); + + test('renders with invisible description', async () => { + const c = await dom(template, { + description: 'Test Description', + description_display: 'invisible', + }); + + expect(c.querySelectorAll('.ct-fieldset .ct-fieldset__description--invisible.ct-visually-hidden')).toHaveLength(1); + expect(c.querySelector('.ct-fieldset .ct-fieldset__description--invisible.ct-visually-hidden').textContent.trim()).toEqual('Test Description'); + assertUniqueCssClasses(c); + }); + + test('renders with message', async () => { + const c = await dom(template, { + message: 'Test Message', + message_type: 'warning', + }); + + expect(c.querySelectorAll('.ct-fieldset .ct-fieldset__message')).toHaveLength(1); + expect(c.querySelector('.ct-fieldset .ct-fieldset__message').textContent.trim()).toEqual('Test Message'); + assertUniqueCssClasses(c); + }); + + test('renders with fields', async () => { + const c = await dom(template, { + fields: '
Test Field
', + }); + + expect(c.querySelectorAll('.ct-fieldset .ct-fieldset__fields')).toHaveLength(1); + expect(c.querySelector('.ct-fieldset .ct-fieldset__fields').innerHTML.trim()).toEqual('
Test Field
'); + assertUniqueCssClasses(c); + }); + + test('renders with prefix and suffix', async () => { + const c = await dom(template, { + prefix: '
Prefix
', + suffix: '
Suffix
', + }); + + expect(c.querySelectorAll('.ct-fieldset .ct-fieldset__prefix')).toHaveLength(1); + expect(c.querySelector('.ct-fieldset .ct-fieldset__prefix').innerHTML.trim()).toContain('Prefix'); + + expect(c.querySelectorAll('.ct-fieldset .ct-fieldset__suffix')).toHaveLength(1); + expect(c.querySelector('.ct-fieldset .ct-fieldset__suffix').innerHTML.trim()).toContain('Suffix'); + + assertUniqueCssClasses(c); + }); + + test('renders with additional attributes and classes', async () => { + const c = await dom(template, { + attributes: 'data-test="true"', + modifier_class: 'custom-modifier', + }); + + expect(c.querySelectorAll('.ct-fieldset.custom-modifier')).toHaveLength(1); + expect(c.querySelector('.ct-fieldset').getAttribute('data-test')).toEqual('true'); + assertUniqueCssClasses(c); + }); +}); diff --git a/components/01-atoms/fieldset/fieldset.twig b/components/01-atoms/fieldset/fieldset.twig index eae93487..8dd95c0e 100644 --- a/components/01-atoms/fieldset/fieldset.twig +++ b/components/01-atoms/fieldset/fieldset.twig @@ -7,6 +7,7 @@ * - theme: [string] Theme: light, dark. Optional. * - legend: [string] Legend for the fieldset. Optional. * - description: [string] Description for the fieldset. Optional. + * - description_display: [string] Description display: before, after, invisible. Default is before. Optional. * - message: [string] Message content. Optional. * - message_type: [string] Type of the message: error, warning, info, success. Default is error. * - fields: [string] Fields content. Optional. @@ -19,10 +20,11 @@ */ #} -{% set required_class = is_required ? 'ct-fieldset--required' : '' %} +{% set description_display = description_display in ['before', 'after', 'invisible'] ? description_display : 'before' %} {% set message_type = message_type|default('error') %} +{% set required_class = is_required ? 'ct-fieldset--required' : '' %} {% set theme_class = 'ct-theme-%s'|format(theme|default('light')) %} -{% set modifier_class = '%s %s %s %s %s %s'|format(theme_class, form_element_type_class, form_element_name_class, required_class, error_class, modifier_class|default('')) %} +{% set modifier_class = '%s %s %s'|format(theme_class, required_class, modifier_class|default('')) %}
{% if legend is not empty %} @@ -37,11 +39,11 @@ {% endif %}
- {% if description is not empty %} + {% if description is not empty and (description_display == 'before' or description_display == 'invisible') %} {% include '@atoms/paragraph/paragraph.twig' with { theme: theme, content: description, - modifier_class: 'ct-fieldset__description', + modifier_class: 'ct-fieldset__description ' ~ (description_display == 'invisible' ? 'ct-fieldset__description--invisible ct-visually-hidden' : 'ct-fieldset__description--before'), } only %} {% endif %} @@ -54,6 +56,10 @@ } only %} {% endif %} + {% if prefix is not empty %} +
{{ prefix }}
+ {% endif %} + {% block fields %} {% if fields is not empty %}
@@ -61,5 +67,17 @@
{% endif %} {% endblock %} + + {% if suffix is not empty %} +
{{ suffix }}
+ {% endif %} + + {% if description is not empty and description_display == 'after' %} + {% include '@atoms/paragraph/paragraph.twig' with { + theme: theme, + content: description, + modifier_class: 'ct-fieldset__description ct-fieldset__description--after', + } only %} + {% endif %}
diff --git a/tests/jest.helpers.js b/tests/jest.helpers.js index 1514d5d1..ac598219 100644 --- a/tests/jest.helpers.js +++ b/tests/jest.helpers.js @@ -9,7 +9,7 @@ Twig.extendFunction('source', (src) => { return fs.readFileSync(src, 'utf8'); }); -global.dom = async function (template, props, matchSnapshot = true) { +global.dom = async function (template, props = {}, matchSnapshot = true) { const { container } = await render(template, props, { base: 'components/00-base', atoms: 'components/01-atoms', @@ -33,7 +33,11 @@ global.assertUniqueCssClasses = function (element) { acc[cls] = (acc[cls] || 0) + 1; return acc; }, {}); + const duplicates = Object.entries(classOccurrences).filter(([, count]) => count > 1); expect(duplicates).toHaveLength(0); + + const undefinedClasses = classes.filter((cls) => cls === 'undefined'); + expect(undefinedClasses).toHaveLength(0); }); };