Skip to content

Commit

Permalink
Shadow Panel: Generates unique shadow slugs by finding max suffix and…
Browse files Browse the repository at this point in the history
… incrementing it (#61997)

* Add function to generate unique shadow slugs by finding max suffix and incrementing it

* Created a generic function getNewIndexFromPresets that returns the next available index.

* Adds JSdoc to getNewIndexFromPresets

* Add unit tests for getNewIndexFromPresets function

* Refactor getNewIndexFromPresets function to improve readability.

Co-authored-by: amitraj2203 <[email protected]>
Co-authored-by: t-hamano <[email protected]>
Co-authored-by: talldan <[email protected]>
Co-authored-by: vk17-starlord <[email protected]>
  • Loading branch information
5 people authored May 29, 2024
1 parent 8dac7db commit e8bec8d
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 2 deletions.
10 changes: 8 additions & 2 deletions packages/edit-site/src/components/global-styles/shadows-panel.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { unlock } from '../../lock-unlock';
import Subtitle from './subtitle';
import { NavigationButtonAsItem } from './navigation-button';
import ScreenHeader from './header';
import { getNewIndexFromPresets } from './utils';

const { useGlobalSetting } = unlock( blockEditorPrivateApis );

Expand Down Expand Up @@ -81,10 +82,15 @@ export default function ShadowsPanel() {

function ShadowList( { label, shadows, category, canCreate, onCreate } ) {
const handleAddShadow = () => {
const newIndex = getNewIndexFromPresets( shadows, 'shadow-' );
onCreate( {
name: `Shadow ${ shadows.length + 1 }`,
name: sprintf(
/* translators: %s: is an index for a preset */
__( 'Shadow %s' ),
newIndex
),
shadow: defaultShadow,
slug: `shadow-${ shadows.length + 1 }`,
slug: `shadow-${ newIndex }`,
} );
};

Expand Down
59 changes: 59 additions & 0 deletions packages/edit-site/src/components/global-styles/test/utils.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/**
* Internal dependencies
*/
import { getNewIndexFromPresets } from '../utils';

const validPresets = {
single: [ { slug: 'preset-1' } ],
multiple: [ { slug: 'preset-1' }, { slug: 'preset-2' } ],
withGaps: [ { slug: 'preset-1' }, { slug: 'preset-3' } ],
mixedPrefixes: [
{ slug: 'preset-1' },
{ slug: 'shadow-2' },
{ slug: 'preset-3' },
],
nonStringSlug: [ { slug: 'preset-1' }, { slug: 2 } ],
emptyArray: [],
};

const invalidPresets = {
noMatch: [ { slug: 'preset-alpha' }, { slug: 'preset-beta' } ],
emptySlug: [ { slug: '' } ],
nullSlug: [ { slug: null } ],
undefinedSlug: [ { slug: undefined } ],
nonObjectElements: [ 'preset-1' ],
};

const getExpectedIndex = ( presetKey, presets ) => {
if ( presetKey === 'withGaps' ) {
return 4;
}
if ( presetKey === 'mixedPrefixes' ) {
return 4;
}
if ( presetKey === 'nonStringSlug' ) {
return 2;
}
return presets.length + 1;
};

describe( 'getNewIndexFromPresets', () => {
Object.entries( validPresets ).forEach( ( [ presetKey, presets ] ) => {
describe( `test valid preset format: ${ presetKey }`, () => {
const newIndex = getNewIndexFromPresets( presets, 'preset-' );
it( `should return correct new index for ${ presetKey }`, () => {
const expectedIndex = getExpectedIndex( presetKey, presets );
expect( newIndex ).toBe( expectedIndex );
} );
} );
} );

Object.entries( invalidPresets ).forEach( ( [ presetKey, presets ] ) => {
describe( `test invalid preset format: ${ presetKey }`, () => {
const newIndex = getNewIndexFromPresets( presets, 'preset-' );
it( `should return 1 for ${ presetKey }`, () => {
expect( newIndex ).toBe( 1 );
} );
} );
} );
} );
27 changes: 27 additions & 0 deletions packages/edit-site/src/components/global-styles/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,33 @@ export function getVariationClassName( variation ) {
return `is-style-${ variation }`;
}

/**
* Iterates through the presets array and searches for slugs that start with the specified
* slugPrefix followed by a numerical suffix. It identifies the highest numerical suffix found
* and returns one greater than the highest found suffix, ensuring that the new index is unique.
*
* @param {Array} presets The array of preset objects, each potentially containing a slug property.
* @param {string} slugPrefix The prefix to look for in the preset slugs.
*
* @return {number} The next available index for a preset with the specified slug prefix, or 1 if no matching slugs are found.
*/
export function getNewIndexFromPresets( presets, slugPrefix ) {
const nameRegex = new RegExp( `^${ slugPrefix }([\\d]+)$` );
const highestPresetValue = presets.reduce( ( currentHighest, preset ) => {
if ( typeof preset?.slug === 'string' ) {
const matches = preset?.slug.match( nameRegex );
if ( matches ) {
const id = parseInt( matches[ 1 ], 10 );
if ( id > currentHighest ) {
return id;
}
}
}
return currentHighest;
}, 0 );
return highestPresetValue + 1;
}

function getFontFamilyFromSetting( fontFamilies, setting ) {
if ( ! Array.isArray( fontFamilies ) || ! setting ) {
return null;
Expand Down

0 comments on commit e8bec8d

Please sign in to comment.