diff --git a/apps/client/package.json b/apps/client/package.json index 2ae7b96d0..f788953c3 100644 --- a/apps/client/package.json +++ b/apps/client/package.json @@ -5,13 +5,10 @@ "type": "module", "dependencies": { "@base-ui-components/react": "1.0.0-beta.1", - "@chakra-ui/react": "^2.7.0", "@dnd-kit/core": "^6.3.1", "@dnd-kit/sortable": "^10.0.0", "@dnd-kit/utilities": "^3.2.2", "@emotion/is-prop-valid": "^1.3.1", - "@emotion/react": "^11.10.6", - "@emotion/styled": "^11.10.6", "@fontsource/open-sans": "^5.0.28", "@mantine/hooks": "^8.1.2", "@sentry/react": "^8.43.0", @@ -22,7 +19,6 @@ "autosize": "^6.0.1", "axios": "^1.9.0", "csv-stringify": "^6.4.5", - "framer-motion": "^10.10.0", "prismjs": "^1.29.0", "react": "^18.3.1", "react-colorful": "^5.6.1", @@ -80,7 +76,6 @@ "eslint-plugin-react-compiler": "19.1.0-rc.2", "eslint-plugin-react-hooks": "^4.6.0", "eslint-plugin-simple-import-sort": "^8.0.0", - "happy-dom": "^16.7.2", "ontime-types": "workspace:*", "ontime-utils": "workspace:*", "prettier": "catalog:", diff --git a/apps/client/src/App.tsx b/apps/client/src/App.tsx index 81e140fe5..d63dd0a13 100644 --- a/apps/client/src/App.tsx +++ b/apps/client/src/App.tsx @@ -1,6 +1,5 @@ import { BrowserRouter } from 'react-router-dom'; import { Tooltip } from '@base-ui-components/react/tooltip'; -import { ChakraProvider } from '@chakra-ui/react'; import { QueryClientProvider } from '@tanstack/react-query'; import { ReactQueryDevtools } from '@tanstack/react-query-devtools'; @@ -9,7 +8,6 @@ import IdentifyOverlay from './common/components/identify-overlay/IdentifyOverla import { AppContextProvider } from './common/context/AppContext'; import { ontimeQueryClient } from './common/queryClient'; import { connectSocket } from './common/utils/socket'; -import theme from './theme/theme'; import { TranslationProvider } from './translation/TranslationProvider'; import AppRouter from './AppRouter'; import { baseURI } from './externals'; @@ -18,28 +16,26 @@ connectSocket(); function App() { return ( - - - - - -
- - - - - - - -
+ + + + +
-
+ + + + - - - - - + +
+ +
+ + + + + ); } diff --git a/apps/client/src/common/components/context-menu/ContextMenu.module.scss b/apps/client/src/common/components/context-menu/ContextMenu.module.scss deleted file mode 100644 index da0e345a0..000000000 --- a/apps/client/src/common/components/context-menu/ContextMenu.module.scss +++ /dev/null @@ -1,8 +0,0 @@ -.contextMenuButton { - position: absolute; -} - -.contextMenuBackdrop { - position: fixed; - inset: 0; -} diff --git a/apps/client/src/common/components/context-menu/ContextMenu.tsx b/apps/client/src/common/components/context-menu/ContextMenu.tsx deleted file mode 100644 index 331532ee4..000000000 --- a/apps/client/src/common/components/context-menu/ContextMenu.tsx +++ /dev/null @@ -1,99 +0,0 @@ -// logic (with some modifications) culled from: -// https://github.com/lukasbach/chakra-ui-contextmenu/blob/main/src/ContextMenu.tsx - -import { ReactElement } from 'react'; -import { IconType } from 'react-icons'; -import { Menu, MenuButton, MenuGroup, MenuList } from '@chakra-ui/react'; -import { create } from 'zustand'; - -import { ContextMenuOption } from './ContextMenuOption'; - -import style from './ContextMenu.module.scss'; - -type ContextMenuCoords = { - x: number; - y: number; -}; - -export type OptionWithoutGroup = { - label: string; - isDisabled?: boolean; - icon: IconType; - onClick: () => void; - withDivider?: boolean; -}; - -type OptionWithGroup = { - label: string; - group: Omit[]; -}; - -export type Option = OptionWithoutGroup | OptionWithGroup; - -const isOptionWithGroup = (option: Option): option is OptionWithGroup => 'group' in option; - -type ContextMenuStore = { - coords: ContextMenuCoords; - options: Option[]; - isOpen: boolean; - setContextMenu: (coords: ContextMenuCoords, options: Option[]) => void; - setIsOpen: (newIsOpen: boolean) => void; -}; - -export const useContextMenuStore = create((set) => ({ - coords: { x: 0, y: 0 }, - options: [], - isOpen: false, - setContextMenu: (coords, options) => set(() => ({ coords, options, isOpen: true })), - setIsOpen: (newIsOpen) => set(() => ({ isOpen: newIsOpen })), -})); - -interface ContextMenuProps { - // ReactElement type required due to early `return` (line 51) returning {children} - children: ReactElement; -} - -export const ContextMenu = ({ children }: ContextMenuProps) => { - const { coords, options, isOpen, setIsOpen } = useContextMenuStore(); - - const onClose = () => { - return setIsOpen(false); - }; - - if (!isOpen) { - return children; - } - - return ( - <> - {children} -
- - - - {options.map((option) => - isOptionWithGroup(option) ? ( - - {option.group.map((groupOption) => ( - - ))} - - ) : ( - - ), - )} - - - - ); -}; diff --git a/apps/client/src/common/components/context-menu/ContextMenuOption.tsx b/apps/client/src/common/components/context-menu/ContextMenuOption.tsx deleted file mode 100644 index 0518e2ebf..000000000 --- a/apps/client/src/common/components/context-menu/ContextMenuOption.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import { MenuDivider, MenuItem } from '@chakra-ui/react'; - -import { OptionWithoutGroup } from './ContextMenu'; - -export const ContextMenuOption = ({ label, onClick, isDisabled, icon: Icon, withDivider }: OptionWithoutGroup) => ( - <> - {withDivider && } - } onClick={onClick} isDisabled={isDisabled}> - {label} - - -); diff --git a/apps/client/src/common/components/copy-tag/CopyTag.module.scss b/apps/client/src/common/components/copy-tag/CopyTag.module.scss new file mode 100644 index 000000000..ef4d711f3 --- /dev/null +++ b/apps/client/src/common/components/copy-tag/CopyTag.module.scss @@ -0,0 +1,40 @@ +.copytag { + display: flex; + align-items: center; +} + +.action { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} + +.label { + border-radius: 3px 0 0 3px; + border: 1px solid $gray-1200; + background-color: $white-3; + padding-inline: 0.5rem 1rem; + line-height: 1em; + display: flex; + align-items: center; + color: $label-gray; +} + +.small { + height: 1.5rem; + font-size: calc(1rem - 3px); +} + +.medium { + height: 2rem; + font-size: calc(1rem - 2px); +} + +.large { + height: 2.5rem; + font-weight: 600; +} + +.copy { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} diff --git a/apps/client/src/common/components/copy-tag/CopyTag.tsx b/apps/client/src/common/components/copy-tag/CopyTag.tsx index 308041bfb..9b9ab9957 100644 --- a/apps/client/src/common/components/copy-tag/CopyTag.tsx +++ b/apps/client/src/common/components/copy-tag/CopyTag.tsx @@ -1,22 +1,28 @@ import { PropsWithChildren, useState } from 'react'; import { IoCheckmark } from 'react-icons/io5'; import { IoCopy } from 'react-icons/io5'; -import { Button, ButtonGroup, IconButton, Tooltip } from '@chakra-ui/react'; -import { tooltipDelayFast } from '../../../ontimeConfig'; -import { Size } from '../../models/Util.type'; import copyToClipboard from '../../utils/copyToClipboard'; +import { cx } from '../../utils/styleUtils'; +import Button from '../buttons/Button'; +import IconButton from '../buttons/IconButton'; + +import style from './CopyTag.module.scss'; interface CopyTagProps { copyValue: string; - label: string; - size?: Size; disabled?: boolean; onClick?: () => void; + size?: 'small' | 'medium' | 'large'; } -export default function CopyTag(props: PropsWithChildren) { - const { copyValue, label, size = 'xs', disabled, children, onClick } = props; +export default function CopyTag({ + copyValue, + disabled, + size = 'medium', + children, + onClick, +}: PropsWithChildren) { const [copied, setCopied] = useState(false); const handleClick = () => { @@ -28,20 +34,24 @@ export default function CopyTag(props: PropsWithChildren) { }; return ( - - - - : } - variant='ontime-filled' - tabIndex={-1} - onClick={handleClick} - isDisabled={disabled} - /> - - + ) : ( +
{children}
+ )} + + {copied ? : } + +
); } diff --git a/apps/client/src/common/components/dialog/Dialog.module.scss b/apps/client/src/common/components/dialog/Dialog.module.scss index 8eab95871..a8370909e 100644 --- a/apps/client/src/common/components/dialog/Dialog.module.scss +++ b/apps/client/src/common/components/dialog/Dialog.module.scss @@ -3,7 +3,6 @@ top: 10%; left: 50%; - z-index: $zindex-dialog; transform: translateX(-50%); padding-inline: 1rem; @@ -19,7 +18,6 @@ .backdrop { position: fixed; inset: 0; - z-index: $zindex-backdrop; background-color: $backdrop-color; transition: opacity 300ms cubic-bezier(0.45, 1.005, 0, 1.005); diff --git a/apps/client/src/common/components/dropdown-menu/DropdownMenu.tsx b/apps/client/src/common/components/dropdown-menu/DropdownMenu.tsx index b7f2a4e12..9181871fd 100644 --- a/apps/client/src/common/components/dropdown-menu/DropdownMenu.tsx +++ b/apps/client/src/common/components/dropdown-menu/DropdownMenu.tsx @@ -1,4 +1,5 @@ -import { PropsWithChildren, ReactNode } from 'react'; +import { PropsWithChildren } from 'react'; +import { IconType } from 'react-icons'; import { Menu as BaseMenu } from '@base-ui-components/react/menu'; import style from './DropdownMenu.module.scss'; @@ -7,13 +8,15 @@ type DropdownMenuItemDivider = { type: 'divider' }; type DropdownMenuItem = { type: 'item'; label: string; - icon?: ReactNode; + icon?: IconType; disabled?: boolean; onClick: () => void; }; +export type DropdownMenuOption = DropdownMenuItemDivider | DropdownMenuItem; + interface DropdownMenuProps extends BaseMenu.Trigger.Props { - items: Array; + items: DropdownMenuOption[]; } export function DropdownMenu({ items, children, ...triggerProps }: PropsWithChildren) { @@ -29,7 +32,8 @@ export function DropdownMenu({ items, children, ...triggerProps }: PropsWithChil } return ( - {item.icon} {item.label} + {item.icon && } + {item.label} ); })} @@ -55,12 +59,9 @@ export function PositionedDropdownMenu({ items, isOpen, position, onClose }: Pos if (!open) onClose(); }} > - + - + {items.map((item, index) => { if (item.type === 'divider') { @@ -68,7 +69,8 @@ export function PositionedDropdownMenu({ items, isOpen, position, onClose }: Pos } return ( - {item.icon} {item.label} + {item.icon && } + {item.label} ); })} diff --git a/apps/client/src/common/components/identify-overlay/IdentifyOverlay.module.scss b/apps/client/src/common/components/identify-overlay/IdentifyOverlay.module.scss index e37204230..85f0f8938 100644 --- a/apps/client/src/common/components/identify-overlay/IdentifyOverlay.module.scss +++ b/apps/client/src/common/components/identify-overlay/IdentifyOverlay.module.scss @@ -15,7 +15,6 @@ display: grid; place-content: center; text-align: center; - z-index: $zindex-modal; cursor: pointer; } diff --git a/apps/client/src/common/components/input/auto-text-area/AutoTextArea.tsx b/apps/client/src/common/components/input/auto-text-area/AutoTextArea.tsx deleted file mode 100644 index 9fc23c8ed..000000000 --- a/apps/client/src/common/components/input/auto-text-area/AutoTextArea.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import { RefObject, useEffect } from 'react'; -import { Textarea, TextareaProps } from '@chakra-ui/react'; -// @ts-expect-error no types from library -import autosize from 'autosize/dist/autosize'; - -export const AutoTextArea = (props: TextareaProps & { inputref: RefObject }) => { - const { value, inputref } = props; - - useEffect(() => { - const node = inputref.current; - autosize(inputref.current); - return () => { - autosize.destroy(node); - }; - }, [inputref, value]); - - return ( -