Skip to content

Commit 5f411b5

Browse files
committed
attributes
1 parent 02cdea2 commit 5f411b5

File tree

2 files changed

+79
-1
lines changed

2 files changed

+79
-1
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { HtmlEditor, HtmlRenderer } from '@compai/css-gui'
2+
import { useState } from 'react'
3+
const initialValue: any = {
4+
tagName: 'div',
5+
children: [
6+
'hello ',
7+
{
8+
tagName: 'span',
9+
children: ['world'],
10+
style: {
11+
color: 'tomato',
12+
},
13+
},
14+
],
15+
}
16+
17+
export default function HtmlEditorExample() {
18+
const [html, setHtml] = useState(initialValue)
19+
return (
20+
<div sx={{ display: 'grid', gridTemplateColumns: '1fr 1fr' }}>
21+
<HtmlEditor value={html} onChange={setHtml} />
22+
<HtmlRenderer value={html} />
23+
</div>
24+
)
25+
}

packages/gui/src/components/html/editor.tsx

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { Editor } from '../Editor'
22
import { HtmlNode } from './types'
33
import * as Collapsible from '@radix-ui/react-collapsible'
44
import { useState } from 'react'
5-
import { isNil } from 'lodash-es'
5+
import { isNil, values } from 'lodash-es'
66
import IconButton from '../ui/IconButton'
77
import { Trash2 } from 'react-feather'
88
import { Label } from '../primitives'
@@ -98,6 +98,15 @@ function NodeSwitch({ value, onChange }: EditorProps) {
9898
onChange={(e) => onChange({ ...value, tagName: e.target.value })}
9999
/>
100100
</div>
101+
<div>
102+
<Label>Attributes</Label>
103+
<AttributeEditor
104+
value={value.attributes ?? {}}
105+
onChange={(newAttributes) =>
106+
onChange({ ...value, attributes: newAttributes })
107+
}
108+
/>
109+
</div>
101110
<div>
102111
<Label>Styles</Label>
103112
<Editor
@@ -223,6 +232,50 @@ function AddChildButton({ onClick }: { onClick(): void }) {
223232
)
224233
}
225234

235+
interface AttributeEditorProps {
236+
value: Record<string, string>
237+
onChange(value: Record<string, string>): void
238+
}
239+
240+
function AttributeEditor({ value = {}, onChange }: AttributeEditorProps) {
241+
const [currentValue, setCurrentValue] = useState('')
242+
return (
243+
<div>
244+
{Object.entries(value).map(([key, attrValue]) => {
245+
return (
246+
<div sx={{ display: 'flex' }}>
247+
<Label>
248+
{key}
249+
<input
250+
value={attrValue}
251+
onChange={(e) => onChange({ ...value, [key]: e.target.value })}
252+
/>
253+
</Label>
254+
<IconButton>
255+
<Trash2 size={14} />
256+
</IconButton>
257+
</div>
258+
)
259+
})}
260+
<div sx={{ display: 'flex' }}>
261+
<input
262+
type="text"
263+
value={currentValue}
264+
onChange={(e) => setCurrentValue(e.target.value)}
265+
/>
266+
<button
267+
onClick={() => {
268+
onChange({ ...value, [currentValue]: '' })
269+
setCurrentValue('')
270+
}}
271+
>
272+
+ Add attribute
273+
</button>
274+
</div>
275+
</div>
276+
)
277+
}
278+
226279
function getChildAtPath(element: HtmlNode, path: ElementPath): HtmlNode {
227280
if (path.length === 0) {
228281
return element

0 commit comments

Comments
 (0)