Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions frontend/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ declare module 'vue' {
BlockProperties: typeof import('./src/components/BlockProperties.vue')['default']
BlockSnapGuides: typeof import('./src/components/BlockSnapGuides.vue')['default']
BooleanOptions: typeof import('./src/components/PropsOptions/BooleanOptions.vue')['default']
BorderControl: typeof import('./src/components/BorderControl.vue')['default']
BorderRadiusControl: typeof import('./src/components/BorderRadiusControl.vue')['default']
BorderRadiusHandler: typeof import('./src/components/BorderRadiusHandler.vue')['default']
BoxResizer: typeof import('./src/components/BoxResizer.vue')['default']
Expand Down
56 changes: 4 additions & 52 deletions frontend/src/components/BlockPropertySections/StyleSection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { BORDER_UNIT_OPTIONS, ROTATION_UNIT_OPTIONS } from "@/utils/unitOptions"
import RangeInput from "../Controls/RangeInput.vue";
import ShadowHandler from "@/components/ShadowHandler.vue";
import BorderRadiusControl from "@/components/BorderRadiusControl.vue";
import BorderControl from "@/components/BorderControl.vue";

const overflowOptions = [
{
Expand Down Expand Up @@ -69,60 +70,11 @@ const styleSectionProperties = [
searchKeyWords: "Text, Color, TextColor, Text Color",
},
{
component: StylePropertyControl,
component: BorderControl,
getProps: () => {
return {
component: ColorInput,
propertyKey: "borderColor",
popoverOffset: 120,
label: "Border Color",
};
},
searchKeyWords: "Border, Color, BorderColor, Border Color",
events: {
"update:modelValue": (val: StyleValue) => {
if (val) {
if (!blockController.getStyle("borderWidth")) {
blockController.setStyle("borderWidth", "1px");
blockController.setStyle("borderStyle", "solid");
}
} else {
blockController.setStyle("borderWidth", null);
blockController.setStyle("borderStyle", null);
}
},
},
},
{
component: StylePropertyControl,
getProps: () => {
return {
label: "Border Width",
propertyKey: "borderWidth",
enableSlider: true,
unitOptions: BORDER_UNIT_OPTIONS,
minValue: 0,
};
},
searchKeyWords: "Border, Width, BorderWidth, Border Width",
condition: () => blockController.getStyle("borderColor") || blockController.getStyle("borderWidth"),
},
{
component: StylePropertyControl,
getProps: () => {
return {
label: "Border Style",
propertyKey: "borderStyle",
type: "select",
options: [
{ value: "solid", label: "Solid" },
{ value: "dashed", label: "Dashed" },
{ value: "dotted", label: "Dotted" },
],
};
return {};
},
searchKeyWords: "Border, Style, BorderStyle, Border Style, Solid, Dashed, Dotted",
condition: () => blockController.getStyle("borderColor"),
searchKeyWords: "Border, Color, Width, Style, BorderColor, BorderWidth, BorderStyle",
},
{
component: ShadowHandler,
Expand Down
105 changes: 105 additions & 0 deletions frontend/src/components/BorderControl.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
<template>
<div class="flex w-full flex-col gap-3">
<!-- Border Color -->
<StylePropertyControl
label="Border Color"
propertyKey="borderColor"
:component="ColorInput"
:popoverOffset="120"
:events="colorEvents" />

<!-- Border Width (with Split Mode Input) -->
<StylePropertyControl
v-if="hasColor"
label="Border Width"
propertyKey="borderWidth"
:component="SplitModeInput"
:unitOptions="BORDER_UNIT_OPTIONS"
:enableStates="true"
:enableSlider="true"
:splits="SPLITS"
:toControlValues="toControlValues"
:toModelValue="toModelValue"
:normalizeValue="normalize"
:inputAttrs="{ min: 0 }"
:getModelValue="readValue"
:getVariantValue="readValue"
:getControlAttrs="getControlAttrs"
:getMergedValue="getMergedValue" />

<!-- Border Style -->
<StylePropertyControl
v-if="hasColor"
label="Border Style"
propertyKey="borderStyle"
type="select"
:options="[
{ value: 'solid', label: 'Solid' },
{ value: 'dashed', label: 'Dashed' },
{ value: 'dotted', label: 'Dotted' },
]" />
</div>
</template>

<script lang="ts" setup>
import SplitModeInput from "@/components/Controls/SplitModeInput.vue";
import StylePropertyControl from "@/components/Controls/StylePropertyControl.vue";
import ColorInput from "@/components/Controls/ColorInput.vue";
import blockController from "@/utils/blockController";
import { expandBoxShorthand, normalizeValueWithUnits } from "@/utils/cssUtils";
import { BORDER_UNIT_OPTIONS } from "@/utils/unitOptions";
import { computed, ref, watch } from "vue";

type BoxValue = string | number | boolean | null;

const SPLITS = ["T", "R", "B", "L"];
const splitModes = ref<Record<string, boolean>>({});

// Reset split modes on selection change
watch(
() => blockController.getSelectedBlocks(),
() => {
splitModes.value = {};
}
);

const readValue = (state: string | null = null) => {
const key = state ? `${state}:borderWidth` : "borderWidth";
return String(blockController.getStyle(key) || "");
};

const toControlValues = (value: unknown) => expandBoxShorthand(value);
const normalize = (value: BoxValue) => normalizeValueWithUnits(String(value || "0"), "px");
const toModelValue = (parts: BoxValue[]) => parts.join(" ");
const getMergedValue = (parts: BoxValue[]) => parts[0] ?? "0px";

const getControlAttrs = (variant: string | null) => {
const key = variant ?? "main";
return {
split: new Set(toControlValues(readValue(variant))).size > 1 || (splitModes.value[key] ?? false),
enableSlider: true,
"onUpdate:split": (split: boolean) => (splitModes.value[key] = split),
};
};

const hasColor = computed(() => {
return Boolean(
blockController.getStyle("borderColor") ||
blockController.getStyle("borderWidth")
);
});

Comment thread
surajshetty3416 marked this conversation as resolved.
const colorEvents = {
"update:modelValue": (val: any) => {
if (val) {
if (!blockController.getStyle("borderWidth")) {
blockController.setStyle("borderWidth", "1px");
blockController.setStyle("borderStyle", "solid");
}
} else {
blockController.setStyle("borderWidth", null);
blockController.setStyle("borderStyle", null);
}
}
};
</script>