diff --git a/docs/source/recipes/color-picker-widget.md b/docs/source/recipes/color-picker-widget.md
new file mode 100644
index 0000000000..18abdf4b69
--- /dev/null
+++ b/docs/source/recipes/color-picker-widget.md
@@ -0,0 +1,164 @@
+---
+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"
+---
+
+# Color picker widget
+
+Volto comes with a color picker widget that can be used in any Volto form.
+It allows to pick a color from a preset list of colors.
+This preset list of colors is passed using the `colors` prop.
+You can [try a demo of the default color picker](https://6.docs.plone.org/storybook/?path=/story/edit-widgets-colorpicker--default).
+You can combine the color picker widget with the {doc}`../blocks/block-style-wrapper` to have a powerful, yet simple way to manage color properties in your blocks.
+You can use it either in your custom block's styles schema or enhance an existing block as follows:
+
+```{code-block} js
+:emphasize-lines: 13-16, 31-42
+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 StyleWrapper support to your block
+ addStyling({ schema, intl });
+
+ // Then we add the field to the fieldset inside the StyleWrapper `styles` field schema fieldset array
+ schema.properties.styles.schema.fieldsets[0].fields = [
+ ...schema.properties.styles.schema.fieldsets[0].fields,
+ 'backGroundColor',
+ ];
+
+ // and finally, we add the field to the StyleWrapper `styles` object field schema properties
+ schema.properties.styles.schema.properties['backGroundColor'] = {
+ widget: 'color_picker',
+ title: intl.formatMessage(messages.backgroundColor),
+ colors,
+ default: defaultBGColor,
+ };
+
+ return schema;
+};
+```
+
+The color picker widget's discriminator is `color_picker`.
+
+## Color definitions
+
+```{versionchanged} 17.9.0
+Enhanced `ColorPickerWidget` with additional color definitions, saving it as an object instead of a string.
+```
+
+The `colors` property of the widget controls which colors are available to choose in the widget.
+This is the signature of the object along with an example:
+
+```ts
+type Color =
+ | {
+ name: string;
+ label: string;
+ style: Record<`--${string}`, string>;
+ }
+ | {
+ name: string;
+ label: string;
+ style: undefined;
+ };
+
+const colors: Color[] = [
+ {
+ name: 'red',
+ label: 'red',
+ style: { '--background-color': 'red' } },
+ {
+ name: 'yellow',
+ label: 'yellow',
+ style: { '--background-color': 'yellow' },
+ },
+ {
+ name: 'green',
+ label: 'green'
+ },
+]
+```
+
+### Basic color definition
+
+The basic color definition is the one that saves a string as the widget value.
+This string is the one defined by the `name` key.
+You can use it on your own code by reading it from the resultant data and use it according your designed solution.
+
+When combined with the `StyleWrapper`, the value will be injected as a class name of the form `has--PROPERTY_NAME--PROPERTY_VALUE`:
+
+```html
+
+ ...
+
+```
+
+Then you should create the CSS rules according to these injected class names.
+
+### Custom CSS properties as color definitions
+
+The `style` key defines a set of custom CSS properties to be added as the value to the HTML attribute `style`.
+They will be injected by the `StyleWrapper` as style definitions, so you can use them in your CSS rules.
+
+```html
+
+...
+
+```
+
+```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.
+
+You can also use this selector, where an element with class names `block` and `teaser` with a child element whose HTML attribute `style` contains the value of `--background-color`:
+
+```css
+.block.teaser {
+ &[style*='--background-color'] {
+ padding: 20px 0;
+ }
+ ```
+
+```{seealso}
+See the MDN CSS Reference for selectors.
+
+- [Attribute selectors](https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors)
+- [`&` nesting selector](https://developer.mozilla.org/en-US/docs/Web/CSS/Nesting_selector)
+```
+
+
+## Use both basic and custom CSS properties definitions
+
+You can combine both basic and custom CSS properties definitions.
+It's up to you how to mix and match them.
diff --git a/docs/source/recipes/index.md b/docs/source/recipes/index.md
index 8c8c15656f..d75154ba39 100644
--- a/docs/source/recipes/index.md
+++ b/docs/source/recipes/index.md
@@ -28,5 +28,6 @@ contextnavigation
pluggables
widget
how-to-restrict-blocks
+color-picker-widget
ie11compat
```
diff --git a/packages/scripts/i18n.cjs b/packages/scripts/i18n.cjs
index 52b6d84869..a19b98c5cf 100755
--- a/packages/scripts/i18n.cjs
+++ b/packages/scripts/i18n.cjs
@@ -30,7 +30,7 @@ function extractMessages() {
// If so, we should do it in the config object or somewhere else
// We also ignore the addons folder since they are populated using
// their own locales files and taken care separatedly in this script
- glob('src/**/*.js?(x)', {
+ glob('src/**/*.{js,jsx,ts,tsx}', {
ignore: ['src/customizations/**', 'src/addons/**'],
}),
(filename) => {
diff --git a/packages/scripts/news/5585.feature b/packages/scripts/news/5585.feature
new file mode 100644
index 0000000000..7bc83eeb8a
--- /dev/null
+++ b/packages/scripts/news/5585.feature
@@ -0,0 +1 @@
+Added support for TS/TSX files in i18n machinery. @sneridagh
diff --git a/packages/volto/.storybook/main.js b/packages/volto/.storybook/main.js
index c11cf59ece..76d33e53d4 100644
--- a/packages/volto/.storybook/main.js
+++ b/packages/volto/.storybook/main.js
@@ -149,4 +149,16 @@ module.exports = {
core: {
builder: 'webpack5',
},
+ typescript: {
+ check: false,
+ checkOptions: {},
+ reactDocgen: 'react-docgen-typescript-plugin',
+ reactDocgenTypescriptOptions: {
+ compilerOptions: {
+ allowSyntheticDefaultImports: false,
+ esModuleInterop: false,
+ },
+ propFilter: () => true,
+ },
+ },
};
diff --git a/packages/volto/news/5585.feature b/packages/volto/news/5585.feature
new file mode 100644
index 0000000000..7d116752d6
--- /dev/null
+++ b/packages/volto/news/5585.feature
@@ -0,0 +1 @@
+Enhanced `ColorPickerWidget` with additional color definitions, saving it as an object instead of a string. @sneridagh
diff --git a/packages/volto/package.json b/packages/volto/package.json
index 4b22e7a2ce..c8ceaa60b0 100644
--- a/packages/volto/package.json
+++ b/packages/volto/package.json
@@ -361,6 +361,7 @@
"@testing-library/react": "12.1.5",
"@testing-library/react-hooks": "8.0.1",
"@types/jest": "^29.5.8",
+ "@types/lodash": "^4.14.201",
"@types/react": "^17.0.52",
"@types/react-dom": "^17",
"@types/react-test-renderer": "18.0.1",
@@ -377,6 +378,7 @@
"jest-environment-jsdom": "^26",
"jsdom": "^16.7.0",
"jsonwebtoken": "9.0.0",
+ "react-docgen-typescript-plugin": "^1.0.5",
"react-error-overlay": "6.0.9",
"react-is": "^16.13.1",
"release-it": "^16.2.1",
diff --git a/packages/volto/src/components/manage/Widgets/ColorPickerWidget.stories.jsx b/packages/volto/src/components/manage/Widgets/ColorPickerWidget.stories.jsx
deleted file mode 100644
index c683b3eba4..0000000000
--- a/packages/volto/src/components/manage/Widgets/ColorPickerWidget.stories.jsx
+++ /dev/null
@@ -1,30 +0,0 @@
-import React from 'react';
-import ColorPickerWidget from './ColorPickerWidget';
-import WidgetStory from './story';
-
-export const Default = WidgetStory.bind({
- widget: ColorPickerWidget,
-});
-
-Default.args = {
- id: 'favoriteColor',
- title: 'Favorite Color',
- colors: [
- { name: 'red', label: 'red' },
- { name: 'yellow', label: 'yellow' },
- { name: 'green', label: 'green' },
- ],
-};
-
-export default {
- title: 'Edit Widgets/ColorPicker',
- component: Default,
- decorators: [
- (Story) => (
-
-
-
- ),
- ],
- argTypes: {},
-};
diff --git a/packages/volto/src/components/manage/Widgets/ColorPickerWidget.stories.tsx b/packages/volto/src/components/manage/Widgets/ColorPickerWidget.stories.tsx
new file mode 100644
index 0000000000..3806dbfebd
--- /dev/null
+++ b/packages/volto/src/components/manage/Widgets/ColorPickerWidget.stories.tsx
@@ -0,0 +1,48 @@
+import ColorPickerWidget from './ColorPickerWidget';
+import WidgetStory from './story';
+import type { Meta, StoryObj } from '@storybook/react';
+
+const meta: Meta = {
+ title: 'Edit Widgets/ColorPicker',
+ component: WidgetStory.bind({
+ widget: ColorPickerWidget,
+ }),
+ decorators: [
+ (Story) => (
+