Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 83 additions & 5 deletions packages/components/src/palette-edit/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
DoneButton,
RemoveButton,
PaletteEditContents,
PaletteVariation,
} from './styles';
import { NavigableMenu } from '../navigable-container';
import { DEFAULT_GRADIENT } from '../custom-gradient-picker/constants';
Expand All @@ -52,6 +53,8 @@
OptionProps,
PaletteEditListViewProps,
PaletteEditProps,
PaletteEditColorVariation,
PaletteEditGradientVariation,
PaletteElement,
} from './types';

Expand Down Expand Up @@ -353,6 +356,10 @@
}

const EMPTY_ARRAY: Color[] = [];
const EMPTY_VARIATIONS: (
| PaletteEditColorVariation
| PaletteEditGradientVariation
)[] = [];

/**
* Allows editing a palette of colors or gradients.
Expand All @@ -379,6 +386,8 @@
colors = EMPTY_ARRAY,
onChange,
paletteLabel,
paletteIcon,
paletteVariations = EMPTY_VARIATIONS,

Check failure on line 390 in packages/components/src/palette-edit/index.tsx

View workflow job for this annotation

GitHub Actions / All

Type '(PaletteEditColorVariation | PaletteEditGradientVariation)[]' is not assignable to type 'PaletteEditColorVariation[] | PaletteEditGradientVariation[]'.

Check failure on line 390 in packages/components/src/palette-edit/index.tsx

View workflow job for this annotation

GitHub Actions / All

Type '(PaletteEditColorVariation | PaletteEditGradientVariation)[]' is not assignable to type 'PaletteEditColorVariation[] | PaletteEditGradientVariation[]'.
paletteLabelHeadingLevel = 2,
emptyMessage,
canOnlyChangeValues,
Expand All @@ -388,6 +397,10 @@
}: PaletteEditProps ) {
const isGradient = !! gradients;
const elements = isGradient ? gradients : colors;
const variations = paletteVariations.map( ( variation ) => ( {
...variation,
elements: isGradient ? variation.gradients : variation.colors,
} ) );
const [ isEditing, setIsEditing ] = useState( false );
const [ editingElement, setEditingElement ] = useState<
number | null | undefined
Expand All @@ -399,6 +412,12 @@
! elements[ editingElement ].slug;
const elementsLength = elements.length;
const hasElements = elementsLength > 0;
const hasVariations = variations.some(
( variation ) => variation.elements.length > 0

Check failure on line 416 in packages/components/src/palette-edit/index.tsx

View workflow job for this annotation

GitHub Actions / All

'variation.elements' is possibly 'undefined'.

Check failure on line 416 in packages/components/src/palette-edit/index.tsx

View workflow job for this annotation

GitHub Actions / All

'variation.elements' is possibly 'undefined'.
);
const hasAnyElements = hasElements || hasVariations;
const canResetAny =
canReset || variations.some( ( variation ) => variation.canReset );
const debounceOnChange = useDebounce( onChange, 100 );
const onSelectPaletteItem = useCallback(
(
Expand Down Expand Up @@ -426,10 +445,11 @@
<PaletteEditStyles>
<HStack>
<PaletteHeading level={ paletteLabelHeadingLevel }>
{ paletteIcon }
{ paletteLabel }
</PaletteHeading>
<PaletteActionsContainer>
{ hasElements && isEditing && (
{ hasAnyElements && isEditing && (
<DoneButton
size="small"
onClick={ () => {
Expand Down Expand Up @@ -483,10 +503,10 @@
/>
) }

{ hasElements &&
{ hasAnyElements &&
( ! isEditing ||
! canOnlyChangeValues ||
canReset ) && (
canResetAny ) && (
<DropdownMenu
icon={ moreVertical }
label={
Expand Down Expand Up @@ -537,7 +557,7 @@
) }
</Button>
) }
{ canReset && (
{ canResetAny && (
<Button
__next40pxDefaultSize
className="components-palette-edit__menu-button"
Expand All @@ -546,7 +566,18 @@
setEditingElement(
null
);
onChange();
if ( canReset ) {
onChange();
}
variations.forEach(
( variation ) => {
if (
variation.canReset
) {
variation.onChange();
}
}
);
onClose();
} }
>
Expand Down Expand Up @@ -622,6 +653,53 @@
) ) }
</PaletteEditContents>
) }
{ variations.map(
( variation ) =>
variation.elements.length > 0 && (

Check failure on line 658 in packages/components/src/palette-edit/index.tsx

View workflow job for this annotation

GitHub Actions / All

'variation.elements' is possibly 'undefined'.

Check failure on line 658 in packages/components/src/palette-edit/index.tsx

View workflow job for this annotation

GitHub Actions / All

'variation.elements' is possibly 'undefined'.
<PaletteVariation key={ variation.paletteLabel }>
<PaletteHeading level={ paletteLabelHeadingLevel }>
{ variation.paletteIcon }
{ variation.paletteLabel }
</PaletteHeading>
<PaletteEditContents>
{ isEditing && (
<PaletteEditListView<
( typeof variation.elements )[ number ]

Check failure on line 667 in packages/components/src/palette-edit/index.tsx

View workflow job for this annotation

GitHub Actions / All

Type 'Color[] | Gradient[] | undefined' has no matching index signature for type 'number'.

Check failure on line 667 in packages/components/src/palette-edit/index.tsx

View workflow job for this annotation

GitHub Actions / All

Type 'Color[] | Gradient[] | undefined' has no matching index signature for type 'number'.
>
canOnlyChangeValues={
canOnlyChangeValues
}
elements={ variation.elements }

Check failure on line 672 in packages/components/src/palette-edit/index.tsx

View workflow job for this annotation

GitHub Actions / All

Type 'Color[] | Gradient[] | undefined' is not assignable to type 'any[]'.

Check failure on line 672 in packages/components/src/palette-edit/index.tsx

View workflow job for this annotation

GitHub Actions / All

Type 'Color[] | Gradient[] | undefined' is not assignable to type 'any[]'.
// @ts-expect-error The variation type matches the parent palette type.

Check failure on line 673 in packages/components/src/palette-edit/index.tsx

View workflow job for this annotation

GitHub Actions / All

Unused '@ts-expect-error' directive.

Check failure on line 673 in packages/components/src/palette-edit/index.tsx

View workflow job for this annotation

GitHub Actions / All

Unused '@ts-expect-error' directive.
onChange={ variation.onChange }
slugPrefix={ slugPrefix }
isGradient={ isGradient }
popoverProps={ popoverProps }
addColorRef={ addColorRef }
/>
) }
{ ! isEditing && isGradient && (
<GradientPicker
gradients={
variation.elements as Gradient[]

Check failure on line 684 in packages/components/src/palette-edit/index.tsx

View workflow job for this annotation

GitHub Actions / All

Cannot find name 'Gradient'.

Check failure on line 684 in packages/components/src/palette-edit/index.tsx

View workflow job for this annotation

GitHub Actions / All

Cannot find name 'Gradient'.
}
onChange={ () => {} }
clearable={ false }
disableCustomGradients
/>
) }
{ ! isEditing && ! isGradient && (
<ColorPalette
colors={ variation.elements as Color[] }
onChange={ () => {} }
clearable={ false }
disableCustomColors
/>
) }
Comment on lines +681 to +698
</PaletteEditContents>
</PaletteVariation>
)
) }
{ ! hasElements && emptyMessage && (
<PaletteEditContents>{ emptyMessage }</PaletteEditContents>
) }
Expand Down
10 changes: 10 additions & 0 deletions packages/components/src/palette-edit/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,15 @@ export const NameContainer = styled.div`
`;

export const PaletteHeading = styled( Heading )`
align-items: center;
display: flex;
gap: ${ space( 1 ) };
text-transform: uppercase;
line-height: ${ space( 6 ) };
font-weight: ${ CONFIG.fontWeightEmphasis };
svg {
flex-shrink: 0;
}
&&& {
font-size: 11px;
margin-bottom: 0;
Expand All @@ -68,6 +74,10 @@ export const PaletteEditContents = styled( View )`
margin-top: ${ space( 2 ) };
`;

export const PaletteVariation = styled( View )`
margin-top: ${ space( 4 ) };
`;

export const PaletteEditStyles = styled( View )`
&&& {
.components-button.has-icon {
Expand Down
106 changes: 106 additions & 0 deletions packages/components/src/palette-edit/test/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,112 @@ describe( 'PaletteEdit', () => {
expect( paletteLabel ).toBeVisible();
} );

it( 'shows an icon before the heading label', () => {
render(
<PaletteEdit
{ ...defaultProps }
colors={ colors }
paletteIcon={ <span data-testid="palette-icon" /> }
/>
);

expect(
screen.getByRole( 'heading', {
level: 2,
name: 'Test label',
} )
).toBeVisible();
expect( screen.getByTestId( 'palette-icon' ) ).toBeVisible();
} );

it( 'edits related palette variations from the same options menu', async () => {
const variationColors = [
{ color: '#ffffff', name: 'Primary', slug: 'primary' },
];

render(
<PaletteEdit
{ ...defaultProps }
colors={ colors }
canOnlyChangeValues
paletteVariations={ [
{
colors: variationColors,
onChange: noop,
paletteLabel: 'Dark palette',
},
] }
/>
);

expect(
screen.getAllByRole( 'button', { name: 'Color options' } )
).toHaveLength( 1 );

await click(
screen.getByRole( 'button', {
name: 'Color options',
} )
);
await click(
screen.getByRole( 'button', {
name: 'Show details',
} )
);

expect(
screen.getByRole( 'heading', {
level: 2,
name: 'Dark palette',
} )
).toBeVisible();
expect(
screen.getAllByRole( 'button', { name: 'Edit: Primary' } )
).toHaveLength( 2 );
} );

it( 'resets the base palette and its variations together', async () => {
const onChange = jest.fn();
const onVariationChange = jest.fn();

render(
<PaletteEdit
{ ...defaultProps }
colors={ colors }
onChange={ onChange }
canReset
paletteVariations={ [
{
canReset: true,
colors: [
{
color: '#ffffff',
name: 'Primary',
slug: 'primary',
},
],
onChange: onVariationChange,
paletteLabel: 'Dark palette',
},
] }
/>
);

await click(
screen.getByRole( 'button', {
name: 'Color options',
} )
);
await click(
screen.getByRole( 'button', {
name: 'Reset colors',
} )
);

expect( onChange ).toHaveBeenCalledWith();
expect( onVariationChange ).toHaveBeenCalledWith();
} );

it( 'shows heading label with custom heading level', () => {
render(
<PaletteEdit
Expand Down
Loading
Loading