@infonomic/uikit 5.44.0 → 6.0.1

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 (180) hide show
  1. package/README.md +12 -3
  2. package/dist/components/accordion/accordion.d.ts +9 -9
  3. package/dist/components/accordion/accordion.d.ts.map +1 -1
  4. package/dist/components/accordion/accordion.js +4 -4
  5. package/dist/components/accordion/accordion.module.css +6 -5
  6. package/dist/components/accordion/accordion_module.css +4 -4
  7. package/dist/components/avatar/avatar.js +2 -2
  8. package/dist/components/badge/badge.d.ts +5 -13
  9. package/dist/components/badge/badge.d.ts.map +1 -1
  10. package/dist/components/badge/badge.js +12 -9
  11. package/dist/components/button/button-group.d.ts +9 -7
  12. package/dist/components/button/button-group.d.ts.map +1 -1
  13. package/dist/components/button/button-group.js +26 -36
  14. package/dist/components/button/button.d.ts +6 -13
  15. package/dist/components/button/button.d.ts.map +1 -1
  16. package/dist/components/button/button.js +19 -18
  17. package/dist/components/button/button.module.css +32 -54
  18. package/dist/components/button/button_module.css +7 -10
  19. package/dist/components/button/combo-button.d.ts +1 -1
  20. package/dist/components/button/combo-button.d.ts.map +1 -1
  21. package/dist/components/button/combo-button.js +13 -9
  22. package/dist/components/button/combo-button.module.css +16 -7
  23. package/dist/components/button/combo-button_module.css +22 -4
  24. package/dist/components/button/icon-button.d.ts +2 -3
  25. package/dist/components/button/icon-button.d.ts.map +1 -1
  26. package/dist/components/card/card.d.ts +5 -12
  27. package/dist/components/card/card.d.ts.map +1 -1
  28. package/dist/components/card/card.js +13 -9
  29. package/dist/components/chips/chip.d.ts +5 -11
  30. package/dist/components/chips/chip.d.ts.map +1 -1
  31. package/dist/components/chips/chip.js +36 -28
  32. package/dist/components/chips/chip.module.css +22 -36
  33. package/dist/components/chips/chip_module.css +3 -6
  34. package/dist/components/dropdown/dropdown.d.ts +28 -14
  35. package/dist/components/dropdown/dropdown.d.ts.map +1 -1
  36. package/dist/components/dropdown/dropdown.js +34 -20
  37. package/dist/components/forms/calendar.d.ts +1 -1
  38. package/dist/components/forms/calendar.d.ts.map +1 -1
  39. package/dist/components/forms/calendar.js +38 -29
  40. package/dist/components/forms/checkbox.astro +13 -8
  41. package/dist/components/forms/checkbox.d.ts +6 -2
  42. package/dist/components/forms/checkbox.d.ts.map +1 -1
  43. package/dist/components/forms/checkbox.js +11 -7
  44. package/dist/components/forms/checkbox.module.css +20 -20
  45. package/dist/components/forms/checkbox_module.css +13 -10
  46. package/dist/components/forms/input.module.css +10 -11
  47. package/dist/components/forms/input_module.css +3 -5
  48. package/dist/components/forms/radio-group.d.ts +6 -5
  49. package/dist/components/forms/radio-group.d.ts.map +1 -1
  50. package/dist/components/forms/radio-group.js +9 -4
  51. package/dist/components/forms/radio-group.module.css +13 -22
  52. package/dist/components/forms/radio-group_module.css +6 -24
  53. package/dist/components/forms/select.d.ts +4 -5
  54. package/dist/components/forms/select.d.ts.map +1 -1
  55. package/dist/components/forms/select.js +27 -29
  56. package/dist/components/forms/select.module.css +22 -22
  57. package/dist/components/forms/select.module.js +15 -15
  58. package/dist/components/forms/select_module.css +15 -15
  59. package/dist/components/notifications/@types/toast.d.ts +9 -7
  60. package/dist/components/notifications/@types/toast.d.ts.map +1 -1
  61. package/dist/components/notifications/toast.d.ts +12 -16
  62. package/dist/components/notifications/toast.d.ts.map +1 -1
  63. package/dist/components/notifications/toast.js +73 -57
  64. package/dist/components/notifications/toast.module.css +151 -177
  65. package/dist/components/notifications/toast.module.js +8 -12
  66. package/dist/components/notifications/toast_module.css +114 -159
  67. package/dist/components/pager/first-button.d.ts +2 -2
  68. package/dist/components/pager/first-button.d.ts.map +1 -1
  69. package/dist/components/pager/first-button.js +23 -16
  70. package/dist/components/pager/last-button.d.ts +2 -2
  71. package/dist/components/pager/last-button.d.ts.map +1 -1
  72. package/dist/components/pager/last-button.js +23 -16
  73. package/dist/components/pager/next-button.d.ts +2 -2
  74. package/dist/components/pager/next-button.d.ts.map +1 -1
  75. package/dist/components/pager/next-button.js +27 -20
  76. package/dist/components/pager/number-button.d.ts +2 -2
  77. package/dist/components/pager/number-button.d.ts.map +1 -1
  78. package/dist/components/pager/number-button.js +28 -23
  79. package/dist/components/pager/pagination.d.ts +8 -13
  80. package/dist/components/pager/pagination.d.ts.map +1 -1
  81. package/dist/components/pager/previous-button.d.ts +2 -2
  82. package/dist/components/pager/previous-button.d.ts.map +1 -1
  83. package/dist/components/pager/previous-button.js +25 -18
  84. package/dist/components/scroll-area/scroll-area.d.ts +2 -2
  85. package/dist/components/scroll-area/scroll-area.d.ts.map +1 -1
  86. package/dist/components/scroll-area/scroll-area.js +4 -2
  87. package/dist/components/tabs/tabs.d.ts +13 -13
  88. package/dist/components/tabs/tabs.d.ts.map +1 -1
  89. package/dist/components/tabs/tabs.js +8 -8
  90. package/dist/components/tabs/tabs.module.css +8 -17
  91. package/dist/components/tabs/tabs_module.css +1 -1
  92. package/dist/components/tooltip/tooltip.d.ts +6 -8
  93. package/dist/components/tooltip/tooltip.d.ts.map +1 -1
  94. package/dist/components/tooltip/tooltip.js +49 -20
  95. package/dist/components/tooltip/tooltip.module.css +43 -10
  96. package/dist/components/tooltip/tooltip.module.js +7 -1
  97. package/dist/components/tooltip/tooltip_module.css +36 -4
  98. package/dist/hooks/use-focus-trap/index.d.ts +2 -0
  99. package/dist/hooks/use-focus-trap/index.d.ts.map +1 -0
  100. package/dist/hooks/use-focus-trap/index.js +1 -0
  101. package/dist/hooks/use-focus-trap/scope-tab.d.ts +11 -0
  102. package/dist/hooks/use-focus-trap/scope-tab.d.ts.map +1 -0
  103. package/dist/hooks/use-focus-trap/scope-tab.js +19 -0
  104. package/dist/hooks/use-focus-trap/tabbable.d.ts +14 -0
  105. package/dist/hooks/use-focus-trap/tabbable.d.ts.map +1 -0
  106. package/dist/hooks/use-focus-trap/tabbable.js +36 -0
  107. package/dist/hooks/use-focus-trap/use-focus-trap.d.ts +11 -0
  108. package/dist/hooks/use-focus-trap/use-focus-trap.d.ts.map +1 -0
  109. package/dist/hooks/use-focus-trap/use-focus-trap.js +45 -0
  110. package/dist/icons/chevron-up-icon.d.ts +7 -0
  111. package/dist/icons/chevron-up-icon.d.ts.map +1 -0
  112. package/dist/icons/chevron-up-icon.js +27 -0
  113. package/dist/lib/ripple.d.ts +25 -0
  114. package/dist/lib/ripple.d.ts.map +1 -0
  115. package/dist/lib/ripple.js +53 -0
  116. package/dist/styles/components-vanilla.css +1 -1
  117. package/dist/widgets/datepicker/datepicker.d.ts +1 -1
  118. package/dist/widgets/datepicker/datepicker.d.ts.map +1 -1
  119. package/dist/widgets/datepicker/datepicker.js +118 -116
  120. package/dist/widgets/datepicker/datepicker.module.css +6 -5
  121. package/dist/widgets/datepicker/datepicker_module.css +4 -4
  122. package/dist/widgets/drawer/drawer-wrapper.d.ts.map +1 -1
  123. package/dist/widgets/drawer/drawer-wrapper.js +1 -1
  124. package/dist/widgets/modal/modal-wrapper.d.ts.map +1 -1
  125. package/dist/widgets/modal/modal-wrapper.js +1 -1
  126. package/package.json +2 -6
  127. package/src/components/accordion/accordion.module.css +6 -5
  128. package/src/components/accordion/accordion.stories.tsx +10 -13
  129. package/src/components/accordion/accordion.tsx +13 -13
  130. package/src/components/avatar/avatar.tsx +2 -2
  131. package/src/components/badge/badge.tsx +20 -29
  132. package/src/components/button/button-group.tsx +60 -44
  133. package/src/components/button/button.module.css +32 -54
  134. package/src/components/button/button.tsx +35 -47
  135. package/src/components/button/combo-button.module.css +16 -7
  136. package/src/components/button/combo-button.tsx +17 -9
  137. package/src/components/button/icon-button.tsx +3 -5
  138. package/src/components/card/card.tsx +20 -32
  139. package/src/components/chips/chip.module.css +22 -36
  140. package/src/components/chips/chip.stories.tsx +2 -2
  141. package/src/components/chips/chip.tsx +59 -57
  142. package/src/components/dropdown/dropdown.stories.tsx +2 -4
  143. package/src/components/dropdown/dropdown.tsx +86 -40
  144. package/src/components/forms/calendar.tsx +43 -33
  145. package/src/components/forms/checkbox-group.tsx +1 -1
  146. package/src/components/forms/checkbox.astro +13 -8
  147. package/src/components/forms/checkbox.module.css +20 -20
  148. package/src/components/forms/checkbox.tsx +11 -6
  149. package/src/components/forms/input.module.css +10 -11
  150. package/src/components/forms/radio-group.module.css +13 -22
  151. package/src/components/forms/radio-group.tsx +13 -11
  152. package/src/components/forms/select.module.css +22 -22
  153. package/src/components/forms/select.tsx +36 -33
  154. package/src/components/notifications/@types/toast.ts +9 -7
  155. package/src/components/notifications/toast.module.css +151 -177
  156. package/src/components/notifications/toast.stories.tsx +21 -23
  157. package/src/components/notifications/toast.tsx +90 -86
  158. package/src/components/pager/first-button.tsx +24 -26
  159. package/src/components/pager/last-button.tsx +24 -25
  160. package/src/components/pager/next-button.tsx +24 -23
  161. package/src/components/pager/number-button.tsx +37 -36
  162. package/src/components/pager/pagination.tsx +4 -11
  163. package/src/components/pager/previous-button.tsx +24 -24
  164. package/src/components/scroll-area/scroll-area.tsx +3 -3
  165. package/src/components/tabs/tabs.module.css +8 -17
  166. package/src/components/tabs/tabs.stories.tsx +5 -5
  167. package/src/components/tabs/tabs.tsx +17 -16
  168. package/src/components/tooltip/tooltip.module.css +43 -10
  169. package/src/components/tooltip/tooltip.stories.tsx +4 -4
  170. package/src/components/tooltip/tooltip.tsx +56 -28
  171. package/src/hooks/use-focus-trap/index.ts +1 -0
  172. package/src/hooks/use-focus-trap/scope-tab.ts +48 -0
  173. package/src/hooks/use-focus-trap/tabbable.ts +72 -0
  174. package/src/hooks/use-focus-trap/use-focus-trap.ts +83 -0
  175. package/src/icons/chevron-up-icon.tsx +37 -0
  176. package/src/lib/ripple.ts +95 -0
  177. package/src/widgets/datepicker/datepicker.module.css +6 -5
  178. package/src/widgets/datepicker/datepicker.tsx +137 -135
  179. package/src/widgets/drawer/drawer-wrapper.tsx +1 -1
  180. package/src/widgets/modal/modal-wrapper.tsx +1 -1
@@ -2,9 +2,8 @@
2
2
 
3
3
  import React from 'react'
4
4
 
5
- import { useFocusTrap, useMergedRef } from '@mantine/hooks'
5
+ import { Toast as ToastPrimitive } from '@base-ui/react/toast'
6
6
  import cx from 'classnames'
7
- import { Toast as ToastPrimitive } from 'radix-ui'
8
7
 
9
8
  import { CloseIcon } from '../../icons/close-icon'
10
9
  import { DangerIcon } from '../../icons/danger-icon'
@@ -13,7 +12,7 @@ import { SuccessIcon } from '../../icons/success-icon'
13
12
  import { WarningIcon } from '../../icons/warning-icon'
14
13
  import { Button } from '../button/button.js'
15
14
  import styles from './toast.module.css'
16
- import type { IconType, Intent, OnOpenChange, Position } from './@types/toast.js'
15
+ import type { Position, ToastData } from './@types/toast.js'
17
16
 
18
17
  const toastIcons = {
19
18
  success: SuccessIcon,
@@ -22,105 +21,110 @@ const toastIcons = {
22
21
  danger: DangerIcon,
23
22
  }
24
23
 
25
- export interface ToastProps extends React.InputHTMLAttributes<HTMLLIElement> {
26
- intent?: Intent
24
+ // Re-export Base UI toast utilities
25
+ export const useToastManager = ToastPrimitive.useToastManager<ToastData>
26
+ export const createToastManager = ToastPrimitive.createToastManager<ToastData>
27
+
28
+ export interface ToastProviderProps {
29
+ children: React.ReactNode
30
+ timeout?: number
31
+ limit?: number
32
+ toastManager?: ReturnType<typeof createToastManager>
33
+ }
34
+
35
+ export function ToastProvider({
36
+ children,
37
+ timeout = 5000,
38
+ limit = 3,
39
+ toastManager,
40
+ }: ToastProviderProps) {
41
+ return (
42
+ <ToastPrimitive.Provider timeout={timeout} limit={limit} toastManager={toastManager}>
43
+ {children}
44
+ </ToastPrimitive.Provider>
45
+ )
46
+ }
47
+
48
+ export interface ToastViewportProps {
27
49
  position?: Position
28
- title: string
29
- message: string
30
- icon?: boolean
31
- iconType?: IconType
32
- close?: boolean
33
- open: boolean
34
- onOpenChange: OnOpenChange
35
50
  className?: string
36
51
  }
37
52
 
38
- export const ToastProvider = ToastPrimitive.Provider
39
- export const ToastViewport = ToastPrimitive.Viewport
40
-
41
- // Important!: see comments in app/ui/components/notifications/styles/toast.ts regarding toast position
53
+ export function ToastViewport({ position = 'bottom-right', className }: ToastViewportProps) {
54
+ const { toasts } = ToastPrimitive.useToastManager<ToastData>()
55
+ return (
56
+ <ToastPrimitive.Portal>
57
+ <ToastPrimitive.Viewport
58
+ className={cx('infonomic-toast-viewport', styles.viewport, styles[position], className)}
59
+ >
60
+ {toasts.map((toast) => (
61
+ <ToastItem key={toast.id} toast={toast} />
62
+ ))}
63
+ </ToastPrimitive.Viewport>
64
+ </ToastPrimitive.Portal>
65
+ )
66
+ }
42
67
 
43
- export const Toast = function Toast({
44
- ref,
45
- intent = 'success',
46
- position = 'bottom-right',
47
- title,
48
- message,
49
- icon = true,
50
- iconType = 'success',
51
- close = true,
52
- open,
53
- onOpenChange,
54
- className,
55
- }: ToastProps & {
56
- ref?: React.RefObject<HTMLLIElement>
68
+ function ToastItem({
69
+ toast,
70
+ }: {
71
+ toast: ToastPrimitive.Root.ToastObject<ToastData>
57
72
  }) {
73
+ const {
74
+ intent = 'success',
75
+ iconType = 'success',
76
+ icon = true,
77
+ close = true,
78
+ } = toast.data ?? {}
58
79
  const eventDateRef = React.useRef(new Date())
59
- const timerRef = React.useRef(0)
60
- const focusTrapRef = useFocusTrap()
61
- const mergedRef = useMergedRef(ref, focusTrapRef)
62
80
  const Icon = toastIcons[iconType as keyof typeof toastIcons]
63
81
 
64
- const handleOnClose = (): void => {
65
- if (onOpenChange != null) onOpenChange(false)
66
- }
67
-
68
- const _handleOnChange = (open: boolean): void => {
69
- console.log('handleOnChange', { open })
70
- if (open) {
71
- timerRef.current = window.setTimeout(() => {
72
- onOpenChange(false)
73
- }, 5000)
74
- } else {
75
- window.clearTimeout(timerRef.current)
76
- }
77
- }
82
+ const swipeDirection = React.useMemo<
83
+ React.ComponentProps<typeof ToastPrimitive.Root>['swipeDirection']
84
+ >(() => ['down', 'right'], [])
78
85
 
79
86
  return (
80
87
  <ToastPrimitive.Root
81
- ref={mergedRef}
82
- className={cx('infonomic-toast', styles.root, styles[position])}
83
- open={open}
84
- onOpenChange={onOpenChange}
88
+ toast={toast}
89
+ swipeDirection={swipeDirection}
90
+ className={cx('infonomic-toast', styles.root)}
85
91
  >
86
- <div className={cx('infonomic-toast-header', styles.header)}>
87
- <time dateTime={eventDateRef.current.toISOString()} className="text-sm">
88
- {new Intl.DateTimeFormat('default', {
89
- hour12: true,
90
- hour: 'numeric',
91
- minute: 'numeric',
92
- }).format(eventDateRef.current)}
93
- </time>
94
- {close === true && (
95
- <ToastPrimitive.Close aria-label="Close" asChild>
96
- <Button
97
- intent={intent}
98
- tabIndex={0}
99
- variant="filled"
100
- aria-label="Close"
101
- className={cx('infonomic-toast-close', styles.close)}
102
- type="button"
103
- onClick={handleOnClose}
92
+ <ToastPrimitive.Content className={cx('infonomic-toast-content', styles.content)}>
93
+ <div className={cx('infonomic-toast-header', styles.header)}>
94
+ <time dateTime={eventDateRef.current.toISOString()} className="text-sm">
95
+ {new Intl.DateTimeFormat('default', {
96
+ hour12: true,
97
+ hour: 'numeric',
98
+ minute: 'numeric',
99
+ }).format(eventDateRef.current)}
100
+ </time>
101
+ {close && (
102
+ <ToastPrimitive.Close
103
+ render={
104
+ <Button
105
+ intent={intent}
106
+ tabIndex={0}
107
+ variant="filled"
108
+ aria-label="Close"
109
+ className={cx('infonomic-toast-close', styles.close)}
110
+ type="button"
111
+ />
112
+ }
104
113
  >
105
114
  <CloseIcon height="12px" width="12px" />
106
- </Button>
107
- </ToastPrimitive.Close>
108
- )}
109
- </div>
110
- <ToastPrimitive.Title className={cx('infonomic-toast-title', styles.title)}>
111
- {icon != null && <Icon />}
112
- {title}
113
- </ToastPrimitive.Title>
114
- <ToastPrimitive.Description className={cx('infonomic-toast-description', styles.description)}>
115
- {message}
116
- </ToastPrimitive.Description>
117
- {/* <ToastPrimitive.Action className={styles.action} asChild altText="Goto schedule to undo">
118
- <div>
119
- <Button intent="primary" tabIndex={0} size="sm" variant="filled">
120
- Undo
121
- </Button>
115
+ </ToastPrimitive.Close>
116
+ )}
122
117
  </div>
123
- </ToastPrimitive.Action> */}
118
+ <ToastPrimitive.Title className={cx('infonomic-toast-title', styles.title)}>
119
+ {icon && Icon && <Icon />}
120
+ {toast.title}
121
+ </ToastPrimitive.Title>
122
+ <ToastPrimitive.Description
123
+ className={cx('infonomic-toast-description', styles.description)}
124
+ >
125
+ {toast.description}
126
+ </ToastPrimitive.Description>
127
+ </ToastPrimitive.Content>
124
128
  </ToastPrimitive.Root>
125
129
  )
126
130
  }
@@ -1,13 +1,10 @@
1
1
  'use client'
2
2
 
3
- /* eslint-disable @typescript-eslint/strict-boolean-expressions */
3
+ import React from 'react'
4
4
 
5
- import type React from 'react'
6
-
7
- import { DoubleArrowLeftIcon } from '@radix-ui/react-icons'
8
- import { Slot } from '@radix-ui/react-slot'
9
5
  import cx from 'classnames'
10
6
 
7
+ import { ChevronLeftDoubleIcon } from '../../icons/chevron-left-double-icon.js'
11
8
  import { usePager } from './pagination'
12
9
  import styles from './pagination.module.css'
13
10
  import type { PagerButtonProps, RefType } from './pagination'
@@ -16,7 +13,7 @@ export const FirstButton = ({
16
13
  ref,
17
14
  className,
18
15
  disabled,
19
- asChild,
16
+ render,
20
17
  children,
21
18
  ...rest
22
19
  }: PagerButtonProps & {
@@ -24,29 +21,30 @@ export const FirstButton = ({
24
21
  }) => {
25
22
  const { variant } = usePager()
26
23
 
27
- const Comp = asChild != null ? Slot : ('button' as React.ElementType)
28
-
29
- const aria = disabled ? { 'aria-disabled': true } : { 'aria-label': 'First' }
24
+ const sharedProps = {
25
+ className: cx(
26
+ styles['first-button'],
27
+ styles[variant],
28
+ styles['rounded-left'],
29
+ 'pagination-first',
30
+ className
31
+ ),
32
+ disabled,
33
+ 'data-testid': 'pagination-first',
34
+ title: 'First',
35
+ ...(disabled ? { 'aria-disabled': true } : { 'aria-label': 'First' }),
36
+ ...rest,
37
+ }
30
38
 
31
39
  return (
32
40
  <li className={styles['mobile-toggle']}>
33
- <Comp
34
- ref={ref}
35
- className={cx(
36
- styles['first-button'],
37
- styles[variant],
38
- styles['rounded-left'],
39
- 'pagination-first',
40
- className
41
- )}
42
- disabled={disabled}
43
- data-testid="pagination-first"
44
- title="First"
45
- {...aria}
46
- {...rest}
47
- >
48
- {(asChild ?? false) ? children : <DoubleArrowLeftIcon />}
49
- </Comp>
41
+ {render ? (
42
+ React.cloneElement(render, { ref, ...sharedProps } as React.Attributes & Record<string, unknown>, children)
43
+ ) : (
44
+ <button ref={ref as React.RefObject<HTMLButtonElement>} {...sharedProps}>
45
+ {children ?? <ChevronLeftDoubleIcon width="18px" height="18px" />}
46
+ </button>
47
+ )}
50
48
  </li>
51
49
  )
52
50
  }
@@ -1,13 +1,10 @@
1
1
  'use client'
2
2
 
3
- /* eslint-disable @typescript-eslint/strict-boolean-expressions */
3
+ import React from 'react'
4
4
 
5
- import type React from 'react'
6
-
7
- import { DoubleArrowRightIcon } from '@radix-ui/react-icons'
8
- import { Slot } from '@radix-ui/react-slot'
9
5
  import cx from 'classnames'
10
6
 
7
+ import { ChevronRightDoubleIcon } from '../../icons/chevron-right-double-icon.js'
11
8
  import { usePager } from './pagination'
12
9
  import styles from './pagination.module.css'
13
10
  import type { PagerButtonProps, RefType } from './pagination'
@@ -21,36 +18,38 @@ export const LastButton = ({
21
18
  className,
22
19
  disabled,
23
20
  count,
24
- asChild,
21
+ render,
25
22
  children,
26
23
  ...rest
27
24
  }: LastButtonProps & {
28
25
  ref?: React.RefObject<RefType>
29
26
  }) => {
30
27
  const { variant } = usePager()
31
- const Comp = asChild != null ? Slot : ('button' as React.ElementType)
32
28
 
33
- const aria = disabled ? { 'aria-disabled': true } : { 'aria-label': 'Last' }
29
+ const sharedProps = {
30
+ className: cx(
31
+ styles['last-button'],
32
+ styles[variant],
33
+ styles['rounded-right'],
34
+ 'pagination-last',
35
+ className
36
+ ),
37
+ disabled,
38
+ title: 'Last',
39
+ 'data-testid': 'pagination-last',
40
+ ...(disabled ? { 'aria-disabled': true } : { 'aria-label': 'Last' }),
41
+ ...rest,
42
+ }
34
43
 
35
44
  return (
36
45
  <li className={styles['mobile-toggle']}>
37
- <Comp
38
- ref={ref}
39
- className={cx(
40
- styles['last-button'],
41
- styles[variant],
42
- styles['rounded-right'],
43
- 'pagination-last',
44
- className
45
- )}
46
- disabled={disabled}
47
- title="Last"
48
- data-testid="pagination-last"
49
- {...aria}
50
- {...rest}
51
- >
52
- {(asChild ?? false) ? children : <DoubleArrowRightIcon />}
53
- </Comp>
46
+ {render ? (
47
+ React.cloneElement(render, { ref, ...sharedProps } as React.Attributes & Record<string, unknown>, children)
48
+ ) : (
49
+ <button ref={ref as React.RefObject<HTMLButtonElement>} {...sharedProps}>
50
+ {children ?? <ChevronRightDoubleIcon width="18px" height="18px" />}
51
+ </button>
52
+ )}
54
53
  </li>
55
54
  )
56
55
  }
@@ -1,11 +1,10 @@
1
1
  'use client'
2
2
 
3
- import type React from 'react'
3
+ import React from 'react'
4
4
 
5
- import { ChevronRightIcon } from '@radix-ui/react-icons'
6
- import { Slot } from '@radix-ui/react-slot'
7
5
  import cx from 'classnames'
8
6
 
7
+ import { ChevronRightIcon } from '../../icons/chevron-right-icon.js'
9
8
  import { usePager } from './pagination'
10
9
  import styles from './pagination.module.css'
11
10
  import type { PagerButtonProps, RefType } from './pagination'
@@ -19,36 +18,38 @@ export const NextButton = ({
19
18
  className,
20
19
  disabled,
21
20
  page,
22
- asChild,
21
+ render,
23
22
  children,
24
23
  ...rest
25
24
  }: NextButtonProps & {
26
25
  ref?: React.RefObject<RefType>
27
26
  }) => {
28
- const Comp = asChild != null ? Slot : ('button' as React.ElementType)
29
27
  const { variant, showLastButton } = usePager()
30
28
 
31
- const aria = disabled ? { 'aria-disabled': true } : { 'aria-label': 'Next' }
29
+ const sharedProps = {
30
+ className: cx(
31
+ styles['next-button'],
32
+ [styles[variant]],
33
+ { [styles['rounded-right']]: showLastButton == null || showLastButton === false },
34
+ 'pagination-next',
35
+ className
36
+ ),
37
+ disabled,
38
+ title: 'Next',
39
+ 'data-testid': 'pagination-next',
40
+ ...(disabled ? { 'aria-disabled': true } : { 'aria-label': 'Next' }),
41
+ ...rest,
42
+ }
32
43
 
33
44
  return (
34
45
  <li className={styles['mobile-toggle']}>
35
- <Comp
36
- ref={ref}
37
- className={cx(
38
- styles['next-button'],
39
- [styles[variant]],
40
- { [styles['rounded-right']]: showLastButton == null || showLastButton === false },
41
- 'pagination-next',
42
- className
43
- )}
44
- disabled={disabled}
45
- title="Next"
46
- data-testid="pagination-next"
47
- {...aria}
48
- {...rest}
49
- >
50
- {(asChild ?? false) ? children : <ChevronRightIcon />}
51
- </Comp>
46
+ {render ? (
47
+ React.cloneElement(render, { ref, ...sharedProps } as React.Attributes & Record<string, unknown>, children)
48
+ ) : (
49
+ <button ref={ref as React.RefObject<HTMLButtonElement>} {...sharedProps}>
50
+ {children ?? <ChevronRightIcon width="18px" height="18px" />}
51
+ </button>
52
+ )}
52
53
  </li>
53
54
  )
54
55
  }
@@ -1,8 +1,7 @@
1
1
  'use client'
2
2
 
3
- import type React from 'react'
3
+ import React from 'react'
4
4
 
5
- import { Slot } from '@radix-ui/react-slot'
6
5
  import cx from 'classnames'
7
6
 
8
7
  import { useMediaQuery } from '../../hooks/use-media-query'
@@ -22,7 +21,7 @@ export const NumberButton = ({
22
21
  className,
23
22
  disabled,
24
23
  activeClassName,
25
- asChild,
24
+ render,
26
25
  children,
27
26
  ...rest
28
27
  }: NumberButtonProps & {
@@ -39,43 +38,45 @@ export const NumberButton = ({
39
38
  hidePrevButton,
40
39
  } = usePager()
41
40
 
42
- const Comp = asChild != null ? Slot : ('button' as React.ElementType)
43
-
44
41
  const active = page === currentPage
45
42
 
43
+ const sharedProps = {
44
+ className: cx(
45
+ styles['number-button'],
46
+ [styles[variant]],
47
+ { [styles.active]: active === true, active: active === true },
48
+ {
49
+ [styles['rounded-left']]:
50
+ page === 1 && ((!(showFirstButton ?? false) && (hidePrevButton ?? false)) || mobile),
51
+ },
52
+ {
53
+ [styles['rounded-right']]:
54
+ page === count &&
55
+ ((!(showLastButton ?? false) && (hideNextButton ?? false)) || mobile),
56
+ },
57
+ 'pagination-number',
58
+ className
59
+ ),
60
+ 'data-testid':
61
+ cx({
62
+ 'pager-number-active': currentPage === page,
63
+ [`pager-number-${page}`]: currentPage !== page,
64
+ }).length > 0 || undefined,
65
+ disabled,
66
+ 'aria-current': currentPage === page,
67
+ 'aria-label': currentPage === page ? `Current Page, Page ${page}` : `Page ${page}`,
68
+ ...rest,
69
+ }
70
+
46
71
  return (
47
72
  <li className="flex">
48
- <Comp
49
- ref={ref}
50
- className={cx(
51
- styles['number-button'],
52
- [styles[variant]],
53
- { [styles.active]: active === true, active: active === true },
54
- {
55
- [styles['rounded-left']]:
56
- page === 1 && ((!(showFirstButton ?? false) && (hidePrevButton ?? false)) || mobile),
57
- },
58
- {
59
- [styles['rounded-right']]:
60
- page === count &&
61
- ((!(showLastButton ?? false) && (hideNextButton ?? false)) || mobile),
62
- },
63
- 'pagination-number',
64
- className
65
- )}
66
- data-testid={
67
- cx({
68
- 'pager-number-active': currentPage === page,
69
- [`pager-number-${page}`]: currentPage !== page,
70
- }).length > 0 || undefined
71
- }
72
- disabled={disabled}
73
- aria-current={currentPage === page}
74
- aria-label={currentPage === page ? `Current Page, Page ${page}` : `Page ${page}`}
75
- {...rest}
76
- >
77
- {(asChild ?? false) ? children : page}
78
- </Comp>
73
+ {render ? (
74
+ React.cloneElement(render, { ref, ...sharedProps } as React.Attributes & Record<string, unknown>, children)
75
+ ) : (
76
+ <button ref={ref as React.RefObject<HTMLButtonElement>} {...sharedProps}>
77
+ {children ?? page}
78
+ </button>
79
+ )}
79
80
  </li>
80
81
  )
81
82
  }
@@ -122,23 +122,16 @@ export function usePager(): PagerContextType {
122
122
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
123
123
  // First, Previous, Next, Last and Page number buttons
124
124
 
125
- // Define the ref type based on asChild prop
126
- export type RefType = React.Ref<HTMLButtonElement> | React.Ref<HTMLElement>
127
-
128
- // Your existing types...
129
- type AsButton = { asChild?: false } & React.ComponentRef<'button'>
130
-
131
- // Or AsSlot
132
- interface AsSlot {
133
- asChild?: true
134
- }
125
+ // Define the ref type
126
+ export type RefType = HTMLButtonElement | HTMLElement
135
127
 
136
128
  export type PagerButtonProps = {
137
129
  className?: string
138
130
  disabled?: boolean
139
131
  children?: React.ReactNode
132
+ render?: React.ReactElement
140
133
  onClick?: React.ReactEventHandler<Element> | undefined
141
- } & (AsButton | AsSlot)
134
+ }
142
135
 
143
136
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
144
137
  // Pager container component
@@ -1,11 +1,10 @@
1
1
  'use client'
2
2
 
3
- import type React from 'react'
3
+ import React from 'react'
4
4
 
5
- import { ChevronLeftIcon } from '@radix-ui/react-icons'
6
- import { Slot } from '@radix-ui/react-slot'
7
5
  import cx from 'classnames'
8
6
 
7
+ import { ChevronLeftIcon } from '../../icons/chevron-left-icon.js'
9
8
  import { usePager } from './pagination'
10
9
  import styles from './pagination.module.css'
11
10
  import type { PagerButtonProps, RefType } from './pagination'
@@ -14,37 +13,38 @@ export const PreviousButton = ({
14
13
  ref,
15
14
  className,
16
15
  disabled,
17
- asChild,
16
+ render,
18
17
  children,
19
18
  ...rest
20
19
  }: PagerButtonProps & {
21
20
  ref?: React.RefObject<RefType>
22
21
  }) => {
23
- const Comp = asChild != null ? Slot : ('button' as React.ElementType)
24
22
  const { showFirstButton, variant } = usePager()
25
23
 
26
- const aria = disabled ? { 'aria-disabled': true } : { 'aria-label': 'Previous' }
24
+ const sharedProps = {
25
+ className: cx(
26
+ styles['previous-button'],
27
+ styles[variant],
28
+ { [styles['rounded-left']]: showFirstButton == null || showFirstButton === false },
29
+ 'pagination-previous',
30
+ className
31
+ ),
32
+ disabled,
33
+ title: 'Previous',
34
+ 'data-testid': 'pagination-previous',
35
+ ...(disabled ? { 'aria-disabled': true } : { 'aria-label': 'Previous' }),
36
+ ...rest,
37
+ }
27
38
 
28
39
  return (
29
40
  <li className={styles['mobile-toggle']}>
30
- <Comp
31
- ref={ref}
32
- className={cx(
33
- styles['previous-button'],
34
- styles[variant],
35
-
36
- { [styles['rounded-left']]: showFirstButton == null || showFirstButton === false },
37
- 'pagination-previous',
38
- className
39
- )}
40
- disabled={disabled}
41
- title="Previous"
42
- data-testid="pagination-previous"
43
- {...aria}
44
- {...rest}
45
- >
46
- {(asChild ?? false) ? children : <ChevronLeftIcon />}
47
- </Comp>
41
+ {render ? (
42
+ React.cloneElement(render, { ref, ...sharedProps } as React.Attributes & Record<string, unknown>, children)
43
+ ) : (
44
+ <button ref={ref as React.RefObject<HTMLButtonElement>} {...sharedProps}>
45
+ {children ?? <ChevronLeftIcon width="18px" height="18px" />}
46
+ </button>
47
+ )}
48
48
  </li>
49
49
  )
50
50
  }
@@ -1,11 +1,11 @@
1
1
  import type React from 'react'
2
2
 
3
+ import { ScrollArea as ScrollAreaPrimitive } from '@base-ui/react/scroll-area'
3
4
  import cx from 'classnames'
4
- import { ScrollArea as ScrollAreaPrimitive } from 'radix-ui'
5
5
 
6
6
  import styles from './scroll-area.module.css'
7
7
 
8
- interface ScrollAreaProps extends React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.Root> {}
8
+ interface ScrollAreaProps extends React.ComponentProps<typeof ScrollAreaPrimitive.Root> { }
9
9
 
10
10
  export const ScrollArea = ({ children, style, className }: ScrollAreaProps) => (
11
11
  <ScrollAreaPrimitive.Root
@@ -13,7 +13,7 @@ export const ScrollArea = ({ children, style, className }: ScrollAreaProps) => (
13
13
  className={cx('infonomic-scroll-area', styles.root, className)}
14
14
  >
15
15
  <ScrollAreaPrimitive.Viewport className={cx('infonomic-scroll-area-viewport', styles.viewport)}>
16
- {children}
16
+ <ScrollAreaPrimitive.Content>{children}</ScrollAreaPrimitive.Content>
17
17
  </ScrollAreaPrimitive.Viewport>
18
18
  <ScrollAreaPrimitive.Scrollbar
19
19
  className={cx('infonomic-scroll-area-scrollbar', styles.scrollbar)}