From c78498413e31eb77045c99da1cc1a417cffa626a Mon Sep 17 00:00:00 2001 From: Alan Cole Date: Wed, 18 Dec 2024 17:14:35 +1100 Subject: [PATCH] [CIVIC-1947] Removed unused storybook utils. --- components/00-base/menu/menu.utils.js | 74 ---------------- .../00-base/storybook/storybook.docs.utils.js | 26 ------ .../storybook/storybook.docs.utils.test.js | 44 ---------- .../storybook/storybook.helpers.utils.js | 59 ------------- .../storybook/storybook.helpers.utils.test.js | 84 ------------------- .../storybook/storybook.layout.utils.js | 33 -------- .../storybook/storybook.layout.utils.test.js | 40 --------- .../00-base/storybook/storybook.utils.js | 10 --- components/02-molecules/field/field.utils.js | 28 ------- .../03-organisms/slider/slider.utils.js | 76 ----------------- 10 files changed, 474 deletions(-) delete mode 100644 components/00-base/menu/menu.utils.js delete mode 100644 components/00-base/storybook/storybook.docs.utils.js delete mode 100644 components/00-base/storybook/storybook.docs.utils.test.js delete mode 100644 components/00-base/storybook/storybook.helpers.utils.js delete mode 100644 components/00-base/storybook/storybook.helpers.utils.test.js delete mode 100644 components/00-base/storybook/storybook.layout.utils.js delete mode 100644 components/00-base/storybook/storybook.layout.utils.test.js delete mode 100644 components/00-base/storybook/storybook.utils.js delete mode 100644 components/02-molecules/field/field.utils.js delete mode 100644 components/03-organisms/slider/slider.utils.js diff --git a/components/00-base/menu/menu.utils.js b/components/00-base/menu/menu.utils.js deleted file mode 100644 index dade132c..00000000 --- a/components/00-base/menu/menu.utils.js +++ /dev/null @@ -1,74 +0,0 @@ -/** - * @file - * Menu component utilities. - */ - -/* eslint-disable camelcase */ - -import { knobBoolean, knobNumber, randomBool, randomUrl } from '../storybook/storybook.utils'; - -export function generateMenuLinks(count, levels, isActiveTrail, title = 'Item', titleCb = null, currentLevel = 1, parents = []) { - const links = []; - - title = title || 'Item'; - currentLevel = currentLevel || 1; - parents = parents || []; - - titleCb = typeof titleCb === 'function' ? titleCb : function (itemTitle, itemIndex, itemCurrentLevel, itemIsActiveTrail, itemParents) { - return `${itemTitle} ${itemParents.join('')}${itemIndex}`; - }; - - const activeTrailIdx = isActiveTrail ? Math.floor(Math.random() * count) : null; - - for (let i = 1; i <= count; i++) { - const link = { - title: titleCb(title, i, currentLevel, isActiveTrail, parents), - url: randomUrl(), - }; - - if (activeTrailIdx === i) { - link.in_active_trail = true; - } - - if (currentLevel < levels) { - link.below = generateMenuLinks(count, levels, activeTrailIdx === i, title, titleCb, currentLevel + 1, parents.concat([i])); - link.is_expanded = randomBool(0.5); - } - - links.push(link); - } - - return links; -} - -export default function getMenuLinks(parentKnobs = {}, titleCb = null) { - const linksPerLevel = knobNumber( - 'Links per level', - 3, - { - range: true, - min: 0, - max: 5, - step: 1, - }, - parentKnobs.links_per_level, - parentKnobs.knobTab, - ); - - const levels = knobNumber( - 'Number of levels', - 3, - { - range: true, - min: 1, - max: 5, - step: 1, - }, - parentKnobs.number_of_levels, - parentKnobs.knobTab, - ); - - const activeTrail = knobBoolean('Show active trail (random)', false, parentKnobs.show_active_trail, parentKnobs.knobTab); - - return generateMenuLinks(linksPerLevel, levels, activeTrail, null, titleCb); -} diff --git a/components/00-base/storybook/storybook.docs.utils.js b/components/00-base/storybook/storybook.docs.utils.js deleted file mode 100644 index 289f8480..00000000 --- a/components/00-base/storybook/storybook.docs.utils.js +++ /dev/null @@ -1,26 +0,0 @@ -// -// Custom docs decorators. -// - -export const decoratorDocs = (content, context) => { - if (context.parameters.docs) { - const size = ['small', 'medium', 'large', 'fluid'].includes(context.parameters.docsSize) ? context.parameters.docsSize : 'fluid'; - - let classes = [ - 'story-docs', - `story-docs-size--${size}`, - ].filter(Boolean).join(' '); - - if (context.parameters.docsClass) { - classes += ` ${context.parameters.docsClass}`; - } - - if (context.parameters.docsPlacement === 'after') { - content = `${typeof content === 'function' ? content() : content}
${context.parameters.docs}
`; - } else { - content = `
${context.parameters.docs}
${typeof content === 'function' ? content() : content}`; - } - } - - return typeof content === 'function' ? content() : content; -}; diff --git a/components/00-base/storybook/storybook.docs.utils.test.js b/components/00-base/storybook/storybook.docs.utils.test.js deleted file mode 100644 index 4201f59a..00000000 --- a/components/00-base/storybook/storybook.docs.utils.test.js +++ /dev/null @@ -1,44 +0,0 @@ -import { jest } from '@jest/globals'; -import { decoratorDocs } from './storybook.docs.utils'; - -describe('decoratorDocs', () => { - const mockContent = jest.fn(() => '
Content
'); - - test.each([ - [ - { parameters: { docs: '

Documentation

', docsSize: 'large', docsClass: 'custom-class' } }, - '

Documentation

Content
', - ], - [ - { parameters: { docs: '

Documentation

', docsSize: 'small', docsPlacement: 'after' } }, - '
Content

Documentation

', - ], - [ - { parameters: { docs: '

Documentation

', docsPlacement: 'before' } }, - '

Documentation

Content
', - ], - [ - { parameters: { docs: '

Documentation

' } }, - '

Documentation

Content
', - ], - [ - { parameters: {} }, - '
Content
', - ], - ])('wraps content correctly based on context parameters', (context, expected) => { - const result = decoratorDocs(mockContent, context); - expect(result).toBe(expected); - }); - - test('returns content without wrapping when docs parameter is not present', () => { - const context = { parameters: {} }; - const result = decoratorDocs(mockContent, context); - expect(result).toBe('
Content
'); - }); - - test('includes additional classes from docsClass parameter', () => { - const context = { parameters: { docs: '

Documentation

', docsClass: 'additional-class' } }; - const result = decoratorDocs(mockContent, context); - expect(result).toContain('additional-class'); - }); -}); diff --git a/components/00-base/storybook/storybook.helpers.utils.js b/components/00-base/storybook/storybook.helpers.utils.js deleted file mode 100644 index 140bb8a4..00000000 --- a/components/00-base/storybook/storybook.helpers.utils.js +++ /dev/null @@ -1,59 +0,0 @@ -// -// Generic helper utilities for all Storybook stories. -// - -export const arrayCombine = function (keys, values) { - const obj = {}; - - if (!keys || !values || keys.constructor !== Array || values.constructor !== Array) { - return false; - } - - if (keys.length !== values.length) { - return false; - } - - for (let i = 0; i < keys.length; i++) { - obj[keys[i]] = values[i]; - } - - return obj; -}; - -export const objectFromArray = (array) => { - const obj = {}; - array.forEach((item) => { - obj[item] = item; - }); - return obj; -}; - -export const capitalizeFirstLetter = (string) => string.charAt(0) - .toUpperCase() + string.slice(1); - -export const cleanCssIdentifier = function (string) { - return string.toLowerCase() - .replace(/_/, '-') - .replace(/(&\w+?;)/gim, ' ') - .replace(/[_.~"<>%|'!*();:@&=+$,/?%#[\]{}\n`^\\]/gim, '') - .replace(/(^\s+)|(\s+$)/gim, '') - .replace(/\s+/gm, '-'); -}; - -export const toLabels = function (values) { - const arr = []; - for (const i in values) { - arr.push(capitalizeFirstLetter(values[i].replace(/[-_]/, ' '))); - } - return arr; -}; - -export const dateIsValid = function (date) { - return !Number.isNaN(Date.parse(date)); -}; - -export const convertDate = (date) => new Date(date).toLocaleDateString('en-uk', { - year: 'numeric', - month: 'short', - day: 'numeric', -}); diff --git a/components/00-base/storybook/storybook.helpers.utils.test.js b/components/00-base/storybook/storybook.helpers.utils.test.js deleted file mode 100644 index a14dc0bd..00000000 --- a/components/00-base/storybook/storybook.helpers.utils.test.js +++ /dev/null @@ -1,84 +0,0 @@ -import { arrayCombine, objectFromArray, capitalizeFirstLetter, cleanCssIdentifier, toLabels, dateIsValid, convertDate } from './storybook.helpers.utils'; - -describe('Helper Utilities', () => { - describe('arrayCombine', () => { - test.each([ - [['a', 'b'], [1, 2], { a: 1, b: 2 }], - [['key1', 'key2'], ['value1', 'value2'], { key1: 'value1', key2: 'value2' }], - [['key'], ['value'], { key: 'value' }], - ])('combines arrays %s and %s into %s', (keys, values, expected) => { - expect(arrayCombine(keys, values)).toEqual(expected); - }); - - test.each([ - [['a'], null, false], - [null, [1], false], - [['a'], [1, 2], false], - [['a', 'b'], [1], false], - ])('returns false for invalid inputs %s and %s', (keys, values, expected) => { - expect(arrayCombine(keys, values)).toBe(expected); - }); - }); - - describe('objectFromArray', () => { - test.each([ - [['a', 'b', 'c'], { a: 'a', b: 'b', c: 'c' }], - [['key1', 'key2'], { key1: 'key1', key2: 'key2' }], - [[], {}], - ])('creates object from array %s as %s', (array, expected) => { - expect(objectFromArray(array)).toEqual(expected); - }); - }); - - describe('capitalizeFirstLetter', () => { - test.each([ - ['hello', 'Hello'], - ['world', 'World'], - ['a', 'A'], - ['', ''], - ])('capitalizes the first letter of %s to %s', (input, expected) => { - expect(capitalizeFirstLetter(input)).toBe(expected); - }); - }); - - describe('cleanCssIdentifier', () => { - test.each([ - ['example identifier', 'example-identifier'], - ['Hello World!', 'hello-world'], - ['CSS_Identifier', 'css-identifier'], - ['CSS&Identifier', 'cssidentifier'], - ])('cleans the CSS identifier %s to %s', (input, expected) => { - expect(cleanCssIdentifier(input)).toBe(expected); - }); - }); - - describe('toLabels', () => { - test.each([ - [['example_identifier', 'another_example'], ['Example identifier', 'Another example']], - [['hello-world', 'test_label'], ['Hello world', 'Test label']], - ])('converts %s to labels %s', (values, expected) => { - expect(toLabels(values)).toEqual(expected); - }); - }); - - describe('dateIsValid', () => { - test.each([ - ['2021-12-31', true], - ['31/12/2021', false], - ['invalid-date', false], - [null, false], - ['', false], - ])('checks if %s is a valid date: %s', (date, expected) => { - expect(dateIsValid(date)).toBe(expected); - }); - }); - - describe('convertDate', () => { - test.each([ - ['2021-12-31', '31 Dec 2021'], - ['2020-01-01', '1 Jan 2020'], - ])('converts date %s to %s', (date, expected) => { - expect(convertDate(date)).toBe(expected); - }); - }); -}); diff --git a/components/00-base/storybook/storybook.layout.utils.js b/components/00-base/storybook/storybook.layout.utils.js deleted file mode 100644 index a4401321..00000000 --- a/components/00-base/storybook/storybook.layout.utils.js +++ /dev/null @@ -1,33 +0,0 @@ -// -// Custom story decorators. -// - -export const decoratorStoryLayout = (content, context) => { - const shouldWrap = Object.keys(context.parameters) - .some((key) => key.startsWith('storyLayout')); - - if (!shouldWrap) { - return content(); - } - - const size = ['small', 'medium', 'large'].includes(context.parameters.storyLayoutSize) ? context.parameters.storyLayoutSize : 'medium'; - - const isCentered = context.parameters.layout === 'centered'; - - let classes = [ - 'story-layout', - `story-layout-size--${size}`, - context.parameters.storyLayoutCenteredVertically || isCentered ? 'story-layout--centered-vertically' : '', - context.parameters.storyLayoutIsContainer ? 'story-layout--container' : '', - context.parameters.storyLayoutIsResizable && (context.globals.resizer || false) ? 'story-layout--resizable' : '', - ].filter(Boolean).join(' '); - - if (context.parameters.storyLayoutClass) { - classes += ` ${context.parameters.storyLayoutClass}`; - } - - context.parameters.storyLayoutHtmlBefore = context.parameters.storyLayoutHtmlBefore || ''; - context.parameters.storyLayoutHtmlAfter = context.parameters.storyLayoutHtmlAfter || ''; - - return `
${context.parameters.storyLayoutHtmlBefore}${content()}${context.parameters.storyLayoutHtmlAfter}
`; -}; diff --git a/components/00-base/storybook/storybook.layout.utils.test.js b/components/00-base/storybook/storybook.layout.utils.test.js deleted file mode 100644 index be639406..00000000 --- a/components/00-base/storybook/storybook.layout.utils.test.js +++ /dev/null @@ -1,40 +0,0 @@ -import { jest } from '@jest/globals'; -import { decoratorStoryLayout } from './storybook.layout.utils'; - -describe('decoratorStoryLayout', () => { - const mockContent = jest.fn(() => '
Content
'); - - test.each([ - [ - { parameters: { storyLayoutSize: 'large', layout: 'centered', storyLayoutClass: 'custom-class' }, globals: {} }, - '
Content
', - ], - [ - { parameters: { storyLayoutSize: 'medium', storyLayoutIsContainer: true, storyLayoutHtmlBefore: '

Before

', storyLayoutHtmlAfter: '

After

' }, globals: {} }, - '

Before

Content

After

', - ], - [ - { parameters: { layout: 'centered', storyLayoutIsResizable: true }, globals: { resizer: true } }, - '
Content
', - ], - [ - { parameters: {}, globals: {} }, - '
Content
', - ], - ])('wraps content correctly based on context parameters', (context, expected) => { - const result = decoratorStoryLayout(mockContent, context); - expect(result).toBe(expected); - }); - - test('returns content without wrapping when storyLayout parameter is not present', () => { - const context = { parameters: {}, globals: {} }; - const result = decoratorStoryLayout(mockContent, context); - expect(result).toBe('
Content
'); - }); - - test('includes additional classes from storyLayoutClass parameter', () => { - const context = { parameters: { storyLayoutClass: 'additional-class' }, globals: {} }; - const result = decoratorStoryLayout(mockContent, context); - expect(result).toContain('additional-class'); - }); -}); diff --git a/components/00-base/storybook/storybook.utils.js b/components/00-base/storybook/storybook.utils.js deleted file mode 100644 index 227dbac1..00000000 --- a/components/00-base/storybook/storybook.utils.js +++ /dev/null @@ -1,10 +0,0 @@ -// -// Centralised utilities for all Storybook stories. -// - -export * from './storybook.helpers.utils'; -export * from './storybook.docs.utils'; -export * from './storybook.layout.utils'; -export * from './storybook.random.utils'; -export * from './storybook.generators.utils'; -export * from './storybook.knobs.utils'; diff --git a/components/02-molecules/field/field.utils.js b/components/02-molecules/field/field.utils.js deleted file mode 100644 index 55c366c3..00000000 --- a/components/02-molecules/field/field.utils.js +++ /dev/null @@ -1,28 +0,0 @@ -import { KnobValues, randomArrayItem } from '../../00-base/storybook/storybook.utils'; -import { Field } from './field.stories'; - -export const randomFields = (count, theme, rand, defaultInputType) => { - rand = rand || false; - - const inputTypes = [ - 'textfield', - 'textarea', - 'select', - 'radio', - 'checkbox', - ]; - - const fields = []; - for (let i = 0; i < count; i++) { - const inputType = defaultInputType || randomArrayItem(inputTypes); - fields.push(Field(new KnobValues({ - theme, - type: inputType, - description: null, - message: null, - orientation: 'vertical', - }))); - } - - return fields; -}; diff --git a/components/03-organisms/slider/slider.utils.js b/components/03-organisms/slider/slider.utils.js deleted file mode 100644 index 2ca2a318..00000000 --- a/components/03-organisms/slider/slider.utils.js +++ /dev/null @@ -1,76 +0,0 @@ -/** - * @file - * Slider component utilities. - */ - -import { dateIsValid, demoImage, randomBool, randomInt, randomString, randomText, randomUrl } from '../../00-base/storybook/storybook.utils'; -import CivicThemeSlide from './slide.twig'; -import CivicThemeTag from '../../01-atoms/tag/tag.twig'; -import CivicThemeButton from '../../01-atoms/button/button.twig'; - -export const randomTagsComponent = (count, theme) => { - const tags = []; - for (let i = 0; i < count; i++) { - tags.push(CivicThemeTag({ - theme, - text: randomString(randomInt(3, 8)), - })); - } - return tags; -}; - -export const randomButtonsComponent = (count, theme) => { - const buttons = []; - for (let i = 0; i < count; i++) { - buttons.push(CivicThemeButton({ - theme, - kind: 'button', - text: randomString(randomInt(3, 8)), - type: ['primary', 'secondary', 'tertiary'][randomInt(0, 2)], - url: randomUrl(), - })); - } - return buttons; -}; - -export const randomSlidesComponent = (count, theme, rand, template) => { - const slides = []; - - const inverseTheme = theme === 'dark' ? 'dark' : 'light'; - - for (let i = 0; i < count; i++) { - const image = template && template.image ? template.image : { - url: demoImage(), - alt: randomText(4), - }; - const imagePosition = template && template.image_position ? template.image_position : 'right'; - const tags = template && template.tags ? template.tags : {}; - const date = template && template.date ? template.date : '20 Jan 2023 11:00'; - const dateEnd = template && template.date_end ? template.date_end : null; - const title = template && template.title ? template.title : `Title ${i + 1}${rand ? ` ${randomString(randomInt(5, 30))}` : ''}`; - const url = template && template.url ? template.url : (randomBool() ? randomUrl() : null); - const content = template && template.content ? template.content : `Content ${i + 1}${rand ? ` ${randomString(randomInt(5, 250))}` : ''}`; - const links = template && template.links ? template.links : randomButtonsComponent(randomInt(0, 4), inverseTheme).join(''); - const attributes = template && template.attributes ? template.attributes : ''; - - const dateIso = dateIsValid(date) ? new Date(date).toISOString() : null; - const dateEndIso = dateIsValid(dateEnd) ? new Date(dateEnd).toISOString() : null; - - slides.push(CivicThemeSlide({ - theme, - image, - image_position: imagePosition, - tags, - date, - date_iso: dateIso, - date_end: dateEnd, - date_end_iso: dateEndIso, - title, - url, - content, - links, - attributes, - })); - } - return slides; -};