@clicktap/ui 0.14.18 → 0.14.25

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 (198) hide show
  1. package/components/ContextMenu/ContextMenu.js +1 -1
  2. package/components/Dialog/Dialog.js +1 -1
  3. package/components/DialogTrigger/DialogTrigger.js +1 -1
  4. package/components/Drawer/Drawer.js +1 -1
  5. package/components/ModalOverlay/ModalOverlay.js +1 -1
  6. package/components/PinInput/PinInput.js +1 -1
  7. package/components/Select/Select.js +1 -1
  8. package/components/Tabs/Tabs.context.d.ts +3 -0
  9. package/package.json +1 -1
  10. package/components/Accordion/Accordion.tsx +0 -82
  11. package/components/Accordion/index.ts +0 -3
  12. package/components/Avatar/Avatar.stories.tsx +0 -99
  13. package/components/Avatar/Avatar.tsx +0 -120
  14. package/components/Avatar/Avatar.types.ts +0 -3
  15. package/components/Avatar/AvatarGroup/AvatarGroup.tsx +0 -32
  16. package/components/Avatar/AvatarGroup/AvatarGroup.types.ts +0 -8
  17. package/components/Avatar/index.ts +0 -4
  18. package/components/Badge/Badge.stories.tsx +0 -72
  19. package/components/Badge/Badge.tsx +0 -169
  20. package/components/Badge/Badge.types.ts +0 -3
  21. package/components/Badge/index.ts +0 -2
  22. package/components/Breadcrumbs/BreadcrumbEllipsis.tsx +0 -47
  23. package/components/Breadcrumbs/BreadcrumbEllipsis.types.ts +0 -5
  24. package/components/Breadcrumbs/BreadcrumbItem.tsx +0 -23
  25. package/components/Breadcrumbs/BreadcrumbItem.types.ts +0 -3
  26. package/components/Breadcrumbs/BreadcrumbLink.tsx +0 -30
  27. package/components/Breadcrumbs/BreadcrumbLink.types.ts +0 -3
  28. package/components/Breadcrumbs/BreadcrumbSeparator.tsx +0 -41
  29. package/components/Breadcrumbs/BreadcrumbSeparator.types.ts +0 -9
  30. package/components/Breadcrumbs/Breadcrumbs.tsx +0 -28
  31. package/components/Breadcrumbs/Breadcrumbs.types.ts +0 -6
  32. package/components/Breadcrumbs/index.ts +0 -10
  33. package/components/Button/Button.tsx +0 -72
  34. package/components/Button/Button.types.ts +0 -7
  35. package/components/Button/index.ts +0 -2
  36. package/components/Card/Card.tsx +0 -15
  37. package/components/Card/Card.types.ts +0 -3
  38. package/components/Card/index.ts +0 -2
  39. package/components/Checkbox/Checkbox.tsx +0 -122
  40. package/components/Checkbox/Checkbox.types.ts +0 -15
  41. package/components/Checkbox/index.ts +0 -2
  42. package/components/Collapsible/Collapsible.tsx +0 -34
  43. package/components/Collapsible/Collapsible.types.ts +0 -5
  44. package/components/Collapsible/CollapsibleTrigger.tsx +0 -57
  45. package/components/Collapsible/CollapsibleTrigger.types.ts +0 -14
  46. package/components/Collapsible/index.ts +0 -10
  47. package/components/Container/Container.tsx +0 -26
  48. package/components/Container/Container.types.ts +0 -3
  49. package/components/Container/index.ts +0 -2
  50. package/components/ContextMenu/ContextMenu.tsx +0 -74
  51. package/components/ContextMenu/ContextMenu.types.ts +0 -17
  52. package/components/ContextMenu/index.ts +0 -2
  53. package/components/CreditCardExpirationInput/CreditCardExpirationInput.tsx +0 -115
  54. package/components/CreditCardExpirationInput/CreditCardExpirationInput.types.ts +0 -10
  55. package/components/CreditCardExpirationInput/index.ts +0 -2
  56. package/components/CreditCardInput/CreditCardInput.tsx +0 -147
  57. package/components/CreditCardInput/CreditCardInput.types.ts +0 -12
  58. package/components/CreditCardInput/index.ts +0 -2
  59. package/components/DateInput/DateInput.tsx +0 -81
  60. package/components/DateInput/DateInput.types.ts +0 -15
  61. package/components/DateInput/index.ts +0 -2
  62. package/components/DateTimeFormat/DateTimeFormat.tsx +0 -16
  63. package/components/DateTimeFormat/DateTimeFormat.types.ts +0 -7
  64. package/components/DateTimeFormat/index.ts +0 -2
  65. package/components/Dialog/Dialog.tsx +0 -65
  66. package/components/Dialog/Dialog.types.ts +0 -9
  67. package/components/Dialog/index.ts +0 -2
  68. package/components/DialogTrigger/DialogTrigger.tsx +0 -45
  69. package/components/DialogTrigger/DialogTrigger.types.ts +0 -6
  70. package/components/DialogTrigger/index.ts +0 -5
  71. package/components/Divider/Divider.stories.tsx +0 -37
  72. package/components/Divider/Divider.tsx +0 -34
  73. package/components/Divider/Divider.types.ts +0 -5
  74. package/components/Divider/index.ts +0 -2
  75. package/components/DobInput/DobInput.tsx +0 -120
  76. package/components/DobInput/index.ts +0 -2
  77. package/components/Drawer/Drawer.tsx +0 -126
  78. package/components/Drawer/Drawer.types.ts +0 -11
  79. package/components/Drawer/index.ts +0 -2
  80. package/components/Icon/Account.tsx +0 -50
  81. package/components/Icon/Cart.tsx +0 -43
  82. package/components/Icon/Checkmark.tsx +0 -34
  83. package/components/Icon/Cross.tsx +0 -36
  84. package/components/Icon/DownArrow.tsx +0 -23
  85. package/components/Icon/Hamburger.tsx +0 -23
  86. package/components/Icon/Icon.types.ts +0 -8
  87. package/components/Icon/LinkArrow.tsx +0 -32
  88. package/components/Icon/Minus.tsx +0 -20
  89. package/components/Icon/Plus.tsx +0 -20
  90. package/components/Icon/Search.tsx +0 -36
  91. package/components/Icon/Trash.tsx +0 -27
  92. package/components/Icon/Verified.tsx +0 -20
  93. package/components/Icon/index.ts +0 -14
  94. package/components/Image/Image.tsx +0 -32
  95. package/components/Image/index.ts +0 -2
  96. package/components/Input/Input.tsx +0 -109
  97. package/components/Input/Input.types.ts +0 -17
  98. package/components/Input/index.ts +0 -2
  99. package/components/Link/Link.stories.tsx +0 -96
  100. package/components/Link/Link.tsx +0 -39
  101. package/components/Link/Link.types.ts +0 -3
  102. package/components/Link/index.ts +0 -2
  103. package/components/Loader/CircularEasing.tsx +0 -66
  104. package/components/Loader/CircularEasing.types.ts +0 -8
  105. package/components/Loader/Pulse.tsx +0 -45
  106. package/components/Loader/Pulse.types.ts +0 -5
  107. package/components/Loader/index.ts +0 -4
  108. package/components/Menu/ContextMenu.tsx +0 -83
  109. package/components/Menu/Menu.tsx +0 -143
  110. package/components/Menu/Menu.types.ts +0 -44
  111. package/components/Menu/index.ts +0 -4
  112. package/components/Meter/Meter.stories.tsx +0 -111
  113. package/components/Meter/Meter.tsx +0 -68
  114. package/components/Meter/Meter.types.ts +0 -10
  115. package/components/Meter/index.ts +0 -2
  116. package/components/Modal/Modal.tsx +0 -16
  117. package/components/Modal/Modal.types.ts +0 -6
  118. package/components/Modal/index.ts +0 -2
  119. package/components/ModalOverlay/ModalOverlay.tsx +0 -121
  120. package/components/ModalOverlay/ModalOverlay.types.ts +0 -18
  121. package/components/ModalOverlay/index.ts +0 -2
  122. package/components/NumberFormat/NumberFormat.tsx +0 -19
  123. package/components/NumberFormat/NumberFormat.types.ts +0 -8
  124. package/components/NumberFormat/index.ts +0 -2
  125. package/components/NumberInput/NumberInput.tsx +0 -164
  126. package/components/NumberInput/NumberInput.types.ts +0 -22
  127. package/components/NumberInput/index.ts +0 -2
  128. package/components/NumberTicker/DigitResolver.tsx +0 -119
  129. package/components/NumberTicker/DigitResolver.types.ts +0 -18
  130. package/components/NumberTicker/NumberTicker.tsx +0 -56
  131. package/components/NumberTicker/NumberTicker.types.ts +0 -96
  132. package/components/NumberTicker/hooks/useColumnTransition.ts +0 -36
  133. package/components/NumberTicker/hooks/useNumberDelta.ts +0 -19
  134. package/components/NumberTicker/hooks/useNumberTicker.ts +0 -36
  135. package/components/NumberTicker/index.ts +0 -10
  136. package/components/Pagination/Pagination.tsx +0 -44
  137. package/components/Pagination/index.ts +0 -2
  138. package/components/PasswordCheck/PasswordCheck.tsx +0 -59
  139. package/components/PasswordCheck/PasswordCheck.types.ts +0 -4
  140. package/components/PasswordCheck/PasswordCheck.utils.ts +0 -47
  141. package/components/PasswordCheck/index.ts +0 -2
  142. package/components/PhoneInput/PhoneInput.tsx +0 -191
  143. package/components/PhoneInput/index.ts +0 -2
  144. package/components/PinInput/PinInput.tsx +0 -314
  145. package/components/PinInput/PinInput.types.ts +0 -21
  146. package/components/PinInput/index.ts +0 -2
  147. package/components/Progressbar/CircularProgressbar.tsx +0 -71
  148. package/components/Progressbar/CircularProgressbar.types.ts +0 -10
  149. package/components/Progressbar/LinearProgressbar.tsx +0 -75
  150. package/components/Progressbar/LinearProgressbar.types.ts +0 -11
  151. package/components/Progressbar/index.ts +0 -4
  152. package/components/Radio/Radio.tsx +0 -88
  153. package/components/Radio/Radio.types.ts +0 -16
  154. package/components/Radio/index.ts +0 -2
  155. package/components/RadioGroup/RadioGroup.tsx +0 -49
  156. package/components/RadioGroup/RadioGroup.types.ts +0 -7
  157. package/components/RadioGroup/index.ts +0 -2
  158. package/components/Select/Option.tsx +0 -32
  159. package/components/Select/Option.types.ts +0 -3
  160. package/components/Select/Select.tsx +0 -272
  161. package/components/Select/Select.types.ts +0 -48
  162. package/components/Select/index.ts +0 -8
  163. package/components/Skeleton/Skeleton.tsx +0 -15
  164. package/components/Skeleton/Skeleton.types.ts +0 -3
  165. package/components/Skeleton/index.ts +0 -2
  166. package/components/Slider/Slider.tsx +0 -110
  167. package/components/Slider/Slider.types.ts +0 -11
  168. package/components/Slider/index.ts +0 -2
  169. package/components/Switch/Switch.tsx +0 -63
  170. package/components/Switch/Switch.types.ts +0 -8
  171. package/components/Switch/index.ts +0 -2
  172. package/components/Table/Table.tsx +0 -52
  173. package/components/Table/Table.types.ts +0 -22
  174. package/components/Table/index.ts +0 -2
  175. package/components/Tabs/Tab.tsx +0 -118
  176. package/components/Tabs/Tab.types.ts +0 -10
  177. package/components/Tabs/TabList.tsx +0 -51
  178. package/components/Tabs/TabList.types.ts +0 -12
  179. package/components/Tabs/TabPanel.tsx +0 -19
  180. package/components/Tabs/TabPanel.types.ts +0 -3
  181. package/components/Tabs/Tabs.context.tsx +0 -9
  182. package/components/Tabs/Tabs.tsx +0 -39
  183. package/components/Tabs/Tabs.types.ts +0 -3
  184. package/components/Tabs/index.ts +0 -9
  185. package/components/TimeInput/TimeInput.stories.tsx +0 -125
  186. package/components/TimeInput/TimeInput.tsx +0 -81
  187. package/components/TimeInput/TimeInput.types.ts +0 -15
  188. package/components/TimeInput/index.ts +0 -2
  189. package/components/ToggleButton/ToggleButton.stories.tsx +0 -89
  190. package/components/ToggleButton/ToggleButton.tsx +0 -69
  191. package/components/ToggleButton/ToggleButton.types.ts +0 -6
  192. package/components/ToggleButton/index.ts +0 -2
  193. package/components/Tooltip/Tooltip.tsx +0 -59
  194. package/components/Tooltip/Tooltip.types.ts +0 -3
  195. package/components/Tooltip/index.ts +0 -2
  196. package/components/UploadImage/UploadImage.tsx +0 -206
  197. package/components/UploadImage/UploadImage.types.ts +0 -15
  198. package/components/UploadImage/index.ts +0 -2
@@ -1,75 +0,0 @@
1
- 'use client';
2
-
3
- import { ProgressBar, Label } from 'react-aria-components';
4
- import { motion } from 'framer-motion';
5
- import { cn } from '../../utils/cn';
6
- import type { LinearProgressbarProps } from './LinearProgressbar.types';
7
-
8
- export function LinearProgressbar({
9
- label,
10
- isIndeterminate,
11
- showValue = true,
12
- width,
13
- className,
14
- classNames,
15
- ...props
16
- }: LinearProgressbarProps) {
17
- return (
18
- <ProgressBar
19
- style={{ width: width || '100%' }}
20
- className={cn('overflow-hidden', className)}
21
- // eslint-disable-next-line react/jsx-props-no-spreading
22
- {...props}
23
- >
24
- {({ percentage, valueText }) => (
25
- <>
26
- <div
27
- className={cn(
28
- 'flex items-center justify-between gap-2 mb-1',
29
- classNames?.labelWrapper
30
- )}
31
- >
32
- <Label className={cn('text-sm', classNames?.label)}>{label}</Label>
33
- {showValue && (
34
- <span className={cn('text-sm', classNames?.value)}>
35
- {valueText}
36
- </span>
37
- )}
38
- </div>
39
- <div
40
- className={cn(
41
- 'overflow-hidden forced-color-adjust-none h-2.5 rounded will-change-transform bg-slate-300',
42
- classNames?.trackWrapper
43
- )}
44
- >
45
- <motion.div
46
- style={{
47
- width:
48
- !isIndeterminate && typeof percentage === 'number'
49
- ? `${percentage}%`
50
- : '',
51
- }}
52
- // eslint-disable-next-line react/jsx-props-no-spreading
53
- {...(isIndeterminate && {
54
- animate: {
55
- x: ['-100%', '250px'],
56
- },
57
- transition: { repeat: Infinity, duration: 1.5 },
58
- })}
59
- className={cn(
60
- 'h-full bg-slate-800 rounded transition-width duration-500 ease-in-out',
61
- {
62
- 'w-1/2': isIndeterminate,
63
- 'transition-none': isIndeterminate,
64
- },
65
- classNames?.track
66
- )}
67
- />
68
- </div>
69
- </>
70
- )}
71
- </ProgressBar>
72
- );
73
- }
74
-
75
- export default LinearProgressbar;
@@ -1,11 +0,0 @@
1
- import type { ProgressBarProps } from 'react-aria-components';
2
- import type { SlotsToClasses } from '../../types/SlotsToClasses';
3
-
4
- export interface LinearProgressbarProps extends ProgressBarProps {
5
- label?: string;
6
- width?: string;
7
- showValue?: boolean;
8
- classNames?: SlotsToClasses<
9
- 'label' | 'value' | 'labelWrapper' | 'track' | 'trackWrapper'
10
- >;
11
- }
@@ -1,4 +0,0 @@
1
- export { CircularProgressbar } from './CircularProgressbar';
2
- export { LinearProgressbar } from './LinearProgressbar';
3
- export type { CircularProgressbarProps } from './CircularProgressbar.types';
4
- export type { LinearProgressbarProps } from './LinearProgressbar.types';
@@ -1,88 +0,0 @@
1
- 'use client';
2
-
3
- import { Radio as AriaRadio } from 'react-aria-components';
4
- import type { RadioRenderProps } from 'react-aria-components';
5
- import { cn } from '../../utils/cn';
6
- import type { RadioProps, RadioSlots } from './Radio.types';
7
-
8
- function ControlSlot({
9
- control,
10
- classNames,
11
- ...props
12
- }: RadioRenderProps &
13
- Pick<RadioSlots, 'control'> &
14
- Pick<RadioProps, 'classNames'>) {
15
- if (!control) {
16
- return (
17
- <div
18
- data-hovered={props?.isHovered}
19
- data-focused={props?.isFocused}
20
- data-disabled={props?.isDisabled}
21
- data-invalid={props?.isInvalid}
22
- data-selected={props?.isSelected}
23
- data-pressed={props?.isPressed}
24
- className={cn(
25
- 'flex items-center justify-center w-6 h-6 border-solid border border-slate-300 ransition-all duration-300 ease rounded-full',
26
- 'data-[hovered="true"]:border-slate-400',
27
- 'data-[focused="true"]:border-slate-400 data-[focused="true"]:outline-2 data-[focused="true"]:outline data-[focused="true"]:outline-slate-200',
28
- 'data-[disabled="true"]:border-slate-200 data-[disabled="true"]:bg-slate-100',
29
- 'data-[invalid="true"]:bg-red-100 data-[invalid="true"]:text-red-600 data-[invalid="true"]:border-red-500',
30
- 'data-[invalid="true"]:data-[disabled="true"]:border-red-200 data-[invalid="true"]:data-[disabled="true"]:bg-red-100',
31
- 'data-[invalid="true"]:data-[hovered="true"]:border-red-600',
32
- 'data-[invalid="true"]:data-[focused="true"]:border-red-600 data-[invalid="true"]:data-[focused="true"]:outline-red-200',
33
- 'data-[invalid="true"]:data-[selected="true"]:bg-red-100 data-[invalid="true"]:data-[selected="true"]:border-red-500',
34
- 'data-[invalid="true"]:data-[pressed="true"]:bg-red-600 data-[invalid="true"]:data-[pressed="true"]:border-red-600',
35
- classNames?.control
36
- )}
37
- // eslint-disable-next-line react/jsx-props-no-spreading
38
- {...props}
39
- >
40
- <div
41
- data-invalid={props?.isInvalid}
42
- className={cn(
43
- 'w-3 h-3 rounded-full bg-slate-900 opacity-0 transition-all duration-300 ease data-[invalid="true"]:bg-red-500',
44
- {
45
- 'opacity-100': props?.isSelected,
46
- }
47
- )}
48
- />
49
- </div>
50
- );
51
- }
52
- return typeof control === 'function' ? control(props) : control;
53
- }
54
-
55
- export function Radio({
56
- children,
57
- slots,
58
- className,
59
- classNames,
60
- ...props
61
- }: RadioProps) {
62
- return (
63
- <AriaRadio
64
- className={cn(
65
- 'flex items-center gap-2 group',
66
- 'invalid:text-red-500 invalid:disabled:text-red-300',
67
- 'disabled:text-slate-400',
68
- className
69
- )}
70
- // eslint-disable-next-line react/jsx-props-no-spreading
71
- {...props}
72
- >
73
- {(renderProps) => (
74
- <>
75
- <ControlSlot
76
- control={slots?.control}
77
- classNames={classNames}
78
- // eslint-disable-next-line react/jsx-props-no-spreading
79
- {...renderProps}
80
- />
81
- {typeof children === 'function' ? children(renderProps) : children}
82
- </>
83
- )}
84
- </AriaRadio>
85
- );
86
- }
87
-
88
- export default Radio;
@@ -1,16 +0,0 @@
1
- import type { ReactNode } from 'react';
2
- import type {
3
- RadioRenderProps,
4
- RadioProps as UiRadioProps,
5
- } from 'react-aria-components';
6
- import type { SlotsToClasses } from '../../types/SlotsToClasses';
7
-
8
- export interface RadioSlots {
9
- control?: ReactNode | ((values: RadioRenderProps) => ReactNode);
10
- }
11
-
12
- export interface RadioProps extends UiRadioProps {
13
- children?: ReactNode | ((values: RadioRenderProps) => ReactNode);
14
- slots?: RadioSlots;
15
- classNames?: SlotsToClasses<'control'>;
16
- }
@@ -1,2 +0,0 @@
1
- export { Radio } from './Radio';
2
- export type { RadioProps, RadioSlots } from './Radio.types';
@@ -1,49 +0,0 @@
1
- import { Label, RadioGroup as AriaRadioGroup } from 'react-aria-components';
2
- import { cn } from '../../utils/cn';
3
- import { RadioGroupProps } from './RadioGroup.types';
4
-
5
- export function RadioGroup({
6
- label,
7
- errorMessage,
8
- description,
9
- orientation,
10
- children,
11
- className,
12
- ...props
13
- }: RadioGroupProps) {
14
- return (
15
- <AriaRadioGroup
16
- className={cn('flex flex-col gap-4', className)}
17
- orientation={orientation}
18
- // eslint-disable-next-line react/jsx-props-no-spreading
19
- {...props}
20
- >
21
- {typeof children === 'function' ? (
22
- children
23
- ) : (
24
- <>
25
- {label && (
26
- <Label className="flex text-slate-500 text-xs">{label}</Label>
27
- )}
28
- <div
29
- className={cn(
30
- 'flex flex-col gap-2',
31
- orientation === 'horizontal' && 'flex-row items-center gap-4'
32
- )}
33
- >
34
- {children}
35
- </div>
36
- {description && (
37
- <p className="flex mt-1 text-slate-500 text-sm">{description}</p>
38
- )}
39
-
40
- {errorMessage && (
41
- <p className="flex pl-6 text-red-500 text-sm">{errorMessage}</p>
42
- )}
43
- </>
44
- )}
45
- </AriaRadioGroup>
46
- );
47
- }
48
-
49
- export default RadioGroup;
@@ -1,7 +0,0 @@
1
- import type { RadioGroupProps as AriaRadioGroupProps } from 'react-aria-components';
2
-
3
- export interface RadioGroupProps extends AriaRadioGroupProps {
4
- label?: string;
5
- description?: string;
6
- errorMessage?: string;
7
- }
@@ -1,2 +0,0 @@
1
- export { RadioGroup } from './RadioGroup';
2
- export type { RadioGroupProps } from './RadioGroup.types';
@@ -1,32 +0,0 @@
1
- 'use client';
2
-
3
- import { ListBoxItem } from 'react-aria-components';
4
- import { cn } from '../../utils/cn';
5
- import type { OptionProps } from './Option.types';
6
-
7
- export function Option({ className, ...props }: OptionProps) {
8
- return (
9
- <ListBoxItem
10
- // eslint-disable-next-line react/jsx-props-no-spreading
11
- {...props}
12
- className={cn(
13
- 'flex flex-auto items-center',
14
- 'rounded-md',
15
- 'p-2.5 mx-1.5',
16
- 'text-sm',
17
- 'cursor-default',
18
- 'outline-none',
19
- 'text-slate-900',
20
- 'transition-all ease-in-out duration-300',
21
- 'data-[hovered]:bg-slate-100 data-[hovered]:text-slate-900',
22
- 'data-[focused]:bg-slate-100 data-[hovered]:text-slate-900',
23
- 'data-[pressed]:bg-slate-200 data-[hovered]:text-slate-900',
24
- 'data-[selected]:bg-none data-[selected]:text-slate-900 data-[selected]:font-semibold data-[selected]:data-[focused]:bg-slate-100',
25
- 'data-[disabled]:bg-none data-[disabled]:text-slate-500',
26
- className
27
- )}
28
- />
29
- );
30
- }
31
-
32
- export default Option;
@@ -1,3 +0,0 @@
1
- import type { ListBoxItemProps } from 'react-aria-components';
2
-
3
- export type OptionProps = ListBoxItemProps;
@@ -1,272 +0,0 @@
1
- 'use client';
2
-
3
- import {
4
- ListBox,
5
- ComboBox,
6
- Label,
7
- Input,
8
- Button,
9
- Text,
10
- FieldError,
11
- Popover,
12
- } from 'react-aria-components';
13
- import type { ComboBoxRenderProps, ListBoxProps } from 'react-aria-components';
14
- import { forwardRef, useState } from 'react';
15
- import type { ForwardedRef, Ref } from 'react';
16
- import { motion } from 'framer-motion';
17
- import { cn } from '../../utils/cn';
18
- import { Pulse } from '../Loader';
19
- import type {
20
- ComboBoxPopoverAnimationState,
21
- SelectProps,
22
- SelectSlots,
23
- } from './Select.types';
24
-
25
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
26
- const ForwardedPopover = forwardRef<HTMLElement, any>(
27
- (props, ref: Ref<HTMLElement>) => (
28
- // eslint-disable-next-line react/jsx-props-no-spreading
29
- <Popover {...props} ref={ref} />
30
- )
31
- );
32
-
33
- // Now use motion with ForwardedPopover
34
- const MotionPopover = motion.create(ForwardedPopover);
35
-
36
- function ButtonIconSlot<T extends object>({
37
- buttonIcon,
38
- ...props
39
- }: ComboBoxRenderProps & Pick<SelectSlots<T>, 'buttonIcon'>) {
40
- if (!buttonIcon) {
41
- return (
42
- <svg
43
- width="24"
44
- height="24"
45
- viewBox="0 0 24 24"
46
- fill="none"
47
- xmlns="http://www.w3.org/2000/svg"
48
- className={cn(
49
- 'transition-all ease-in-out duration-200',
50
- props.isOpen ? 'rotate-180' : 'rotate-0'
51
- )}
52
- >
53
- <path
54
- d="M6 9L12 15L18 9"
55
- strokeWidth="2"
56
- strokeLinecap="round"
57
- strokeLinejoin="round"
58
- className={cn([
59
- 'stroke-slate-900',
60
- props.isDisabled && 'stroke-slate-400',
61
- props.isInvalid && 'stroke-red-500',
62
- ])}
63
- />
64
- </svg>
65
- );
66
- }
67
-
68
- return typeof buttonIcon === 'function' ? buttonIcon(props) : buttonIcon;
69
- }
70
-
71
- function ListBoxSlot<T extends object>({
72
- listBoxComponent,
73
- children,
74
- ...props
75
- }: ListBoxProps<T> & Pick<SelectSlots<T>, 'listBoxComponent'>) {
76
- const Component = listBoxComponent || ListBox;
77
-
78
- return (
79
- <Component
80
- // eslint-disable-next-line react/jsx-props-no-spreading
81
- {...props}
82
- >
83
- {children}
84
- </Component>
85
- );
86
- }
87
-
88
- // Internal component - necessary to preserve generics in children
89
- // i.e. <Select items={[{id: 'test', value: 'test'}]}.../> won't reference "any"
90
- function SelectInner<T extends object>(
91
- {
92
- label,
93
- description,
94
- errorMessage,
95
- children,
96
- placeholder,
97
- key,
98
- isLoading,
99
- slots,
100
- popoverPortalContainer,
101
- popoverOffset,
102
- selectedKey,
103
- className,
104
- classNames,
105
- autoComplete,
106
- ...props
107
- }: SelectProps<T>,
108
- ref: ForwardedRef<HTMLInputElement>
109
- ) {
110
- const [animation, setAnimation] =
111
- useState<ComboBoxPopoverAnimationState>('unmounted');
112
- const [isComboOpen, setIsComboOpen] = useState<boolean>(false);
113
-
114
- return (
115
- <ComboBox
116
- onOpenChange={() => {
117
- setAnimation(animation === 'visible' ? 'hidden' : 'visible');
118
- setIsComboOpen(!isComboOpen);
119
- }}
120
- isDisabled={props.isDisabled || isLoading}
121
- data-has-value={!!selectedKey}
122
- selectedKey={selectedKey}
123
- // eslint-disable-next-line react/jsx-props-no-spreading
124
- {...props}
125
- className={cn('flex flex-col', 'w-full', className)}
126
- >
127
- {(renderProps) => (
128
- <>
129
- <Label
130
- className={cn('flex', 'text-xs text-slate-500', classNames?.label)}
131
- >
132
- {label}
133
- </Label>
134
- <div
135
- className={cn(
136
- 'flex',
137
- 'relative',
138
- 'w-full',
139
- classNames?.comboBoxContainer
140
- )}
141
- >
142
- <Input
143
- placeholder={placeholder}
144
- className={cn(
145
- 'border border-solid border-slate-300',
146
- 'text-sm text-slate-900',
147
- 'py-0 px-2',
148
- 'h-10 w-full',
149
- 'm-0',
150
- 'rounded-md',
151
- 'bg-white',
152
- 'transition-all ease-in-out duration-200',
153
- 'data-[hovered]:border-slate-400',
154
- 'data-[focused]:border-slate-400 data-[focused]:outline data-[focused]:outline-2 data-[focused]:outline-slate-200',
155
- ' data-[disabled]:bg-slate-100 data-[disabled]:border-slate-300',
156
- isLoading
157
- ? 'data-[disabled]:text-slate-900'
158
- : 'data-[disabled]:text-slate-500',
159
- 'data-[invalid]:border-red-500 data-[invalid]:bg-red-100 data-[invalid]:text-red-600',
160
- 'data-[invalid]:data-[hovered]:border-red-600',
161
- 'data-[invalid]:data-[focused]:border-red-600 data-[invalid]:data-[focused]:outline data-[invalid]:data-[focused]:outline-2 data-[invalid]:data-[focused]:outline-red-200',
162
- 'data-[invalid]:placeholder:text-slate-400',
163
- classNames?.input
164
- )}
165
- ref={ref}
166
- autoComplete={autoComplete}
167
- />
168
- {isLoading ? (
169
- <div
170
- className={cn(
171
- 'absolute top-2 right-2',
172
- 'block',
173
- classNames?.loader
174
- )}
175
- >
176
- {slots?.loadingIcon || <Pulse />}
177
- </div>
178
- ) : (
179
- <Button
180
- className={cn(
181
- 'absolute top-2 right-0',
182
- 'block',
183
- 'border-none',
184
- 'bg-none',
185
- classNames?.arrowButton
186
- )}
187
- >
188
- <ButtonIconSlot
189
- buttonIcon={slots?.buttonIcon}
190
- // eslint-disable-next-line react/jsx-props-no-spreading
191
- {...renderProps}
192
- />
193
- </Button>
194
- )}
195
- </div>
196
- {description && (
197
- <Text
198
- slot="description"
199
- className={cn(
200
- 'flex',
201
- 'text-xs',
202
- 'text-slate-500',
203
- classNames?.description
204
- )}
205
- >
206
- {description}
207
- </Text>
208
- )}
209
- <FieldError
210
- className={cn(
211
- 'flex',
212
- 'text-xs',
213
- 'text-red-500',
214
- classNames?.errorMessage
215
- )}
216
- >
217
- {errorMessage}
218
- </FieldError>
219
- <MotionPopover
220
- key={key}
221
- isOpen={isComboOpen}
222
- isExiting={animation === 'hidden'}
223
- offset={popoverOffset}
224
- UNSTABLE_portalContainer={popoverPortalContainer}
225
- onAnimationComplete={(completedAnimation: string) => {
226
- setAnimation((a) =>
227
- completedAnimation === 'hidden' && a === 'hidden'
228
- ? 'unmounted'
229
- : a
230
- );
231
- }}
232
- variants={{
233
- hidden: { opacity: 0, y: -10 },
234
- visible: { opacity: 1, y: 0 },
235
- }}
236
- initial="hidden"
237
- animate={animation}
238
- className={cn(
239
- 'px-0 py-1.5',
240
- 'shadow-[0_10px_15px_-3px_rgba(0,0,0,0.1),0_4px_6px_-4px_rgba(0,0,0,0.1)]',
241
- 'rounded-md',
242
- 'w-[var(--trigger-width)]',
243
- 'bg-white',
244
- 'border border-solid border-slate-300',
245
- classNames?.listContainer
246
- )}
247
- >
248
- <ListBoxSlot
249
- listBoxComponent={slots?.listBoxComponent}
250
- className={cn('max-h-80', 'overflow-y-scroll', classNames?.list)}
251
- >
252
- {children}
253
- </ListBoxSlot>
254
- </MotionPopover>
255
- </>
256
- )}
257
- </ComboBox>
258
- );
259
- }
260
-
261
- // Type for the exported component that preserves generics
262
- interface SelectComponent {
263
- <T extends object>(
264
- props: SelectProps<T> & { ref?: ForwardedRef<HTMLInputElement> }
265
- ): JSX.Element;
266
- }
267
-
268
- // Create the forwarded component with proper typing
269
- export const Select = forwardRef(SelectInner) as SelectComponent;
270
-
271
- export default Select;
272
-
@@ -1,48 +0,0 @@
1
- import type {
2
- ComboBoxRenderProps,
3
- ComboBoxProps as AriaComboBoxProps,
4
- ValidationResult,
5
- ListBoxProps,
6
- } from 'react-aria-components';
7
- import type {
8
- ComponentType,
9
- HTMLInputAutoCompleteAttribute,
10
- Key,
11
- ReactNode,
12
- } from 'react';
13
- import type { SlotsToClasses } from '../../types/SlotsToClasses';
14
-
15
- export type ComboBoxPopoverAnimationState = 'unmounted' | 'hidden' | 'visible';
16
-
17
- export type SelectSlots<T extends object> = {
18
- buttonIcon?: ReactNode | ((values: ComboBoxRenderProps) => ReactNode);
19
- loadingIcon?: ReactNode;
20
- listBoxComponent?: ComponentType<ListBoxProps<T>>;
21
- };
22
-
23
- export interface SelectProps<T extends object>
24
- extends Omit<AriaComboBoxProps<T>, 'children'> {
25
- label?: string;
26
- description?: string | null;
27
- errorMessage?: string | ((validation: ValidationResult) => string);
28
- placeholder?: string;
29
- key?: Key | null;
30
- isLoading?: boolean;
31
- children: ReactNode | ((item: T) => ReactNode);
32
- slots?: SelectSlots<T>;
33
- popoverOffset?: number;
34
- popoverPortalContainer?: Element;
35
- classNames?: SlotsToClasses<
36
- | 'label'
37
- | 'name'
38
- | 'comboBoxContainer'
39
- | 'input'
40
- | 'loader'
41
- | 'arrowButton'
42
- | 'description'
43
- | 'errorMessage'
44
- | 'listContainer'
45
- | 'list'
46
- >;
47
- autoComplete?: HTMLInputAutoCompleteAttribute;
48
- }
@@ -1,8 +0,0 @@
1
- export { Option } from './Option';
2
- export { Select } from './Select';
3
- export type { OptionProps } from './Option.types';
4
- export type {
5
- ComboBoxPopoverAnimationState,
6
- SelectProps,
7
- SelectSlots,
8
- } from './Select.types';
@@ -1,15 +0,0 @@
1
- import { cn } from '../../utils/cn';
2
- import type { SkeletonProps } from './Skeleton.types';
3
-
4
- export function Skeleton({ className }: SkeletonProps) {
5
- return (
6
- <div
7
- className={cn(
8
- 'relative rounded-md animate-pulse bg-slate-200',
9
- className
10
- )}
11
- />
12
- );
13
- }
14
-
15
- export default Skeleton;
@@ -1,3 +0,0 @@
1
- export type SkeletonProps = {
2
- className?: string;
3
- };
@@ -1,2 +0,0 @@
1
- export { Skeleton } from './Skeleton';
2
- export type { SkeletonProps } from './Skeleton.types';