@charcoal-ui/react 5.6.0-beta.0 → 5.6.0-beta.3

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@charcoal-ui/react",
3
- "version": "5.6.0-beta.0",
3
+ "version": "5.6.0-beta.3",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -54,10 +54,10 @@
54
54
  "react-compiler-runtime": "1.0.0",
55
55
  "react-stately": "^3.26.0",
56
56
  "warning": "^4.0.3",
57
- "@charcoal-ui/foundation": "5.6.0-beta.0",
58
- "@charcoal-ui/icons": "5.6.0-beta.0",
59
- "@charcoal-ui/theme": "5.6.0-beta.0",
60
- "@charcoal-ui/utils": "5.6.0-beta.0"
57
+ "@charcoal-ui/foundation": "5.6.0-beta.3",
58
+ "@charcoal-ui/theme": "5.6.0-beta.3",
59
+ "@charcoal-ui/icons": "5.6.0-beta.3",
60
+ "@charcoal-ui/utils": "5.6.0-beta.3"
61
61
  },
62
62
  "peerDependencies": {
63
63
  "react": ">=17.0.0"
@@ -1,13 +1,6 @@
1
1
  import './index.css'
2
2
 
3
- import React, {
4
- ReactNode,
5
- useState,
6
- useRef,
7
- useMemo,
8
- useCallback,
9
- forwardRef,
10
- } from 'react'
3
+ import React, { ReactNode, useState, useRef, useMemo, useCallback } from 'react'
11
4
  import Icon from '../Icon'
12
5
  import FieldLabel from '../FieldLabel'
13
6
  import { DropdownPopover } from './DropdownPopover'
@@ -40,124 +33,118 @@ export type DropdownSelectorProps = {
40
33
  className?: string
41
34
  } & Pick<PopoverProps, 'inertWorkaround'>
42
35
 
43
- const DropdownSelector = forwardRef<HTMLSelectElement, DropdownSelectorProps>(
44
- ({ onChange, showLabel = false, ...props }: DropdownSelectorProps, ref) => {
45
- const triggerRef = useRef<HTMLButtonElement>(null)
46
- const [isOpen, setIsOpen] = useState(false)
47
- const preview = findPreviewRecursive(props.children, props.value)
36
+ export default function DropdownSelector({
37
+ onChange,
38
+ showLabel = false,
39
+ ...props
40
+ }: DropdownSelectorProps) {
41
+ const triggerRef = useRef<HTMLButtonElement>(null)
42
+ const [isOpen, setIsOpen] = useState(false)
43
+ const preview = findPreviewRecursive(props.children, props.value)
48
44
 
49
- const isPlaceholder = useMemo(
50
- () => props.placeholder !== undefined && preview === undefined,
51
- [preview, props.placeholder],
52
- )
45
+ const isPlaceholder = useMemo(
46
+ () => props.placeholder !== undefined && preview === undefined,
47
+ [preview, props.placeholder],
48
+ )
53
49
 
54
- const propsArray = getValuesRecursive(props.children)
50
+ const propsArray = getValuesRecursive(props.children)
55
51
 
56
- const { visuallyHiddenProps } = useVisuallyHidden()
52
+ const { visuallyHiddenProps } = useVisuallyHidden()
57
53
 
58
- const handleChange = useCallback(
59
- (e: React.ChangeEvent<HTMLSelectElement>) => {
60
- onChange(e.target.value)
61
- },
62
- [onChange],
63
- )
54
+ const handleChange = useCallback(
55
+ (e: React.ChangeEvent<HTMLSelectElement>) => {
56
+ onChange(e.target.value)
57
+ },
58
+ [onChange],
59
+ )
64
60
 
65
- const labelId = useId()
66
- const describedbyId = useId()
61
+ const labelId = useId()
62
+ const describedbyId = useId()
67
63
 
68
- const classNames = useClassNames(
69
- 'charcoal-dropdown-selector-root',
70
- props.className,
71
- )
64
+ const classNames = useClassNames(
65
+ 'charcoal-dropdown-selector-root',
66
+ props.className,
67
+ )
72
68
 
73
- return (
74
- <div className={classNames} aria-disabled={props.disabled}>
75
- <FieldLabel
76
- id={labelId}
77
- label={props.label}
78
- required={props.required}
79
- requiredText={props.requiredText}
80
- subLabel={props.subLabel}
81
- {...(!showLabel ? visuallyHiddenProps : {})}
82
- />
83
- <div {...visuallyHiddenProps} aria-hidden="true">
84
- <select
85
- ref={ref}
86
- name={props.name}
87
- value={props.value}
88
- onChange={handleChange}
89
- tabIndex={-1}
90
- >
91
- {propsArray.map((itemProps) => {
92
- return (
93
- <option
94
- key={itemProps.value}
95
- value={itemProps.value}
96
- disabled={itemProps.disabled}
97
- >
98
- {itemProps.value}
99
- </option>
100
- )
101
- })}
102
- </select>
103
- </div>
104
- {/* eslint-disable-next-line jsx-a11y/role-supports-aria-props */}
105
- <button
106
- className="charcoal-dropdown-selector-button"
107
- aria-labelledby={labelId}
108
- aria-invalid={props.invalid}
109
- aria-describedby={
110
- props.assistiveText !== undefined ? describedbyId : undefined
111
- }
112
- disabled={props.disabled}
113
- onClick={() => {
114
- if (props.disabled === true) return
115
- setIsOpen(true)
116
- }}
117
- ref={triggerRef}
118
- type="button"
119
- data-active={isOpen}
69
+ return (
70
+ <div className={classNames} aria-disabled={props.disabled}>
71
+ <FieldLabel
72
+ id={labelId}
73
+ label={props.label}
74
+ required={props.required}
75
+ requiredText={props.requiredText}
76
+ subLabel={props.subLabel}
77
+ {...(!showLabel ? visuallyHiddenProps : {})}
78
+ />
79
+ <div {...visuallyHiddenProps} aria-hidden="true">
80
+ <select
81
+ name={props.name}
82
+ value={props.value}
83
+ onChange={handleChange}
84
+ tabIndex={-1}
120
85
  >
121
- <span
122
- className="charcoal-ui-dropdown-selector-text"
123
- data-placeholder={isPlaceholder}
124
- >
125
- {isPlaceholder ? props.placeholder : preview}
126
- </span>
127
- <Icon className="charcoal-ui-dropdown-selector-icon" name="16/Menu" />
128
- </button>
129
- {isOpen && (
130
- <DropdownPopover
131
- isOpen={isOpen}
132
- onClose={() => setIsOpen(false)}
133
- triggerRef={triggerRef}
86
+ {propsArray.map((itemProps) => {
87
+ return (
88
+ <option
89
+ key={itemProps.value}
90
+ value={itemProps.value}
91
+ disabled={itemProps.disabled}
92
+ >
93
+ {itemProps.value}
94
+ </option>
95
+ )
96
+ })}
97
+ </select>
98
+ </div>
99
+ {/* eslint-disable-next-line jsx-a11y/role-supports-aria-props */}
100
+ <button
101
+ className="charcoal-dropdown-selector-button"
102
+ aria-labelledby={labelId}
103
+ aria-invalid={props.invalid}
104
+ aria-describedby={
105
+ props.assistiveText !== undefined ? describedbyId : undefined
106
+ }
107
+ disabled={props.disabled}
108
+ onClick={() => {
109
+ if (props.disabled === true) return
110
+ setIsOpen(true)
111
+ }}
112
+ ref={triggerRef}
113
+ type="button"
114
+ data-active={isOpen}
115
+ >
116
+ <span
117
+ className="charcoal-ui-dropdown-selector-text"
118
+ data-placeholder={isPlaceholder}
119
+ >
120
+ {isPlaceholder ? props.placeholder : preview}
121
+ </span>
122
+ <Icon className="charcoal-ui-dropdown-selector-icon" name="16/Menu" />
123
+ </button>
124
+ {isOpen && (
125
+ <DropdownPopover
126
+ isOpen={isOpen}
127
+ onClose={() => setIsOpen(false)}
128
+ triggerRef={triggerRef}
129
+ value={props.value}
130
+ inertWorkaround={props.inertWorkaround}
131
+ >
132
+ <MenuList
134
133
  value={props.value}
135
- inertWorkaround={props.inertWorkaround}
136
- >
137
- <MenuList
138
- value={props.value}
139
- onChange={(v) => {
140
- onChange(v)
141
- setIsOpen(false)
142
- }}
143
- >
144
- {props.children}
145
- </MenuList>
146
- </DropdownPopover>
147
- )}
148
- {props.assistiveText !== undefined && (
149
- <AssistiveText
150
- data-invalid={props.invalid === true}
151
- id={describedbyId}
134
+ onChange={(v) => {
135
+ onChange(v)
136
+ setIsOpen(false)
137
+ }}
152
138
  >
153
- {props.assistiveText}
154
- </AssistiveText>
155
- )}
156
- </div>
157
- )
158
- },
159
- )
160
-
161
- DropdownSelector.displayName = 'DropdownSelector'
162
-
163
- export default DropdownSelector
139
+ {props.children}
140
+ </MenuList>
141
+ </DropdownPopover>
142
+ )}
143
+ {props.assistiveText !== undefined && (
144
+ <AssistiveText data-invalid={props.invalid === true} id={describedbyId}>
145
+ {props.assistiveText}
146
+ </AssistiveText>
147
+ )}
148
+ </div>
149
+ )
150
+ }
@@ -2,7 +2,7 @@ import './index.css'
2
2
 
3
3
  import { usePaginationWindow } from './helper'
4
4
  import { useClassNames } from '../../_lib/useClassNames'
5
- import IconButton from '../IconButton'
5
+ import IconButton, { IconButtonProps } from '../IconButton'
6
6
  import {
7
7
  PaginationContext,
8
8
  usePaginationContext,
@@ -14,9 +14,10 @@ import {
14
14
 
15
15
  type NavButtonProps = {
16
16
  direction: 'prev' | 'next'
17
+ ariaLabel: IconButtonProps['aria-label']
17
18
  }
18
19
 
19
- function NavButton({ direction }: NavButtonProps) {
20
+ function NavButton({ direction, ariaLabel }: NavButtonProps) {
20
21
  'use memo'
21
22
  const {
22
23
  page,
@@ -44,6 +45,7 @@ function NavButton({ direction }: NavButtonProps) {
44
45
  icon={isPrev ? '24/Prev' : '24/Next'}
45
46
  size={size}
46
47
  hidden={disabled}
48
+ aria-label={ariaLabel}
47
49
  {...(isLinkMode && makeUrl
48
50
  ? {
49
51
  component: LinkComponent as 'a',
@@ -122,11 +124,13 @@ function PageItem({ value }: { value: number | string }) {
122
124
  )
123
125
  }
124
126
 
125
- interface CommonProps {
127
+ interface PaginationCommonProps {
126
128
  page: number
127
129
  pageCount: number
128
130
  pageRangeDisplayed?: PageRangeDisplayed
129
131
  size?: Size
132
+ ariaLabelPrev?: string
133
+ ariaLabelNext?: string
130
134
  }
131
135
 
132
136
  type NavProps = Omit<React.ComponentPropsWithoutRef<'nav'>, 'onChange'>
@@ -150,29 +154,33 @@ type NavProps = Omit<React.ComponentPropsWithoutRef<'nav'>, 'onChange'>
150
154
  * // Link mode with linkProps (e.g. Next.js scroll)
151
155
  * <Pagination page={1} pageCount={10} makeUrl={(p) => `?page=${p}`} component={Link} linkProps={{ scroll: 'marker' }} />
152
156
  */
153
- export type PaginationProps<T extends React.ElementType = 'a'> = CommonProps &
154
- NavProps &
155
- (
156
- | {
157
- onChange(newPage: number): void
158
- makeUrl?: never
159
- component?: never
160
- linkProps?: undefined
161
- }
162
- | {
163
- makeUrl(page: number): string
164
- onChange?: never
165
- /**
166
- * The component used for link elements. Receives `href`, `className`, and `children`.
167
- * @default 'a'
168
- */
169
- component?: T
170
- /**
171
- * Additional props passed to all link elements (e.g. Next.js Link's scroll, prefetch).
172
- */
173
- linkProps?: Omit<React.ComponentPropsWithoutRef<T>, 'href' | 'children'>
174
- }
175
- )
157
+ export type PaginationProps<T extends React.ElementType = 'a'> =
158
+ PaginationCommonProps &
159
+ NavProps &
160
+ (
161
+ | {
162
+ onChange(newPage: number): void
163
+ makeUrl?: never
164
+ component?: never
165
+ linkProps?: undefined
166
+ }
167
+ | {
168
+ makeUrl(page: number): string
169
+ onChange?: never
170
+ /**
171
+ * The component used for link elements. Receives `href`, `className`, and `children`.
172
+ * @default 'a'
173
+ */
174
+ component?: T
175
+ /**
176
+ * Additional props passed to all link elements (e.g. Next.js Link's scroll, prefetch).
177
+ */
178
+ linkProps?: Omit<
179
+ React.ComponentPropsWithoutRef<T>,
180
+ 'href' | 'children'
181
+ >
182
+ }
183
+ )
176
184
 
177
185
  export default function Pagination<T extends React.ElementType = 'a'>({
178
186
  page,
@@ -184,6 +192,8 @@ export default function Pagination<T extends React.ElementType = 'a'>({
184
192
  component: LinkComponent = 'a' as T,
185
193
  linkProps,
186
194
  className,
195
+ ariaLabelNext = 'Next',
196
+ ariaLabelPrev = 'Previous',
187
197
  ...navProps
188
198
  }: PaginationProps<T>) {
189
199
  'use memo'
@@ -217,11 +227,11 @@ export default function Pagination<T extends React.ElementType = 'a'>({
217
227
  {...navProps}
218
228
  className={classNames}
219
229
  >
220
- <NavButton direction="prev" />
230
+ <NavButton direction="prev" ariaLabel={ariaLabelPrev} />
221
231
  {window.map((p) => (
222
232
  <PageItem key={p} value={p} />
223
233
  ))}
224
- <NavButton direction="next" />
234
+ <NavButton direction="next" ariaLabel={ariaLabelNext} />
225
235
  </nav>
226
236
  </PaginationContext.Provider>
227
237
  )