Skip to content

Commit 8e03ac8

Browse files
authored
Merge f14ad83 into 3bd12c6
2 parents 3bd12c6 + f14ad83 commit 8e03ac8

8 files changed

Lines changed: 451 additions & 0 deletions

File tree

.changeset/small-boxes-move.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@guardian/source-development-kitchen': minor
3+
---
4+
5+
Add Popover component for displaying information ontop of the document, relative to the anchoring element to be clicked

libs/@guardian/source-development-kitchen/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
"@storybook/addon-docs": "10.3.3",
3939
"@storybook/addon-links": "10.3.3",
4040
"@storybook/react-vite": "10.3.3",
41+
"@types/chai": "5.2.3",
4142
"@types/jest": "30.0.0",
4243
"@types/react": "18.2.79",
4344
"eslint": "9.39.1",

libs/@guardian/source-development-kitchen/src/react-components/index.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export type {
1313
LogoProps,
1414
NumericInput,
1515
NumericInputProps,
16+
PopoverProps,
1617
StarRatingProps,
1718
ToggleSwitchProps,
1819
ToggleSwitchAppsProps,
@@ -33,6 +34,7 @@ it('Should have exactly these exports', () => {
3334
'Lines',
3435
'Logo',
3536
'NumericInput',
37+
'Popover',
3638
'SquigglyLines',
3739
'StarRating',
3840
'StraightLines',

libs/@guardian/source-development-kitchen/src/react-components/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,3 +62,6 @@ export type { TabContainerProps, TabProps } from './tabs/types';
6262

6363
export { Ticker } from './ticker/Ticker';
6464
export type { TickerSettings } from './ticker/Ticker';
65+
66+
export { Popover } from './popover/Popover';
67+
export type { PopoverProps } from './popover/Popover';
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
import { css } from '@emotion/react';
2+
import { space } from '@guardian/source/foundations';
3+
import {
4+
Button,
5+
LinkButton,
6+
SvgInfoRound,
7+
} from '@guardian/source/react-components';
8+
import type { Meta, StoryObj } from '@storybook/react-vite';
9+
import { useState } from 'react';
10+
import { userEvent, within } from 'storybook/test';
11+
import { Popover } from './Popover';
12+
13+
const meta: Meta<typeof Popover> = {
14+
title: 'React Components/Popover',
15+
component: Popover,
16+
args: {
17+
title: 'Title',
18+
position: 'top',
19+
showPointer: true,
20+
theme: 'medium',
21+
width: '250px',
22+
},
23+
render: (args) => {
24+
// eslint-disable-next-line react-hooks/rules-of-hooks -- Storybook
25+
const [isExpanded, setIsExpanded] = useState(false);
26+
const handleButtonClick = () => setIsExpanded(!isExpanded);
27+
28+
return (
29+
<div
30+
css={css`
31+
position: relative;
32+
width: fit-content;
33+
left: 300px;
34+
top: 300px;
35+
`}
36+
>
37+
<Popover
38+
{...args}
39+
anchorElement={
40+
<Button
41+
id="info-icon"
42+
icon={<SvgInfoRound />}
43+
size="xsmall"
44+
priority="tertiary"
45+
theme={{ borderTertiary: 'unset' }}
46+
hideLabel={true}
47+
onClick={handleButtonClick}
48+
>
49+
More information
50+
</Button>
51+
}
52+
isOpen={isExpanded}
53+
handleClose={() => setIsExpanded(false)}
54+
>
55+
<span>
56+
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
57+
eiusmod tempor incididunt ut labore et dolore magna aliqua.
58+
</span>
59+
<div
60+
css={css`
61+
margin-top: ${space[3]}px;
62+
`}
63+
>
64+
<LinkButton
65+
priority="primary"
66+
size="xsmall"
67+
href="https://www.theguardian.com/uk"
68+
>
69+
Primary button xs
70+
</LinkButton>
71+
</div>
72+
</Popover>
73+
</div>
74+
);
75+
},
76+
};
77+
78+
export default meta;
79+
type Story = StoryObj<typeof Popover>;
80+
81+
export const WithTitleAndPointerTop: Story = {
82+
play: async ({ canvasElement, step }) => {
83+
const canvas = within(canvasElement);
84+
85+
await step('Click anchor element', async () => {
86+
await userEvent.click(canvas.getByText('More information'));
87+
});
88+
},
89+
};
90+
91+
export const WithoutTitleAndPointerLeft: Story = {
92+
args: {
93+
title: undefined,
94+
position: 'left',
95+
showPointer: false,
96+
},
97+
play: async ({ canvasElement, step }) => {
98+
const canvas = within(canvasElement);
99+
100+
await step('Click anchor element', async () => {
101+
await userEvent.click(canvas.getByText('More information'));
102+
});
103+
},
104+
};

0 commit comments

Comments
 (0)