paris 0.17.9 → 0.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/package.json +139 -150
  3. package/src/helpers/renderEnhancer.tsx +4 -5
  4. package/src/helpers/useResizeObserver.ts +17 -23
  5. package/src/pages/_document.tsx +1 -3
  6. package/src/pages/index.tsx +8 -24
  7. package/src/stories/Pagination.mdx +1 -1
  8. package/src/stories/Tokens.mdx +1 -1
  9. package/src/stories/Welcome.mdx +1 -1
  10. package/src/stories/accordion/Accordion.stories.ts +1 -1
  11. package/src/stories/accordion/Accordion.tsx +14 -35
  12. package/src/stories/accordionselect/AccordionSelect.stories.ts +2 -5
  13. package/src/stories/accordionselect/AccordionSelect.tsx +26 -50
  14. package/src/stories/avatar/Avatar.stories.ts +1 -1
  15. package/src/stories/avatar/Avatar.tsx +14 -13
  16. package/src/stories/button/Button.stories.ts +18 -15
  17. package/src/stories/button/Button.tsx +44 -48
  18. package/src/stories/callout/Callout.stories.ts +3 -7
  19. package/src/stories/callout/Callout.tsx +4 -8
  20. package/src/stories/card/Card.stories.ts +1 -1
  21. package/src/stories/card/Card.tsx +4 -11
  22. package/src/stories/cardbutton/CardButton.stories.tsx +1 -1
  23. package/src/stories/cardbutton/CardButton.tsx +16 -18
  24. package/src/stories/checkbox/Checkbox.stories.ts +1 -1
  25. package/src/stories/checkbox/Checkbox.tsx +37 -49
  26. package/src/stories/combobox/Combobox.stories.ts +65 -71
  27. package/src/stories/combobox/Combobox.tsx +80 -89
  28. package/src/stories/dialog/Dialog.stories.tsx +2 -2
  29. package/src/stories/dialog/Dialog.tsx +45 -68
  30. package/src/stories/drawer/Drawer.stories.tsx +63 -105
  31. package/src/stories/drawer/Drawer.tsx +93 -90
  32. package/src/stories/field/Field.stories.ts +1 -1
  33. package/src/stories/field/Field.tsx +25 -30
  34. package/src/stories/icon/Ellipsis.tsx +4 -1
  35. package/src/stories/icon/Icon.stories.ts +2 -2
  36. package/src/stories/icon/Icon.tsx +16 -26
  37. package/src/stories/icon/Info.tsx +4 -1
  38. package/src/stories/icon/Spinner.tsx +4 -2
  39. package/src/stories/icon/index.ts +6 -6
  40. package/src/stories/informationaltooltip/InformationalTooltip.stories.tsx +12 -11
  41. package/src/stories/informationaltooltip/InformationalTooltip.tsx +23 -28
  42. package/src/stories/input/Input.stories.ts +14 -15
  43. package/src/stories/input/Input.tsx +119 -95
  44. package/src/stories/markdown/Markdown.module.scss +384 -0
  45. package/src/stories/markdown/Markdown.stories.ts +203 -0
  46. package/src/stories/markdown/Markdown.tsx +293 -0
  47. package/src/stories/markdown/index.ts +1 -0
  48. package/src/stories/menu/Menu.module.scss +9 -0
  49. package/src/stories/menu/Menu.stories.tsx +4 -10
  50. package/src/stories/menu/Menu.tsx +27 -29
  51. package/src/stories/pagination/usePagination.ts +8 -8
  52. package/src/stories/popover/Popover.stories.ts +2 -2
  53. package/src/stories/popover/Popover.tsx +4 -10
  54. package/src/stories/select/Select.stories.ts +10 -10
  55. package/src/stories/select/Select.tsx +268 -240
  56. package/src/stories/styledlink/StyledLink.stories.ts +1 -1
  57. package/src/stories/styledlink/StyledLink.tsx +11 -17
  58. package/src/stories/table/Table.stories.ts +1 -1
  59. package/src/stories/table/Table.tsx +55 -65
  60. package/src/stories/tabs/Tabs.stories.tsx +2 -2
  61. package/src/stories/tabs/Tabs.tsx +15 -21
  62. package/src/stories/tag/Tag.stories.ts +1 -4
  63. package/src/stories/tag/Tag.tsx +9 -17
  64. package/src/stories/text/Text.stories.ts +1 -1
  65. package/src/stories/text/Text.tsx +49 -31
  66. package/src/stories/text/Typography.module.css +120 -120
  67. package/src/stories/textarea/TextArea.stories.ts +2 -5
  68. package/src/stories/textarea/TextArea.tsx +91 -84
  69. package/src/stories/theme/index.ts +1 -1
  70. package/src/stories/theme/themes.ts +423 -424
  71. package/src/stories/theme/tokens.ts +3 -3
  72. package/src/stories/theme/tw-preflight.css +4 -3
  73. package/src/stories/tilt/Tilt.stories.tsx +3 -6
  74. package/src/stories/tilt/Tilt.tsx +160 -126
  75. package/src/stories/toast/Toast.stories.tsx +2 -2
  76. package/src/stories/toast/Toast.tsx +3 -6
  77. package/src/stories/utility/RemoveFromDOM.tsx +9 -13
  78. package/src/stories/utility/TextWhenString.tsx +3 -16
  79. package/src/stories/utility/VisuallyHidden.tsx +10 -17
  80. package/src/styles/Home.module.css +185 -195
  81. package/src/styles/globals.css +0 -2
@@ -0,0 +1,293 @@
1
+ 'use client';
2
+
3
+ import { clsx } from 'clsx';
4
+ import type { FC, ReactNode } from 'react';
5
+ import { Children, isValidElement, memo, useMemo } from 'react';
6
+ import type { Components } from 'react-markdown';
7
+ import ReactMarkdown from 'react-markdown';
8
+ import rehypeRaw from 'rehype-raw';
9
+ import remarkGfm from 'remark-gfm';
10
+ import { Accordion } from '../accordion';
11
+ import { Callout } from '../callout';
12
+ import { StyledLink } from '../styledlink';
13
+ import type { TextProps } from '../text';
14
+ import { Text } from '../text';
15
+ import { pvar } from '../theme';
16
+ import styles from './Markdown.module.scss';
17
+
18
+ export type MarkdownSize = Extract<
19
+ TextProps['kind'],
20
+ 'paragraphLarge' | 'paragraphMedium' | 'paragraphSmall' | 'paragraphXSmall' | 'paragraphXXSmall'
21
+ >;
22
+
23
+ const smallerSize: Record<MarkdownSize, MarkdownSize> = {
24
+ paragraphLarge: 'paragraphMedium',
25
+ paragraphMedium: 'paragraphSmall',
26
+ paragraphSmall: 'paragraphXSmall',
27
+ paragraphXSmall: 'paragraphXXSmall',
28
+ paragraphXXSmall: 'paragraphXXSmall',
29
+ };
30
+
31
+ /**
32
+ * Extracts plain text from React children recursively.
33
+ * Useful for generating IDs from heading content.
34
+ */
35
+ function extractText(children: ReactNode): string {
36
+ return Children.toArray(children)
37
+ .map((child) => {
38
+ if (typeof child === 'string') return child;
39
+ if (typeof child === 'number') return String(child);
40
+ if (isValidElement<{ children?: ReactNode }>(child) && child.props?.children) {
41
+ return extractText(child.props.children);
42
+ }
43
+ return '';
44
+ })
45
+ .join('');
46
+ }
47
+
48
+ /**
49
+ * Maps heading level to Paris Text `kind` and HTML element.
50
+ */
51
+ const headingConfig = {
52
+ 1: { kind: 'headingLarge', as: 'h1' },
53
+ 2: { kind: 'headingMedium', as: 'h2' },
54
+ 3: { kind: 'headingSmall', as: 'h3' },
55
+ 4: { kind: 'headingXSmall', as: 'h4' },
56
+ 5: { kind: 'headingXXSmall', as: 'h5' },
57
+ 6: { kind: 'labelMedium', as: 'h6' },
58
+ } as const;
59
+
60
+ /**
61
+ * Creates a heading component for a given level (1–6).
62
+ */
63
+ function createHeading(level: keyof typeof headingConfig) {
64
+ const { kind, as } = headingConfig[level];
65
+ const HeadingComponent: Components[`h${typeof level}`] = ({ children }) => {
66
+ const id = extractText(children)
67
+ .toLowerCase()
68
+ .replace(/\s+/g, '-')
69
+ .replace(/[^\w-]/g, '');
70
+ return (
71
+ <Text as={as} kind={kind} className={styles.heading} id={id}>
72
+ {children}
73
+ </Text>
74
+ );
75
+ };
76
+ return HeadingComponent;
77
+ }
78
+
79
+ /**
80
+ * Builds the react-markdown component overrides for a given base text size.
81
+ */
82
+ function createMarkdownComponents(size: MarkdownSize): Components {
83
+ const ddSize = smallerSize[size];
84
+
85
+ return {
86
+ // ── Headings ──────────────────────────────────────────────
87
+ h1: createHeading(1),
88
+ h2: createHeading(2),
89
+ h3: createHeading(3),
90
+ h4: createHeading(4),
91
+ h5: createHeading(5),
92
+ h6: createHeading(6),
93
+
94
+ // ── Paragraphs & inline text ─────────────────────────────
95
+ p: ({ children }) => (
96
+ <Text as="p" kind={size} className={styles.paragraph}>
97
+ {children}
98
+ </Text>
99
+ ),
100
+ strong: ({ children }) => (
101
+ <Text as="span" kind={size} weight="semibold">
102
+ {children}
103
+ </Text>
104
+ ),
105
+ em: ({ children }) => (
106
+ <Text as="span" kind={size} fontStyle="italic">
107
+ {children}
108
+ </Text>
109
+ ),
110
+ del: ({ children }) => <span className={styles.strikethrough}>{children}</span>,
111
+
112
+ // ── Links & images ───────────────────────────────────────
113
+ a: ({ href, children }) => (
114
+ <StyledLink href={href} target="_blank" rel="noopener noreferrer">
115
+ {children}
116
+ </StyledLink>
117
+ ),
118
+ img: ({ src, alt }) => (
119
+ <span className={styles.imageWrapper}>
120
+ <img src={src} alt={alt || ''} className={styles.image} loading="lazy" />
121
+ </span>
122
+ ),
123
+
124
+ // ── Blockquotes ──────────────────────────────────────────
125
+ blockquote: ({ children }) => (
126
+ <Callout variant="default" icon={null} className={styles.blockquote}>
127
+ {children}
128
+ </Callout>
129
+ ),
130
+
131
+ // ── Horizontal rules ─────────────────────────────────────
132
+ hr: () => <hr className={styles.hr} />,
133
+
134
+ // ── Lists ────────────────────────────────────────────────
135
+ ul: ({ children, className }) => {
136
+ const isTaskList = className === 'contains-task-list';
137
+ return (
138
+ <ul className={clsx(styles.list, styles.unorderedList, isTaskList && styles.taskList)}>{children}</ul>
139
+ );
140
+ },
141
+ ol: ({ children, start }) => (
142
+ <ol className={clsx(styles.list, styles.orderedList)} start={start}>
143
+ {children}
144
+ </ol>
145
+ ),
146
+ li: ({ children, className }) => {
147
+ const isTask = className === 'task-list-item';
148
+ return <li className={clsx(styles.listItem, isTask && styles.taskListItem)}>{children}</li>;
149
+ },
150
+
151
+ // ── Code ─────────────────────────────────────────────────
152
+ code: ({ children, className }) => {
153
+ const languageMatch = className?.match(/language-(\w+)/);
154
+ const isBlock = !!languageMatch;
155
+
156
+ if (isBlock) {
157
+ return (
158
+ <div className={styles.codeBlockWrapper}>
159
+ {languageMatch?.[1] && (
160
+ <div className={styles.codeLanguage}>
161
+ <Text as="span" kind="labelXSmall" weight="medium">
162
+ {languageMatch[1]}
163
+ </Text>
164
+ </div>
165
+ )}
166
+ <code className={clsx(styles.codeBlock, className)}>{children}</code>
167
+ </div>
168
+ );
169
+ }
170
+
171
+ return <code className={styles.inlineCode}>{children}</code>;
172
+ },
173
+ pre: ({ children }) => <pre className={styles.pre}>{children}</pre>,
174
+
175
+ // ── Tables ───────────────────────────────────────────────
176
+ table: ({ children }) => (
177
+ <div className={styles.tableWrapper}>
178
+ <table className={styles.table}>{children}</table>
179
+ </div>
180
+ ),
181
+ thead: ({ children }) => <thead className={styles.thead}>{children}</thead>,
182
+ tbody: ({ children }) => <tbody className={styles.tbody}>{children}</tbody>,
183
+ tr: ({ children }) => <tr className={styles.tr}>{children}</tr>,
184
+ th: ({ children, style }) => (
185
+ <th className={styles.th} style={style}>
186
+ <Text as="span" kind="labelXSmall" weight="semibold">
187
+ {children}
188
+ </Text>
189
+ </th>
190
+ ),
191
+ td: ({ children, style }) => (
192
+ <td className={styles.td} style={style}>
193
+ {children}
194
+ </td>
195
+ ),
196
+
197
+ // ── HTML passthrough elements ────────────────────────────
198
+ details: ({ children }) => {
199
+ const childArray = Children.toArray(children);
200
+ let summaryContent: ReactNode = 'Details';
201
+ const bodyContent: ReactNode[] = [];
202
+
203
+ for (const child of childArray) {
204
+ if (isValidElement<{ children?: ReactNode }>(child) && child.type === 'summary') {
205
+ summaryContent = child.props.children;
206
+ } else {
207
+ bodyContent.push(child);
208
+ }
209
+ }
210
+
211
+ return (
212
+ <Accordion title={summaryContent} kind="card" size="small">
213
+ <div className={styles.accordionBody}>{bodyContent}</div>
214
+ </Accordion>
215
+ );
216
+ },
217
+ summary: () => null,
218
+
219
+ kbd: ({ children }) => <kbd className={styles.kbd}>{children}</kbd>,
220
+ sup: ({ children }) => <sup className={styles.sup}>{children}</sup>,
221
+ sub: ({ children }) => <sub className={styles.sub}>{children}</sub>,
222
+ mark: ({ children }) => <mark className={styles.mark}>{children}</mark>,
223
+
224
+ // ── Definition lists (HTML passthrough) ──────────────────
225
+ dl: ({ children }) => <dl className={styles.dl}>{children}</dl>,
226
+ dt: ({ children }) => (
227
+ <dt className={styles.dt}>
228
+ <Text as="span" kind={size} weight="semibold">
229
+ {children}
230
+ </Text>
231
+ </dt>
232
+ ),
233
+ dd: ({ children }) => (
234
+ <dd className={styles.dd}>
235
+ <Text as="span" kind={ddSize} color={pvar('new.colors.contentSecondary')}>
236
+ {children}
237
+ </Text>
238
+ </dd>
239
+ ),
240
+ };
241
+ }
242
+
243
+ export type MarkdownProps = {
244
+ /** The markdown string to render. */
245
+ children: string;
246
+ /** An optional CSS class name for the wrapper element. */
247
+ className?: string;
248
+ /**
249
+ * The base text size for body content (paragraphs, list items, inline text).
250
+ * Maps to Paris paragraph typography variants. Headings and labels are unaffected.
251
+ * @default 'paragraphSmall'
252
+ */
253
+ size?: MarkdownSize;
254
+ };
255
+
256
+ /**
257
+ * A `Markdown` component renders a markdown string using Paris design system components.
258
+ *
259
+ * It supports GitHub-flavored markdown (tables, task lists, strikethrough, footnotes)
260
+ * and HTML passthrough for elements like `<kbd>`, `<mark>`, `<details>`, and `<dl>`.
261
+ *
262
+ * <hr />
263
+ *
264
+ * To use this component, import it as follows:
265
+ *
266
+ * ```tsx
267
+ * import { Markdown } from 'paris/markdown';
268
+ *
269
+ * export const Example: FC = () => (
270
+ * <Markdown>{`# Hello World\n\nThis is **bold** and *italic* text.`}</Markdown>
271
+ * );
272
+ * ```
273
+ *
274
+ * @constructor
275
+ */
276
+ export const Markdown: FC<MarkdownProps> = memo(({ children, className, size = 'paragraphSmall' }) => {
277
+ const components = useMemo(() => createMarkdownComponents(size), [size]);
278
+
279
+ return (
280
+ <div
281
+ className={clsx(styles.markdown, className)}
282
+ style={
283
+ {
284
+ '--markdown-base-font-size': `var(--pte-new-typography-styles-${size}-fontSize)`,
285
+ } as React.CSSProperties
286
+ }
287
+ >
288
+ <ReactMarkdown remarkPlugins={[remarkGfm]} rehypePlugins={[rehypeRaw]} components={components}>
289
+ {children}
290
+ </ReactMarkdown>
291
+ </div>
292
+ );
293
+ });
@@ -0,0 +1 @@
1
+ export * from './Markdown';
@@ -20,6 +20,15 @@
20
20
 
21
21
  overflow: hidden;
22
22
  z-index: 100;
23
+
24
+ transition: var(--pte-animations-interaction);
25
+ opacity: 1;
26
+ transform: translateY(0);
27
+
28
+ &[data-closed] {
29
+ opacity: 0;
30
+ transform: translateY(-8px);
31
+ }
23
32
  }
24
33
 
25
34
  .leftPosition {
@@ -1,9 +1,7 @@
1
- import type { Meta, StoryObj } from '@storybook/react';
2
- import {
3
- Menu, MenuButton, MenuItems, MenuItem,
4
- } from './Menu';
1
+ import type { Meta, StoryObj } from '@storybook/nextjs-vite';
5
2
  import { Button } from '../button';
6
3
  import { ChevronRight, Ellipsis } from '../icon';
4
+ import { Menu, MenuButton, MenuItem, MenuItems } from './Menu';
7
5
 
8
6
  const meta: Meta<typeof Menu> = {
9
7
  title: 'Surfaces/Menu',
@@ -18,15 +16,11 @@ export const Default: Story = {
18
16
  args: {
19
17
  children: 'Hello world! This is a new Menu component.',
20
18
  },
21
- render: (args) => (
19
+ render: (_args) => (
22
20
  <div style={{ height: '150px' }}>
23
21
  <Menu as="div">
24
22
  <MenuButton>
25
- <Button
26
- kind="tertiary"
27
- shape="circle"
28
- startEnhancer={<Ellipsis size={20} />}
29
- >
23
+ <Button kind="tertiary" shape="circle" startEnhancer={<Ellipsis size={20} />}>
30
24
  Action menu
31
25
  </Button>
32
26
  </MenuButton>
@@ -1,14 +1,14 @@
1
- import type { FC } from 'react';
2
- import type {
3
- MenuProps, MenuItemsProps, MenuItemProps, MenuButtonProps,
4
- } from '@headlessui/react';
1
+ import type { MenuButtonProps, MenuItemProps, MenuItemsProps, MenuProps } from '@headlessui/react';
5
2
  import {
6
- Menu as HeadlessMenu, MenuButton as HMenuButton, MenuItems as HMenuItems, MenuItem as HMenuItem, Transition,
3
+ Menu as HeadlessMenu,
4
+ MenuButton as HMenuButton,
5
+ MenuItem as HMenuItem,
6
+ MenuItems as HMenuItems,
7
7
  } from '@headlessui/react';
8
8
  import { clsx } from 'clsx';
9
+ import type { FC } from 'react';
9
10
 
10
11
  import styles from './Menu.module.scss';
11
- import dropdownStyles from '../utility/Dropdown.module.scss';
12
12
 
13
13
  /**
14
14
  * Wraps the `HeadlessMenu` component from `@headlessui/react` to provide a styled dropdown menu.
@@ -51,25 +51,23 @@ export const MenuButton: FC<MenuButtonProps<React.ElementType>> = ({ className,
51
51
  *
52
52
  * @param position - Controls the positioning of the menu items ('left' or 'right').
53
53
  */
54
- export const MenuItems: FC<MenuItemsProps<React.ElementType> & {
55
- position?: 'left' | 'right';
56
- }> = ({
57
- className, children, position = 'left', ...props
58
- }) => (
59
- <Transition
60
- as="div"
61
- className={dropdownStyles.transitionContainer}
62
- enter={dropdownStyles.transition}
63
- enterFrom={dropdownStyles.enterFrom}
64
- enterTo={dropdownStyles.enterTo}
65
- leave={dropdownStyles.transition}
66
- leaveFrom={dropdownStyles.leaveFrom}
67
- leaveTo={dropdownStyles.leaveTo}
54
+ export const MenuItems: FC<
55
+ MenuItemsProps<React.ElementType> & {
56
+ position?: 'left' | 'right';
57
+ }
58
+ > = ({ className, children, position = 'left', ...props }) => (
59
+ <HMenuItems
60
+ transition
61
+ className={clsx(
62
+ styles.menuItems,
63
+ position === 'left' && styles.leftPosition,
64
+ position === 'right' && styles.rightPosition,
65
+ className,
66
+ )}
67
+ {...props}
68
68
  >
69
- <HMenuItems className={clsx(styles.menuItems, position === 'left' && styles.leftPosition, position === 'right' && styles.rightPosition, className)} {...props}>
70
- {children}
71
- </HMenuItems>
72
- </Transition>
69
+ {children}
70
+ </HMenuItems>
73
71
  );
74
72
 
75
73
  /**
@@ -79,11 +77,11 @@ export const MenuItems: FC<MenuItemsProps<React.ElementType> & {
79
77
  *
80
78
  * @param isNew - Whether the menu items should be styled as new items.
81
79
  */
82
- export const MenuItem: FC<MenuItemProps<React.ElementType> & {
83
- isNew?: boolean;
84
- }> = ({
85
- className, children, isNew = false, ...props
86
- }) => (
80
+ export const MenuItem: FC<
81
+ MenuItemProps<React.ElementType> & {
82
+ isNew?: boolean;
83
+ }
84
+ > = ({ className, children, isNew = false, ...props }) => (
87
85
  <HMenuItem className={clsx(styles.menuItem, isNew && styles.newItem, className)} {...props}>
88
86
  {children}
89
87
  </HMenuItem>
@@ -4,47 +4,47 @@ export type PaginationState<T extends string[] | readonly string[] = string[]> =
4
4
  /**
5
5
  * The current page key.
6
6
  */
7
- currentPage: T[number],
7
+ currentPage: T[number];
8
8
 
9
9
  /**
10
10
  * Open a page and add it to the history.
11
11
  * @param page - The page's unique key.
12
12
  */
13
- open: (page: T[number]) => void,
13
+ open: (page: T[number]) => void;
14
14
 
15
15
  /**
16
16
  * Check if the current page can go back.
17
17
  */
18
- canGoBack: () => boolean,
18
+ canGoBack: () => boolean;
19
19
 
20
20
  /**
21
21
  * Go back to the previous page.
22
22
  *
23
23
  * If the current page is the first page, nothing happens.
24
24
  */
25
- back: () => void,
25
+ back: () => void;
26
26
 
27
27
  /**
28
28
  * Check if the current page can go forward.
29
29
  */
30
- canGoForward: () => boolean,
30
+ canGoForward: () => boolean;
31
31
 
32
32
  /**
33
33
  * Go forward to the next page.
34
34
  *
35
35
  * If there is no next page, nothing happens.
36
36
  */
37
- forward: () => void,
37
+ forward: () => void;
38
38
 
39
39
  /**
40
40
  * The page history.
41
41
  */
42
- history: T[number][],
42
+ history: T[number][];
43
43
 
44
44
  /**
45
45
  * Clear the page history and reset to the initial page.
46
46
  */
47
- reset: () => void,
47
+ reset: () => void;
48
48
  };
49
49
 
50
50
  /**
@@ -1,7 +1,7 @@
1
- import type { Meta, StoryObj } from '@storybook/react';
1
+ import type { Meta, StoryObj } from '@storybook/nextjs-vite';
2
2
  import { createElement } from 'react';
3
- import { Popover } from './Popover';
4
3
  import { Button } from '../button';
4
+ import { Popover } from './Popover';
5
5
 
6
6
  const meta: Meta<typeof Popover> = {
7
7
  title: 'Surfaces/Popover',
@@ -1,14 +1,12 @@
1
1
  'use client';
2
2
 
3
- import type {
4
- ComponentPropsWithoutRef, FC, ReactElement, ReactNode,
5
- } from 'react';
3
+ import { clsx } from 'clsx';
4
+ import type { ComponentPropsWithoutRef, FC, ReactElement, ReactNode } from 'react';
6
5
  import { forwardRef, useState } from 'react';
7
6
  import type { PopoverProps as RTPopoverProps } from 'react-tiny-popover';
8
7
  import { Popover as RTPopover } from 'react-tiny-popover';
9
- import { clsx } from 'clsx';
10
- import styles from './Popover.module.scss';
11
8
  import typography from '../text/Typography.module.css';
9
+ import styles from './Popover.module.scss';
12
10
 
13
11
  // TODO(URGENT): Figure out how to properly handle accessibility; the popover content should capture focus for tabbing and clicking, and `esc` should allow closing the popover. Might be better to use Radix popover instead of react-tiny-popover?
14
12
 
@@ -68,11 +66,7 @@ export const Popover: FC<PopoverProps> = ({
68
66
  padding={padding || 8}
69
67
  isOpen={typeof isOpen === 'undefined' ? open : isOpen}
70
68
  containerClassName={clsx(typography.paragraphSmall, styles.content)}
71
- content={(
72
- <>
73
- {children}
74
- </>
75
- )}
69
+ content={<>{children}</>}
76
70
  onClickOutside={() => {
77
71
  setIsOpen?.(false);
78
72
  setOpen(false);
@@ -1,7 +1,7 @@
1
- import type { Meta, StoryObj } from '@storybook/react';
1
+ import type { Meta, StoryObj } from '@storybook/nextjs-vite';
2
2
  import { createElement, useState } from 'react';
3
- import { Select } from './Select';
4
3
  import { Text } from '../text';
4
+ import { Select } from './Select';
5
5
 
6
6
  const meta: Meta<typeof Select> = {
7
7
  title: 'Inputs/Select',
@@ -25,15 +25,15 @@ const render: Story['render'] = function Render(args) {
25
25
  Select,
26
26
  args.multiple
27
27
  ? {
28
- ...args,
29
- value: selectedMultiple,
30
- onChange: (value: string[] | null) => setSelectedMultiple(value),
31
- }
28
+ ...args,
29
+ value: selectedMultiple,
30
+ onChange: (value: string[] | null) => setSelectedMultiple(value),
31
+ }
32
32
  : {
33
- ...args,
34
- value: selected,
35
- onChange: (value: string | null) => setSelected(value),
36
- },
33
+ ...args,
34
+ value: selected,
35
+ onChange: (value: string | null) => setSelected(value),
36
+ },
37
37
  ),
38
38
  );
39
39
  };