Skip to content

Commit a7164d1

Browse files
use common component
1 parent 5ad78bb commit a7164d1

File tree

4 files changed

+37
-79
lines changed

4 files changed

+37
-79
lines changed

apps/studio/src/routes/editor/LayersPanel/BrandTab/ColorPanel/GroupNameInput.tsx renamed to apps/studio/src/routes/editor/LayersPanel/BrandTab/ColorPanel/ColorNameInput.tsx

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,23 @@ import { useState, useEffect } from 'react';
44
import { toNormalCase } from '@onlook/utility';
55
import { useEditorEngine } from '@/components/Context';
66

7-
interface GroupNameInputProps {
7+
interface ColorNameInputProps {
88
initialName: string;
99
onSubmit: (newName: string) => void;
1010
onCancel: () => void;
1111
existingNames?: string[];
1212
autoFocus?: boolean;
13-
customValidate?: (name: string) => string | null;
13+
disabled?: boolean;
1414
}
1515

16-
const GroupNameInput = ({
16+
const ColorNameInput = ({
1717
initialName,
1818
onSubmit,
1919
onCancel,
2020
existingNames = [],
2121
autoFocus = true,
22-
customValidate,
23-
}: GroupNameInputProps) => {
22+
disabled = false,
23+
}: ColorNameInputProps) => {
2424
const [inputValue, setInputValue] = useState(toNormalCase(initialName));
2525
const [error, setError] = useState<string | null>(null);
2626
const editorEngine = useEditorEngine();
@@ -31,20 +31,16 @@ const GroupNameInput = ({
3131
}, [initialName]);
3232

3333
const validateName = (value: string): string | null => {
34-
// If custom validation function is provided, use it first
35-
if (customValidate) {
36-
const customError = customValidate(value);
37-
if (customError) {
38-
return customError;
39-
}
40-
}
4134
if (value.trim() === '') {
42-
return 'Group name cannot be empty';
35+
return 'Color name cannot be empty';
4336
}
4437

45-
// Only allow text characters, numbers, and spaces and not start with number
46-
if (!/^[a-zA-Z0-9\s]+$/.test(value) || /^[0-9]/.test(value)) {
47-
return 'Group name can only contain text, numbers, spaces and not start with number';
38+
// Allow full numbers (e.g. "123") but not allow names starting with numbers (e.g. "1abc")
39+
if (!/^[a-zA-Z0-9\s]+$/.test(value)) {
40+
return 'Color name can only contain text, numbers, and spaces';
41+
}
42+
if (/^[0-9]/.test(value) && !/^[0-9]+$/.test(value)) {
43+
return 'Color name cannot start with a number';
4844
}
4945

5046
// Skip this check if we're editing the same name
@@ -58,7 +54,7 @@ const GroupNameInput = ({
5854
themeManagerNames.includes(camelCase(value)) ||
5955
existingNames.includes(camelCase(value))
6056
) {
61-
return 'Group name already exists';
57+
return 'Color name already exists';
6258
}
6359

6460
return null;
@@ -97,9 +93,10 @@ const GroupNameInput = ({
9793
onKeyDown={handleKeyDown}
9894
className={`text-sm font-normal w-full rounded-md border ${
9995
error ? 'border-red-500' : 'border-white/10'
100-
} bg-background-secondary px-2 py-1`}
96+
} bg-background-secondary px-2 py-1 ${disabled ? 'opacity-50 cursor-not-allowed' : ''}`}
10197
placeholder="Enter group name"
10298
autoFocus={autoFocus}
99+
disabled={disabled}
103100
/>
104101
</TooltipTrigger>
105102
<TooltipPortal>
@@ -111,4 +108,4 @@ const GroupNameInput = ({
111108
);
112109
};
113110

114-
export default GroupNameInput;
111+
export default ColorNameInput;

apps/studio/src/routes/editor/LayersPanel/BrandTab/ColorPanel/ColorPalletGroup.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@ import { Tooltip, TooltipContent, TooltipPortal, TooltipTrigger } from '@onlook/
1414
import { Color, toNormalCase } from '@onlook/utility';
1515
import { useState } from 'react';
1616
import { ColorPopover } from './ColorPopover';
17-
import { camelCase } from 'lodash';
18-
import GroupNameInput from './GroupNameInput';
17+
import ColorNameInput from './ColorNameInput';
1918

2019
export interface ColorItem {
2120
name: string;
@@ -128,7 +127,7 @@ export const BrandPalletGroup = ({
128127
<div className="flex flex-col gap-1 group/palette">
129128
<div className="flex justify-between items-center">
130129
{!isDefaultPalette && isRenaming ? (
131-
<GroupNameInput
130+
<ColorNameInput
132131
initialName={title}
133132
onSubmit={(newName) => {
134133
onRename(title, newName);

apps/studio/src/routes/editor/LayersPanel/BrandTab/ColorPanel/ColorPopover.tsx

Lines changed: 17 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
import { DEFAULT_COLOR_NAME } from '@onlook/models/constants';
22
import { Popover, PopoverContent, PopoverTrigger } from '@onlook/ui/popover';
3-
import { Tooltip, TooltipContent, TooltipTrigger } from '@onlook/ui/tooltip';
4-
import { cn } from '@onlook/ui/utils';
53
import { toNormalCase, type Color } from '@onlook/utility';
6-
import { camelCase } from 'lodash';
74
import { useEffect, useState } from 'react';
85
import ColorPickerContent from '../../../EditPanel/StylesTab/single/ColorInput/ColorPicker';
6+
import ColorNameInput from './ColorNameInput';
97

108
export const ColorPopover = ({
119
color,
@@ -26,36 +24,16 @@ export const ColorPopover = ({
2624
}) => {
2725
const [editedColor, setEditedColor] = useState<Color>(color);
2826
const [editedName, setEditedName] = useState<string>(brandColor);
29-
const [error, setError] = useState<string | null>(null);
3027

3128
const handleColorChange = (newColor: Color) => {
3229
setEditedColor(newColor);
3330
};
34-
const handleSave = () => {
35-
let camelCaseName = editedName === DEFAULT_COLOR_NAME ? editedName : camelCase(editedName);
36-
37-
if (existedName?.includes(camelCaseName) && camelCaseName !== brandColor) {
38-
setError('Color name already exists');
39-
return;
40-
}
41-
// Color name should not contain any special characters
42-
if (!/^[a-zA-Z0-9\s]+$/.test(editedName)) {
43-
setError('Color name should not contain any special characters');
44-
return;
45-
}
46-
47-
if (!editedName) {
48-
if (!brandColor) {
49-
setError('Color name is required');
50-
return;
51-
}
52-
camelCaseName = brandColor;
53-
}
5431

32+
const handleNameChange = (newName: string) => {
33+
setEditedName(newName);
5534
if (onColorChangeEnd) {
56-
onColorChangeEnd(editedColor, camelCaseName);
35+
onColorChangeEnd(editedColor, newName);
5736
}
58-
5937
if (onClose) {
6038
onClose();
6139
}
@@ -66,7 +44,7 @@ export const ColorPopover = ({
6644
}, [brandColor]);
6745

6846
return (
69-
<Popover onOpenChange={(open) => !open && handleSave()} open={true}>
47+
<Popover onOpenChange={(open) => !open && handleNameChange(editedName)} open={true}>
7048
<PopoverTrigger asChild>
7149
<div
7250
className="w-full aspect-square rounded-lg cursor-pointer hover:ring-2 hover:ring-border-primary border border-white/10"
@@ -77,34 +55,18 @@ export const ColorPopover = ({
7755
<div className="flex flex-col gap-0 p-0">
7856
<div className="flex flex-col gap-1 p-2 pb-1">
7957
<label className="text-xs text-muted-foreground">Color Name</label>
80-
<Tooltip open={!!error}>
81-
<TooltipTrigger asChild>
82-
<input
83-
type="text"
84-
value={editedName}
85-
onChange={(e) => {
86-
setEditedName(e.target.value);
87-
setError(null);
88-
}}
89-
className={cn(
90-
'w-full rounded-md border bg-background-secondary px-2 py-1 text-sm',
91-
error ? 'border-red-500' : 'border-white/10',
92-
)}
93-
disabled={isDefaultPalette || brandColor === DEFAULT_COLOR_NAME}
94-
onKeyDown={(e) => {
95-
if (e.key === 'Enter') {
96-
handleSave();
97-
}
98-
}}
99-
autoFocus
100-
/>
101-
</TooltipTrigger>
102-
{error && (
103-
<TooltipContent side="top" className="bg-red-500 text-white">
104-
{error}
105-
</TooltipContent>
106-
)}
107-
</Tooltip>
58+
<ColorNameInput
59+
initialName={editedName}
60+
onSubmit={handleNameChange}
61+
onCancel={() => {
62+
setEditedName(brandColor);
63+
if (onClose) {
64+
onClose();
65+
}
66+
}}
67+
existingNames={existedName}
68+
disabled={isDefaultPalette || brandColor === DEFAULT_COLOR_NAME}
69+
/>
10870
</div>
10971
<ColorPickerContent
11072
color={editedColor}

apps/studio/src/routes/editor/LayersPanel/BrandTab/ColorPanel/index.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import type { Color } from '@onlook/utility';
77
import { observer } from 'mobx-react-lite';
88
import { useEffect, useState } from 'react';
99
import { BrandPalletGroup } from './ColorPalletGroup';
10-
import GroupNameInput from './GroupNameInput';
10+
import ColorNameInput from './ColorNameInput';
1111
import { camelCase } from 'lodash';
1212

1313
interface ColorPanelProps {
@@ -131,7 +131,7 @@ const ColorPanel = observer(({ onClose }: ColorPanelProps) => {
131131
</div>
132132
{isAddingNewGroup ? (
133133
<div className="flex flex-col gap-1">
134-
<GroupNameInput
134+
<ColorNameInput
135135
initialName=""
136136
onSubmit={handleAddNewGroup}
137137
onCancel={() => setIsAddingNewGroup(false)}

0 commit comments

Comments
 (0)