@valbuild/ui 0.21.2 → 0.22.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/.storybook/theme.css +5 -1
- package/components.json +16 -0
- package/dist/valbuild-ui.cjs.d.ts +11 -7
- package/dist/valbuild-ui.cjs.js +43607 -33216
- package/dist/valbuild-ui.esm.js +48313 -37938
- package/fix-server-hack.js +45 -0
- package/fullscreen.vite.config.ts +11 -0
- package/index.html +13 -0
- package/package.json +52 -13
- package/server/dist/manifest.json +16 -0
- package/server/dist/style.css +2145 -0
- package/server/dist/valbuild-ui-main.cjs.js +74441 -0
- package/server/dist/valbuild-ui-main.esm.js +74442 -0
- package/server/dist/valbuild-ui-server.cjs.js +19 -2
- package/server/dist/valbuild-ui-server.esm.js +19 -2
- package/server.vite.config.ts +2 -0
- package/src/App.tsx +73 -0
- package/src/assets/icons/Logo.tsx +103 -0
- package/src/components/Button.tsx +10 -2
- package/src/components/Dropdown.tsx +2 -2
- package/src/components/{dashboard/Grid.stories.tsx → Grid.stories.tsx} +8 -17
- package/src/components/{dashboard/Grid.tsx → Grid.tsx} +36 -23
- package/src/components/RichTextEditor/ContentEditable.tsx +109 -1
- package/src/components/RichTextEditor/Plugins/Toolbar.tsx +2 -2
- package/src/components/RichTextEditor/RichTextEditor.tsx +1 -1
- package/src/components/ValFormField.tsx +576 -0
- package/src/components/ValFullscreen.tsx +1283 -0
- package/src/components/ValMenu.tsx +65 -13
- package/src/components/ValOverlay.tsx +32 -338
- package/src/components/ValWindow.tsx +12 -9
- package/src/components/dashboard/FormGroup.tsx +12 -6
- package/src/components/dashboard/Tree.tsx +2 -2
- package/src/components/ui/accordion.tsx +58 -0
- package/src/components/ui/alert-dialog.tsx +139 -0
- package/src/components/ui/avatar.tsx +48 -0
- package/src/components/ui/button.tsx +56 -0
- package/src/components/ui/calendar.tsx +62 -0
- package/src/components/ui/card.tsx +86 -0
- package/src/components/ui/checkbox.tsx +28 -0
- package/src/components/ui/command.tsx +153 -0
- package/src/components/ui/dialog.tsx +120 -0
- package/src/components/ui/dropdown-menu.tsx +198 -0
- package/src/components/ui/form.tsx +177 -0
- package/src/components/ui/input.tsx +24 -0
- package/src/components/ui/label.tsx +24 -0
- package/src/components/ui/popover.tsx +29 -0
- package/src/components/ui/progress.tsx +26 -0
- package/src/components/ui/radio-group.tsx +42 -0
- package/src/components/ui/scroll-area.tsx +51 -0
- package/src/components/ui/select.tsx +119 -0
- package/src/components/ui/switch.tsx +27 -0
- package/src/components/ui/tabs.tsx +53 -0
- package/src/components/ui/toggle.tsx +43 -0
- package/src/components/ui/tooltip.tsx +28 -0
- package/src/components/usePatch.ts +86 -0
- package/src/components/useTheme.ts +45 -0
- package/src/exports.ts +2 -1
- package/src/index.css +96 -60
- package/src/lib/IValStore.ts +6 -0
- package/src/lib/utils.ts +6 -0
- package/src/main.jsx +10 -0
- package/src/richtext/conversion/lexicalToRichTextSource.ts +0 -1
- package/src/richtext/shadowRootPolyFill.js +115 -0
- package/src/server.ts +39 -2
- package/src/utils/resolvePath.ts +0 -1
- package/src/vite-server.ts +20 -3
- package/tailwind.config.js +63 -51
- package/tsconfig.json +2 -1
- package/vite.config.ts +10 -0
- package/src/components/dashboard/ValDashboard.tsx +0 -150
package/server.vite.config.ts
CHANGED
|
@@ -4,9 +4,11 @@ import { defineConfig } from "vite";
|
|
|
4
4
|
export default defineConfig({
|
|
5
5
|
build: {
|
|
6
6
|
outDir: "./server/dist",
|
|
7
|
+
manifest: true,
|
|
7
8
|
lib: {
|
|
8
9
|
entry: {
|
|
9
10
|
"valbuild-ui-server": "./src/vite-server.ts",
|
|
11
|
+
"valbuild-ui-main": "./src/main.jsx",
|
|
10
12
|
},
|
|
11
13
|
formats: ["cjs", "es"],
|
|
12
14
|
/**
|
package/src/App.tsx
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { ValApi } from "@valbuild/core";
|
|
2
|
+
import { ValFullscreen } from "./components/ValFullscreen";
|
|
3
|
+
import { ErrorBoundary } from "react-error-boundary";
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
Accordion,
|
|
7
|
+
AccordionItem,
|
|
8
|
+
AccordionContent,
|
|
9
|
+
AccordionTrigger,
|
|
10
|
+
} from "./components/ui/accordion";
|
|
11
|
+
import Logo from "./assets/icons/Logo";
|
|
12
|
+
import { X } from "lucide-react";
|
|
13
|
+
import { createBrowserRouter, RouterProvider } from "react-router-dom";
|
|
14
|
+
|
|
15
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
16
|
+
function fallbackRender({ error, resetErrorBoundary }: any) {
|
|
17
|
+
console.error(error);
|
|
18
|
+
return (
|
|
19
|
+
<div className="absolute top-0 left-0 flex items-center justify-center w-screen h-screen bg-card-foreground">
|
|
20
|
+
<div className="w-full h-full p-10">
|
|
21
|
+
<div className="w-full h-full p-10 bg-card text-primary">
|
|
22
|
+
<div className="flex items-center justify-between">
|
|
23
|
+
<div className="flex items-center gap-[0.5em] text-lg font-bold text-center py-2">
|
|
24
|
+
<Logo /> encountered an error
|
|
25
|
+
</div>
|
|
26
|
+
<button onClick={resetErrorBoundary}>
|
|
27
|
+
<X />
|
|
28
|
+
</button>
|
|
29
|
+
</div>
|
|
30
|
+
<div className="text-4xl font-normal ">Message:</div>
|
|
31
|
+
<pre>{error.message}</pre>
|
|
32
|
+
{error.stack && (
|
|
33
|
+
<Accordion
|
|
34
|
+
type="single"
|
|
35
|
+
className="font-serif"
|
|
36
|
+
collapsible
|
|
37
|
+
defaultValue="error"
|
|
38
|
+
>
|
|
39
|
+
<AccordionItem value={"error"}>
|
|
40
|
+
<AccordionTrigger>Stack trace:</AccordionTrigger>
|
|
41
|
+
<AccordionContent className="p-4 bg-popover text-popover-foreground">
|
|
42
|
+
{error.stack && <pre>{error.stack}</pre>}
|
|
43
|
+
</AccordionContent>
|
|
44
|
+
</AccordionItem>
|
|
45
|
+
</Accordion>
|
|
46
|
+
)}
|
|
47
|
+
</div>
|
|
48
|
+
</div>
|
|
49
|
+
</div>
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function App() {
|
|
54
|
+
const router = createBrowserRouter(
|
|
55
|
+
[
|
|
56
|
+
{
|
|
57
|
+
path: "/*",
|
|
58
|
+
element: (
|
|
59
|
+
<ErrorBoundary fallbackRender={fallbackRender}>
|
|
60
|
+
<ValFullscreen valApi={new ValApi("/api/val")} />
|
|
61
|
+
</ErrorBoundary>
|
|
62
|
+
),
|
|
63
|
+
},
|
|
64
|
+
],
|
|
65
|
+
{
|
|
66
|
+
basename: "/api/val/static/edit",
|
|
67
|
+
}
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
return <RouterProvider router={router} />;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export default App;
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { FC } from "react";
|
|
2
|
+
|
|
3
|
+
const Logo: FC<{ className?: string }> = ({ className }) => {
|
|
4
|
+
return (
|
|
5
|
+
<svg
|
|
6
|
+
width="58"
|
|
7
|
+
height="34"
|
|
8
|
+
viewBox="0 0 58 34"
|
|
9
|
+
fill="none"
|
|
10
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
11
|
+
className={className}
|
|
12
|
+
>
|
|
13
|
+
<g filter="url(#filter0_d_21_1677)">
|
|
14
|
+
<path
|
|
15
|
+
d="M5 5.36426C5 5.16309 5.16309 5 5.36426 5H17.6581C17.8593 5 18.0223 5.16309 18.0223 5.36426V28.4949C18.0223 28.696 17.8593 28.8591 17.6581 28.8591H5.36426C5.16309 28.8591 5 28.696 5 28.4949V5.36426Z"
|
|
16
|
+
fill="#38CD98"
|
|
17
|
+
/>
|
|
18
|
+
</g>
|
|
19
|
+
<g filter="url(#filter1_i_21_1677)">
|
|
20
|
+
<circle cx="11.4656" cy="23.7595" r="2.18557" fill="currentColor" />
|
|
21
|
+
</g>
|
|
22
|
+
<path
|
|
23
|
+
fillRule="evenodd"
|
|
24
|
+
clipRule="evenodd"
|
|
25
|
+
d="M52.8588 23.839H48.7257H48.537H48.1128C47.6715 23.839 47.4508 23.5942 47.4508 23.1044V13.7293C47.4508 13.5784 47.3285 13.4561 47.1777 13.4561H45.8118C45.6609 13.4561 45.5386 13.5784 45.5386 13.7293V15.1836C45.5386 15.2844 45.4569 15.3661 45.3561 15.3661C45.2876 15.3661 45.225 15.3275 45.1924 15.2672C44.805 14.5503 44.283 14.02 43.6264 13.6765C42.9563 13.301 42.2045 13.1132 41.3709 13.1132C40.6028 13.1132 39.8755 13.252 39.189 13.5295C38.5026 13.8071 37.8979 14.2152 37.3748 14.7539C36.8682 15.2764 36.4678 15.9212 36.1736 16.6885C35.8794 17.4558 35.7323 18.3374 35.7323 19.3332V19.725C35.7323 20.7372 35.8794 21.627 36.1736 22.3942C36.4678 23.1615 36.8682 23.8146 37.3748 24.3533C37.8979 24.8757 38.5026 25.2757 39.189 25.5532C39.8755 25.8144 40.6191 25.945 41.42 25.945C42.1881 25.945 42.9154 25.7491 43.6019 25.3573C44.2751 24.982 44.8058 24.4119 45.1941 23.6471C45.2255 23.5852 45.2886 23.5452 45.358 23.5452H45.3917C45.4728 23.5452 45.5386 23.611 45.5386 23.6921C45.5386 23.7904 45.544 23.8856 45.5547 23.9777V25.1392C45.5547 25.3904 45.7584 25.5941 46.0096 25.5941H47.2261C47.2914 25.5995 47.3581 25.6022 47.4263 25.6022H48.537H48.7257H57.7268C57.8777 25.6022 58 25.4799 58 25.329V24.1122C58 23.9614 57.8777 23.839 57.7268 23.839H55.3174C55.1665 23.839 55.0442 23.7167 55.0442 23.5659V8.73368C55.0442 8.58279 54.9219 8.46048 54.771 8.46048H50.5054C50.3545 8.46048 50.2322 8.58279 50.2322 8.73368V9.95043C50.2322 10.1013 50.3545 10.2236 50.5054 10.2236H52.8588C53.0097 10.2236 53.132 10.3459 53.132 10.4968V23.5659C53.132 23.7167 53.0097 23.839 52.8588 23.839ZM41.6161 24.1329C42.1881 24.1329 42.7111 24.0268 43.1851 23.8146C43.6754 23.6023 44.0922 23.3003 44.4354 22.9085C44.7786 22.5167 45.0483 22.0514 45.2444 21.5127C45.4406 20.9576 45.5386 20.3454 45.5386 19.6761V19.3822C45.5386 18.7292 45.4406 18.1333 45.2444 17.5946C45.0483 17.0395 44.7705 16.5661 44.4109 16.1743C44.0677 15.7824 43.6509 15.4804 43.1606 15.2682C42.6866 15.0396 42.1718 14.9254 41.6161 14.9254C41.044 14.9254 40.521 15.0315 40.0471 15.2437C39.5731 15.4559 39.1563 15.758 38.7968 16.1498C38.4535 16.5252 38.1839 16.9905 37.9877 17.5456C37.7916 18.0843 37.6936 18.6802 37.6936 19.3332V19.725C37.6936 21.1127 38.0531 22.1983 38.7722 22.982C39.5077 23.7493 40.4557 24.1329 41.6161 24.1329ZM31.1115 25.4191C31.0732 25.5287 30.9698 25.6022 30.8536 25.6022H27.4661C27.35 25.6022 27.2465 25.5287 27.2082 25.4191L23.1578 13.8193C23.0958 13.6417 23.2276 13.4561 23.4157 13.4561H25.089C25.2068 13.4561 25.3114 13.5316 25.3484 13.6435L28.9666 24.581C28.9942 24.6643 29.0721 24.7206 29.1599 24.7206C29.2477 24.7206 29.3256 24.6643 29.3532 24.581L32.9714 13.6435C33.0084 13.5316 33.1129 13.4561 33.2308 13.4561H34.9041C35.0922 13.4561 35.224 13.6417 35.162 13.8193L31.1115 25.4191Z"
|
|
26
|
+
fill="currentColor"
|
|
27
|
+
/>
|
|
28
|
+
<defs>
|
|
29
|
+
<filter
|
|
30
|
+
id="filter0_d_21_1677"
|
|
31
|
+
x="0.124722"
|
|
32
|
+
y="0.124722"
|
|
33
|
+
width="22.7729"
|
|
34
|
+
height="33.6097"
|
|
35
|
+
filterUnits="userSpaceOnUse"
|
|
36
|
+
colorInterpolationFilters="sRGB"
|
|
37
|
+
>
|
|
38
|
+
<feFlood floodOpacity="0" result="BackgroundImageFix" />
|
|
39
|
+
<feColorMatrix
|
|
40
|
+
in="SourceAlpha"
|
|
41
|
+
type="matrix"
|
|
42
|
+
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
|
|
43
|
+
result="hardAlpha"
|
|
44
|
+
/>
|
|
45
|
+
<feOffset />
|
|
46
|
+
<feGaussianBlur stdDeviation="2.43764" />
|
|
47
|
+
<feComposite in2="hardAlpha" operator="out" />
|
|
48
|
+
<feColorMatrix
|
|
49
|
+
type="matrix"
|
|
50
|
+
values="0 0 0 0 0.219608 0 0 0 0 0.803922 0 0 0 0 0.501961 0 0 0 0.3 0"
|
|
51
|
+
/>
|
|
52
|
+
<feBlend
|
|
53
|
+
mode="normal"
|
|
54
|
+
in2="BackgroundImageFix"
|
|
55
|
+
result="effect1_dropShadow_21_1677"
|
|
56
|
+
/>
|
|
57
|
+
<feBlend
|
|
58
|
+
mode="normal"
|
|
59
|
+
in="SourceGraphic"
|
|
60
|
+
in2="effect1_dropShadow_21_1677"
|
|
61
|
+
result="shape"
|
|
62
|
+
/>
|
|
63
|
+
</filter>
|
|
64
|
+
<filter
|
|
65
|
+
id="filter1_i_21_1677"
|
|
66
|
+
x="9.28003"
|
|
67
|
+
y="21.5739"
|
|
68
|
+
width="4.37112"
|
|
69
|
+
height="4.37112"
|
|
70
|
+
filterUnits="userSpaceOnUse"
|
|
71
|
+
colorInterpolationFilters="sRGB"
|
|
72
|
+
>
|
|
73
|
+
<feFlood floodOpacity="0" result="BackgroundImageFix" />
|
|
74
|
+
<feBlend
|
|
75
|
+
mode="normal"
|
|
76
|
+
in="SourceGraphic"
|
|
77
|
+
in2="BackgroundImageFix"
|
|
78
|
+
result="shape"
|
|
79
|
+
/>
|
|
80
|
+
<feColorMatrix
|
|
81
|
+
in="SourceAlpha"
|
|
82
|
+
type="matrix"
|
|
83
|
+
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
|
|
84
|
+
result="hardAlpha"
|
|
85
|
+
/>
|
|
86
|
+
<feOffset />
|
|
87
|
+
<feGaussianBlur stdDeviation="0.546392" />
|
|
88
|
+
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1" />
|
|
89
|
+
<feColorMatrix
|
|
90
|
+
type="matrix"
|
|
91
|
+
values="0 0 0 0 0.219608 0 0 0 0 0.803922 0 0 0 0 0.501961 0 0 0 0.3 0"
|
|
92
|
+
/>
|
|
93
|
+
<feBlend
|
|
94
|
+
mode="normal"
|
|
95
|
+
in2="shape"
|
|
96
|
+
result="effect1_innerShadow_21_1677"
|
|
97
|
+
/>
|
|
98
|
+
</filter>
|
|
99
|
+
</defs>
|
|
100
|
+
</svg>
|
|
101
|
+
);
|
|
102
|
+
};
|
|
103
|
+
export default Logo;
|
|
@@ -9,6 +9,10 @@ export interface ButtonProps
|
|
|
9
9
|
disabled?: boolean;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
+
/**
|
|
13
|
+
*
|
|
14
|
+
* @deprecated Use ui/Button
|
|
15
|
+
*/
|
|
12
16
|
export function PrimaryButton({
|
|
13
17
|
children,
|
|
14
18
|
onClick,
|
|
@@ -41,9 +45,9 @@ const Button: FC<ButtonProps> = ({
|
|
|
41
45
|
"font-sans font-[12px] tracking-[0.04em] py-1 px-2 rounded whitespace-nowrap group relative text-primary",
|
|
42
46
|
{
|
|
43
47
|
"font-bold": variant === "primary",
|
|
44
|
-
"bg-
|
|
48
|
+
"bg-background hover:bg-background text-fill disabled:bg-fill disabled:text-background":
|
|
45
49
|
variant === "primary",
|
|
46
|
-
"bg-transparent border border-primary text-primary hover:border-highlight hover:text-highlight disabled:bg-fill disabled:text-
|
|
50
|
+
"bg-transparent border border-primary text-primary hover:border-highlight hover:text-highlight disabled:bg-fill disabled:text-background":
|
|
47
51
|
variant !== "primary",
|
|
48
52
|
}
|
|
49
53
|
)}
|
|
@@ -57,4 +61,8 @@ const Button: FC<ButtonProps> = ({
|
|
|
57
61
|
);
|
|
58
62
|
};
|
|
59
63
|
|
|
64
|
+
/**
|
|
65
|
+
*
|
|
66
|
+
* @deprecated Use ui/Button
|
|
67
|
+
*/
|
|
60
68
|
export default Button;
|
|
@@ -81,9 +81,9 @@ const Dropdown: React.FC<DropdownProps> = ({
|
|
|
81
81
|
ev.preventDefault();
|
|
82
82
|
handleSelect(option, idx);
|
|
83
83
|
}}
|
|
84
|
-
className={`text-left px-2 py-1 hover:bg-
|
|
84
|
+
className={`text-left px-2 py-1 hover:bg-background hover:text-highlight ${
|
|
85
85
|
idx === selectedOption &&
|
|
86
|
-
"font-bold bg-
|
|
86
|
+
"font-bold bg-background hover:bg-background truncate"
|
|
87
87
|
}`}
|
|
88
88
|
>
|
|
89
89
|
{option}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
2
|
import { Grid } from "./Grid";
|
|
3
|
-
import { Tree } from "./Tree";
|
|
4
|
-
import { Dropdown } from "./Dropdown";
|
|
5
|
-
import { FormGroup } from "./FormGroup";
|
|
3
|
+
import { Tree } from "./dashboard/Tree";
|
|
4
|
+
import { Dropdown } from "./dashboard/Dropdown";
|
|
6
5
|
|
|
7
6
|
const meta: Meta<typeof Grid> = { component: Grid };
|
|
8
7
|
|
|
@@ -24,26 +23,18 @@ export const Default: Story = {
|
|
|
24
23
|
</Tree.Node>
|
|
25
24
|
</Tree.Node>
|
|
26
25
|
</Tree>
|
|
27
|
-
<div className="
|
|
26
|
+
<div className="flex items-center justify-between w-full h-full px-3 font-serif text-xs text-white">
|
|
28
27
|
<p>Content</p>
|
|
29
|
-
<button className="flex justify-between
|
|
28
|
+
<button className="flex justify-between flex-shrink-0 gap-1">
|
|
30
29
|
<span className="w-fit">+</span>
|
|
31
30
|
<span className="w-fit">Add item</span>
|
|
32
31
|
</button>
|
|
33
32
|
</div>
|
|
34
33
|
<div>
|
|
35
|
-
<
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
<div>Object 4</div>
|
|
40
|
-
</FormGroup>
|
|
41
|
-
<FormGroup>
|
|
42
|
-
<div>Object 5</div>
|
|
43
|
-
<div>Object 6</div>
|
|
44
|
-
<div>Object 7</div>
|
|
45
|
-
<div>Object 8</div>
|
|
46
|
-
</FormGroup>
|
|
34
|
+
<div>Object 1</div>
|
|
35
|
+
<div>Object 2</div>
|
|
36
|
+
<div>Object 3</div>
|
|
37
|
+
<div>Object 4</div>
|
|
47
38
|
</div>
|
|
48
39
|
<div className="text-white">History</div>
|
|
49
40
|
<div className="text-white">hey</div>
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import classNames from "classnames";
|
|
1
2
|
import { Children, useEffect, useRef } from "react";
|
|
3
|
+
import { ScrollArea } from "./ui/scroll-area";
|
|
2
4
|
|
|
3
5
|
type GridProps = {
|
|
4
6
|
children: React.ReactNode | React.ReactNode[];
|
|
@@ -70,41 +72,54 @@ export function Grid({ children }: GridProps): React.ReactElement {
|
|
|
70
72
|
}, []);
|
|
71
73
|
|
|
72
74
|
return (
|
|
73
|
-
<div className="flex
|
|
75
|
+
<div className="flex h-screen">
|
|
74
76
|
<div
|
|
75
77
|
ref={leftColRef}
|
|
76
|
-
className="relative
|
|
78
|
+
className="relative border-r border-border"
|
|
77
79
|
style={{ width: 300 }}
|
|
78
80
|
>
|
|
79
81
|
<Grid.Column>
|
|
80
82
|
{header1}
|
|
81
|
-
{
|
|
83
|
+
<ScrollArea style={{ height: "calc(100vh - 50px)" }}>
|
|
84
|
+
{body1}
|
|
85
|
+
</ScrollArea>
|
|
82
86
|
</Grid.Column>
|
|
83
87
|
<div
|
|
84
|
-
className="absolute inset-y-0 right-0 cursor-col-resize w-[1px]
|
|
88
|
+
className="absolute inset-y-0 right-0 cursor-col-resize w-[1px] hover:w-[3px] h-full hover:bg-border"
|
|
85
89
|
onMouseDown={handleMouseDown("left")}
|
|
86
90
|
></div>
|
|
87
91
|
</div>
|
|
88
|
-
<div className="flex-auto bg-warm-black">
|
|
89
|
-
<Grid.Column>
|
|
90
|
-
{header2}
|
|
91
|
-
{body2}
|
|
92
|
-
</Grid.Column>
|
|
93
|
-
</div>
|
|
94
92
|
<div
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
93
|
+
className={classNames("", {
|
|
94
|
+
"w-full": !header3 && !body3,
|
|
95
|
+
})}
|
|
98
96
|
>
|
|
99
97
|
<Grid.Column>
|
|
100
|
-
{
|
|
101
|
-
{
|
|
98
|
+
{header2}
|
|
99
|
+
<ScrollArea style={{ height: "calc(100vh - 50px)" }}>
|
|
100
|
+
{body2}
|
|
101
|
+
</ScrollArea>
|
|
102
102
|
</Grid.Column>
|
|
103
|
-
<div
|
|
104
|
-
onMouseDown={handleMouseDown("right")}
|
|
105
|
-
className="absolute inset-y-0 left-0 cursor-col-resize w-[1px] bg-dark-gray hover:w-[2px] hover:bg-light-gray"
|
|
106
|
-
></div>
|
|
107
103
|
</div>
|
|
104
|
+
{header3 ||
|
|
105
|
+
(body3 && (
|
|
106
|
+
<div
|
|
107
|
+
ref={rightColRef}
|
|
108
|
+
className="relative h-screen border-l border-border"
|
|
109
|
+
style={{ width: 300 }}
|
|
110
|
+
>
|
|
111
|
+
<Grid.Column>
|
|
112
|
+
{header3}
|
|
113
|
+
<ScrollArea style={{ height: "calc(100vh - 50px)" }}>
|
|
114
|
+
{body3}
|
|
115
|
+
</ScrollArea>
|
|
116
|
+
</Grid.Column>
|
|
117
|
+
<div
|
|
118
|
+
onMouseDown={handleMouseDown("right")}
|
|
119
|
+
className="absolute inset-y-0 left-0 cursor-col-resize w-[1px] bg-border hover:w-[3px] hover:bg-border"
|
|
120
|
+
></div>
|
|
121
|
+
</div>
|
|
122
|
+
))}
|
|
108
123
|
</div>
|
|
109
124
|
);
|
|
110
125
|
}
|
|
@@ -116,10 +131,8 @@ type GridChildProps = {
|
|
|
116
131
|
Grid.Column = ({ children }: GridChildProps): React.ReactElement => {
|
|
117
132
|
const [header, body] = Children.toArray(children);
|
|
118
133
|
return (
|
|
119
|
-
<div className="flex flex-col
|
|
120
|
-
<div className="
|
|
121
|
-
{header}
|
|
122
|
-
</div>
|
|
134
|
+
<div className="flex flex-col">
|
|
135
|
+
<div className="flex items-center border-b border-border">{header}</div>
|
|
123
136
|
{body}
|
|
124
137
|
</div>
|
|
125
138
|
);
|
|
@@ -1,4 +1,112 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { useCallback, useState } from "react";
|
|
4
|
+
import "../../richtext/shadowRootPolyFill";
|
|
5
|
+
|
|
6
|
+
export type Props = {
|
|
7
|
+
ariaActiveDescendant?: React.AriaAttributes["aria-activedescendant"];
|
|
8
|
+
ariaAutoComplete?: React.AriaAttributes["aria-autocomplete"];
|
|
9
|
+
ariaControls?: React.AriaAttributes["aria-controls"];
|
|
10
|
+
ariaDescribedBy?: React.AriaAttributes["aria-describedby"];
|
|
11
|
+
ariaExpanded?: React.AriaAttributes["aria-expanded"];
|
|
12
|
+
ariaLabel?: React.AriaAttributes["aria-label"];
|
|
13
|
+
ariaLabelledBy?: React.AriaAttributes["aria-labelledby"];
|
|
14
|
+
ariaMultiline?: React.AriaAttributes["aria-multiline"];
|
|
15
|
+
ariaOwns?: React.AriaAttributes["aria-owns"];
|
|
16
|
+
ariaRequired?: React.AriaAttributes["aria-required"];
|
|
17
|
+
autoCapitalize?: HTMLDivElement["autocapitalize"];
|
|
18
|
+
"data-testid"?: string | null | undefined;
|
|
19
|
+
} & React.AllHTMLAttributes<HTMLDivElement>;
|
|
20
|
+
|
|
21
|
+
export function ContentEditable({
|
|
22
|
+
ariaActiveDescendant,
|
|
23
|
+
ariaAutoComplete,
|
|
24
|
+
ariaControls,
|
|
25
|
+
ariaDescribedBy,
|
|
26
|
+
ariaExpanded,
|
|
27
|
+
ariaLabel,
|
|
28
|
+
ariaLabelledBy,
|
|
29
|
+
ariaMultiline,
|
|
30
|
+
ariaOwns,
|
|
31
|
+
ariaRequired,
|
|
32
|
+
autoCapitalize,
|
|
33
|
+
className,
|
|
34
|
+
id,
|
|
35
|
+
role = "textbox",
|
|
36
|
+
spellCheck = true,
|
|
37
|
+
style,
|
|
38
|
+
tabIndex,
|
|
39
|
+
"data-testid": testid,
|
|
40
|
+
...rest
|
|
41
|
+
}: Props): JSX.Element {
|
|
42
|
+
const [editor] = useLexicalComposerContext();
|
|
43
|
+
const [isEditable, setEditable] = useState(false);
|
|
44
|
+
|
|
45
|
+
const ref = useCallback(
|
|
46
|
+
(rootElement: null | HTMLElement) => {
|
|
47
|
+
editor.setRootElement(rootElement);
|
|
48
|
+
const shadowRoot = document.getElementById("val-ui")?.shadowRoot;
|
|
49
|
+
if (!shadowRoot) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
// Lexical doesnt officially support shadow dom yet, but this is a workaround
|
|
53
|
+
// It happens to work in firefox since their document.getSelection pierces shadow dom
|
|
54
|
+
// Chrome does not do this,. but has getSelection on the shadowRoot
|
|
55
|
+
// Safari does not have getSelection on the shadowRoot, and document.getSelection does not pierce shadow dom
|
|
56
|
+
// So for Safari this is polyfilled in shadowRootPolyFill.js
|
|
57
|
+
// https://github.com/facebook/lexical/issues/2119
|
|
58
|
+
//
|
|
59
|
+
// In the code below we have a hack to override the window object on the editor with the shadowRoot
|
|
60
|
+
// then it will call getSelection on the shadowRoot instead of the document
|
|
61
|
+
if ("getSelection" in shadowRoot) {
|
|
62
|
+
// safari (if polyfilled) and chrome
|
|
63
|
+
editor._window = shadowRoot as unknown as Window;
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
[editor]
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
React.useLayoutEffect(() => {
|
|
71
|
+
setEditable(editor.isEditable());
|
|
72
|
+
return editor.registerEditableListener((currentIsEditable) => {
|
|
73
|
+
setEditable(currentIsEditable);
|
|
74
|
+
});
|
|
75
|
+
}, [editor]);
|
|
76
|
+
|
|
77
|
+
return (
|
|
78
|
+
<div
|
|
79
|
+
{...rest}
|
|
80
|
+
aria-activedescendant={!isEditable ? undefined : ariaActiveDescendant}
|
|
81
|
+
aria-autocomplete={!isEditable ? "none" : ariaAutoComplete}
|
|
82
|
+
aria-controls={!isEditable ? undefined : ariaControls}
|
|
83
|
+
aria-describedby={ariaDescribedBy}
|
|
84
|
+
aria-expanded={
|
|
85
|
+
!isEditable
|
|
86
|
+
? undefined
|
|
87
|
+
: role === "combobox"
|
|
88
|
+
? !!ariaExpanded
|
|
89
|
+
: undefined
|
|
90
|
+
}
|
|
91
|
+
aria-label={ariaLabel}
|
|
92
|
+
aria-labelledby={ariaLabelledBy}
|
|
93
|
+
aria-multiline={ariaMultiline}
|
|
94
|
+
aria-owns={!isEditable ? undefined : ariaOwns}
|
|
95
|
+
aria-readonly={!isEditable ? true : undefined}
|
|
96
|
+
aria-required={ariaRequired}
|
|
97
|
+
autoCapitalize={autoCapitalize}
|
|
98
|
+
className={className}
|
|
99
|
+
contentEditable={isEditable}
|
|
100
|
+
data-testid={testid}
|
|
101
|
+
id={id}
|
|
102
|
+
ref={ref}
|
|
103
|
+
role={role}
|
|
104
|
+
spellCheck={spellCheck}
|
|
105
|
+
style={style}
|
|
106
|
+
tabIndex={tabIndex}
|
|
107
|
+
/>
|
|
108
|
+
);
|
|
109
|
+
}
|
|
2
110
|
|
|
3
111
|
export default function LexicalContentEditable({
|
|
4
112
|
className,
|
|
@@ -300,7 +300,7 @@ const Toolbar: FC<ToolbarSettingsProps> = ({
|
|
|
300
300
|
};
|
|
301
301
|
|
|
302
302
|
return (
|
|
303
|
-
<div className="sticky top-0 border-b bg-
|
|
303
|
+
<div className="sticky top-0 border-b bg-background border-highlight flex flex-col">
|
|
304
304
|
<div className="flex flex-row gap-1">
|
|
305
305
|
<Dropdown
|
|
306
306
|
options={Object.values(blockTypes)}
|
|
@@ -379,7 +379,7 @@ const Toolbar: FC<ToolbarSettingsProps> = ({
|
|
|
379
379
|
<input
|
|
380
380
|
type="text"
|
|
381
381
|
placeholder="Enter URL"
|
|
382
|
-
className="w-1/3 text-primary bg-
|
|
382
|
+
className="w-1/3 text-primary bg-background px-2"
|
|
383
383
|
value={url}
|
|
384
384
|
onChange={(ev) => {
|
|
385
385
|
ev.preventDefault();
|
|
@@ -82,7 +82,7 @@ export const RichTextEditor: FC<RichTextEditorProps> = ({
|
|
|
82
82
|
<RichTextPlugin
|
|
83
83
|
contentEditable={
|
|
84
84
|
<div
|
|
85
|
-
className="
|
|
85
|
+
className="font-sans border-b text-primary border-highlight"
|
|
86
86
|
style={{
|
|
87
87
|
minHeight: windowSize?.innerHeight
|
|
88
88
|
? windowSize?.innerHeight - TOOLBAR_HEIGHT
|