Skip to content

Commit 9f3042b

Browse files
committed
Convert HeaderBox
1 parent 9e76d8f commit 9f3042b

File tree

10 files changed

+155
-46
lines changed

10 files changed

+155
-46
lines changed

addons/html_builder/static/src/core/core_builder_action_plugin.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ export function withoutTransition(editingElement, callback) {
1616

1717
export class CoreBuilderActionPlugin extends Plugin {
1818
static id = "coreBuilderAction";
19-
static shared = ["setStyle"];
19+
static shared = ["setStyle", "getStyleAction"];
2020
resources = {
2121
builder_actions: this.getActions(),
2222
builder_style_actions: this.getStyleActions(),

addons/html_builder/static/src/plugins/border_configurator_option.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@ export class BorderConfigurator extends BaseOptionComponent {
77
direction: { type: String, optional: true },
88
withRoundCorner: { type: Boolean, optional: true },
99
withBSClass: { type: Boolean, optional: true },
10+
action: { type: String, optional: true },
1011
};
1112
static defaultProps = {
1213
withRoundCorner: true,
1314
withBSClass: true, // TODO remove, and actually configure propertly in caller
15+
action: "styleAction",
1416
};
1517

1618
setup() {

addons/html_builder/static/src/plugins/border_configurator_option.xml

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,19 @@
33

44
<t t-name="html_builder.BorderConfiguratorOption">
55
<BuilderRow label="props.label">
6-
<BuilderNumberInput styleAction="{ mainParam: getStyleActionParam('width'), extraClass: props.withBSClass and 'border' }" unit="'px'" min="0" default="0" composable="true"/>
7-
<BuilderSelect styleAction="getStyleActionParam('style')" t-if="state.hasBorder">
8-
<BuilderSelectItem title="'Solid'" styleActionValue="'solid'"><div class="o_we_border_preview" style="border-style: solid;"/></BuilderSelectItem>
9-
<BuilderSelectItem title="'Dashed'" styleActionValue="'dashed'"><div class="o_we_border_preview" style="border-style: dashed;"/></BuilderSelectItem>
10-
<BuilderSelectItem title="'Dotted'" styleActionValue="'dotted'"><div class="o_we_border_preview" style="border-style: dotted;"/></BuilderSelectItem>
11-
<BuilderSelectItem title="'Double'" styleActionValue="'double'"><div class="o_we_border_preview" style="border-style: double; border-left: none; border-right: none;"/></BuilderSelectItem>
6+
<BuilderNumberInput action="props.action" actionParam="{ mainParam: getStyleActionParam('width'), extraClass: props.withBSClass and 'border' }" unit="'px'" min="0" default="0" composable="true"/>
7+
<BuilderSelect action="props.action" actionParam="getStyleActionParam('style')" t-if="state.hasBorder">
8+
<BuilderSelectItem title="'Solid'" actionValue="'solid'"><div class="o_we_border_preview" style="border-style: solid;"/></BuilderSelectItem>
9+
<BuilderSelectItem title="'Dashed'" actionValue="'dashed'"><div class="o_we_border_preview" style="border-style: dashed;"/></BuilderSelectItem>
10+
<BuilderSelectItem title="'Dotted'" actionValue="'dotted'"><div class="o_we_border_preview" style="border-style: dotted;"/></BuilderSelectItem>
11+
<BuilderSelectItem title="'Double'" actionValue="'double'"><div class="o_we_border_preview" style="border-style: double; border-left: none; border-right: none;"/></BuilderSelectItem>
1212
</BuilderSelect>
13-
<BuilderColorPicker styleAction="getStyleActionParam('color')" t-if="state.hasBorder"/>
13+
<BuilderColorPicker action="props.action" actionParam="getStyleActionParam('color')" t-if="state.hasBorder"/>
1414
</BuilderRow>
1515

1616
<!-- TODO: handle the dependency with border_width_opt bg_color_opt-->
1717
<BuilderRow t-if="props.withRoundCorner" label.translate="Round Corners">
18-
<BuilderNumberInput styleAction="{ mainParam: 'border-radius', extraClass: props.withBSClass and 'rounded' }" unit="'px'" default="0" min="0" composable="true"/>
18+
<BuilderNumberInput action="props.action" actionParam="{ mainParam: 'border-radius', extraClass: props.withBSClass and 'rounded' }" unit="'px'" default="0" min="0" composable="true"/>
1919
</BuilderRow>
2020
</t>
2121
</templates>

addons/html_builder/static/src/plugins/shadow_option.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,12 @@ import { BaseOptionComponent } from "@html_builder/core/utils";
22

33
export class ShadowOption extends BaseOptionComponent {
44
static template = "html_builder.ShadowOption";
5-
static props = {};
5+
static props = {
6+
setShadowModeAction: { type: String, optional: true },
7+
setShadowAction: { type: String, optional: true },
8+
};
9+
static defaultProps = {
10+
setShadowModeAction: "setShadowMode",
11+
setShadowAction: "setShadow",
12+
};
613
}

addons/html_builder/static/src/plugins/shadow_option.xml

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,28 +3,28 @@
33

44
<t t-name="html_builder.ShadowOption">
55
<BuilderRow label.translate="Shadow">
6-
<BuilderButtonGroup action="'setShadowMode'">
7-
<BuilderButton actionParam="'none'" id="'no_shadow'">None</BuilderButton>
8-
<BuilderButton actionParam="'outset'" title.translate="Outset" iconImg="'/html_builder/static/img/options/shadow_out.svg'"/>
9-
<BuilderButton actionParam="'inset'" title.translate="Inset" iconImg="'/html_builder/static/img/options/shadow_in.svg'"/>
6+
<BuilderButtonGroup action="props.setShadowModeAction">
7+
<BuilderButton actionValue="'none'" id="'no_shadow'">None</BuilderButton>
8+
<BuilderButton actionValue="'outset'" title.translate="Outset" iconImg="'/html_builder/static/img/options/shadow_out.svg'"/>
9+
<BuilderButton actionValue="'inset'" title.translate="Inset" iconImg="'/html_builder/static/img/options/shadow_in.svg'"/>
1010
</BuilderButtonGroup>
1111
</BuilderRow>
12-
<BuilderContext t-if="!this.isActiveItem('no_shadow')">
12+
<BuilderContext t-if="!this.isActiveItem('no_shadow')" action="props.setShadowAction">
1313
<BuilderRow label.translate="Color" level="1">
14-
<BuilderColorPicker action="'setShadow'" actionParam="'color'"/>
14+
<BuilderColorPicker actionParam="'color'"/>
1515
</BuilderRow>
1616

1717
<BuilderRow label.translate="Offset (X, Y)" level="1">
18-
<BuilderNumberInput action="'setShadow'" actionParam="'offsetX'" unit="'px'"/>
19-
<BuilderNumberInput action="'setShadow'" actionParam="'offsetY'" unit="'px'"/>
18+
<BuilderNumberInput actionParam="'offsetX'" unit="'px'"/>
19+
<BuilderNumberInput actionParam="'offsetY'" unit="'px'"/>
2020
</BuilderRow>
2121

2222
<BuilderRow label.translate="Blur" level="1">
23-
<BuilderNumberInput action="'setShadow'" actionParam="'blur'" unit="'px'"/>
23+
<BuilderNumberInput actionParam="'blur'" unit="'px'"/>
2424
</BuilderRow>
2525

2626
<BuilderRow label.translate="Spread" level="1">
27-
<BuilderNumberInput action="'setShadow'" actionParam="'spread'" unit="'px'"/>
27+
<BuilderNumberInput actionParam="'spread'" unit="'px'"/>
2828
</BuilderRow>
2929
</BuilderContext>
3030
</t>

addons/html_builder/static/src/plugins/shadow_option_plugin.js

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,18 @@ const shadowClass = "shadow";
55

66
class ShadowOptionPlugin extends Plugin {
77
static id = "shadowOption";
8+
static shared = ["getActions"];
89
resources = {
910
builder_actions: this.getActions(),
1011
};
1112

1213
getActions() {
1314
return {
1415
setShadowMode: {
15-
isApplied: ({ editingElement, param: { mainParam: shadowMode } }) => {
16-
const currentBoxShadow = editingElement.style["box-shadow"];
17-
if (shadowMode === "none") {
18-
return currentBoxShadow === "";
19-
}
20-
if (shadowMode === "inset") {
21-
return currentBoxShadow.includes("inset");
22-
}
23-
if (shadowMode === "outset") {
24-
return !currentBoxShadow.includes("inset") && currentBoxShadow !== "";
25-
}
26-
},
27-
apply: ({ editingElement, param: { mainParam: shadowMode } }) => {
16+
isApplied: ({ editingElement, value: shadowMode }) =>
17+
shadowMode === getShadowMode(editingElement),
18+
getValue: ({ editingElement }) => getShadowMode(editingElement, "mode"),
19+
apply: ({ editingElement, value: shadowMode }) => {
2820
if (shadowMode === "none") {
2921
editingElement.classList.remove(shadowClass);
3022
setBoxShadow(editingElement, "");
@@ -60,7 +52,7 @@ class ShadowOptionPlugin extends Plugin {
6052
}
6153
}
6254

63-
function getDefaultShadow(mode) {
55+
export function getDefaultShadow(mode) {
6456
const el = document.createElement("div");
6557
el.classList.add(shadowClass);
6658
document.body.appendChild(el);
@@ -69,20 +61,33 @@ function getDefaultShadow(mode) {
6961
return shadow;
7062
}
7163

72-
function getCurrentShadow(editingElement) {
73-
return parseShadow(editingElement.style["box-shadow"]);
64+
function getShadowMode(editingElement) {
65+
const currentBoxShadow = getComputedStyle(editingElement)["box-shadow"];
66+
if (currentBoxShadow === "none") {
67+
return "none";
68+
}
69+
if (currentBoxShadow.includes("inset")) {
70+
return "inset";
71+
}
72+
if (!currentBoxShadow.includes("inset") && currentBoxShadow !== "none") {
73+
return "outset";
74+
}
75+
}
76+
77+
export function getCurrentShadow(editingElement) {
78+
return parseShadow(getComputedStyle(editingElement)["box-shadow"]);
7479
}
7580

7681
function parseShadow(value) {
77-
if (!value) {
82+
if (!value || value === "none") {
7883
return {};
7984
}
8085
const regex =
8186
/(?<color>(rgb(a)?\([^)]*\))|(var\([^)]+\)))\s+(?<offsetX>\d+px)\s+(?<offsetY>\d+px)\s+(?<blur>\d+px)\s+(?<spread>\d+px)(\s+)?(?<mode>\w+)?/;
8287
return value.match(regex).groups;
8388
}
8489

85-
function shadowToString(shadow) {
90+
export function shadowToString(shadow) {
8691
if (!shadow) {
8792
return "";
8893
}

addons/html_builder/static/src/website_builder/plugins/customize_website_plugin.js

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export class CustomizeWebsitePlugin extends Plugin {
1212
static dependencies = ["builderActions", "history", "savePlugin"];
1313
static shared = [
1414
"customizeWebsiteColors",
15+
"customizeWebsiteVariables",
1516
"loadTemplateKey",
1617
"makeSCSSCusto",
1718
"toggleTemplate",
@@ -82,7 +83,6 @@ export class CustomizeWebsitePlugin extends Plugin {
8283
}); // reloads bundles
8384
} else {
8485
await this.customizeWebsiteColors({ [color]: value }, { colorType });
85-
await this.reloadBundles();
8686
}
8787
},
8888
}),
@@ -320,16 +320,14 @@ export class CustomizeWebsitePlugin extends Plugin {
320320
}
321321
}
322322
}
323-
return this.makeSCSSCusto(url, finalColors, nullValue);
323+
await this.makeSCSSCusto(url, finalColors, nullValue);
324+
await this.reloadBundles();
324325
}
325326
async makeSCSSCusto(url, values, defaultValue = "null") {
326327
Object.keys(values).forEach((key) => {
327328
values[key] = values[key] || defaultValue;
328329
});
329-
return this.services.orm.call("web_editor.assets", "make_scss_customization", [
330-
url,
331-
values,
332-
]);
330+
await this.services.orm.call("web_editor.assets", "make_scss_customization", [url, values]);
333331
}
334332
async reloadBundles() {
335333
const bundles = await rpc("/website/theme_customize_bundle_reload");
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { BaseOptionComponent, useDomState } from "@html_builder/core/utils";
2+
import { BorderConfigurator } from "@html_builder/plugins/border_configurator_option";
3+
import { ShadowOption } from "@html_builder/plugins/shadow_option";
4+
5+
export class HeaderBorderOption extends BaseOptionComponent {
6+
static template = "website.HeaderBorderOption";
7+
static props = {};
8+
static components = { BorderConfigurator, ShadowOption };
9+
10+
setup() {
11+
super.setup();
12+
this.domState = useDomState((editingElement) => ({
13+
withRoundCorner: !editingElement.classList.contains("o_header_force_no_radius"),
14+
}));
15+
}
16+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<templates xml:space="preserve">
3+
4+
<t t-name="website.HeaderBorderOption">
5+
<BuilderContext preview="false">
6+
<BorderConfigurator label.translate="Border" action="'styleActionHeader'" withRoundCorner="this.domState.withRoundCorner"/>
7+
<ShadowOption setShadowModeAction="'setShadowModeHeader'" setShadowAction="'setShadowHeader'"/>
8+
</BuilderContext>
9+
</t>
10+
11+
</templates>

addons/html_builder/static/src/website_builder/plugins/header_option.js

Lines changed: 72 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,22 @@
1-
import { registry } from "@web/core/registry";
1+
import {
2+
getCurrentShadow,
3+
getDefaultShadow,
4+
shadowToString,
5+
} from "@html_builder/plugins/shadow_option_plugin";
6+
import { after, SNIPPET_SPECIFIC_NEXT } from "@html_builder/utils/option_sequence";
27
import { Plugin } from "@html_editor/plugin";
38
import { withSequence } from "@html_editor/utils/resource";
4-
import { after, SNIPPET_SPECIFIC_NEXT } from "@html_builder/utils/option_sequence";
9+
import { registry } from "@web/core/registry";
10+
import { HeaderBorderOption } from "./header_border_option";
511

612
export const HEADER_TEMPLATE = SNIPPET_SPECIFIC_NEXT;
713
export const HEADER_SCROLL_EFFECT = after(SNIPPET_SPECIFIC_NEXT);
814
export const HEADER_ELEMENT = after(HEADER_SCROLL_EFFECT);
15+
export const HEADER_BORDER = after(HEADER_ELEMENT);
916

1017
class HeaderOptionPlugin extends Plugin {
1118
static id = "headerOption";
19+
static dependencies = ["coreBuilderAction", "customizeWebsite", "shadowOption"];
1220

1321
resources = {
1422
builder_options: [
@@ -31,8 +39,70 @@ class HeaderOptionPlugin extends Plugin {
3139
selector: "header",
3240
groups: ["website.group_website_designer"],
3341
}),
42+
withSequence(HEADER_BORDER, {
43+
editableOnly: false,
44+
OptionComponent: HeaderBorderOption,
45+
selector: "#wrapwrap > header",
46+
applyTo: ".navbar:not(.d-none)",
47+
groups: ["website.group_website_designer"],
48+
}),
3449
],
50+
builder_actions: this.getActions(),
3551
};
52+
53+
getActions() {
54+
const styleAction = this.dependencies.coreBuilderAction.getStyleAction();
55+
const { setShadowMode, setShadow } = this.dependencies.shadowOption.getActions();
56+
const withHistoryFromLoad = this.dependencies.customizeWebsite.withHistoryFromLoad;
57+
return {
58+
styleActionHeader: withHistoryFromLoad({
59+
...styleAction,
60+
getValue: (...args) => {
61+
const { param } = args[0];
62+
const value = styleAction.getValue(...args);
63+
if (param.mainParam === "border-width") {
64+
return value.replace(/(^|\s)0px/gi, "").trim() || value;
65+
}
66+
return value;
67+
},
68+
load: async ({ param, value }) => {
69+
const styleName = param.mainParam;
70+
71+
if (styleName === "border-color") {
72+
return this.dependencies.customizeWebsite.customizeWebsiteColors({
73+
"menu-border-color": value,
74+
});
75+
}
76+
return this.dependencies.customizeWebsite.customizeWebsiteVariables({
77+
[`menu-${styleName}`]: value,
78+
});
79+
},
80+
}),
81+
setShadowModeHeader: withHistoryFromLoad({
82+
...setShadowMode,
83+
load: ({ value: shadowMode }) => {
84+
const defaultShadow =
85+
shadowMode === "none" ? "none" : getDefaultShadow(shadowMode);
86+
return this.dependencies.customizeWebsite.customizeWebsiteVariables({
87+
"menu-box-shadow": defaultShadow,
88+
});
89+
},
90+
apply: () => {},
91+
}),
92+
setShadowHeader: withHistoryFromLoad({
93+
...setShadow,
94+
load: ({ editingElement, param: { mainParam: attributeName }, value }) => {
95+
const shadow = getCurrentShadow(editingElement);
96+
shadow[attributeName] = value;
97+
98+
return this.dependencies.customizeWebsite.customizeWebsiteVariables({
99+
"menu-box-shadow": shadowToString(shadow),
100+
});
101+
},
102+
apply: () => {},
103+
}),
104+
};
105+
}
36106
}
37107

38108
registry.category("website-plugins").add(HeaderOptionPlugin.id, HeaderOptionPlugin);

0 commit comments

Comments
 (0)