Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Global Styles: Improve organisation of site background color and image #63216

Closed
wants to merge 21 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
3401d45
Adds background icon
amitraj2203 Jul 6, 2024
70fc60f
Removes Background Panel from layout screen
amitraj2203 Jul 6, 2024
a555902
Improves organisation of site background image and color options in g…
amitraj2203 Jul 6, 2024
c78e9f0
Merge branch 'trunk' of github.com:WordPress/gutenberg into feat/add-…
amitraj2203 Jul 31, 2024
5caa672
Fix styling issue after merge conflict
amitraj2203 Jul 31, 2024
d6252d6
Resets border radius top and bottom for the first and last control
amitraj2203 Jul 31, 2024
4a99ca1
Refactor global styles to fix border focus issue for background panel
amitraj2203 Aug 1, 2024
c4a1706
Adds upload icon for background image and change it's shape to rounde…
amitraj2203 Aug 1, 2024
635c62e
Change the border-radius to 2px and fix the missing border-top when t…
amitraj2203 Aug 2, 2024
7f4951d
Move background panel to the top
mtias Aug 3, 2024
f3fc268
Makes use of ColorIndicator component
amitraj2203 Aug 5, 2024
9f2d715
Used $radius-small instead of $radius-block-ui
amitraj2203 Aug 5, 2024
267a62b
Refactor SVG attributes to adhere to camel case convention
amitraj2203 Aug 5, 2024
dba7140
Wraps "Image" and "Color" items with ItemGroup
amitraj2203 Aug 7, 2024
f27779e
Merge branch 'trunk' of github.com:WordPress/gutenberg into feat/add-…
amitraj2203 Aug 17, 2024
f4e3a7d
feat: Use ItemGroup to wrap the Color and Image item
amitraj2203 Aug 17, 2024
f2cc826
Merge branch 'trunk' of github.com:WordPress/gutenberg into feat/add-…
amitraj2203 Aug 19, 2024
4f83540
Merge branch 'trunk' of github.com:WordPress/gutenberg into feat/add-…
amitraj2203 Aug 29, 2024
98833df
Removed blank lines
amitraj2203 Aug 29, 2024
7b8110a
chore: Update showColorControl prop in BackgroundPanel component
amitraj2203 Aug 31, 2024
9cd986c
chore: Update use of hasBackgroundPanel in RootMenu component
amitraj2203 Aug 31, 2024
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
Prev Previous commit
Next Next commit
Improves organisation of site background image and color options in g…
…lobal styles
  • Loading branch information
amitraj2203 committed Jul 6, 2024
commit a5559020587a375ed629ee01e885e60c92c76237
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,29 @@ import clsx from 'clsx';
* WordPress dependencies
*/
import {
__experimentalUseNavigator as useNavigator,
__experimentalToolsPanel as ToolsPanel,
__experimentalToolsPanelItem as ToolsPanelItem,
ToggleControl,
__experimentalToggleGroupControl as ToggleGroupControl,
__experimentalToggleGroupControlOption as ToggleGroupControlOption,
__experimentalUnitControl as UnitControl,
__experimentalVStack as VStack,
Button,
ColorIndicator,
DropZone,
Flex,
FlexItem,
FocalPointPicker,
MenuItem,
VisuallyHidden,
__experimentalItemGroup as ItemGroup,
__experimentalHStack as HStack,
__experimentalTruncate as Truncate,
__experimentalZStack as ZStack,
Dropdown,
__experimentalDropdownContentWrapper as DropdownContentWrapper,
privateApis as componentsPrivateApis,
} from '@wordpress/components';
import { __, _x, sprintf } from '@wordpress/i18n';
import { store as noticesStore } from '@wordpress/notices';
Expand All @@ -42,15 +48,19 @@ import { isBlobURL } from '@wordpress/blob';
/**
* Internal dependencies
*/
import { useToolsPanelDropdownMenuProps } from './utils';
import { getValueFromVariable, useToolsPanelDropdownMenuProps } from './utils';
import { setImmutably } from '../../utils/object';
import { useColorsPerOrigin, useGradientsPerOrigin } from './hooks';
import ColorGradientControl from '../colors-gradients/control';
import MediaReplaceFlow from '../media-replace-flow';
import { store as blockEditorStore } from '../../store';
import { getResolvedThemeFilePath } from './theme-file-uri-utils';
import { unlock } from '../../lock-unlock';

const IMAGE_BACKGROUND_TYPE = 'image';
const DEFAULT_CONTROLS = {
backgroundImage: true,
background: true,
};
const BACKGROUND_POPOVER_PROPS = {
placement: 'left-start',
Expand Down Expand Up @@ -644,6 +654,140 @@ function BackgroundToolsPanel( {
);
}

const { Tabs } = unlock( componentsPrivateApis );

function ColorPanelTab( {
isGradient,
inheritedValue,
userValue,
setValue,
colorGradientControlSettings,
} ) {
return (
<ColorGradientControl
{ ...colorGradientControlSettings }
showTitle={ false }
enableAlpha
__experimentalIsRenderedInSidebar
colorValue={ isGradient ? undefined : inheritedValue }
gradientValue={ isGradient ? inheritedValue : undefined }
onColorChange={ isGradient ? undefined : setValue }
onGradientChange={ isGradient ? setValue : undefined }
clearable={ inheritedValue === userValue }
headingLevel={ 3 }
/>
);
}

const LabeledColorIndicators = ( { indicators, label } ) => (
<HStack justify="flex-start">
<ZStack isLayered={ false } offset={ -8 }>
{ indicators.map( ( indicator, index ) => (
<Flex key={ index } expanded={ false }>
<ColorIndicator colorValue={ indicator } />
</Flex>
) ) }
</ZStack>
<FlexItem
className="block-editor-panel-color-gradient-settings__color-name"
title={ label }
>
{ label }
</FlexItem>
</HStack>
);

function ColorPanelDropdown( {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've mentioned it before, but I think this file is getting too large and probably needs some composition, e.g.,

<BackgroundPanel>
      <BackgroundImageControls />
      <BackgroundColorControls />
</BackgroundPanel>

label,
hasValue,
resetValue,
isShownByDefault,
indicators,
tabs,
colorGradientControlSettings,
panelId,
} ) {
const currentTab = tabs.find( ( tab ) => tab.userValue !== undefined );
return (
<ToolsPanelItem
className="block-editor-global-styles-background-panel__image-tools-panel-item"
hasValue={ hasValue }
label={ label }
onDeselect={ resetValue }
isShownByDefault={ isShownByDefault }
panelId={ panelId }
>
<Dropdown
popoverProps={ BACKGROUND_POPOVER_PROPS }
renderToggle={ ( { onToggle, isOpen } ) => {
const toggleProps = {
onClick: onToggle,
className: clsx(
'block-editor-panel-color-gradient-settings__dropdown',
{ 'is-open': isOpen }
),
'aria-expanded': isOpen,
'aria-label': sprintf(
/* translators: %s is the type of color property, e.g., "background" */
__( 'Color %s styles' ),
label
),
};

return (
<Button { ...toggleProps }>
<LabeledColorIndicators
indicators={ indicators }
label={ label }
/>
</Button>
);
} }
renderContent={ () => (
<DropdownContentWrapper paddingSize="none">
<div className="block-editor-panel-color-gradient-settings__dropdown-content">
{ tabs.length > 1 && (
<Tabs defaultTabId={ currentTab?.key }>
<Tabs.TabList>
{ tabs.map( ( tab ) => (
<Tabs.Tab
key={ tab.key }
tabId={ tab.key }
>
{ tab.label }
</Tabs.Tab>
) ) }
</Tabs.TabList>

{ tabs.map( ( tab ) => {
const { key: tabKey, ...restTabProps } =
tab;
return (
<Tabs.TabPanel
key={ tabKey }
tabId={ tabKey }
focusable={ false }
>
<ColorPanelTab
key={ tabKey }
{ ...restTabProps }
colorGradientControlSettings={
colorGradientControlSettings
}
/>
</Tabs.TabPanel>
);
} ) }
</Tabs>
) }
</div>
</DropdownContentWrapper>
) }
/>
</ToolsPanelItem>
);
}

export default function BackgroundPanel( {
as: Wrapper = BackgroundToolsPanel,
value,
Expand All @@ -653,13 +797,83 @@ export default function BackgroundPanel( {
panelId,
defaultControls = DEFAULT_CONTROLS,
defaultValues = {},
headerLabel = __( 'Background image' ),
headerLabel = __( 'Elements' ),
themeFileURIs,
} ) {
const navigator = useNavigator();
const { path } = navigator.location;

const colors = useColorsPerOrigin( settings );
const gradients = useGradientsPerOrigin( settings );
const areCustomSolidsEnabled = settings?.color?.custom;
const areCustomGradientsEnabled = settings?.color?.customGradient;
const hasSolidColors = colors.length > 0 || areCustomSolidsEnabled;
const hasGradientColors = gradients.length > 0 || areCustomGradientsEnabled;
const decodeValue = ( rawValue ) =>
getValueFromVariable( { settings }, '', rawValue );
const encodeColorValue = ( colorValue ) => {
const allColors = colors.flatMap(
( { colors: originColors } ) => originColors
);
const colorObject = allColors.find(
( { color } ) => color === colorValue
);
return colorObject
? 'var:preset|color|' + colorObject.slug
: colorValue;
};
const encodeGradientValue = ( gradientValue ) => {
const allGradients = gradients.flatMap(
( { gradients: originGradients } ) => originGradients
);
const gradientObject = allGradients.find(
( { gradient } ) => gradient === gradientValue
);
return gradientObject
? 'var:preset|gradient|' + gradientObject.slug
: gradientValue;
};

// BackgroundColor
const showBackgroundPanel = useHasBackgroundPanel( settings );
const backgroundColor = decodeValue( inheritedValue?.color?.background );
const userBackgroundColor = decodeValue( value?.color?.background );
const gradient = decodeValue( inheritedValue?.color?.gradient );
const userGradient = decodeValue( value?.color?.gradient );
const hasBackground = () => !! userBackgroundColor || !! userGradient;
const setBackgroundColor = ( newColor ) => {
const newValue = setImmutably(
value,
[ 'color', 'background' ],
encodeColorValue( newColor )
);
newValue.color.gradient = undefined;
onChange( newValue );
};
const setGradient = ( newGradient ) => {
const newValue = setImmutably(
value,
[ 'color', 'gradient' ],
encodeGradientValue( newGradient )
);
newValue.color.background = undefined;
onChange( newValue );
};
const resetBackgroundColor = () => {
const newValue = setImmutably(
value,
[ 'color', 'background' ],
undefined
);
newValue.color.gradient = undefined;
onChange( newValue );
};

const resetAllFilter = useCallback( ( previousValue ) => {
return {
...previousValue,
background: {},
color: undefined,
};
}, [] );

Expand Down Expand Up @@ -697,44 +911,84 @@ export default function BackgroundPanel( {
}
) }
>
{ shouldShowBackgroundImageControls ? (
<BackgroundControlsPanel
label={ title }
filename={ title }
url={ getResolvedThemeFilePath( url, themeFileURIs ) }
onToggle={ setIsDropDownOpen }
hasImageValue={ hasImageValue }
>
<VStack spacing={ 3 } className="single-column">
<BackgroundImageControls
onChange={ onChange }
style={ value }
inheritedValue={ inheritedValue }
themeFileURIs={ themeFileURIs }
displayInPanel
onRemoveImage={ () => {
setIsDropDownOpen( false );
resetBackground();
} }
/>
<BackgroundSizeControls
onChange={ onChange }
panelId={ panelId }
style={ value }
defaultValues={ defaultValues }
inheritedValue={ inheritedValue }
themeFileURIs={ themeFileURIs }
/>
</VStack>
</BackgroundControlsPanel>
) : (
<BackgroundImageControls
onChange={ onChange }
style={ value }
inheritedValue={ inheritedValue }
themeFileURIs={ themeFileURIs }
/>
) }
<>
{ shouldShowBackgroundImageControls ? (
<BackgroundControlsPanel
label={ title }
filename={ title }
url={ getResolvedThemeFilePath(
url,
themeFileURIs
) }
onToggle={ setIsDropDownOpen }
hasImageValue={ hasImageValue }
>
<VStack spacing={ 3 } className="single-column">
<BackgroundImageControls
onChange={ onChange }
style={ value }
inheritedValue={ inheritedValue }
themeFileURIs={ themeFileURIs }
displayInPanel
onRemoveImage={ () => {
setIsDropDownOpen( false );
resetBackground();
} }
/>
<BackgroundSizeControls
onChange={ onChange }
panelId={ panelId }
style={ value }
defaultValues={ defaultValues }
inheritedValue={ inheritedValue }
themeFileURIs={ themeFileURIs }
/>
</VStack>
</BackgroundControlsPanel>
) : (
<BackgroundImageControls
onChange={ onChange }
style={ value }
inheritedValue={ inheritedValue }
themeFileURIs={ themeFileURIs }
/>
) }
{ showBackgroundPanel && path === '/background' && (
amitraj2203 marked this conversation as resolved.
Show resolved Hide resolved
<ColorPanelDropdown
key="background"
label={ __( 'Color' ) }
hasValue={ hasBackground }
resetValue={ resetBackgroundColor }
isShownByDefault={ defaultControls.background }
indicators={ [ gradient ?? backgroundColor ] }
tabs={ [
hasSolidColors && {
key: 'background',
label: __( 'Background' ),
inheritedValue: backgroundColor,
setValue: setBackgroundColor,
userValue: userBackgroundColor,
},
hasGradientColors && {
key: 'gradient',
label: __( 'Gradient' ),
inheritedValue: gradient,
setValue: setGradient,
userValue: userGradient,
isGradient: true,
},
].filter( Boolean ) }
colorGradientControlSettings={ {
colors,
disableCustomColors: ! areCustomSolidsEnabled,
gradients,
disableCustomGradients:
! areCustomGradientsEnabled,
} }
panelId={ panelId }
/>
) }
</>
</div>

{ /* Dummy ToolsPanel items, so we can control what's in the dropdown popover */ }
amitraj2203 marked this conversation as resolved.
Show resolved Hide resolved
Expand Down
Loading
Loading