✨(frontend) add a Popover primitive
easily use buttons toggling styled RAC popovers
This commit is contained in:
@@ -146,6 +146,7 @@ const config: Config = {
|
|||||||
2: { value: '2' },
|
2: { value: '2' },
|
||||||
},
|
},
|
||||||
radii: {
|
radii: {
|
||||||
|
4: { value: '0.25rem' },
|
||||||
6: { value: '0.375rem' },
|
6: { value: '0.375rem' },
|
||||||
8: { value: '0.5rem' },
|
8: { value: '0.5rem' },
|
||||||
16: { value: '1rem' },
|
16: { value: '1rem' },
|
||||||
@@ -187,7 +188,7 @@ const config: Config = {
|
|||||||
text: { value: '{colors.white}' },
|
text: { value: '{colors.white}' },
|
||||||
warm: { value: '{colors.blue.300}' },
|
warm: { value: '{colors.blue.300}' },
|
||||||
subtle: { value: '{colors.blue.100}' },
|
subtle: { value: '{colors.blue.100}' },
|
||||||
'subtle-text': { value: '{colors.sky.700}' },
|
'subtle-text': { value: '{colors.blue.700}' },
|
||||||
},
|
},
|
||||||
danger: {
|
danger: {
|
||||||
DEFAULT: { value: '{colors.red.600}' },
|
DEFAULT: { value: '{colors.red.600}' },
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ export const Box = ({
|
|||||||
}: BoxProps) => {
|
}: BoxProps) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
return (
|
return (
|
||||||
<BoxDiv asScreen>
|
<BoxDiv type="screen">
|
||||||
{!!title && <H lvl={1}>{title}</H>}
|
{!!title && <H lvl={1}>{title}</H>}
|
||||||
{children}
|
{children}
|
||||||
{!!withBackButton && (
|
{!!withBackButton && (
|
||||||
|
|||||||
@@ -9,14 +9,18 @@ const box = cva({
|
|||||||
flex: 1,
|
flex: 1,
|
||||||
},
|
},
|
||||||
variants: {
|
variants: {
|
||||||
asScreen: {
|
type: {
|
||||||
true: {
|
screen: {
|
||||||
margin: 'auto',
|
margin: 'auto',
|
||||||
width: '38rem',
|
width: '38rem',
|
||||||
maxWidth: '100%',
|
maxWidth: '100%',
|
||||||
marginTop: '6rem',
|
marginTop: '6rem',
|
||||||
textAlign: 'center',
|
textAlign: 'center',
|
||||||
},
|
},
|
||||||
|
popover: {
|
||||||
|
padding: 'boxPadding.xs',
|
||||||
|
minWidth: '10rem',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
variant: {
|
variant: {
|
||||||
default: {
|
default: {
|
||||||
@@ -42,7 +46,6 @@ const box = cva({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
defaultVariants: {
|
defaultVariants: {
|
||||||
asScreen: false,
|
|
||||||
variant: 'default',
|
variant: 'default',
|
||||||
size: 'default',
|
size: 'default',
|
||||||
},
|
},
|
||||||
|
|||||||
68
src/frontend/src/primitives/Popover.tsx
Normal file
68
src/frontend/src/primitives/Popover.tsx
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
import { ReactNode } from 'react'
|
||||||
|
import {
|
||||||
|
DialogProps,
|
||||||
|
DialogTrigger,
|
||||||
|
Popover as RACPopover,
|
||||||
|
Dialog,
|
||||||
|
OverlayArrow,
|
||||||
|
} from 'react-aria-components'
|
||||||
|
import { styled } from '@/styled-system/jsx'
|
||||||
|
import { Box } from './Box'
|
||||||
|
|
||||||
|
const StyledPopover = styled(RACPopover, {
|
||||||
|
base: {
|
||||||
|
'&[data-placement="bottom"]': {
|
||||||
|
marginTop: 0.25,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const StyledOverlayArrow = styled(OverlayArrow, {
|
||||||
|
base: {
|
||||||
|
display: 'block',
|
||||||
|
fill: 'box.bg',
|
||||||
|
stroke: 'box.border',
|
||||||
|
strokeWidth: 1,
|
||||||
|
'&[data-placement="bottom"] svg': {
|
||||||
|
transform: 'rotate(180deg) translateY(-1px)',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* a Popover is a tuple of a trigger component (most usually a Button) that toggles some interactive content in a tooltip around the trigger
|
||||||
|
*/
|
||||||
|
export const Popover = ({
|
||||||
|
children,
|
||||||
|
...dialogProps
|
||||||
|
}: {
|
||||||
|
children: [
|
||||||
|
trigger: ReactNode,
|
||||||
|
popoverContent:
|
||||||
|
| (({ close }: { close: () => void }) => ReactNode)
|
||||||
|
| ReactNode,
|
||||||
|
]
|
||||||
|
} & DialogProps) => {
|
||||||
|
const [trigger, popoverContent] = children
|
||||||
|
return (
|
||||||
|
<DialogTrigger>
|
||||||
|
{trigger}
|
||||||
|
<StyledPopover>
|
||||||
|
<StyledOverlayArrow>
|
||||||
|
<svg width={12} height={12} viewBox="0 0 12 12">
|
||||||
|
<path d="M0 0 L6 6 L12 0" />
|
||||||
|
</svg>
|
||||||
|
</StyledOverlayArrow>
|
||||||
|
<Dialog {...dialogProps}>
|
||||||
|
{({ close }) => (
|
||||||
|
<Box size="sm" type="popover">
|
||||||
|
{typeof popoverContent === 'function'
|
||||||
|
? popoverContent({ close })
|
||||||
|
: popoverContent}
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
</Dialog>
|
||||||
|
</StyledPopover>
|
||||||
|
</DialogTrigger>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -9,4 +9,6 @@ export { Hr } from './Hr'
|
|||||||
export { Italic } from './Italic'
|
export { Italic } from './Italic'
|
||||||
export { Link } from './Link'
|
export { Link } from './Link'
|
||||||
export { P } from './P'
|
export { P } from './P'
|
||||||
|
export { Popover } from './Popover'
|
||||||
|
export { PopoverList } from './PopoverList'
|
||||||
export { Text } from './Text'
|
export { Text } from './Text'
|
||||||
|
|||||||
Reference in New Issue
Block a user