Many things

This commit is contained in:
Max 2024-11-24 20:14:55 +03:00
parent 7c38c6ca9b
commit 66178664f3
19 changed files with 731 additions and 71 deletions

135
enshi/package-lock.json generated
View File

@ -10,7 +10,9 @@
"dependencies": {
"@radix-ui/react-dialog": "^1.1.1",
"@radix-ui/react-form": "^0.1.0",
"@radix-ui/react-icons": "^1.3.2",
"@radix-ui/react-navigation-menu": "^1.2.1",
"@radix-ui/react-toast": "^1.2.2",
"@radix-ui/react-tooltip": "^1.1.2",
"@radix-ui/themes": "^3.1.3",
"@tanstack/react-query": "^5.55.0",
@ -1622,6 +1624,15 @@
}
}
},
"node_modules/@radix-ui/react-icons": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/@radix-ui/react-icons/-/react-icons-1.3.2.tgz",
"integrity": "sha512-fyQIhGDhzfc9pK2kH6Pl9c4BDJGfMkPqkyIgYDthyNYoNg3wVhoJMMh19WS4Up/1KMPFVpNsT2q3WmXn2N1m6g==",
"license": "MIT",
"peerDependencies": {
"react": "^16.x || ^17.x || ^18.x || ^19.0.0 || ^19.0.0-rc"
}
},
"node_modules/@radix-ui/react-id": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.0.tgz",
@ -2216,6 +2227,130 @@
}
}
},
"node_modules/@radix-ui/react-toast": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/@radix-ui/react-toast/-/react-toast-1.2.2.tgz",
"integrity": "sha512-Z6pqSzmAP/bFJoqMAston4eSNa+ud44NSZTiZUmUen+IOZ5nBY8kzuU5WDBVyFXPtcW6yUalOHsxM/BP6Sv8ww==",
"license": "MIT",
"dependencies": {
"@radix-ui/primitive": "1.1.0",
"@radix-ui/react-collection": "1.1.0",
"@radix-ui/react-compose-refs": "1.1.0",
"@radix-ui/react-context": "1.1.1",
"@radix-ui/react-dismissable-layer": "1.1.1",
"@radix-ui/react-portal": "1.1.2",
"@radix-ui/react-presence": "1.1.1",
"@radix-ui/react-primitive": "2.0.0",
"@radix-ui/react-use-callback-ref": "1.1.0",
"@radix-ui/react-use-controllable-state": "1.1.0",
"@radix-ui/react-use-layout-effect": "1.1.0",
"@radix-ui/react-visually-hidden": "1.1.0"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
},
"@types/react-dom": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-toast/node_modules/@radix-ui/react-context": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.1.tgz",
"integrity": "sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==",
"license": "MIT",
"peerDependencies": {
"@types/react": "*",
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-toast/node_modules/@radix-ui/react-dismissable-layer": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.1.tgz",
"integrity": "sha512-QSxg29lfr/xcev6kSz7MAlmDnzbP1eI/Dwn3Tp1ip0KT5CUELsxkekFEMVBEoykI3oV39hKT4TKZzBNMbcTZYQ==",
"license": "MIT",
"dependencies": {
"@radix-ui/primitive": "1.1.0",
"@radix-ui/react-compose-refs": "1.1.0",
"@radix-ui/react-primitive": "2.0.0",
"@radix-ui/react-use-callback-ref": "1.1.0",
"@radix-ui/react-use-escape-keydown": "1.1.0"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
},
"@types/react-dom": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-toast/node_modules/@radix-ui/react-portal": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.2.tgz",
"integrity": "sha512-WeDYLGPxJb/5EGBoedyJbT0MpoULmwnIPMJMSldkuiMsBAv7N1cRdsTWZWht9vpPOiN3qyiGAtbK2is47/uMFg==",
"license": "MIT",
"dependencies": {
"@radix-ui/react-primitive": "2.0.0",
"@radix-ui/react-use-layout-effect": "1.1.0"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
},
"@types/react-dom": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-toast/node_modules/@radix-ui/react-presence": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.1.tgz",
"integrity": "sha512-IeFXVi4YS1K0wVZzXNrbaaUvIJ3qdY+/Ih4eHFhWA9SwGR9UDX7Ck8abvL57C4cv3wwMvUE0OG69Qc3NCcTe/A==",
"license": "MIT",
"dependencies": {
"@radix-ui/react-compose-refs": "1.1.0",
"@radix-ui/react-use-layout-effect": "1.1.0"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
},
"@types/react-dom": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-toggle": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@radix-ui/react-toggle/-/react-toggle-1.1.0.tgz",

View File

@ -12,7 +12,9 @@
"dependencies": {
"@radix-ui/react-dialog": "^1.1.1",
"@radix-ui/react-form": "^0.1.0",
"@radix-ui/react-icons": "^1.3.2",
"@radix-ui/react-navigation-menu": "^1.2.1",
"@radix-ui/react-toast": "^1.2.2",
"@radix-ui/react-tooltip": "^1.1.2",
"@radix-ui/themes": "^3.1.3",
"@tanstack/react-query": "^5.55.0",

11
enshi/src/@types/index.d.ts vendored Normal file
View File

@ -0,0 +1,11 @@
type TToast = {
title: string;
description?: string;
action?: React.Component;
};
type TExistingToast = TToast & {
id: number;
resetFunc: (arg0: boolean) => void;
open: boolean;
};

View File

@ -1,11 +1,12 @@
import { Theme } from "@radix-ui/themes";
import "@radix-ui/themes/styles.css";
import { QueryClientProvider } from "@tanstack/react-query";
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
import "axios";
import { createBrowserRouter, RouterProvider } from "react-router-dom";
import queryClient from "./api/QueryClient/QueryClient";
import "./App.css";
import ToastProvider from "./Components/ToastProvider/ToastProvider";
import { routes } from "./routes/routes";
const router = createBrowserRouter(routes);
@ -13,11 +14,13 @@ const router = createBrowserRouter(routes);
export default function App() {
return (
<Theme className="h-fit" accentColor="indigo" grayColor="slate">
<QueryClientProvider client={queryClient}>
<RouterProvider router={router} />
{/* <ThemePanel /> */}
<ReactQueryDevtools />
</QueryClientProvider>
<ToastProvider>
<QueryClientProvider client={queryClient}>
<RouterProvider router={router} />
{/* <ThemePanel /> */}
<ReactQueryDevtools />
</QueryClientProvider>
</ToastProvider>
</Theme>
);
}

View File

@ -1,4 +1,50 @@
import { atom } from "jotai";
import { TUser } from "../types/UserType";
import { atomWithStorage } from "jotai/utils";
import { TUser } from "../@types/UserType";
export const userAtom = atom<TUser>()
export const userAtom = atom<TUser>();
export const postCreationAtom = atom<string>();
export const postCreationTitleAtom = atom<string>();
type TPostData = {
title: string;
content: string;
};
export const storagePostAtom = atomWithStorage<TPostData>(
"draft-post",
{ title: "", content: "" },
{
getItem: (key) => sessionStorage.getItem(key) as any,
setItem: (key, value) => sessionStorage.setItem(key, value as any),
removeItem: (key) => sessionStorage.removeItem(key),
},
{ getOnInit: true }
);
export const toastAtom = atom<TExistingToast[]>([]);
export const setToastAtom = atom(null, (get, set, value: TToast) => {
let maxToastId = Math.max(...get(toastAtom).map((toast) => toast.id));
maxToastId = maxToastId >= 0 ? maxToastId : 1;
let atomValueWithNewToast = get(toastAtom);
atomValueWithNewToast = [
...atomValueWithNewToast,
{
id: maxToastId + 1,
resetFunc: (_) => {
let currentToasts = get(toastAtom);
let afterRemoval = currentToasts.filter(
(toast) => toast.id != maxToastId + 1
);
set(toastAtom, afterRemoval);
},
title: value.title,
action: value.action,
description: value.description,
open: true,
},
];
set(toastAtom, atomValueWithNewToast);
});

View File

@ -11,13 +11,13 @@ import ReactQuill from "react-quill";
type TEditor = {
readOnly?: boolean;
defaultValue?: string | Delta;
onChange: (d: string) => void;
onChange?: (d: string) => void;
onSelectionChange?: any;
};
const modules = {
toolbar: [
[{ header: [1, 2, 3, false] }],
[{ header: [1, 2, 3, 4, 5, false] }],
["bold", "italic", "underline", "strike", "blockquote", "span-wrapper"],
[
{ list: "ordered" },
@ -28,10 +28,7 @@ const modules = {
["link", "image"],
["clean"],
[{ align: [] }],
],
clipboard: {
matchVisual: true,
},
]
};
/**
@ -53,31 +50,12 @@ const Editor = forwardRef((props: TEditor) => {
};
}, [editor.current]);
useEffect(() => {
let Inline = Quill.import('attributors/style/size');
console.log(Inline);
// //@ts-ignore
// class BoldBlot extends Inline {}
// //@ts-ignore
// BoldBlot.blotName = 'bold1';
// //@ts-ignore
// BoldBlot.tagName = 'strong';
// console.log(BoldBlot, true);
Quill.register(Inline as any, true);
return () => {
}
}, [])
const changeHandler = (val: string, _changeDelta: Delta, _source: Sources, _editor: ReactQuill.UnprivilegedEditor) => {
console.log(val);
console.log(JSON.stringify(quill?.getContents().ops, null, 2))
let fullDelta = quill?.getContents()
props.onChange(val || "")
if (props.onChange) props.onChange(val || "")
setValue(fullDelta || new Delta())
}
@ -87,8 +65,6 @@ const Editor = forwardRef((props: TEditor) => {
value={value}
ref={editor}
modules={modules}
formats={['bold1']}
onChange={changeHandler}

View File

@ -4,14 +4,12 @@ import SearchField from "./SearchField/SearchField";
export default function NavBar() {
return (
// <Container size={"4"}>
<nav className="flex justify-center pt-2 pb-2 ml-4 mr-4">
<CustomNavigationMenu />
<nav className="flex justify-center pt-2 pb-2 ml-4 mr-4 flex-[1] max-h-fit">
<CustomNavigationMenu />
<SearchField />
<SearchField />
<RightButtonBar />
</nav>
// </Container>
<RightButtonBar />
</nav>
);
}

View File

@ -0,0 +1,44 @@
import { Cross1Icon } from "@radix-ui/react-icons";
import * as Toast from "@radix-ui/react-toast";
import { Card, Text } from "@radix-ui/themes";
import { useAtomValue } from "jotai";
import React from "react";
import { toastAtom } from "../../AtomStore/AtomStore";
export default function ToastProvider(props: React.PropsWithChildren) {
const toastsToRender = useAtomValue(toastAtom);
return (
<Toast.Provider swipeDirection="right">
{props.children}
{toastsToRender.map((toast) => {
return (
<Toast.Root
key={toast.id}
className="mt-2 mr-2 data-[state=open]:animate-slideFromRight data-[state=closed]:animate-fadeOut"
open={toast.open}
onOpenChange={toast.resetFunc}
color={"red"}
>
<Card className="relative w-60">
<Toast.Title>
<Text size={"4"} weight={"bold"}>
{toast.title}
</Text>
</Toast.Title>
<Toast.Description className="overflow-hidden w-50 text-ellipsis">
<Text className="text-pretty line-clamp-2">{toast.description}</Text>
</Toast.Description>
<Toast.Close className="absolute top-2 right-2">
<Cross1Icon color="red" />
</Toast.Close>
</Card>
</Toast.Root>
);
})}
<Toast.Viewport className="fixed right-0 bottom-2" />
</Toast.Provider>
);
}

View File

@ -10,7 +10,7 @@ export default function AuthPageWrapper(props: React.PropsWithChildren) {
const navigate = useNavigate();
if (!user) {
navigate("/login")
navigate("/login");
return (
<Container size={"4"} className="mt-4">
<Text size={"7"}>{t("errors.unauthorized")}</Text>

View File

@ -1,4 +1,4 @@
import { Spinner } from "@radix-ui/themes";
import { Box, Flex, Spinner } from "@radix-ui/themes";
import { useQuery } from "@tanstack/react-query";
import { useSetAtom } from "jotai";
import { Outlet } from "react-router-dom";
@ -52,10 +52,14 @@ export default function MainPage() {
<Spinner size={"3"} />
</div>
) : (
<>
<NavBar />
<Outlet />
</>
<Flex direction={"column"} className="min-h-[100vh] max-h-[100vh]">
<Box flexGrow={"1"} className="flex-[1]">
<NavBar />
</Box>
<Box flexGrow={"100"} className="flex flex-col overflow-auto">
<Outlet />
</Box>
</Flex>
)}
</>
);

View File

@ -1,26 +1,42 @@
import { Container } from "@radix-ui/themes";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import ArticleViewer from "../../Components/ArticleViewer/ArticleViewer";
import { Box, Container, Flex } from "@radix-ui/themes";
import { useSetAtom } from "jotai";
import {
postCreationAtom,
postCreationTitleAtom
} from "../../AtomStore/AtomStore";
import Editor from "../../Components/Editor/Editor";
import SubmitPostButton from "./SubmitPostButton/SubmitPostButton";
export default function PostCreatorPage() {
const [userInput, setUserInput] = useState("");
const { t } = useTranslation();
const setTitleValue = useSetAtom(postCreationTitleAtom);
const setContentValue = useSetAtom(postCreationAtom);
return (
<>
<Container className="mt-10">
<input
placeholder={"Post title"}
className="mb-2 border-0 border-b-[1px]
outline-none w-full border-b-gray-400
text-[60px] pl-4 pr-4 font-times"
></input>
<Editor onChange={setUserInput} />
<ArticleViewer htmlToParse={userInput} />
</Container>
<Box className="flex flex-col flex-1">
<Flex gap={"4"} direction={"column"} className="flex-[1]">
<Container className="flex-[1]">
<input
placeholder={"Post title"}
className="mb-2 border-0 border-b-[1px]
outline-none w-full border-b-gray-400
text-[60px] pl-4 pr-4 font-times"
onChange={(e) => {
setTitleValue(e.target.value);
}}
/>
</Container>
<Container className="overflow-y-auto flex-grow-[100]">
<Editor onChange={setContentValue} />
</Container>
<Box className="flex justify-center flex-[1] mb-4">
<SubmitPostButton className="text-2xl rounded-full w-52" />
</Box>
</Flex>
</Box>
</>
);
}

View File

@ -0,0 +1,57 @@
import { Button } from "@radix-ui/themes";
import { useMutation } from "@tanstack/react-query";
import { useAtomValue } from "jotai";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { useNavigate } from "react-router-dom";
import { axiosLocalhost } from "../../../api/axios/axios";
import {
postCreationAtom,
postCreationTitleAtom,
} from "../../../AtomStore/AtomStore";
type TSubmitPostButton = {
className: string;
};
export default function SubmitPostButton(props: TSubmitPostButton) {
const { t } = useTranslation();
const contentValue = useAtomValue(postCreationAtom);
const titleValue = useAtomValue(postCreationTitleAtom);
const navigate = useNavigate();
const [isDisabled, setIsDisabled] = useState(false);
const postMutation = useMutation({
mutationFn: async () => {
axiosLocalhost.post("/posts", {
title: titleValue,
content: contentValue,
});
},
onMutate: () => {
setIsDisabled(true);
},
onError: () => {
setIsDisabled(false);
},
onSuccess: () => {
navigate("/");
},
});
return (
<Button
onClick={() => {
postMutation.mutate();
}}
className={props.className}
variant="soft"
size={"4"}
disabled={isDisabled}
>
{t("submit")}
</Button>
);
}

View File

@ -0,0 +1,7 @@
import { useSetAtom } from "jotai";
import { setToastAtom } from "../AtomStore/AtomStore";
export default function useToast() {
const createToast = useSetAtom(setToastAtom);
return createToast;
}

View File

@ -4,7 +4,7 @@ import './index.css'
import './locale/i18n.ts'
import i18n from './locale/i18n.ts'
i18n.changeLanguage("ru")
i18n.changeLanguage(navigator.language)
createRoot(document.getElementById('root')!).render(
<App />

View File

@ -21,12 +21,13 @@ export const routes = createRoutesFromElements(
<>
<Route path="/" errorElement={<ErrorBoundary />} element={<MainPage />}>
<Route index element={<Text size={"5"}>Cringer path</Text>} />
<Route
path="/a?/c"
element={
<Text weight={"regular"}>Cringer path, but this a</Text>
}
></Route>
/>
<Route
path="/create"

View File

@ -13,8 +13,26 @@ export default {
animation: {
appear: "appear 0.25s",
widthOut: "widthOut cubic-bezier(0.4, 0, 0.6, 1) 0.4s",
slideFromRight: "slideFromRight cubic-bezier(0.4, 0, 0.6, 1) 0.2s",
fadeOut: "fadeOut 0.2s ease-in",
},
keyframes: {
fadeOut: {
from: {
opacity: "1",
},
to: {
opacity: "0",
}
},
slideFromRight: {
"0%": {
transform: "translateX(110%)"
},
"100%": {
transform: "translateX(0%)"
}
},
appear: {
"100%": { opacity: "1" },
},

341
package-lock.json generated
View File

@ -6,9 +6,114 @@
"": {
"dependencies": {
"@radix-ui/react-icons": "^1.3.2",
"@radix-ui/react-toast": "^1.2.2",
"interweave": "^13.1.0"
}
},
"node_modules/@radix-ui/primitive": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.0.tgz",
"integrity": "sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA==",
"license": "MIT"
},
"node_modules/@radix-ui/react-collection": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.0.tgz",
"integrity": "sha512-GZsZslMJEyo1VKm5L1ZJY8tGDxZNPAoUeQUIbKeJfoi7Q4kmig5AsgLMYYuyYbfjd8fBmFORAIwYAkXMnXZgZw==",
"license": "MIT",
"dependencies": {
"@radix-ui/react-compose-refs": "1.1.0",
"@radix-ui/react-context": "1.1.0",
"@radix-ui/react-primitive": "2.0.0",
"@radix-ui/react-slot": "1.1.0"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
},
"@types/react-dom": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-collection/node_modules/@radix-ui/react-context": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.0.tgz",
"integrity": "sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A==",
"license": "MIT",
"peerDependencies": {
"@types/react": "*",
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-compose-refs": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.0.tgz",
"integrity": "sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw==",
"license": "MIT",
"peerDependencies": {
"@types/react": "*",
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-context": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.1.tgz",
"integrity": "sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==",
"license": "MIT",
"peerDependencies": {
"@types/react": "*",
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-dismissable-layer": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.1.tgz",
"integrity": "sha512-QSxg29lfr/xcev6kSz7MAlmDnzbP1eI/Dwn3Tp1ip0KT5CUELsxkekFEMVBEoykI3oV39hKT4TKZzBNMbcTZYQ==",
"license": "MIT",
"dependencies": {
"@radix-ui/primitive": "1.1.0",
"@radix-ui/react-compose-refs": "1.1.0",
"@radix-ui/react-primitive": "2.0.0",
"@radix-ui/react-use-callback-ref": "1.1.0",
"@radix-ui/react-use-escape-keydown": "1.1.0"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
},
"@types/react-dom": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-icons": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/@radix-ui/react-icons/-/react-icons-1.3.2.tgz",
@ -18,6 +123,218 @@
"react": "^16.x || ^17.x || ^18.x || ^19.0.0 || ^19.0.0-rc"
}
},
"node_modules/@radix-ui/react-portal": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.2.tgz",
"integrity": "sha512-WeDYLGPxJb/5EGBoedyJbT0MpoULmwnIPMJMSldkuiMsBAv7N1cRdsTWZWht9vpPOiN3qyiGAtbK2is47/uMFg==",
"license": "MIT",
"dependencies": {
"@radix-ui/react-primitive": "2.0.0",
"@radix-ui/react-use-layout-effect": "1.1.0"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
},
"@types/react-dom": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-presence": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.1.tgz",
"integrity": "sha512-IeFXVi4YS1K0wVZzXNrbaaUvIJ3qdY+/Ih4eHFhWA9SwGR9UDX7Ck8abvL57C4cv3wwMvUE0OG69Qc3NCcTe/A==",
"license": "MIT",
"dependencies": {
"@radix-ui/react-compose-refs": "1.1.0",
"@radix-ui/react-use-layout-effect": "1.1.0"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
},
"@types/react-dom": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-primitive": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.0.tgz",
"integrity": "sha512-ZSpFm0/uHa8zTvKBDjLFWLo8dkr4MBsiDLz0g3gMUwqgLHz9rTaRRGYDgvZPtBJgYCBKXkS9fzmoySgr8CO6Cw==",
"license": "MIT",
"dependencies": {
"@radix-ui/react-slot": "1.1.0"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
},
"@types/react-dom": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-slot": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.0.tgz",
"integrity": "sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw==",
"license": "MIT",
"dependencies": {
"@radix-ui/react-compose-refs": "1.1.0"
},
"peerDependencies": {
"@types/react": "*",
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-toast": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/@radix-ui/react-toast/-/react-toast-1.2.2.tgz",
"integrity": "sha512-Z6pqSzmAP/bFJoqMAston4eSNa+ud44NSZTiZUmUen+IOZ5nBY8kzuU5WDBVyFXPtcW6yUalOHsxM/BP6Sv8ww==",
"license": "MIT",
"dependencies": {
"@radix-ui/primitive": "1.1.0",
"@radix-ui/react-collection": "1.1.0",
"@radix-ui/react-compose-refs": "1.1.0",
"@radix-ui/react-context": "1.1.1",
"@radix-ui/react-dismissable-layer": "1.1.1",
"@radix-ui/react-portal": "1.1.2",
"@radix-ui/react-presence": "1.1.1",
"@radix-ui/react-primitive": "2.0.0",
"@radix-ui/react-use-callback-ref": "1.1.0",
"@radix-ui/react-use-controllable-state": "1.1.0",
"@radix-ui/react-use-layout-effect": "1.1.0",
"@radix-ui/react-visually-hidden": "1.1.0"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
},
"@types/react-dom": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-use-callback-ref": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.0.tgz",
"integrity": "sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==",
"license": "MIT",
"peerDependencies": {
"@types/react": "*",
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-use-controllable-state": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.1.0.tgz",
"integrity": "sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==",
"license": "MIT",
"dependencies": {
"@radix-ui/react-use-callback-ref": "1.1.0"
},
"peerDependencies": {
"@types/react": "*",
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-use-escape-keydown": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.0.tgz",
"integrity": "sha512-L7vwWlR1kTTQ3oh7g1O0CBF3YCyyTj8NmhLR+phShpyA50HCfBFKVJTpshm9PzLiKmehsrQzTYTpX9HvmC9rhw==",
"license": "MIT",
"dependencies": {
"@radix-ui/react-use-callback-ref": "1.1.0"
},
"peerDependencies": {
"@types/react": "*",
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-use-layout-effect": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.0.tgz",
"integrity": "sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==",
"license": "MIT",
"peerDependencies": {
"@types/react": "*",
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-visually-hidden": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.1.0.tgz",
"integrity": "sha512-N8MDZqtgCgG5S3aV60INAB475osJousYpZ4cTJ2cFbMpdHS5Y6loLTH8LPtkj2QN0x93J30HT/M3qJXM0+lyeQ==",
"license": "MIT",
"dependencies": {
"@radix-ui/react-primitive": "2.0.0"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
},
"@types/react-dom": {
"optional": true
}
}
},
"node_modules/escape-html": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
@ -72,6 +389,30 @@
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/react-dom": {
"version": "18.3.1",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz",
"integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==",
"license": "MIT",
"peer": true,
"dependencies": {
"loose-envify": "^1.1.0",
"scheduler": "^0.23.2"
},
"peerDependencies": {
"react": "^18.3.1"
}
},
"node_modules/scheduler": {
"version": "0.23.2",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz",
"integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==",
"license": "MIT",
"peer": true,
"dependencies": {
"loose-envify": "^1.1.0"
}
}
}
}

View File

@ -1,6 +1,7 @@
{
"dependencies": {
"@radix-ui/react-icons": "^1.3.2",
"@radix-ui/react-toast": "^1.2.2",
"interweave": "^13.1.0"
}
}