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 2 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
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