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

Enhance ColorPickerWidget #5585

Merged
merged 26 commits into from
Jan 10, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
c21cb55
Enhance ColorPickerWidget
sneridagh Jan 2, 2024
7fd72e9
Changelog
sneridagh Jan 2, 2024
37326c7
Apply suggestions from code review
sneridagh Jan 3, 2024
5152fb2
Improve exports, include the main ConfigData definition from registry…
sneridagh Jan 2, 2024
3c18d29
Release @plone/types 1.0.0-alpha.1
sneridagh Jan 2, 2024
f1a99e1
Release @plone/registry 1.2.0
sneridagh Jan 2, 2024
4d73990
Release @plone/client 1.0.0-alpha.11
sneridagh Jan 2, 2024
9c526b2
Changelog
sneridagh Jan 2, 2024
8ca8b5e
Release @plone/client 1.0.0-alpha.12
sneridagh Jan 2, 2024
bcdfb15
Release 18.0.0-alpha.6
sneridagh Jan 2, 2024
6ff7dad
Clarify how CSS properties work (#5592)
stevepiercy Jan 2, 2024
67a2d6f
Allow to bail off the nested name build in the custom CSS properties …
sneridagh Jan 2, 2024
8b4aff0
Pin mrs.developer to an updated version, never to star. (#5593)
sneridagh Jan 2, 2024
f9529d8
Refactor ColorPickerWidget to TS
sneridagh Jan 3, 2024
5ce597b
Rename file
sneridagh Jan 3, 2024
16e9dc5
Merge branch 'main' into enhanceColorPickerWidget
stevepiercy Jan 3, 2024
b67d616
Fix TSX support for i18n
sneridagh Jan 3, 2024
41e9c6f
use reStructuredText fallback syntax to get emphasize lines
stevepiercy Jan 3, 2024
e5dd2d7
Apply suggestions from code review
sneridagh Jan 3, 2024
7b3cc6a
Fix TS errors
sneridagh Jan 3, 2024
bb53671
Changelog
sneridagh Jan 3, 2024
51ad919
Move `name` key to the top, to be consistent with the two forms
sneridagh Jan 3, 2024
79aa787
Prettify a bit docs
sneridagh Jan 3, 2024
51af7a0
David's suggestions and improvements
sneridagh Jan 3, 2024
5201647
Apply suggestions from code review
sneridagh Jan 3, 2024
86bad73
Update packages/scripts/news/5585.feature
sneridagh Jan 4, 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
139 changes: 139 additions & 0 deletions docs/source/recipes/how-to-use-color-picker-widget.md
stevepiercy marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
---
myst:
html_meta:
"description": "How to use the color picker widget in blocks settings and forms"
"property=og:description": "How to use the color picker widget in blocks settings and forms"
"property=og:title": "How to use the color picker widget"
"keywords": "Volto, Plone, frontend, React, blocks, forms, widget, color, picker"
---

# How to use the color picker widget
sneridagh marked this conversation as resolved.
Show resolved Hide resolved

stevepiercy marked this conversation as resolved.
Show resolved Hide resolved
Volto comes with a color picker widget that can be used in any Volto form.
stevepiercy marked this conversation as resolved.
Show resolved Hide resolved
The most common use case is use this value along with the blocks StyleWrapper as show in the example. See {ref}`block-style-wrapper-label` for more background about how the blocks StyleWrapper works.
sneridagh marked this conversation as resolved.
Show resolved Hide resolved
Combined with the blocks StyleWrapper you can have a powerful, yet simple way to manage color properties in your blocks.
sneridagh marked this conversation as resolved.
Show resolved Hide resolved
It can be used in your custom block settings schema or enhance an existing block as follows:
sneridagh marked this conversation as resolved.
Show resolved Hide resolved

```js hl_lines="13-16, 31-42"
sneridagh marked this conversation as resolved.
Show resolved Hide resolved
import { addStyling } from '@plone/volto/helpers/Extensions/withBlockSchemaEnhancer';
import { defineMessages } from 'react-intl';
import config from '@plone/volto/registry';

const messages = defineMessages({
backgroundColor: {
id: 'Background color',
defaultMessage: 'Background color',
},
});

export const defaultStylingSchema = ({ schema, formData, intl }) => {
const BG_COLORS = [
{ name: 'transparent', label: 'Transparent' },
{ name: 'grey', label: 'Grey' },
];

// You could allow passing the color definition from the config or from the default
// defined above
const colors =
config.blocks?.blocksConfig?.[formData['@type']]?.colors || BG_COLORS;

// Same for the default used (or undefined)
const defaultBGColor =
config.blocks?.blocksConfig?.[formData['@type']]?.defaultBGColor;

// This adds the StylingWrapper support to your block
sneridagh marked this conversation as resolved.
Show resolved Hide resolved
addStyling({ schema, intl });

// Then we add the field to the fieldset inside the StylingWrapper `styles` field schema fieldset array
sneridagh marked this conversation as resolved.
Show resolved Hide resolved
schema.properties.styles.schema.fieldsets[0].fields = [
...schema.properties.styles.schema.fieldsets[0].fields,
'backGroundColor',
];

// and finally, we add the field to the StylingWrapper `styles` object field schema properties
sneridagh marked this conversation as resolved.
Show resolved Hide resolved
schema.properties.styles.schema.properties['backGroundColor'] = {
widget: 'color_picker',
title: intl.formatMessage(messages.backgroundColor),
colors,
default: defaultBGColor,
};

return schema;
};
```

The widget name the color picker widget uses is `color_picker`.
stevepiercy marked this conversation as resolved.
Show resolved Hide resolved

## Color definitions

sneridagh marked this conversation as resolved.
Show resolved Hide resolved
The `colors` property of the widget controls which colors are available to choose in the widget.
This is the signature of the object:

```ts
type Color =
| {
label: string;
style: Record<`--${string}`, string> & { name: string };
}
| {
name: string;
label: string;
};

const colors: Color[] = [
{ style: { name: 'red', '--background-color': 'red' }, label: 'red' },
davisagli marked this conversation as resolved.
Show resolved Hide resolved
{
style: { name: 'yellow', '--background-color': 'yellow' },
label: 'yellow',
},
{ name: 'green', label: 'green' },
]
```

## Using basic definitions
sneridagh marked this conversation as resolved.
Show resolved Hide resolved

The basic color definition is the one that saves a string label as the widget value.
You can use it on your own code by reading it from the resultant data and use it according your designed solution.

In the case of using it along with the StyleWrapper, the value will be injected as a class name of the form:
sneridagh marked this conversation as resolved.
Show resolved Hide resolved

```html
<div class="has--backgroundColor--ee22ee">
...
</div>
```

Then you should create the CSS rules according to these injected class names.

## Using custom CSS properties as color definitions
sneridagh marked this conversation as resolved.
Show resolved Hide resolved

The `style` key defines a set of custom CSS properties to be saved as widget value.
sneridagh marked this conversation as resolved.
Show resolved Hide resolved
They will be injected by the StyleWrapper as style definitions and you will be able to use them in your CSS rules.
sneridagh marked this conversation as resolved.
Show resolved Hide resolved

```html
<div class="block teaser" style="--background-color': 'red'">
sneridagh marked this conversation as resolved.
Show resolved Hide resolved
...
</div>
```

```css
.block.teaser {
background-color: var(--background-color, transparent);
}
```

The `name` key is mandatory in order to generate proper markup in the resultant HTML in both forms.
It is also included by the StyleWrapper as a injected class name, in case you need it too in your CSS selectors.
sneridagh marked this conversation as resolved.
Show resolved Hide resolved

You can also use this selector in case it comes in handy:
sneridagh marked this conversation as resolved.
Show resolved Hide resolved

```css
.block.teaser {
&[style*='--background-color'] {
padding: 20px 0;
}
```

sneridagh marked this conversation as resolved.
Show resolved Hide resolved
## Use both basic and custom CSS properties definitions

You can combine both basic and style definitions, it's up to you how to mix and match them.
sneridagh marked this conversation as resolved.
Show resolved Hide resolved
1 change: 1 addition & 0 deletions packages/volto/news/5585.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Enhance `ColorPickerWidget` with additional color definitions and save an object instead of a string @sneridagh
sneridagh marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -44,21 +44,24 @@ const ColorPickerWidget = (props) => {

<div className="buttons">
{colors.map((color) => {
const colorName = color?.style?.name || color.name;
const colorValue = color.style || color.name;
return (
<Button
key={id + color.name}
className={color.name}
key={id + colorName}
className={colorName}
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
onChange(
id,
value === color.name
value === colorValue
? props.missing_value
: color.name,
: colorValue,
);
}}
active={value === color.name}
style={color.style}
active={value === colorValue}
circular
aria-label={color.label}
title={color.label}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,23 @@ Default.args = {
],
};

export const WithEnhancedStyleConfig = WidgetStory.bind({
widget: ColorPickerWidget,
});

WithEnhancedStyleConfig.args = {
id: 'favoriteColor',
title: 'Favorite Color',
colors: [
{ style: { name: 'red', '--background-color': 'red' }, label: 'red' },
{
style: { name: 'yellow', '--background-color': 'yellow' },
label: 'yellow',
},
{ name: 'green', label: 'green' },
],
};

export default {
title: 'Edit Widgets/ColorPicker',
component: Default,
Expand Down