Add some sidebars and license stuff
This commit is contained in:
4
.husky/pre-commit
Executable file
4
.husky/pre-commit
Executable file
@ -0,0 +1,4 @@
|
||||
#!/usr/bin/env sh
|
||||
. "$(dirname -- "$0")/_/husky.sh"
|
||||
|
||||
pnpm pre-commit
|
@ -4,4 +4,6 @@
|
||||
**/node_modules
|
||||
/public
|
||||
/dist
|
||||
.husky
|
||||
src/assets/
|
||||
|
||||
|
44
license-emit.js
Normal file
44
license-emit.js
Normal file
@ -0,0 +1,44 @@
|
||||
import { spawn } from 'child_process';
|
||||
import { dirname } from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
import { outputJsonSync } from 'fs-extra/esm';
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
const licenseReportFile = [`${__dirname}/src/assets/licenses.json`];
|
||||
|
||||
const licenseReportExec = {
|
||||
// exec: `${__dirname}/node_modules/.bin/license-report`,
|
||||
exec: `license-report`,
|
||||
args: [`--config=${__dirname}/license-report.config.json`],
|
||||
};
|
||||
|
||||
/*
|
||||
{
|
||||
name: z.string(),
|
||||
licenseType: z.string(),
|
||||
author: z.string(),
|
||||
link: z.string().url().optional(),
|
||||
installedFrom: z.string().url().optional(),
|
||||
}[]
|
||||
*/
|
||||
const externalLicenses = [];
|
||||
|
||||
const emitReport = (file, toExec, externalLicenses) => {
|
||||
const exec = spawn(toExec.exec, toExec.args);
|
||||
|
||||
let licensesString = '';
|
||||
exec.stdout.on('data', (data) => {
|
||||
licensesString += data.toString();
|
||||
});
|
||||
|
||||
exec.on('close', (code) => {
|
||||
console.log(`child process exited with code ${code}`);
|
||||
const licenses = JSON.parse(licensesString);
|
||||
const report = licenses.concat(externalLicenses);
|
||||
outputJsonSync(file, report, { spaces: 2 });
|
||||
});
|
||||
};
|
||||
|
||||
for (const file of licenseReportFile) {
|
||||
emitReport(file, licenseReportExec, externalLicenses);
|
||||
}
|
4
license-report.config.json
Normal file
4
license-report.config.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"output": "json",
|
||||
"fields": ["name", "licenseType", "author", "link", "installedFrom"]
|
||||
}
|
35
package.json
35
package.json
@ -3,23 +3,40 @@
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"type": "module",
|
||||
"lint-staged": {
|
||||
"*": [
|
||||
"node license-emit.js"
|
||||
],
|
||||
"*.{ts,tsx,js,cjs,json,html,css}": [
|
||||
"prettier --write"
|
||||
],
|
||||
"src/**/*.{ts,tsx}": [
|
||||
"eslint --fix --report-unused-disable-directives --max-warnings 0"
|
||||
]
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "tsc && vite build",
|
||||
"pre-commit": "lint-staged",
|
||||
"pre-build:license-report": "node license-emit.js",
|
||||
"build": "run-s pre-build build:*",
|
||||
"build:vite": "tsc && vite build",
|
||||
"lint": "eslint src --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
|
||||
"fmt": "prettier --write \"**/*.{ts,tsx,js,cjs,json,html,css}\"",
|
||||
"preview": "vite preview"
|
||||
"preview": "vite preview",
|
||||
"prepare": "husky install"
|
||||
},
|
||||
"dependencies": {
|
||||
"@emotion/react": "^11.11.1",
|
||||
"@emotion/styled": "^11.11.0",
|
||||
"@excalidraw/excalidraw": "^0.15.2",
|
||||
"@fontsource/roboto": "^5.0.5",
|
||||
"@mui/icons-material": "^5.14.1",
|
||||
"@mui/material": "^5.14.1",
|
||||
"@mui/styled-engine-sc": "^5.12.0",
|
||||
"jotai": "^2.2.2",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0"
|
||||
"react-dom": "^18.2.0",
|
||||
"styled-components": "^6.0.4",
|
||||
"ts-pattern": "^5.0.4",
|
||||
"zod": "^3.21.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/react": "^18.2.14",
|
||||
@ -30,8 +47,14 @@
|
||||
"eslint": "^8.44.0",
|
||||
"eslint-plugin-react-hooks": "^4.6.0",
|
||||
"eslint-plugin-react-refresh": "^0.4.1",
|
||||
"fs-extra": "^11.1.1",
|
||||
"husky": "^8.0.0",
|
||||
"license-report": "^6.4.0",
|
||||
"lint-staged": "^13.2.3",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"prettier": "^3.0.0",
|
||||
"typescript": "^5.0.2",
|
||||
"vite": "^4.4.0"
|
||||
"vite": "^4.4.0",
|
||||
"vite-tsconfig-paths": "^4.2.0"
|
||||
}
|
||||
}
|
||||
|
3139
pnpm-lock.yaml
generated
3139
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
124
src/App.tsx
124
src/App.tsx
@ -1,119 +1,21 @@
|
||||
import { Excalidraw, Sidebar } from '@excalidraw/excalidraw';
|
||||
import { Box, Button, Container } from '@mui/material';
|
||||
import type {
|
||||
ExcalidrawProps,
|
||||
ExcalidrawImperativeAPI,
|
||||
} from '@excalidraw/excalidraw/types/types';
|
||||
import { FC, useState } from 'react';
|
||||
import styled from 'styled-components';
|
||||
import ExcalidrawMain from '@/Components/Excalidraw';
|
||||
|
||||
const ExcalidrawContainer: FC<
|
||||
ExcalidrawProps & { refCallback: (api: ExcalidrawImperativeAPI) => void }
|
||||
> = (props) => {
|
||||
return (
|
||||
<Container>
|
||||
<Box
|
||||
sx={{
|
||||
border: '1.5px solid',
|
||||
width: '95vw',
|
||||
height: '95vh',
|
||||
}}
|
||||
>
|
||||
<Excalidraw {...props} ref={props.refCallback} />
|
||||
</Box>
|
||||
</Container>
|
||||
);
|
||||
};
|
||||
export const Main = styled.div`
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
margin-right: -50%;
|
||||
transform: translate(-50%, -50%);
|
||||
`;
|
||||
|
||||
function App() {
|
||||
// TODO: jotai premitives
|
||||
const isCollaborating = false;
|
||||
|
||||
const [excalidrawAPI, setExcalidrawAPI] = useState<ExcalidrawImperativeAPI>();
|
||||
|
||||
return (
|
||||
<Container
|
||||
sx={{
|
||||
display: 'grid',
|
||||
height: '100%',
|
||||
width: '100%',
|
||||
placeContent: 'center',
|
||||
overflow: 'hidden',
|
||||
}}
|
||||
>
|
||||
<ExcalidrawContainer
|
||||
refCallback={(api) => setExcalidrawAPI(api)}
|
||||
isCollaborating={isCollaborating}
|
||||
autoFocus={true}
|
||||
name="Excalidraw with WebRTC"
|
||||
renderTopRightUI={() => {
|
||||
return (
|
||||
<Button
|
||||
onClick={() => {
|
||||
excalidrawAPI?.toggleMenu('customSidebar');
|
||||
}}
|
||||
>
|
||||
Button
|
||||
</Button>
|
||||
);
|
||||
}}
|
||||
renderSidebar={() => {
|
||||
return (
|
||||
<Sidebar dockable={true}>
|
||||
<Sidebar.Header> Header </Sidebar.Header>
|
||||
<Button>Button</Button>
|
||||
</Sidebar>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</Container>
|
||||
<Main>
|
||||
<ExcalidrawMain />
|
||||
</Main>
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
export interface ExcalidrawProps {
|
||||
// Render UI elements
|
||||
renderTopRightUI?: (isMobile: boolean, appState: AppState) => JSX.Element | null;
|
||||
renderSidebar?: () => JSX.Element | null;
|
||||
|
||||
onChange?: (elements: readonly ExcalidrawElement[], appState: AppState, files: BinaryFiles) => void;
|
||||
initialData?: ExcalidrawInitialDataState | null | Promise<ExcalidrawInitialDataState | null>;
|
||||
excalidrawRef?: ForwardRef<ExcalidrawAPIRefValue>;
|
||||
isCollaborating?: boolean;
|
||||
onPointerUpdate?: (payload: {
|
||||
pointer: {
|
||||
x: number;
|
||||
y: number;
|
||||
};
|
||||
button: "down" | "up";
|
||||
pointersMap: Gesture["pointers"];
|
||||
}) => void;
|
||||
onPaste?: (data: ClipboardData, event: ClipboardEvent | null) => Promise<boolean> | boolean;
|
||||
|
||||
|
||||
|
||||
|
||||
langCode?: Language["code"];
|
||||
onPointerDown?: (activeTool: AppState["activeTool"], pointerDownState: PointerDownState) => void;
|
||||
generateIdForFile?: (file: File) => string | Promise<string>;
|
||||
UIOptions?: Partial<UIOptions>;
|
||||
renderCustomStats?: (elements: readonly NonDeletedExcalidrawElement[], appState: AppState) => JSX.Element;
|
||||
|
||||
viewModeEnabled?: boolean;
|
||||
zenModeEnabled?: boolean;
|
||||
gridModeEnabled?: boolean;
|
||||
libraryReturnUrl?: string;
|
||||
name?: string;
|
||||
theme?: Theme;
|
||||
detectScroll?: boolean;
|
||||
handleKeyboardGlobally?: boolean;
|
||||
onLibraryChange?: (libraryItems: LibraryItems) => void | Promise<any>;
|
||||
autoFocus?: boolean;
|
||||
onLinkOpen?: (element: NonDeletedExcalidrawElement, event: CustomEvent<{
|
||||
nativeEvent: MouseEvent | React.PointerEvent<HTMLCanvasElement>;
|
||||
}>) => void;
|
||||
onScrollChange?: (scrollX: number, scrollY: number) => void;
|
||||
children?: React.ReactNode;
|
||||
}
|
||||
*/
|
||||
|
||||
export default App;
|
||||
|
87
src/Components/Excalidraw.tsx
Normal file
87
src/Components/Excalidraw.tsx
Normal file
@ -0,0 +1,87 @@
|
||||
import { ExcalidrawImperativeAPI } from '@excalidraw/excalidraw/types/types';
|
||||
import ExcalidrawContainer from './Excalidraw/Container';
|
||||
import { useCallback, useState } from 'react';
|
||||
import Sidebar, { SidebarVariant } from './Excalidraw/Sidebar';
|
||||
import RightTopUI from './Excalidraw/RightTopUI';
|
||||
|
||||
export const ExcalidrawMain = () => {
|
||||
const [excalidrawAPI, setExcalidrawAPI] = useState<ExcalidrawImperativeAPI>();
|
||||
|
||||
const [sidebarVariant, setSidebarVariant] =
|
||||
useState<SidebarVariant>('general');
|
||||
|
||||
const [toggleState, setToggleState] = useState<boolean>(false);
|
||||
|
||||
const onClose = useCallback(
|
||||
() => setToggleState(!toggleState),
|
||||
[toggleState]
|
||||
);
|
||||
|
||||
return (
|
||||
<ExcalidrawContainer
|
||||
refCallback={(api) => setExcalidrawAPI(api)}
|
||||
autoFocus={true}
|
||||
name="Excalidraw with WebRTC"
|
||||
renderTopRightUI={() => (
|
||||
<RightTopUI
|
||||
toggleState={toggleState}
|
||||
setToggleState={setToggleState}
|
||||
setSidebarVariant={setSidebarVariant}
|
||||
excalidrawAPI={excalidrawAPI!}
|
||||
/>
|
||||
)}
|
||||
renderSidebar={() => {
|
||||
return <Sidebar variant={sidebarVariant} variantProps={{ onClose }} />;
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
/*
|
||||
export interface ExcalidrawProps {
|
||||
// Render UI elements
|
||||
renderTopRightUI?: (isMobile: boolean, appState: AppState) => JSX.Element | null;
|
||||
renderSidebar?: () => JSX.Element | null;
|
||||
|
||||
onChange?: (elements: readonly ExcalidrawElement[], appState: AppState, files: BinaryFiles) => void;
|
||||
initialData?: ExcalidrawInitialDataState | null | Promise<ExcalidrawInitialDataState | null>;
|
||||
excalidrawRef?: ForwardRef<ExcalidrawAPIRefValue>;
|
||||
isCollaborating?: boolean;
|
||||
onPointerUpdate?: (payload: {
|
||||
pointer: {
|
||||
x: number;
|
||||
y: number;
|
||||
};
|
||||
button: "down" | "up";
|
||||
pointersMap: Gesture["pointers"];
|
||||
}) => void;
|
||||
onPaste?: (data: ClipboardData, event: ClipboardEvent | null) => Promise<boolean> | boolean;
|
||||
|
||||
|
||||
|
||||
|
||||
langCode?: Language["code"];
|
||||
onPointerDown?: (activeTool: AppState["activeTool"], pointerDownState: PointerDownState) => void;
|
||||
generateIdForFile?: (file: File) => string | Promise<string>;
|
||||
UIOptions?: Partial<UIOptions>;
|
||||
renderCustomStats?: (elements: readonly NonDeletedExcalidrawElement[], appState: AppState) => JSX.Element;
|
||||
|
||||
viewModeEnabled?: boolean;
|
||||
zenModeEnabled?: boolean;
|
||||
gridModeEnabled?: boolean;
|
||||
libraryReturnUrl?: string;
|
||||
name?: string;
|
||||
theme?: Theme;
|
||||
detectScroll?: boolean;
|
||||
handleKeyboardGlobally?: boolean;
|
||||
onLibraryChange?: (libraryItems: LibraryItems) => void | Promise<any>;
|
||||
autoFocus?: boolean;
|
||||
onLinkOpen?: (element: NonDeletedExcalidrawElement, event: CustomEvent<{
|
||||
nativeEvent: MouseEvent | React.PointerEvent<HTMLCanvasElement>;
|
||||
}>) => void;
|
||||
onScrollChange?: (scrollX: number, scrollY: number) => void;
|
||||
children?: React.ReactNode;
|
||||
}
|
||||
*/
|
||||
|
||||
export default ExcalidrawMain;
|
68
src/Components/Excalidraw/Container.tsx
Normal file
68
src/Components/Excalidraw/Container.tsx
Normal file
@ -0,0 +1,68 @@
|
||||
import { Excalidraw } from '@excalidraw/excalidraw';
|
||||
import type {
|
||||
ExcalidrawProps,
|
||||
ExcalidrawImperativeAPI,
|
||||
} from '@excalidraw/excalidraw/types/types';
|
||||
import { FC, useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import styled from 'styled-components';
|
||||
|
||||
export type WindowRect = {
|
||||
width: number;
|
||||
height: number;
|
||||
};
|
||||
|
||||
export type ExcalidrawBoxProps = {
|
||||
$windowRect: WindowRect;
|
||||
$scale?: number;
|
||||
};
|
||||
|
||||
const ExcalidrawBox = styled.div<ExcalidrawBoxProps>`
|
||||
${(props) => {
|
||||
const { $windowRect: windowRect, $scale: $scale } = props;
|
||||
const scale = $scale! ? $scale : 1;
|
||||
const { width, height } = windowRect;
|
||||
|
||||
const scaledWidth = width * scale;
|
||||
const scaledHeight = height * scale;
|
||||
return `
|
||||
width: ${scaledWidth}px;
|
||||
height: ${scaledHeight}px;
|
||||
`;
|
||||
}}
|
||||
`;
|
||||
|
||||
export type ExcalidrawContainerProps = ExcalidrawProps & {
|
||||
refCallback: (api: ExcalidrawImperativeAPI) => void;
|
||||
} & Omit<ExcalidrawBoxProps, '$windowRect'>;
|
||||
|
||||
export const ExcalidrawContainer: FC<ExcalidrawContainerProps> = (props) => {
|
||||
const scale = useMemo(
|
||||
() => (props.$scale ? props.$scale : 1),
|
||||
[props.$scale]
|
||||
);
|
||||
|
||||
const [windowRect, setWindowRect] = useState<WindowRect>({
|
||||
width: window.innerWidth,
|
||||
height: window.innerHeight,
|
||||
});
|
||||
|
||||
const onResize = useCallback(() => {
|
||||
setWindowRect({
|
||||
width: window.innerWidth,
|
||||
height: window.innerHeight,
|
||||
});
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
window.addEventListener('resize', onResize);
|
||||
return () => window.removeEventListener('resize', onResize);
|
||||
}, [onResize]);
|
||||
|
||||
return (
|
||||
<ExcalidrawBox $scale={scale} $windowRect={windowRect}>
|
||||
<Excalidraw {...props} ref={props.refCallback} />
|
||||
</ExcalidrawBox>
|
||||
);
|
||||
};
|
||||
|
||||
export default ExcalidrawContainer;
|
43
src/Components/Excalidraw/RightTopUI.tsx
Normal file
43
src/Components/Excalidraw/RightTopUI.tsx
Normal file
@ -0,0 +1,43 @@
|
||||
import { ExcalidrawImperativeAPI } from '@excalidraw/excalidraw/types/types';
|
||||
import { FC, useCallback } from 'react';
|
||||
import { ToggleButton, ToggleButtonGroup } from '@/Components/Utilities';
|
||||
import { SidebarVariant, SidebarVariantSchema } from './Sidebar';
|
||||
import { z } from 'zod';
|
||||
|
||||
export const RightTopUIPropsScheme = z.object({
|
||||
setSidebarVariant: z.function().args(SidebarVariantSchema).returns(z.void()),
|
||||
setToggleState: z.function().args(z.boolean()).returns(z.void()),
|
||||
toggleState: z.boolean(),
|
||||
});
|
||||
|
||||
export type RightTopUIProps = z.infer<typeof RightTopUIPropsScheme> & {
|
||||
excalidrawAPI: ExcalidrawImperativeAPI;
|
||||
};
|
||||
|
||||
const RightTopUI: FC<RightTopUIProps> = (props) => {
|
||||
const excalidrawAPI = props.excalidrawAPI;
|
||||
|
||||
const sidebarToggle = useCallback(
|
||||
(variant: SidebarVariant) => {
|
||||
if (excalidrawAPI && !props.toggleState) {
|
||||
props.setToggleState(props.toggleState);
|
||||
props.setSidebarVariant(variant);
|
||||
excalidrawAPI.toggleMenu('customSidebar');
|
||||
}
|
||||
},
|
||||
[excalidrawAPI, props]
|
||||
);
|
||||
|
||||
return (
|
||||
<ToggleButtonGroup
|
||||
exclusive
|
||||
onChange={(_, value: SidebarVariant) => sidebarToggle(value)}
|
||||
disabled={props.toggleState}
|
||||
>
|
||||
<ToggleButton value="general">General</ToggleButton>
|
||||
<ToggleButton value="collaboration">Collaboration</ToggleButton>
|
||||
</ToggleButtonGroup>
|
||||
);
|
||||
};
|
||||
|
||||
export default RightTopUI;
|
40
src/Components/Excalidraw/Sidebar.tsx
Normal file
40
src/Components/Excalidraw/Sidebar.tsx
Normal file
@ -0,0 +1,40 @@
|
||||
import { FC } from 'react';
|
||||
import { match } from 'ts-pattern';
|
||||
import { z } from 'zod';
|
||||
import CollaborationSidebar, {
|
||||
CollaborationSidebarPropsSchema,
|
||||
} from './Sidebar/Collaboration';
|
||||
import GeneralSidebar, { GeneralSidebarPropsSchema } from './Sidebar/General';
|
||||
|
||||
export const SidebarVariantSchema = z.enum(['collaboration', 'general']);
|
||||
|
||||
export type SidebarVariant = z.infer<typeof SidebarVariantSchema>;
|
||||
|
||||
export const SidebarVariantPropsSchema = z.union([
|
||||
CollaborationSidebarPropsSchema,
|
||||
GeneralSidebarPropsSchema,
|
||||
]);
|
||||
|
||||
export type SidebarVariantProps = z.infer<typeof SidebarVariantPropsSchema>;
|
||||
|
||||
export const SidebarProrps = z.object({
|
||||
variant: SidebarVariantSchema,
|
||||
variantProps: SidebarVariantPropsSchema,
|
||||
});
|
||||
|
||||
export type SidebarProps = z.infer<typeof SidebarProrps>;
|
||||
|
||||
export const Sidebar: FC<SidebarProps> = (props) => {
|
||||
return match(props.variant)
|
||||
.with('collaboration', () => {
|
||||
const _props = CollaborationSidebarPropsSchema.parse(props.variantProps);
|
||||
return <CollaborationSidebar {..._props} />;
|
||||
})
|
||||
.with('general', () => {
|
||||
const _props = GeneralSidebarPropsSchema.parse(props.variantProps);
|
||||
return <GeneralSidebar {..._props} />;
|
||||
})
|
||||
.exhaustive();
|
||||
};
|
||||
|
||||
export default Sidebar;
|
22
src/Components/Excalidraw/Sidebar/Base.tsx
Normal file
22
src/Components/Excalidraw/Sidebar/Base.tsx
Normal file
@ -0,0 +1,22 @@
|
||||
import { SidebarProvider } from '@/Components/Utilities';
|
||||
import { FC } from 'react';
|
||||
import { z } from 'zod';
|
||||
import type { ReactNode } from 'react';
|
||||
|
||||
export const SidebarBasePropsSchema = z.object({
|
||||
onClose: z.function().returns(z.void()),
|
||||
});
|
||||
|
||||
export type SidebarBaseProps = z.infer<typeof SidebarBasePropsSchema> & {
|
||||
children?: ReactNode;
|
||||
};
|
||||
|
||||
const SidebarProviderBase: FC<SidebarBaseProps> = (props) => {
|
||||
return (
|
||||
<SidebarProvider dockable={true} onClose={props.onClose}>
|
||||
{props.children}
|
||||
</SidebarProvider>
|
||||
);
|
||||
};
|
||||
|
||||
export default SidebarProviderBase;
|
23
src/Components/Excalidraw/Sidebar/Collaboration.tsx
Normal file
23
src/Components/Excalidraw/Sidebar/Collaboration.tsx
Normal file
@ -0,0 +1,23 @@
|
||||
import { FC } from 'react';
|
||||
import { Button, SidebarHeader } from '@/Components/Utilities';
|
||||
import { z } from 'zod';
|
||||
import SidebarProviderBase, { SidebarBasePropsSchema } from './Base';
|
||||
|
||||
export type CollaborationSidebarProps = z.infer<
|
||||
typeof CollaborationSidebarPropsSchema
|
||||
>;
|
||||
|
||||
export const CollaborationSidebarPropsSchema = z
|
||||
.object({})
|
||||
.merge(SidebarBasePropsSchema);
|
||||
|
||||
const CollaborationSidebar: FC<CollaborationSidebarProps> = (props) => {
|
||||
return (
|
||||
<SidebarProviderBase onClose={props.onClose}>
|
||||
<SidebarHeader>Collaboration Settings</SidebarHeader>
|
||||
<Button>Button</Button>
|
||||
</SidebarProviderBase>
|
||||
);
|
||||
};
|
||||
|
||||
export default CollaborationSidebar;
|
21
src/Components/Excalidraw/Sidebar/General.tsx
Normal file
21
src/Components/Excalidraw/Sidebar/General.tsx
Normal file
@ -0,0 +1,21 @@
|
||||
import { FC } from 'react';
|
||||
import { Button, SidebarHeader } from '@/Components/Utilities';
|
||||
import { z } from 'zod';
|
||||
import SidebarProviderBase, { SidebarBasePropsSchema } from './Base';
|
||||
|
||||
export type GeneralSidebarProps = z.infer<typeof GeneralSidebarPropsSchema>;
|
||||
|
||||
export const GeneralSidebarPropsSchema = z
|
||||
.object({})
|
||||
.merge(SidebarBasePropsSchema);
|
||||
|
||||
const GeneralSidebar: FC<GeneralSidebarProps> = (props) => {
|
||||
return (
|
||||
<SidebarProviderBase onClose={props.onClose}>
|
||||
<SidebarHeader>General Settings</SidebarHeader>
|
||||
<Button>Button</Button>
|
||||
</SidebarProviderBase>
|
||||
);
|
||||
};
|
||||
|
||||
export default GeneralSidebar;
|
16
src/Components/Utilities.tsx
Normal file
16
src/Components/Utilities.tsx
Normal file
@ -0,0 +1,16 @@
|
||||
import styled from 'styled-components';
|
||||
import {
|
||||
Button as ButtonBase,
|
||||
ToggleButtonGroup as ToggleButtonGroupBase,
|
||||
ToggleButton as ToggleButtonBase,
|
||||
} from '@mui/material';
|
||||
import { Sidebar } from '@excalidraw/excalidraw';
|
||||
|
||||
export const SidebarProvider = styled(Sidebar)``;
|
||||
export const SidebarHeader = styled(Sidebar.Header)``;
|
||||
|
||||
export const Button = styled(ButtonBase)``;
|
||||
|
||||
export const ToggleButtonGroup = styled(ToggleButtonGroupBase)``;
|
||||
|
||||
export const ToggleButton = styled(ToggleButtonBase)``;
|
198
src/assets/licenses.json
Normal file
198
src/assets/licenses.json
Normal file
@ -0,0 +1,198 @@
|
||||
[
|
||||
{
|
||||
"name": "@excalidraw/excalidraw",
|
||||
"licenseType": "MIT",
|
||||
"author": "n/a",
|
||||
"link": "https://github.com/excalidraw/excalidraw",
|
||||
"installedFrom": "https://registry.npmjs.org/@excalidraw/excalidraw/-/excalidraw-0.15.2.tgz"
|
||||
},
|
||||
{
|
||||
"name": "@fontsource/roboto",
|
||||
"licenseType": "Apache-2.0",
|
||||
"author": "Google Inc.",
|
||||
"link": "git+https://github.com/fontsource/font-files.git",
|
||||
"installedFrom": "https://registry.npmjs.org/@fontsource/roboto/-/roboto-5.0.5.tgz"
|
||||
},
|
||||
{
|
||||
"name": "@mui/icons-material",
|
||||
"licenseType": "MIT",
|
||||
"author": "MUI Team",
|
||||
"link": "git+https://github.com/mui/material-ui.git",
|
||||
"installedFrom": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.14.1.tgz"
|
||||
},
|
||||
{
|
||||
"name": "@mui/material",
|
||||
"licenseType": "MIT",
|
||||
"author": "MUI Team",
|
||||
"link": "git+https://github.com/mui/material-ui.git",
|
||||
"installedFrom": "https://registry.npmjs.org/@mui/material/-/material-5.14.1.tgz"
|
||||
},
|
||||
{
|
||||
"name": "@mui/styled-engine-sc",
|
||||
"licenseType": "MIT",
|
||||
"author": "MUI Team",
|
||||
"link": "git+https://github.com/mui/material-ui.git",
|
||||
"installedFrom": "https://registry.npmjs.org/@mui/styled-engine-sc/-/styled-engine-sc-5.12.0.tgz"
|
||||
},
|
||||
{
|
||||
"name": "jotai",
|
||||
"licenseType": "MIT",
|
||||
"author": "Daishi Kato",
|
||||
"link": "git+https://github.com/pmndrs/jotai.git",
|
||||
"installedFrom": "https://registry.npmjs.org/jotai/-/jotai-2.2.2.tgz"
|
||||
},
|
||||
{
|
||||
"name": "react",
|
||||
"licenseType": "MIT",
|
||||
"author": "n/a",
|
||||
"link": "git+https://github.com/facebook/react.git",
|
||||
"installedFrom": "https://registry.npmjs.org/react/-/react-18.2.0.tgz"
|
||||
},
|
||||
{
|
||||
"name": "react-dom",
|
||||
"licenseType": "MIT",
|
||||
"author": "n/a",
|
||||
"link": "git+https://github.com/facebook/react.git",
|
||||
"installedFrom": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz"
|
||||
},
|
||||
{
|
||||
"name": "styled-components",
|
||||
"licenseType": "MIT",
|
||||
"author": "Glen Maddern",
|
||||
"link": "git+https://github.com/styled-components/styled-components.git",
|
||||
"installedFrom": "https://registry.npmjs.org/styled-components/-/styled-components-6.0.4.tgz"
|
||||
},
|
||||
{
|
||||
"name": "ts-pattern",
|
||||
"licenseType": "MIT",
|
||||
"author": "Gabriel Vergnaud",
|
||||
"link": "git+ssh://git@github.com/gvergnaud/ts-pattern.git",
|
||||
"installedFrom": "https://registry.npmjs.org/ts-pattern/-/ts-pattern-5.0.4.tgz"
|
||||
},
|
||||
{
|
||||
"name": "zod",
|
||||
"licenseType": "MIT",
|
||||
"author": "Colin McDonnell <colin@colinhacks.com>",
|
||||
"link": "git+https://github.com/colinhacks/zod.git",
|
||||
"installedFrom": "https://registry.npmjs.org/zod/-/zod-3.21.4.tgz"
|
||||
},
|
||||
{
|
||||
"name": "@types/react",
|
||||
"licenseType": "MIT",
|
||||
"author": "n/a",
|
||||
"link": "https://github.com/DefinitelyTyped/DefinitelyTyped.git",
|
||||
"installedFrom": "https://registry.npmjs.org/@types/react/-/react-18.2.14.tgz"
|
||||
},
|
||||
{
|
||||
"name": "@types/react-dom",
|
||||
"licenseType": "MIT",
|
||||
"author": "n/a",
|
||||
"link": "https://github.com/DefinitelyTyped/DefinitelyTyped.git",
|
||||
"installedFrom": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.6.tgz"
|
||||
},
|
||||
{
|
||||
"name": "@typescript-eslint/eslint-plugin",
|
||||
"licenseType": "MIT",
|
||||
"author": "n/a",
|
||||
"link": "git+https://github.com/typescript-eslint/typescript-eslint.git",
|
||||
"installedFrom": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.61.0.tgz"
|
||||
},
|
||||
{
|
||||
"name": "@typescript-eslint/parser",
|
||||
"licenseType": "BSD-2-Clause",
|
||||
"author": "n/a",
|
||||
"link": "git+https://github.com/typescript-eslint/typescript-eslint.git",
|
||||
"installedFrom": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.61.0.tgz"
|
||||
},
|
||||
{
|
||||
"name": "@vitejs/plugin-react-swc",
|
||||
"licenseType": "MIT",
|
||||
"author": "Arnaud Barré (https://github.com/ArnaudBarre)",
|
||||
"link": "git+https://github.com/vitejs/vite-plugin-react-swc.git",
|
||||
"installedFrom": "https://registry.npmjs.org/@vitejs/plugin-react-swc/-/plugin-react-swc-3.3.2.tgz"
|
||||
},
|
||||
{
|
||||
"name": "eslint",
|
||||
"licenseType": "MIT",
|
||||
"author": "Nicholas C. Zakas <nicholas+npm@nczconsulting.com>",
|
||||
"link": "git+https://github.com/eslint/eslint.git",
|
||||
"installedFrom": "https://registry.npmjs.org/eslint/-/eslint-8.44.0.tgz"
|
||||
},
|
||||
{
|
||||
"name": "eslint-plugin-react-hooks",
|
||||
"licenseType": "MIT",
|
||||
"author": "n/a",
|
||||
"link": "git+https://github.com/facebook/react.git",
|
||||
"installedFrom": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz"
|
||||
},
|
||||
{
|
||||
"name": "eslint-plugin-react-refresh",
|
||||
"licenseType": "MIT",
|
||||
"author": "Arnaud Barré (https://github.com/ArnaudBarre)",
|
||||
"link": "git+https://github.com/ArnaudBarre/eslint-plugin-react-refresh.git",
|
||||
"installedFrom": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.1.tgz"
|
||||
},
|
||||
{
|
||||
"name": "fs-extra",
|
||||
"licenseType": "MIT",
|
||||
"author": "JP Richardson <jprichardson@gmail.com>",
|
||||
"link": "git+https://github.com/jprichardson/node-fs-extra.git",
|
||||
"installedFrom": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.1.1.tgz"
|
||||
},
|
||||
{
|
||||
"name": "husky",
|
||||
"licenseType": "MIT",
|
||||
"author": "Typicode <typicode@gmail.com>",
|
||||
"link": "git+https://github.com/typicode/husky.git",
|
||||
"installedFrom": "https://registry.npmjs.org/husky/-/husky-8.0.0.tgz"
|
||||
},
|
||||
{
|
||||
"name": "license-report",
|
||||
"licenseType": "MIT",
|
||||
"author": "Yaniv Kessler",
|
||||
"link": "git+https://github.com/ironSource/license-report.git",
|
||||
"installedFrom": "https://registry.npmjs.org/license-report/-/license-report-6.4.0.tgz"
|
||||
},
|
||||
{
|
||||
"name": "lint-staged",
|
||||
"licenseType": "MIT",
|
||||
"author": "Andrey Okonetchnikov <andrey@okonet.ru>",
|
||||
"link": "git+https://github.com/okonet/lint-staged.git",
|
||||
"installedFrom": "https://registry.npmjs.org/lint-staged/-/lint-staged-13.2.3.tgz"
|
||||
},
|
||||
{
|
||||
"name": "npm-run-all",
|
||||
"licenseType": "MIT",
|
||||
"author": "Toru Nagashima",
|
||||
"link": "git+https://github.com/mysticatea/npm-run-all.git",
|
||||
"installedFrom": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz"
|
||||
},
|
||||
{
|
||||
"name": "prettier",
|
||||
"licenseType": "MIT",
|
||||
"author": "James Long",
|
||||
"link": "git+https://github.com/prettier/prettier.git",
|
||||
"installedFrom": "https://registry.npmjs.org/prettier/-/prettier-3.0.0.tgz"
|
||||
},
|
||||
{
|
||||
"name": "typescript",
|
||||
"licenseType": "Apache-2.0",
|
||||
"author": "Microsoft Corp.",
|
||||
"link": "git+https://github.com/Microsoft/TypeScript.git",
|
||||
"installedFrom": "https://registry.npmjs.org/typescript/-/typescript-5.0.2.tgz"
|
||||
},
|
||||
{
|
||||
"name": "vite",
|
||||
"licenseType": "MIT",
|
||||
"author": "Evan You",
|
||||
"link": "git+https://github.com/vitejs/vite.git",
|
||||
"installedFrom": "https://registry.npmjs.org/vite/-/vite-4.4.0.tgz"
|
||||
},
|
||||
{
|
||||
"name": "vite-tsconfig-paths",
|
||||
"licenseType": "MIT",
|
||||
"author": "aleclarson",
|
||||
"link": "git+https://github.com/aleclarson/vite-tsconfig-paths.git",
|
||||
"installedFrom": "https://registry.npmjs.org/vite-tsconfig-paths/-/vite-tsconfig-paths-4.2.0.tgz"
|
||||
}
|
||||
]
|
5
src/index.css
Normal file
5
src/index.css
Normal file
@ -0,0 +1,5 @@
|
||||
body {
|
||||
margin: 0;
|
||||
display: flex;
|
||||
place-items: center;
|
||||
}
|
@ -1,11 +1,7 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom/client';
|
||||
import App from './App.tsx';
|
||||
|
||||
import '@fontsource/roboto/300.css';
|
||||
import '@fontsource/roboto/400.css';
|
||||
import '@fontsource/roboto/500.css';
|
||||
import '@fontsource/roboto/700.css';
|
||||
import './index.css';
|
||||
|
||||
ReactDOM.createRoot(document.getElementById('root')!).render(
|
||||
<React.StrictMode>
|
||||
|
13
src/types/license.ts
Normal file
13
src/types/license.ts
Normal file
@ -0,0 +1,13 @@
|
||||
import { z } from 'zod';
|
||||
|
||||
export const License = z.array(
|
||||
z.object({
|
||||
name: z.string(),
|
||||
licenseType: z.string(),
|
||||
author: z.string(),
|
||||
link: z.string().url().optional(),
|
||||
installedFrom: z.string().url().optional(),
|
||||
})
|
||||
);
|
||||
|
||||
export type License = z.infer<typeof License>;
|
@ -5,7 +5,6 @@
|
||||
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
||||
"module": "ESNext",
|
||||
"skipLibCheck": true,
|
||||
|
||||
/* Bundler mode */
|
||||
"moduleResolution": "bundler",
|
||||
"allowImportingTsExtensions": true,
|
||||
@ -13,13 +12,22 @@
|
||||
"isolatedModules": true,
|
||||
"noEmit": true,
|
||||
"jsx": "react-jsx",
|
||||
|
||||
/* Linting */
|
||||
"strict": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"noFallthroughCasesInSwitch": true
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
/* Aliases */
|
||||
"baseUrl": "./",
|
||||
"paths": {
|
||||
"@/*": ["src/*"],
|
||||
"@mui/styled-engine": ["./node_modules/@mui/styled-engine-sc"]
|
||||
}
|
||||
},
|
||||
"include": ["src"],
|
||||
"references": [{ "path": "./tsconfig.node.json" }]
|
||||
"references": [
|
||||
{
|
||||
"path": "./tsconfig.node.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -1,7 +1,22 @@
|
||||
import { defineConfig } from 'vite';
|
||||
import react from '@vitejs/plugin-react-swc';
|
||||
import tsconfigPaths from 'vite-tsconfig-paths';
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [react()],
|
||||
resolve: {
|
||||
alias: {
|
||||
'@mui/styled-engine': '@mui/styled-engine-sc',
|
||||
},
|
||||
},
|
||||
optimizeDeps: {
|
||||
include: [
|
||||
'react',
|
||||
'react-dom',
|
||||
'@mui/material',
|
||||
'@excalidraw/excalidraw',
|
||||
'styled-components',
|
||||
],
|
||||
},
|
||||
plugins: [react(), tsconfigPaths()],
|
||||
});
|
||||
|
Reference in New Issue
Block a user