@intlayer/design-system 9.4.0-canary.0 → 9.4.1
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/README.md +2 -2
- package/dist/esm/api/index.mjs +3 -3
- package/dist/esm/api/useAuth/useOAuth2.mjs.map +1 -1
- package/dist/esm/api/useIntlayerAPI.mjs +1 -3
- package/dist/esm/api/useIntlayerAPI.mjs.map +1 -1
- package/dist/esm/components/Carousel/index.mjs +48 -30
- package/dist/esm/components/Carousel/index.mjs.map +1 -1
- package/dist/esm/components/ContentEditor/ContentEditorTextArea.mjs +1 -1
- package/dist/esm/components/DictionaryFieldEditor/ContentEditor.mjs +2 -2
- package/dist/esm/components/DictionaryFieldEditor/ContentEditorView/TextEditor.mjs +2 -2
- package/dist/esm/components/DictionaryFieldEditor/DictionaryCreationForm/DictionaryCreationForm.mjs +1 -1
- package/dist/esm/components/DictionaryFieldEditor/DictionaryDetails/DictionaryDetailsForm.mjs +6 -6
- package/dist/esm/components/DictionaryFieldEditor/DictionaryFieldEditor.mjs +1 -1
- package/dist/esm/components/DictionaryFieldEditor/NavigationView/NavigationViewNode.mjs +1 -1
- package/dist/esm/components/DictionaryFieldEditor/SaveForm/SaveForm.mjs +2 -2
- package/dist/esm/components/DictionaryFieldEditor/StructureView/StructureView.mjs +1 -1
- package/dist/esm/components/Navbar/MobileNavbar.mjs +24 -2
- package/dist/esm/components/Navbar/MobileNavbar.mjs.map +1 -1
- package/dist/esm/components/Pattern/GridDistortionPattern.mjs +1 -1
- package/dist/esm/components/RightDrawer/RightDrawer.mjs +29 -6
- package/dist/esm/components/RightDrawer/RightDrawer.mjs.map +1 -1
- package/dist/esm/components/RightDrawer/index.mjs +2 -2
- package/dist/esm/components/RightDrawer/useRightDrawer.mjs +37 -5
- package/dist/esm/components/RightDrawer/useRightDrawer.mjs.map +1 -1
- package/dist/esm/components/Tab/Tab.mjs +20 -3
- package/dist/esm/components/Tab/Tab.mjs.map +1 -1
- package/dist/esm/components/TechLogo/TechLogo.mjs +1 -0
- package/dist/esm/components/TechLogo/TechLogo.mjs.map +1 -1
- package/dist/esm/components/TechLogo/logos/Elysia.mjs +62 -0
- package/dist/esm/components/TechLogo/logos/Elysia.mjs.map +1 -0
- package/dist/esm/components/TechLogo/techLogos.mjs +3 -1
- package/dist/esm/components/TechLogo/techLogos.mjs.map +1 -1
- package/dist/esm/components/index.mjs +2 -2
- package/dist/esm/hooks/useScrollBlockage/index.mjs +9 -10
- package/dist/esm/hooks/useScrollBlockage/index.mjs.map +1 -1
- package/dist/esm/hooks/useScrollDetection.mjs +15 -2
- package/dist/esm/hooks/useScrollDetection.mjs.map +1 -1
- package/dist/esm/hooks/useScrollY.mjs +1 -1
- package/dist/esm/routes.mjs +3 -1
- package/dist/esm/routes.mjs.map +1 -1
- package/dist/esm/utils/index.mjs +1 -1
- package/dist/types/api/useIntlayerAPI.d.ts +12 -0
- package/dist/types/api/useIntlayerAPI.d.ts.map +1 -1
- package/dist/types/components/Carousel/index.d.ts.map +1 -1
- package/dist/types/components/Navbar/MobileNavbar.d.ts.map +1 -1
- package/dist/types/components/RightDrawer/RightDrawer.d.ts.map +1 -1
- package/dist/types/components/RightDrawer/index.d.ts +2 -2
- package/dist/types/components/RightDrawer/useRightDrawer.d.ts +34 -1
- package/dist/types/components/RightDrawer/useRightDrawer.d.ts.map +1 -1
- package/dist/types/components/Tab/Tab.d.ts.map +1 -1
- package/dist/types/components/TechLogo/TechLogo.d.ts.map +1 -1
- package/dist/types/components/TechLogo/logos/Elysia.d.ts +6 -0
- package/dist/types/components/TechLogo/logos/Elysia.d.ts.map +1 -0
- package/dist/types/components/TechLogo/techLogos.d.ts +3 -2
- package/dist/types/components/TechLogo/types.d.ts +1 -1
- package/dist/types/components/index.d.ts +2 -2
- package/dist/types/hooks/useScrollBlockage/index.d.ts.map +1 -1
- package/dist/types/hooks/useScrollDetection.d.ts.map +1 -1
- package/dist/types/routes.d.ts +3 -1
- package/dist/types/routes.d.ts.map +1 -1
- package/package.json +21 -21
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import { useTheme } from "../../providers/ThemeProvider.mjs";
|
|
4
3
|
import { cn } from "../../utils/cn.mjs";
|
|
4
|
+
import { useTheme } from "../../providers/ThemeProvider.mjs";
|
|
5
5
|
import { useEffect, useRef } from "react";
|
|
6
6
|
import { jsx } from "react/jsx-runtime";
|
|
7
7
|
|
|
@@ -9,8 +9,8 @@ import { useGetElementOrWindow } from "../../hooks/useGetElementOrWindow.mjs";
|
|
|
9
9
|
import { useScrollBlockage } from "../../hooks/useScrollBlockage/index.mjs";
|
|
10
10
|
import { MaxWidthSmoother } from "../MaxWidthSmoother/index.mjs";
|
|
11
11
|
import { isElementAtTopAndNotCovered } from "./isElementAtTopAndNotCovered.mjs";
|
|
12
|
-
import {
|
|
13
|
-
import { useEffect, useRef } from "react";
|
|
12
|
+
import { useIsRightDrawerOpen, useRightDrawerActions } from "./useRightDrawer.mjs";
|
|
13
|
+
import { useEffect, useRef, useState } from "react";
|
|
14
14
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
15
15
|
import { ChevronLeft, X } from "lucide-react";
|
|
16
16
|
import { useIntlayer } from "react-intlayer";
|
|
@@ -23,18 +23,41 @@ const RightDrawer = ({ title, identifier, children, header, footer, closeOnOutsi
|
|
|
23
23
|
const panelRef = useRef(null);
|
|
24
24
|
const childrenContainerRef = useRef(null);
|
|
25
25
|
const containerElement = useGetElementOrWindow(container);
|
|
26
|
-
const { open: openDrawer, close: closeDrawer
|
|
27
|
-
const storeIsOpen =
|
|
26
|
+
const { open: openDrawer, close: closeDrawer } = useRightDrawerActions();
|
|
27
|
+
const storeIsOpen = useIsRightDrawerOpen(identifier);
|
|
28
28
|
const isOpen = storeIsOpen;
|
|
29
|
+
/**
|
|
30
|
+
* A drawer mounted by its parent in the already-open state is inserted into
|
|
31
|
+
* the DOM at its final width, leaving the transition no previous value to
|
|
32
|
+
* start from: it pops instead of sliding. Painting the closed state for a
|
|
33
|
+
* frame first gives the transition its starting point.
|
|
34
|
+
*/
|
|
35
|
+
const [hasEnteredOpen, setHasEnteredOpen] = useState(false);
|
|
36
|
+
useEffect(() => {
|
|
37
|
+
if (!isOpen) {
|
|
38
|
+
setHasEnteredOpen(false);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
let secondFrame = 0;
|
|
42
|
+
const firstFrame = requestAnimationFrame(() => {
|
|
43
|
+
secondFrame = requestAnimationFrame(() => setHasEnteredOpen(true));
|
|
44
|
+
});
|
|
45
|
+
return () => {
|
|
46
|
+
cancelAnimationFrame(firstFrame);
|
|
47
|
+
cancelAnimationFrame(secondFrame);
|
|
48
|
+
};
|
|
49
|
+
}, [isOpen]);
|
|
50
|
+
const isVisuallyOpen = isOpen && hasEnteredOpen;
|
|
29
51
|
useScrollBlockage({
|
|
30
52
|
disableScroll: isOpen,
|
|
31
53
|
key: identifier ? `right_drawer_${identifier}` : "right_drawer"
|
|
32
54
|
});
|
|
33
55
|
useEffect(() => {
|
|
56
|
+
if (!isOpen) return;
|
|
34
57
|
const handleClickOutside = (event) => {
|
|
35
58
|
try {
|
|
36
59
|
if (!panelRef.current) return;
|
|
37
|
-
const isClickAble =
|
|
60
|
+
const isClickAble = closeOnOutsideClick;
|
|
38
61
|
const isClickOutside = event.target && !panelRef.current.contains(event.target);
|
|
39
62
|
const isAtTopAndVisible = isElementAtTopAndNotCovered(panelRef.current);
|
|
40
63
|
if (isClickAble && isClickOutside && isAtTopAndVisible || !event.target) {
|
|
@@ -95,7 +118,7 @@ const RightDrawer = ({ title, identifier, children, header, footer, closeOnOutsi
|
|
|
95
118
|
return createPortal(/* @__PURE__ */ jsx("div", {
|
|
96
119
|
className: "fixed top-0 right-0 z-50 flex h-full justify-end",
|
|
97
120
|
children: /* @__PURE__ */ jsx(MaxWidthSmoother, {
|
|
98
|
-
isHidden: !
|
|
121
|
+
isHidden: !isVisuallyOpen,
|
|
99
122
|
align: "right",
|
|
100
123
|
children: /* @__PURE__ */ jsxs(Container, {
|
|
101
124
|
className: "relative flex h-screen w-screen flex-col border-l text-text md:w-100",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RightDrawer.mjs","names":[],"sources":["../../../../src/components/RightDrawer/RightDrawer.tsx"],"sourcesContent":["'use client';\n\nimport { useGetElementOrWindow } from '@hooks/index';\nimport { useDevice } from '@hooks/useDevice';\nimport { useScrollBlockage } from '@hooks/useScrollBlockage';\nimport { ChevronLeft, X } from 'lucide-react';\nimport {\n type FC,\n type KeyboardEventHandler,\n type MouseEventHandler,\n type ReactNode,\n useEffect,\n useRef,\n} from 'react';\nimport { createPortal } from 'react-dom';\nimport { useIntlayer } from 'react-intlayer';\nimport { Button } from '../Button';\nimport { Container } from '../Container';\nimport { KeyboardShortcut } from '../KeyboardShortcut';\nimport { MaxWidthSmoother } from '../MaxWidthSmoother/index';\nimport { Popover } from '../Popover';\nimport { isElementAtTopAndNotCovered } from './isElementAtTopAndNotCovered';\nimport { useRightDrawer } from './useRightDrawer';\n\n/**\n * Configuration for the back button functionality in the RightDrawer\n *\n * @interface BackButtonProps\n */\ntype BackButtonProps = {\n /** Callback function triggered when the back button is clicked */\n onBack: () => void;\n /** Optional custom text for the back buttoDefaults to \"Go back\" if not provided */\n text?: string;\n};\n\n/**\n * Props configuration for the RightDrawer component\n *\n * @interface RightDrawerProps\n */\ntype RightDrawerProps = {\n /**\n * Title displayed in the drawer header\n */\n title?: ReactNode;\n\n /**\n * Unique identifier for the drawer instancRequired for store management\n */\n identifier: string;\n\n /** The content to be displayed inside the drawer */\n children?: ReactNode;\n\n /**\n * Optional header content displayed below the title\n */\n header?: ReactNode;\n\n /**\n * Optional footer content pinned to the bottom of the drawer\n */\n footer?: ReactNode;\n\n /**\n * Whether the drawer should close when clicking outside of it\n * @default true\n */\n closeOnOutsideClick?: boolean;\n\n /**\n * Configuration for an optional back button in the drawer header\n */\n backButton?: BackButtonProps;\n\n /**\n * External control for the open statWhen provided, overrides internal store state\n */\n isOpen?: boolean;\n\n /**\n * Callback function triggered when the drawer is closed\n */\n onClose?: () => void;\n\n /**\n * Optional container to render the drawer into.\n * If not provided, it will be rendered into the body.\n */\n container?: HTMLElement;\n};\n\nexport const RightDrawer: FC<RightDrawerProps> = ({\n title,\n identifier,\n children,\n header,\n footer,\n closeOnOutsideClick = true,\n backButton,\n isOpen: isOpenProp,\n onClose,\n container,\n}) => {\n const content = useIntlayer('right-drawer');\n const { isMobile } = useDevice('md');\n const panelRef = useRef<HTMLDivElement>(null);\n const childrenContainerRef = useRef<HTMLDivElement>(null);\n const containerElement = useGetElementOrWindow(container);\n\n const {\n open: openDrawer,\n close: closeDrawer,\n isOpen: checkIsOpen,\n } = useRightDrawer();\n const storeIsOpen = checkIsOpen(identifier);\n const isOpen = storeIsOpen;\n\n useScrollBlockage({\n disableScroll: isOpen,\n key: identifier ? `right_drawer_${identifier}` : 'right_drawer',\n });\n\n // Handle Click Outside\n useEffect(() => {\n const handleClickOutside = (event: MouseEvent) => {\n try {\n if (!panelRef.current) return;\n\n const isClickAble = isOpen && closeOnOutsideClick;\n const isClickOutside =\n event.target && !panelRef.current.contains(event.target as Node);\n const isAtTopAndVisible = isElementAtTopAndNotCovered(panelRef.current);\n\n if (\n (isClickAble && isClickOutside && isAtTopAndVisible) ||\n !event.target\n ) {\n closeDrawer(identifier);\n onClose?.();\n }\n } catch (_e) {\n closeDrawer(identifier);\n onClose?.();\n }\n };\n\n window.addEventListener('mousedown', handleClickOutside);\n return () => window.removeEventListener('mousedown', handleClickOutside);\n }, [isOpen, closeDrawer, onClose, closeOnOutsideClick, identifier]);\n\n const onCloseRef = useRef(onClose);\n useEffect(() => {\n onCloseRef.current = onClose;\n }, [onClose]);\n\n useEffect(() => {\n if (isOpenProp === undefined) return;\n if (isOpenProp === storeIsOpen) return;\n\n if (isOpenProp) {\n openDrawer(identifier);\n } else {\n closeDrawer(identifier);\n onCloseRef.current?.();\n }\n }, [isOpenProp, storeIsOpen, identifier, openDrawer, closeDrawer]);\n\n const handleSpareSpaceClick: MouseEventHandler<HTMLDivElement> = (e) => {\n if (e.target !== e.currentTarget) {\n return;\n }\n if (isMobile) {\n closeDrawer(identifier);\n onClose?.();\n }\n };\n\n // Handle Keyboard on Spare Space (Linter Fix)\n const handleSpareSpaceKeyDown: KeyboardEventHandler<HTMLDivElement> = (e) => {\n if (e.target !== e.currentTarget) return;\n\n // Allow closing via Enter or Space if focused on the spare area\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n if (isMobile) {\n closeDrawer(identifier);\n onClose?.();\n }\n }\n };\n\n if (!containerElement) return <></>;\n\n return createPortal(\n <div className=\"fixed top-0 right-0 z-50 flex h-full justify-end\">\n <MaxWidthSmoother isHidden={!isOpen} align=\"right\">\n <Container\n className=\"relative flex h-screen w-screen flex-col border-l text-text md:w-100\"\n ref={panelRef}\n roundedSize=\"none\"\n borderColor=\"neutral\"\n >\n {/* Header */}\n <div className=\"flex shrink-0 flex-col gap-3 px-6 pt-6\">\n <div className=\"flex justify-between gap-3\">\n <div>\n {backButton && (\n <Button\n variant=\"hoverable\"\n color=\"text\"\n label={backButton.text ?? content.goBack.value}\n onClick={backButton.onBack}\n Icon={ChevronLeft}\n >\n {backButton?.text}\n </Button>\n )}\n </div>\n <div>\n <Popover identifier=\"close-drawer\">\n <Button\n variant=\"hoverable\"\n color=\"text\"\n label=\"Close\"\n className=\"ml-auto\"\n onClick={() => {\n closeDrawer(identifier);\n onClose?.();\n }}\n Icon={X}\n size=\"icon-md\"\n />\n\n <Popover.Detail identifier=\"close-drawer\">\n <div className=\"flex items-center gap-2 p-2\">\n <span className=\"whitespace-nowrap text-neutral text-xs\">\n {content.closeDrawer}\n </span>\n <KeyboardShortcut\n shortcut=\"Escape\"\n size=\"sm\"\n onTriggered={() => {\n closeDrawer(identifier);\n onClose?.();\n }}\n />\n </div>\n </Popover.Detail>\n </Popover>\n </div>\n </div>\n {title && (\n <h2 className=\"flex items-center justify-center font-bold text-lg\">\n {title}\n </h2>\n )}\n {header}\n </div>\n\n {/* Body */}\n <div className=\"flex min-h-0 flex-1 flex-col overflow-y-auto p-2\">\n {/** biome-ignore lint/a11y/useSemanticElements: This div is used to handle the spare space click and keydown events */}\n <div\n className=\"flex flex-1 flex-col outline-none\"\n onClick={handleSpareSpaceClick}\n onKeyDown={handleSpareSpaceKeyDown}\n ref={childrenContainerRef}\n role=\"button\" // Semantically acts as a button area\n tabIndex={0} // Makes it focusable to receive key events\n >\n {children}\n </div>\n </div>\n\n {/* Footer */}\n {footer && <div className=\"shrink-0\">{footer}</div>}\n </Container>\n </MaxWidthSmoother>\n </div>,\n containerElement\n );\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"RightDrawer.mjs","names":[],"sources":["../../../../src/components/RightDrawer/RightDrawer.tsx"],"sourcesContent":["'use client';\n\nimport { useGetElementOrWindow } from '@hooks/index';\nimport { useDevice } from '@hooks/useDevice';\nimport { useScrollBlockage } from '@hooks/useScrollBlockage';\nimport { ChevronLeft, X } from 'lucide-react';\nimport {\n type FC,\n type KeyboardEventHandler,\n type MouseEventHandler,\n type ReactNode,\n useEffect,\n useRef,\n useState,\n} from 'react';\nimport { createPortal } from 'react-dom';\nimport { useIntlayer } from 'react-intlayer';\nimport { Button } from '../Button';\nimport { Container } from '../Container';\nimport { KeyboardShortcut } from '../KeyboardShortcut';\nimport { MaxWidthSmoother } from '../MaxWidthSmoother/index';\nimport { Popover } from '../Popover';\nimport { isElementAtTopAndNotCovered } from './isElementAtTopAndNotCovered';\nimport { useIsRightDrawerOpen, useRightDrawerActions } from './useRightDrawer';\n\n/**\n * Configuration for the back button functionality in the RightDrawer\n *\n * @interface BackButtonProps\n */\ntype BackButtonProps = {\n /** Callback function triggered when the back button is clicked */\n onBack: () => void;\n /** Optional custom text for the back buttoDefaults to \"Go back\" if not provided */\n text?: string;\n};\n\n/**\n * Props configuration for the RightDrawer component\n *\n * @interface RightDrawerProps\n */\ntype RightDrawerProps = {\n /**\n * Title displayed in the drawer header\n */\n title?: ReactNode;\n\n /**\n * Unique identifier for the drawer instancRequired for store management\n */\n identifier: string;\n\n /** The content to be displayed inside the drawer */\n children?: ReactNode;\n\n /**\n * Optional header content displayed below the title\n */\n header?: ReactNode;\n\n /**\n * Optional footer content pinned to the bottom of the drawer\n */\n footer?: ReactNode;\n\n /**\n * Whether the drawer should close when clicking outside of it\n * @default true\n */\n closeOnOutsideClick?: boolean;\n\n /**\n * Configuration for an optional back button in the drawer header\n */\n backButton?: BackButtonProps;\n\n /**\n * External control for the open statWhen provided, overrides internal store state\n */\n isOpen?: boolean;\n\n /**\n * Callback function triggered when the drawer is closed\n */\n onClose?: () => void;\n\n /**\n * Optional container to render the drawer into.\n * If not provided, it will be rendered into the body.\n */\n container?: HTMLElement;\n};\n\nexport const RightDrawer: FC<RightDrawerProps> = ({\n title,\n identifier,\n children,\n header,\n footer,\n closeOnOutsideClick = true,\n backButton,\n isOpen: isOpenProp,\n onClose,\n container,\n}) => {\n const content = useIntlayer('right-drawer');\n const { isMobile } = useDevice('md');\n const panelRef = useRef<HTMLDivElement>(null);\n const childrenContainerRef = useRef<HTMLDivElement>(null);\n const containerElement = useGetElementOrWindow(container);\n\n const { open: openDrawer, close: closeDrawer } = useRightDrawerActions();\n const storeIsOpen = useIsRightDrawerOpen(identifier);\n const isOpen = storeIsOpen;\n\n /**\n * A drawer mounted by its parent in the already-open state is inserted into\n * the DOM at its final width, leaving the transition no previous value to\n * start from: it pops instead of sliding. Painting the closed state for a\n * frame first gives the transition its starting point.\n */\n const [hasEnteredOpen, setHasEnteredOpen] = useState(false);\n\n useEffect(() => {\n if (!isOpen) {\n setHasEnteredOpen(false);\n return;\n }\n\n let secondFrame = 0;\n const firstFrame = requestAnimationFrame(() => {\n secondFrame = requestAnimationFrame(() => setHasEnteredOpen(true));\n });\n\n return () => {\n cancelAnimationFrame(firstFrame);\n cancelAnimationFrame(secondFrame);\n };\n }, [isOpen]);\n\n const isVisuallyOpen = isOpen && hasEnteredOpen;\n\n useScrollBlockage({\n disableScroll: isOpen,\n key: identifier ? `right_drawer_${identifier}` : 'right_drawer',\n });\n\n // Handle Click Outside\n useEffect(() => {\n if (!isOpen) return;\n\n const handleClickOutside = (event: MouseEvent) => {\n try {\n if (!panelRef.current) return;\n\n const isClickAble = closeOnOutsideClick;\n const isClickOutside =\n event.target && !panelRef.current.contains(event.target as Node);\n const isAtTopAndVisible = isElementAtTopAndNotCovered(panelRef.current);\n\n if (\n (isClickAble && isClickOutside && isAtTopAndVisible) ||\n !event.target\n ) {\n closeDrawer(identifier);\n onClose?.();\n }\n } catch (_e) {\n closeDrawer(identifier);\n onClose?.();\n }\n };\n\n window.addEventListener('mousedown', handleClickOutside);\n return () => window.removeEventListener('mousedown', handleClickOutside);\n }, [isOpen, closeDrawer, onClose, closeOnOutsideClick, identifier]);\n\n const onCloseRef = useRef(onClose);\n useEffect(() => {\n onCloseRef.current = onClose;\n }, [onClose]);\n\n useEffect(() => {\n if (isOpenProp === undefined) return;\n if (isOpenProp === storeIsOpen) return;\n\n if (isOpenProp) {\n openDrawer(identifier);\n } else {\n closeDrawer(identifier);\n onCloseRef.current?.();\n }\n }, [isOpenProp, storeIsOpen, identifier, openDrawer, closeDrawer]);\n\n const handleSpareSpaceClick: MouseEventHandler<HTMLDivElement> = (e) => {\n if (e.target !== e.currentTarget) {\n return;\n }\n if (isMobile) {\n closeDrawer(identifier);\n onClose?.();\n }\n };\n\n // Handle Keyboard on Spare Space (Linter Fix)\n const handleSpareSpaceKeyDown: KeyboardEventHandler<HTMLDivElement> = (e) => {\n if (e.target !== e.currentTarget) return;\n\n // Allow closing via Enter or Space if focused on the spare area\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n if (isMobile) {\n closeDrawer(identifier);\n onClose?.();\n }\n }\n };\n\n if (!containerElement) return <></>;\n\n return createPortal(\n <div className=\"fixed top-0 right-0 z-50 flex h-full justify-end\">\n <MaxWidthSmoother isHidden={!isVisuallyOpen} align=\"right\">\n <Container\n className=\"relative flex h-screen w-screen flex-col border-l text-text md:w-100\"\n ref={panelRef}\n roundedSize=\"none\"\n borderColor=\"neutral\"\n >\n {/* Header */}\n <div className=\"flex shrink-0 flex-col gap-3 px-6 pt-6\">\n <div className=\"flex justify-between gap-3\">\n <div>\n {backButton && (\n <Button\n variant=\"hoverable\"\n color=\"text\"\n label={backButton.text ?? content.goBack.value}\n onClick={backButton.onBack}\n Icon={ChevronLeft}\n >\n {backButton?.text}\n </Button>\n )}\n </div>\n <div>\n <Popover identifier=\"close-drawer\">\n <Button\n variant=\"hoverable\"\n color=\"text\"\n label=\"Close\"\n className=\"ml-auto\"\n onClick={() => {\n closeDrawer(identifier);\n onClose?.();\n }}\n Icon={X}\n size=\"icon-md\"\n />\n\n <Popover.Detail identifier=\"close-drawer\">\n <div className=\"flex items-center gap-2 p-2\">\n <span className=\"whitespace-nowrap text-neutral text-xs\">\n {content.closeDrawer}\n </span>\n <KeyboardShortcut\n shortcut=\"Escape\"\n size=\"sm\"\n onTriggered={() => {\n closeDrawer(identifier);\n onClose?.();\n }}\n />\n </div>\n </Popover.Detail>\n </Popover>\n </div>\n </div>\n {title && (\n <h2 className=\"flex items-center justify-center font-bold text-lg\">\n {title}\n </h2>\n )}\n {header}\n </div>\n\n {/* Body */}\n <div className=\"flex min-h-0 flex-1 flex-col overflow-y-auto p-2\">\n {/** biome-ignore lint/a11y/useSemanticElements: This div is used to handle the spare space click and keydown events */}\n <div\n className=\"flex flex-1 flex-col outline-none\"\n onClick={handleSpareSpaceClick}\n onKeyDown={handleSpareSpaceKeyDown}\n ref={childrenContainerRef}\n role=\"button\" // Semantically acts as a button area\n tabIndex={0} // Makes it focusable to receive key events\n >\n {children}\n </div>\n </div>\n\n {/* Footer */}\n {footer && <div className=\"shrink-0\">{footer}</div>}\n </Container>\n </MaxWidthSmoother>\n </div>,\n containerElement\n );\n};\n"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { drawerManager, useRightDrawer } from "./useRightDrawer.mjs";
|
|
1
|
+
import { drawerManager, useIsRightDrawerOpen, useRightDrawer, useRightDrawerActions } from "./useRightDrawer.mjs";
|
|
2
2
|
import { RightDrawer } from "./RightDrawer.mjs";
|
|
3
3
|
|
|
4
|
-
export { RightDrawer, drawerManager, useRightDrawer };
|
|
4
|
+
export { RightDrawer, drawerManager, useIsRightDrawerOpen, useRightDrawer, useRightDrawerActions };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import { useSyncExternalStore } from "react";
|
|
3
|
+
import { useCallback, useSyncExternalStore } from "react";
|
|
4
4
|
|
|
5
5
|
//#region src/components/RightDrawer/useRightDrawer.ts
|
|
6
6
|
var DrawerObservable = class {
|
|
@@ -15,6 +15,7 @@ var DrawerObservable = class {
|
|
|
15
15
|
getSnapshot = () => {
|
|
16
16
|
return this.drawers;
|
|
17
17
|
};
|
|
18
|
+
isOpen = (key) => Boolean(this.drawers[key]);
|
|
18
19
|
open = (key) => {
|
|
19
20
|
if (this.drawers[key]) return;
|
|
20
21
|
this.drawers = {
|
|
@@ -50,16 +51,47 @@ var DrawerObservable = class {
|
|
|
50
51
|
};
|
|
51
52
|
};
|
|
52
53
|
const drawerManager = new DrawerObservable();
|
|
54
|
+
const rightDrawerActions = {
|
|
55
|
+
open: drawerManager.open,
|
|
56
|
+
close: drawerManager.close,
|
|
57
|
+
set: drawerManager.set
|
|
58
|
+
};
|
|
59
|
+
const getServerSnapshot = () => false;
|
|
60
|
+
/**
|
|
61
|
+
* Returns the drawer actions without subscribing to the store.
|
|
62
|
+
*
|
|
63
|
+
* Prefer it over {@link useRightDrawer} in components that only need to open,
|
|
64
|
+
* close or set drawers: they then no longer re-render every time an unrelated
|
|
65
|
+
* drawer toggles.
|
|
66
|
+
*/
|
|
67
|
+
const useRightDrawerActions = () => rightDrawerActions;
|
|
68
|
+
/**
|
|
69
|
+
* Subscribes to the open state of a single drawer.
|
|
70
|
+
*
|
|
71
|
+
* The snapshot is a boolean, so a component only re-renders when its own
|
|
72
|
+
* drawer toggles, instead of on every change of the shared drawer record.
|
|
73
|
+
*
|
|
74
|
+
* @param identifier - Identifier of the drawer to watch
|
|
75
|
+
*/
|
|
76
|
+
const useIsRightDrawerOpen = (identifier) => {
|
|
77
|
+
const getSnapshot = useCallback(() => drawerManager.isOpen(identifier), [identifier]);
|
|
78
|
+
return useSyncExternalStore(drawerManager.subscribe, getSnapshot, getServerSnapshot);
|
|
79
|
+
};
|
|
80
|
+
/**
|
|
81
|
+
* Gives access to the whole drawer record.
|
|
82
|
+
*
|
|
83
|
+
* Any change to any drawer re-renders the consumer. When only one drawer
|
|
84
|
+
* matters, use {@link useIsRightDrawerOpen}; when only the actions matter, use
|
|
85
|
+
* {@link useRightDrawerActions}.
|
|
86
|
+
*/
|
|
53
87
|
const useRightDrawer = () => {
|
|
54
88
|
const drawers = useSyncExternalStore(drawerManager.subscribe, drawerManager.getSnapshot, () => ({}));
|
|
55
89
|
return {
|
|
56
|
-
|
|
57
|
-
close: drawerManager.close,
|
|
58
|
-
set: drawerManager.set,
|
|
90
|
+
...rightDrawerActions,
|
|
59
91
|
isOpen: (key) => !!drawers[key]
|
|
60
92
|
};
|
|
61
93
|
};
|
|
62
94
|
|
|
63
95
|
//#endregion
|
|
64
|
-
export { drawerManager, useRightDrawer };
|
|
96
|
+
export { drawerManager, useIsRightDrawerOpen, useRightDrawer, useRightDrawerActions };
|
|
65
97
|
//# sourceMappingURL=useRightDrawer.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useRightDrawer.mjs","names":[],"sources":["../../../../src/components/RightDrawer/useRightDrawer.ts"],"sourcesContent":["'use client';\n\nimport { useSyncExternalStore } from 'react';\n\ntype DrawerState = Record<string, boolean>;\n\nclass DrawerObservable {\n private listeners = new Set<() => void>();\n private drawers: DrawerState = {};\n\n subscribe = (listener: () => void) => {\n this.listeners.add(listener);\n return () => {\n this.listeners.delete(listener);\n };\n };\n\n getSnapshot = () => {\n return this.drawers;\n };\n\n open = (key: string) => {\n if (this.drawers[key]) return;\n this.drawers = { ...this.drawers, [key]: true };\n this.emit();\n };\n\n close = (key: string) => {\n if (!this.drawers[key]) return;\n this.drawers = { ...this.drawers, [key]: false };\n this.emit();\n };\n\n set = (states: DrawerState) => {\n let changed = false;\n const newDrawers = { ...this.drawers };\n\n for (const [key, value] of Object.entries(states)) {\n if (newDrawers[key] !== value) {\n newDrawers[key] = value;\n changed = true;\n }\n }\n\n if (changed) {\n this.drawers = newDrawers;\n this.emit();\n }\n };\n\n private emit = () => {\n this.listeners.forEach((listener) => {\n listener();\n });\n };\n}\n\nexport const drawerManager = new DrawerObservable();\n\nexport const useRightDrawer = () => {\n const drawers = useSyncExternalStore(\n drawerManager.subscribe,\n drawerManager.getSnapshot,\n () => ({}) as DrawerState\n );\n\n return {\n
|
|
1
|
+
{"version":3,"file":"useRightDrawer.mjs","names":[],"sources":["../../../../src/components/RightDrawer/useRightDrawer.ts"],"sourcesContent":["'use client';\n\nimport { useCallback, useSyncExternalStore } from 'react';\n\ntype DrawerState = Record<string, boolean>;\n\nclass DrawerObservable {\n private listeners = new Set<() => void>();\n private drawers: DrawerState = {};\n\n subscribe = (listener: () => void) => {\n this.listeners.add(listener);\n return () => {\n this.listeners.delete(listener);\n };\n };\n\n getSnapshot = () => {\n return this.drawers;\n };\n\n isOpen = (key: string) => Boolean(this.drawers[key]);\n\n open = (key: string) => {\n if (this.drawers[key]) return;\n this.drawers = { ...this.drawers, [key]: true };\n this.emit();\n };\n\n close = (key: string) => {\n if (!this.drawers[key]) return;\n this.drawers = { ...this.drawers, [key]: false };\n this.emit();\n };\n\n set = (states: DrawerState) => {\n let changed = false;\n const newDrawers = { ...this.drawers };\n\n for (const [key, value] of Object.entries(states)) {\n if (newDrawers[key] !== value) {\n newDrawers[key] = value;\n changed = true;\n }\n }\n\n if (changed) {\n this.drawers = newDrawers;\n this.emit();\n }\n };\n\n private emit = () => {\n this.listeners.forEach((listener) => {\n listener();\n });\n };\n}\n\nexport const drawerManager = new DrawerObservable();\n\n/**\n * Actions to drive any drawer, detached from the store snapshot.\n */\ntype RightDrawerActions = {\n open: (key: string) => void;\n close: (key: string) => void;\n set: (states: DrawerState) => void;\n};\n\nconst rightDrawerActions: RightDrawerActions = {\n open: drawerManager.open,\n close: drawerManager.close,\n set: drawerManager.set,\n};\n\nconst getServerSnapshot = () => false;\n\n/**\n * Returns the drawer actions without subscribing to the store.\n *\n * Prefer it over {@link useRightDrawer} in components that only need to open,\n * close or set drawers: they then no longer re-render every time an unrelated\n * drawer toggles.\n */\nexport const useRightDrawerActions = (): RightDrawerActions =>\n rightDrawerActions;\n\n/**\n * Subscribes to the open state of a single drawer.\n *\n * The snapshot is a boolean, so a component only re-renders when its own\n * drawer toggles, instead of on every change of the shared drawer record.\n *\n * @param identifier - Identifier of the drawer to watch\n */\nexport const useIsRightDrawerOpen = (identifier: string): boolean => {\n const getSnapshot = useCallback(\n () => drawerManager.isOpen(identifier),\n [identifier]\n );\n\n return useSyncExternalStore(\n drawerManager.subscribe,\n getSnapshot,\n getServerSnapshot\n );\n};\n\n/**\n * Gives access to the whole drawer record.\n *\n * Any change to any drawer re-renders the consumer. When only one drawer\n * matters, use {@link useIsRightDrawerOpen}; when only the actions matter, use\n * {@link useRightDrawerActions}.\n */\nexport const useRightDrawer = () => {\n const drawers = useSyncExternalStore(\n drawerManager.subscribe,\n drawerManager.getSnapshot,\n () => ({}) as DrawerState\n );\n\n return {\n ...rightDrawerActions,\n isOpen: (key: string) => !!drawers[key],\n };\n};\n"],"mappings":";;;;;AAMA,IAAM,mBAAN,MAAuB;CACrB,AAAQ,4BAAY,IAAI,IAAgB;CACxC,AAAQ,UAAuB,CAAC;CAEhC,aAAa,aAAyB;EACpC,KAAK,UAAU,IAAI,QAAQ;EAC3B,aAAa;GACX,KAAK,UAAU,OAAO,QAAQ;EAChC;CACF;CAEA,oBAAoB;EAClB,OAAO,KAAK;CACd;CAEA,UAAU,QAAgB,QAAQ,KAAK,QAAQ,IAAI;CAEnD,QAAQ,QAAgB;EACtB,IAAI,KAAK,QAAQ,MAAM;EACvB,KAAK,UAAU;GAAE,GAAG,KAAK;IAAU,MAAM;EAAK;EAC9C,KAAK,KAAK;CACZ;CAEA,SAAS,QAAgB;EACvB,IAAI,CAAC,KAAK,QAAQ,MAAM;EACxB,KAAK,UAAU;GAAE,GAAG,KAAK;IAAU,MAAM;EAAM;EAC/C,KAAK,KAAK;CACZ;CAEA,OAAO,WAAwB;EAC7B,IAAI,UAAU;EACd,MAAM,aAAa,EAAE,GAAG,KAAK,QAAQ;EAErC,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,MAAM,GAC9C,IAAI,WAAW,SAAS,OAAO;GAC7B,WAAW,OAAO;GAClB,UAAU;EACZ;EAGF,IAAI,SAAS;GACX,KAAK,UAAU;GACf,KAAK,KAAK;EACZ;CACF;CAEA,AAAQ,aAAa;EACnB,KAAK,UAAU,SAAS,aAAa;GACnC,SAAS;EACX,CAAC;CACH;AACF;AAEA,MAAa,gBAAgB,IAAI,iBAAiB;AAWlD,MAAM,qBAAyC;CAC7C,MAAM,cAAc;CACpB,OAAO,cAAc;CACrB,KAAK,cAAc;AACrB;AAEA,MAAM,0BAA0B;;;;;;;;AAShC,MAAa,8BACX;;;;;;;;;AAUF,MAAa,wBAAwB,eAAgC;CACnE,MAAM,cAAc,kBACZ,cAAc,OAAO,UAAU,GACrC,CAAC,UAAU,CACb;CAEA,OAAO,qBACL,cAAc,WACd,aACA,iBACF;AACF;;;;;;;;AASA,MAAa,uBAAuB;CAClC,MAAM,UAAU,qBACd,cAAc,WACd,cAAc,oBACP,CAAC,EACV;CAEA,OAAO;EACL,GAAG;EACH,SAAS,QAAgB,CAAC,CAAC,QAAQ;CACrC;AACF"}
|
|
@@ -17,6 +17,22 @@ import { cva } from "class-variance-authority";
|
|
|
17
17
|
* the one panel, and silently breaks the association for screen readers.
|
|
18
18
|
*/
|
|
19
19
|
const toIdFragment = (value) => value.trim().replace(/\s+/g, "-").replace(/[^\w-]/g, "");
|
|
20
|
+
/**
|
|
21
|
+
* Builds one id fragment per tab, free of collisions.
|
|
22
|
+
*
|
|
23
|
+
* Sanitizing alone is not enough: two values can reduce to the same fragment
|
|
24
|
+
* (`>=9.4` and `<9.4` both reduce to `94`), which would give two tabs the same
|
|
25
|
+
* DOM id and cross-wire `aria-controls` between their panels.
|
|
26
|
+
*/
|
|
27
|
+
const toIdFragments = (values) => {
|
|
28
|
+
const fragmentUsageCount = /* @__PURE__ */ new Map();
|
|
29
|
+
return values.map((value, index) => {
|
|
30
|
+
const fragment = toIdFragment(value) || String(index);
|
|
31
|
+
const previousUsageCount = fragmentUsageCount.get(fragment) ?? 0;
|
|
32
|
+
fragmentUsageCount.set(fragment, previousUsageCount + 1);
|
|
33
|
+
return previousUsageCount === 0 ? fragment : `${fragment}-${previousUsageCount + 1}`;
|
|
34
|
+
});
|
|
35
|
+
};
|
|
20
36
|
const TabContext = createContext(void 0);
|
|
21
37
|
const tabContainerVariant = cva("relative w-full rounded-lg", {
|
|
22
38
|
variants: {
|
|
@@ -81,6 +97,7 @@ const TabComponent = ({ defaultTab, group, variant, children, className, headerC
|
|
|
81
97
|
const currentTabValue = (group && typeof tabsValues === "object" ? tabsValues?.[group] : activeTab) ?? defaultTab ?? firstTabValue;
|
|
82
98
|
const activeTabIndex = tabItems.findIndex((tab) => tab.value === currentTabValue);
|
|
83
99
|
const tabsCount = tabItems.length;
|
|
100
|
+
const idFragments = toIdFragments(tabItems.map(({ value }) => value));
|
|
84
101
|
const { containerProps, dragDeltaPct, isDragging } = useHorizontalSwipe({
|
|
85
102
|
itemIndex: activeTabIndex,
|
|
86
103
|
itemCount: tabsCount,
|
|
@@ -115,9 +132,9 @@ const TabComponent = ({ defaultTab, group, variant, children, className, headerC
|
|
|
115
132
|
className: cn("flex shrink-0 gap-3 p-3", headerClassName),
|
|
116
133
|
children: /* @__PURE__ */ jsx(TabSelector, {
|
|
117
134
|
selectedChoice: currentTabValue,
|
|
118
|
-
tabs: tabItems.map(({ label, value, disabled }) => {
|
|
135
|
+
tabs: tabItems.map(({ label, value, disabled }, index) => {
|
|
119
136
|
const isActive = currentTabValue === value;
|
|
120
|
-
const idFragment =
|
|
137
|
+
const idFragment = idFragments[index];
|
|
121
138
|
return /* @__PURE__ */ jsx("button", {
|
|
122
139
|
className: cn("cursor-pointer whitespace-nowrap rounded-md px-4 py-1 font-medium text-sm transition-colors focus:outline-none", !isActive && "text-neutral/70"),
|
|
123
140
|
"data-active": isActive,
|
|
@@ -145,7 +162,7 @@ const TabComponent = ({ defaultTab, group, variant, children, className, headerC
|
|
|
145
162
|
},
|
|
146
163
|
children: tabItems.map(({ value, children, className: itemClassName }, index) => {
|
|
147
164
|
const isActive = index === activeTabIndex;
|
|
148
|
-
const idFragment =
|
|
165
|
+
const idFragment = idFragments[index];
|
|
149
166
|
return /* @__PURE__ */ jsx("div", {
|
|
150
167
|
role: "tabpanel",
|
|
151
168
|
"aria-labelledby": `tab-${idFragment}`,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Tab.mjs","names":[],"sources":["../../../../src/components/Tab/Tab.tsx"],"sourcesContent":["'use client';\n\nimport { useHorizontalSwipe } from '@hooks/useHorizontalSwipe';\nimport { cn } from '@utils/cn';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport {\n Children,\n createContext,\n type HTMLAttributes,\n isValidElement,\n type ReactElement,\n type ReactNode,\n useState,\n} from 'react';\nimport { TabSelector } from '../TabSelector';\nimport { useTabContext } from './TabContext';\n\n/**\n * Builds an id fragment usable in `id` / `aria-controls`.\n *\n * Tab values come from markdown (`<Tab value=\"Extract command\">`), so they can\n * hold spaces — which makes `aria-controls` reference a list of ids rather than\n * the one panel, and silently breaks the association for screen readers.\n */\nconst toIdFragment = (value: string) =>\n value\n .trim()\n .replace(/\\s+/g, '-')\n .replace(/[^\\w-]/g, '');\n\n// Context for managing tab state\ntype TabContextType = {\n activeTab: string;\n setActiveTab: (tab: string) => void;\n};\n\nconst TabContext = createContext<TabContextType | undefined>(undefined);\n\n// Tab container variants\nconst tabContainerVariant = cva('relative w-full rounded-lg', {\n variants: {\n background: {\n with: 'border border-neutral/20 bg-background/2 shadow-[0_0_10px_-15px_rgba(0,0,0,0.3)] backdrop-blur',\n without: '',\n },\n variant: {\n default: '',\n bordered: 'border-2',\n ghost: 'border-0 bg-transparent shadow-none',\n },\n },\n defaultVariants: {\n variant: 'default',\n },\n});\n\nexport type TabProps = HTMLAttributes<HTMLDivElement> &\n VariantProps<typeof tabContainerVariant> & {\n defaultTab?: string;\n group?: string;\n children: ReactNode;\n headerClassName?: string;\n fullHeight?: boolean;\n };\n\nexport type TabItemProps = HTMLAttributes<HTMLDivElement> & {\n label?: string;\n value?: string;\n disabled?: boolean;\n children: ReactNode;\n};\n\n/** A tab item whose identifier has been resolved to a usable string. */\ntype ResolvedTabItem = TabItemProps & { value: string };\n\n/**\n * Resolves the identifier of a tab.\n *\n * Both `label` and `value` are optional for markdown-authored tabs\n * (`<Tab label=\"next-intl\">`), so the identifier falls back to the label, then\n * to the position, keeping every tab addressable instead of rendering ids from\n * `undefined`.\n */\nconst resolveTabValue = (\n { value, label }: TabItemProps,\n index: number\n): string => {\n const identifier = value ?? label;\n\n return typeof identifier === 'string' ? identifier : String(index);\n};\n\n/**\n * TabItem component that represents a single tab\n * Must be used as a child of the Tab component\n */\nconst TabItem = ({ children, ...props }: TabItemProps) => (\n // This component is primarily used for its props by the parent Tab component\n // The actual rendering is handled by the Tab component\n <div {...props}>{children}</div>\n);\n\n// Add display name for better debugging\nTabItem.displayName = 'TabItem';\n\n/**\n * Tab container component that manages tab state and renders tab headers and content\n *\n * Example:\n * ```jsx\n * <Tab defaultTab=\"tab1\">\n * <Tab.Item label=\"First Tab\" value=\"tab1\">\n * Content for first tab\n * </Tab.Item>\n * <Tab.Item label=\"Second Tab\" value=\"tab2\">\n * Content for second tab\n * </Tab.Item>\n * </Tab>\n * ```\n */\nconst TabComponent = ({\n defaultTab,\n group,\n variant,\n children,\n className,\n headerClassName,\n fullHeight,\n ...props\n}: TabProps) => {\n // Extract TabItem children to get their props\n const tabItems: ResolvedTabItem[] = (\n Children.toArray(children).filter((child) => {\n return isValidElement(child) && child.type === TabItem;\n }) as ReactElement<TabItemProps>[]\n ).map((child, index) => ({\n ...child.props,\n value: resolveTabValue(child.props, index),\n }));\n\n const firstTabValue = tabItems[0]?.value;\n const { tabsValues, setTabsValues } = useTabContext();\n const [activeTab, setActiveTab] = useState(defaultTab ?? firstTabValue ?? '');\n const hasGroup = group && typeof tabsValues === 'object';\n const currentTabValue =\n (hasGroup ? tabsValues?.[group] : activeTab) ?? defaultTab ?? firstTabValue;\n const activeTabIndex = tabItems.findIndex(\n (tab) => tab.value === currentTabValue\n );\n\n const tabsCount = tabItems.length;\n\n const { containerProps, dragDeltaPct, isDragging } = useHorizontalSwipe({\n itemIndex: activeTabIndex,\n itemCount: tabsCount,\n onSwipeLeft: () => {\n const targetIndex = Math.min(tabsCount - 1, activeTabIndex + 1);\n const nextValue = tabItems[targetIndex]?.value;\n if (nextValue) handleSetActiveTab(nextValue);\n },\n onSwipeRight: () => {\n const targetIndex = Math.max(0, activeTabIndex - 1);\n const nextValue = tabItems[targetIndex]?.value;\n if (nextValue) handleSetActiveTab(nextValue);\n },\n });\n\n const handleSetActiveTab = (tab: string) => {\n setActiveTab(tab);\n\n if (typeof setTabsValues === 'function') {\n setTabsValues((prev) => ({ ...prev, [group!]: tab }));\n }\n };\n\n const contextValue: TabContextType = {\n activeTab: activeTab ?? firstTabValue ?? '',\n setActiveTab: handleSetActiveTab,\n };\n\n return (\n <TabContext.Provider value={contextValue}>\n <div\n className={cn(\n tabContainerVariant({ variant }),\n fullHeight && 'flex h-full flex-col overflow-hidden',\n className\n )}\n {...props}\n >\n {/* Tab Headers — `TabSelector` is the tablist; wrapping it in another\n one would nest two, leaving the outer without any `tab` child. */}\n <div className={cn('flex shrink-0 gap-3 p-3', headerClassName)}>\n <TabSelector\n selectedChoice={currentTabValue}\n tabs={tabItems.map(({ label, value, disabled }) => {\n const isActive = currentTabValue === value;\n const idFragment = toIdFragment(value);\n\n return (\n <button\n key={value}\n className={cn(\n 'cursor-pointer whitespace-nowrap rounded-md px-4 py-1 font-medium text-sm transition-colors focus:outline-none',\n !isActive && 'text-neutral/70'\n )}\n data-active={isActive}\n disabled={disabled}\n onClick={() => !disabled && handleSetActiveTab(value)}\n role=\"tab\"\n aria-selected={isActive}\n aria-controls={`tabpanel-${idFragment}`}\n id={`tab-${idFragment}`}\n type=\"button\"\n >\n {label ?? value}\n </button>\n );\n })}\n hoverable\n color=\"text\"\n />\n </div>\n {/* Tab Content */}\n {/* Clipper: no overflow; uses clip-path */}\n <div\n className={cn(\n 'relative w-full min-w-0 overflow-x-clip [-webkit-clip-path:inset(0)] [clip-path:inset(0)]',\n fullHeight && 'min-h-0 flex-1'\n )}\n {...containerProps}\n >\n {/* Track — presentational: it carries the sliding transform, while\n the panels it holds are the tablist's controlled regions. */}\n <div\n className={cn(\n 'grid w-full min-w-0',\n fullHeight && 'h-full',\n isDragging\n ? 'transition-none'\n : 'transition-transform duration-300 ease-in-out'\n )}\n style={{\n gridTemplateColumns: `repeat(${tabItems.length}, 100%)`,\n transform: `translateX(-${activeTabIndex * 100 - (isDragging ? dragDeltaPct : 0)}%)`,\n }}\n >\n {tabItems.map(\n ({ value, children, className: itemClassName }, index) => {\n const isActive = index === activeTabIndex;\n const idFragment = toIdFragment(value);\n\n return (\n <div\n key={value}\n role=\"tabpanel\"\n aria-labelledby={`tab-${idFragment}`}\n id={`tabpanel-${idFragment}`}\n // `inert` takes the whole subtree out of the tab order and\n // the accessibility tree at once. `aria-hidden` alone leaves\n // the buttons and links of an off-screen panel focusable,\n // which strands keyboard users on invisible controls.\n inert={!isActive}\n tabIndex={isActive ? 0 : -1}\n data-active={isActive}\n className={cn(\n 'w-full min-w-0 p-3 opacity-100 transition-opacity duration-300 ease-in-out',\n fullHeight && 'h-full overflow-y-auto',\n !isActive && 'pointer-events-none opacity-0', // prevent offscreen interaction\n itemClassName\n )}\n >\n <div\n className={cn(\n 'flex w-full min-w-0 flex-col items-stretch gap-6',\n fullHeight && 'min-h-full'\n )}\n >\n {children}\n </div>\n </div>\n );\n }\n )}\n </div>\n </div>\n </div>\n </TabContext.Provider>\n );\n};\n\n// Create the compound component\nexport const Tab = Object.assign(TabComponent, {\n Item: TabItem,\n});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Tab.mjs","names":[],"sources":["../../../../src/components/Tab/Tab.tsx"],"sourcesContent":["'use client';\n\nimport { useHorizontalSwipe } from '@hooks/useHorizontalSwipe';\nimport { cn } from '@utils/cn';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport {\n Children,\n createContext,\n type HTMLAttributes,\n isValidElement,\n type ReactElement,\n type ReactNode,\n useState,\n} from 'react';\nimport { TabSelector } from '../TabSelector';\nimport { useTabContext } from './TabContext';\n\n/**\n * Builds an id fragment usable in `id` / `aria-controls`.\n *\n * Tab values come from markdown (`<Tab value=\"Extract command\">`), so they can\n * hold spaces — which makes `aria-controls` reference a list of ids rather than\n * the one panel, and silently breaks the association for screen readers.\n */\nconst toIdFragment = (value: string) =>\n value\n .trim()\n .replace(/\\s+/g, '-')\n .replace(/[^\\w-]/g, '');\n\n/**\n * Builds one id fragment per tab, free of collisions.\n *\n * Sanitizing alone is not enough: two values can reduce to the same fragment\n * (`>=9.4` and `<9.4` both reduce to `94`), which would give two tabs the same\n * DOM id and cross-wire `aria-controls` between their panels.\n */\nconst toIdFragments = (values: string[]): string[] => {\n const fragmentUsageCount = new Map<string, number>();\n\n return values.map((value, index) => {\n const fragment = toIdFragment(value) || String(index);\n const previousUsageCount = fragmentUsageCount.get(fragment) ?? 0;\n\n fragmentUsageCount.set(fragment, previousUsageCount + 1);\n\n return previousUsageCount === 0\n ? fragment\n : `${fragment}-${previousUsageCount + 1}`;\n });\n};\n\n// Context for managing tab state\ntype TabContextType = {\n activeTab: string;\n setActiveTab: (tab: string) => void;\n};\n\nconst TabContext = createContext<TabContextType | undefined>(undefined);\n\n// Tab container variants\nconst tabContainerVariant = cva('relative w-full rounded-lg', {\n variants: {\n background: {\n with: 'border border-neutral/20 bg-background/2 shadow-[0_0_10px_-15px_rgba(0,0,0,0.3)] backdrop-blur',\n without: '',\n },\n variant: {\n default: '',\n bordered: 'border-2',\n ghost: 'border-0 bg-transparent shadow-none',\n },\n },\n defaultVariants: {\n variant: 'default',\n },\n});\n\nexport type TabProps = HTMLAttributes<HTMLDivElement> &\n VariantProps<typeof tabContainerVariant> & {\n defaultTab?: string;\n group?: string;\n children: ReactNode;\n headerClassName?: string;\n fullHeight?: boolean;\n };\n\nexport type TabItemProps = HTMLAttributes<HTMLDivElement> & {\n label?: string;\n value?: string;\n disabled?: boolean;\n children: ReactNode;\n};\n\n/** A tab item whose identifier has been resolved to a usable string. */\ntype ResolvedTabItem = TabItemProps & { value: string };\n\n/**\n * Resolves the identifier of a tab.\n *\n * Both `label` and `value` are optional for markdown-authored tabs\n * (`<Tab label=\"next-intl\">`), so the identifier falls back to the label, then\n * to the position, keeping every tab addressable instead of rendering ids from\n * `undefined`.\n */\nconst resolveTabValue = (\n { value, label }: TabItemProps,\n index: number\n): string => {\n const identifier = value ?? label;\n\n return typeof identifier === 'string' ? identifier : String(index);\n};\n\n/**\n * TabItem component that represents a single tab\n * Must be used as a child of the Tab component\n */\nconst TabItem = ({ children, ...props }: TabItemProps) => (\n // This component is primarily used for its props by the parent Tab component\n // The actual rendering is handled by the Tab component\n <div {...props}>{children}</div>\n);\n\n// Add display name for better debugging\nTabItem.displayName = 'TabItem';\n\n/**\n * Tab container component that manages tab state and renders tab headers and content\n *\n * Example:\n * ```jsx\n * <Tab defaultTab=\"tab1\">\n * <Tab.Item label=\"First Tab\" value=\"tab1\">\n * Content for first tab\n * </Tab.Item>\n * <Tab.Item label=\"Second Tab\" value=\"tab2\">\n * Content for second tab\n * </Tab.Item>\n * </Tab>\n * ```\n */\nconst TabComponent = ({\n defaultTab,\n group,\n variant,\n children,\n className,\n headerClassName,\n fullHeight,\n ...props\n}: TabProps) => {\n // Extract TabItem children to get their props\n const tabItems: ResolvedTabItem[] = (\n Children.toArray(children).filter((child) => {\n return isValidElement(child) && child.type === TabItem;\n }) as ReactElement<TabItemProps>[]\n ).map((child, index) => ({\n ...child.props,\n value: resolveTabValue(child.props, index),\n }));\n\n const firstTabValue = tabItems[0]?.value;\n const { tabsValues, setTabsValues } = useTabContext();\n const [activeTab, setActiveTab] = useState(defaultTab ?? firstTabValue ?? '');\n const hasGroup = group && typeof tabsValues === 'object';\n const currentTabValue =\n (hasGroup ? tabsValues?.[group] : activeTab) ?? defaultTab ?? firstTabValue;\n const activeTabIndex = tabItems.findIndex(\n (tab) => tab.value === currentTabValue\n );\n\n const tabsCount = tabItems.length;\n const idFragments = toIdFragments(tabItems.map(({ value }) => value));\n\n const { containerProps, dragDeltaPct, isDragging } = useHorizontalSwipe({\n itemIndex: activeTabIndex,\n itemCount: tabsCount,\n onSwipeLeft: () => {\n const targetIndex = Math.min(tabsCount - 1, activeTabIndex + 1);\n const nextValue = tabItems[targetIndex]?.value;\n if (nextValue) handleSetActiveTab(nextValue);\n },\n onSwipeRight: () => {\n const targetIndex = Math.max(0, activeTabIndex - 1);\n const nextValue = tabItems[targetIndex]?.value;\n if (nextValue) handleSetActiveTab(nextValue);\n },\n });\n\n const handleSetActiveTab = (tab: string) => {\n setActiveTab(tab);\n\n if (typeof setTabsValues === 'function') {\n setTabsValues((prev) => ({ ...prev, [group!]: tab }));\n }\n };\n\n const contextValue: TabContextType = {\n activeTab: activeTab ?? firstTabValue ?? '',\n setActiveTab: handleSetActiveTab,\n };\n\n return (\n <TabContext.Provider value={contextValue}>\n <div\n className={cn(\n tabContainerVariant({ variant }),\n fullHeight && 'flex h-full flex-col overflow-hidden',\n className\n )}\n {...props}\n >\n {/* Tab Headers — `TabSelector` is the tablist; wrapping it in another\n one would nest two, leaving the outer without any `tab` child. */}\n <div className={cn('flex shrink-0 gap-3 p-3', headerClassName)}>\n <TabSelector\n selectedChoice={currentTabValue}\n tabs={tabItems.map(({ label, value, disabled }, index) => {\n const isActive = currentTabValue === value;\n const idFragment = idFragments[index];\n\n return (\n <button\n key={value}\n className={cn(\n 'cursor-pointer whitespace-nowrap rounded-md px-4 py-1 font-medium text-sm transition-colors focus:outline-none',\n !isActive && 'text-neutral/70'\n )}\n data-active={isActive}\n disabled={disabled}\n onClick={() => !disabled && handleSetActiveTab(value)}\n role=\"tab\"\n aria-selected={isActive}\n aria-controls={`tabpanel-${idFragment}`}\n id={`tab-${idFragment}`}\n type=\"button\"\n >\n {label ?? value}\n </button>\n );\n })}\n hoverable\n color=\"text\"\n />\n </div>\n {/* Tab Content */}\n {/* Clipper: no overflow; uses clip-path */}\n <div\n className={cn(\n 'relative w-full min-w-0 overflow-x-clip [-webkit-clip-path:inset(0)] [clip-path:inset(0)]',\n fullHeight && 'min-h-0 flex-1'\n )}\n {...containerProps}\n >\n {/* Track — presentational: it carries the sliding transform, while\n the panels it holds are the tablist's controlled regions. */}\n <div\n className={cn(\n 'grid w-full min-w-0',\n fullHeight && 'h-full',\n isDragging\n ? 'transition-none'\n : 'transition-transform duration-300 ease-in-out'\n )}\n style={{\n gridTemplateColumns: `repeat(${tabItems.length}, 100%)`,\n transform: `translateX(-${activeTabIndex * 100 - (isDragging ? dragDeltaPct : 0)}%)`,\n }}\n >\n {tabItems.map(\n ({ value, children, className: itemClassName }, index) => {\n const isActive = index === activeTabIndex;\n const idFragment = idFragments[index];\n\n return (\n <div\n key={value}\n role=\"tabpanel\"\n aria-labelledby={`tab-${idFragment}`}\n id={`tabpanel-${idFragment}`}\n // `inert` takes the whole subtree out of the tab order and\n // the accessibility tree at once. `aria-hidden` alone leaves\n // the buttons and links of an off-screen panel focusable,\n // which strands keyboard users on invisible controls.\n inert={!isActive}\n tabIndex={isActive ? 0 : -1}\n data-active={isActive}\n className={cn(\n 'w-full min-w-0 p-3 opacity-100 transition-opacity duration-300 ease-in-out',\n fullHeight && 'h-full overflow-y-auto',\n !isActive && 'pointer-events-none opacity-0', // prevent offscreen interaction\n itemClassName\n )}\n >\n <div\n className={cn(\n 'flex w-full min-w-0 flex-col items-stretch gap-6',\n fullHeight && 'min-h-full'\n )}\n >\n {children}\n </div>\n </div>\n );\n }\n )}\n </div>\n </div>\n </div>\n </TabContext.Provider>\n );\n};\n\n// Create the compound component\nexport const Tab = Object.assign(TabComponent, {\n Item: TabItem,\n});\n"],"mappings":"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"}
|
|
@@ -13,6 +13,7 @@ const logoRecord = {
|
|
|
13
13
|
adonis: dynamicLogo(() => import("./logos/Adonis.mjs"), "AdonisLogo"),
|
|
14
14
|
angular: dynamicLogo(() => import("./logos/Angular.mjs"), "AngularLogo"),
|
|
15
15
|
astro: dynamicLogo(() => import("./logos/Astro.mjs"), "AstroLogo"),
|
|
16
|
+
elysia: dynamicLogo(() => import("./logos/Elysia.mjs"), "ElysiaLogo"),
|
|
16
17
|
express: dynamicLogo(() => import("./logos/Express.mjs"), "ExpressLogo"),
|
|
17
18
|
fastify: dynamicLogo(() => import("./logos/Fastify.mjs"), "FastifyLogo"),
|
|
18
19
|
hono: dynamicLogo(() => import("./logos/Hono.mjs"), "HonoLogo"),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TechLogo.mjs","names":[],"sources":["../../../../src/components/TechLogo/TechLogo.tsx"],"sourcesContent":["import { type FC, type JSX, lazy, Suspense, type SVGProps } from 'react';\nimport { cn } from '../../utils/cn';\nimport type { TechLogoName } from './types';\n\nexport type TechLogoProps = SVGProps<SVGSVGElement> & {\n name: TechLogoName;\n};\n\n/**\n * This ensures React.lazy always receives a valid component.\n */\nconst dynamicLogo = (importFn: () => Promise<any>, exportName: string) =>\n lazy(async () => {\n const module = await importFn();\n const asset = module[exportName];\n\n return { default: asset };\n });\n\nconst logoRecord: Record<TechLogoName, ReturnType<typeof dynamicLogo>> = {\n adonis: dynamicLogo(() => import('./logos/Adonis'), 'AdonisLogo'),\n angular: dynamicLogo(() => import('./logos/Angular'), 'AngularLogo'),\n astro: dynamicLogo(() => import('./logos/Astro'), 'AstroLogo'),\n express: dynamicLogo(() => import('./logos/Express'), 'ExpressLogo'),\n fastify: dynamicLogo(() => import('./logos/Fastify'), 'FastifyLogo'),\n hono: dynamicLogo(() => import('./logos/Hono'), 'HonoLogo'),\n lynx: dynamicLogo(() => import('./logos/Lynx'), 'LynxLogo'),\n nestjs: dynamicLogo(() => import('./logos/NestJS'), 'NestJSLogo'),\n nextjs: dynamicLogo(() => import('./logos/Nextjs'), 'NextJSLogo'),\n node: dynamicLogo(() => import('./logos/Node'), 'NodejsLogo'),\n nuxt: dynamicLogo(() => import('./logos/Nuxt'), 'NuxtLogo'),\n preact: dynamicLogo(() => import('./logos/Preact'), 'PreactLogo'),\n react: dynamicLogo(() => import('./logos/Reactjs'), 'ReactLogo'),\n solid: dynamicLogo(() => import('./logos/Solid'), 'SolidLogo'),\n svelte: dynamicLogo(() => import('./logos/Svelte'), 'SvelteLogo'),\n tanstack: dynamicLogo(() => import('./logos/Tanstack'), 'TanstackLogo'),\n vite: dynamicLogo(() => import('./logos/Vitejs'), 'ViteLogo'),\n vue: dynamicLogo(() => import('./logos/Vuejs'), 'VuejsLogo'),\n lit: dynamicLogo(() => import('./logos/Lit'), 'LitLogo'),\n vanilla: dynamicLogo(() => import('./logos/Vanilla'), 'JavaScriptLogo'),\n anthropic: dynamicLogo(() => import('./logos/Anthropic'), 'AnthropicLogo'),\n claude: dynamicLogo(() => import('./logos/Claude'), 'ClaudeLogo'),\n chatgpt: dynamicLogo(() => import('./logos/ChatGPT'), 'ChatGPTLogo'),\n deepseek: dynamicLogo(() => import('./logos/DeepSeek'), 'DeepSeekLogo'),\n gemini: dynamicLogo(() => import('./logos/Gemini'), 'GeminiLogo'),\n googleai: dynamicLogo(() => import('./logos/GoogleAI'), 'GoogleAILogo'),\n grok: dynamicLogo(() => import('./logos/Grok'), 'GrokLogo'),\n mistral: dynamicLogo(() => import('./logos/Mistral'), 'MistralLogo'),\n ollama: dynamicLogo(() => import('./logos/Ollama'), 'OllamaLogo'),\n openai: dynamicLogo(() => import('./logos/OpenAI'), 'OpenAILogo'),\n perplexity: dynamicLogo(() => import('./logos/Perplexity'), 'PerplexityLogo'),\n github: dynamicLogo(() => import('./logos/GitHub'), 'GitHubLogo'),\n gitlab: dynamicLogo(() => import('./logos/GitLab'), 'GitLabLogo'),\n bitbucket: dynamicLogo(() => import('./logos/Bitbucket'), 'BitbucketLogo'),\n google: dynamicLogo(() => import('./logos/Google'), 'GoogleLogo'),\n linkedin: dynamicLogo(() => import('./logos/LinkedIn'), 'LinkedInLogo'),\n};\n\nexport const TechLogo: FC<TechLogoProps> = ({\n name,\n ...props\n}): JSX.Element => {\n const LazyLogo = logoRecord[name as TechLogoName];\n\n if (!LazyLogo) {\n return <></>;\n }\n\n return (\n <Suspense\n fallback={\n <div className={cn('animate-pulse bg-neutral-200', props.className)} />\n }\n >\n <LazyLogo {...(props as any)} />\n </Suspense>\n );\n};\n"],"mappings":";;;;;;;;AAWA,MAAM,eAAe,UAA8B,eACjD,KAAK,YAAY;CAIf,OAAO,EAAE,UAFK,MADO,SAAS,EACV,CAAC,YAEG;AAC1B,CAAC;AAEH,MAAM,aAAmE;CACvE,QAAQ,kBAAkB,OAAO,uBAAmB,YAAY;CAChE,SAAS,kBAAkB,OAAO,wBAAoB,aAAa;CACnE,OAAO,kBAAkB,OAAO,sBAAkB,WAAW;CAC7D,SAAS,kBAAkB,OAAO,wBAAoB,aAAa;CACnE,SAAS,kBAAkB,OAAO,wBAAoB,aAAa;CACnE,MAAM,kBAAkB,OAAO,qBAAiB,UAAU;CAC1D,MAAM,kBAAkB,OAAO,qBAAiB,UAAU;CAC1D,QAAQ,kBAAkB,OAAO,uBAAmB,YAAY;CAChE,QAAQ,kBAAkB,OAAO,uBAAmB,YAAY;CAChE,MAAM,kBAAkB,OAAO,qBAAiB,YAAY;CAC5D,MAAM,kBAAkB,OAAO,qBAAiB,UAAU;CAC1D,QAAQ,kBAAkB,OAAO,uBAAmB,YAAY;CAChE,OAAO,kBAAkB,OAAO,wBAAoB,WAAW;CAC/D,OAAO,kBAAkB,OAAO,sBAAkB,WAAW;CAC7D,QAAQ,kBAAkB,OAAO,uBAAmB,YAAY;CAChE,UAAU,kBAAkB,OAAO,yBAAqB,cAAc;CACtE,MAAM,kBAAkB,OAAO,uBAAmB,UAAU;CAC5D,KAAK,kBAAkB,OAAO,sBAAkB,WAAW;CAC3D,KAAK,kBAAkB,OAAO,oBAAgB,SAAS;CACvD,SAAS,kBAAkB,OAAO,wBAAoB,gBAAgB;CACtE,WAAW,kBAAkB,OAAO,0BAAsB,eAAe;CACzE,QAAQ,kBAAkB,OAAO,uBAAmB,YAAY;CAChE,SAAS,kBAAkB,OAAO,wBAAoB,aAAa;CACnE,UAAU,kBAAkB,OAAO,yBAAqB,cAAc;CACtE,QAAQ,kBAAkB,OAAO,uBAAmB,YAAY;CAChE,UAAU,kBAAkB,OAAO,yBAAqB,cAAc;CACtE,MAAM,kBAAkB,OAAO,qBAAiB,UAAU;CAC1D,SAAS,kBAAkB,OAAO,wBAAoB,aAAa;CACnE,QAAQ,kBAAkB,OAAO,uBAAmB,YAAY;CAChE,QAAQ,kBAAkB,OAAO,uBAAmB,YAAY;CAChE,YAAY,kBAAkB,OAAO,2BAAuB,gBAAgB;CAC5E,QAAQ,kBAAkB,OAAO,uBAAmB,YAAY;CAChE,QAAQ,kBAAkB,OAAO,uBAAmB,YAAY;CAChE,WAAW,kBAAkB,OAAO,0BAAsB,eAAe;CACzE,QAAQ,kBAAkB,OAAO,uBAAmB,YAAY;CAChE,UAAU,kBAAkB,OAAO,yBAAqB,cAAc;AACxE;AAEA,MAAa,YAA+B,EAC1C,MACA,GAAG,YACc;CACjB,MAAM,WAAW,WAAW;CAE5B,IAAI,CAAC,UACH,OAAO,iCAAI;CAGb,OACE,oBAAC,UAAD;EACE,UACE,oBAAC,OAAD,EAAK,WAAW,GAAG,gCAAgC,MAAM,SAAS,EAAI;YAGxE,oBAAC,UAAD,EAAU,GAAK,MAAgB;CACvB;AAEd"}
|
|
1
|
+
{"version":3,"file":"TechLogo.mjs","names":[],"sources":["../../../../src/components/TechLogo/TechLogo.tsx"],"sourcesContent":["import { type FC, type JSX, lazy, Suspense, type SVGProps } from 'react';\nimport { cn } from '../../utils/cn';\nimport type { TechLogoName } from './types';\n\nexport type TechLogoProps = SVGProps<SVGSVGElement> & {\n name: TechLogoName;\n};\n\n/**\n * This ensures React.lazy always receives a valid component.\n */\nconst dynamicLogo = (importFn: () => Promise<any>, exportName: string) =>\n lazy(async () => {\n const module = await importFn();\n const asset = module[exportName];\n\n return { default: asset };\n });\n\nconst logoRecord: Record<TechLogoName, ReturnType<typeof dynamicLogo>> = {\n adonis: dynamicLogo(() => import('./logos/Adonis'), 'AdonisLogo'),\n angular: dynamicLogo(() => import('./logos/Angular'), 'AngularLogo'),\n astro: dynamicLogo(() => import('./logos/Astro'), 'AstroLogo'),\n elysia: dynamicLogo(() => import('./logos/Elysia'), 'ElysiaLogo'),\n express: dynamicLogo(() => import('./logos/Express'), 'ExpressLogo'),\n fastify: dynamicLogo(() => import('./logos/Fastify'), 'FastifyLogo'),\n hono: dynamicLogo(() => import('./logos/Hono'), 'HonoLogo'),\n lynx: dynamicLogo(() => import('./logos/Lynx'), 'LynxLogo'),\n nestjs: dynamicLogo(() => import('./logos/NestJS'), 'NestJSLogo'),\n nextjs: dynamicLogo(() => import('./logos/Nextjs'), 'NextJSLogo'),\n node: dynamicLogo(() => import('./logos/Node'), 'NodejsLogo'),\n nuxt: dynamicLogo(() => import('./logos/Nuxt'), 'NuxtLogo'),\n preact: dynamicLogo(() => import('./logos/Preact'), 'PreactLogo'),\n react: dynamicLogo(() => import('./logos/Reactjs'), 'ReactLogo'),\n solid: dynamicLogo(() => import('./logos/Solid'), 'SolidLogo'),\n svelte: dynamicLogo(() => import('./logos/Svelte'), 'SvelteLogo'),\n tanstack: dynamicLogo(() => import('./logos/Tanstack'), 'TanstackLogo'),\n vite: dynamicLogo(() => import('./logos/Vitejs'), 'ViteLogo'),\n vue: dynamicLogo(() => import('./logos/Vuejs'), 'VuejsLogo'),\n lit: dynamicLogo(() => import('./logos/Lit'), 'LitLogo'),\n vanilla: dynamicLogo(() => import('./logos/Vanilla'), 'JavaScriptLogo'),\n anthropic: dynamicLogo(() => import('./logos/Anthropic'), 'AnthropicLogo'),\n claude: dynamicLogo(() => import('./logos/Claude'), 'ClaudeLogo'),\n chatgpt: dynamicLogo(() => import('./logos/ChatGPT'), 'ChatGPTLogo'),\n deepseek: dynamicLogo(() => import('./logos/DeepSeek'), 'DeepSeekLogo'),\n gemini: dynamicLogo(() => import('./logos/Gemini'), 'GeminiLogo'),\n googleai: dynamicLogo(() => import('./logos/GoogleAI'), 'GoogleAILogo'),\n grok: dynamicLogo(() => import('./logos/Grok'), 'GrokLogo'),\n mistral: dynamicLogo(() => import('./logos/Mistral'), 'MistralLogo'),\n ollama: dynamicLogo(() => import('./logos/Ollama'), 'OllamaLogo'),\n openai: dynamicLogo(() => import('./logos/OpenAI'), 'OpenAILogo'),\n perplexity: dynamicLogo(() => import('./logos/Perplexity'), 'PerplexityLogo'),\n github: dynamicLogo(() => import('./logos/GitHub'), 'GitHubLogo'),\n gitlab: dynamicLogo(() => import('./logos/GitLab'), 'GitLabLogo'),\n bitbucket: dynamicLogo(() => import('./logos/Bitbucket'), 'BitbucketLogo'),\n google: dynamicLogo(() => import('./logos/Google'), 'GoogleLogo'),\n linkedin: dynamicLogo(() => import('./logos/LinkedIn'), 'LinkedInLogo'),\n};\n\nexport const TechLogo: FC<TechLogoProps> = ({\n name,\n ...props\n}): JSX.Element => {\n const LazyLogo = logoRecord[name as TechLogoName];\n\n if (!LazyLogo) {\n return <></>;\n }\n\n return (\n <Suspense\n fallback={\n <div className={cn('animate-pulse bg-neutral-200', props.className)} />\n }\n >\n <LazyLogo {...(props as any)} />\n </Suspense>\n );\n};\n"],"mappings":";;;;;;;;AAWA,MAAM,eAAe,UAA8B,eACjD,KAAK,YAAY;CAIf,OAAO,EAAE,UAFK,MADO,SAAS,EACV,CAAC,YAEG;AAC1B,CAAC;AAEH,MAAM,aAAmE;CACvE,QAAQ,kBAAkB,OAAO,uBAAmB,YAAY;CAChE,SAAS,kBAAkB,OAAO,wBAAoB,aAAa;CACnE,OAAO,kBAAkB,OAAO,sBAAkB,WAAW;CAC7D,QAAQ,kBAAkB,OAAO,uBAAmB,YAAY;CAChE,SAAS,kBAAkB,OAAO,wBAAoB,aAAa;CACnE,SAAS,kBAAkB,OAAO,wBAAoB,aAAa;CACnE,MAAM,kBAAkB,OAAO,qBAAiB,UAAU;CAC1D,MAAM,kBAAkB,OAAO,qBAAiB,UAAU;CAC1D,QAAQ,kBAAkB,OAAO,uBAAmB,YAAY;CAChE,QAAQ,kBAAkB,OAAO,uBAAmB,YAAY;CAChE,MAAM,kBAAkB,OAAO,qBAAiB,YAAY;CAC5D,MAAM,kBAAkB,OAAO,qBAAiB,UAAU;CAC1D,QAAQ,kBAAkB,OAAO,uBAAmB,YAAY;CAChE,OAAO,kBAAkB,OAAO,wBAAoB,WAAW;CAC/D,OAAO,kBAAkB,OAAO,sBAAkB,WAAW;CAC7D,QAAQ,kBAAkB,OAAO,uBAAmB,YAAY;CAChE,UAAU,kBAAkB,OAAO,yBAAqB,cAAc;CACtE,MAAM,kBAAkB,OAAO,uBAAmB,UAAU;CAC5D,KAAK,kBAAkB,OAAO,sBAAkB,WAAW;CAC3D,KAAK,kBAAkB,OAAO,oBAAgB,SAAS;CACvD,SAAS,kBAAkB,OAAO,wBAAoB,gBAAgB;CACtE,WAAW,kBAAkB,OAAO,0BAAsB,eAAe;CACzE,QAAQ,kBAAkB,OAAO,uBAAmB,YAAY;CAChE,SAAS,kBAAkB,OAAO,wBAAoB,aAAa;CACnE,UAAU,kBAAkB,OAAO,yBAAqB,cAAc;CACtE,QAAQ,kBAAkB,OAAO,uBAAmB,YAAY;CAChE,UAAU,kBAAkB,OAAO,yBAAqB,cAAc;CACtE,MAAM,kBAAkB,OAAO,qBAAiB,UAAU;CAC1D,SAAS,kBAAkB,OAAO,wBAAoB,aAAa;CACnE,QAAQ,kBAAkB,OAAO,uBAAmB,YAAY;CAChE,QAAQ,kBAAkB,OAAO,uBAAmB,YAAY;CAChE,YAAY,kBAAkB,OAAO,2BAAuB,gBAAgB;CAC5E,QAAQ,kBAAkB,OAAO,uBAAmB,YAAY;CAChE,QAAQ,kBAAkB,OAAO,uBAAmB,YAAY;CAChE,WAAW,kBAAkB,OAAO,0BAAsB,eAAe;CACzE,QAAQ,kBAAkB,OAAO,uBAAmB,YAAY;CAChE,UAAU,kBAAkB,OAAO,yBAAqB,cAAc;AACxE;AAEA,MAAa,YAA+B,EAC1C,MACA,GAAG,YACc;CACjB,MAAM,WAAW,WAAW;CAE5B,IAAI,CAAC,UACH,OAAO,iCAAI;CAGb,OACE,oBAAC,UAAD;EACE,UACE,oBAAC,OAAD,EAAK,WAAW,GAAG,gCAAgC,MAAM,SAAS,EAAI;YAGxE,oBAAC,UAAD,EAAU,GAAK,MAAgB;CACvB;AAEd"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
|
|
3
|
+
//#region src/components/TechLogo/logos/Elysia.tsx
|
|
4
|
+
const ElysiaLogo = (props) => /* @__PURE__ */ jsxs("svg", {
|
|
5
|
+
shapeRendering: "geometricPrecision",
|
|
6
|
+
textRendering: "geometricPrecision",
|
|
7
|
+
imageRendering: "optimizeQuality",
|
|
8
|
+
fillRule: "evenodd",
|
|
9
|
+
clipRule: "evenodd",
|
|
10
|
+
role: "img",
|
|
11
|
+
"aria-label": "Elysia logo",
|
|
12
|
+
width: "512",
|
|
13
|
+
height: "512",
|
|
14
|
+
viewBox: "0 0 512 512",
|
|
15
|
+
fill: "none",
|
|
16
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
17
|
+
...props,
|
|
18
|
+
children: [
|
|
19
|
+
/* @__PURE__ */ jsx("path", {
|
|
20
|
+
fillRule: "evenodd",
|
|
21
|
+
clipRule: "evenodd",
|
|
22
|
+
d: "M424.404 470.816C478.089 423.889 512 354.905 512 278C512 136.615 397.385 22 256 22C114.615 22 0 136.615 0 278C0 352.658 31.9583 419.851 82.9409 466.646L83.1767 465L419.144 355L424.404 470.816Z",
|
|
23
|
+
fill: "#333333"
|
|
24
|
+
}),
|
|
25
|
+
/* @__PURE__ */ jsx("path", {
|
|
26
|
+
d: "M189.915 52.7412L144.5 46L151.303 43.9069C155.402 42.6455 159.248 40.6719 162.662 38.0765L163.73 37.2654C167.845 34.1375 171.12 30.0364 173.259 25.3304C174.414 22.7883 175.224 20.1027 175.665 17.3454L176.173 14.1698C176.72 10.7473 176.692 7.25741 176.09 3.84416C175.834 2.39429 177.279 1.23239 178.64 1.79296L180.498 2.55815C182.829 3.51798 185.084 4.65434 187.242 5.95732L194.965 10.6205C205.229 16.8174 214.226 24.9023 221.48 34.4477L226.616 41.2051C228.529 43.7228 230.783 45.9625 233.313 47.8599C236.088 49.9411 239.164 51.5874 242.435 52.7418L246 54L227.274 54.749C214.785 55.2486 202.278 54.5764 189.915 52.7412Z",
|
|
27
|
+
fill: "#CCCCCC"
|
|
28
|
+
}),
|
|
29
|
+
/* @__PURE__ */ jsx("path", {
|
|
30
|
+
d: "M178.321 93.006L191.79 68.3844C191.922 68.143 191.93 67.8528 191.812 67.6042L187.22 57.9361C184.337 51.8673 178.219 48 171.5 48L170.23 47.9562C161.437 47.653 152.704 46.3829 144.188 44.169L142.504 43.731C135.521 41.9153 128.746 39.3732 122.293 36.1463L119.446 34.723C115.159 32.5797 111.099 30.012 107.325 27.0584L103.55 24.1043C102.428 23.2265 100.803 23.4506 99.9606 24.5992C97.3651 28.1384 95.7379 32.2935 95.2395 36.6541L94.5535 42.6571C94.1854 45.8774 94.1446 49.1267 94.4316 52.3552L96.1031 71.1595C97.3467 85.1501 102.175 98.584 110.123 110.165L111.825 112.645C114.267 116.203 117.113 119.466 120.306 122.369C120.756 122.778 121.329 123.03 121.936 123.084C145.029 125.156 167.194 113.348 178.321 93.006Z",
|
|
31
|
+
fill: "#CCCCCC"
|
|
32
|
+
}),
|
|
33
|
+
/* @__PURE__ */ jsx("path", {
|
|
34
|
+
d: "M127.378 123.538L143.376 116.613C150.438 113.557 152.588 104.577 147.676 98.6533C143.683 93.8378 136.58 93.0803 131.661 96.9453L127.867 99.9256C126.958 100.64 126.127 101.448 125.387 102.336L116.263 113.284C114.982 114.822 115.084 117.084 116.5 118.5L119.318 121.721C119.77 122.237 120.296 122.685 120.878 123.049C122.833 124.271 125.263 124.453 127.378 123.538Z",
|
|
35
|
+
fill: "#EDEDED"
|
|
36
|
+
}),
|
|
37
|
+
/* @__PURE__ */ jsx("path", {
|
|
38
|
+
d: "M147.988 44.8437L147.5 45L148.962 45.4651C155.294 47.4798 161.861 48.66 168.498 48.9761C168.83 48.9919 169.163 48.9534 169.483 48.8619L172.5 48L174 47.5L164.419 45.4172C163.158 45.1431 161.982 44.5687 160.991 43.7426C160.218 43.0981 160.223 41.9084 161.002 41.2708L162.423 40.1084C164.12 38.7197 165.493 36.976 166.444 35C160.934 39.3642 154.682 42.6988 147.988 44.8437Z",
|
|
39
|
+
fill: "#B2B2B2"
|
|
40
|
+
}),
|
|
41
|
+
/* @__PURE__ */ jsx("path", {
|
|
42
|
+
d: "M202.776 219.428L72.2905 452.693C71.643 453.851 70.0687 454.069 69.1308 453.131L66.5 450.5L55.5 438L48.4888 428.927C41.8407 420.323 35.9052 411.192 30.7414 401.624L29.7434 399.775C24.2581 389.611 19.6635 378.991 16.0112 368.034L12.5 357.5C7.22519 338.379 6.01447 318.365 8.94583 298.747L9.06961 297.919C10.354 289.323 12.4034 280.86 15.1935 272.629L21 255.5L25.3334 246.385C32.0537 232.249 41.3193 219.472 52.6669 208.691L58.1719 203.462C69.5529 192.65 83.3937 184.769 98.5 180.5C94.967 181.498 91.3608 182.216 87.7149 182.647L80.5 183.5L75 184L69 185L63 185.561L59 186L56.1186 186.18C55.1927 186.238 54.7576 185.057 55.4998 184.5L55.5002 184.5L59.5273 182.57C72.5066 176.351 83.1766 166.172 90 153.5L94.4475 146.562C99.7511 138.288 106.807 131.28 115.116 126.032L116.833 124.948C119.935 122.989 123.246 121.384 126.705 120.163L142.446 114.607C145.348 113.583 147.69 111.39 148.903 108.561L149.143 108C149.705 106.687 149.932 105.255 149.803 103.833C149.608 101.689 148.616 99.6966 147.023 98.2485L144.256 95.7328C144.086 95.5779 143.93 95.4073 143.792 95.2232L126 71.5L111.803 51.9315C108.994 48.0592 107.359 43.4599 107.094 38.6832C107.051 37.9263 107.836 37.4015 108.52 37.7295L123.881 45.1028C137.174 51.4834 152.33 52.825 166.537 48.8786C169.84 47.9612 173.214 47.3242 176.624 46.9745L183.675 46.2513C201.406 44.4328 219.32 45.9054 236.516 50.5953L238 51L254.798 57.0472C275.869 64.6329 292.567 81.0571 300.5 102L304.022 115.734C305.004 119.567 306.392 123.285 308.162 126.824C312.321 135.142 318.495 142.289 326.121 147.613L335.084 153.87C339.023 156.62 343.157 159.078 347.453 161.227L367.289 171.145C368.178 171.589 368.444 172.732 367.843 173.523C362.372 180.721 355.148 186.395 346.859 190.005L335.371 195.008C330.797 197 326.081 198.65 321.262 199.945L312.822 202.212C300.992 205.39 288.796 207 276.546 207H256.333C252.148 207 248.001 206.213 244.108 204.679C228.581 198.562 210.923 204.863 202.776 219.428Z",
|
|
43
|
+
fill: "white"
|
|
44
|
+
}),
|
|
45
|
+
/* @__PURE__ */ jsx("path", {
|
|
46
|
+
d: "M271.185 135.316L279.987 135.418C281.182 135.432 281.452 133.748 280.312 133.388C278.441 132.797 276.623 132.048 274.879 131.15L268.008 127.61C263.35 125.211 258.969 122.308 254.944 118.953L253.592 117.827C250.54 115.283 247.77 112.418 245.33 109.282L243.768 107.273C243.234 106.586 242.134 107.005 242.192 107.873C243.212 123.186 255.839 135.138 271.185 135.316Z",
|
|
47
|
+
fill: "#666666"
|
|
48
|
+
}),
|
|
49
|
+
/* @__PURE__ */ jsx("path", {
|
|
50
|
+
d: "M82.2231 456.395L231.313 323.4C245.367 310.863 257.58 296.403 267.59 280.45L268.5 279C273.404 269.192 275.497 258.217 274.547 247.293L273.24 232.258C272.436 223.009 268.618 214.28 262.373 207.41C262.131 207.144 261.81 206.961 261.457 206.889L237.5 202C220.117 196.752 201.688 195.995 183.933 199.8L183 200L169.06 203.259C128.405 212.763 92.5742 236.685 68.2116 270.592L67.597 271.447C60.8846 280.789 55.1822 290.817 50.5856 301.362L49.765 303.245C38.1544 329.881 34.2409 359.238 38.4684 387.985L39.8511 397.387C41.2751 407.07 44.1931 416.474 48.5011 425.262C52.4798 433.379 57.6014 440.883 63.7095 447.547L71.3177 455.847C74.1911 458.981 79.0498 459.225 82.2231 456.395Z",
|
|
51
|
+
fill: "#CCCCCC"
|
|
52
|
+
}),
|
|
53
|
+
/* @__PURE__ */ jsx("path", {
|
|
54
|
+
d: "M212.749 278.858L212.267 279.133C199.686 286.322 192.918 299.892 193.58 314.367C193.768 318.484 197.893 322.255 201.858 321.132L209.163 319.062C218.607 316.386 227.353 311.681 234.789 305.274L256 287L262.292 282.343C298.871 255.269 344.833 244.113 389.754 251.405C391.14 251.63 391.184 253.607 389.81 253.894L384.5 255L382.093 255.842C377.15 257.572 372.856 260.776 369.79 265.022C369.214 265.819 369.982 266.89 370.922 266.601L372.663 266.065C382.467 263.049 392.751 261.904 402.978 262.691L407 263C428.843 263.95 449.114 274.626 462.254 292.1L467.179 298.65C481.776 318.063 487.953 342.53 484.319 366.545L482.421 379.087C479.837 396.163 473.618 412.486 464.184 426.952L463.5 428L453 442L441.5 455L430.965 465.114C421.346 474.348 410.827 482.597 399.567 489.738L396 492L389.175 495.25C387.417 496.087 385.95 493.678 387.5 492.5L397 483.5L398.953 481.449C404.232 475.906 408.027 469.12 409.986 461.721L410.889 458.309C411.295 456.776 411.5 455.174 411.5 453.588C411.5 444.909 405.354 437.298 396.836 435.631C391.554 434.597 386.085 435.962 381.907 439.356L372.5 447L355.894 460.587C344.995 469.504 333.185 477.245 320.66 483.682L303.5 492.5L274.5 503.5L268.412 505.16C257.822 508.049 247.012 510.06 236.092 511.174L228 512H202L167.5 508.25L148.832 504.21C138.985 502.079 129.456 498.682 120.482 494.103C113.181 490.378 106.293 485.894 99.931 480.725L85.5 469C68.005 455.64 57.0449 435.448 55.3749 413.498L54.5 402L55.5295 385.822C57.134 360.608 66.7911 336.576 83.0792 317.263C89.6652 309.454 97.2376 302.534 105.606 296.675L108.677 294.526C121.458 285.579 135.72 278.961 150.805 274.976L160.947 272.297C174.135 268.813 187.952 268.445 201.307 271.22L211.887 273.418C214.542 273.97 215.103 277.513 212.749 278.858Z",
|
|
55
|
+
fill: "#5E5E5E"
|
|
56
|
+
})
|
|
57
|
+
]
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
//#endregion
|
|
61
|
+
export { ElysiaLogo };
|
|
62
|
+
//# sourceMappingURL=Elysia.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Elysia.mjs","names":[],"sources":["../../../../../src/components/TechLogo/logos/Elysia.tsx"],"sourcesContent":["import type { FC, SVGProps } from 'react';\n\nexport const ElysiaLogo: FC<SVGProps<SVGSVGElement>> = (props) => (\n <svg\n shapeRendering=\"geometricPrecision\"\n textRendering=\"geometricPrecision\"\n imageRendering=\"optimizeQuality\"\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n role=\"img\"\n aria-label=\"Elysia logo\"\n width=\"512\"\n height=\"512\"\n viewBox=\"0 0 512 512\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M424.404 470.816C478.089 423.889 512 354.905 512 278C512 136.615 397.385 22 256 22C114.615 22 0 136.615 0 278C0 352.658 31.9583 419.851 82.9409 466.646L83.1767 465L419.144 355L424.404 470.816Z\"\n fill=\"#333333\"\n />\n <path\n d=\"M189.915 52.7412L144.5 46L151.303 43.9069C155.402 42.6455 159.248 40.6719 162.662 38.0765L163.73 37.2654C167.845 34.1375 171.12 30.0364 173.259 25.3304C174.414 22.7883 175.224 20.1027 175.665 17.3454L176.173 14.1698C176.72 10.7473 176.692 7.25741 176.09 3.84416C175.834 2.39429 177.279 1.23239 178.64 1.79296L180.498 2.55815C182.829 3.51798 185.084 4.65434 187.242 5.95732L194.965 10.6205C205.229 16.8174 214.226 24.9023 221.48 34.4477L226.616 41.2051C228.529 43.7228 230.783 45.9625 233.313 47.8599C236.088 49.9411 239.164 51.5874 242.435 52.7418L246 54L227.274 54.749C214.785 55.2486 202.278 54.5764 189.915 52.7412Z\"\n fill=\"#CCCCCC\"\n />\n <path\n d=\"M178.321 93.006L191.79 68.3844C191.922 68.143 191.93 67.8528 191.812 67.6042L187.22 57.9361C184.337 51.8673 178.219 48 171.5 48L170.23 47.9562C161.437 47.653 152.704 46.3829 144.188 44.169L142.504 43.731C135.521 41.9153 128.746 39.3732 122.293 36.1463L119.446 34.723C115.159 32.5797 111.099 30.012 107.325 27.0584L103.55 24.1043C102.428 23.2265 100.803 23.4506 99.9606 24.5992C97.3651 28.1384 95.7379 32.2935 95.2395 36.6541L94.5535 42.6571C94.1854 45.8774 94.1446 49.1267 94.4316 52.3552L96.1031 71.1595C97.3467 85.1501 102.175 98.584 110.123 110.165L111.825 112.645C114.267 116.203 117.113 119.466 120.306 122.369C120.756 122.778 121.329 123.03 121.936 123.084C145.029 125.156 167.194 113.348 178.321 93.006Z\"\n fill=\"#CCCCCC\"\n />\n <path\n d=\"M127.378 123.538L143.376 116.613C150.438 113.557 152.588 104.577 147.676 98.6533C143.683 93.8378 136.58 93.0803 131.661 96.9453L127.867 99.9256C126.958 100.64 126.127 101.448 125.387 102.336L116.263 113.284C114.982 114.822 115.084 117.084 116.5 118.5L119.318 121.721C119.77 122.237 120.296 122.685 120.878 123.049C122.833 124.271 125.263 124.453 127.378 123.538Z\"\n fill=\"#EDEDED\"\n />\n <path\n d=\"M147.988 44.8437L147.5 45L148.962 45.4651C155.294 47.4798 161.861 48.66 168.498 48.9761C168.83 48.9919 169.163 48.9534 169.483 48.8619L172.5 48L174 47.5L164.419 45.4172C163.158 45.1431 161.982 44.5687 160.991 43.7426C160.218 43.0981 160.223 41.9084 161.002 41.2708L162.423 40.1084C164.12 38.7197 165.493 36.976 166.444 35C160.934 39.3642 154.682 42.6988 147.988 44.8437Z\"\n fill=\"#B2B2B2\"\n />\n <path\n d=\"M202.776 219.428L72.2905 452.693C71.643 453.851 70.0687 454.069 69.1308 453.131L66.5 450.5L55.5 438L48.4888 428.927C41.8407 420.323 35.9052 411.192 30.7414 401.624L29.7434 399.775C24.2581 389.611 19.6635 378.991 16.0112 368.034L12.5 357.5C7.22519 338.379 6.01447 318.365 8.94583 298.747L9.06961 297.919C10.354 289.323 12.4034 280.86 15.1935 272.629L21 255.5L25.3334 246.385C32.0537 232.249 41.3193 219.472 52.6669 208.691L58.1719 203.462C69.5529 192.65 83.3937 184.769 98.5 180.5C94.967 181.498 91.3608 182.216 87.7149 182.647L80.5 183.5L75 184L69 185L63 185.561L59 186L56.1186 186.18C55.1927 186.238 54.7576 185.057 55.4998 184.5L55.5002 184.5L59.5273 182.57C72.5066 176.351 83.1766 166.172 90 153.5L94.4475 146.562C99.7511 138.288 106.807 131.28 115.116 126.032L116.833 124.948C119.935 122.989 123.246 121.384 126.705 120.163L142.446 114.607C145.348 113.583 147.69 111.39 148.903 108.561L149.143 108C149.705 106.687 149.932 105.255 149.803 103.833C149.608 101.689 148.616 99.6966 147.023 98.2485L144.256 95.7328C144.086 95.5779 143.93 95.4073 143.792 95.2232L126 71.5L111.803 51.9315C108.994 48.0592 107.359 43.4599 107.094 38.6832C107.051 37.9263 107.836 37.4015 108.52 37.7295L123.881 45.1028C137.174 51.4834 152.33 52.825 166.537 48.8786C169.84 47.9612 173.214 47.3242 176.624 46.9745L183.675 46.2513C201.406 44.4328 219.32 45.9054 236.516 50.5953L238 51L254.798 57.0472C275.869 64.6329 292.567 81.0571 300.5 102L304.022 115.734C305.004 119.567 306.392 123.285 308.162 126.824C312.321 135.142 318.495 142.289 326.121 147.613L335.084 153.87C339.023 156.62 343.157 159.078 347.453 161.227L367.289 171.145C368.178 171.589 368.444 172.732 367.843 173.523C362.372 180.721 355.148 186.395 346.859 190.005L335.371 195.008C330.797 197 326.081 198.65 321.262 199.945L312.822 202.212C300.992 205.39 288.796 207 276.546 207H256.333C252.148 207 248.001 206.213 244.108 204.679C228.581 198.562 210.923 204.863 202.776 219.428Z\"\n fill=\"white\"\n />\n <path\n d=\"M271.185 135.316L279.987 135.418C281.182 135.432 281.452 133.748 280.312 133.388C278.441 132.797 276.623 132.048 274.879 131.15L268.008 127.61C263.35 125.211 258.969 122.308 254.944 118.953L253.592 117.827C250.54 115.283 247.77 112.418 245.33 109.282L243.768 107.273C243.234 106.586 242.134 107.005 242.192 107.873C243.212 123.186 255.839 135.138 271.185 135.316Z\"\n fill=\"#666666\"\n />\n <path\n d=\"M82.2231 456.395L231.313 323.4C245.367 310.863 257.58 296.403 267.59 280.45L268.5 279C273.404 269.192 275.497 258.217 274.547 247.293L273.24 232.258C272.436 223.009 268.618 214.28 262.373 207.41C262.131 207.144 261.81 206.961 261.457 206.889L237.5 202C220.117 196.752 201.688 195.995 183.933 199.8L183 200L169.06 203.259C128.405 212.763 92.5742 236.685 68.2116 270.592L67.597 271.447C60.8846 280.789 55.1822 290.817 50.5856 301.362L49.765 303.245C38.1544 329.881 34.2409 359.238 38.4684 387.985L39.8511 397.387C41.2751 407.07 44.1931 416.474 48.5011 425.262C52.4798 433.379 57.6014 440.883 63.7095 447.547L71.3177 455.847C74.1911 458.981 79.0498 459.225 82.2231 456.395Z\"\n fill=\"#CCCCCC\"\n />\n <path\n d=\"M212.749 278.858L212.267 279.133C199.686 286.322 192.918 299.892 193.58 314.367C193.768 318.484 197.893 322.255 201.858 321.132L209.163 319.062C218.607 316.386 227.353 311.681 234.789 305.274L256 287L262.292 282.343C298.871 255.269 344.833 244.113 389.754 251.405C391.14 251.63 391.184 253.607 389.81 253.894L384.5 255L382.093 255.842C377.15 257.572 372.856 260.776 369.79 265.022C369.214 265.819 369.982 266.89 370.922 266.601L372.663 266.065C382.467 263.049 392.751 261.904 402.978 262.691L407 263C428.843 263.95 449.114 274.626 462.254 292.1L467.179 298.65C481.776 318.063 487.953 342.53 484.319 366.545L482.421 379.087C479.837 396.163 473.618 412.486 464.184 426.952L463.5 428L453 442L441.5 455L430.965 465.114C421.346 474.348 410.827 482.597 399.567 489.738L396 492L389.175 495.25C387.417 496.087 385.95 493.678 387.5 492.5L397 483.5L398.953 481.449C404.232 475.906 408.027 469.12 409.986 461.721L410.889 458.309C411.295 456.776 411.5 455.174 411.5 453.588C411.5 444.909 405.354 437.298 396.836 435.631C391.554 434.597 386.085 435.962 381.907 439.356L372.5 447L355.894 460.587C344.995 469.504 333.185 477.245 320.66 483.682L303.5 492.5L274.5 503.5L268.412 505.16C257.822 508.049 247.012 510.06 236.092 511.174L228 512H202L167.5 508.25L148.832 504.21C138.985 502.079 129.456 498.682 120.482 494.103C113.181 490.378 106.293 485.894 99.931 480.725L85.5 469C68.005 455.64 57.0449 435.448 55.3749 413.498L54.5 402L55.5295 385.822C57.134 360.608 66.7911 336.576 83.0792 317.263C89.6652 309.454 97.2376 302.534 105.606 296.675L108.677 294.526C121.458 285.579 135.72 278.961 150.805 274.976L160.947 272.297C174.135 268.813 187.952 268.445 201.307 271.22L211.887 273.418C214.542 273.97 215.103 277.513 212.749 278.858Z\"\n fill=\"#5E5E5E\"\n />\n </svg>\n);\n"],"mappings":";;;AAEA,MAAa,cAA2C,UACtD,qBAAC,OAAD;CACE,gBAAe;CACf,eAAc;CACd,gBAAe;CACf,UAAS;CACT,UAAS;CACT,MAAK;CACL,cAAW;CACX,OAAM;CACN,QAAO;CACP,SAAQ;CACR,MAAK;CACL,OAAM;CACN,GAAI;WAbN;EAeE,oBAAC,QAAD;GACE,UAAS;GACT,UAAS;GACT,GAAE;GACF,MAAK;EACN;EACD,oBAAC,QAAD;GACE,GAAE;GACF,MAAK;EACN;EACD,oBAAC,QAAD;GACE,GAAE;GACF,MAAK;EACN;EACD,oBAAC,QAAD;GACE,GAAE;GACF,MAAK;EACN;EACD,oBAAC,QAAD;GACE,GAAE;GACF,MAAK;EACN;EACD,oBAAC,QAAD;GACE,GAAE;GACF,MAAK;EACN;EACD,oBAAC,QAAD;GACE,GAAE;GACF,MAAK;EACN;EACD,oBAAC,QAAD;GACE,GAAE;GACF,MAAK;EACN;EACD,oBAAC,QAAD;GACE,GAAE;GACF,MAAK;EACN;CACE"}
|
|
@@ -12,6 +12,7 @@ import { AtlassianLogo } from "./logos/Atlassian.mjs";
|
|
|
12
12
|
import { ChatGPTLogo } from "./logos/ChatGPT.mjs";
|
|
13
13
|
import { ClaudeLogo } from "./logos/Claude.mjs";
|
|
14
14
|
import { DeepSeekLogo } from "./logos/DeepSeek.mjs";
|
|
15
|
+
import { ElysiaLogo } from "./logos/Elysia.mjs";
|
|
15
16
|
import { ExpressLogo } from "./logos/Express.mjs";
|
|
16
17
|
import { FastifyLogo } from "./logos/Fastify.mjs";
|
|
17
18
|
import { GeminiLogo } from "./logos/Gemini.mjs";
|
|
@@ -49,6 +50,7 @@ var techLogos_exports = /* @__PURE__ */ __exportAll({
|
|
|
49
50
|
CHATGPT: () => ChatGPTLogo,
|
|
50
51
|
CLAUDE: () => ClaudeLogo,
|
|
51
52
|
DEEPSEEK: () => DeepSeekLogo,
|
|
53
|
+
ELYSIA: () => ElysiaLogo,
|
|
52
54
|
EXPRESS: () => ExpressLogo,
|
|
53
55
|
FASTIFY: () => FastifyLogo,
|
|
54
56
|
GEMINI: () => GeminiLogo,
|
|
@@ -81,5 +83,5 @@ var techLogos_exports = /* @__PURE__ */ __exportAll({
|
|
|
81
83
|
});
|
|
82
84
|
|
|
83
85
|
//#endregion
|
|
84
|
-
export { AdonisLogo as ADONIS, AngularLogo as ANGULAR, AnthropicLogo as ANTHROPIC, AstroLogo as ASTRO, AtlassianLogo as ATLASSIAN, BitbucketLogo as BITBUCKET, ChatGPTLogo as CHATGPT, ClaudeLogo as CLAUDE, DeepSeekLogo as DEEPSEEK, ExpressLogo as EXPRESS, FastifyLogo as FASTIFY, GeminiLogo as GEMINI, GitHubLogo as GITHUB, GitLabLogo as GITLAB, GoogleLogo as GOOGLE, GoogleAILogo as GOOGLE_AI, GrokLogo as GROK, HonoLogo as HONO, LinkedInLogo as LINKEDIN, LitLogo as LIT, LynxLogo as LYNX, MicrosoftLogo as MICROSOFT, MistralLogo as MISTRAL, NestJSLogo as NESTJS, NextJSLogo as NEXTJS, NodejsLogo as NODE, NuxtLogo as NUXT, OllamaLogo as OLLAMA, OpenAILogo as OPENAI, PerplexityLogo as PERPLEXITY, PreactLogo as PREACT, ReactLogo as REACT, SolidLogo as SOLID, SvelteLogo as SVELTE, TanstackLogo as TANSTACK, JavaScriptLogo as VANILLA, ViteLogo as VITE, VuejsLogo as VUE, techLogos_exports };
|
|
86
|
+
export { AdonisLogo as ADONIS, AngularLogo as ANGULAR, AnthropicLogo as ANTHROPIC, AstroLogo as ASTRO, AtlassianLogo as ATLASSIAN, BitbucketLogo as BITBUCKET, ChatGPTLogo as CHATGPT, ClaudeLogo as CLAUDE, DeepSeekLogo as DEEPSEEK, ElysiaLogo as ELYSIA, ExpressLogo as EXPRESS, FastifyLogo as FASTIFY, GeminiLogo as GEMINI, GitHubLogo as GITHUB, GitLabLogo as GITLAB, GoogleLogo as GOOGLE, GoogleAILogo as GOOGLE_AI, GrokLogo as GROK, HonoLogo as HONO, LinkedInLogo as LINKEDIN, LitLogo as LIT, LynxLogo as LYNX, MicrosoftLogo as MICROSOFT, MistralLogo as MISTRAL, NestJSLogo as NESTJS, NextJSLogo as NEXTJS, NodejsLogo as NODE, NuxtLogo as NUXT, OllamaLogo as OLLAMA, OpenAILogo as OPENAI, PerplexityLogo as PERPLEXITY, PreactLogo as PREACT, ReactLogo as REACT, SolidLogo as SOLID, SvelteLogo as SVELTE, TanstackLogo as TANSTACK, JavaScriptLogo as VANILLA, ViteLogo as VITE, VuejsLogo as VUE, techLogos_exports };
|
|
85
87
|
//# sourceMappingURL=techLogos.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"techLogos.mjs","names":[],"sources":["../../../../src/components/TechLogo/techLogos.ts"],"sourcesContent":["export { AdonisLogo as ADONIS } from './logos/Adonis';\nexport { AngularLogo as ANGULAR } from './logos/Angular';\nexport { AnthropicLogo as ANTHROPIC } from './logos/Anthropic';\nexport { AstroLogo as ASTRO } from './logos/Astro';\nexport { AtlassianLogo as ATLASSIAN } from './logos/Atlassian';\nexport { BitbucketLogo as BITBUCKET } from './logos/Bitbucket';\nexport { ChatGPTLogo as CHATGPT } from './logos/ChatGPT';\nexport { ClaudeLogo as CLAUDE } from './logos/Claude';\nexport { DeepSeekLogo as DEEPSEEK } from './logos/DeepSeek';\nexport { ExpressLogo as EXPRESS } from './logos/Express';\nexport { FastifyLogo as FASTIFY } from './logos/Fastify';\nexport { GeminiLogo as GEMINI } from './logos/Gemini';\nexport { GitHubLogo as GITHUB } from './logos/GitHub';\nexport { GitLabLogo as GITLAB } from './logos/GitLab';\nexport { GoogleLogo as GOOGLE } from './logos/Google';\nexport { GoogleAILogo as GOOGLE_AI } from './logos/GoogleAI';\nexport { GrokLogo as GROK } from './logos/Grok';\nexport { HonoLogo as HONO } from './logos/Hono';\nexport { LinkedInLogo as LINKEDIN } from './logos/LinkedIn';\nexport { LitLogo as LIT } from './logos/Lit';\nexport { LynxLogo as LYNX } from './logos/Lynx';\nexport { MicrosoftLogo as MICROSOFT } from './logos/Microsoft';\nexport { MistralLogo as MISTRAL } from './logos/Mistral';\nexport { NestJSLogo as NESTJS } from './logos/NestJS';\nexport { NextJSLogo as NEXTJS } from './logos/Nextjs';\nexport { NodejsLogo as NODE } from './logos/Node';\nexport { NuxtLogo as NUXT } from './logos/Nuxt';\nexport { OllamaLogo as OLLAMA } from './logos/Ollama';\nexport { OpenAILogo as OPENAI } from './logos/OpenAI';\nexport { PerplexityLogo as PERPLEXITY } from './logos/Perplexity';\nexport { PreactLogo as PREACT } from './logos/Preact';\nexport { ReactLogo as REACT } from './logos/Reactjs';\nexport { SolidLogo as SOLID } from './logos/Solid';\nexport { SvelteLogo as SVELTE } from './logos/Svelte';\nexport { TanstackLogo as TANSTACK } from './logos/Tanstack';\nexport { JavaScriptLogo as VANILLA } from './logos/Vanilla';\nexport { ViteLogo as VITE } from './logos/Vitejs';\nexport { VuejsLogo as VUE } from './logos/Vuejs';\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"techLogos.mjs","names":[],"sources":["../../../../src/components/TechLogo/techLogos.ts"],"sourcesContent":["export { AdonisLogo as ADONIS } from './logos/Adonis';\nexport { AngularLogo as ANGULAR } from './logos/Angular';\nexport { AnthropicLogo as ANTHROPIC } from './logos/Anthropic';\nexport { AstroLogo as ASTRO } from './logos/Astro';\nexport { AtlassianLogo as ATLASSIAN } from './logos/Atlassian';\nexport { BitbucketLogo as BITBUCKET } from './logos/Bitbucket';\nexport { ChatGPTLogo as CHATGPT } from './logos/ChatGPT';\nexport { ClaudeLogo as CLAUDE } from './logos/Claude';\nexport { DeepSeekLogo as DEEPSEEK } from './logos/DeepSeek';\nexport { ElysiaLogo as ELYSIA } from './logos/Elysia';\nexport { ExpressLogo as EXPRESS } from './logos/Express';\nexport { FastifyLogo as FASTIFY } from './logos/Fastify';\nexport { GeminiLogo as GEMINI } from './logos/Gemini';\nexport { GitHubLogo as GITHUB } from './logos/GitHub';\nexport { GitLabLogo as GITLAB } from './logos/GitLab';\nexport { GoogleLogo as GOOGLE } from './logos/Google';\nexport { GoogleAILogo as GOOGLE_AI } from './logos/GoogleAI';\nexport { GrokLogo as GROK } from './logos/Grok';\nexport { HonoLogo as HONO } from './logos/Hono';\nexport { LinkedInLogo as LINKEDIN } from './logos/LinkedIn';\nexport { LitLogo as LIT } from './logos/Lit';\nexport { LynxLogo as LYNX } from './logos/Lynx';\nexport { MicrosoftLogo as MICROSOFT } from './logos/Microsoft';\nexport { MistralLogo as MISTRAL } from './logos/Mistral';\nexport { NestJSLogo as NESTJS } from './logos/NestJS';\nexport { NextJSLogo as NEXTJS } from './logos/Nextjs';\nexport { NodejsLogo as NODE } from './logos/Node';\nexport { NuxtLogo as NUXT } from './logos/Nuxt';\nexport { OllamaLogo as OLLAMA } from './logos/Ollama';\nexport { OpenAILogo as OPENAI } from './logos/OpenAI';\nexport { PerplexityLogo as PERPLEXITY } from './logos/Perplexity';\nexport { PreactLogo as PREACT } from './logos/Preact';\nexport { ReactLogo as REACT } from './logos/Reactjs';\nexport { SolidLogo as SOLID } from './logos/Solid';\nexport { SvelteLogo as SVELTE } from './logos/Svelte';\nexport { TanstackLogo as TANSTACK } from './logos/Tanstack';\nexport { JavaScriptLogo as VANILLA } from './logos/Vanilla';\nexport { ViteLogo as VITE } from './logos/Vitejs';\nexport { VuejsLogo as VUE } from './logos/Vuejs';\n"],"mappings":""}
|
|
@@ -131,7 +131,7 @@ import { DotPattern } from "./Pattern/DotPattern.mjs";
|
|
|
131
131
|
import { GridDistortionPattern } from "./Pattern/GridDistortionPattern.mjs";
|
|
132
132
|
import { GridPattern } from "./Pattern/GridPattern.mjs";
|
|
133
133
|
import { Spotlight } from "./Pattern/SpotLight.mjs";
|
|
134
|
-
import { drawerManager, useRightDrawer } from "./RightDrawer/useRightDrawer.mjs";
|
|
134
|
+
import { drawerManager, useIsRightDrawerOpen, useRightDrawer, useRightDrawerActions } from "./RightDrawer/useRightDrawer.mjs";
|
|
135
135
|
import { RightDrawer } from "./RightDrawer/RightDrawer.mjs";
|
|
136
136
|
import { Step, Steps } from "./Steps/index.mjs";
|
|
137
137
|
import { Tag } from "./Tag/index.mjs";
|
|
@@ -141,4 +141,4 @@ import { Terminal } from "./Terminal/Terminal.mjs";
|
|
|
141
141
|
import { DesktopThemeSwitcher } from "./ThemeSwitcherDropDown/DesktopThemeSwitcher.mjs";
|
|
142
142
|
import { MobileThemeSwitcher } from "./ThemeSwitcherDropDown/MobileThemeSwitcher.mjs";
|
|
143
143
|
|
|
144
|
-
export { Accordion, AutoCompleteTextarea, AutoSizedTextArea, Avatar, Badge, BitbucketLogo, Breadcrumb, Browser, Burger, Button, Carousel, Checkbox, ClickOutsideDiv, Code, CodeBlock, CodeDefault, CodeHighlighted, CollapsibleTable, Command, CommandRoot, Container, ContentEditableTextArea, ContentEditorInput, ContentEditorTextArea, ContentSelector, CopyButton, CopyToClipboard, DesktopNavbar, DesktopThemeSwitcher, Detail, DictionaryCreationForm, DictionaryEditor, DictionaryFieldEditor, DiscordLogo, DotPattern, DropDown, EditableFieldInput, EditableFieldTextArea, ExpandCollapse, FacebookLogo, FileList, Flag, flags_exports as Flags, Footer, Form, AutoSizedTextAreaElement as FormAutoSizedTextArea, Button as FormButton, CheckboxElement as FormCheckbox, FormControl, FormDescription, EditableFieldInputElement as FormEditableFieldInput, EditableFieldTextAreaElement as FormEditableFieldTextArea, FormElement, FormField, InputElement as FormInput, InputPasswordElement as FormInputPassword, FormItem, FormLabelLayout as FormLabel, FormMessage, MultiSelectElement as FormMultiSelect, OTPElement as FormOTP, SearchInputElement as FormSearchInput, SelectElement as FormSelect, SwitchSelectorElement as FormSwitchSelector, TextAreaElement as FormTextArea, GitHubLogo, GitLabLogo, GoogleLogo, GridDistortionPattern, GridPattern, H1, H2, H3, H4, H5, H6, HTMLRenderer, HeightResizer, HideShow, Hr, IDE, InformationTag, Input, InputIndicator, InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot, InputPassword, InstagramLogo, KeyPathBreadcrumb, KeyboardScreenAdapter, KeyboardShortcut, Label, LanguageBackground, LanguageSection, Link, LinkedInLogo, Loader, LocaleSwitcher, LocaleSwitcherContent, LocaleSwitcherContentProvider, Logo, LogoTextOnly, LogoWithText, LogoWithTextBelow, MarkDownIframe, MarkdownEditor, MarkdownRenderer, MaxHeightSmoother, MaxWidthSmoother, MobileNavbar, MobileThemeSwitcher, Modal, MultiSelect, Navbar, NumberItemsSelector, OTPInput, OTPInputContext, Pagination, Popover, PopoverStatic, PressableSpan, ProductHuntLogo, Radio, RightDrawer, SaveForm, SearchInput, Select, SelectContent, SelectLabel, SelectSeparator, ShowingResultsNumberItems, SmartTable, SocialNetworks, Spotlight, Step, Steps, SwitchSelector, Tab, TabSelector, Table, Tag, Td, TechLogo, techLogos_exports as TechLogos, Terminal, TextArea, TextEditor, TextEditorContainer, Th, TiktokLogo, Toast, ToastAction, ToastClose, ToastDescription, ToastProvider, ToastTitle, ToastViewport, Toaster, Tr, VersionSwitcher, VersionSwitcherProvider, VerticalSwitchSelector, WithResizer, XLogo, YoutubeLogo, badgeVariants, baseMarkdownComponents, buttonVariants, checkIsExternalLink, checkboxVariants, choiceVariant, containerVariants, createEditorUploadFn, defaultChoices, drawerManager, getCapitals, getIntlayerHTMLOptions, getIntlayerMarkdownOptions, indicatorVariant, inputSlotVariants, inputVariants, isTextChildren, linkVariants, paginationVariants, radioVariants, reducer, shikiWrapperClassName, switchSelectorVariant, toast, toastVariants, traceKeys, useContentEditable, useCopyToClipboard, useForm, useFormField, useLocaleSwitcherContent, usePasswordManagerBadge, usePopoverIds, usePrevious, useRightDrawer, useToast, useVersionSwitcher };
|
|
144
|
+
export { Accordion, AutoCompleteTextarea, AutoSizedTextArea, Avatar, Badge, BitbucketLogo, Breadcrumb, Browser, Burger, Button, Carousel, Checkbox, ClickOutsideDiv, Code, CodeBlock, CodeDefault, CodeHighlighted, CollapsibleTable, Command, CommandRoot, Container, ContentEditableTextArea, ContentEditorInput, ContentEditorTextArea, ContentSelector, CopyButton, CopyToClipboard, DesktopNavbar, DesktopThemeSwitcher, Detail, DictionaryCreationForm, DictionaryEditor, DictionaryFieldEditor, DiscordLogo, DotPattern, DropDown, EditableFieldInput, EditableFieldTextArea, ExpandCollapse, FacebookLogo, FileList, Flag, flags_exports as Flags, Footer, Form, AutoSizedTextAreaElement as FormAutoSizedTextArea, Button as FormButton, CheckboxElement as FormCheckbox, FormControl, FormDescription, EditableFieldInputElement as FormEditableFieldInput, EditableFieldTextAreaElement as FormEditableFieldTextArea, FormElement, FormField, InputElement as FormInput, InputPasswordElement as FormInputPassword, FormItem, FormLabelLayout as FormLabel, FormMessage, MultiSelectElement as FormMultiSelect, OTPElement as FormOTP, SearchInputElement as FormSearchInput, SelectElement as FormSelect, SwitchSelectorElement as FormSwitchSelector, TextAreaElement as FormTextArea, GitHubLogo, GitLabLogo, GoogleLogo, GridDistortionPattern, GridPattern, H1, H2, H3, H4, H5, H6, HTMLRenderer, HeightResizer, HideShow, Hr, IDE, InformationTag, Input, InputIndicator, InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot, InputPassword, InstagramLogo, KeyPathBreadcrumb, KeyboardScreenAdapter, KeyboardShortcut, Label, LanguageBackground, LanguageSection, Link, LinkedInLogo, Loader, LocaleSwitcher, LocaleSwitcherContent, LocaleSwitcherContentProvider, Logo, LogoTextOnly, LogoWithText, LogoWithTextBelow, MarkDownIframe, MarkdownEditor, MarkdownRenderer, MaxHeightSmoother, MaxWidthSmoother, MobileNavbar, MobileThemeSwitcher, Modal, MultiSelect, Navbar, NumberItemsSelector, OTPInput, OTPInputContext, Pagination, Popover, PopoverStatic, PressableSpan, ProductHuntLogo, Radio, RightDrawer, SaveForm, SearchInput, Select, SelectContent, SelectLabel, SelectSeparator, ShowingResultsNumberItems, SmartTable, SocialNetworks, Spotlight, Step, Steps, SwitchSelector, Tab, TabSelector, Table, Tag, Td, TechLogo, techLogos_exports as TechLogos, Terminal, TextArea, TextEditor, TextEditorContainer, Th, TiktokLogo, Toast, ToastAction, ToastClose, ToastDescription, ToastProvider, ToastTitle, ToastViewport, Toaster, Tr, VersionSwitcher, VersionSwitcherProvider, VerticalSwitchSelector, WithResizer, XLogo, YoutubeLogo, badgeVariants, baseMarkdownComponents, buttonVariants, checkIsExternalLink, checkboxVariants, choiceVariant, containerVariants, createEditorUploadFn, defaultChoices, drawerManager, getCapitals, getIntlayerHTMLOptions, getIntlayerMarkdownOptions, indicatorVariant, inputSlotVariants, inputVariants, isTextChildren, linkVariants, paginationVariants, radioVariants, reducer, shikiWrapperClassName, switchSelectorVariant, toast, toastVariants, traceKeys, useContentEditable, useCopyToClipboard, useForm, useFormField, useIsRightDrawerOpen, useLocaleSwitcherContent, usePasswordManagerBadge, usePopoverIds, usePrevious, useRightDrawer, useRightDrawerActions, useToast, useVersionSwitcher };
|
|
@@ -1,29 +1,28 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import { useGetElementOrWindow } from "../useGetElementOrWindow.mjs";
|
|
4
|
-
import {
|
|
5
|
-
import { useEffect } from "react";
|
|
4
|
+
import { scrollBlockageManager } from "./useScrollBlockageStore.mjs";
|
|
5
|
+
import { useCallback, useEffect, useSyncExternalStore } from "react";
|
|
6
6
|
|
|
7
7
|
//#region src/hooks/useScrollBlockage/index.tsx
|
|
8
|
+
const getServerSnapshot = () => false;
|
|
8
9
|
const useScrollBlockage = (props) => {
|
|
9
10
|
const { disableScroll = false, element, key = "unnamed_blocker" } = props ?? {};
|
|
10
|
-
const { isElementScrollBlocked, addBlockage, removeBlockage } = useScrollBlockageStore();
|
|
11
11
|
const containerElement = useGetElementOrWindow(element);
|
|
12
12
|
useEffect(() => {
|
|
13
13
|
const el = element ?? window.document.body;
|
|
14
|
-
if (disableScroll) addBlockage(key, el);
|
|
15
|
-
else removeBlockage(key, el);
|
|
14
|
+
if (disableScroll) scrollBlockageManager.addBlockage(key, el);
|
|
15
|
+
else scrollBlockageManager.removeBlockage(key, el);
|
|
16
16
|
return () => {
|
|
17
|
-
removeBlockage(key, el);
|
|
17
|
+
scrollBlockageManager.removeBlockage(key, el);
|
|
18
18
|
};
|
|
19
19
|
}, [
|
|
20
|
-
addBlockage,
|
|
21
20
|
disableScroll,
|
|
22
21
|
element,
|
|
23
|
-
key
|
|
24
|
-
removeBlockage
|
|
22
|
+
key
|
|
25
23
|
]);
|
|
26
|
-
|
|
24
|
+
const getIsScrollBlocked = useCallback(() => containerElement ? scrollBlockageManager.isElementScrollBlocked(containerElement) : false, [containerElement]);
|
|
25
|
+
return { isScrollBlocked: useSyncExternalStore(scrollBlockageManager.subscribe, getIsScrollBlocked, getServerSnapshot) };
|
|
27
26
|
};
|
|
28
27
|
|
|
29
28
|
//#endregion
|