[FIX] chakra ui component is not full
This commit is contained in:
parent
2812d21782
commit
91defa42c2
@ -25,7 +25,7 @@ import { environment } from '@/environment';
|
|||||||
import { App as SpaApp } from '@/scene/App';
|
import { App as SpaApp } from '@/scene/App';
|
||||||
import { USERS, USERS_COLLECTION } from '@/service/session';
|
import { USERS, USERS_COLLECTION } from '@/service/session';
|
||||||
import { hashLocalData } from '@/utils/sso';
|
import { hashLocalData } from '@/utils/sso';
|
||||||
import { Toaster } from './components/toaster';
|
import { Toaster } from './components/ui/toaster';
|
||||||
|
|
||||||
const AppEnvHint = () => {
|
const AppEnvHint = () => {
|
||||||
const dialog = useDisclosure();
|
const dialog = useDisclosure();
|
||||||
|
@ -11,7 +11,6 @@ import {
|
|||||||
Flex,
|
Flex,
|
||||||
HStack,
|
HStack,
|
||||||
IconButton,
|
IconButton,
|
||||||
Menu,
|
|
||||||
Text,
|
Text,
|
||||||
useDisclosure,
|
useDisclosure,
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
@ -33,6 +32,7 @@ import { requestSignIn, requestSignOut, requestSignUp } from '@/utils/sso';
|
|||||||
import { useThemeMode } from '@/utils/theme-tools';
|
import { useThemeMode } from '@/utils/theme-tools';
|
||||||
import { useSessionService } from '@/service/session';
|
import { useSessionService } from '@/service/session';
|
||||||
import { MdHelp, MdHome, MdMore, MdOutlinePlaylistPlay, MdOutlineUploadFile, MdSupervisedUserCircle } from 'react-icons/md';
|
import { MdHelp, MdHome, MdMore, MdOutlinePlaylistPlay, MdOutlineUploadFile, MdSupervisedUserCircle } from 'react-icons/md';
|
||||||
|
import { MenuContent, MenuItem, MenuRoot, MenuTrigger } from '../ui/menu';
|
||||||
|
|
||||||
export const TOP_BAR_HEIGHT = '50px';
|
export const TOP_BAR_HEIGHT = '50px';
|
||||||
|
|
||||||
@ -139,38 +139,36 @@ export const TopBar = ({ title, children }: TopBarProps) => {
|
|||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{session?.state === SessionState.CONNECTED && (
|
{session?.state === SessionState.CONNECTED && (
|
||||||
<Menu.Root>
|
<MenuRoot>
|
||||||
<Menu.Trigger asChild>
|
<MenuTrigger asChild>
|
||||||
<IconButton
|
<IconButton
|
||||||
as={IconButton}
|
as={IconButton}
|
||||||
aria-label="Options"
|
aria-label="Options"
|
||||||
{...BUTTON_TOP_BAR_PROPERTY}
|
{...BUTTON_TOP_BAR_PROPERTY}
|
||||||
width={TOP_BAR_HEIGHT}
|
width={TOP_BAR_HEIGHT}
|
||||||
><MdSupervisedUserCircle /></IconButton>
|
><MdSupervisedUserCircle /></IconButton>
|
||||||
</Menu.Trigger>
|
</MenuTrigger>
|
||||||
<Menu.Positioner>
|
<MenuContent>
|
||||||
<Menu.Content>
|
<MenuItem value="user" valueText="user" _hover={{}} color={mode('brand.800', 'brand.200')}>
|
||||||
<Menu.Item value="user" valueText="user" _hover={{}} color={mode('brand.800', 'brand.200')}>
|
<MdSupervisedUserCircle />
|
||||||
<MdSupervisedUserCircle />
|
<Box flex="1">Sign in as {session?.login ?? 'Fail'}</Box>
|
||||||
<Box flex="1">Sign in as {session?.login ?? 'Fail'}</Box>
|
</MenuItem>
|
||||||
</Menu.Item>
|
<MenuItem value="Settings" valueText="Settings" onClick={onSettings}><LuSettings />Settings</MenuItem>
|
||||||
<Menu.Item value="Settings" valueText="Settings" onClick={onSettings}><LuSettings />Settings</Menu.Item>
|
<MenuItem value="Help" valueText="Help" onClick={onHelp}><MdHelp /> Help</MenuItem>
|
||||||
<Menu.Item value="Help" valueText="Help" onClick={onHelp}><MdHelp /> Help</Menu.Item>
|
<MenuItem value="Sign-out" valueText="Sign-out" onClick={onSignOut}>
|
||||||
<Menu.Item value="Sign-out" valueText="Sign-out" onClick={onSignOut}>
|
<LuLogOut /> Sign-out
|
||||||
<LuLogOut /> Sign-out
|
</MenuItem>
|
||||||
</Menu.Item>
|
{colorMode === 'light' ? (
|
||||||
{colorMode === 'light' ? (
|
<MenuItem value="set-dark" valueText="set-dark" onClick={toggleColorMode}>
|
||||||
<Menu.Item value="set-dark" valueText="set-dark" onClick={toggleColorMode}>
|
<LuMoon /> Set dark mode
|
||||||
<LuMoon /> Set dark mode
|
</MenuItem>
|
||||||
</Menu.Item>
|
) : (
|
||||||
) : (
|
<MenuItem value="set-light" valueText="set-light" onClick={toggleColorMode}>
|
||||||
<Menu.Item value="set-light" valueText="set-light" onClick={toggleColorMode}>
|
<LuSun /> Set light mode
|
||||||
<LuSun /> Set light mode
|
</MenuItem>
|
||||||
</Menu.Item>
|
)}
|
||||||
)}
|
</MenuContent>
|
||||||
</Menu.Content>
|
</MenuRoot>
|
||||||
</Menu.Positioner>
|
|
||||||
</Menu.Root>
|
|
||||||
)}
|
)}
|
||||||
</Flex>
|
</Flex>
|
||||||
<Drawer.Root
|
<Drawer.Root
|
||||||
|
@ -2,9 +2,9 @@ import { useState } from 'react';
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
IconButton,
|
IconButton,
|
||||||
Menu,
|
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import { LuMenu } from 'react-icons/lu';
|
import { LuMenu } from 'react-icons/lu';
|
||||||
|
import { MenuContent, MenuItem, MenuRoot, MenuTrigger } from '../ui/menu';
|
||||||
|
|
||||||
export type MenuElement = {
|
export type MenuElement = {
|
||||||
name: string;
|
name: string;
|
||||||
@ -20,26 +20,24 @@ export const ContextMenu = ({ elements }: ContextMenuProps) => {
|
|||||||
return <></>;
|
return <></>;
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<Menu.Root
|
<MenuRoot
|
||||||
data-testid="context-menu">
|
data-testid="context-menu">
|
||||||
<Menu.Trigger asChild
|
<MenuTrigger asChild
|
||||||
data-testid="context-menu_trigger">
|
data-testid="context-menu_trigger">
|
||||||
{/* This is very stupid, we need to set as span to prevent a button in button... WTF */}
|
{/* This is very stupid, we need to set as span to prevent a button in button... WTF */}
|
||||||
<IconButton as='span'>
|
<IconButton as='span'>
|
||||||
<LuMenu />
|
<LuMenu />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</Menu.Trigger>
|
</MenuTrigger>
|
||||||
<Menu.Positioner>
|
<MenuContent
|
||||||
<Menu.Content
|
data-testid="context-menu_content">
|
||||||
data-testid="context-menu_content">
|
{elements?.map((data) => (
|
||||||
{elements?.map((data) => (
|
<MenuItem key={data.name} value={data.name} onClick={data.onClick}
|
||||||
<Menu.Item key={data.name} value={data.name} onClick={data.onClick}
|
data-testid="context-menu_item">
|
||||||
data-testid="context-menu_item">
|
{data.name}
|
||||||
{data.name}
|
</MenuItem>
|
||||||
</Menu.Item>
|
))}
|
||||||
))}
|
</MenuContent>
|
||||||
</Menu.Content>
|
</MenuRoot>
|
||||||
</Menu.Positioner>
|
|
||||||
</Menu.Root>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
110
front/src/components/ui/menu.tsx
Normal file
110
front/src/components/ui/menu.tsx
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import { AbsoluteCenter, Menu as ChakraMenu, Portal } from "@chakra-ui/react"
|
||||||
|
import * as React from "react"
|
||||||
|
import { LuCheck, LuChevronRight } from "react-icons/lu"
|
||||||
|
|
||||||
|
interface MenuContentProps extends ChakraMenu.ContentProps {
|
||||||
|
portalled?: boolean
|
||||||
|
portalRef?: React.RefObject<HTMLElement>
|
||||||
|
}
|
||||||
|
|
||||||
|
export const MenuContent = React.forwardRef<HTMLDivElement, MenuContentProps>(
|
||||||
|
function MenuContent(props, ref) {
|
||||||
|
const { portalled = true, portalRef, ...rest } = props
|
||||||
|
return (
|
||||||
|
<Portal disabled={!portalled} container={portalRef}>
|
||||||
|
<ChakraMenu.Positioner>
|
||||||
|
<ChakraMenu.Content ref={ref} {...rest} />
|
||||||
|
</ChakraMenu.Positioner>
|
||||||
|
</Portal>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
export const MenuArrow = React.forwardRef<
|
||||||
|
HTMLDivElement,
|
||||||
|
ChakraMenu.ArrowProps
|
||||||
|
>(function MenuArrow(props, ref) {
|
||||||
|
return (
|
||||||
|
<ChakraMenu.Arrow ref={ref} {...props}>
|
||||||
|
<ChakraMenu.ArrowTip />
|
||||||
|
</ChakraMenu.Arrow>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
export const MenuCheckboxItem = React.forwardRef<
|
||||||
|
HTMLDivElement,
|
||||||
|
ChakraMenu.CheckboxItemProps
|
||||||
|
>(function MenuCheckboxItem(props, ref) {
|
||||||
|
return (
|
||||||
|
<ChakraMenu.CheckboxItem ref={ref} {...props}>
|
||||||
|
<ChakraMenu.ItemIndicator hidden={false}>
|
||||||
|
<LuCheck />
|
||||||
|
</ChakraMenu.ItemIndicator>
|
||||||
|
{props.children}
|
||||||
|
</ChakraMenu.CheckboxItem>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
export const MenuRadioItem = React.forwardRef<
|
||||||
|
HTMLDivElement,
|
||||||
|
ChakraMenu.RadioItemProps
|
||||||
|
>(function MenuRadioItem(props, ref) {
|
||||||
|
const { children, ...rest } = props
|
||||||
|
return (
|
||||||
|
<ChakraMenu.RadioItem ps="8" ref={ref} {...rest}>
|
||||||
|
<AbsoluteCenter axis="horizontal" left="4" asChild>
|
||||||
|
<ChakraMenu.ItemIndicator>
|
||||||
|
<LuCheck />
|
||||||
|
</ChakraMenu.ItemIndicator>
|
||||||
|
</AbsoluteCenter>
|
||||||
|
<ChakraMenu.ItemText>{children}</ChakraMenu.ItemText>
|
||||||
|
</ChakraMenu.RadioItem>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
export const MenuItemGroup = React.forwardRef<
|
||||||
|
HTMLDivElement,
|
||||||
|
ChakraMenu.ItemGroupProps
|
||||||
|
>(function MenuItemGroup(props, ref) {
|
||||||
|
const { title, children, ...rest } = props
|
||||||
|
return (
|
||||||
|
<ChakraMenu.ItemGroup ref={ref} {...rest}>
|
||||||
|
{title && (
|
||||||
|
<ChakraMenu.ItemGroupLabel userSelect="none">
|
||||||
|
{title}
|
||||||
|
</ChakraMenu.ItemGroupLabel>
|
||||||
|
)}
|
||||||
|
{children}
|
||||||
|
</ChakraMenu.ItemGroup>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
export interface MenuTriggerItemProps extends ChakraMenu.ItemProps {
|
||||||
|
startIcon?: React.ReactNode
|
||||||
|
}
|
||||||
|
|
||||||
|
export const MenuTriggerItem = React.forwardRef<
|
||||||
|
HTMLDivElement,
|
||||||
|
MenuTriggerItemProps
|
||||||
|
>(function MenuTriggerItem(props, ref) {
|
||||||
|
const { startIcon, children, ...rest } = props
|
||||||
|
return (
|
||||||
|
<ChakraMenu.TriggerItem ref={ref} {...rest}>
|
||||||
|
{startIcon}
|
||||||
|
{children}
|
||||||
|
<LuChevronRight />
|
||||||
|
</ChakraMenu.TriggerItem>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
export const MenuRadioItemGroup = ChakraMenu.RadioItemGroup
|
||||||
|
export const MenuContextTrigger = ChakraMenu.ContextTrigger
|
||||||
|
export const MenuRoot = ChakraMenu.Root
|
||||||
|
export const MenuSeparator = ChakraMenu.Separator
|
||||||
|
|
||||||
|
export const MenuItem = ChakraMenu.Item
|
||||||
|
export const MenuItemText = ChakraMenu.ItemText
|
||||||
|
export const MenuItemCommand = ChakraMenu.ItemCommand
|
||||||
|
export const MenuTrigger = ChakraMenu.Trigger
|
@ -9,13 +9,10 @@ import {
|
|||||||
Toast,
|
Toast,
|
||||||
createToaster,
|
createToaster,
|
||||||
} from "@chakra-ui/react"
|
} from "@chakra-ui/react"
|
||||||
import { useCallback } from "react";
|
|
||||||
|
|
||||||
export const toaster = createToaster({
|
export const toaster = createToaster({
|
||||||
duration: 3000,
|
placement: "bottom-end",
|
||||||
placement: 'top-end',
|
pauseOnPageIdle: true,
|
||||||
// offset: { top: '50px' },
|
|
||||||
// variant: 'solid',
|
|
||||||
})
|
})
|
||||||
|
|
||||||
export const toasterAPIError = (error: RestErrorResponse) => {
|
export const toasterAPIError = (error: RestErrorResponse) => {
|
||||||
@ -28,13 +25,9 @@ export const toasterAPIError = (error: RestErrorResponse) => {
|
|||||||
export const Toaster = () => {
|
export const Toaster = () => {
|
||||||
return (
|
return (
|
||||||
<Portal>
|
<Portal>
|
||||||
<ChakraToaster
|
<ChakraToaster toaster={toaster} insetInline={{ mdDown: "4" }}>
|
||||||
toaster={toaster}
|
|
||||||
insetInline={{ mdDown: "1rem" }}
|
|
||||||
width={{ md: "356px" }}
|
|
||||||
>
|
|
||||||
{(toast) => (
|
{(toast) => (
|
||||||
<Toast.Root>
|
<Toast.Root width={{ md: "sm" }}>
|
||||||
{toast.type === "loading" ? (
|
{toast.type === "loading" ? (
|
||||||
<Spinner size="sm" color="blue.solid" />
|
<Spinner size="sm" color="blue.solid" />
|
||||||
) : (
|
) : (
|
@ -7,7 +7,7 @@ import { DependencyList, useCallback, useEffect, useState } from 'react';
|
|||||||
|
|
||||||
import { RestErrorResponse } from '@/back-api';
|
import { RestErrorResponse } from '@/back-api';
|
||||||
import { isNullOrUndefined } from '@/utils/validator';
|
import { isNullOrUndefined } from '@/utils/validator';
|
||||||
import { toasterAPIError } from '@/components/toaster';
|
import { toasterAPIError } from '@/components/ui/toaster';
|
||||||
|
|
||||||
export type DataStoreType<TYPE> = {
|
export type DataStoreType<TYPE> = {
|
||||||
isLoading: boolean;
|
isLoading: boolean;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user