@fpkit/acss 0.4.19 → 0.5.2

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 (119) hide show
  1. package/libs/chunk-TBM2QIVT.js +8 -0
  2. package/libs/chunk-TBM2QIVT.js.map +1 -0
  3. package/libs/chunk-VAH6X2DZ.cjs +31 -0
  4. package/libs/chunk-VAH6X2DZ.cjs.map +1 -0
  5. package/libs/components/badge/badge.css +1 -1
  6. package/libs/components/badge/badge.css.map +1 -1
  7. package/libs/components/badge/badge.min.css +2 -2
  8. package/libs/components/buttons/button.css +1 -1
  9. package/libs/components/buttons/button.css.map +1 -1
  10. package/libs/components/buttons/button.min.css +2 -2
  11. package/libs/components/cards/card.css +1 -1
  12. package/libs/components/cards/card.css.map +1 -1
  13. package/libs/components/cards/card.min.css +2 -2
  14. package/libs/components/details/details.css +1 -1
  15. package/libs/components/details/details.css.map +1 -1
  16. package/libs/components/details/details.min.css +2 -2
  17. package/libs/components/icons/icon.css +1 -1
  18. package/libs/components/icons/icon.css.map +1 -1
  19. package/libs/components/icons/icon.min.css +2 -2
  20. package/libs/{icons-1f5afc0c.d.ts → icons-2f29127c.d.ts} +32 -1
  21. package/libs/icons.cjs +2 -2
  22. package/libs/icons.d.cts +1 -1
  23. package/libs/icons.d.ts +1 -1
  24. package/libs/icons.js +1 -1
  25. package/libs/index.cjs +37 -37
  26. package/libs/index.cjs.map +1 -1
  27. package/libs/index.css +1 -1
  28. package/libs/index.css.map +1 -1
  29. package/libs/index.d.cts +8 -5
  30. package/libs/index.d.ts +8 -5
  31. package/libs/index.js +6 -6
  32. package/libs/index.js.map +1 -1
  33. package/package.json +3 -2
  34. package/src/components/badge/badge.scss +1 -0
  35. package/src/components/badge/badge.stories.tsx +3 -3
  36. package/src/components/breadcrumbs/breadcrumb.stories.tsx +26 -10
  37. package/src/components/breadcrumbs/breadcrumb.tsx +48 -40
  38. package/src/components/buttons/button.scss +3 -4
  39. package/src/components/buttons/button.stories.tsx +50 -28
  40. package/src/components/buttons/button.test.tsx +1 -1
  41. package/src/components/buttons/button.tsx +31 -4
  42. package/src/components/cards/card.scss +5 -3
  43. package/src/components/cards/card.stories.tsx +4 -4
  44. package/src/components/cards/card.tsx +0 -1
  45. package/src/components/details/details.scss +12 -3
  46. package/src/components/details/details.stories.tsx +20 -4
  47. package/src/components/details/details.tsx +2 -1
  48. package/src/components/form/form.stories.tsx +2 -2
  49. package/src/components/form/input.stories.tsx +2 -2
  50. package/src/components/form/select.stories.tsx +2 -2
  51. package/src/components/form/select.tsx +23 -33
  52. package/src/components/fp.test.tsx +1 -1
  53. package/src/components/heading/heading.stories.tsx +2 -2
  54. package/src/components/heading/heading.tsx +2 -2
  55. package/src/components/icons/components/svg.tsx +1 -0
  56. package/src/components/icons/icon.scss +2 -0
  57. package/src/components/icons/icon.stories.tsx +23 -3
  58. package/src/components/icons/icon.tsx +11 -0
  59. package/src/components/icons/types.ts +1 -1
  60. package/src/components/images/figure.stories.tsx +3 -6
  61. package/src/components/images/img.stories.tsx +3 -3
  62. package/src/components/layout/footer.stories.tsx +2 -2
  63. package/src/components/layout/landmarks.stories.tsx +2 -2
  64. package/src/components/layout/main.stories.tsx +2 -2
  65. package/src/components/link/link.stories.tsx +2 -2
  66. package/src/components/list/list.stories.tsx +7 -2
  67. package/src/components/nav/nav.stories.tsx +4 -3
  68. package/src/components/popover/popover.stories.tsx +2 -2
  69. package/src/components/progress/progress.stories.tsx +2 -2
  70. package/src/components/tag/tag.stories.tsx +3 -3
  71. package/src/components/text/text.stories.tsx +6 -6
  72. package/src/patterns/page/page-header.stories.tsx +2 -2
  73. package/src/sass/_globals.scss +9 -7
  74. package/src/styles/badge/badge.css +1 -0
  75. package/src/styles/badge/badge.css.map +1 -1
  76. package/src/styles/buttons/button.css +3 -3
  77. package/src/styles/buttons/button.css.map +1 -1
  78. package/src/styles/cards/card.css +2 -3
  79. package/src/styles/cards/card.css.map +1 -1
  80. package/src/styles/details/details.css +11 -3
  81. package/src/styles/details/details.css.map +1 -1
  82. package/src/styles/icons/icon.css +2 -0
  83. package/src/styles/icons/icon.css.map +1 -1
  84. package/src/styles/index.css +26 -16
  85. package/src/styles/index.css.map +1 -1
  86. package/LICENSE +0 -21
  87. package/dist/chunk-77CZU5XZ.cjs +0 -9
  88. package/dist/chunk-77CZU5XZ.cjs.map +0 -1
  89. package/dist/chunk-D43FJIRQ.cjs +0 -31
  90. package/dist/chunk-D43FJIRQ.cjs.map +0 -1
  91. package/dist/chunk-GJWMCDFS.js +0 -9
  92. package/dist/chunk-GJWMCDFS.js.map +0 -1
  93. package/dist/chunk-PCDUGD3C.js +0 -5
  94. package/dist/chunk-PCDUGD3C.js.map +0 -1
  95. package/dist/hooks.cjs +0 -10
  96. package/dist/hooks.cjs.map +0 -1
  97. package/dist/hooks.d.cts +0 -32
  98. package/dist/hooks.d.ts +0 -32
  99. package/dist/hooks.js +0 -8
  100. package/dist/hooks.js.map +0 -1
  101. package/dist/icon-e6044c73.d.ts +0 -227
  102. package/dist/icons.cjs +0 -73
  103. package/dist/icons.cjs.map +0 -1
  104. package/dist/icons.d.cts +0 -252
  105. package/dist/icons.d.ts +0 -252
  106. package/dist/icons.js +0 -4
  107. package/dist/icons.js.map +0 -1
  108. package/dist/index.cjs +0 -59
  109. package/dist/index.cjs.map +0 -1
  110. package/dist/index.d.cts +0 -566
  111. package/dist/index.d.ts +0 -566
  112. package/dist/index.js +0 -11
  113. package/dist/index.js.map +0 -1
  114. package/libs/chunk-QHIABQNQ.js +0 -8
  115. package/libs/chunk-QHIABQNQ.js.map +0 -1
  116. package/libs/chunk-ZOHIKF6I.cjs +0 -31
  117. package/libs/chunk-ZOHIKF6I.cjs.map +0 -1
  118. package/src/components/popover/node_modules/.vitest/results.json +0 -1
  119. package/src/hooks/popover/node_modules/.vitest/results.json +0 -1
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@fpkit/acss",
3
3
  "description": "A lightweight React UI library for building modern and accessible components that leverage CSS custom properties for reactive Styles.",
4
4
  "private": false,
5
- "version": "0.4.19",
5
+ "version": "0.5.2",
6
6
  "scripts": {
7
7
  "start": "run-p package:watch sass:watch",
8
8
  "dev": "vite --open",
@@ -26,6 +26,7 @@
26
26
  },
27
27
  "dependencies": {
28
28
  "focus-trap": "^7.5.2",
29
+ "jest-mock": "^29.7.0",
29
30
  "react": "^18.0.0",
30
31
  "react-dom": "^18.0.0"
31
32
  },
@@ -121,5 +122,5 @@
121
122
  "publishConfig": {
122
123
  "access": "public"
123
124
  },
124
- "gitHead": "9987edab37ae375b33c513cad2e254d62af064ca"
125
+ "gitHead": "2278d7751dcd37ed1799b84773926d9b0268e329"
125
126
  }
@@ -10,6 +10,7 @@ sup:has(> span) {
10
10
  padding: var(--badge-padding);
11
11
  border-radius: var(--badge-radius);
12
12
  vertical-align: var(--badge-v-align);
13
+ font-size: var(--badge-fs);
13
14
  span {
14
15
  color: inherit;
15
16
  }
@@ -1,9 +1,9 @@
1
1
  import { StoryObj, Meta } from '@storybook/react'
2
- import { within, userEvent, screen } from '@storybook/testing-library'
3
- import { expect } from '@storybook/jest'
2
+ import { within, expect } from '@storybook/test'
3
+
4
4
 
5
5
  import Badge from './badge'
6
- import './badge.scss'
6
+ // import './badge.scss'
7
7
 
8
8
  const meta: Meta<typeof Badge> = {
9
9
  title: 'FP.REACT Components/Badge',
@@ -1,9 +1,11 @@
1
- import { StoryObj, Meta } from '@storybook/react'
2
- import { within, userEvent, screen } from '@storybook/testing-library'
3
- import { expect } from '@storybook/jest'
1
+ import type { StoryObj, Meta } from '@storybook/react'
2
+ import { within, userEvent, fn, expect } from '@storybook/test'
3
+
4
4
 
5
5
  import Breadcrumb from './breadcrumb'
6
6
 
7
+ const linkClicked = fn()
8
+
7
9
  const meta: Meta<typeof Breadcrumb> = {
8
10
  title: 'FP.REACT Components/Breadcrumb',
9
11
  component: Breadcrumb,
@@ -16,10 +18,9 @@ const meta: Meta<typeof Breadcrumb> = {
16
18
  },
17
19
  },
18
20
  args: {
19
- // @ts-ignore
20
21
  children: 'Link',
21
22
  },
22
- } as Story
23
+ } as Meta
23
24
 
24
25
  export default meta
25
26
  type Story = StoryObj<typeof Breadcrumb>
@@ -75,13 +76,9 @@ export const EncodedBreadcrumbs: Story = {
75
76
  },
76
77
  ],
77
78
  currentRoute: '/products/learning%20in%20public',
79
+
78
80
  },
79
81
 
80
- play: async ({ canvasElement }) => {
81
- const canvas = within(canvasElement)
82
- await userEvent.click(screen.getByText('Shirts'))
83
- expect(screen.getByText('Shirts')).toBeInTheDocument()
84
- },
85
82
  } as Story
86
83
 
87
84
  export const TruncateName: Story = {
@@ -90,3 +87,22 @@ export const TruncateName: Story = {
90
87
  currentRoute: '/products/AveryLongNameTruncate',
91
88
  },
92
89
  } as Story
90
+
91
+ export const ClickHomeLink: Story = {
92
+ args: {
93
+ ...CustomURL.args,
94
+ currentRoute: '/products/shirts',
95
+ startRouteUrl: "#",
96
+ linkProps: {
97
+ onClick: linkClicked,
98
+ },
99
+ },
100
+
101
+ play: async ({ canvasElement }) => {
102
+ const canvas = within(canvasElement)
103
+ const homeLink = canvas.getByRole('link', { name: 'Home' })
104
+ expect(homeLink).toHaveAttribute('href', '#')
105
+ // await userEvent.click(homeLink)
106
+ // expect(linkClicked).toHaveBeenCalled()
107
+ },
108
+ } as Story
@@ -2,6 +2,7 @@
2
2
  import React from 'react'
3
3
  import UI from '#components/ui'
4
4
  import { Truncate } from '#libs/content'
5
+ import Link from '#components/link/link'
5
6
 
6
7
  // TYPES
7
8
 
@@ -19,6 +20,8 @@ type BreadcrumbProps = {
19
20
  routes?: customRoute[]
20
21
  /** Starting route node */
21
22
  startRoute?: React.ReactNode
23
+ /* Starting route url */
24
+ startRouteUrl?: string
22
25
  /** Spacer node between routes */
23
26
  spacer?: React.ReactNode
24
27
  /** String representing current route */
@@ -27,6 +30,8 @@ type BreadcrumbProps = {
27
30
  ariaLabelPrefix?: string
28
31
  /** Truncate breadcrumb text after this length */
29
32
  truncateLength?: number
33
+ /** Link props for breadcrumb links */
34
+ linkProps?: React.ComponentProps<typeof Link>
30
35
  } & React.ComponentProps<typeof UI>
31
36
 
32
37
  // Components
@@ -106,6 +111,7 @@ const Nav = ({
106
111
  */
107
112
  export const Breadcrumb = ({
108
113
  startRoute = 'Home',
114
+ startRouteUrl = "/",
109
115
  currentRoute,
110
116
  spacer = <>&#47;</>,
111
117
  routes,
@@ -114,6 +120,7 @@ export const Breadcrumb = ({
114
120
  classes,
115
121
  ariaLabelPrefix,
116
122
  truncateLength = 15,
123
+ linkProps,
117
124
  ...props
118
125
  }: BreadcrumbProps): React.JSX.Element => {
119
126
  const [currentPath, setCurrentPath] = React.useState('')
@@ -122,7 +129,7 @@ export const Breadcrumb = ({
122
129
  if (path.length) {
123
130
  setCurrentPath(path)
124
131
  }
125
- }, [])
132
+ }, [currentRoute])
126
133
 
127
134
  /**
128
135
  * Gets the path name for the given path segment.
@@ -148,6 +155,7 @@ export const Breadcrumb = ({
148
155
  /** Unique id for breadcrumb */
149
156
  const uuid = React.useId()
150
157
 
158
+
151
159
  return currentPath.length ? (
152
160
  <Nav
153
161
  id={id}
@@ -157,53 +165,53 @@ export const Breadcrumb = ({
157
165
  aria-label={ariaLabelPrefix}
158
166
  >
159
167
  <Items key={`${startRoute}-${uuid}`}>
160
- <a href="/">{startRoute}</a>
168
+ <Link href={startRouteUrl} {...linkProps}>{startRoute}</Link>
161
169
  </Items>
170
+ <>
162
171
  {segments.length ? (
163
172
  segments.map((segment: any, index: number) => {
164
173
  const currentSegment = getPathName(segment)
165
174
  const { name, url, path } = currentSegment
166
- if (index === lastSegment) {
167
- return (
168
- <>
169
- {typeof segments[lastSegment] === 'string' &&
170
- segments[lastSegment].length > 3 &&
171
- segments[lastSegment] !== segments[lastSegment - 1] && (
172
- <Items key={`${path || index}-${uuid}`}>
173
- <>
174
- <span aria-hidden="true">{spacer}</span>
175
- <a
176
- aria-current="page"
177
- aria-label={
178
- name.length > truncateLength ? name : undefined
179
- }
180
- >
181
- {Truncate(decodeURIComponent(name), truncateLength)}
182
- </a>
183
- </>{' '}
184
- </Items>
185
- )}
186
- </>
187
- )
188
- } else {
189
- return (
190
- <Items key={`${currentSegment?.name}-${uuid}`}>
191
- <span aria-hidden="true">{spacer}</span>
192
- <span>
193
- <a
194
- href={url}
195
- aria-label={name.length > truncateLength ? name : undefined}
196
- >
197
- {Truncate(decodeURIComponent(name), truncateLength)}
198
- </a>
199
- </span>
200
- </Items>
201
- )
202
- }
175
+ return index === lastSegment ? (
176
+ <>
177
+ {typeof segments[lastSegment] === 'string' &&
178
+ segments[lastSegment].length > 3 &&
179
+ segments[lastSegment] !== segments[lastSegment - 1] && (
180
+ <Items key={`${path || index}-${uuid}`}>
181
+
182
+ <span aria-hidden="true">{spacer}</span>
183
+ <a
184
+ href="#"
185
+ aria-current="page"
186
+ aria-label={
187
+ name.length > truncateLength ? name : undefined
188
+ }
189
+ >
190
+ {Truncate(decodeURIComponent(name), truncateLength)}
191
+ </a>
192
+
193
+ </Items>
194
+ )}
195
+ </>
196
+ ) : (
197
+ <Items key={`${currentSegment?.name}-${uuid}`}>
198
+ <span aria-hidden="true">{spacer}</span>
199
+ <span>
200
+ <Link
201
+ href={url}
202
+ aria-label={name.length > truncateLength ? name : undefined}
203
+ {...linkProps}
204
+ >
205
+ {Truncate(decodeURIComponent(name), truncateLength)}
206
+ </Link>
207
+ </span>
208
+ </Items>
209
+ );
203
210
  })
204
211
  ) : (
205
- <></>
212
+ null
206
213
  )}
214
+ </>
207
215
  </Nav>
208
216
  ) : (
209
217
  <></>
@@ -3,9 +3,9 @@ button {
3
3
  --btn-md: calc(16rem / 16);
4
4
  --btn-lg: calc(21rem / 16);
5
5
  --btn-pill: 100rem;
6
- --btn-height: calc(40rem / 16);
6
+ --btn-height: 2.5rem;
7
7
  --fs: 0.95rem;
8
- --btn-fs: calc(15rem / 16);
8
+ --btn-fs: 0.9375rem;
9
9
  --btn-bg: lightgray;
10
10
  --btn-width: max-content;
11
11
 
@@ -58,7 +58,7 @@ button {
58
58
  background-color: var(--btn-bg, var(--btn, lightgray));
59
59
  filter: invert(1) hue-rotate (180deg);
60
60
  transform: scale(0.95) var(--line-style, solid);
61
- outline-offset: var(--line-offset, 5px);
61
+ outline-offset: var(--line-offset, 1px);
62
62
 
63
63
  &[aria-disabled='true'] {
64
64
  transform: none;
@@ -105,7 +105,6 @@ button {
105
105
  --btn-width: unset;
106
106
  --btn-py: 0.75rem;
107
107
  --btn-px: 0.75rem;
108
-
109
108
  &:is(:hover, :focus) {
110
109
  background-color: transparent;
111
110
  outline: 0.07rem solid var(--btn-cl);
@@ -1,57 +1,79 @@
1
- import { StoryObj, Meta } from '@storybook/react'
2
- import { within, userEvent } from '@storybook/testing-library'
3
- import { expect } from '@storybook/jest'
1
+ import type { StoryObj, Meta } from "@storybook/react";
2
+ import { within, userEvent, expect, fn } from "@storybook/test";
4
3
 
5
- import Button from './button'
6
- import './button.scss'
4
+ import Button from "./button";
5
+ import "./button.scss";
7
6
 
8
- const meta: Meta<typeof Button> = {
9
- title: 'FP.React Components/Buttons',
7
+ const buttonClicked = fn();
8
+
9
+ const meta = {
10
+ title: "FP.React Components/Buttons",
10
11
  component: Button,
11
12
  args: {
12
- children: 'Click me',
13
+ children: "Click me",
14
+ onClick: buttonClicked,
13
15
  },
14
16
  parameters: {
15
- // actions: { argTypesRegex: '^on.*' },
17
+ actions: { argTypesRegex: '^on.*' },
16
18
  },
17
- argTypes: { onClick: { action: 'clicked' } },
18
- } as Meta
19
+ } as Meta;
19
20
 
20
- export default meta
21
- type Story = StoryObj<typeof Button>
21
+ export default meta;
22
+ type Story = StoryObj<typeof Button>;
22
23
 
23
24
  export const ButtonComponent: Story = {
24
- args: {},
25
- play: async ({ canvasElement }) => {
26
- const canvas = within(canvasElement)
27
- expect(canvas.getByRole('button')).toBeInTheDocument()
28
- await userEvent.tab()
29
- expect(canvas.getByRole('button')).toHaveFocus()
25
+ args: {
26
+ onClick: buttonClicked,
27
+ },
28
+ play: async ({ canvasElement, step }) => {
29
+ const canvas = within(canvasElement);
30
+ const button = canvas.getByRole("button");
31
+ await step("Button is rendered", async () => {
32
+ expect(button).toBeInTheDocument();
33
+ });
34
+ await step("Button gets focus on tab", async () => {
35
+ await userEvent.tab();
36
+ expect(button).toHaveFocus();
37
+ });
38
+ await step("Button is clicked", async () => {
39
+ await userEvent.click(button);
40
+ expect(buttonClicked).toHaveBeenCalled();
41
+ });
42
+ // step to check for enter key press
43
+ await step("Button is clicked with enter key", async () => {
44
+ await userEvent.type(button, "{enter}");
45
+ expect(buttonClicked).toHaveBeenCalled();
46
+ });
47
+ // step check for space key press
48
+ await step("Button is clicked with space key", async () => {
49
+ await userEvent.type(button, "{space}");
50
+ expect(buttonClicked).toHaveBeenCalled();
51
+ });
30
52
  },
31
- } as Story
53
+ } as Story;
32
54
 
33
55
  export const Small: Story = {
34
56
  args: {
35
- 'data-btn': 'sm',
57
+ "data-btn": "sm",
36
58
  },
37
- } as Story
59
+ } as Story;
38
60
 
39
61
  export const Medium: Story = {
40
62
  args: {
41
- 'data-btn': 'md',
63
+ "data-btn": "md",
42
64
  },
43
- } as Story
65
+ } as Story;
44
66
 
45
67
  export const Large: Story = {
46
68
  args: {
47
- 'data-btn': 'lg',
69
+ "data-btn": "lg",
48
70
  },
49
- } as Story
71
+ } as Story;
50
72
 
51
73
  export const Custom: Story = {
52
74
  args: {
53
75
  styles: {
54
- '--btn-fs': '2rem',
76
+ "--btn-fs": "2rem",
55
77
  },
56
78
  },
57
- } as Story
79
+ } as Story;
@@ -3,7 +3,7 @@ import { render, screen } from '@testing-library/react'
3
3
  import { Button } from './button'
4
4
  import user from '@testing-library/user-event'
5
5
  import jest from 'jest-mock'
6
- import { userEvent } from '@storybook/testing-library'
6
+ import { userEvent } from '@storybook/test'
7
7
 
8
8
  describe('Button', () => {
9
9
  it('renders a button element with the correct label', () => {
@@ -1,8 +1,7 @@
1
1
  import UI from '../ui'
2
2
  import React from 'react'
3
3
 
4
- export type ButtonProps = React.ButtonHTMLAttributes<HTMLButtonElement> &
5
- Partial<React.ComponentProps<typeof UI>> & {
4
+ export type ButtonProps = Partial<React.ComponentProps<typeof UI>> & {
6
5
  /**
7
6
  * The button type
8
7
  * Required - 'button' | 'submit' | 'reset'
@@ -19,27 +18,54 @@ export const Button = ({
19
18
  onPointerDown,
20
19
  onPointerOver,
21
20
  onPointerLeave,
22
-
21
+ onClick,
23
22
  ...props
24
23
  }: ButtonProps) => {
24
+ /**
25
+ * Handles the pointer down event on the button.
26
+ * Only triggers the onPointerDown callback if the button is not disabled.
27
+ * @param e The pointer event object from the button element
28
+ */
25
29
  const handlePointerDown = (e: React.PointerEvent<HTMLButtonElement>) => {
26
30
  if (!disabled) {
27
31
  onPointerDown?.(e)
28
32
  }
29
33
  }
30
34
 
35
+ /**
36
+ * Handles the pointer over event on the button.
37
+ * Only triggers the onPointerOver callback if the button is not disabled.
38
+ * @param e The pointer event object from the button element
39
+ */
31
40
  const handlePointerOver = (e: React.PointerEvent<HTMLButtonElement>) => {
32
41
  if (!disabled) {
33
42
  onPointerOver?.(e)
34
43
  }
35
44
  }
36
45
 
46
+ /**
47
+ * Handles the pointer leave event on the button.
48
+ * Only triggers the onPointerLeave callback if the button is not disabled.
49
+ * @param e The pointer event object from the button element
50
+ */
37
51
  const handlePointerLeave = (e: React.PointerEvent<HTMLButtonElement>) => {
38
52
  if (!disabled) {
39
53
  onPointerLeave?.(e)
40
54
  }
41
55
  }
42
56
 
57
+ /**
58
+ * Handles the click event on the button.
59
+ * Only triggers the onClick callback if the button is not disabled.
60
+ * @param e The mouse event object from the button element
61
+ */
62
+ const handleOnClick = (e: React.MouseEvent<HTMLButtonElement>) => {
63
+ if (!disabled) {
64
+ onClick?.(e)
65
+ }
66
+ }
67
+
68
+
43
69
  /* Returning a button element. */
44
70
  return (
45
71
  <UI
@@ -48,10 +74,11 @@ export const Button = ({
48
74
  onPointerOver={handlePointerOver}
49
75
  onPointerDown={handlePointerDown}
50
76
  onPointerLeave={handlePointerLeave}
77
+ onKeyDown={handlePointerDown}
51
78
  style={styles}
52
79
  className={classes}
53
80
  aria-disabled={disabled}
54
- onClick={handlePointerDown}
81
+ onClick={handleOnClick}
55
82
  {...props}
56
83
  >
57
84
  {children}
@@ -5,8 +5,9 @@
5
5
  --card-position: relative;
6
6
  --card-display: flex;
7
7
  --card-direction: column;
8
- --card-gap: 1.5rem;
8
+ --card-gap: 1rem;
9
9
  }
10
+
10
11
  [data-card],
11
12
  [data-component~='card'] {
12
13
  display: var(--card-display);
@@ -15,11 +16,11 @@
15
16
  border-radius: var(--card-radius);
16
17
  background-color: var(--card-bg);
17
18
  text-align: var(--card-align, left);
18
-
19
- [data-card-content],
19
+
20
20
  h3,
21
21
  h2 {
22
22
  margin-block-end: 0;
23
+ padding-block-end: 0;
23
24
  }
24
25
  + div {
25
26
  margin-block-start: 0;
@@ -41,3 +42,4 @@
41
42
  padding-block-start: calc(var(--card-p) - 0.5rem);
42
43
  }
43
44
  }
45
+
@@ -1,6 +1,6 @@
1
1
  import { StoryObj, Meta } from '@storybook/react'
2
- import { within, userEvent, screen } from '@storybook/testing-library'
3
- import { expect } from '@storybook/jest'
2
+ import { within, userEvent, screen } from '@storybook/test'
3
+
4
4
 
5
5
  import Card from './card'
6
6
  // import './card.scss'
@@ -30,7 +30,7 @@ export const Multiple: Story = {
30
30
  },
31
31
  },
32
32
  render: (args) => (
33
- <>
33
+ <div style={{ display: 'flex', gap: '1rem', flexDirection: 'column' }}>
34
34
  <Card {...args}>
35
35
  <p>
36
36
  Proident et amet aliqua excepteur sunt qui deserunt commodo tempor
@@ -55,7 +55,7 @@ export const Multiple: Story = {
55
55
  culpa aliqua veniam.
56
56
  </p>
57
57
  </Card>
58
- </>
58
+ </div>
59
59
  ),
60
60
  } as Story
61
61
 
@@ -133,7 +133,6 @@ Footer.displayName = 'Footer'
133
133
  * @param {boolean} [props.renderStyles=true] - Whether to render default styles
134
134
  * @param {string} [props.dataStyle] - data-card attribute value
135
135
  * @param {string} [props.id] - Unique ID
136
- *
137
136
  * @returns {ReactElement} Card component
138
137
  */
139
138
  export const Card = ({
@@ -4,10 +4,10 @@ details {
4
4
  --details-border: 1px solid #dfdfdf;
5
5
  --details-display: flex;
6
6
  --details-justify: flex-start;
7
- --details-direction: columns;
8
- --details-gap: 5rem;
7
+ --details-direction: column;
8
+ --details-gap: 0rem;
9
9
  --details-px: 1.5rem;
10
- --details-py: 1.5rem;
10
+ --details-py: 1rem;
11
11
  --details-radius: 0.5rem;
12
12
  --summary-cursor: pointer;
13
13
  --summary-transitions: all 0.75s linear;
@@ -41,11 +41,19 @@ details {
41
41
  padding-block: var(--summary-py, var(--details-py));
42
42
  gap: var(--summary-gap);
43
43
  list-style: none;
44
+ border-top-left-radius: var(--details-radius);
45
+ border-top-right-radius: var(--details-radius);
44
46
 
45
47
  &::-webkit-details-marker {
46
48
  display: none;
47
49
  }
48
50
 
51
+ &:focus-within {
52
+ outline: none;
53
+ border-bottom: solid 2px var(--details-border);
54
+ background-color: whitesmoke;
55
+ }
56
+
49
57
  /* This ensures no bullet points are shown */
50
58
 
51
59
  &:hover {
@@ -59,6 +67,7 @@ details {
59
67
  > section {
60
68
  padding-inline: var(--details-px);
61
69
  padding-block: var(--details-py);
70
+ margin-block-start: 0;
62
71
  border: 1px transparent solid;
63
72
  }
64
73
 
@@ -1,10 +1,9 @@
1
1
  import { StoryObj, Meta } from '@storybook/react'
2
- import { within, userEvent, screen } from '@storybook/testing-library'
3
- import { expect } from '@storybook/jest'
2
+ import { within, expect, userEvent } from '@storybook/test'
3
+
4
4
 
5
5
  import Details from './details'
6
6
  import Icons from '../icons/icon'
7
- import '../../styles/details/details.css'
8
7
 
9
8
  const content = (
10
9
  <>
@@ -56,7 +55,7 @@ export const DetailsDropdown: Story = {
56
55
  args: {},
57
56
  play: async ({ canvasElement }) => {
58
57
  const canvas = within(canvasElement)
59
- expect(canvas.getByRole('group')).toBeInTheDocument()
58
+ expect(canvas.getByRole('group', { name: /details dropdown/i })).toBeInTheDocument()
60
59
  },
61
60
  } as Story
62
61
 
@@ -120,3 +119,20 @@ export const DetailsAccordion: Story = {
120
119
  </>
121
120
  )
122
121
  } as Story
122
+
123
+ export const DetailsInteractionTest: Story = {
124
+ args: {},
125
+ play: async ({ canvasElement }) => {
126
+ const canvas = within(canvasElement);
127
+
128
+ // Find the summary element
129
+ const summaryElement = canvas.getByText('Summary Section');
130
+
131
+ // Simulate a click on the summary element
132
+ await userEvent.click(summaryElement);
133
+
134
+ // Assert that the details element is open
135
+ const detailsElement = canvas.getByRole('group', { name: /details dropdown/i });
136
+ expect(detailsElement).toHaveAttribute('open');
137
+ },
138
+ }
@@ -61,10 +61,11 @@ export const Details = ({
61
61
  ref={ref}
62
62
  open={open}
63
63
  aria-label={ariaLabel || 'Details dropdown'}
64
+ // aria-roledescription="detail accordion"
64
65
  name={name}
65
66
  {...props}
66
67
  >
67
- <UI as="summary" role="group" onPointerDown={onPointerDownCallback}>
68
+ <UI as="summary" onPointerDown={onPointerDownCallback}>
68
69
  {icon}
69
70
  {summary}
70
71
  </UI>
@@ -1,6 +1,6 @@
1
1
  import { StoryObj, Meta } from '@storybook/react'
2
- import { within, userEvent, screen } from '@storybook/testing-library'
3
- import { expect } from '@storybook/jest'
2
+ import { within, expect } from '@storybook/test'
3
+
4
4
 
5
5
  import Form from './form'
6
6
  import './form.scss'
@@ -1,6 +1,6 @@
1
1
  import { StoryObj, Meta } from '@storybook/react'
2
- import { within, userEvent, screen } from '@storybook/testing-library'
3
- import { expect } from '@storybook/jest'
2
+ import { within, userEvent, expect } from '@storybook/test'
3
+
4
4
 
5
5
  import Input from './inputs'
6
6
  import './form.scss'