Repository: odoo-dev/odoo
Pull request #4172: add theme colors option
Author: login: emge-odoo
Created: 2025-03-07T15:37:57Z | Merged: 2025-03-28T15:36:50Z



Diff:
diff --git a/addons/html_builder/static/src/core/building_blocks/builder_row.js b/addons/html_builder/static/src/core/building_blocks/builder_row.js
index 7654b457d50a43..1a69f3c186e811 100644
--- a/addons/html_builder/static/src/core/building_blocks/builder_row.js
+++ b/addons/html_builder/static/src/core/building_blocks/builder_row.js
@@ -13,7 +13,7 @@ export class BuilderRow extends Component {
     static components = { BuilderComponent };
     static props = {
         ...basicContainerBuilderComponentProps,
-        label: String,
+        label: { type: String, optional: true },
         tooltip: { type: String, optional: true },
         slots: { type: Object, optional: true },
         level: { type: Number, optional: true },
diff --git a/addons/html_builder/static/src/core/building_blocks/builder_row.xml b/addons/html_builder/static/src/core/building_blocks/builder_row.xml
index 73cd4e624db1cf..a266ea9dad26ed 100644
--- a/addons/html_builder/static/src/core/building_blocks/builder_row.xml
+++ b/addons/html_builder/static/src/core/building_blocks/builder_row.xml
@@ -10,10 +10,15 @@
                     t-on-click="toggleCollapseContent"
                     t-att-aria-expanded="state.expanded ? 'true' : 'false'"
                     t-att-aria-controls="collapseContentId"/>
-            <div class="d-flex hb-row-label" style="flex-grow: 0.4; flex-basis: 0; min-width: 0;" t-att-data-tooltip="props.tooltip" t-on-click="toggleCollapseContent">
-                <span class="text-nowrap text-truncate" t-out="props.label"/>
-            </div>
-            <div class="d-flex" style="flex-grow: 0.6; flex-basis: 0; min-width: 0; gap: 4px;" t-ref="content">
+            <t t-if="props.label">
+                <div class="d-flex hb-row-label" style="flex-grow: 0.4; flex-basis: 0; min-width: 0;" t-att-data-tooltip="props.tooltip" t-on-click="toggleCollapseContent">
+                    <span class="text-nowrap text-truncate" t-out="props.label"/>
+                </div>
+                <div class="d-flex" style="flex-grow: 0.6; flex-basis: 0; min-width: 0; gap: 4px;" t-ref="content">
+                    <t t-slot="default"/>
+                </div>
+            </t>
+            <div t-else="" class="d-flex" style="flex-grow: 1; flex-basis: 0; min-width: 0; gap: 4px;" t-ref="content">
                 <t t-slot="default"/>
             </div>
         </div>
diff --git a/addons/html_builder/static/src/sidebar/theme_colors_option.js b/addons/html_builder/static/src/sidebar/theme_colors_option.js
new file mode 100644
index 00000000000000..7a8fe818fef596
--- /dev/null
+++ b/addons/html_builder/static/src/sidebar/theme_colors_option.js
@@ -0,0 +1,77 @@
+import { onMounted } from "@odoo/owl";
+import { getCSSVariableValue } from "@html_builder/utils/utils_css";
+import { BaseOptionComponent, useDomState } from "@html_builder/core/utils";
+
+export class ThemeColorsOption extends BaseOptionComponent {
+    static template = "html_builder.ThemeColorsOption";
+    static props = {};
+    setup() {
+        super.setup();
+        this.palettes = this.getPalettes();
+        this.state = useDomState(() => ({
+            presets: this.getPresets(),
+        }));
+        onMounted(() => {
+            this.iframeDocument = document.querySelector("iframe").contentWindow.document;
+            this.state.presets = this.getPresets();
+        });
+    }
+
+    getPalettes() {
+        const palettes = [];
+        const style = window.getComputedStyle(document.documentElement);
+        const allPaletteNames = getCSSVariableValue("palette-names", style)
+            .split(", ")
+            .map((name) => name.replace(/'/g, ""));
+        for (const paletteName of allPaletteNames) {
+            const palette = {
+                name: paletteName,
+                colors: [],
+            };
+            [1, 3, 2].forEach((c) => {
+                const color = getCSSVariableValue(`o-palette-${paletteName}-o-color-${c}`, style);
+                palette.colors.push(color);
+            });
+            palettes.push(palette);
+        }
+        return palettes;
+    }
+
+    getPresets() {
+        const presets = [];
+        for (let i = 1; i <= 5; i++) {
+            const preset = {
+                id: i,
+                background: this.getColor(`o-cc${i}-bg`),
+                backgroundGradient: this.getColor(`o-cc${i}-bg-gradient`),
+                text: this.getColor(`o-cc${i}-text`),
+                headings: this.getColor(`o-cc${i}-headings`),
+                primaryBtn: this.getColor(`o-cc${i}-btn-primary`),
+                primaryBtnText: this.getColor(`o-cc${i}-btn-primary-text`),
+                primaryBtnBorder: this.getColor(`o-cc${i}-btn-primary-border`),
+                secondaryBtn: this.getColor(`o-cc${i}-btn-secondary`),
+                secondaryBtnText: this.getColor(`o-cc${i}-btn-secondary-text`),
+                secondaryBtnBorder: this.getColor(`o-cc${i}-btn-secondary-border`),
+            };
+
+            // TODO: check if this is necessary
+            if (preset.backgroundGradient) {
+                preset.backgroundGradient += ", url('/web/static/img/transparent.png')";
+            }
+            presets.push(preset);
+        }
+        return presets;
+    }
+
+    getColor(color) {
+        if (!this.iframeDocument) {
+            return "";
+        }
+        if (!this.iframeStyle) {
+            this.iframeStyle = this.iframeDocument.defaultView.getComputedStyle(
+                this.iframeDocument.documentElement
+            );
+        }
+        return getCSSVariableValue(color, this.iframeStyle);
+    }
+}
diff --git a/addons/html_builder/static/src/sidebar/theme_colors_option.xml b/addons/html_builder/static/src/sidebar/theme_colors_option.xml
new file mode 100644
index 00000000000000..40864691cd0b5e
--- /dev/null
+++ b/addons/html_builder/static/src/sidebar/theme_colors_option.xml
@@ -0,0 +1,168 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<templates xml:space="preserve">
+    <t t-name="html_builder.ThemeColorsOption">
+        <BuilderContext preview="false">
+            <!-- TODO
+            <we-alert class="o_old_color_system_warning d-none mt-2">
+                It appears your website is still using the old color system of
+                Odoo 13.0 in some places. We made sure it is still working but
+                we recommend you to try to use the new color system, which is
+                still customizable.
+            </we-alert>-->
+            <BuilderRow>
+                <div class="d-flex flex-row gap-3 w-100 justify-content-between" style="height: 50px">
+                    <div class="d-flex flex-column h-100 justify-content-between">
+                        <span class="font-italic">Main</span>
+                        <div class="d-flex flex-row">
+                            <BuilderColorPicker
+                                title="Primary"
+                                action="'customizeWebsiteColor'"
+                                actionParam="'o-color-1'"
+                                withGradient="false"/>
+                            <BuilderColorPicker
+                                title="Secondary"
+                                action="'customizeWebsiteColor'"
+                                actionParam="'o-color-2'"
+                                withGradient="false"/>
+                            <BuilderColorPicker
+                                action="'customizeWebsiteColor'"
+                                actionParam="'o-color-3'"
+                                withGradient="false"/>
+                        </div>
+                    </div>
+                    <div class="d-flex flex-column h-100 justify-content-between">
+                        <span class="font-italic">Light &amp; Dark</span>
+                        <div class="d-flex flex-row">
+                            <BuilderColorPicker
+                                action="'customizeWebsiteColor'"
+                                actionParam="'o-color-4'"
+                                withGradient="false"/>
+                            <BuilderColorPicker
+                                action="'customizeWebsiteColor'"
+                                actionParam="'o-color-5'"
+                                withGradient="false"/>
+                        </div>
+                    </div>
+                    <div class="d-flex flex-column h-100">
+                        <!-- TODO: use icon for palette selection button -->
+                        <!-- <button class="btn btn-primary h-100 p-2">
+                            <img class="p-2 h-100" src="/website/static/src/img/snippets_options/palette.svg"/>
+                        </button> -->
+                        <div class="d-flex flex-column h-100 justify-content-between">
+                            <span class="font-italic">Palette</span>
+                            <BuilderSelect action="'customizeWebsiteVariable'" actionParam="'color-palettes-name'">
+                                <t t-foreach="palettes" t-as="palette" t-key="palette.name">
+                                    <BuilderSelectItem actionValue="palette.name">
+                                        <div class="d-flex flex-row" style="min-width: 60px">
+                                            <t t-foreach="palette.colors" t-as="color" t-key="color">
+                                                <span class="w-100" t-attf-style="background-color: {{color}}; height: 25px"></span>
+                                            </t>
+                                        </div>
+                                    </BuilderSelectItem>
+                                </t>
+                            </BuilderSelect>
+                        </div>
+                    </div>
+                </div>
+            </BuilderRow>
+            <BuilderRow label.translate="Color Presets">
+                <div></div>     <!-- This is required, without it the row is not displayed at all -->
+                <t t-set-slot="collapse">
+                    <t t-foreach="state.presets" t-as="preset" t-key="preset.id">
+                        <BuilderRow>
+                            <div
+                                t-attf-class="
+                                    w-100 p-2 d-flex justify-content-between
+                                    align-items-center"
+                                t-attf-style="
+                                    background-color: {{preset.background}};
+                                    background-image: {{preset.backgroundGradient}};
+                                    color: {{preset.text}}">
+                                <h3
+                                    class="m-0"
+                                    t-attf-style="color: {{preset.headings}}">
+                                    Title
+                                </h3>
+                                <p class="m-0">
+                                    Text
+                                </p>
+                                <button
+                                    class="btn btn-sm"
+                                    t-attf-style="
+                                        background-color: {{preset.primaryBtn}};
+                                        color: {{preset.primaryBtnText}};
+                                        border: 1px solid {{preset.primaryBtnBorder}}">
+                                    Button
+                                </button>
+                                <button
+                                    class="btn btn-sm"
+                                    t-attf-style="
+                                        background-color: {{preset.secondaryBtn}};
+                                        color: {{preset.secondaryBtnText}};
+                                        border: 1px solid {{preset.secondaryBtnBorder}}">
+                                    Button
+                                </button>
+                            </div>
+                            <t t-set-slot="collapse">
+                                <BuilderRow label.translate="Background">
+                                    <BuilderColorPicker
+                                        action="'customizeWebsiteColor'"
+                                        actionParam="`o-cc${preset.id}-bg`"
+                                        withGradient="true"/>
+                                </BuilderRow>
+                                <BuilderRow label.translate="Text">
+                                    <BuilderColorPicker
+                                        action="'customizeWebsiteColor'"
+                                        actionParam="`o-cc${preset.id}-text`"
+                                        withGradient="false"/>
+                                </BuilderRow>
+                                <BuilderRow label.translate="Headings">
+                                    <BuilderColorPicker
+                                        action="'customizeWebsiteColor'"
+                                        actionParam="`o-cc${preset.id}-headings`"
+                                        withGradient="false"/>
+                                    <t t-set-slot="collapse">
+                                        <t t-foreach="[2, 3, 4, 5, 6]" t-as="j" t-key="j">
+                                            <BuilderRow label="`Headings ${j}`">
+                                                <BuilderColorPicker
+                                                    action="'customizeWebsiteColor'"
+                                                    actionParam="`o-cc${preset.id}-h${j}`"
+                                                    withGradient="false"/>
+                                            </BuilderRow>
+                                        </t>
+                                    </t>
+                                </BuilderRow>
+                                <BuilderRow label.translate="Links">
+                                    <BuilderColorPicker
+                                        action="'customizeWebsiteColor'"
+                                        actionParam="`o-cc${preset.id}-link`"
+                                        withGradient="false"/>
+                                </BuilderRow>
+                                <BuilderRow label.translate="Primary Buttons">
+                                    <BuilderColorPicker
+                                        action="'customizeWebsiteColor'"
+                                        actionParam="`o-cc${preset.id}-btn-primary`"
+                                        withGradient="false"/>
+                                    <BuilderColorPicker
+                                        action="'customizeWebsiteColor'"
+                                        actionParam="`o-cc${preset.id}-btn-primary-border`"
+                                        withGradient="false"/>
+                                </BuilderRow>
+                                <BuilderRow label.translate="Secondary Buttons">
+                                    <BuilderColorPicker
+                                        action="'customizeWebsiteColor'"
+                                        actionParam="`o-cc${preset.id}-btn-secondary`"
+                                        withGradient="false"/>
+                                    <BuilderColorPicker
+                                        action="'customizeWebsiteColor'"
+                                        actionParam="`o-cc${preset.id}-btn-secondary-border`"
+                                        withGradient="false"/>
+                                </BuilderRow>
+                            </t>
+                        </BuilderRow>
+                    </t>
+                </t>
+            </BuilderRow>
+        </BuilderContext>
+    </t>
+</templates>
diff --git a/addons/html_builder/static/src/sidebar/theme_tab.xml b/addons/html_builder/static/src/sidebar/theme_tab.xml
index 166e56019e69c3..1cae3e8eb7a004 100644
--- a/addons/html_builder/static/src/sidebar/theme_tab.xml
+++ b/addons/html_builder/static/src/sidebar/theme_tab.xml
@@ -18,44 +18,6 @@
         </div>
     </div>
 </t>
-
-<t t-name="html_builder.ThemeColorsOption">
-    <BuilderContext preview="false">
-        TODO
-        <!--
-        <we-alert class="o_old_color_system_warning d-none mt-2">
-            It appears your website is still using the old color system of
-            Odoo 13.0 in some places. We made sure it is still working but
-            we recommend you to try to use the new color system, which is
-            still customizable.
-        </we-alert>
-        <we-row class="o_we_theme_colors_selector">
-            <div class="o_we_theme_colors_selector_group">
-                <we-title>Main</we-title>
-                <we-colorpicker data-name="color_1_opt" title="Primary"
-                                data-customize-website-color="" data-color="o-color-1"
-                                data-use-css-color="true" data-selected-tab="custom-colors"/>
-                <we-colorpicker data-name="color_2_opt" title="Secondary"
-                                data-customize-website-color="" data-color="o-color-2"
-                                data-use-css-color="true" data-selected-tab="custom-colors"/>
-                <we-colorpicker data-customize-website-color="" data-color="o-color-3"
-                                data-use-css-color="true" data-selected-tab="custom-colors"/>
-            </div>
-            <div class="o_we_theme_colors_selector_group">
-                <we-title>Light &amp; Dark</we-title>
-                <we-colorpicker data-customize-website-color="" data-color="o-color-4"
-                                data-use-css-color="true" data-selected-tab="custom-colors"/>
-                <we-colorpicker data-customize-website-color="" data-color="o-color-5"
-                                data-use-css-color="true" data-selected-tab="custom-colors"/>
-            </div>
-            <we-select data-img="/website/static/src/img/snippets_options/palette.svg" class="o_we_theme_colors_select" data-variable="color-palettes-name"/>
-        </we-row>
-        <we-collapse class="o_we_theme_presets_collapse" string="Color Presets">
-        </we-collapse>
-        -->
-    </BuilderContext>
-</t>
-
 <t t-name="html_builder.ThemeWebsiteSettingsOption">
     <BuilderContext preview="false">
         <BuilderRow label.translate="Theme">
diff --git a/addons/html_builder/static/src/website_builder/plugins/theme_tab_plugin.js b/addons/html_builder/static/src/website_builder/plugins/theme_tab_plugin.js
index 3cefb748ae2530..9e4e8501b34d1e 100644
--- a/addons/html_builder/static/src/website_builder/plugins/theme_tab_plugin.js
+++ b/addons/html_builder/static/src/website_builder/plugins/theme_tab_plugin.js
@@ -3,6 +3,7 @@ import { Plugin } from "@html_editor/plugin";
 import { withSequence } from "@html_editor/utils/resource";
 import { _t } from "@web/core/l10n/translation";
 import { registry } from "@web/core/registry";
+import { ThemeColorsOption } from "@html_builder/sidebar/theme_colors_option";
 
 export class ThemeTabPlugin extends Plugin {
     static id = "themeTab";
@@ -11,11 +12,7 @@ export class ThemeTabPlugin extends Plugin {
         theme_options: [
             withSequence(
                 10,
-                this.getThemeOptionBlock(
-                    "theme-colors",
-                    _t("Colors"),
-                    "html_builder.ThemeColorsOption"
-                )
+                this.getThemeOptionBlock("theme-colors", _t("Colors"), null, ThemeColorsOption)
             ),
             withSequence(
                 20,
@@ -72,12 +69,21 @@ export class ThemeTabPlugin extends Plugin {
         ],
     };
 
-    getThemeOptionBlock(id, name, template) {
+    getThemeOptionBlock(id, name, template, Component = null) {
         // TODO Have a specific kind of options container that takes the specific parameters like name, no element, no selector...
         const el = this.document.createElement("div");
         el.dataset.name = name;
         this.document.body.appendChild(el); // Currently editingElement needs to be isConnected
 
+        const option = {
+            selector: "*",
+        };
+        if (template) {
+            option.template = template;
+        } else {
+            option.OptionComponent = Component;
+        }
+
         return {
             id: id,
             element: el,
@@ -85,12 +91,7 @@ export class ThemeTabPlugin extends Plugin {
             headerMiddleButton: false,
             isClonable: false,
             isRemovable: false,
-            options: [
-                {
-                    template: template,
-                    selector: "*",
-                },
-            ],
+            options: [option],
             optionsContainerTopButtons: [],
             snippetModel: {},
         };


Reviews:
user: login: bso-odoo
state: COMMENTED
author_association: NONE
submitted_at: 2025-03-07T15:55:38Z
user: login: bso-odoo
state: COMMENTED
author_association: NONE
submitted_at: 2025-03-07T15:59:26Z
user: login: FrancoisGe
state: COMMENTED
author_association: NONE
submitted_at: 2025-03-07T16:15:29Z
user: login: FrancoisGe
state: COMMENTED
author_association: NONE
submitted_at: 2025-03-07T16:23:43Z
user: login: emge-odoo
state: COMMENTED
author_association: NONE
submitted_at: 2025-03-07T16:23:45Z
user: login: emge-odoo
state: COMMENTED
author_association: NONE
submitted_at: 2025-03-07T16:24:44Z

Review comments:
diff_hunk: @@ -0,0 +1,78 @@
+import { Component, useState, onMounted } from "@odoo/owl";
+import { getCSSVariableValue } from "@html_builder/utils/utils_css";
+import { defaultBuilderComponents } from "../core/default_builder_components";
+
+export class ThemeColorsOption extends Component {
+    static template = "html_builder.ThemeColorsOption";
+    static components = { ...defaultBuilderComponents };
+    static props = {};
+    setup() {
+        this.presets = useState([]);
+        this.palettes = this._getPalettes();
+        const observer = new MutationObserver(this._updatePresets.bind(this));
+        onMounted(() => {
+            this.iframeDocument = document.querySelector("iframe").contentWindow.document;
+            observer.observe(this.iframeDocument.documentElement, {
+                attributes: true,
+                childList: true,
+                subtree: true,
+                attributeFilter: ["style"],
+            });
+            this._updatePresets();
+        });
+    }
+
+    _getPalettes() {
path: addons/html_builder/static/src/sidebar/theme_colors_option.js
user: login: bso-odoo
body: In Owl components, no need for the `_` prefix, everything is considered private.
created_at: 2025-03-07T15:55:38Z
author_association: NONE
diff_hunk: @@ -0,0 +1,154 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<templates xml:space="preserve">
+    <t t-name="html_builder.ThemeColorsOption">
+        <BuilderContext preview="false">
+            <!-- TODO
+            <we-alert class="o_old_color_system_warning d-none mt-2">
+                It appears your website is still using the old color system of
+                Odoo 13.0 in some places. We made sure it is still working but
+                we recommend you to try to use the new color system, which is
+                still customizable.
+            </we-alert>-->
+            <BuilderRow>
+                <div class="d-flex flex-row gap-3 w-100 justify-content-between" style="height: 50px">
+                    <div class="d-flex flex-column h-100 justify-content-between">
+                        <span class="font-italic">Main</span>
+                        <div class="d-flex flex-row">
+                            <BuilderColorPicker
path: addons/html_builder/static/src/sidebar/theme_colors_option.xml
user: login: bso-odoo
body: Check the various color pickers, most of them should not allow for gradients.
created_at: 2025-03-07T15:59:26Z
author_association: NONE
diff_hunk: @@ -0,0 +1,154 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<templates xml:space="preserve">
+    <t t-name="html_builder.ThemeColorsOption">
+        <BuilderContext preview="false">
+            <!-- TODO
+            <we-alert class="o_old_color_system_warning d-none mt-2">
+                It appears your website is still using the old color system of
+                Odoo 13.0 in some places. We made sure it is still working but
+                we recommend you to try to use the new color system, which is
+                still customizable.
+            </we-alert>-->
+            <BuilderRow>
path: addons/html_builder/static/src/sidebar/theme_colors_option.xml
user: login: FrancoisGe
body: You probably don t need to use BuilderRow if you don t have a label
created_at: 2025-03-07T16:15:29Z
author_association: NONE
diff_hunk: @@ -0,0 +1,78 @@
+import { Component, useState, onMounted } from "@odoo/owl";
+import { getCSSVariableValue } from "@html_builder/utils/utils_css";
+import { defaultBuilderComponents } from "../core/default_builder_components";
+
+export class ThemeColorsOption extends Component {
+    static template = "html_builder.ThemeColorsOption";
+    static components = { ...defaultBuilderComponents };
+    static props = {};
+    setup() {
+        this.presets = useState([]);
+        this.palettes = this._getPalettes();
+        const observer = new MutationObserver(this._updatePresets.bind(this));
+        onMounted(() => {
+            this.iframeDocument = document.querySelector("iframe").contentWindow.document;
+            observer.observe(this.iframeDocument.documentElement, {
+                attributes: true,
+                childList: true,
+                subtree: true,
+                attributeFilter: ["style"],
+            });
+            this._updatePresets();
+        });
path: addons/html_builder/static/src/sidebar/theme_colors_option.js
user: login: FrancoisGe
body: Why ? Listen DOM_UPDATED is probably enough. You maybe just need to add custom mutation (PR in progess https://github.com/odoo-dev/odoo/pull/4128)
created_at: 2025-03-07T16:18:49Z
author_association: NONE
diff_hunk: @@ -0,0 +1,154 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<templates xml:space="preserve">
+    <t t-name="html_builder.ThemeColorsOption">
+        <BuilderContext preview="false">
+            <!-- TODO
+            <we-alert class="o_old_color_system_warning d-none mt-2">
+                It appears your website is still using the old color system of
+                Odoo 13.0 in some places. We made sure it is still working but
+                we recommend you to try to use the new color system, which is
+                still customizable.
+            </we-alert>-->
+            <BuilderRow>
+                <div class="d-flex flex-row gap-3 w-100 justify-content-between" style="height: 50px">
+                    <div class="d-flex flex-column h-100 justify-content-between">
+                        <span class="font-italic">Main</span>
+                        <div class="d-flex flex-row">
+                            <BuilderColorPicker
+                                title="Primary"
+                                action="'customizeWebsiteColor'"
path: addons/html_builder/static/src/sidebar/theme_colors_option.xml
user: login: FrancoisGe
body: Where did you define "customizeWebsiteColor"
created_at: 2025-03-07T16:20:19Z
author_association: NONE
diff_hunk: @@ -0,0 +1,154 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<templates xml:space="preserve">
+    <t t-name="html_builder.ThemeColorsOption">
+        <BuilderContext preview="false">
+            <!-- TODO
+            <we-alert class="o_old_color_system_warning d-none mt-2">
+                It appears your website is still using the old color system of
+                Odoo 13.0 in some places. We made sure it is still working but
+                we recommend you to try to use the new color system, which is
+                still customizable.
+            </we-alert>-->
+            <BuilderRow>
path: addons/html_builder/static/src/sidebar/theme_colors_option.xml
user: login: emge-odoo
body: I used it to make sure that the padding is right.
created_at: 2025-03-07T16:23:45Z
author_association: NONE
diff_hunk: @@ -0,0 +1,154 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<templates xml:space="preserve">
+    <t t-name="html_builder.ThemeColorsOption">
+        <BuilderContext preview="false">
+            <!-- TODO
+            <we-alert class="o_old_color_system_warning d-none mt-2">
+                It appears your website is still using the old color system of
+                Odoo 13.0 in some places. We made sure it is still working but
+                we recommend you to try to use the new color system, which is
+                still customizable.
+            </we-alert>-->
+            <BuilderRow>
+                <div class="d-flex flex-row gap-3 w-100 justify-content-between" style="height: 50px">
+                    <div class="d-flex flex-column h-100 justify-content-between">
+                        <span class="font-italic">Main</span>
+                        <div class="d-flex flex-row">
+                            <BuilderColorPicker
+                                title="Primary"
+                                action="'customizeWebsiteColor'"
path: addons/html_builder/static/src/sidebar/theme_colors_option.xml
user: login: emge-odoo
body: it is in theme_tab_plugin.js
created_at: 2025-03-07T16:24:44Z
author_association: NONE

PR comments:
user: login: robodoo
created_at: 2025-03-07T15:37:59Z
body: This PR targets the un-managed branch odoo-dev/odoo:master-mysterious-egg, it needs to be retargeted before it can be merged.
author_association: NONE
user: login: robodoo
created_at: 2025-03-07T15:38:10Z
body: This PR targets the un-managed branch odoo-dev/odoo:master-mysterious-egg, it needs to be retargeted before it can be merged.
author_association: NONE
user: login: bso-odoo
created_at: 2025-03-28T15:36:52Z
body: To do after merge:
- support gradients
- palette icon
author_association: NONE