Skip to content
This repository has been archived by the owner on Nov 7, 2022. It is now read-only.

Create new Popover and use in formula block #465

Merged
merged 3 commits into from
Jul 25, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion packages/design-system/.storybook/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ const createSwcLoader = () => {
react: {
runtime: 'automatic'
}
}
},
externalHelpers: false
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`PopoverN Basic should match the snapshot 1`] = `
<div>
<div
style="display: flex; justify-content: center; align-items: center;"
>
<div
class="mc-c-pmrKX"
>
<button
aria-expanded="false"
aria-haspopup="dialog"
class="mc-c-gtItaD"
>
What does 42 mean?
</button>
</div>
</div>
</div>
`;

exports[`PopoverN ContextMenu should match the snapshot 1`] = `
<div>
<div
style="display: flex; justify-content: center; align-items: center;"
>
<div
class="mc-c-pmrKX"
>
<button
aria-expanded="false"
aria-haspopup="dialog"
class="mc-c-gtItaD"
>
<div
style="height: 4rem; width: 100%; display: flex; justify-content: center; align-items: center; background-color: rgb(239, 239, 239);"
>
Click
</div>
</button>
</div>
</div>
</div>
`;
1 change: 1 addition & 0 deletions packages/design-system/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
],
"sideEffects": false,
"dependencies": {
"@floating-ui/react-dom-interactions": "^0.8.1",
"@hookform/resolvers": "^2.9.6",
"@mashcard/active-support": "workspace:^",
"@mashcard/design-icons": "workspace:^",
Expand Down
5 changes: 5 additions & 0 deletions packages/design-system/src/components/Popover/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ export interface PopoverProps extends AbstractTriggerProps {
compact?: boolean
}

/**
*
* @deprecated This component is planned to be abandoned and PopoverN is now recommended.
* You can continue to use this component now, but popoverN will replace it later
*/
const Popover: ForwardRefRenderFunction<unknown, PopoverProps> = (props, ref) => {
const { title, content, role = 'dialog', compact, ...otherProps } = props

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { composeStories } from '@storybook/testing-react'
import { a11yTest, toStoryTable } from '../../../utilities/testing'
import { render } from '@testing-library/react'
import { FC } from 'react'
import * as PopoverStories from '../popovern.stories'

const { Basic } = composeStories(PopoverStories)
const storyTable = toStoryTable(composeStories(PopoverStories))

describe('PopoverN', () => {
it('PopoverN Should be passed a11y test', async () => await a11yTest(Basic as FC))


it.each(storyTable)('$name should match the snapshot', ({ Component }) => {
const { container } = render(<Component />)
expect(container).toMatchSnapshot()
})
})
116 changes: 116 additions & 0 deletions packages/design-system/src/components/PopoverN/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
import React, { cloneElement } from 'react'
import {
Placement,
offset,
flip,
shift,
autoUpdate,
useFloating,
useInteractions,
useRole,
useDismiss,
useId,
useClick,
FloatingFocusManager,
Middleware,
Strategy
} from '@floating-ui/react-dom-interactions'
import { PopoverWrapper, ChildWrapper, ContentWrapper } from './styles/index.style'

interface Props {
render: (data: { close: () => void; labelId: string; descriptionId: string }) => React.ReactNode
children: React.ReactNode
onOpenChange?: (open: boolean) => void
placement?: Placement
middleware?: Array<Middleware>
strategy?: Strategy
overlayInnerStyle: React.CSSProperties
visible?: boolean
defaultVisible?: boolean
onVisibleChange?: (status: boolean) => void
className?: string
destroyTooltipOnHide?: boolean
offset?: number
}

const PopoverN = ({
children,
render,
placement,
strategy: _strategy,
middleware,
overlayInnerStyle,
visible,
defaultVisible,
onVisibleChange,
className,
destroyTooltipOnHide,
offset: _offset
}: Props) => {
const open = visible !== undefined ? visible : defaultVisible !== undefined ? defaultVisible : false

const { x, y, reference, floating, strategy, context } = useFloating({
open,
onOpenChange: onVisibleChange,
middleware: middleware ?? [offset(_offset ?? 5), flip(), shift()],
placement,
whileElementsMounted: autoUpdate,
strategy: _strategy
})

const id = useId()
const labelId = `${id}-label`
const descriptionId = `${id}-description`

const { getReferenceProps, getFloatingProps } = useInteractions([
useClick(context),
useRole(context),
useDismiss(context)
])

const refProps = getReferenceProps({ ref: reference })

return (
<PopoverWrapper className={className}>
{cloneElement(<ChildWrapper>{children}</ChildWrapper>, getReferenceProps({ ref: reference }))}
{(open || destroyTooltipOnHide === false) && (
<FloatingFocusManager context={context} modal={false} order={['reference', 'content']} returnFocus={false}>
<ContentWrapper
style={overlayInnerStyle}
{...getFloatingProps({
className: 'Popover',
ref: floating,
style: {
display: open ? undefined : 'none',
zIndex: 1,
position: strategy,
top: y ?? 0,
left: x ?? 0
},
'aria-labelledby': labelId,
'aria-describedby': descriptionId
})}
>
{render({
labelId,
descriptionId,
close: () => {
onVisibleChange?.(false)
}
})}
</ContentWrapper>
</FloatingFocusManager>
)}
</PopoverWrapper>
)
}

PopoverN.displayName = 'PopoverN'

PopoverN.defaultProps = {
placement: 'top-start',
strategy: 'absolute',
destroyTooltipOnHide: true
}

export { PopoverN }
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { PopoverN } from './index'
import { ComponentMeta, ComponentStory } from '@storybook/react'
import { Button } from '..'

export default {
title: 'Components/PopoverN',
component: PopoverN,
args: {
placement: 'top-start'
},
argTypes: {},
parameters: {
docs: {
description: {
component: `
The next generation of Popover, called PopoverN for ease of differentiation

based on floating-ui.
will replace Popover later on.

The floating card popped by clicking or hovering.

#### When To Use

- A simple popup menu to provide extra information or operations.

- Comparing with popover, besides information Popover card can also provide action elements like links and buttons.

`
}
},
design: {
type: 'figma',
url: 'https://www.figma.com/file/YcVOEbdec2oqyKrYFSkeYW/Components-Base?node-id=4443%3A2288'
}
}
} as ComponentMeta<typeof PopoverN>

const Template: ComponentStory<typeof PopoverN> = args => (
<div
style={{
display: 'flex',
justifyContent: 'center',
alignItems: 'center'
}}
>
<PopoverN {...args} />
</div>
)

export const Basic = Template.bind({})

Basic.args = {
render: () => <p>42 is the meaning of life</p>,
children: 'What does 42 mean?'
}

export const ContextMenu = Template.bind({})
ContextMenu.args = {
render: () => <p>42 is the meaning of life</p>,
children: (
<div
style={{
height: '4rem',
width: '100%',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#efefef'
}}
>
Click
</div>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { theme, styled } from '../../../themes'

export const PopoverWrapper = styled('div', {
position: 'relative',
display: 'inline'
})

export const ChildWrapper = styled('button', {
position: 'relative',
border: 'none',
background: 'transparent',
padding: 0
})

export const ContentWrapper = styled('div', {
include: ['ceramicPrimary', 'refractionPrimary', 'cornerFix'],
backgroundColor: theme.colors.white,
backgroundClip: 'padding-box',
color: theme.colors.typePrimary,
padding: '10px 12px',
minHeight: '2rem',
borderRadius: '4px',
minWidth: '10rem',
// The outline here should appear internally
outline: `0.2px solid ${theme.colors.white}`,
outlineOffset: '-0.2px'
})
1 change: 1 addition & 0 deletions packages/design-system/src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export * from './Tag'
export * from './Empty'
export * from './Form'
export * from './Popover'
export * from './PopoverN'
melchior-voidwolf marked this conversation as resolved.
Show resolved Hide resolved
export * from './Provider'
export * from './Dropdown'
export * from './Toast'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,29 +13,38 @@ exports[`FormulaBlock matches correct snapshot 1`] = `
>

</span>
<span
aria-haspopup="dialog"
class="mc-c-hxsbZB"
<div
class="mc-c-pmrKX mc-c-cEkrQs"
>
<span
aria-label="formula"
class="mc-icon mc-icon-formula mashcard-formula-empty-icon"
role="img"
<button
aria-expanded="false"
aria-haspopup="dialog"
class="mc-c-gtItaD"
>
<svg
fill="none"
viewBox="0 0 24 24"
<span
class="mc-c-hxsbZB"
>
<path
d="M20 4.5 18.5 3H4l9 9-9 9h14.5l1.5-1.5"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
/>
</svg>
</span>
</span>
<span
aria-label="formula"
class="mc-icon mc-icon-formula mashcard-formula-empty-icon"
role="img"
>
<svg
fill="none"
viewBox="0 0 24 24"
>
<path
d="M20 4.5 18.5 3H4l9 9-9 9h14.5l1.5-1.5"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
/>
</svg>
</span>
</span>
</button>
</div>
<span
class="mc-c-bbClCh"
contenteditable="false"
Expand Down
Loading