@regardio/react 0.5.7 → 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 (214) hide show
  1. package/dist/background-slideshow/index.d.mts +34 -0
  2. package/dist/background-slideshow/index.mjs +110 -0
  3. package/dist/blurry-gradient/index.d.mts +16 -0
  4. package/dist/blurry-gradient/index.mjs +93 -0
  5. package/dist/button/index.d.mts +2 -0
  6. package/dist/button/index.mjs +3 -0
  7. package/dist/button-BiSQpBbc.mjs +129 -0
  8. package/dist/carousel/index.d.mts +74 -0
  9. package/dist/carousel/index.mjs +136 -0
  10. package/dist/checkbox/index.d.mts +28 -0
  11. package/dist/checkbox/index.mjs +70 -0
  12. package/dist/checkbox-group/index.d.mts +16 -0
  13. package/dist/checkbox-group/index.mjs +29 -0
  14. package/dist/chunk-BTpB_u-K.mjs +18 -0
  15. package/dist/countdown/index.d.mts +4 -0
  16. package/dist/countdown/index.mjs +58 -0
  17. package/dist/field/index.d.mts +68 -0
  18. package/dist/field/index.mjs +115 -0
  19. package/dist/fieldset/index.d.mts +34 -0
  20. package/dist/fieldset/index.mjs +61 -0
  21. package/dist/form/index.d.mts +21 -0
  22. package/dist/form/index.mjs +31 -0
  23. package/dist/generic-error/index.d.mts +44 -0
  24. package/dist/generic-error/index.mjs +57 -0
  25. package/dist/grid/index.d.mts +101 -0
  26. package/dist/grid/index.mjs +219 -0
  27. package/dist/heading/index.d.mts +27 -0
  28. package/dist/heading/index.mjs +28 -0
  29. package/dist/highlight/index.d.mts +17 -0
  30. package/dist/highlight/index.mjs +35 -0
  31. package/dist/hooks/use-current-route-data.d.mts +8 -0
  32. package/dist/hooks/use-current-route-data.mjs +22 -0
  33. package/dist/hooks/{use-focus-search.d.ts → use-focus-search.d.mts} +4 -3
  34. package/dist/hooks/use-focus-search.mjs +23 -0
  35. package/dist/hooks/use-matches-data.d.mts +10 -0
  36. package/dist/hooks/use-matches-data.mjs +23 -0
  37. package/dist/hooks/use-media-query.d.mts +9 -0
  38. package/dist/hooks/use-media-query.mjs +28 -0
  39. package/dist/hooks/use-mobile.d.mts +4 -0
  40. package/dist/hooks/use-mobile.mjs +22 -0
  41. package/dist/hooks/use-nonce.d.mts +6 -0
  42. package/dist/hooks/use-nonce.mjs +13 -0
  43. package/dist/hooks/use-orientation.d.mts +12 -0
  44. package/dist/hooks/use-orientation.mjs +32 -0
  45. package/dist/hooks/use-user.d.mts +53 -0
  46. package/dist/hooks/use-user.mjs +39 -0
  47. package/dist/icon-button/index.d.mts +28 -0
  48. package/dist/icon-button/index.mjs +36 -0
  49. package/dist/if/index.d.mts +13 -0
  50. package/dist/if/index.mjs +21 -0
  51. package/dist/iframe/index.d.mts +11 -0
  52. package/dist/iframe/index.mjs +15 -0
  53. package/dist/index-Bj5_XfEC.d.mts +29 -0
  54. package/dist/index-C_evL5vG.d.mts +35 -0
  55. package/dist/input/index.d.mts +2 -0
  56. package/dist/input/index.mjs +3 -0
  57. package/dist/input-CtR6aRVi.mjs +73 -0
  58. package/dist/link/index.d.mts +71 -0
  59. package/dist/link/index.mjs +129 -0
  60. package/dist/list/index.d.mts +72 -0
  61. package/dist/list/index.mjs +54 -0
  62. package/dist/markdown-container/index.d.mts +23 -0
  63. package/dist/markdown-container/index.mjs +71 -0
  64. package/dist/password-input/index.d.mts +23 -0
  65. package/dist/password-input/index.mjs +92 -0
  66. package/dist/picture/index.d.mts +39 -0
  67. package/dist/picture/index.mjs +3 -0
  68. package/dist/picture-DkX3W5zl.mjs +69 -0
  69. package/dist/protected-email/index.d.mts +24 -0
  70. package/dist/protected-email/index.mjs +37 -0
  71. package/dist/radio/index.d.mts +28 -0
  72. package/dist/radio/index.mjs +72 -0
  73. package/dist/radio-group/index.d.mts +16 -0
  74. package/dist/radio-group/index.mjs +29 -0
  75. package/dist/slider/index.d.mts +63 -0
  76. package/dist/slider/index.mjs +133 -0
  77. package/dist/switch/index.d.mts +29 -0
  78. package/dist/switch/index.mjs +87 -0
  79. package/dist/text/index.d.mts +25 -0
  80. package/dist/text/index.mjs +32 -0
  81. package/dist/text-EQC4zJbE.mjs +52 -0
  82. package/dist/toggle/index.d.mts +25 -0
  83. package/dist/toggle/index.mjs +82 -0
  84. package/dist/utils/author/index.d.mts +4 -0
  85. package/dist/utils/author/index.mjs +26 -0
  86. package/dist/utils/text/{index.d.ts → index.d.mts} +9 -8
  87. package/dist/utils/text/index.mjs +3 -0
  88. package/package.json +131 -83
  89. package/src/background-slideshow/background-slideshow.tsx +1 -2
  90. package/src/blurry-gradient/blurry-gradient.tsx +1 -1
  91. package/src/button/button.stories.tsx +161 -0
  92. package/src/button/button.test.tsx +73 -0
  93. package/src/button/button.tsx +118 -0
  94. package/src/button/index.ts +2 -0
  95. package/src/carousel/carousel-content.tsx +17 -14
  96. package/src/carousel/carousel-item.tsx +18 -18
  97. package/src/carousel/carousel-next.tsx +22 -17
  98. package/src/carousel/carousel-previous.tsx +22 -17
  99. package/src/carousel/carousel-root.tsx +91 -86
  100. package/src/checkbox/checkbox.stories.tsx +118 -0
  101. package/src/checkbox/checkbox.tsx +102 -0
  102. package/src/checkbox/index.ts +2 -0
  103. package/src/checkbox-group/checkbox-group.tsx +40 -0
  104. package/src/checkbox-group/index.ts +2 -0
  105. package/src/countdown/countdown.tsx +1 -1
  106. package/src/field/field.stories.tsx +105 -0
  107. package/src/field/field.test.tsx +61 -0
  108. package/src/field/field.tsx +186 -0
  109. package/src/field/index.ts +12 -0
  110. package/src/fieldset/fieldset.stories.tsx +204 -0
  111. package/src/fieldset/fieldset.test.tsx +63 -0
  112. package/src/fieldset/fieldset.tsx +86 -0
  113. package/src/fieldset/index.ts +7 -0
  114. package/src/form/form.stories.tsx +230 -0
  115. package/src/form/form.test.tsx +68 -0
  116. package/src/form/form.tsx +38 -0
  117. package/src/form/index.ts +2 -0
  118. package/src/generic-error/generic-error.tsx +2 -3
  119. package/src/grid/grid-item.tsx +77 -36
  120. package/src/grid/grid-root.tsx +49 -22
  121. package/src/heading/heading.tsx +7 -3
  122. package/src/highlight/highlight.tsx +1 -1
  123. package/src/hooks/use-current-route-data.ts +4 -2
  124. package/src/hooks/use-focus-search.ts +3 -1
  125. package/src/hooks/use-matches-data.ts +2 -0
  126. package/src/hooks/use-media-query.ts +2 -0
  127. package/src/hooks/use-mobile.ts +3 -1
  128. package/src/hooks/use-nonce.ts +3 -3
  129. package/src/hooks/use-orientation.ts +2 -0
  130. package/src/hooks/use-user.tsx +3 -2
  131. package/src/icon-button/icon-button.stories.tsx +128 -7
  132. package/src/icon-button/icon-button.test.tsx +152 -0
  133. package/src/icon-button/icon-button.tsx +43 -9
  134. package/src/if/if.tsx +3 -1
  135. package/src/input/index.ts +2 -0
  136. package/src/input/input.stories.tsx +151 -0
  137. package/src/input/input.test.tsx +65 -0
  138. package/src/input/input.tsx +113 -0
  139. package/src/link/link.tsx +4 -3
  140. package/src/list/list-item.tsx +10 -13
  141. package/src/list/list-root-context.ts +3 -3
  142. package/src/list/list-root.tsx +10 -13
  143. package/src/password-input/index.ts +1 -1
  144. package/src/password-input/password-input.tsx +104 -27
  145. package/src/protected-email/protected-email.tsx +6 -1
  146. package/src/radio/index.ts +2 -0
  147. package/src/radio/radio.tsx +103 -0
  148. package/src/radio-group/index.ts +2 -0
  149. package/src/radio-group/radio-group.tsx +40 -0
  150. package/src/slider/index.ts +18 -0
  151. package/src/slider/slider.tsx +201 -0
  152. package/src/switch/index.ts +2 -0
  153. package/src/switch/switch.stories.tsx +118 -0
  154. package/src/switch/switch.tsx +112 -0
  155. package/src/text/text.tsx +6 -1
  156. package/src/toggle/index.ts +2 -0
  157. package/src/toggle/toggle.stories.tsx +232 -0
  158. package/src/toggle/toggle.test.tsx +149 -0
  159. package/src/toggle/toggle.tsx +88 -0
  160. package/src/utils/text/text.tsx +8 -16
  161. package/dist/background-slideshow/index.d.ts +0 -24
  162. package/dist/background-slideshow/index.js +0 -165
  163. package/dist/blurry-gradient/index.d.ts +0 -16
  164. package/dist/blurry-gradient/index.js +0 -128
  165. package/dist/carousel/index.d.ts +0 -36
  166. package/dist/carousel/index.js +0 -171
  167. package/dist/countdown/index.d.ts +0 -5
  168. package/dist/countdown/index.js +0 -73
  169. package/dist/generic-error/index.d.ts +0 -43
  170. package/dist/generic-error/index.js +0 -47
  171. package/dist/grid/index.d.ts +0 -1196
  172. package/dist/grid/index.js +0 -239
  173. package/dist/heading/index.d.ts +0 -24
  174. package/dist/heading/index.js +0 -99
  175. package/dist/highlight/index.d.ts +0 -13
  176. package/dist/highlight/index.js +0 -59
  177. package/dist/hooks/use-current-route-data.d.ts +0 -7
  178. package/dist/hooks/use-current-route-data.js +0 -16
  179. package/dist/hooks/use-focus-search.js +0 -19
  180. package/dist/hooks/use-matches-data.d.ts +0 -9
  181. package/dist/hooks/use-matches-data.js +0 -15
  182. package/dist/hooks/use-media-query.d.ts +0 -8
  183. package/dist/hooks/use-media-query.js +0 -20
  184. package/dist/hooks/use-mobile.d.ts +0 -3
  185. package/dist/hooks/use-mobile.js +0 -19
  186. package/dist/hooks/use-nonce.d.ts +0 -7
  187. package/dist/hooks/use-nonce.js +0 -8
  188. package/dist/hooks/use-orientation.d.ts +0 -11
  189. package/dist/hooks/use-orientation.js +0 -29
  190. package/dist/hooks/use-user.d.ts +0 -50
  191. package/dist/hooks/use-user.js +0 -25
  192. package/dist/icon-button/index.d.ts +0 -9
  193. package/dist/icon-button/index.js +0 -17
  194. package/dist/if/index.d.ts +0 -10
  195. package/dist/if/index.js +0 -24
  196. package/dist/iframe/index.d.ts +0 -10
  197. package/dist/iframe/index.js +0 -17
  198. package/dist/link/index.d.ts +0 -55
  199. package/dist/link/index.js +0 -195
  200. package/dist/list/index.d.ts +0 -69
  201. package/dist/list/index.js +0 -65
  202. package/dist/markdown-container/index.d.ts +0 -22
  203. package/dist/markdown-container/index.js +0 -128
  204. package/dist/password-input/index.d.ts +0 -11
  205. package/dist/password-input/index.js +0 -46
  206. package/dist/picture/index.d.ts +0 -38
  207. package/dist/picture/index.js +0 -68
  208. package/dist/protected-email/index.d.ts +0 -20
  209. package/dist/protected-email/index.js +0 -30
  210. package/dist/text/index.d.ts +0 -20
  211. package/dist/text/index.js +0 -38
  212. package/dist/utils/author/index.d.ts +0 -3
  213. package/dist/utils/author/index.js +0 -33
  214. package/dist/utils/text/index.js +0 -73
@@ -1,13 +1,6 @@
1
1
  'use client';
2
2
 
3
- import {
4
- type ComponentPropsWithoutRef,
5
- type ElementType,
6
- type ForwardedRef,
7
- forwardRef,
8
- type ReactNode,
9
- useMemo,
10
- } from 'react';
3
+ import { type ComponentPropsWithoutRef, type ElementType, type ReactNode, useMemo } from 'react';
11
4
  import { ListRootContext, type ListRootContextValue } from './list-root-context';
12
5
 
13
6
  type ListRootElement = 'ul' | 'ol' | 'dl' | 'div' | 'menu' | 'nav';
@@ -34,17 +27,21 @@ export type ListRootProps<T extends ListRootElement = 'ul'> = Omit<
34
27
  * Default className to apply to all list items.
35
28
  */
36
29
  defaultItemClassName?: string;
30
+ /**
31
+ * Ref to the root element.
32
+ */
33
+ ref?: React.Ref<HTMLElement>;
37
34
  };
38
35
 
39
36
  function ListRootImpl<T extends ListRootElement = 'ul'>(
40
37
  props: ListRootProps<T>,
41
- ref: ForwardedRef<HTMLElement>,
42
- ) {
38
+ ): React.JSX.Element {
43
39
  const {
44
40
  render = 'ul' as T,
45
41
  children,
46
42
  defaultItemElement,
47
43
  defaultItemClassName,
44
+ ref,
48
45
  ...elementProps
49
46
  } = props;
50
47
 
@@ -72,9 +69,9 @@ function ListRootImpl<T extends ListRootElement = 'ul'>(
72
69
  );
73
70
  }
74
71
 
75
- export const ListRoot = forwardRef(ListRootImpl) as <T extends ListRootElement = 'ul'>(
76
- props: ListRootProps<T> & { ref?: ForwardedRef<HTMLElement> },
77
- ) => ReturnType<typeof ListRootImpl>;
72
+ export const ListRoot = ListRootImpl as <T extends ListRootElement = 'ul'>(
73
+ props: ListRootProps<T>,
74
+ ) => React.JSX.Element;
78
75
 
79
76
  export namespace ListRoot {
80
77
  export type Props<T extends ListRootElement = 'ul'> = ListRootProps<T>;
@@ -1,2 +1,2 @@
1
- export type { InputProps, PasswordInputProps } from './password-input';
1
+ export type { PasswordInputProps } from './password-input';
2
2
  export { PasswordInput } from './password-input';
@@ -1,17 +1,66 @@
1
1
  'use client';
2
2
 
3
- import { Button } from '@base-ui/react/button';
4
- import { Input } from '@base-ui/react/input';
5
- import { cn } from '@regardio/tailwind/utils';
3
+ import { tv } from '@regardio/tailwind/utils';
6
4
  import { useState } from 'react';
5
+ import { Button } from '../button';
6
+ import { Input } from '../input';
7
7
 
8
- export interface InputProps extends React.ComponentPropsWithoutRef<typeof Input> {}
8
+ const passwordInputVariants = {
9
+ default: [],
10
+ withToggle: [],
11
+ } as const;
9
12
 
10
- export interface PasswordInputProps extends InputProps {
13
+ const passwordInput = tv({
14
+ base: ['relative'],
15
+ defaultVariants: {
16
+ variant: 'default',
17
+ },
18
+ variants: {
19
+ variant: passwordInputVariants,
20
+ },
21
+ });
22
+
23
+ const toggleButton = tv({
24
+ base: [
25
+ 'absolute',
26
+ 'right-3',
27
+ 'top-1/2',
28
+ '-translate-y-1/2',
29
+ 'flex',
30
+ 'h-5',
31
+ 'w-5',
32
+ 'cursor-pointer',
33
+ 'items-center',
34
+ 'justify-center',
35
+ 'text-gray-500',
36
+ 'hover:text-gray-700',
37
+ 'focus:outline-none',
38
+ 'focus:ring-2',
39
+ 'focus:ring-blue-500',
40
+ 'focus:ring-offset-2',
41
+ 'rounded',
42
+ 'transition-colors',
43
+ 'duration-200',
44
+ ],
45
+ });
46
+
47
+ export type PasswordInputVariant = keyof typeof passwordInputVariants;
48
+
49
+ export interface PasswordInputProps
50
+ extends Omit<React.ComponentProps<typeof Input>, 'type' | 'variant'> {
11
51
  className?: string;
52
+ variant?: PasswordInputVariant;
53
+ inputVariant?: 'default' | 'error' | 'success';
54
+ showToggle?: boolean;
12
55
  }
13
56
 
14
- export const PasswordInput = ({ className, ...props }: PasswordInputProps) => {
57
+ export const PasswordInput = ({
58
+ className,
59
+ variant = 'default',
60
+ inputVariant = 'default',
61
+ showToggle = true,
62
+ ...props
63
+ }: PasswordInputProps): React.JSX.Element => {
15
64
  const [showPassword, setShowPassword] = useState(false);
16
65
 
17
66
  const togglePasswordVisibility = () => {
@@ -19,31 +68,59 @@ export const PasswordInput = ({ className, ...props }: PasswordInputProps) => {
19
68
  };
20
69
 
21
70
  return (
22
- <div className={'relative'}>
71
+ <div className={passwordInput({ className, variant })}>
23
72
  <Input
24
- autoComplete={'off'}
25
- className={cn(className)}
73
+ autoComplete="off"
74
+ className={showToggle ? 'pr-10' : ''}
26
75
  type={showPassword ? 'text' : 'password'}
76
+ variant={inputVariant}
27
77
  {...props}
28
78
  />
29
- <Button
30
- className={cn(
31
- 'absolute',
32
- 'right-[14px]',
33
- 'top-[35px]',
34
- 'flex',
35
- 'h-6',
36
- 'w-[20px]',
37
- 'cursor-pointer',
38
- 'flex-col',
39
- 'items-end',
40
- 'justify-center',
41
- 'text-gray-500',
42
- )}
43
- onClick={togglePasswordVisibility}
44
- >
45
- {showPassword ? 'Off' : 'On'}
46
- </Button>
79
+ {showToggle && (
80
+ <Button
81
+ aria-label={showPassword ? 'Hide password' : 'Show password'}
82
+ className={toggleButton()}
83
+ onClick={togglePasswordVisibility}
84
+ size="sm"
85
+ variant="ghost"
86
+ >
87
+ {showPassword ? (
88
+ <svg
89
+ className="h-4 w-4"
90
+ fill="none"
91
+ stroke="currentColor"
92
+ viewBox="0 0 24 24"
93
+ >
94
+ <path
95
+ d="M13.875 18.825A10.05 10.05 0 0112 19c-4.478 0-8.268-2.943-9.543-7a9.97 9.97 0 011.563-3.029m5.858.908a3 3 0 114.243 4.243M9.878 9.878l4.242 4.242M9.88 9.88l-3.29-3.29m7.532 7.532l3.29 3.29M3 3l3.59 3.59m0 0A9.953 9.953 0 0112 5c4.478 0 8.268 2.943 9.543 7a10.025 10.025 0 01-4.132 5.411m0 0L21 21"
96
+ strokeLinecap="round"
97
+ strokeLinejoin="round"
98
+ strokeWidth={2}
99
+ />
100
+ </svg>
101
+ ) : (
102
+ <svg
103
+ className="h-4 w-4"
104
+ fill="none"
105
+ stroke="currentColor"
106
+ viewBox="0 0 24 24"
107
+ >
108
+ <path
109
+ d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"
110
+ strokeLinecap="round"
111
+ strokeLinejoin="round"
112
+ strokeWidth={2}
113
+ />
114
+ <path
115
+ d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"
116
+ strokeLinecap="round"
117
+ strokeLinejoin="round"
118
+ strokeWidth={2}
119
+ />
120
+ </svg>
121
+ )}
122
+ </Button>
123
+ )}
47
124
  </div>
48
125
  );
49
126
  };
@@ -18,7 +18,12 @@ export interface ProtectedEmailProps {
18
18
  * @param text - Optional display text (defaults to username(at)domain)
19
19
  * @param className - Optional CSS class name
20
20
  */
21
- export function ProtectedEmail({ username, domain, text, className }: ProtectedEmailProps) {
21
+ export function ProtectedEmail({
22
+ username,
23
+ domain,
24
+ text,
25
+ className,
26
+ }: ProtectedEmailProps): React.JSX.Element {
22
27
  const [mounted, setMounted] = useState(false);
23
28
 
24
29
  // Only assemble the email on the client side
@@ -0,0 +1,2 @@
1
+ export type { RadioIndicatorProps, RadioRootProps, RadioSize } from './radio';
2
+ export { Radio, RadioIndicator, RadioRoot } from './radio';
@@ -0,0 +1,103 @@
1
+ import { Radio as BaseUIRadio } from '@base-ui/react/radio';
2
+ import { tv } from '@regardio/tailwind/utils';
3
+ import type { ComponentProps } from 'react';
4
+
5
+ const radioRoot = tv({
6
+ base: [
7
+ 'h-4',
8
+ 'w-4',
9
+ 'rounded-full',
10
+ 'border',
11
+ 'border-gray-300',
12
+ 'bg-white',
13
+ 'focus:outline-none',
14
+ 'focus:ring-2',
15
+ 'focus:ring-blue-500',
16
+ 'focus:ring-offset-2',
17
+ 'disabled:cursor-not-allowed',
18
+ 'disabled:opacity-50',
19
+ 'data-[checked]:bg-blue-600',
20
+ 'data-[checked]:border-blue-600',
21
+ 'transition-colors',
22
+ 'duration-200',
23
+ 'cursor-pointer',
24
+ ],
25
+ defaultVariants: {
26
+ size: 'md',
27
+ },
28
+ variants: {
29
+ size: {
30
+ lg: ['h-5', 'w-5'],
31
+ md: ['h-4', 'w-4'],
32
+ sm: ['h-3', 'w-3'],
33
+ },
34
+ },
35
+ });
36
+
37
+ const radioIndicator = tv({
38
+ base: ['flex', 'items-center', 'justify-center', 'text-white', 'data-[unchecked]:invisible'],
39
+ });
40
+
41
+ export type RadioSize = 'sm' | 'md' | 'lg';
42
+
43
+ export interface RadioRootProps extends Omit<ComponentProps<typeof BaseUIRadio.Root>, 'className'> {
44
+ className?: string;
45
+ size?: RadioSize;
46
+ }
47
+
48
+ export interface RadioIndicatorProps
49
+ extends Omit<ComponentProps<typeof BaseUIRadio.Indicator>, 'className'> {
50
+ className?: string;
51
+ }
52
+
53
+ export const RadioRoot = ({
54
+ className,
55
+ size = 'md',
56
+ ...props
57
+ }: RadioRootProps): React.JSX.Element => {
58
+ return (
59
+ <BaseUIRadio.Root
60
+ className={radioRoot({
61
+ className,
62
+ size,
63
+ })}
64
+ {...props}
65
+ />
66
+ );
67
+ };
68
+
69
+ export const RadioIndicator = ({
70
+ className,
71
+ children,
72
+ ...props
73
+ }: RadioIndicatorProps): React.JSX.Element => {
74
+ return (
75
+ <BaseUIRadio.Indicator
76
+ className={radioIndicator({ className })}
77
+ {...props}
78
+ >
79
+ {children || (
80
+ <svg
81
+ fill="currentColor"
82
+ height="8"
83
+ viewBox="0 0 8 8"
84
+ width="8"
85
+ >
86
+ <circle
87
+ cx="4"
88
+ cy="4"
89
+ r="3"
90
+ />
91
+ </svg>
92
+ )}
93
+ </BaseUIRadio.Indicator>
94
+ );
95
+ };
96
+
97
+ export const Radio: {
98
+ Indicator: typeof RadioIndicator;
99
+ Root: typeof RadioRoot;
100
+ } = {
101
+ Indicator: RadioIndicator,
102
+ Root: RadioRoot,
103
+ };
@@ -0,0 +1,2 @@
1
+ export type { RadioGroupOrientation, RadioGroupProps } from './radio-group';
2
+ export { RadioGroup } from './radio-group';
@@ -0,0 +1,40 @@
1
+ import { RadioGroup as BaseUIRadioGroup } from '@base-ui/react/radio-group';
2
+ import { tv } from '@regardio/tailwind/utils';
3
+ import type { ComponentProps } from 'react';
4
+
5
+ const radioGroup = tv({
6
+ base: ['flex', 'flex-col', 'gap-2'],
7
+ defaultVariants: {
8
+ orientation: 'vertical',
9
+ },
10
+ variants: {
11
+ orientation: {
12
+ horizontal: ['flex-row', 'gap-4'],
13
+ vertical: ['flex-col', 'gap-2'],
14
+ },
15
+ },
16
+ });
17
+
18
+ export type RadioGroupOrientation = 'horizontal' | 'vertical';
19
+
20
+ export interface RadioGroupProps
21
+ extends Omit<ComponentProps<typeof BaseUIRadioGroup>, 'className'> {
22
+ className?: string;
23
+ orientation?: RadioGroupOrientation;
24
+ }
25
+
26
+ export const RadioGroup = ({
27
+ className,
28
+ orientation = 'vertical',
29
+ ...props
30
+ }: RadioGroupProps): React.JSX.Element => {
31
+ return (
32
+ <BaseUIRadioGroup
33
+ className={radioGroup({
34
+ className,
35
+ orientation,
36
+ })}
37
+ {...props}
38
+ />
39
+ );
40
+ };
@@ -0,0 +1,18 @@
1
+ export type {
2
+ SliderControlProps,
3
+ SliderIndicatorProps,
4
+ SliderRootProps,
5
+ SliderSize,
6
+ SliderThumbProps,
7
+ SliderTrackProps,
8
+ SliderValueProps,
9
+ } from './slider';
10
+ export {
11
+ Slider,
12
+ SliderControl,
13
+ SliderIndicator,
14
+ SliderRoot,
15
+ SliderThumb,
16
+ SliderTrack,
17
+ SliderValue,
18
+ } from './slider';
@@ -0,0 +1,201 @@
1
+ import { Slider as BaseUISlider } from '@base-ui/react/slider';
2
+ import { tv } from '@regardio/tailwind/utils';
3
+ import type { ComponentProps } from 'react';
4
+
5
+ const sliderRoot = tv({
6
+ base: ['relative', 'flex', 'items-center', 'w-full'],
7
+ defaultVariants: {
8
+ size: 'md',
9
+ },
10
+ variants: {
11
+ size: {
12
+ lg: ['h-8'],
13
+ md: ['h-6'],
14
+ sm: ['h-4'],
15
+ },
16
+ },
17
+ });
18
+
19
+ const sliderControl = tv({
20
+ base: ['relative', 'flex', 'items-center', 'w-full', 'touch-none'],
21
+ });
22
+
23
+ const sliderTrack = tv({
24
+ base: ['relative', 'w-full', 'rounded-full', 'bg-gray-200', 'overflow-hidden'],
25
+ defaultVariants: {
26
+ size: 'md',
27
+ },
28
+ variants: {
29
+ size: {
30
+ lg: ['h-3'],
31
+ md: ['h-2'],
32
+ sm: ['h-1'],
33
+ },
34
+ },
35
+ });
36
+
37
+ const sliderIndicator = tv({
38
+ base: ['absolute', 'h-full', 'bg-blue-600', 'rounded-full'],
39
+ });
40
+
41
+ const sliderThumb = tv({
42
+ base: [
43
+ 'block',
44
+ 'rounded-full',
45
+ 'bg-white',
46
+ 'border-2',
47
+ 'border-blue-600',
48
+ 'shadow-lg',
49
+ 'focus:outline-none',
50
+ 'focus:ring-2',
51
+ 'focus:ring-blue-500',
52
+ 'focus:ring-offset-2',
53
+ 'disabled:cursor-not-allowed',
54
+ 'disabled:opacity-50',
55
+ 'cursor-grab',
56
+ 'active:cursor-grabbing',
57
+ ],
58
+ defaultVariants: {
59
+ size: 'md',
60
+ },
61
+ variants: {
62
+ size: {
63
+ lg: ['h-6', 'w-6'],
64
+ md: ['h-5', 'w-5'],
65
+ sm: ['h-3', 'w-3'],
66
+ },
67
+ },
68
+ });
69
+
70
+ const sliderValue = tv({
71
+ base: ['text-sm', 'font-medium', 'text-gray-700', 'mb-2'],
72
+ });
73
+
74
+ export type SliderSize = 'sm' | 'md' | 'lg';
75
+
76
+ export interface SliderRootProps
77
+ extends Omit<ComponentProps<typeof BaseUISlider.Root>, 'className'> {
78
+ className?: string;
79
+ size?: SliderSize;
80
+ }
81
+
82
+ export interface SliderControlProps
83
+ extends Omit<ComponentProps<typeof BaseUISlider.Control>, 'className'> {
84
+ className?: string;
85
+ }
86
+
87
+ export interface SliderTrackProps
88
+ extends Omit<ComponentProps<typeof BaseUISlider.Track>, 'className'> {
89
+ className?: string;
90
+ size?: SliderSize;
91
+ }
92
+
93
+ export interface SliderIndicatorProps
94
+ extends Omit<ComponentProps<typeof BaseUISlider.Indicator>, 'className'> {
95
+ className?: string;
96
+ }
97
+
98
+ export interface SliderThumbProps
99
+ extends Omit<ComponentProps<typeof BaseUISlider.Thumb>, 'className'> {
100
+ className?: string;
101
+ size?: SliderSize;
102
+ }
103
+
104
+ export interface SliderValueProps
105
+ extends Omit<ComponentProps<typeof BaseUISlider.Value>, 'className'> {
106
+ className?: string;
107
+ }
108
+
109
+ export const SliderRoot = ({
110
+ className,
111
+ size = 'md',
112
+ ...props
113
+ }: SliderRootProps): React.JSX.Element => {
114
+ return (
115
+ <BaseUISlider.Root
116
+ className={sliderRoot({
117
+ className,
118
+ size,
119
+ })}
120
+ {...props}
121
+ />
122
+ );
123
+ };
124
+
125
+ export const SliderControl = ({ className, ...props }: SliderControlProps): React.JSX.Element => {
126
+ return (
127
+ <BaseUISlider.Control
128
+ className={sliderControl({ className })}
129
+ {...props}
130
+ />
131
+ );
132
+ };
133
+
134
+ export const SliderTrack = ({
135
+ className,
136
+ size = 'md',
137
+ ...props
138
+ }: SliderTrackProps): React.JSX.Element => {
139
+ return (
140
+ <BaseUISlider.Track
141
+ className={sliderTrack({
142
+ className,
143
+ size,
144
+ })}
145
+ {...props}
146
+ />
147
+ );
148
+ };
149
+
150
+ export const SliderIndicator = ({
151
+ className,
152
+ ...props
153
+ }: SliderIndicatorProps): React.JSX.Element => {
154
+ return (
155
+ <BaseUISlider.Indicator
156
+ className={sliderIndicator({ className })}
157
+ {...props}
158
+ />
159
+ );
160
+ };
161
+
162
+ export const SliderThumb = ({
163
+ className,
164
+ size = 'md',
165
+ ...props
166
+ }: SliderThumbProps): React.JSX.Element => {
167
+ return (
168
+ <BaseUISlider.Thumb
169
+ className={sliderThumb({
170
+ className,
171
+ size,
172
+ })}
173
+ {...props}
174
+ />
175
+ );
176
+ };
177
+
178
+ export const SliderValue = ({ className, ...props }: SliderValueProps): React.JSX.Element => {
179
+ return (
180
+ <BaseUISlider.Value
181
+ className={sliderValue({ className })}
182
+ {...props}
183
+ />
184
+ );
185
+ };
186
+
187
+ export const Slider: {
188
+ Control: typeof SliderControl;
189
+ Indicator: typeof SliderIndicator;
190
+ Root: typeof SliderRoot;
191
+ Thumb: typeof SliderThumb;
192
+ Track: typeof SliderTrack;
193
+ Value: typeof SliderValue;
194
+ } = {
195
+ Control: SliderControl,
196
+ Indicator: SliderIndicator,
197
+ Root: SliderRoot,
198
+ Thumb: SliderThumb,
199
+ Track: SliderTrack,
200
+ Value: SliderValue,
201
+ };
@@ -0,0 +1,2 @@
1
+ export type { SwitchRootProps, SwitchSize, SwitchThumbProps } from './switch';
2
+ export { Switch, SwitchRoot, SwitchThumb } from './switch';