Skip to content

Commit b96e6ca

Browse files
fix: Glitch while selecting gradient from preset
1 parent 39d1024 commit b96e6ca

4 files changed

Lines changed: 34 additions & 15 deletions

File tree

frontend/src/components/BackgroundHandler.vue

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,11 @@
4444
<!-- Color Tab -->
4545
<div v-if="activeTab === 'color'" class="w-full space-y-4">
4646
<ColorPicker renderMode="inline" :modelValue="backgroundColor" @update:modelValue="setBGColor" />
47-
<BuilderButton v-if="backgroundColor" class="w-full" variant="subtle" @click="setBGColor(null)">
47+
<BuilderButton
48+
:disabled="!backgroundColor"
49+
class="w-full"
50+
variant="subtle"
51+
@click="setBGColor(null)">
4852
Clear Color
4953
</BuilderButton>
5054
</div>
@@ -104,9 +108,7 @@
104108

105109
<!-- Gradient Tab -->
106110
<div v-else class="space-y-4">
107-
<GradientEditor
108-
:modelValue="isGradient ? rawBackgroundImage : null"
109-
@update:modelValue="setGradient" />
111+
<GradientEditor :modelValue="rawBackgroundImage" @update:modelValue="setGradient" />
110112
<BuilderButton v-if="isGradient" class="w-full" variant="subtle" @click="clearBGImage">
111113
Clear Gradient
112114
</BuilderButton>
@@ -150,7 +152,9 @@ const getStyleKey = (prop: string, state: string | null = activeState.value) =>
150152
return state ? `${state}:${prop}` : prop;
151153
};
152154
153-
const rawBackgroundImage = computed(() => blockController.getStyle(getStyleKey("backgroundImage")) as any);
155+
const rawBackgroundImage = computed(
156+
() => (blockController.getStyle(getStyleKey("backgroundImage")) || "") as string,
157+
);
154158
const backgroundColor = computed(() => blockController.getStyle(getStyleKey("backgroundColor")) as any);
155159
156160
const isGradient = computed(() => rawBackgroundImage.value?.includes("gradient"));

frontend/src/components/Controls/AnglePicker.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ const emit = defineEmits(["update:modelValue"]);
2727
2828
const dialRef = ref<HTMLElement | null>(null);
2929
const { elementX, elementY, elementWidth, elementHeight } = useMouseInElement(dialRef);
30-
const { pressed } = useMousePressed();
30+
const { pressed } = useMousePressed({ target: dialRef });
3131
3232
watch([elementX, elementY, pressed], () => {
3333
if (!pressed.value) return;

frontend/src/components/Controls/GradientEditor.vue

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -86,14 +86,14 @@
8686

8787
<script setup lang="ts">
8888
import { parseGradient, stringifyGradient, type Gradient, type GradientStop } from "@/utils/gradientUtils";
89+
import { useMouseInElement, useMousePressed } from "@vueuse/core";
8990
import { Popover } from "frappe-ui";
9091
import { computed, ref, watch } from "vue";
9192
import AnglePicker from "./AnglePicker.vue";
9293
import BuilderButton from "./BuilderButton.vue";
9394
import ColorPicker from "./ColorPicker.vue";
9495
import Input from "./Input.vue";
9596
import TabButtons from "./TabButtons.vue";
96-
import { useMouseInElement, useMousePressed } from "@vueuse/core";
9797
9898
const props = defineProps<{
9999
modelValue: string | null;
@@ -152,20 +152,31 @@ const applyPreset = (presetGradient: string) => {
152152
const parsed = parseGradient(presetGradient);
153153
if (parsed) {
154154
gradient.value = parsed;
155-
emitUpdate();
155+
emit("update:modelValue", stringifyGradient(parsed));
156156
}
157157
};
158158
159-
const defaultGradient: Gradient = {
159+
const getDefaultGradient = (): Gradient => ({
160160
type: "linear-gradient",
161161
angle: "180deg",
162162
stops: [
163163
{ color: "#ffffff", position: 0 },
164164
{ color: "#000000", position: 100 },
165165
],
166+
});
167+
168+
const gradient = ref<Gradient>(getDefaultGradient());
169+
170+
const initializeGradient = (value: string | null) => {
171+
const parsed = parseGradient(value || "");
172+
if (parsed) {
173+
gradient.value = parsed;
174+
} else if (!gradient.value.stops.length || !value) {
175+
gradient.value = getDefaultGradient();
176+
}
166177
};
167178
168-
const gradient = ref<Gradient>(parseGradient(props.modelValue || "") || { ...defaultGradient });
179+
initializeGradient(props.modelValue);
169180
170181
const angleValue = computed(() => {
171182
return gradient.value.angle.replace("deg", "");
@@ -191,8 +202,12 @@ watch(
191202
() => props.modelValue,
192203
(newVal) => {
193204
const parsed = parseGradient(newVal || "");
194-
if (parsed && stringifyGradient(parsed) !== stringifyGradient(gradient.value)) {
195-
gradient.value = parsed;
205+
if (parsed) {
206+
const currentString = stringifyGradient(gradient.value);
207+
const newString = stringifyGradient(parsed);
208+
if (currentString !== newString) {
209+
gradient.value = parsed;
210+
}
196211
}
197212
},
198213
);

frontend/src/utils/gradientUtils.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@ export function parseGradient(gradientStr: string): Gradient | null {
2424

2525
if (parts[0]) {
2626
const firstPart = parts[0].trim();
27-
const isAngle = firstPart.includes("deg") || firstPart.includes("to ");
28-
const isRadialConfig = firstPart.includes("circle") || firstPart.includes("ellipse") || firstPart.includes("at ");
29-
27+
const isAngle = /^(-?\d+(\.\d+)?deg|to\s+(top|bottom|left|right)(\s+(top|bottom|left|right))?)/i.test(firstPart);
28+
const isRadialConfig = /^(circle|ellipse|at\s+|closest-side|farthest-side|closest-corner|farthest-corner)/i.test(firstPart);
29+
3030
if (isAngle || isRadialConfig) {
3131
angle = firstPart;
3232
stopsStartIdx = 1;

0 commit comments

Comments
 (0)