@valbuild/ui 0.13.4 → 0.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/valbuild-ui.cjs.d.ts +13 -18
- package/dist/valbuild-ui.cjs.js +7624 -1718
- package/dist/valbuild-ui.esm.js +7625 -1719
- package/package.json +5 -2
- package/src/assets/icons/ImageIcon.tsx +15 -7
- package/src/assets/icons/Section.tsx +41 -0
- package/src/assets/icons/TextIcon.tsx +20 -0
- package/src/components/Button.tsx +18 -7
- package/src/components/DraggableList.stories.tsx +20 -0
- package/src/components/DraggableList.tsx +95 -0
- package/src/components/Dropdown.tsx +2 -0
- package/src/components/ExpandLogo.tsx +72 -0
- package/src/components/RichTextEditor/Plugins/Toolbar.tsx +1 -16
- package/src/components/RichTextEditor/RichTextEditor.tsx +2 -2
- package/src/components/User.tsx +17 -0
- package/src/components/ValMenu.tsx +40 -0
- package/src/components/ValOverlay.tsx +513 -29
- package/src/components/ValOverlayContext.tsx +63 -0
- package/src/components/ValWindow.stories.tsx +3 -3
- package/src/components/ValWindow.tsx +26 -18
- package/src/components/dashboard/DashboardButton.tsx +25 -0
- package/src/components/dashboard/DashboardDropdown.tsx +59 -0
- package/src/components/dashboard/Dropdown.stories.tsx +11 -0
- package/src/components/dashboard/Dropdown.tsx +70 -0
- package/src/components/dashboard/FormGroup.stories.tsx +37 -0
- package/src/components/dashboard/FormGroup.tsx +36 -0
- package/src/components/dashboard/Grid.stories.tsx +52 -0
- package/src/components/dashboard/Grid.tsx +126 -0
- package/src/components/dashboard/Grid2.stories.tsx +56 -0
- package/src/components/dashboard/Grid2.tsx +72 -0
- package/src/components/dashboard/Tree.stories.tsx +91 -0
- package/src/components/dashboard/Tree.tsx +72 -0
- package/src/components/dashboard/ValDashboard.tsx +148 -0
- package/src/components/dashboard/ValDashboardEditor.tsx +269 -0
- package/src/components/dashboard/ValDashboardGrid.tsx +142 -0
- package/src/components/dashboard/ValTreeNavigator.tsx +253 -0
- package/src/components/forms/Form.tsx +2 -2
- package/src/components/forms/{TextForm.tsx → TextArea.tsx} +5 -3
- package/src/dto/SerializedSchema.ts +69 -0
- package/src/dto/Session.ts +12 -0
- package/src/dto/SessionMode.ts +5 -0
- package/src/dto/Tree.ts +18 -0
- package/src/exports.ts +1 -0
- package/src/utils/Remote.ts +15 -0
- package/src/utils/resolvePath.ts +33 -0
- package/tailwind.config.js +20 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@valbuild/ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.17.0",
|
|
4
4
|
"sideEffects": false,
|
|
5
5
|
"scripts": {
|
|
6
6
|
"typecheck": "tsc --noEmit",
|
|
@@ -17,11 +17,14 @@
|
|
|
17
17
|
"@types/express": "^4.17.17",
|
|
18
18
|
"@types/react": "^18.0.26",
|
|
19
19
|
"classnames": "^2.3.2",
|
|
20
|
+
"esbuild": "^0.17.19",
|
|
20
21
|
"lexical": "^0.10.0",
|
|
21
22
|
"react-feather": "^2.0.10",
|
|
22
23
|
"rollup-plugin-peer-deps-external": "^2.2.4",
|
|
23
24
|
"rollup-plugin-postcss": "^4.0.2",
|
|
24
|
-
"rollup-plugin-typescript2": "^0.34.1"
|
|
25
|
+
"rollup-plugin-typescript2": "^0.34.1",
|
|
26
|
+
"zod": "^3.22.2",
|
|
27
|
+
"@valbuild/core": "~0.17.0"
|
|
25
28
|
},
|
|
26
29
|
"devDependencies": {
|
|
27
30
|
"@storybook/addon-essentials": "^7.0.12",
|
|
@@ -3,17 +3,25 @@ import { FC } from "react";
|
|
|
3
3
|
const ImageIcon: FC<{ className?: string }> = ({ className }) => {
|
|
4
4
|
return (
|
|
5
5
|
<svg
|
|
6
|
+
width="9"
|
|
7
|
+
height="10"
|
|
8
|
+
viewBox="0 0 9 10"
|
|
9
|
+
fill="none"
|
|
6
10
|
xmlns="http://www.w3.org/2000/svg"
|
|
7
|
-
viewBox="0 0 32 32"
|
|
8
11
|
className={className}
|
|
9
|
-
width={25}
|
|
10
|
-
height={25}
|
|
11
|
-
strokeWidth="4"
|
|
12
12
|
>
|
|
13
|
-
<g>
|
|
14
|
-
<
|
|
15
|
-
|
|
13
|
+
<g clipPath="url(#clip0_1225_1638)">
|
|
14
|
+
<rect y="0.5" width="9" height="9" />
|
|
15
|
+
|
|
16
|
+
<path d="M0 7L8.5 5" stroke="currentColor" />
|
|
17
|
+
<circle cx="3" cy="3.5" r="1" fill="currentColor" />
|
|
16
18
|
</g>
|
|
19
|
+
<rect x="0.5" y="1" width="8" height="8" stroke="currentColor" />
|
|
20
|
+
<defs>
|
|
21
|
+
<clipPath id="clip0_1225_1638">
|
|
22
|
+
<rect y="0.5" width="9" height="9" fill="white" />
|
|
23
|
+
</clipPath>
|
|
24
|
+
</defs>
|
|
17
25
|
</svg>
|
|
18
26
|
);
|
|
19
27
|
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { FC } from "react";
|
|
2
|
+
|
|
3
|
+
const Section: FC<{ className?: string }> = ({ className }) => {
|
|
4
|
+
return (
|
|
5
|
+
<svg
|
|
6
|
+
width="9"
|
|
7
|
+
height="10"
|
|
8
|
+
viewBox="0 0 9 10"
|
|
9
|
+
className={className}
|
|
10
|
+
fill="currentColor"
|
|
11
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
12
|
+
>
|
|
13
|
+
<g clipPath="url(#clip0_1222_1618)">
|
|
14
|
+
<path
|
|
15
|
+
fillRule="evenodd"
|
|
16
|
+
clipRule="evenodd"
|
|
17
|
+
d="M9 1.5H0V0.5H9V1.5Z"
|
|
18
|
+
fill="currentColor"
|
|
19
|
+
/>
|
|
20
|
+
<path
|
|
21
|
+
fillRule="evenodd"
|
|
22
|
+
clipRule="evenodd"
|
|
23
|
+
d="M9 9.5H0V8.5H9V9.5Z"
|
|
24
|
+
fill="currentColor"
|
|
25
|
+
/>
|
|
26
|
+
</g>
|
|
27
|
+
<defs>
|
|
28
|
+
<clipPath id="clip0_1222_1618">
|
|
29
|
+
<rect
|
|
30
|
+
width="9"
|
|
31
|
+
height="9"
|
|
32
|
+
fill="white"
|
|
33
|
+
transform="translate(0 0.5)"
|
|
34
|
+
/>
|
|
35
|
+
</clipPath>
|
|
36
|
+
</defs>
|
|
37
|
+
</svg>
|
|
38
|
+
);
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export default Section;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { FC } from "react";
|
|
2
|
+
|
|
3
|
+
const TextIcon: FC<{ className?: string }> = ({ className }) => {
|
|
4
|
+
return (
|
|
5
|
+
<svg
|
|
6
|
+
width="9"
|
|
7
|
+
height="10"
|
|
8
|
+
viewBox="0 0 9 10"
|
|
9
|
+
fill="currentColor"
|
|
10
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
11
|
+
className={className}
|
|
12
|
+
>
|
|
13
|
+
<g clipPath="url(#clip0_1229_1625)">
|
|
14
|
+
<path d="M0.0145513 0.5H8.98545L9 3.18569H8.57074C8.43007 2.2276 8.02749 1.57948 7.36298 1.24133C6.98949 1.05491 6.43169 0.953035 5.68957 0.935694V7.94581C5.68957 8.43569 5.78416 8.76084 5.97332 8.92124C6.16734 9.08165 6.5675 9.16185 7.17381 9.16185V9.5H1.86257V9.16185C2.44462 9.16185 2.83023 9.08165 3.0194 8.92124C3.21342 8.7565 3.31043 8.43136 3.31043 7.94581V0.935694C2.58286 0.953035 2.02506 1.05491 1.63703 1.24133C0.92401 1.58815 0.521423 2.23627 0.429264 3.18569H0L0.0145513 0.5Z" />
|
|
15
|
+
</g>
|
|
16
|
+
</svg>
|
|
17
|
+
);
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export default TextIcon;
|
|
@@ -9,6 +9,24 @@ export interface ButtonProps
|
|
|
9
9
|
disabled?: boolean;
|
|
10
10
|
tooltip?: string;
|
|
11
11
|
}
|
|
12
|
+
|
|
13
|
+
export function PrimaryButton({
|
|
14
|
+
children,
|
|
15
|
+
onClick,
|
|
16
|
+
}: {
|
|
17
|
+
children: React.ReactNode;
|
|
18
|
+
onClick?: () => void;
|
|
19
|
+
}) {
|
|
20
|
+
return (
|
|
21
|
+
<button
|
|
22
|
+
onClick={onClick}
|
|
23
|
+
className="px-4 py-[2px] font-serif border rounded-sm border-border bg-fill text-primary hover:dark:bg-yellow hover:bg-warm-black hover:dark:text-dark-gray hover:text-white focus-visible:border-highlight focus:outline-none"
|
|
24
|
+
>
|
|
25
|
+
{children}
|
|
26
|
+
</button>
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
|
|
12
30
|
const Button: FC<ButtonProps> = ({
|
|
13
31
|
variant = "primary",
|
|
14
32
|
onClick,
|
|
@@ -49,10 +67,3 @@ const Button: FC<ButtonProps> = ({
|
|
|
49
67
|
};
|
|
50
68
|
|
|
51
69
|
export default Button;
|
|
52
|
-
export function PrimaryButton({ children }: { children: React.ReactNode }) {
|
|
53
|
-
return (
|
|
54
|
-
<button className="px-4 py-[2px] font-serif border rounded-sm border-border bg-fill text-primary hover:dark:bg-yellow hover:bg-warm-black hover:dark:text-dark-gray hover:text-white focus-visible:border-highlight focus:outline-none">
|
|
55
|
-
{children}
|
|
56
|
-
</button>
|
|
57
|
-
);
|
|
58
|
-
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
|
|
3
|
+
import { DraggableList } from "./DraggableList";
|
|
4
|
+
|
|
5
|
+
const meta: Meta<typeof DraggableList> = { component: DraggableList };
|
|
6
|
+
|
|
7
|
+
export default meta;
|
|
8
|
+
type Story = StoryObj<typeof DraggableList>;
|
|
9
|
+
|
|
10
|
+
export const Default: Story = {
|
|
11
|
+
args: {
|
|
12
|
+
children: [
|
|
13
|
+
<div className="p-4 bg-white w-fit">test 1</div>,
|
|
14
|
+
<div className="p-4 bg-white w-fit">test 2</div>,
|
|
15
|
+
<div className="p-4 bg-white w-fit">test 3</div>,
|
|
16
|
+
<div className="p-4 bg-white w-fit">test 4</div>,
|
|
17
|
+
<div className="p-4 bg-white w-fit">test 5</div>,
|
|
18
|
+
],
|
|
19
|
+
},
|
|
20
|
+
};
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import classNames from "classnames";
|
|
2
|
+
import { createRef, useEffect, useState } from "react";
|
|
3
|
+
|
|
4
|
+
export type DraggableResult = {
|
|
5
|
+
from: number;
|
|
6
|
+
to: number;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export type DraggableListProps = {
|
|
10
|
+
children: React.ReactNode | React.ReactNode[];
|
|
11
|
+
onDragEnd?: (result: DraggableResult) => void;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export const DraggableList = ({
|
|
15
|
+
children: rawChildren,
|
|
16
|
+
onDragEnd,
|
|
17
|
+
}: DraggableListProps): React.ReactElement => {
|
|
18
|
+
const [from, setFrom] = useState<number | undefined>();
|
|
19
|
+
const [dragOver, setDragOver] = useState<number | undefined>();
|
|
20
|
+
const [children, setChildren] = useState<React.ReactNode[]>([]);
|
|
21
|
+
const [dropHappened, setDropHappened] = useState<boolean>(false);
|
|
22
|
+
useEffect(() => {
|
|
23
|
+
setChildren(Array.isArray(rawChildren) ? rawChildren : [rawChildren]);
|
|
24
|
+
}, [rawChildren]);
|
|
25
|
+
|
|
26
|
+
return (
|
|
27
|
+
<div className="bg-transparent">
|
|
28
|
+
{[...children, <div className="h-[1px]"></div>].map((child, idx) => {
|
|
29
|
+
const ref = createRef<HTMLDivElement>();
|
|
30
|
+
return (
|
|
31
|
+
<div key={idx} className="relative">
|
|
32
|
+
{dragOver === idx && (
|
|
33
|
+
<div className="flex items-center">
|
|
34
|
+
<div className="border-[2px] border-yellow w-3 h-3 rounded-full" />
|
|
35
|
+
<div className="bg-yellow border-yellow w-full h-[1px]" />
|
|
36
|
+
<div className="border-[2px] border-yellow w-3 h-3 rounded-full" />
|
|
37
|
+
</div>
|
|
38
|
+
)}
|
|
39
|
+
<div
|
|
40
|
+
ref={ref}
|
|
41
|
+
draggable
|
|
42
|
+
className={classNames("cursor-grab transition-opacity")}
|
|
43
|
+
onDragStart={(ev) => {
|
|
44
|
+
ev.dataTransfer.setDragImage(new Image(), 0, 0);
|
|
45
|
+
setFrom(idx);
|
|
46
|
+
}}
|
|
47
|
+
onDragOver={(ev) => {
|
|
48
|
+
ev.preventDefault();
|
|
49
|
+
setDragOver(idx);
|
|
50
|
+
}}
|
|
51
|
+
onDragEnd={(ev) => {
|
|
52
|
+
ev.preventDefault();
|
|
53
|
+
if (
|
|
54
|
+
from !== undefined &&
|
|
55
|
+
!dropHappened &&
|
|
56
|
+
dragOver !== undefined
|
|
57
|
+
) {
|
|
58
|
+
const copy = [...children];
|
|
59
|
+
const end = Math.min(dragOver, children.length - 1);
|
|
60
|
+
copy.splice(from, 1);
|
|
61
|
+
copy.splice(end, 0, children[from]);
|
|
62
|
+
setChildren(copy);
|
|
63
|
+
if (onDragEnd) {
|
|
64
|
+
onDragEnd({ from: from, to: end });
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
setDropHappened(false);
|
|
68
|
+
setFrom(undefined);
|
|
69
|
+
setDragOver(undefined);
|
|
70
|
+
}}
|
|
71
|
+
onDrop={(ev) => {
|
|
72
|
+
ev.preventDefault();
|
|
73
|
+
if (from !== undefined) {
|
|
74
|
+
const copy = [...children];
|
|
75
|
+
copy.splice(from, 1);
|
|
76
|
+
const end = Math.min(idx, children.length - 1);
|
|
77
|
+
copy.splice(end, 0, children[from]);
|
|
78
|
+
if (onDragEnd) {
|
|
79
|
+
onDragEnd({ from: from, to: end });
|
|
80
|
+
}
|
|
81
|
+
setChildren(copy);
|
|
82
|
+
setDragOver(undefined);
|
|
83
|
+
setFrom(undefined);
|
|
84
|
+
setDropHappened(true);
|
|
85
|
+
}
|
|
86
|
+
}}
|
|
87
|
+
>
|
|
88
|
+
{child}
|
|
89
|
+
</div>
|
|
90
|
+
</div>
|
|
91
|
+
);
|
|
92
|
+
})}
|
|
93
|
+
</div>
|
|
94
|
+
);
|
|
95
|
+
};
|
|
@@ -7,6 +7,7 @@ export interface DropdownProps {
|
|
|
7
7
|
label: string;
|
|
8
8
|
onChange: (selectedOption: string) => void;
|
|
9
9
|
icon?: React.ReactElement<SVGProps<SVGSVGElement>>;
|
|
10
|
+
variant?: "primary" | "secondary";
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
const Dropdown: React.FC<DropdownProps> = ({
|
|
@@ -14,6 +15,7 @@ const Dropdown: React.FC<DropdownProps> = ({
|
|
|
14
15
|
onChange,
|
|
15
16
|
label,
|
|
16
17
|
icon,
|
|
18
|
+
// variant = "primary",
|
|
17
19
|
}) => {
|
|
18
20
|
const [isOpen, setIsOpen] = useState<boolean>(false);
|
|
19
21
|
const dropdownRef = useRef<HTMLDivElement>(null);
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { FC } from "react";
|
|
2
|
+
|
|
3
|
+
const ExpandLogo: FC<{ expanded: boolean; className?: string }> = ({
|
|
4
|
+
expanded,
|
|
5
|
+
className,
|
|
6
|
+
}) => {
|
|
7
|
+
return (
|
|
8
|
+
<div>
|
|
9
|
+
{expanded ? (
|
|
10
|
+
<svg
|
|
11
|
+
width="11"
|
|
12
|
+
height="11"
|
|
13
|
+
viewBox="0 0 11 11"
|
|
14
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
15
|
+
className={className}
|
|
16
|
+
>
|
|
17
|
+
<path
|
|
18
|
+
fillRule="evenodd"
|
|
19
|
+
clipRule="evenodd"
|
|
20
|
+
d="M0.606061 9.39394V6.25H0V10H3.75V9.39394H0.606061Z"
|
|
21
|
+
/>
|
|
22
|
+
<path
|
|
23
|
+
fillRule="evenodd"
|
|
24
|
+
clipRule="evenodd"
|
|
25
|
+
d="M9.4319 0.644146L9.4319 3.78809L10.038 3.78809L10.038 0.0380859L6.28796 0.0380863L6.28796 0.644146L9.4319 0.644146Z"
|
|
26
|
+
/>
|
|
27
|
+
<path
|
|
28
|
+
fillRule="evenodd"
|
|
29
|
+
clipRule="evenodd"
|
|
30
|
+
d="M3.11371e-05 9.59583L3.34602 6.24995L3.78796 6.6919L0.441965 10.0378L3.11371e-05 9.59583Z"
|
|
31
|
+
/>
|
|
32
|
+
<path
|
|
33
|
+
fillRule="evenodd"
|
|
34
|
+
clipRule="evenodd"
|
|
35
|
+
d="M10.0379 0.441766L6.69194 3.78764L6.25001 3.3457L9.596 -0.000183055L10.0379 0.441766Z"
|
|
36
|
+
/>
|
|
37
|
+
</svg>
|
|
38
|
+
) : (
|
|
39
|
+
<svg
|
|
40
|
+
width="11"
|
|
41
|
+
height="11"
|
|
42
|
+
viewBox="0 0 11 11"
|
|
43
|
+
fill="none"
|
|
44
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
45
|
+
className={className}
|
|
46
|
+
>
|
|
47
|
+
<path
|
|
48
|
+
fillRule="evenodd"
|
|
49
|
+
clipRule="evenodd"
|
|
50
|
+
d="M3.14394 6.85606L3.14394 10L3.75 10L3.75 6.25L-3.27835e-07 6.25L-2.74852e-07 6.85606L3.14394 6.85606Z"
|
|
51
|
+
/>
|
|
52
|
+
<path
|
|
53
|
+
fillRule="evenodd"
|
|
54
|
+
clipRule="evenodd"
|
|
55
|
+
d="M6.89402 3.18203V0.0380859L6.28796 0.0380859L6.28796 3.78809L10.038 3.78809V3.18203L6.89402 3.18203Z"
|
|
56
|
+
/>
|
|
57
|
+
<path
|
|
58
|
+
fillRule="evenodd"
|
|
59
|
+
clipRule="evenodd"
|
|
60
|
+
d="M3.11371e-05 9.59583L3.34602 6.24995L3.78796 6.6919L0.441965 10.0378L3.11371e-05 9.59583Z"
|
|
61
|
+
/>
|
|
62
|
+
<path
|
|
63
|
+
fillRule="evenodd"
|
|
64
|
+
clipRule="evenodd"
|
|
65
|
+
d="M10.0379 0.441766L6.69194 3.78764L6.25001 3.3457L9.596 -0.000183055L10.0379 0.441766Z"
|
|
66
|
+
/>
|
|
67
|
+
</svg>
|
|
68
|
+
)}
|
|
69
|
+
</div>
|
|
70
|
+
);
|
|
71
|
+
};
|
|
72
|
+
export default ExpandLogo;
|
|
@@ -284,22 +284,7 @@ const Toolbar: FC<ToolbarSettingsProps> = ({
|
|
|
284
284
|
};
|
|
285
285
|
|
|
286
286
|
return (
|
|
287
|
-
<div className="flex flex-row items-center gap-6 p-2 overflow-
|
|
288
|
-
{/* <div className="flex flex-row gap-2">
|
|
289
|
-
<button className="hidden w-0 h-0 " disabled></button>
|
|
290
|
-
<Button
|
|
291
|
-
icon={<Undo />}
|
|
292
|
-
onClick={() => {
|
|
293
|
-
editor.dispatchCommand(UNDO_COMMAND, undefined);
|
|
294
|
-
}}
|
|
295
|
-
></Button>
|
|
296
|
-
<Button
|
|
297
|
-
icon={<Undo className="transform -scale-x-100" />}
|
|
298
|
-
onClick={() => {
|
|
299
|
-
editor.dispatchCommand(REDO_COMMAND, undefined);
|
|
300
|
-
}}
|
|
301
|
-
/>
|
|
302
|
-
</div> */}
|
|
287
|
+
<div className="flex flex-row items-center gap-6 p-2 overflow-clip">
|
|
303
288
|
<div className="flex flex-row gap-2">
|
|
304
289
|
<Dropdown
|
|
305
290
|
options={Object.values(blockTypes)}
|
|
@@ -152,13 +152,13 @@ export const RichTextEditor: FC<RichTextEditorProps> = ({
|
|
|
152
152
|
onError,
|
|
153
153
|
};
|
|
154
154
|
return (
|
|
155
|
-
<div className=" relative bg-base min-h-[200px] mt-2 border border-highlight rounded">
|
|
155
|
+
<div className=" relative bg-base min-h-[200px] mt-2 border border-highlight rounded overflow-none resize">
|
|
156
156
|
<LexicalComposer initialConfig={initialConfig}>
|
|
157
157
|
<Toolbar onEditor={onEditor} />
|
|
158
158
|
<ImagesPlugin />
|
|
159
159
|
<RichTextPlugin
|
|
160
160
|
contentEditable={
|
|
161
|
-
<LexicalContentEditable className="relative bg-fill flex flex-col h-full w-full min-h-[200px] text-primary outline-none" />
|
|
161
|
+
<LexicalContentEditable className="relative bg-fill flex flex-col h-full w-full min-h-[200px] min-w-[566px] text-primary outline-none overflow-auto resize" />
|
|
162
162
|
}
|
|
163
163
|
placeholder={
|
|
164
164
|
<div className="absolute top-[calc(58px+1rem)] left-4 text-base/25 text-primary">
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { FC } from "react";
|
|
2
|
+
|
|
3
|
+
const User: FC<{ name: string }> = ({ name }) => {
|
|
4
|
+
return (
|
|
5
|
+
<div className="flex flex-row items-center gap-2">
|
|
6
|
+
<div className="w-[32px] h-[32px] rounded-full bg-light-gray flex justify-center items-center">
|
|
7
|
+
{name
|
|
8
|
+
.split(" ")
|
|
9
|
+
.map((name) => name.charAt(0))
|
|
10
|
+
.join("")}
|
|
11
|
+
</div>
|
|
12
|
+
<div className="text-white">{name}</div>
|
|
13
|
+
</div>
|
|
14
|
+
);
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export default User;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Edit2, Edit3, Moon, Power, Sun } from "react-feather";
|
|
2
|
+
import { useValOverlayContext } from "./ValOverlayContext";
|
|
3
|
+
import { ValApi } from "@valbuild/core";
|
|
4
|
+
|
|
5
|
+
export function ValMenu({ api }: { api: ValApi }) {
|
|
6
|
+
const { theme, setTheme, editMode, setEditMode } = useValOverlayContext();
|
|
7
|
+
return (
|
|
8
|
+
<div className="flex flex-row items-center justify-center w-full h-full space-x-4 text-primary">
|
|
9
|
+
<button
|
|
10
|
+
className="p-1 border rounded-full shadow bg-base border-highlight"
|
|
11
|
+
onClick={() => {
|
|
12
|
+
setEditMode((prev) => (prev === "off" ? "hover" : "off"));
|
|
13
|
+
}}
|
|
14
|
+
>
|
|
15
|
+
<div className="h-[24px] w-[24px] flex justify-center items-center">
|
|
16
|
+
{editMode === "off" ? <Edit2 size={18} /> : <Edit3 size={18} />}
|
|
17
|
+
</div>
|
|
18
|
+
</button>
|
|
19
|
+
<button
|
|
20
|
+
className="p-1 border rounded-full shadow bg-base border-highlight"
|
|
21
|
+
onClick={() => {
|
|
22
|
+
setTheme(theme === "dark" ? "light" : "dark");
|
|
23
|
+
}}
|
|
24
|
+
>
|
|
25
|
+
<div className="h-[24px] w-[24px] flex justify-center items-center">
|
|
26
|
+
{theme === "dark" && <Sun size={15} />}
|
|
27
|
+
{theme === "light" && <Moon size={15} />}
|
|
28
|
+
</div>
|
|
29
|
+
</button>
|
|
30
|
+
<a
|
|
31
|
+
className="p-1 border rounded-full shadow bg-base border-highlight"
|
|
32
|
+
href={api.getDisableUrl()}
|
|
33
|
+
>
|
|
34
|
+
<div className="h-[24px] w-[24px] flex justify-center items-center">
|
|
35
|
+
<Power size={18} />
|
|
36
|
+
</div>
|
|
37
|
+
</a>
|
|
38
|
+
</div>
|
|
39
|
+
);
|
|
40
|
+
}
|