@regardio/react 0.6.0 → 0.7.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 (102) hide show
  1. package/dist/background-slideshow/index.d.mts +1 -3
  2. package/dist/blurry-gradient/index.d.mts +4 -5
  3. package/dist/button/index.d.mts +1 -1
  4. package/dist/carousel/index.d.mts +42 -8
  5. package/dist/carousel/index.mjs +11 -16
  6. package/dist/checkbox/index.d.mts +7 -16
  7. package/dist/checkbox-group/index.d.mts +3 -4
  8. package/dist/countdown/index.d.mts +1 -3
  9. package/dist/field/index.d.mts +40 -38
  10. package/dist/fieldset/index.d.mts +15 -14
  11. package/dist/form/index.d.mts +2 -3
  12. package/dist/generic-error/index.d.mts +20 -23
  13. package/dist/grid/index.d.mts +77 -1173
  14. package/dist/grid/index.mjs +5 -7
  15. package/dist/heading/index.d.mts +7 -11
  16. package/dist/heading/index.mjs +2 -3
  17. package/dist/highlight/index.d.mts +2 -3
  18. package/dist/hooks/use-current-route-data.d.mts +4 -4
  19. package/dist/hooks/use-current-route-data.mjs +3 -1
  20. package/dist/hooks/use-focus-search.mjs +2 -0
  21. package/dist/hooks/use-matches-data.d.mts +5 -5
  22. package/dist/hooks/use-matches-data.mjs +2 -0
  23. package/dist/hooks/use-media-query.d.mts +4 -4
  24. package/dist/hooks/use-media-query.mjs +2 -0
  25. package/dist/hooks/use-mobile.mjs +2 -0
  26. package/dist/hooks/use-nonce.d.mts +2 -4
  27. package/dist/hooks/use-orientation.d.mts +6 -6
  28. package/dist/hooks/use-orientation.mjs +2 -0
  29. package/dist/hooks/use-user.d.mts +23 -25
  30. package/dist/icon-button/index.d.mts +4 -5
  31. package/dist/if/index.d.mts +2 -4
  32. package/dist/if/index.mjs +4 -4
  33. package/dist/{index-Bm-tWhsb.d.mts → index-Bj5_XfEC.d.mts} +2 -3
  34. package/dist/{index-YT2CkvL6.d.mts → index-C_evL5vG.d.mts} +4 -5
  35. package/dist/input/index.d.mts +1 -1
  36. package/dist/link/index.d.mts +9 -11
  37. package/dist/link/index.mjs +3 -3
  38. package/dist/list/index.d.mts +39 -38
  39. package/dist/list/index.mjs +7 -7
  40. package/dist/markdown-container/index.d.mts +1 -1
  41. package/dist/markdown-container/index.mjs +1 -1
  42. package/dist/password-input/index.d.mts +4 -5
  43. package/dist/picture/index.d.mts +10 -10
  44. package/dist/protected-email/index.d.mts +9 -11
  45. package/dist/radio/index.d.mts +7 -16
  46. package/dist/radio-group/index.d.mts +3 -4
  47. package/dist/slider/index.d.mts +19 -41
  48. package/dist/switch/index.d.mts +7 -16
  49. package/dist/text/index.d.mts +2 -3
  50. package/dist/{text-CPlUND-Z.mjs → text-EQC4zJbE.mjs} +7 -13
  51. package/dist/toggle/index.d.mts +4 -38
  52. package/dist/utils/text/index.d.mts +5 -5
  53. package/dist/utils/text/index.mjs +1 -1
  54. package/package.json +170 -10
  55. package/src/background-slideshow/background-slideshow.tsx +1 -2
  56. package/src/blurry-gradient/blurry-gradient.tsx +1 -1
  57. package/src/button/button.stories.tsx +1 -1
  58. package/src/button/button.tsx +7 -1
  59. package/src/carousel/carousel-content.tsx +17 -14
  60. package/src/carousel/carousel-item.tsx +18 -18
  61. package/src/carousel/carousel-next.tsx +21 -16
  62. package/src/carousel/carousel-previous.tsx +21 -16
  63. package/src/carousel/carousel-root.tsx +91 -86
  64. package/src/checkbox/checkbox.tsx +14 -3
  65. package/src/checkbox-group/checkbox-group.tsx +1 -1
  66. package/src/countdown/countdown.tsx +1 -1
  67. package/src/field/field.stories.tsx +1 -1
  68. package/src/field/field.tsx +27 -6
  69. package/src/fieldset/fieldset.stories.tsx +1 -1
  70. package/src/fieldset/fieldset.tsx +14 -3
  71. package/src/form/form.stories.tsx +1 -1
  72. package/src/form/form.tsx +1 -1
  73. package/src/generic-error/generic-error.tsx +2 -3
  74. package/src/grid/grid-item.tsx +77 -36
  75. package/src/grid/grid-root.tsx +49 -22
  76. package/src/heading/heading.tsx +7 -3
  77. package/src/highlight/highlight.tsx +1 -1
  78. package/src/hooks/use-current-route-data.ts +4 -2
  79. package/src/hooks/use-focus-search.ts +3 -1
  80. package/src/hooks/use-matches-data.ts +2 -0
  81. package/src/hooks/use-media-query.ts +2 -0
  82. package/src/hooks/use-mobile.ts +3 -1
  83. package/src/hooks/use-nonce.ts +3 -3
  84. package/src/hooks/use-orientation.ts +2 -0
  85. package/src/hooks/use-user.tsx +3 -2
  86. package/src/icon-button/icon-button.tsx +1 -1
  87. package/src/if/if.tsx +3 -1
  88. package/src/input/input.stories.tsx +1 -1
  89. package/src/input/input.tsx +1 -1
  90. package/src/link/link.tsx +4 -3
  91. package/src/list/list-item.tsx +10 -13
  92. package/src/list/list-root-context.ts +3 -3
  93. package/src/list/list-root.tsx +10 -13
  94. package/src/password-input/password-input.tsx +1 -1
  95. package/src/protected-email/protected-email.tsx +6 -1
  96. package/src/radio/radio.tsx +14 -3
  97. package/src/radio-group/radio-group.tsx +5 -1
  98. package/src/slider/slider.tsx +29 -7
  99. package/src/switch/switch.tsx +14 -3
  100. package/src/text/text.tsx +6 -1
  101. package/src/toggle/toggle.tsx +3 -3
  102. package/src/utils/text/text.tsx +8 -16
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://www.schemastore.org/package.json",
3
3
  "name": "@regardio/react",
4
- "version": "0.6.0",
4
+ "version": "0.7.0",
5
5
  "private": false,
6
6
  "description": "Regardio React UI components",
7
7
  "keywords": [
@@ -26,14 +26,174 @@
26
26
  ],
27
27
  "type": "module",
28
28
  "exports": {
29
- "./tailwind.css": "./src/tailwind.css"
29
+ "./tailwind.css": "./src/tailwind.css",
30
+ "./background-slideshow": {
31
+ "types": "./dist/background-slideshow/index.d.mts",
32
+ "import": "./dist/background-slideshow/index.mjs"
33
+ },
34
+ "./blurry-gradient": {
35
+ "types": "./dist/blurry-gradient/index.d.mts",
36
+ "import": "./dist/blurry-gradient/index.mjs"
37
+ },
38
+ "./button": {
39
+ "types": "./dist/button/index.d.mts",
40
+ "import": "./dist/button/index.mjs"
41
+ },
42
+ "./carousel": {
43
+ "types": "./dist/carousel/index.d.mts",
44
+ "import": "./dist/carousel/index.mjs"
45
+ },
46
+ "./checkbox": {
47
+ "types": "./dist/checkbox/index.d.mts",
48
+ "import": "./dist/checkbox/index.mjs"
49
+ },
50
+ "./checkbox-group": {
51
+ "types": "./dist/checkbox-group/index.d.mts",
52
+ "import": "./dist/checkbox-group/index.mjs"
53
+ },
54
+ "./countdown": {
55
+ "types": "./dist/countdown/index.d.mts",
56
+ "import": "./dist/countdown/index.mjs"
57
+ },
58
+ "./field": {
59
+ "types": "./dist/field/index.d.mts",
60
+ "import": "./dist/field/index.mjs"
61
+ },
62
+ "./fieldset": {
63
+ "types": "./dist/fieldset/index.d.mts",
64
+ "import": "./dist/fieldset/index.mjs"
65
+ },
66
+ "./form": {
67
+ "types": "./dist/form/index.d.mts",
68
+ "import": "./dist/form/index.mjs"
69
+ },
70
+ "./generic-error": {
71
+ "types": "./dist/generic-error/index.d.mts",
72
+ "import": "./dist/generic-error/index.mjs"
73
+ },
74
+ "./grid": {
75
+ "types": "./dist/grid/index.d.mts",
76
+ "import": "./dist/grid/index.mjs"
77
+ },
78
+ "./heading": {
79
+ "types": "./dist/heading/index.d.mts",
80
+ "import": "./dist/heading/index.mjs"
81
+ },
82
+ "./highlight": {
83
+ "types": "./dist/highlight/index.d.mts",
84
+ "import": "./dist/highlight/index.mjs"
85
+ },
86
+ "./icon-button": {
87
+ "types": "./dist/icon-button/index.d.mts",
88
+ "import": "./dist/icon-button/index.mjs"
89
+ },
90
+ "./if": {
91
+ "types": "./dist/if/index.d.mts",
92
+ "import": "./dist/if/index.mjs"
93
+ },
94
+ "./iframe": {
95
+ "types": "./dist/iframe/index.d.mts",
96
+ "import": "./dist/iframe/index.mjs"
97
+ },
98
+ "./input": {
99
+ "types": "./dist/input/index.d.mts",
100
+ "import": "./dist/input/index.mjs"
101
+ },
102
+ "./link": {
103
+ "types": "./dist/link/index.d.mts",
104
+ "import": "./dist/link/index.mjs"
105
+ },
106
+ "./list": {
107
+ "types": "./dist/list/index.d.mts",
108
+ "import": "./dist/list/index.mjs"
109
+ },
110
+ "./markdown-container": {
111
+ "types": "./dist/markdown-container/index.d.mts",
112
+ "import": "./dist/markdown-container/index.mjs"
113
+ },
114
+ "./password-input": {
115
+ "types": "./dist/password-input/index.d.mts",
116
+ "import": "./dist/password-input/index.mjs"
117
+ },
118
+ "./picture": {
119
+ "types": "./dist/picture/index.d.mts",
120
+ "import": "./dist/picture/index.mjs"
121
+ },
122
+ "./protected-email": {
123
+ "types": "./dist/protected-email/index.d.mts",
124
+ "import": "./dist/protected-email/index.mjs"
125
+ },
126
+ "./radio": {
127
+ "types": "./dist/radio/index.d.mts",
128
+ "import": "./dist/radio/index.mjs"
129
+ },
130
+ "./radio-group": {
131
+ "types": "./dist/radio-group/index.d.mts",
132
+ "import": "./dist/radio-group/index.mjs"
133
+ },
134
+ "./slider": {
135
+ "types": "./dist/slider/index.d.mts",
136
+ "import": "./dist/slider/index.mjs"
137
+ },
138
+ "./switch": {
139
+ "types": "./dist/switch/index.d.mts",
140
+ "import": "./dist/switch/index.mjs"
141
+ },
142
+ "./text": {
143
+ "types": "./dist/text/index.d.mts",
144
+ "import": "./dist/text/index.mjs"
145
+ },
146
+ "./toggle": {
147
+ "types": "./dist/toggle/index.d.mts",
148
+ "import": "./dist/toggle/index.mjs"
149
+ },
150
+ "./hooks/use-current-route-data": {
151
+ "types": "./dist/hooks/use-current-route-data.d.mts",
152
+ "import": "./dist/hooks/use-current-route-data.mjs"
153
+ },
154
+ "./hooks/use-focus-search": {
155
+ "types": "./dist/hooks/use-focus-search.d.mts",
156
+ "import": "./dist/hooks/use-focus-search.mjs"
157
+ },
158
+ "./hooks/use-matches-data": {
159
+ "types": "./dist/hooks/use-matches-data.d.mts",
160
+ "import": "./dist/hooks/use-matches-data.mjs"
161
+ },
162
+ "./hooks/use-media-query": {
163
+ "types": "./dist/hooks/use-media-query.d.mts",
164
+ "import": "./dist/hooks/use-media-query.mjs"
165
+ },
166
+ "./hooks/use-mobile": {
167
+ "types": "./dist/hooks/use-mobile.d.mts",
168
+ "import": "./dist/hooks/use-mobile.mjs"
169
+ },
170
+ "./hooks/use-nonce": {
171
+ "types": "./dist/hooks/use-nonce.d.mts",
172
+ "import": "./dist/hooks/use-nonce.mjs"
173
+ },
174
+ "./hooks/use-orientation": {
175
+ "types": "./dist/hooks/use-orientation.d.mts",
176
+ "import": "./dist/hooks/use-orientation.mjs"
177
+ },
178
+ "./hooks/use-user": {
179
+ "types": "./dist/hooks/use-user.d.mts",
180
+ "import": "./dist/hooks/use-user.mjs"
181
+ },
182
+ "./utils/author": {
183
+ "types": "./dist/utils/author/index.d.mts",
184
+ "import": "./dist/utils/author/index.mjs"
185
+ },
186
+ "./utils/text": {
187
+ "types": "./dist/utils/text/index.d.mts",
188
+ "import": "./dist/utils/text/index.mjs"
189
+ }
30
190
  },
31
191
  "files": [
32
192
  "dist",
33
193
  "src"
34
194
  ],
35
195
  "scripts": {
36
- "build": "tsdown && post-build-exports --preserve \"./tailwind.css\" && pnpm fix",
196
+ "build": "tsdown && pnpm fix",
37
197
  "clean": "exec-clean .turbo dist",
38
198
  "dev": "tsdown --watch",
39
199
  "fix": "exec-p fix:*",
@@ -57,10 +217,10 @@
57
217
  "dependencies": {
58
218
  "@base-ui/react": "1.0.0",
59
219
  "@maptiler/leaflet-maptilersdk": "4.1.1",
60
- "@maptiler/sdk": "3.9.0",
220
+ "@maptiler/sdk": "3.10.0",
61
221
  "@mdx-js/react": "3.1.1",
62
- "@regardio/js": "0.6.0",
63
- "@regardio/tailwind": "0.2.0",
222
+ "@regardio/js": "0.7.0",
223
+ "@regardio/tailwind": "0.3.0",
64
224
  "@supabase/supabase-js": "2.90.1",
65
225
  "cmdk": "1.1.1",
66
226
  "embla-carousel": "8.6.0",
@@ -73,15 +233,15 @@
73
233
  "react": "19.2.3",
74
234
  "react-day-picker": "9.13.0",
75
235
  "react-dom": "19.2.3",
76
- "react-hook-form": "7.71.0",
77
- "react-resizable-panels": "4.4.0",
236
+ "react-hook-form": "7.71.1",
237
+ "react-resizable-panels": "4.4.1",
78
238
  "react-router": "7.12.0",
79
239
  "tailwind-variants": "3.2.2",
80
240
  "vaul": "1.1.2",
81
241
  "zod": "4.3.5"
82
242
  },
83
243
  "devDependencies": {
84
- "@regardio/dev": "1.11.4",
244
+ "@regardio/dev": "1.12.0",
85
245
  "@storybook/addon-a11y": "10.1.11",
86
246
  "@storybook/addon-docs": "10.1.11",
87
247
  "@storybook/addon-vitest": "10.1.11",
@@ -102,7 +262,7 @@
102
262
  "playwright": "1.57.0",
103
263
  "storybook": "10.1.11",
104
264
  "tailwindcss": "4.1.18",
105
- "tsdown": "0.20.0-beta.1",
265
+ "tsdown": "0.20.0-beta.3",
106
266
  "typescript": "5.9.3",
107
267
  "vite": "7.3.1",
108
268
  "vitest": "4.0.17"
@@ -1,6 +1,5 @@
1
1
  'use client';
2
2
 
3
- import type { ReactElement } from 'react';
4
3
  import { useEffect, useMemo, useRef, useState } from 'react';
5
4
  import { Picture } from '../picture';
6
5
 
@@ -36,7 +35,7 @@ export function BackgroundSlideshow({
36
35
  slideshowInterval = 6000,
37
36
  transitionDuration = 6000,
38
37
  filter,
39
- }: BackgroundSlideshowProps): ReactElement {
38
+ }: BackgroundSlideshowProps): React.JSX.Element {
40
39
  // Validate images synchronously for immediate first image render
41
40
  const validatedImages = useMemo(() => {
42
41
  return images
@@ -11,7 +11,7 @@ export interface BlurryGradientProps extends SVGProps<SVGSVGElement> {
11
11
  description?: string;
12
12
  }
13
13
 
14
- export const BlurryGradient = (props: BlurryGradientProps) => {
14
+ export const BlurryGradient = (props: BlurryGradientProps): React.JSX.Element => {
15
15
  const {
16
16
  description = 'Decorative blurry gradient',
17
17
  neutralColor,
@@ -1,7 +1,7 @@
1
1
  import type { Meta, StoryObj } from '@storybook/react-vite';
2
2
  import { Button } from './button';
3
3
 
4
- const meta = {
4
+ const meta: Meta<typeof Button> = {
5
5
  argTypes: {
6
6
  children: {
7
7
  control: 'text',
@@ -96,7 +96,13 @@ export interface ButtonProps extends Omit<ComponentProps<typeof BaseUIButton>, '
96
96
  type?: 'button' | 'submit' | 'reset';
97
97
  }
98
98
 
99
- export const Button = ({ children, className, variant, size, ...props }: ButtonProps) => {
99
+ export const Button = ({
100
+ children,
101
+ className,
102
+ variant,
103
+ size,
104
+ ...props
105
+ }: ButtonProps): React.JSX.Element => {
100
106
  return (
101
107
  <BaseUIButton
102
108
  className={button({
@@ -1,16 +1,19 @@
1
- 'use client';
1
+ import type { HTMLAttributes } from 'react';
2
2
 
3
- import { forwardRef, type HTMLAttributes } from 'react';
3
+ export interface CarouselContentProps extends HTMLAttributes<HTMLDivElement> {
4
+ ref?: React.Ref<HTMLDivElement>;
5
+ }
4
6
 
5
- export const CarouselContent = forwardRef<HTMLDivElement, HTMLAttributes<HTMLDivElement>>(
6
- ({ className, ...props }, ref) => {
7
- return (
8
- <div
9
- className={className}
10
- ref={ref}
11
- {...props}
12
- />
13
- );
14
- },
15
- );
16
- CarouselContent.displayName = 'CarouselContent';
7
+ export const CarouselContent = function CarouselContent({
8
+ className,
9
+ ref,
10
+ ...props
11
+ }: CarouselContentProps): React.JSX.Element {
12
+ return (
13
+ <div
14
+ className={className}
15
+ ref={ref}
16
+ {...props}
17
+ />
18
+ );
19
+ };
@@ -1,23 +1,23 @@
1
- 'use client';
2
-
3
- import { forwardRef, type HTMLAttributes } from 'react';
1
+ import type { HTMLAttributes } from 'react';
4
2
 
5
3
  export interface CarouselItemProps extends HTMLAttributes<HTMLDivElement> {
6
4
  'aria-label'?: string;
5
+ ref?: React.Ref<HTMLDivElement>;
7
6
  }
8
7
 
9
- export const CarouselItem = forwardRef<HTMLDivElement, CarouselItemProps>(
10
- ({ className, ...props }, ref) => {
11
- return (
12
- // biome-ignore lint/a11y/useSemanticElements: False positive
13
- <div
14
- aria-roledescription="slide"
15
- className={className}
16
- ref={ref}
17
- role="group"
18
- {...props}
19
- />
20
- );
21
- },
22
- );
23
- CarouselItem.displayName = 'CarouselItem';
8
+ export const CarouselItem = function CarouselItem({
9
+ className,
10
+ ref,
11
+ ...props
12
+ }: CarouselItemProps): React.JSX.Element {
13
+ return (
14
+ // biome-ignore lint/a11y/useSemanticElements: False positive
15
+ <div
16
+ aria-roledescription="slide"
17
+ className={className}
18
+ ref={ref}
19
+ role="group"
20
+ {...props}
21
+ />
22
+ );
23
+ };
@@ -1,22 +1,27 @@
1
1
  'use client';
2
2
 
3
- import { forwardRef, type HTMLAttributes } from 'react';
3
+ import type { HTMLAttributes } from 'react';
4
4
  import { Button } from '../button';
5
5
  import { useCarousel } from './carousel-root';
6
6
 
7
- export const CarouselNext = forwardRef<HTMLButtonElement, HTMLAttributes<HTMLButtonElement>>(
8
- ({ className, ...props }, ref) => {
9
- const { canScrollNext, scrollNext } = useCarousel();
7
+ export interface CarouselNextProps extends HTMLAttributes<HTMLButtonElement> {
8
+ ref?: React.Ref<HTMLButtonElement>;
9
+ }
10
10
 
11
- return (
12
- <Button
13
- className={className}
14
- disabled={!canScrollNext}
15
- onClick={scrollNext}
16
- ref={ref}
17
- {...props}
18
- />
19
- );
20
- },
21
- );
22
- CarouselNext.displayName = 'CarouselNext';
11
+ export const CarouselNext = function CarouselNext({
12
+ className,
13
+ ref,
14
+ ...props
15
+ }: CarouselNextProps): React.JSX.Element {
16
+ const { canScrollNext, scrollNext } = useCarousel();
17
+
18
+ return (
19
+ <Button
20
+ className={className}
21
+ disabled={!canScrollNext}
22
+ onClick={scrollNext}
23
+ ref={ref}
24
+ {...props}
25
+ />
26
+ );
27
+ };
@@ -1,22 +1,27 @@
1
1
  'use client';
2
2
 
3
- import { forwardRef, type HTMLAttributes } from 'react';
3
+ import type { HTMLAttributes } from 'react';
4
4
  import { Button } from '../button';
5
5
  import { useCarousel } from './carousel-root';
6
6
 
7
- export const CarouselPrevious = forwardRef<HTMLButtonElement, HTMLAttributes<HTMLButtonElement>>(
8
- ({ className, ...props }, ref) => {
9
- const { canScrollPrev, scrollPrev } = useCarousel();
7
+ export interface CarouselPreviousProps extends HTMLAttributes<HTMLButtonElement> {
8
+ ref?: React.Ref<HTMLButtonElement>;
9
+ }
10
10
 
11
- return (
12
- <Button
13
- className={className}
14
- disabled={!canScrollPrev}
15
- onClick={scrollPrev}
16
- ref={ref}
17
- {...props}
18
- />
19
- );
20
- },
21
- );
22
- CarouselPrevious.displayName = 'CarouselPrevious';
11
+ export const CarouselPrevious = function CarouselPrevious({
12
+ className,
13
+ ref,
14
+ ...props
15
+ }: CarouselPreviousProps): React.JSX.Element {
16
+ const { canScrollPrev, scrollPrev } = useCarousel();
17
+
18
+ return (
19
+ <Button
20
+ className={className}
21
+ disabled={!canScrollPrev}
22
+ onClick={scrollPrev}
23
+ ref={ref}
24
+ {...props}
25
+ />
26
+ );
27
+ };
@@ -4,7 +4,6 @@ import type { EmblaCarouselType, EmblaOptionsType } from 'embla-carousel';
4
4
  import useEmblaCarousel from 'embla-carousel-react';
5
5
  import {
6
6
  createContext,
7
- forwardRef,
8
7
  type HTMLAttributes,
9
8
  type KeyboardEvent,
10
9
  useCallback,
@@ -25,7 +24,7 @@ interface CarouselContextValue {
25
24
 
26
25
  const CarouselContext = createContext<CarouselContextValue | null>(null);
27
26
 
28
- export function useCarousel() {
27
+ export function useCarousel(): CarouselContextValue {
29
28
  const context = useContext(CarouselContext);
30
29
  if (!context) {
31
30
  throw new Error('useCarousel must be used within a <Carousel.Root />');
@@ -37,91 +36,97 @@ export interface CarouselRootProps extends HTMLAttributes<HTMLDivElement> {
37
36
  opts?: EmblaOptionsType;
38
37
  setApi?: (api: CarouselApi) => void;
39
38
  orientation?: 'horizontal' | 'vertical';
39
+ ref?: React.Ref<HTMLDivElement>;
40
40
  }
41
41
 
42
- export const CarouselRoot = forwardRef<HTMLDivElement, CarouselRootProps>(
43
- ({ children, className, opts, orientation = 'horizontal', setApi, ...props }, ref) => {
44
- const [emblaRef, emblaApi] = useEmblaCarousel({
45
- ...opts,
46
- axis: orientation === 'horizontal' ? 'x' : 'y',
47
- });
48
- const [canScrollPrev, setCanScrollPrev] = useState(false);
49
- const [canScrollNext, setCanScrollNext] = useState(false);
50
-
51
- const onSelect = useCallback((api: CarouselApi) => {
52
- if (!api) {
53
- return;
42
+ export const CarouselRoot = function CarouselRoot({
43
+ children,
44
+ className,
45
+ opts,
46
+ orientation = 'horizontal',
47
+ setApi,
48
+ ref,
49
+ ...props
50
+ }: CarouselRootProps): React.JSX.Element {
51
+ const [emblaRef, emblaApi] = useEmblaCarousel({
52
+ ...opts,
53
+ axis: orientation === 'horizontal' ? 'x' : 'y',
54
+ });
55
+ const [canScrollPrev, setCanScrollPrev] = useState(false);
56
+ const [canScrollNext, setCanScrollNext] = useState(false);
57
+
58
+ const onSelect = useCallback((api: CarouselApi) => {
59
+ if (!api) {
60
+ return;
61
+ }
62
+ setCanScrollPrev(api.canScrollPrev());
63
+ setCanScrollNext(api.canScrollNext());
64
+ }, []);
65
+
66
+ const scrollPrev = useCallback(() => {
67
+ emblaApi?.scrollPrev();
68
+ }, [emblaApi]);
69
+
70
+ const scrollNext = useCallback(() => {
71
+ emblaApi?.scrollNext();
72
+ }, [emblaApi]);
73
+
74
+ const handleKeyDown = useCallback(
75
+ (event: KeyboardEvent<HTMLDivElement>) => {
76
+ if (event.key === 'ArrowLeft') {
77
+ event.preventDefault();
78
+ scrollPrev();
79
+ } else if (event.key === 'ArrowRight') {
80
+ event.preventDefault();
81
+ scrollNext();
54
82
  }
55
- setCanScrollPrev(api.canScrollPrev());
56
- setCanScrollNext(api.canScrollNext());
57
- }, []);
58
-
59
- const scrollPrev = useCallback(() => {
60
- emblaApi?.scrollPrev();
61
- }, [emblaApi]);
62
-
63
- const scrollNext = useCallback(() => {
64
- emblaApi?.scrollNext();
65
- }, [emblaApi]);
66
-
67
- const handleKeyDown = useCallback(
68
- (event: KeyboardEvent<HTMLDivElement>) => {
69
- if (event.key === 'ArrowLeft') {
70
- event.preventDefault();
71
- scrollPrev();
72
- } else if (event.key === 'ArrowRight') {
73
- event.preventDefault();
74
- scrollNext();
75
- }
76
- },
77
- [scrollPrev, scrollNext],
78
- );
79
-
80
- useEffect(() => {
81
- if (!emblaApi || !setApi) {
82
- return;
83
- }
84
- setApi(emblaApi);
85
- }, [emblaApi, setApi]);
86
-
87
- useEffect(() => {
88
- if (!emblaApi) {
89
- return;
90
- }
91
-
92
- onSelect(emblaApi);
93
- emblaApi.on('reInit', onSelect);
94
- emblaApi.on('select', onSelect);
95
-
96
- return () => {
97
- emblaApi?.off('select', onSelect);
98
- };
99
- }, [emblaApi, onSelect]);
100
-
101
- return (
102
- <CarouselContext.Provider
103
- value={{
104
- api: emblaApi,
105
- canScrollNext,
106
- canScrollPrev,
107
- scrollNext,
108
- scrollPrev,
109
- }}
83
+ },
84
+ [scrollPrev, scrollNext],
85
+ );
86
+
87
+ useEffect(() => {
88
+ if (!emblaApi || !setApi) {
89
+ return;
90
+ }
91
+ setApi(emblaApi);
92
+ }, [emblaApi, setApi]);
93
+
94
+ useEffect(() => {
95
+ if (!emblaApi) {
96
+ return;
97
+ }
98
+
99
+ onSelect(emblaApi);
100
+ emblaApi.on('reInit', onSelect);
101
+ emblaApi.on('select', onSelect);
102
+
103
+ return () => {
104
+ emblaApi?.off('select', onSelect);
105
+ };
106
+ }, [emblaApi, onSelect]);
107
+
108
+ return (
109
+ <CarouselContext.Provider
110
+ value={{
111
+ api: emblaApi,
112
+ canScrollNext,
113
+ canScrollPrev,
114
+ scrollNext,
115
+ scrollPrev,
116
+ }}
117
+ >
118
+ <section
119
+ aria-label="Carousel"
120
+ aria-roledescription="carousel"
121
+ className={className}
122
+ onKeyDownCapture={handleKeyDown}
123
+ ref={ref}
124
+ {...props}
110
125
  >
111
- <section
112
- aria-label="Carousel"
113
- aria-roledescription="carousel"
114
- className={className}
115
- onKeyDownCapture={handleKeyDown}
116
- ref={ref}
117
- {...props}
118
- >
119
- <div ref={emblaRef}>
120
- <div>{children}</div>
121
- </div>
122
- </section>
123
- </CarouselContext.Provider>
124
- );
125
- },
126
- );
127
- CarouselRoot.displayName = 'CarouselRoot';
126
+ <div ref={emblaRef}>
127
+ <div>{children}</div>
128
+ </div>
129
+ </section>
130
+ </CarouselContext.Provider>
131
+ );
132
+ };