Skip to content

Commit 875502b

Browse files
authored
fix: Border icon also needs to have mixed behavior (#2604)
1 parent 52bce45 commit 875502b

File tree

1 file changed

+53
-12
lines changed
  • apps/web/client/src/app/project/[id]/_components/editor-bar/dropdowns

1 file changed

+53
-12
lines changed

apps/web/client/src/app/project/[id]/_components/editor-bar/dropdowns/border.tsx

Lines changed: 53 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,65 @@ import { Button } from '@onlook/ui/button';
44
import { DropdownMenu, DropdownMenuContent, DropdownMenuTrigger } from '@onlook/ui/dropdown-menu';
55
import { Icons } from '@onlook/ui/icons';
66
import { observer } from 'mobx-react-lite';
7-
import { useState } from 'react';
7+
import { useMemo, useState } from 'react';
88
import { useBoxControl } from '../hooks/use-box-control';
99
import { useDropdownControl } from '../hooks/use-dropdown-manager';
1010
import { HoverOnlyTooltip } from '../hover-tooltip';
1111
import { InputRange } from '../inputs/input-range';
1212
import { SpacingInputs } from '../inputs/spacing-inputs';
1313
import { ToolbarButton } from '../toolbar-button';
1414

15+
export enum BorderTab {
16+
ALL = 'all',
17+
INDIVIDUAL = 'individual',
18+
}
19+
1520
export const Border = observer(() => {
16-
const [activeTab, setActiveTab] = useState('all');
1721
const { boxState, handleBoxChange, handleUnitChange, handleIndividualChange, borderExists } =
1822
useBoxControl('border');
1923

2024
const { isOpen, onOpenChange } = useDropdownControl({
2125
id: 'border-dropdown',
2226
});
2327

28+
const areAllBordersEqual = useMemo((): boolean => {
29+
const borders = {
30+
top: boxState.borderTopWidth.num ?? 0,
31+
right: boxState.borderRightWidth.num ?? 0,
32+
bottom: boxState.borderBottomWidth.num ?? 0,
33+
left: boxState.borderLeftWidth.num ?? 0,
34+
};
35+
36+
const values = Object.values(borders);
37+
38+
return values.every(val => val === values[0]);
39+
}, [boxState.borderTopWidth.num, boxState.borderRightWidth.num, boxState.borderBottomWidth.num, boxState.borderLeftWidth.num]);
40+
41+
const [activeTab, setActiveTab] = useState<BorderTab>(areAllBordersEqual ? BorderTab.ALL : BorderTab.INDIVIDUAL);
42+
43+
const getBorderDisplay = () => {
44+
const top = boxState.borderTopWidth.num ?? 0;
45+
const right = boxState.borderRightWidth.num ?? 0;
46+
const bottom = boxState.borderBottomWidth.num ?? 0;
47+
const left = boxState.borderLeftWidth.num ?? 0;
48+
49+
if (top === 0 && right === 0 && bottom === 0 && left === 0) {
50+
return null;
51+
}
52+
53+
const nonZeroValues = [top, right, bottom, left].filter(val => val !== 0);
54+
55+
if(nonZeroValues.length === 4 && nonZeroValues.every((val) => val === nonZeroValues[0])) {
56+
return boxState.borderWidth.unit === 'px'
57+
? `${boxState.borderWidth.num}`
58+
: `${boxState.borderWidth.value}`
59+
}
60+
61+
return "Mixed"
62+
}
63+
64+
const borderValue = getBorderDisplay()
65+
2466
return (
2567
<DropdownMenu open={isOpen} onOpenChange={onOpenChange} modal={false}>
2668
<HoverOnlyTooltip
@@ -35,12 +77,11 @@ export const Border = observer(() => {
3577
isOpen={isOpen}
3678
className="flex items-center gap-1 min-w-10"
3779
>
38-
<Icons.BorderEdit className="h-4 w-4 min-h-4 min-w-4" />
39-
{borderExists && (
80+
<Icons.BorderEdit className={`h-4 w-4 min-h-4 min-w-4 ${borderExists ? 'text-white' : ''}
81+
`} />
82+
{borderValue && (
4083
<span className="text-xs">
41-
{boxState.borderWidth.unit === 'px'
42-
? boxState.borderWidth.num
43-
: boxState.borderWidth.value}
84+
{borderValue}
4485
</span>
4586
)}
4687
</ToolbarButton>
@@ -53,25 +94,25 @@ export const Border = observer(() => {
5394
>
5495
<div className="flex items-center gap-2 mb-3">
5596
<button
56-
onClick={() => setActiveTab('all')}
57-
className={`flex-1 text-sm px-4 py-1.5 rounded-md transition-colors cursor-pointer ${activeTab === 'all'
97+
onClick={() => setActiveTab(BorderTab.ALL)}
98+
className={`flex-1 text-sm px-4 py-1.5 rounded-md transition-colors cursor-pointer ${activeTab === BorderTab.ALL
5899
? 'text-foreground-primary bg-background-active/50'
59100
: 'text-muted-foreground hover:bg-background-tertiary/20 hover:text-foreground-hover'
60101
}`}
61102
>
62103
All sides
63104
</button>
64105
<button
65-
onClick={() => setActiveTab('individual')}
66-
className={`flex-1 text-sm px-4 py-1.5 rounded-md transition-colors cursor-pointer ${activeTab === 'individual'
106+
onClick={() => setActiveTab(BorderTab.INDIVIDUAL)}
107+
className={`flex-1 text-sm px-4 py-1.5 rounded-md transition-colors cursor-pointer ${activeTab === BorderTab.INDIVIDUAL
67108
? 'text-foreground-primary bg-background-active/50'
68109
: 'text-muted-foreground hover:bg-background-tertiary/20 hover:text-foreground-hover'
69110
}`}
70111
>
71112
Individual
72113
</button>
73114
</div>
74-
{activeTab === 'all' ? (
115+
{activeTab === BorderTab.ALL ? (
75116
<InputRange
76117
value={boxState.borderWidth.num ?? 0}
77118
onChange={(value) => handleBoxChange('borderWidth', value.toString())}

0 commit comments

Comments
 (0)