diff --git a/wp-content/themes/moonshine/acf-json/group_abstract_builder.json b/wp-content/themes/moonshine/acf-json/group_abstract_builder.json index 6fe4d45..d4d0d5e 100644 --- a/wp-content/themes/moonshine/acf-json/group_abstract_builder.json +++ b/wp-content/themes/moonshine/acf-json/group_abstract_builder.json @@ -96,7 +96,11 @@ "min": "", "max": "", "acfe_flexible_modal_edit_size": "", - "acfe_flexible_settings": ["group_layout_contained"], + "acfe_flexible_settings": [ + "group_layout_colored", + "group_layout_contained", + "group_layout_padded" + ], "acfe_flexible_settings_size": "large", "acfe_flexible_render_template": false, "acfe_flexible_render_style": false, @@ -190,7 +194,7 @@ "min": "", "max": "", "acfe_flexible_modal_edit_size": "", - "acfe_flexible_settings": "", + "acfe_flexible_settings": ["group_layout_colored", "group_layout_padded"], "acfe_flexible_settings_size": "large", "acfe_flexible_render_template": false, "acfe_flexible_render_style": false, @@ -236,5 +240,5 @@ "graphql_types": "", "acfe_meta": "", "acfe_note": "", - "modified": 1769779666 + "modified": 1770740697 } diff --git a/wp-content/themes/moonshine/acf-json/group_layout_colored.json b/wp-content/themes/moonshine/acf-json/group_layout_colored.json new file mode 100644 index 0000000..f689da7 --- /dev/null +++ b/wp-content/themes/moonshine/acf-json/group_layout_colored.json @@ -0,0 +1,64 @@ +{ + "key": "group_layout_colored", + "title": "Layout - Colored", + "fields": [ + { + "key": "field_693c8c945ce51", + "label": "Variante de couleur", + "name": "color", + "aria-label": "", + "type": "button_group", + "instructions": "", + "required": 1, + "conditional_logic": 0, + "wrapper": { + "width": "", + "class": "", + "id": "" + }, + "choices": { + "default": "Par défaut", + "muted": "Atténué", + "elevated": "Surélevé", + "accented": "Accentué", + "inverted": "Inversé", + "primary": "Couleur principale" + }, + "default_value": "default", + "return_format": "value", + "allow_null": 0, + "allow_in_bindings": 0, + "layout": "horizontal", + "show_in_graphql": 1, + "graphql_description": "", + "graphql_field_name": "color", + "graphql_non_null": 1 + } + ], + "location": [ + [ + { + "param": "abstract" + } + ] + ], + "menu_order": 0, + "position": "normal", + "style": "seamless", + "label_placement": "top", + "instruction_placement": "label", + "hide_on_screen": "", + "active": true, + "description": "", + "show_in_rest": 0, + "display_title": "", + "acfe_autosync": ["json"], + "acfe_form": 0, + "show_in_graphql": 1, + "graphql_field_name": "GroupLayoutColored", + "map_graphql_types_from_location_rules": 0, + "graphql_types": "", + "acfe_meta": "", + "acfe_note": "", + "modified": 1770132035 +} diff --git a/wp-content/themes/moonshine/acf-json/group_layout_contained.json b/wp-content/themes/moonshine/acf-json/group_layout_contained.json index 21a630a..875adb9 100644 --- a/wp-content/themes/moonshine/acf-json/group_layout_contained.json +++ b/wp-content/themes/moonshine/acf-json/group_layout_contained.json @@ -4,10 +4,10 @@ "fields": [ { "key": "field_68dc29d78941c", - "label": "Conteneur", + "label": "Largeur du contenu", "name": "container", "aria-label": "", - "type": "select", + "type": "button_group", "instructions": "", "required": 1, "conditional_logic": 0, @@ -21,101 +21,17 @@ "xl": "1280px", "lg": "1024px", "fluid": "Largeur fluide", - "none": "Pleine largeur" + "fullbleed": "Pleine largeur" }, "default_value": "default", "return_format": "value", - "multiple": 0, - "max": "", - "prepend": "", - "append": "", - "required_message": "", "allow_null": 0, "allow_in_bindings": 0, - "ui": 0, + "layout": "horizontal", "show_in_graphql": 1, "graphql_description": "", "graphql_field_name": "container", - "graphql_non_null": 1, - "ajax": 0, - "placeholder": "", - "create_options": 0, - "save_options": 0, - "allow_custom": 0, - "search_placeholder": "", - "min": "" - }, - { - "key": "field_693c8c3b5ce50", - "label": "Espacement vertical", - "name": "vertical_padding", - "aria-label": "", - "type": "select", - "instructions": "", - "required": 1, - "conditional_logic": 0, - "wrapper": { - "width": "", - "class": "", - "id": "" - }, - "choices": { - "sm": "Petit (12px)", - "md": "Medium (24px)", - "lg": "Grand (48px)" - }, - "default_value": "md", - "return_format": "value", - "multiple": 0, - "allow_null": 0, - "allow_in_bindings": 0, - "ui": 0, - "show_in_graphql": 1, - "graphql_description": "", - "graphql_field_name": "verticalPadding", - "graphql_non_null": 1, - "ajax": 0, - "placeholder": "", - "create_options": 0, - "save_options": 0, - "allow_custom": 0, - "search_placeholder": "" - }, - { - "key": "field_693c8c945ce51", - "label": "Couleur d'arrière-plan", - "name": "bg_color", - "aria-label": "", - "type": "select", - "instructions": "", - "required": 1, - "conditional_logic": 0, - "wrapper": { - "width": "", - "class": "", - "id": "" - }, - "choices": { - "default": "Par défaut", - "muted": "Atténué", - "inverted": "Inversé" - }, - "default_value": "default", - "return_format": "value", - "multiple": 0, - "allow_null": 0, - "allow_in_bindings": 0, - "ui": 0, - "show_in_graphql": 1, - "graphql_description": "", - "graphql_field_name": "bgColor", - "graphql_non_null": 1, - "ajax": 0, - "placeholder": "", - "create_options": 0, - "save_options": 0, - "allow_custom": 0, - "search_placeholder": "" + "graphql_non_null": 1 } ], "location": [ @@ -143,5 +59,5 @@ "graphql_types": "", "acfe_meta": "", "acfe_note": "", - "modified": 1768358794 + "modified": 1770740626 } diff --git a/wp-content/themes/moonshine/acf-json/group_layout_padded.json b/wp-content/themes/moonshine/acf-json/group_layout_padded.json new file mode 100644 index 0000000..0bf8bc3 --- /dev/null +++ b/wp-content/themes/moonshine/acf-json/group_layout_padded.json @@ -0,0 +1,62 @@ +{ + "key": "group_layout_padded", + "title": "Layout - Padded", + "fields": [ + { + "key": "field_693c8c3b5ce50", + "label": "Espacement intérieur vertical", + "name": "vertical_padding", + "aria-label": "", + "type": "button_group", + "instructions": "", + "required": 1, + "conditional_logic": 0, + "wrapper": { + "width": "", + "class": "", + "id": "" + }, + "choices": { + "none": "Aucun", + "sm": "Petit (12px)", + "md": "Medium (24px)", + "lg": "Grand (48px)" + }, + "default_value": "md", + "return_format": "value", + "allow_null": 0, + "allow_in_bindings": 0, + "layout": "horizontal", + "show_in_graphql": 1, + "graphql_description": "", + "graphql_field_name": "verticalPadding", + "graphql_non_null": 1 + } + ], + "location": [ + [ + { + "param": "abstract" + } + ] + ], + "menu_order": 0, + "position": "normal", + "style": "default", + "label_placement": "left", + "instruction_placement": "label", + "hide_on_screen": "", + "active": true, + "description": "", + "show_in_rest": 0, + "display_title": "", + "acfe_autosync": ["json"], + "acfe_form": 0, + "show_in_graphql": 1, + "graphql_field_name": "GroupLayoutPadded", + "map_graphql_types_from_location_rules": 0, + "graphql_types": "", + "acfe_meta": "", + "acfe_note": "", + "modified": 1770740636 +} diff --git a/wp-content/themes/moonshine/app/components/builder/LayoutColored.fragment.gql b/wp-content/themes/moonshine/app/components/builder/LayoutColored.fragment.gql new file mode 100644 index 0000000..8186293 --- /dev/null +++ b/wp-content/themes/moonshine/app/components/builder/LayoutColored.fragment.gql @@ -0,0 +1,3 @@ +fragment LayoutColored on GroupLayoutColored_Fields { + color +} diff --git a/wp-content/themes/moonshine/app/components/builder/LayoutContained.fragment.gql b/wp-content/themes/moonshine/app/components/builder/LayoutContained.fragment.gql index 553e93d..1913ad8 100644 --- a/wp-content/themes/moonshine/app/components/builder/LayoutContained.fragment.gql +++ b/wp-content/themes/moonshine/app/components/builder/LayoutContained.fragment.gql @@ -1,5 +1,3 @@ fragment LayoutContained on GroupLayoutContained_Fields { container - verticalPadding - bgColor } diff --git a/wp-content/themes/moonshine/app/components/builder/LayoutContained.vue b/wp-content/themes/moonshine/app/components/builder/LayoutContained.vue deleted file mode 100644 index 188c1c2..0000000 --- a/wp-content/themes/moonshine/app/components/builder/LayoutContained.vue +++ /dev/null @@ -1,50 +0,0 @@ - - - diff --git a/wp-content/themes/moonshine/app/components/builder/LayoutPadded.fragment.gql b/wp-content/themes/moonshine/app/components/builder/LayoutPadded.fragment.gql new file mode 100644 index 0000000..89af36f --- /dev/null +++ b/wp-content/themes/moonshine/app/components/builder/LayoutPadded.fragment.gql @@ -0,0 +1,3 @@ +fragment LayoutPadded on GroupLayoutPadded_Fields { + verticalPadding +} diff --git a/wp-content/themes/moonshine/app/components/builder/LayoutWrapper.vue b/wp-content/themes/moonshine/app/components/builder/LayoutWrapper.vue new file mode 100644 index 0000000..d3db55b --- /dev/null +++ b/wp-content/themes/moonshine/app/components/builder/LayoutWrapper.vue @@ -0,0 +1,12 @@ + + + diff --git a/wp-content/themes/moonshine/app/components/nodes/NodePage.global.vue b/wp-content/themes/moonshine/app/components/nodes/NodePage.global.vue index d72e491..c5b6009 100644 --- a/wp-content/themes/moonshine/app/components/nodes/NodePage.global.vue +++ b/wp-content/themes/moonshine/app/components/nodes/NodePage.global.vue @@ -6,9 +6,7 @@ defineProps(); diff --git a/wp-content/themes/moonshine/app/components/page/PageHeader.vue b/wp-content/themes/moonshine/app/components/page/PageHeader.vue new file mode 100644 index 0000000..25a8d6b --- /dev/null +++ b/wp-content/themes/moonshine/app/components/page/PageHeader.vue @@ -0,0 +1,15 @@ + + + diff --git a/wp-content/themes/moonshine/app/components/sections/SectionAuthConnexion.vue b/wp-content/themes/moonshine/app/components/sections/SectionAuthConnexion.vue index 0d13a8c..e7f2959 100644 --- a/wp-content/themes/moonshine/app/components/sections/SectionAuthConnexion.vue +++ b/wp-content/themes/moonshine/app/components/sections/SectionAuthConnexion.vue @@ -1,18 +1,19 @@ diff --git a/wp-content/themes/moonshine/app/components/sections/SectionHeroSplit.fragment.gql b/wp-content/themes/moonshine/app/components/sections/SectionHeroSplit.fragment.gql index 21effec..cd0fde7 100644 --- a/wp-content/themes/moonshine/app/components/sections/SectionHeroSplit.fragment.gql +++ b/wp-content/themes/moonshine/app/components/sections/SectionHeroSplit.fragment.gql @@ -2,4 +2,8 @@ fragment SectionHeroSplit on GroupAbstractBuilderSectionsHeroSplitLayout { content reverse ...AcfMedia + layoutSettings { + ...LayoutColored + ...LayoutPadded + } } diff --git a/wp-content/themes/moonshine/app/components/sections/SectionHeroSplit.global.vue b/wp-content/themes/moonshine/app/components/sections/SectionHeroSplit.global.vue index fc7722c..e870123 100644 --- a/wp-content/themes/moonshine/app/components/sections/SectionHeroSplit.global.vue +++ b/wp-content/themes/moonshine/app/components/sections/SectionHeroSplit.global.vue @@ -3,8 +3,8 @@ import { tv, type VariantProps } from "tailwind-variants"; import type { SectionHeroSplitFragment } from "#graphql/operations"; const tvSectionHeroSplit = tv({ + extend: tvLayoutWrapper, slots: { - base: "py-6", container: "container flex flex-col items-center gap-6", content: "flex-1", media: "w-full basis-1/2", @@ -27,6 +27,7 @@ const tvSectionHeroSplit = tv({ const props = defineProps(); const classes = tvSectionHeroSplit({ reverse: props.reverse, + ...props.layoutSettings, } as VariantProps); diff --git a/wp-content/themes/moonshine/app/components/sections/SectionTextBlock.fragment.gql b/wp-content/themes/moonshine/app/components/sections/SectionTextBlock.fragment.gql index b7f5ab4..a0e96c3 100644 --- a/wp-content/themes/moonshine/app/components/sections/SectionTextBlock.fragment.gql +++ b/wp-content/themes/moonshine/app/components/sections/SectionTextBlock.fragment.gql @@ -1,6 +1,8 @@ fragment SectionTextBlock on GroupAbstractBuilderSectionsTextBlockLayout { content layoutSettings { + ...LayoutColored ...LayoutContained + ...LayoutPadded } } diff --git a/wp-content/themes/moonshine/app/components/sections/SectionTextBlock.global.vue b/wp-content/themes/moonshine/app/components/sections/SectionTextBlock.global.vue index 1f9b0e8..7eaf6e5 100644 --- a/wp-content/themes/moonshine/app/components/sections/SectionTextBlock.global.vue +++ b/wp-content/themes/moonshine/app/components/sections/SectionTextBlock.global.vue @@ -5,7 +5,7 @@ defineProps(); diff --git a/wp-content/themes/moonshine/app/composables/useLayoutWrapper.ts b/wp-content/themes/moonshine/app/composables/useLayoutWrapper.ts new file mode 100644 index 0000000..f8717e0 --- /dev/null +++ b/wp-content/themes/moonshine/app/composables/useLayoutWrapper.ts @@ -0,0 +1,64 @@ +import { tv, type VariantProps } from "tailwind-variants"; +import * as z from "zod"; + +// Tailwind Variants for LayoutWrapper +export const tvLayoutWrapper = tv({ + slots: { + base: "", + inner: "", + }, + variants: { + // LayoutColored + color: { + default: { base: "bg-default" }, + muted: { base: "bg-muted" }, + elevated: { base: "bg-elevated" }, + accented: { base: "bg-accented" }, + inverted: { base: "bg-inverted text-inverted" }, + primary: { base: "bg-primary text-inverted" }, + }, + // LayoutContained + container: { + default: { inner: "container" }, + xl: { inner: "container-xl" }, + lg: { inner: "container-lg" }, + fluid: { inner: "container-fluid" }, + fullbleed: { inner: "container-fullbleed" }, + }, + // LayoutPadded + verticalPadding: { + sm: { base: "py-3" }, + md: { base: "py-6" }, + lg: { base: "py-12" }, + none: {}, + }, + }, + defaultVariants: { + color: "default", + container: "default", + verticalPadding: "md", + }, +}); + +export type LayoutWrapperProps = VariantProps; + +// Zod schemas for validating layout settings +const colorEnum = z.enum(["default", "muted", "elevated", "accented", "inverted", "primary"]); +const containerEnum = z.enum(["default", "xl", "lg", "fluid", "fullbleed"]); +const verticalPaddingEnum = z.enum(["sm", "md", "lg", "none"]); + +const layoutSettingsSchema = z.object({ + color: z.string().pipe(colorEnum).optional(), + container: z.string().pipe(containerEnum).optional(), + verticalPadding: z.string().pipe(verticalPaddingEnum).optional(), +}); + +export type LayoutSettings = z.input; + +export function useLayoutWrapper(input?: LayoutSettings) { + try { + return tvLayoutWrapper(layoutSettingsSchema.parse(input)); + } catch { + return tvLayoutWrapper(); + } +}