Skip to content

Commit 8e2161d

Browse files
committed
feat(): update
1 parent 1ab84a0 commit 8e2161d

File tree

6 files changed

+209
-43
lines changed

6 files changed

+209
-43
lines changed

packages/plasma-new-hope/src/components/_beta/Popover/Popover.styles.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ export const base = css`
99
padding: var(${tokens.padding});
1010
border-radius: var(${tokens.borderRadius});
1111
box-shadow: var(${tokens.boxShadow});
12+
width: 100%;
13+
height: 100%;
14+
box-sizing: border-box;
1215
`;
1316

1417
export const Target = styled.div`

packages/plasma-new-hope/src/components/_beta/Popover/Popover.tokens.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
export const classes = {
2-
popoverContainer: 'popover-container',
2+
popoverRoot: 'popover-root',
33
popoverCloseIconButton: 'popover-close-icon-button',
44
};
55

packages/plasma-new-hope/src/components/_beta/Popover/Popover.tsx

Lines changed: 43 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,12 @@ import {
1818
FloatingPortal,
1919
autoUpdate,
2020
} from '@floating-ui/react';
21-
import { mergeRefs } from 'src/utils';
2221
import { css } from '@linaria/core';
2322

2423
import { IconClose } from '../../_Icon';
24+
import { Resizable } from '../../_Resizable';
2525

26-
import { sizeToIconSize } from './utils';
26+
import { sizeToIconSize, matchPlacements } from './utils';
2727
import { tokens, classes } from './Popover.tokens';
2828
import { base, Target, CloseButton } from './Popover.styles';
2929
import type { PopoverProps } from './Popover.types';
@@ -53,15 +53,14 @@ export const popoverRoot = (Root: RootProps<HTMLDivElement, PopoverProps>) =>
5353
shift: outsideShift = true,
5454
offset: outerOffset = 0,
5555
outsideClick = true,
56-
resizable,
56+
resizable = false,
5757
onResizeStart,
5858
onResizeEnd,
5959
onToggle,
6060
delayOpen = 0,
6161
delayClose = 0,
6262
zIndex = 1000,
6363
className,
64-
style,
6564
size,
6665
...rest
6766
},
@@ -115,8 +114,6 @@ export const popoverRoot = (Root: RootProps<HTMLDivElement, PopoverProps>) =>
115114

116115
const { getReferenceProps, getFloatingProps } = useInteractions([dismiss, role, click, hover]);
117116

118-
const commonRef = mergeRefs(outerRootRef, refs.setFloating);
119-
120117
return (
121118
<>
122119
<Target ref={refs.setReference} {...getReferenceProps()}>
@@ -126,38 +123,49 @@ export const popoverRoot = (Root: RootProps<HTMLDivElement, PopoverProps>) =>
126123
{opened && (
127124
<FloatingPortal>
128125
<FloatingFocusManager context={context}>
129-
<Root
130-
ref={commonRef}
131-
target={target}
132-
className={cls(className, classes.popoverContainer)}
133-
style={{ zIndex, ...style, ...floatingStyles }}
134-
size={size}
126+
<div
127+
ref={refs.setFloating}
128+
style={{ ...floatingStyles, zIndex }}
135129
{...getFloatingProps()}
136-
{...rest}
137-
data-popover-open={opened}
138130
>
139-
{appearance === 'closeInner' && (
140-
<CloseButton
141-
className={classes.popoverCloseIconButton}
142-
onClick={() => handleToggle(false)}
131+
<Resizable
132+
placement={matchPlacements(placement)}
133+
resizable={resizable}
134+
onResizeStart={onResizeStart}
135+
onResizeEnd={onResizeEnd}
136+
>
137+
<Root
138+
ref={outerRootRef}
139+
target={target}
140+
className={cls(className, classes.popoverRoot)}
141+
size={size}
142+
{...rest}
143+
data-popover-open={opened}
143144
>
144-
<IconClose size={sizeToIconSize(size)} color="inherit" />
145-
</CloseButton>
146-
)}
147-
148-
{outerArrow && (
149-
<FloatingArrow
150-
ref={arrowRef}
151-
context={context}
152-
width={ARROW_WIDTH}
153-
height={ARROW_HEIGHT}
154-
fill={`var(${tokens.backgroundColor})`}
155-
d={ARROW_POLYGON}
156-
/>
157-
)}
158-
159-
{children}
160-
</Root>
145+
{appearance === 'closeInner' && (
146+
<CloseButton
147+
className={classes.popoverCloseIconButton}
148+
onClick={() => handleToggle(false)}
149+
>
150+
<IconClose size={sizeToIconSize(size)} color="inherit" />
151+
</CloseButton>
152+
)}
153+
154+
{outerArrow && (
155+
<FloatingArrow
156+
ref={arrowRef}
157+
context={context}
158+
width={ARROW_WIDTH}
159+
height={ARROW_HEIGHT}
160+
fill={`var(${tokens.backgroundColor})`}
161+
d={ARROW_POLYGON}
162+
/>
163+
)}
164+
165+
{children}
166+
</Root>
167+
</Resizable>
168+
</div>
161169
</FloatingFocusManager>
162170
</FloatingPortal>
163171
)}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
export * from './sizeToIconSize';
2+
export * from './matchPlacements';
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { Placement as ResizablePlacement } from '../../../_Resizable/Resizable.types';
2+
import { PopoverProps } from '../Popover.types';
3+
4+
export const matchPlacements = (placement: PopoverProps['placement']): ResizablePlacement => {
5+
switch (placement) {
6+
case 'top':
7+
return 'top';
8+
9+
case 'right':
10+
return 'right';
11+
12+
case 'bottom':
13+
return 'bottom';
14+
15+
case 'left':
16+
return 'left';
17+
18+
case 'top-start':
19+
case 'left-start':
20+
return 'top-left';
21+
22+
case 'top-end':
23+
case 'right-start':
24+
return 'top-right';
25+
26+
case 'right-end':
27+
case 'bottom-end':
28+
return 'bottom-right';
29+
30+
case 'bottom-start':
31+
case 'left-end':
32+
return 'bottom-left';
33+
34+
default:
35+
return 'center';
36+
}
37+
};

packages/plasma-new-hope/src/examples/components/_beta/Popover/Popover.stories.tsx

Lines changed: 124 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import * as React from 'react';
2-
import type { ComponentProps } from 'react';
2+
import { ComponentProps, useState } from 'react';
33
import type { StoryObj, Meta } from '@storybook/react-vite';
44

55
import { Cell, CellTextbox, CellTextboxTitle, CellTextboxSubtitle } from '../../Cell/Cell';
@@ -91,11 +91,6 @@ const meta: Meta<StoryProps> = {
9191
type: 'number',
9292
},
9393
},
94-
resizable: {
95-
control: {
96-
type: 'boolean',
97-
},
98-
},
9994
view: {
10095
options: view,
10196
control: {
@@ -121,7 +116,6 @@ const meta: Meta<StoryProps> = {
121116
outsideClick: true,
122117
delayOpen: 0,
123118
delayClose: 0,
124-
resizable: false,
125119
view: 'default',
126120
size: 'm',
127121
},
@@ -166,3 +160,126 @@ const StoryDefault = (args: StoryProps) => {
166160
export const Default: StoryObj<StoryProps> = {
167161
render: (args) => <StoryDefault {...args} />,
168162
};
163+
164+
const StoryResizable = (args: StoryProps) => {
165+
const {
166+
resizableDirections,
167+
resizableHiddenIcons,
168+
resizableDefaultSize,
169+
resizableMinWidth,
170+
resizableMinHeight,
171+
resizableMaxWidth,
172+
resizableMaxHeight,
173+
resizableIconSize,
174+
} = args;
175+
176+
React.useEffect(() => {
177+
window.scrollTo(
178+
(document.documentElement.scrollWidth - window.innerWidth) / 2,
179+
(document.documentElement.scrollHeight - window.innerHeight) / 2,
180+
);
181+
}, []);
182+
183+
const cells = [
184+
{ num: 1, color: '#e74c3c' },
185+
{ num: 2, color: '#3498db' },
186+
{ num: 3, color: '#f1c40f' },
187+
{ num: 4, color: '#27ae60' },
188+
];
189+
190+
return (
191+
<div
192+
style={{
193+
display: 'flex',
194+
alignItems: 'center',
195+
justifyContent: 'center',
196+
width: '400vw',
197+
height: '400vh',
198+
}}
199+
>
200+
<Popover
201+
target={<Button>Target</Button>}
202+
resizable={{
203+
directions: resizableDirections,
204+
hiddenIcons: resizableHiddenIcons,
205+
defaultSize: resizableDefaultSize,
206+
minWidth: resizableMinWidth,
207+
minHeight: resizableMinHeight,
208+
maxWidth: resizableMaxWidth,
209+
maxHeight: resizableMaxHeight,
210+
iconSize: resizableIconSize,
211+
}}
212+
{...args}
213+
>
214+
<div
215+
style={{
216+
width: '100%',
217+
height: '100%',
218+
display: 'grid',
219+
gridTemplateColumns: '1fr 1fr',
220+
gridTemplateRows: '1fr 1fr',
221+
}}
222+
>
223+
{cells.map(({ num, color }) => (
224+
<div
225+
key={num}
226+
style={{
227+
background: color,
228+
color: 'white',
229+
fontSize: '4vw',
230+
display: 'flex',
231+
justifyContent: 'center',
232+
alignItems: 'center',
233+
}}
234+
>
235+
{num}
236+
</div>
237+
))}
238+
</div>
239+
</Popover>
240+
</div>
241+
);
242+
};
243+
244+
export const Resizable: StoryObj<StoryProps> = {
245+
argTypes: {
246+
resizableDirections: {
247+
control: 'check',
248+
options: ['top', 'top-right', 'right', 'bottom-right', 'bottom', 'bottom-left', 'left', 'top-left'],
249+
},
250+
resizableDefaultSize: {
251+
control: 'object',
252+
},
253+
resizableHiddenIcons: {
254+
control: 'check',
255+
options: ['top-right', 'bottom-right', 'bottom-left', 'top-left'],
256+
},
257+
resizableMinWidth: {
258+
control: 'number',
259+
},
260+
resizableMinHeight: {
261+
control: 'number',
262+
},
263+
resizableMaxWidth: {
264+
control: 'number',
265+
},
266+
resizableMaxHeight: {
267+
control: 'number',
268+
},
269+
resizableIconSize: {
270+
control: {
271+
type: 'select',
272+
},
273+
options: ['xs', 's', 'm'],
274+
},
275+
},
276+
args: {
277+
resizableDirections: ['bottom-right'],
278+
resizableHiddenIcons: [],
279+
resizableIconSize: 's',
280+
resizableDefaultSize: { width: 300, height: 300 },
281+
resizableMinWidth: 300,
282+
resizableMinHeight: 300,
283+
},
284+
render: (args) => <StoryResizable {...args} />,
285+
};

0 commit comments

Comments
 (0)