@rescui/chip-list 0.13.6 → 0.14.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.
- package/lib/chip-list-multi.d.ts +10 -1
- package/lib/chip-list-multi.js +9 -1
- package/lib/chip-list.d.ts +30 -3
- package/lib/chip-list.js +13 -0
- package/lib/index.css +65 -46
- package/lib/parts/chip-list-base.d.ts +9 -2
- package/lib/parts/chip-list-base.js +60 -4
- package/lib/parts/chip-list-context.js +2 -1
- package/lib/parts/chip-list.p.module.css.js +24 -23
- package/lib/parts/chip.d.ts +7 -5
- package/lib/parts/chip.js +91 -30
- package/lib/parts/types.d.ts +10 -0
- package/lib/parts/use-items-ids.d.ts +4 -0
- package/lib/parts/use-items-ids.js +64 -8
- package/lib/parts/use-roving-tab-index.d.ts +9 -0
- package/lib/parts/use-roving-tab-index.js +73 -0
- package/lib/parts/use-safe-id.d.ts +2 -0
- package/lib/parts/use-safe-id.js +15 -0
- package/package.json +3 -3
package/lib/chip-list-multi.d.ts
CHANGED
|
@@ -20,10 +20,16 @@ export declare type ChipListMultiProps<ValueType> = {
|
|
|
20
20
|
compareValues?: (activeValue: ValueType[], value: ValueType) => boolean;
|
|
21
21
|
/** Identifier for e2e tests */
|
|
22
22
|
'data-e2e'?: string;
|
|
23
|
+
/** Optional name of all `input[type="checkbox"]` children. */
|
|
24
|
+
name?: string;
|
|
25
|
+
/** Optional a11y label for the chip list. Recommended to use either that or `aria-labelledby`. */
|
|
26
|
+
'aria-label'?: string;
|
|
27
|
+
/** Optional a11y label reference for the chip list. Recommended to use either that or `aria-label`. */
|
|
28
|
+
'aria-labelledby'?: string;
|
|
23
29
|
/** CSS style object */
|
|
24
30
|
style?: React.CSSProperties;
|
|
25
31
|
};
|
|
26
|
-
export declare function ChipListMulti<ValueType>({ onChange, compareValues, value, children, size, sparse, compact, disabled, mode, alignItems, ...props }: ChipListMultiProps<ValueType>): JSX.Element;
|
|
32
|
+
export declare function ChipListMulti<ValueType>({ onChange, compareValues, value, children, size, sparse, compact, disabled, mode, alignItems, name, ...props }: ChipListMultiProps<ValueType>): JSX.Element;
|
|
27
33
|
export declare namespace ChipListMulti {
|
|
28
34
|
var displayName: string;
|
|
29
35
|
var propTypes: {
|
|
@@ -38,6 +44,9 @@ export declare namespace ChipListMulti {
|
|
|
38
44
|
value: PropTypes.Validator<any[]>;
|
|
39
45
|
onChange: PropTypes.Validator<(...args: any[]) => any>;
|
|
40
46
|
compareValues: PropTypes.Requireable<(...args: any[]) => any>;
|
|
47
|
+
name: PropTypes.Requireable<string>;
|
|
48
|
+
'aria-label': PropTypes.Requireable<string>;
|
|
49
|
+
'aria-labelledby': PropTypes.Requireable<string>;
|
|
41
50
|
'data-e2e': PropTypes.Requireable<string>;
|
|
42
51
|
style: PropTypes.Requireable<object>;
|
|
43
52
|
};
|
package/lib/chip-list-multi.js
CHANGED
|
@@ -3,6 +3,7 @@ import _includesInstanceProperty from "@babel/runtime-corejs3/core-js-stable/ins
|
|
|
3
3
|
import React from 'react';
|
|
4
4
|
import PropTypes from 'prop-types';
|
|
5
5
|
import { ChipListBase } from './parts/chip-list-base.js';
|
|
6
|
+
import { useSafeId } from './parts/use-safe-id.js';
|
|
6
7
|
|
|
7
8
|
const compareValuesDefault = (activeValues, value) => Array.isArray(activeValues) && _includesInstanceProperty(activeValues).call(activeValues, value);
|
|
8
9
|
|
|
@@ -18,8 +19,10 @@ function ChipListMulti(_ref) {
|
|
|
18
19
|
disabled = false,
|
|
19
20
|
mode = 'classic',
|
|
20
21
|
alignItems = 'left',
|
|
22
|
+
name,
|
|
21
23
|
...props
|
|
22
24
|
} = _ref;
|
|
25
|
+
const uniqueId = useSafeId();
|
|
23
26
|
return /*#__PURE__*/React.createElement(ChipListBase, {
|
|
24
27
|
compareValues: compareValues,
|
|
25
28
|
value: value,
|
|
@@ -33,7 +36,9 @@ function ChipListMulti(_ref) {
|
|
|
33
36
|
disabled: disabled,
|
|
34
37
|
mode: mode,
|
|
35
38
|
alignItems: alignItems,
|
|
36
|
-
...props
|
|
39
|
+
...props,
|
|
40
|
+
pattern: "group",
|
|
41
|
+
name: name ?? `rs-chip-list-multi-${uniqueId}`
|
|
37
42
|
}, children);
|
|
38
43
|
}
|
|
39
44
|
|
|
@@ -50,6 +55,9 @@ ChipListMulti.propTypes = {
|
|
|
50
55
|
value: PropTypes.array.isRequired,
|
|
51
56
|
onChange: PropTypes.func.isRequired,
|
|
52
57
|
compareValues: PropTypes.func,
|
|
58
|
+
name: PropTypes.string,
|
|
59
|
+
'aria-label': PropTypes.string,
|
|
60
|
+
'aria-labelledby': PropTypes.string,
|
|
53
61
|
'data-e2e': PropTypes.string,
|
|
54
62
|
style: PropTypes.object
|
|
55
63
|
};
|
package/lib/chip-list.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
2
3
|
import { Theme } from '@rescui/ui-contexts';
|
|
3
|
-
import { ChipListSizeType, ChipListModeType, ChipListAlignItemsType } from './parts/types';
|
|
4
|
+
import { ChipListSizeType, ChipListModeType, ChipListAlignItemsType, ChipListPatternType } from './parts/types';
|
|
4
5
|
export declare const compareValuesDefault: <V>(activeValue: V, value: V) => boolean;
|
|
5
6
|
export declare type ChipListProps<ValueType> = {
|
|
6
7
|
className?: string;
|
|
@@ -13,17 +14,43 @@ export declare type ChipListProps<ValueType> = {
|
|
|
13
14
|
theme?: Theme;
|
|
14
15
|
mode?: ChipListModeType;
|
|
15
16
|
alignItems?: ChipListAlignItemsType;
|
|
17
|
+
/** Behavior pattern. `auto` renders chips with `aria-controls` as `tablist`, links as `navigation`, and chips without links as `radiogroup`. */
|
|
18
|
+
pattern?: ChipListPatternType;
|
|
16
19
|
value: ValueType;
|
|
17
20
|
onChange: (value: ValueType) => void;
|
|
18
21
|
children: React.ReactNode;
|
|
19
22
|
compareValues?: (activeValue: ValueType, value: ValueType) => boolean;
|
|
23
|
+
/** Optional name of all `input[type="radio"]` children. */
|
|
24
|
+
name?: string;
|
|
25
|
+
/** Optional a11y label for the chip list. Recommended to use either that or `aria-labelledby`. */
|
|
26
|
+
'aria-label'?: string;
|
|
27
|
+
/** Optional a11y label reference for the chip list. Recommended to use either that or `aria-label`. */
|
|
28
|
+
'aria-labelledby'?: string;
|
|
20
29
|
/** Identifier for e2e tests */
|
|
21
30
|
'data-e2e'?: string;
|
|
22
31
|
/** CSS style object */
|
|
23
32
|
style?: React.CSSProperties;
|
|
24
33
|
};
|
|
25
|
-
export declare function ChipList<ValueType>({ children, compareValues, value, onChange, size, sparse, compact, disabled, mode, alignItems, ...props }: ChipListProps<ValueType>): JSX.Element;
|
|
34
|
+
export declare function ChipList<ValueType>({ children, compareValues, value, onChange, size, sparse, compact, disabled, mode, alignItems, pattern, name, ...props }: ChipListProps<ValueType>): JSX.Element;
|
|
26
35
|
export declare namespace ChipList {
|
|
27
36
|
var displayName: string;
|
|
28
|
-
var propTypes: {
|
|
37
|
+
var propTypes: {
|
|
38
|
+
size: PropTypes.Requireable<string>;
|
|
39
|
+
sparse: PropTypes.Requireable<boolean>;
|
|
40
|
+
compact: PropTypes.Requireable<boolean>;
|
|
41
|
+
disabled: PropTypes.Requireable<boolean>;
|
|
42
|
+
theme: PropTypes.Requireable<string>;
|
|
43
|
+
className: PropTypes.Requireable<string>;
|
|
44
|
+
mode: PropTypes.Requireable<string>;
|
|
45
|
+
alignItems: PropTypes.Requireable<string>;
|
|
46
|
+
pattern: PropTypes.Requireable<string>;
|
|
47
|
+
value: PropTypes.Validator<any>;
|
|
48
|
+
onChange: PropTypes.Validator<(...args: any[]) => any>;
|
|
49
|
+
compareValues: PropTypes.Requireable<(...args: any[]) => any>;
|
|
50
|
+
name: PropTypes.Requireable<string>;
|
|
51
|
+
'aria-label': PropTypes.Requireable<string>;
|
|
52
|
+
'aria-labelledby': PropTypes.Requireable<string>;
|
|
53
|
+
'data-e2e': PropTypes.Requireable<string>;
|
|
54
|
+
style: PropTypes.Requireable<object>;
|
|
55
|
+
};
|
|
29
56
|
}
|
package/lib/chip-list.js
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
"use client";
|
|
2
|
+
import _includesInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/includes";
|
|
2
3
|
import React from 'react';
|
|
3
4
|
import PropTypes from 'prop-types';
|
|
4
5
|
import { ChipListBase } from './parts/chip-list-base.js';
|
|
6
|
+
import { useSafeId } from './parts/use-safe-id.js';
|
|
5
7
|
|
|
6
8
|
const compareValuesDefault = (activeValue, value) => activeValue === value;
|
|
7
9
|
|
|
8
10
|
function ChipList(_ref) {
|
|
11
|
+
var _context;
|
|
12
|
+
|
|
9
13
|
let {
|
|
10
14
|
children,
|
|
11
15
|
compareValues = compareValuesDefault,
|
|
@@ -17,8 +21,11 @@ function ChipList(_ref) {
|
|
|
17
21
|
disabled = false,
|
|
18
22
|
mode = 'classic',
|
|
19
23
|
alignItems = 'left',
|
|
24
|
+
pattern = 'auto',
|
|
25
|
+
name,
|
|
20
26
|
...props
|
|
21
27
|
} = _ref;
|
|
28
|
+
const uniqueId = useSafeId();
|
|
22
29
|
return /*#__PURE__*/React.createElement(ChipListBase, {
|
|
23
30
|
compareValues: (activeValues, compareVal) => compareValues(activeValues[0], compareVal),
|
|
24
31
|
onChange: onChange,
|
|
@@ -29,6 +36,8 @@ function ChipList(_ref) {
|
|
|
29
36
|
disabled: disabled,
|
|
30
37
|
mode: mode,
|
|
31
38
|
alignItems: alignItems,
|
|
39
|
+
pattern: _includesInstanceProperty(_context = ['auto', 'radiogroup', 'navigation', 'tablist']).call(_context, pattern) ? pattern : 'auto',
|
|
40
|
+
name: name ?? `rs-chip-list-${uniqueId}`,
|
|
32
41
|
...props
|
|
33
42
|
}, children);
|
|
34
43
|
}
|
|
@@ -43,9 +52,13 @@ ChipList.propTypes = {
|
|
|
43
52
|
className: PropTypes.string,
|
|
44
53
|
mode: PropTypes.oneOf(['classic', 'rock']),
|
|
45
54
|
alignItems: PropTypes.oneOf(['left', 'center', 'right']),
|
|
55
|
+
pattern: PropTypes.oneOf(['auto', 'radiogroup', 'navigation', 'tablist']),
|
|
46
56
|
value: PropTypes.any.isRequired,
|
|
47
57
|
onChange: PropTypes.func.isRequired,
|
|
48
58
|
compareValues: PropTypes.func,
|
|
59
|
+
name: PropTypes.string,
|
|
60
|
+
'aria-label': PropTypes.string,
|
|
61
|
+
'aria-labelledby': PropTypes.string,
|
|
49
62
|
'data-e2e': PropTypes.string,
|
|
50
63
|
style: PropTypes.object
|
|
51
64
|
};
|
package/lib/index.css
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
.
|
|
1
|
+
._light_13vk6i6_8{
|
|
2
2
|
--rs-theme-dark:0;
|
|
3
3
|
}
|
|
4
|
-
.
|
|
4
|
+
._dark_13vk6i6_11{
|
|
5
5
|
--rs-theme-dark:1;
|
|
6
6
|
}
|
|
7
|
-
.
|
|
7
|
+
._alignLeft_13vk6i6_15{
|
|
8
8
|
--_rs-cl-align:left;
|
|
9
9
|
}
|
|
10
|
-
.
|
|
10
|
+
._alignCenter_13vk6i6_18{
|
|
11
11
|
--_rs-cl-align:center;
|
|
12
12
|
}
|
|
13
|
-
.
|
|
13
|
+
._alignRight_13vk6i6_21{
|
|
14
14
|
--_rs-cl-align:right;
|
|
15
15
|
}
|
|
16
|
-
.
|
|
16
|
+
._sizeXs_13vk6i6_25{
|
|
17
17
|
--_rs-cl-chip-base-border-radius:4px;
|
|
18
18
|
--_rs-cl-chip-compact-border-radius:var(--_rs-cl-chip-base-border-radius);
|
|
19
19
|
--_rs-cl-chip-vertical-padding:2px;
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
--_rs-cl-compact-horizontal-gap:4px;
|
|
28
28
|
--_rs-cl-sparse-horizontal-gap:12px;
|
|
29
29
|
}
|
|
30
|
-
.
|
|
30
|
+
._sizeXs_13vk6i6_25 [data-rs-internal='chip-list__chip']{
|
|
31
31
|
--_rs-typography-letter-spacing:var(--rs-text-3-letter-spacing, 0.0045em);
|
|
32
32
|
--_rs-typography-text-transform:initial;
|
|
33
33
|
--_rs-typography-font-variant-numeric:initial;
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
--_rs-typography-link-external-standalone-border-offset-from-text-base:1.02em;
|
|
63
63
|
--_rs-typography-link-border-bottom-width-from-text:1px;
|
|
64
64
|
}
|
|
65
|
-
.
|
|
65
|
+
._sizeS_13vk6i6_28{
|
|
66
66
|
--_rs-cl-chip-base-border-radius:16px;
|
|
67
67
|
--_rs-cl-chip-compact-border-radius:4px;
|
|
68
68
|
--_rs-cl-chip-vertical-padding:6px;
|
|
@@ -76,7 +76,7 @@
|
|
|
76
76
|
--_rs-cl-compact-horizontal-gap:6px;
|
|
77
77
|
--_rs-cl-sparse-horizontal-gap:12px;
|
|
78
78
|
}
|
|
79
|
-
.
|
|
79
|
+
._sizeS_13vk6i6_28 [data-rs-internal='chip-list__chip']{
|
|
80
80
|
--_rs-typography-letter-spacing:var(--rs-text-3-letter-spacing, 0.0045em);
|
|
81
81
|
--_rs-typography-text-transform:initial;
|
|
82
82
|
--_rs-typography-font-variant-numeric:initial;
|
|
@@ -111,7 +111,7 @@
|
|
|
111
111
|
--_rs-typography-link-external-standalone-border-offset-from-text-base:1.02em;
|
|
112
112
|
--_rs-typography-link-border-bottom-width-from-text:1px;
|
|
113
113
|
}
|
|
114
|
-
.
|
|
114
|
+
._sizeM_13vk6i6_31{
|
|
115
115
|
--_rs-cl-chip-base-border-radius:20px;
|
|
116
116
|
--_rs-cl-chip-compact-border-radius:8px;
|
|
117
117
|
--_rs-cl-chip-vertical-padding:8px;
|
|
@@ -125,7 +125,7 @@
|
|
|
125
125
|
--_rs-cl-compact-horizontal-gap:6px;
|
|
126
126
|
--_rs-cl-sparse-horizontal-gap:16px;
|
|
127
127
|
}
|
|
128
|
-
.
|
|
128
|
+
._sizeM_13vk6i6_31 [data-rs-internal='chip-list__chip']{
|
|
129
129
|
--_rs-typography-letter-spacing:var(--rs-text-2-letter-spacing, 0.0015em);
|
|
130
130
|
--_rs-typography-text-transform:initial;
|
|
131
131
|
--_rs-typography-font-variant-numeric:initial;
|
|
@@ -164,11 +164,11 @@
|
|
|
164
164
|
--_rs-typography-link-border-bottom-width-from-text:1px;
|
|
165
165
|
}
|
|
166
166
|
@media screen and (max-width: 640px){
|
|
167
|
-
.
|
|
167
|
+
._sizeM_13vk6i6_31 [data-rs-internal='chip-list__chip']{
|
|
168
168
|
--_rs-typography-text-2-sm-list-li-margin-top-from-text:12px;
|
|
169
169
|
}
|
|
170
170
|
}
|
|
171
|
-
.
|
|
171
|
+
._sizeL_13vk6i6_34{
|
|
172
172
|
--_rs-cl-chip-base-border-radius:26px;
|
|
173
173
|
--_rs-cl-chip-compact-border-radius:12px;
|
|
174
174
|
--_rs-cl-chip-vertical-padding:12px;
|
|
@@ -183,11 +183,11 @@
|
|
|
183
183
|
--_rs-cl-sparse-horizontal-gap:16px;
|
|
184
184
|
}
|
|
185
185
|
@media screen and (max-width: 640px){
|
|
186
|
-
.
|
|
186
|
+
._sizeL_13vk6i6_34{
|
|
187
187
|
--_rs-cl-vertical-gap:12px;
|
|
188
188
|
}
|
|
189
189
|
}
|
|
190
|
-
.
|
|
190
|
+
._sizeL_13vk6i6_34 [data-rs-internal='chip-list__chip']{
|
|
191
191
|
--_rs-typography-letter-spacing:var(--rs-text-1-letter-spacing, normal);
|
|
192
192
|
--_rs-typography-text-transform:initial;
|
|
193
193
|
--_rs-typography-font-variant-numeric:initial;
|
|
@@ -226,34 +226,34 @@
|
|
|
226
226
|
--_rs-typography-link-border-bottom-width-from-text:1px;
|
|
227
227
|
}
|
|
228
228
|
@media screen and (max-width: 640px){
|
|
229
|
-
.
|
|
229
|
+
._sizeL_13vk6i6_34 [data-rs-internal='chip-list__chip']{
|
|
230
230
|
--_rs-typography-text-1-sm-list-li-margin-top-from-text:16px;
|
|
231
231
|
}
|
|
232
232
|
}
|
|
233
|
-
.
|
|
233
|
+
._innerOffsetL_13vk6i6_38{
|
|
234
234
|
--_rs-cl-horizontal-gap-from-sparse:var(--_rs-cl-sparse-horizontal-gap);
|
|
235
235
|
}
|
|
236
236
|
@media screen and (max-width: 640px){
|
|
237
|
-
.
|
|
237
|
+
._innerOffsetL_13vk6i6_38{
|
|
238
238
|
--_rs-cl-horizontal-gap-from-sparse:var(--_rs-cl-base-horizontal-gap);
|
|
239
239
|
}
|
|
240
240
|
}
|
|
241
|
-
.
|
|
241
|
+
._innerOffsetM_13vk6i6_41{
|
|
242
242
|
--_rs-cl-horizontal-gap-from-sparse:initial;
|
|
243
243
|
}
|
|
244
|
-
.
|
|
244
|
+
._classic_13vk6i6_45{
|
|
245
245
|
--_rs-cl-chip-active-border-color:var(--_rs-color-primary);
|
|
246
246
|
--_rs-cl-chip-selected-border-color:var(--_rs-color-primary);
|
|
247
247
|
--_rs-cl-chip-hover-background:var(--_rs-color-primary-t-fog);
|
|
248
248
|
--_rs-cl-chip-active-background:var(--_rs-color-primary-t-fog);
|
|
249
249
|
}
|
|
250
|
-
.
|
|
250
|
+
._rock_13vk6i6_48{
|
|
251
251
|
--_rs-cl-chip-active-border-color:rgba(calc(25 + var(--_rs-theme-dark-coefficient, 0)*230), calc(25 + var(--_rs-theme-dark-coefficient, 0)*230), calc(28 + var(--_rs-theme-dark-coefficient, 0)*227));
|
|
252
252
|
--_rs-cl-chip-selected-border-color:rgba(calc(25 + var(--_rs-theme-dark-coefficient, 0)*230), calc(25 + var(--_rs-theme-dark-coefficient, 0)*230), calc(28 + var(--_rs-theme-dark-coefficient, 0)*227));
|
|
253
253
|
--_rs-cl-chip-hover-background:rgba(calc(25 + var(--_rs-theme-dark-coefficient, 0)*230), calc(25 + var(--_rs-theme-dark-coefficient, 0)*230), calc(28 + var(--_rs-theme-dark-coefficient, 0)*227), 0.1);
|
|
254
254
|
--_rs-cl-chip-active-background:rgba(calc(25 + var(--_rs-theme-dark-coefficient, 0)*230), calc(25 + var(--_rs-theme-dark-coefficient, 0)*230), calc(28 + var(--_rs-theme-dark-coefficient, 0)*227), 0.1);
|
|
255
255
|
}
|
|
256
|
-
.
|
|
256
|
+
._compact_13vk6i6_52{
|
|
257
257
|
--_rs-cl-chip-border-radius-from-compact:var(
|
|
258
258
|
--_rs-cl-chip-compact-border-radius
|
|
259
259
|
);
|
|
@@ -262,7 +262,7 @@
|
|
|
262
262
|
);
|
|
263
263
|
--_rs-cl-horizontal-gap-from-compact:var(--_rs-cl-compact-horizontal-gap);
|
|
264
264
|
}
|
|
265
|
-
.
|
|
265
|
+
._main_13vk6i6_56{
|
|
266
266
|
--_rs-theme-dark:var(
|
|
267
267
|
--_rs-internal-force-theme-dark-consult-rescui-before-using,
|
|
268
268
|
var(--rs-theme-dark, 0)
|
|
@@ -272,7 +272,7 @@
|
|
|
272
272
|
--_rs-theme-light-coefficient:calc(1 - var(--_rs-theme-dark-coefficient));
|
|
273
273
|
}
|
|
274
274
|
@supports (color: color-mix(in srgb, #fff 50%, #000 50%)){
|
|
275
|
-
.
|
|
275
|
+
._main_13vk6i6_56{
|
|
276
276
|
--_rs-color-primary:color-mix(in srgb, var(--rs-color-primary-light-theme, #6B57FF) calc(100%*var(--_rs-theme-light-coefficient, 1)), var(--rs-color-primary-dark-theme, #8473FF) calc(100%*var(--_rs-theme-dark-coefficient, 0)));
|
|
277
277
|
--_rs-color-primary-dim:color-mix(in srgb, var(--rs-color-primary-dim-light-theme, #8979ff) calc(100%*var(--_rs-theme-light-coefficient, 1)), var(--rs-color-primary-dim-dark-theme, #6f61d2) calc(100%*var(--_rs-theme-dark-coefficient, 0)));
|
|
278
278
|
--_rs-color-primary-fog:color-mix(in srgb, var(--rs-color-primary-fog-light-theme, #e1ddff) calc(100%*var(--_rs-theme-light-coefficient, 1)), var(--rs-color-primary-fog-dark-theme, #2e2b49) calc(100%*var(--_rs-theme-dark-coefficient, 0)));
|
|
@@ -281,7 +281,7 @@
|
|
|
281
281
|
}
|
|
282
282
|
}
|
|
283
283
|
@supports not (color: color-mix(in srgb, #fff 50%, #000 50%)){
|
|
284
|
-
.
|
|
284
|
+
._main_13vk6i6_56{
|
|
285
285
|
--_rs-color-primary:rgb(calc(var(--_rs-theme-light-coefficient, 1)*107 + var(--_rs-theme-dark-coefficient, 0)*132), calc(var(--_rs-theme-light-coefficient, 1)*87 + var(--_rs-theme-dark-coefficient, 0)*115), 255);
|
|
286
286
|
--_rs-color-primary-dim:rgb(calc(var(--_rs-theme-light-coefficient, 1)*137 + var(--_rs-theme-dark-coefficient, 0)*111), calc(var(--_rs-theme-light-coefficient, 1)*121 + var(--_rs-theme-dark-coefficient, 0)*97), calc(var(--_rs-theme-light-coefficient, 1)*255 + var(--_rs-theme-dark-coefficient, 0)*210));
|
|
287
287
|
--_rs-color-primary-fog:rgb(calc(var(--_rs-theme-light-coefficient, 1)*225 + var(--_rs-theme-dark-coefficient, 0)*46), calc(var(--_rs-theme-light-coefficient, 1)*221 + var(--_rs-theme-dark-coefficient, 0)*43), calc(var(--_rs-theme-light-coefficient, 1)*255 + var(--_rs-theme-dark-coefficient, 0)*73));
|
|
@@ -289,7 +289,7 @@
|
|
|
289
289
|
--_rs-color-primary-t-fog:rgba(calc(var(--_rs-theme-light-coefficient, 1)*107 + var(--_rs-theme-dark-coefficient, 0)*132), calc(var(--_rs-theme-light-coefficient, 1)*87 + var(--_rs-theme-dark-coefficient, 0)*115), 255, calc(var(--_rs-theme-light-coefficient, 1)*0.2 + var(--_rs-theme-dark-coefficient, 0)*0.3));
|
|
290
290
|
}
|
|
291
291
|
}
|
|
292
|
-
.
|
|
292
|
+
._main_13vk6i6_56 {
|
|
293
293
|
--_rs-cl-chip-border-radius:var(
|
|
294
294
|
--_rs-cl-chip-border-radius-from-compact,
|
|
295
295
|
var(--_rs-cl-chip-base-border-radius)
|
|
@@ -303,7 +303,7 @@
|
|
|
303
303
|
var(--_rs-cl-horizontal-gap-from-sparse, var(--_rs-cl-base-horizontal-gap))
|
|
304
304
|
);
|
|
305
305
|
}
|
|
306
|
-
.
|
|
306
|
+
._chipsContainer_13vk6i6_62{
|
|
307
307
|
position:relative;
|
|
308
308
|
|
|
309
309
|
display:flex;
|
|
@@ -312,17 +312,17 @@
|
|
|
312
312
|
|
|
313
313
|
gap:var(--_rs-cl-vertical-gap) var(--_rs-cl-horizontal-gap);
|
|
314
314
|
}
|
|
315
|
-
.
|
|
315
|
+
._alignIconLeft_13vk6i6_72{
|
|
316
316
|
--_rs-cl-chip-icon-flex-direction:row;
|
|
317
317
|
--_rs-cl-chip-icon-position-multiplier-left:1;
|
|
318
318
|
--_rs-cl-chip-icon-position-multiplier-right:0;
|
|
319
319
|
}
|
|
320
|
-
.
|
|
320
|
+
._alignIconRight_13vk6i6_75{
|
|
321
321
|
--_rs-cl-chip-icon-flex-direction:row-reverse;
|
|
322
322
|
--_rs-cl-chip-icon-position-multiplier-left:0;
|
|
323
323
|
--_rs-cl-chip-icon-position-multiplier-right:1;
|
|
324
324
|
}
|
|
325
|
-
.
|
|
325
|
+
._chip_13vk6i6_62{
|
|
326
326
|
letter-spacing:var(
|
|
327
327
|
--rs-text-base-letter-spacing,
|
|
328
328
|
var(--_rs-typography-letter-spacing)
|
|
@@ -369,27 +369,30 @@
|
|
|
369
369
|
background:transparent;
|
|
370
370
|
box-shadow:none;
|
|
371
371
|
|
|
372
|
-
transition:color 100ms, background-color 100ms;
|
|
372
|
+
transition:color 100ms var(--rs-transition-function, ease), background-color 100ms var(--rs-transition-function, ease);
|
|
373
373
|
-webkit-font-smoothing:inherit;
|
|
374
374
|
-moz-osx-font-smoothing:inherit;
|
|
375
375
|
-webkit-appearance:none;
|
|
376
376
|
}
|
|
377
|
-
.
|
|
377
|
+
._chip_13vk6i6_62::-moz-focus-inner{
|
|
378
378
|
padding:0;
|
|
379
379
|
|
|
380
380
|
border:none;
|
|
381
381
|
}
|
|
382
|
-
.
|
|
383
|
-
.
|
|
384
|
-
.
|
|
382
|
+
._chip_13vk6i6_62:hover,
|
|
383
|
+
._chip_13vk6i6_62:focus,
|
|
384
|
+
._chip_13vk6i6_62:active{
|
|
385
385
|
outline:none;
|
|
386
386
|
|
|
387
387
|
text-decoration:none;
|
|
388
388
|
}
|
|
389
|
-
.
|
|
389
|
+
._chip_13vk6i6_62:focus[data-focus-method='key']{
|
|
390
390
|
box-shadow:var(--_rs-color-primary-t-dim) 0 0 0 4px;
|
|
391
391
|
}
|
|
392
|
-
.
|
|
392
|
+
._chip_13vk6i6_62:has(:focus[data-focus-method='key']){
|
|
393
|
+
box-shadow:var(--_rs-color-primary-t-dim) 0 0 0 4px;
|
|
394
|
+
}
|
|
395
|
+
._chip_13vk6i6_62:focus{
|
|
393
396
|
--_rs-cl-chip-border-color:rgba(
|
|
394
397
|
calc(25 + var(--_rs-theme-dark-coefficient, 0)*230), calc(25 + var(--_rs-theme-dark-coefficient, 0)*230), calc(28 + var(--_rs-theme-dark-coefficient, 0)*227),
|
|
395
398
|
calc(0.3 + var(--_rs-theme-dark-coefficient)*0.1)
|
|
@@ -398,7 +401,7 @@
|
|
|
398
401
|
color:rgba(calc(25 + var(--_rs-theme-dark-coefficient, 0)*230), calc(25 + var(--_rs-theme-dark-coefficient, 0)*230), calc(28 + var(--_rs-theme-dark-coefficient, 0)*227));
|
|
399
402
|
}
|
|
400
403
|
@media (hover: hover){
|
|
401
|
-
.
|
|
404
|
+
._chip_13vk6i6_62:hover{
|
|
402
405
|
--_rs-cl-chip-border-color:rgba(
|
|
403
406
|
calc(25 + var(--_rs-theme-dark-coefficient, 0)*230), calc(25 + var(--_rs-theme-dark-coefficient, 0)*230), calc(28 + var(--_rs-theme-dark-coefficient, 0)*227),
|
|
404
407
|
calc(0.3 + var(--_rs-theme-dark-coefficient)*0.1)
|
|
@@ -409,20 +412,20 @@
|
|
|
409
412
|
background:var(--_rs-cl-chip-hover-background);
|
|
410
413
|
}
|
|
411
414
|
}
|
|
412
|
-
.
|
|
415
|
+
._chip_13vk6i6_62:active{
|
|
413
416
|
--_rs-cl-chip-border-color:var(--_rs-cl-chip-active-border-color);
|
|
414
417
|
|
|
415
418
|
color:rgba(calc(25 + var(--_rs-theme-dark-coefficient, 0)*230), calc(25 + var(--_rs-theme-dark-coefficient, 0)*230), calc(28 + var(--_rs-theme-dark-coefficient, 0)*227));
|
|
416
419
|
|
|
417
420
|
background:var(--_rs-cl-chip-active-background);
|
|
418
421
|
}
|
|
419
|
-
.
|
|
422
|
+
._chip_13vk6i6_62._selected_13vk6i6_176{
|
|
420
423
|
--_rs-cl-chip-border-color:var(--_rs-cl-chip-selected-border-color);
|
|
421
424
|
--_rs-cl-chip-border-width:2px;
|
|
422
425
|
|
|
423
426
|
color:rgba(calc(25 + var(--_rs-theme-dark-coefficient, 0)*230), calc(25 + var(--_rs-theme-dark-coefficient, 0)*230), calc(28 + var(--_rs-theme-dark-coefficient, 0)*227));
|
|
424
427
|
}
|
|
425
|
-
.
|
|
428
|
+
._disabled_13vk6i6_183 ._chip_13vk6i6_62{
|
|
426
429
|
--_rs-cl-chip-border-color:rgba(calc(25 + var(--_rs-theme-dark-coefficient, 0)*230), calc(25 + var(--_rs-theme-dark-coefficient, 0)*230), calc(28 + var(--_rs-theme-dark-coefficient, 0)*227), 0.2);
|
|
427
430
|
|
|
428
431
|
pointer-events:none;
|
|
@@ -431,10 +434,10 @@
|
|
|
431
434
|
|
|
432
435
|
background:transparent;
|
|
433
436
|
}
|
|
434
|
-
.
|
|
437
|
+
._disabled_13vk6i6_183 ._chip_13vk6i6_62._selected_13vk6i6_176{
|
|
435
438
|
--_rs-cl-chip-border-color:rgba(calc(25 + var(--_rs-theme-dark-coefficient, 0)*230), calc(25 + var(--_rs-theme-dark-coefficient, 0)*230), calc(28 + var(--_rs-theme-dark-coefficient, 0)*227), 0.4);
|
|
436
439
|
}
|
|
437
|
-
.
|
|
440
|
+
._chip_13vk6i6_62::before{
|
|
438
441
|
position:absolute;
|
|
439
442
|
top:0;
|
|
440
443
|
right:0;
|
|
@@ -449,9 +452,9 @@
|
|
|
449
452
|
content:'';
|
|
450
453
|
pointer-events:none;
|
|
451
454
|
|
|
452
|
-
transition:border-color 100ms;
|
|
455
|
+
transition:border-color 100ms var(--rs-transition-function, ease);
|
|
453
456
|
}
|
|
454
|
-
.
|
|
457
|
+
._chip_13vk6i6_62 ._icon_13vk6i6_216{
|
|
455
458
|
flex:0 0 auto;
|
|
456
459
|
|
|
457
460
|
width:auto;
|
|
@@ -460,7 +463,23 @@
|
|
|
460
463
|
margin:0;
|
|
461
464
|
fill:currentColor;
|
|
462
465
|
}
|
|
463
|
-
.
|
|
466
|
+
._hiddenInput_13vk6i6_227{
|
|
467
|
+
position:absolute;
|
|
468
|
+
|
|
469
|
+
overflow:hidden;
|
|
470
|
+
clip:rect(0 0 0 0);
|
|
471
|
+
|
|
472
|
+
width:1px;
|
|
473
|
+
height:1px;
|
|
474
|
+
margin:-1px;
|
|
475
|
+
padding:0;
|
|
476
|
+
|
|
477
|
+
border:none;
|
|
478
|
+
|
|
479
|
+
white-space:nowrap;
|
|
480
|
+
clip-path:inset(50%);
|
|
481
|
+
}
|
|
482
|
+
._withoutText_13vk6i6_244{
|
|
464
483
|
--_rs-cl-chip-horizontal-real-padding:var(--_rs-cl-chip-icon-only-padding);
|
|
465
484
|
--_rs-cl-chip-vertical-real-padding:var(--_rs-cl-chip-icon-only-padding);
|
|
466
485
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { Theme } from '@rescui/ui-contexts';
|
|
3
|
-
import { ChipListSizeType, ChipListModeType, ChipListAlignItemsType } from './types';
|
|
3
|
+
import { ChipListSizeType, ChipListModeType, ChipListAlignItemsType, ChipListBasePatternType } from './types';
|
|
4
4
|
export declare type ChipListBaseProps<V> = {
|
|
5
5
|
className?: string;
|
|
6
6
|
size?: ChipListSizeType;
|
|
@@ -12,13 +12,20 @@ export declare type ChipListBaseProps<V> = {
|
|
|
12
12
|
theme?: Theme;
|
|
13
13
|
mode?: ChipListModeType;
|
|
14
14
|
alignItems?: ChipListAlignItemsType;
|
|
15
|
+
pattern?: ChipListBasePatternType;
|
|
15
16
|
value: V[];
|
|
16
17
|
onChange: (value: V) => void;
|
|
17
18
|
children: React.ReactNode;
|
|
18
19
|
compareValues?: (activeValue: V[], value: V) => boolean;
|
|
20
|
+
/** Optional name of all `input[type="radio"]` children. */
|
|
21
|
+
name?: string;
|
|
22
|
+
/** Optional a11y label for the chip list. Recommended to use either that or `aria-labelledby`. */
|
|
23
|
+
'aria-label'?: string;
|
|
24
|
+
/** Optional a11y label reference for the chip list. Recommended to use either that or `aria-label`. */
|
|
25
|
+
'aria-labelledby'?: string;
|
|
19
26
|
/** Identifier for e2e tests */
|
|
20
27
|
'data-e2e'?: string;
|
|
21
28
|
/** CSS style object */
|
|
22
29
|
style?: React.CSSProperties;
|
|
23
30
|
};
|
|
24
|
-
export declare function ChipListBase<V>({ size, sparse, compact, disabled, className, mode, alignItems, theme: themeFromProps, value, onChange, compareValues, children, ['data-e2e']: e2eId, style }: ChipListBaseProps<V>): JSX.Element;
|
|
31
|
+
export declare function ChipListBase<V>({ size, sparse, compact, disabled, className, mode, alignItems, pattern, theme: themeFromProps, value, onChange, compareValues, children, name, ['aria-label']: ariaLabel, ['aria-labelledby']: ariaLabelledBy, ['data-e2e']: e2eId, style }: ChipListBaseProps<V>): JSX.Element;
|
|
@@ -5,6 +5,8 @@ import { useThemeWithUndefined } from '@rescui/ui-contexts';
|
|
|
5
5
|
import { ChipListContext } from './chip-list-context.js';
|
|
6
6
|
import styles from './chip-list.p.module.css.js';
|
|
7
7
|
import { useItemsIds } from './use-items-ids.js';
|
|
8
|
+
import { useRovingTabIndex } from './use-roving-tab-index.js';
|
|
9
|
+
const IS_PRODUCTION = process.env.NODE_ENV === 'production';
|
|
8
10
|
const STYLES_SIZES = {
|
|
9
11
|
xs: styles.sizeXs,
|
|
10
12
|
s: styles.sizeS,
|
|
@@ -17,7 +19,21 @@ const ALIGN_ITEMS_STYLES = {
|
|
|
17
19
|
right: styles.alignRight
|
|
18
20
|
};
|
|
19
21
|
|
|
20
|
-
|
|
22
|
+
const calculateAutoPattern = _ref => {
|
|
23
|
+
let {
|
|
24
|
+
hasHref,
|
|
25
|
+
hasControls
|
|
26
|
+
} = _ref;
|
|
27
|
+
|
|
28
|
+
if (hasControls) {
|
|
29
|
+
return 'tablist';
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return hasHref ? 'navigation' : 'radiogroup';
|
|
33
|
+
}; // eslint-disable-next-line complexity
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
function ChipListBase(_ref2) {
|
|
21
37
|
let {
|
|
22
38
|
size = 'm',
|
|
23
39
|
sparse = false,
|
|
@@ -26,34 +42,74 @@ function ChipListBase(_ref) {
|
|
|
26
42
|
className,
|
|
27
43
|
mode = 'classic',
|
|
28
44
|
alignItems = 'left',
|
|
45
|
+
pattern = 'auto',
|
|
29
46
|
theme: themeFromProps,
|
|
30
47
|
value,
|
|
31
48
|
onChange,
|
|
32
49
|
compareValues,
|
|
33
50
|
children,
|
|
51
|
+
name,
|
|
52
|
+
['aria-label']: ariaLabel,
|
|
53
|
+
['aria-labelledby']: ariaLabelledBy,
|
|
34
54
|
['data-e2e']: e2eId,
|
|
35
55
|
style
|
|
36
|
-
} =
|
|
56
|
+
} = _ref2;
|
|
37
57
|
const theme = useThemeWithUndefined(themeFromProps);
|
|
38
58
|
const {
|
|
39
59
|
childrenWithValues,
|
|
40
|
-
selectedIds
|
|
60
|
+
selectedIds,
|
|
61
|
+
hasHref,
|
|
62
|
+
hasControls,
|
|
63
|
+
allItemsHaveControls,
|
|
64
|
+
tabRefs
|
|
41
65
|
} = useItemsIds({
|
|
42
66
|
children,
|
|
43
67
|
compareValues,
|
|
44
68
|
value
|
|
45
69
|
});
|
|
70
|
+
const resolvedPattern = pattern === 'auto' ? calculateAutoPattern({
|
|
71
|
+
hasHref,
|
|
72
|
+
hasControls
|
|
73
|
+
}) : pattern;
|
|
74
|
+
const rovingTabIndex = useRovingTabIndex({
|
|
75
|
+
enabled: resolvedPattern === 'tablist' && !disabled,
|
|
76
|
+
selectedId: selectedIds[0],
|
|
77
|
+
tabRefs
|
|
78
|
+
}); // eslint-disable-next-line complexity
|
|
79
|
+
|
|
80
|
+
React.useEffect(() => {
|
|
81
|
+
if (!IS_PRODUCTION && resolvedPattern === 'radiogroup' && hasHref) {
|
|
82
|
+
// eslint-disable-next-line no-console
|
|
83
|
+
console.warn('[RescUI] ChipList with pattern="radiogroup" contains Chip with href. href is ignored. Use pattern="navigation" or pattern="auto" for link chips.');
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (!IS_PRODUCTION && resolvedPattern !== 'tablist' && hasControls) {
|
|
87
|
+
// eslint-disable-next-line no-console
|
|
88
|
+
console.warn('[RescUI] ChipList with pattern other than "tablist" contains Chip with aria-controls. Use pattern="tablist" or pattern="auto" for controlled tab panels.');
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (!IS_PRODUCTION && resolvedPattern === 'tablist' && !allItemsHaveControls) {
|
|
92
|
+
// eslint-disable-next-line no-console
|
|
93
|
+
console.warn('[RescUI] ChipList with pattern="tablist" requires every Chip to have aria-controls. Every tab should control a panel.');
|
|
94
|
+
}
|
|
95
|
+
}, [allItemsHaveControls, hasControls, hasHref, resolvedPattern]);
|
|
46
96
|
return /*#__PURE__*/React.createElement(ChipListContext.Provider, {
|
|
47
97
|
value: {
|
|
48
98
|
onChange,
|
|
49
99
|
selectedIds,
|
|
50
|
-
disabled
|
|
100
|
+
disabled,
|
|
101
|
+
pattern: resolvedPattern,
|
|
102
|
+
name,
|
|
103
|
+
rovingTabIndex: resolvedPattern === 'tablist' ? rovingTabIndex : undefined
|
|
51
104
|
}
|
|
52
105
|
}, /*#__PURE__*/React.createElement("div", {
|
|
53
106
|
className: cn(styles.main, styles[theme], styles[mode], STYLES_SIZES[size], sparse ? styles.innerOffsetL : styles.innerOffsetM, compact && styles.compact, disabled && styles.disabled, ALIGN_ITEMS_STYLES[alignItems], className),
|
|
54
107
|
"data-e2e": e2eId ? `${e2eId}__chips-container` : null,
|
|
55
108
|
"data-rs-internal": 'chip-list',
|
|
56
109
|
"data-test": 'chip-list',
|
|
110
|
+
role: resolvedPattern,
|
|
111
|
+
"aria-label": ariaLabel,
|
|
112
|
+
"aria-labelledby": ariaLabelledBy,
|
|
57
113
|
style: style
|
|
58
114
|
}, /*#__PURE__*/React.createElement("div", {
|
|
59
115
|
className: styles.chipsContainer
|
|
@@ -4,7 +4,8 @@ const ChipListContext = /*#__PURE__*/createContext({
|
|
|
4
4
|
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
5
5
|
onChange: () => {},
|
|
6
6
|
selectedIds: [],
|
|
7
|
-
disabled: false
|
|
7
|
+
disabled: false,
|
|
8
|
+
pattern: 'navigation'
|
|
8
9
|
});
|
|
9
10
|
|
|
10
11
|
const useChipListContext = () => useContext(ChipListContext);
|
|
@@ -1,26 +1,27 @@
|
|
|
1
1
|
var styles = {
|
|
2
|
-
"light": "
|
|
3
|
-
"dark": "
|
|
4
|
-
"alignLeft": "
|
|
5
|
-
"alignCenter": "
|
|
6
|
-
"alignRight": "
|
|
7
|
-
"sizeXs": "
|
|
8
|
-
"sizeS": "
|
|
9
|
-
"sizeM": "
|
|
10
|
-
"sizeL": "
|
|
11
|
-
"innerOffsetL": "
|
|
12
|
-
"innerOffsetM": "
|
|
13
|
-
"classic": "
|
|
14
|
-
"rock": "
|
|
15
|
-
"compact": "
|
|
16
|
-
"main": "
|
|
17
|
-
"chipsContainer": "
|
|
18
|
-
"alignIconLeft": "
|
|
19
|
-
"alignIconRight": "
|
|
20
|
-
"chip": "
|
|
21
|
-
"selected": "
|
|
22
|
-
"disabled": "
|
|
23
|
-
"icon": "
|
|
24
|
-
"
|
|
2
|
+
"light": "_light_13vk6i6_8",
|
|
3
|
+
"dark": "_dark_13vk6i6_11",
|
|
4
|
+
"alignLeft": "_alignLeft_13vk6i6_15",
|
|
5
|
+
"alignCenter": "_alignCenter_13vk6i6_18",
|
|
6
|
+
"alignRight": "_alignRight_13vk6i6_21",
|
|
7
|
+
"sizeXs": "_sizeXs_13vk6i6_25",
|
|
8
|
+
"sizeS": "_sizeS_13vk6i6_28",
|
|
9
|
+
"sizeM": "_sizeM_13vk6i6_31",
|
|
10
|
+
"sizeL": "_sizeL_13vk6i6_34",
|
|
11
|
+
"innerOffsetL": "_innerOffsetL_13vk6i6_38",
|
|
12
|
+
"innerOffsetM": "_innerOffsetM_13vk6i6_41",
|
|
13
|
+
"classic": "_classic_13vk6i6_45",
|
|
14
|
+
"rock": "_rock_13vk6i6_48",
|
|
15
|
+
"compact": "_compact_13vk6i6_52",
|
|
16
|
+
"main": "_main_13vk6i6_56",
|
|
17
|
+
"chipsContainer": "_chipsContainer_13vk6i6_62",
|
|
18
|
+
"alignIconLeft": "_alignIconLeft_13vk6i6_72",
|
|
19
|
+
"alignIconRight": "_alignIconRight_13vk6i6_75",
|
|
20
|
+
"chip": "_chip_13vk6i6_62",
|
|
21
|
+
"selected": "_selected_13vk6i6_176",
|
|
22
|
+
"disabled": "_disabled_13vk6i6_183",
|
|
23
|
+
"icon": "_icon_13vk6i6_216",
|
|
24
|
+
"hiddenInput": "_hiddenInput_13vk6i6_227",
|
|
25
|
+
"withoutText": "_withoutText_13vk6i6_244"
|
|
25
26
|
};
|
|
26
27
|
export { styles as default };
|
package/lib/parts/chip.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { ChipIconPosition } from './types';
|
|
3
|
-
|
|
3
|
+
declare type InheritType<Main, Parent> = Main & Omit<Parent, keyof Main>;
|
|
4
|
+
export declare type ChipOwnProps = {
|
|
4
5
|
className?: string;
|
|
5
6
|
/**
|
|
6
7
|
* Chip value
|
|
@@ -27,8 +28,9 @@ export declare type ChipExplicitProps = {
|
|
|
27
28
|
icon?: never;
|
|
28
29
|
iconPosition?: never;
|
|
29
30
|
});
|
|
30
|
-
declare type
|
|
31
|
-
declare type
|
|
32
|
-
|
|
33
|
-
declare
|
|
31
|
+
declare type ChipLabelProps = InheritType<ChipOwnProps, React.LabelHTMLAttributes<HTMLLabelElement>>;
|
|
32
|
+
declare type ChipButtonProps = InheritType<ChipOwnProps, React.ButtonHTMLAttributes<HTMLButtonElement>>;
|
|
33
|
+
declare type ChipAnchorProps = InheritType<ChipOwnProps, React.AnchorHTMLAttributes<HTMLAnchorElement>>;
|
|
34
|
+
export declare type ChipProps = ChipLabelProps | ChipButtonProps | ChipAnchorProps;
|
|
35
|
+
declare const Chip: React.ForwardRefExoticComponent<ChipProps & React.RefAttributes<HTMLLabelElement | HTMLButtonElement | HTMLAnchorElement>>;
|
|
34
36
|
export default Chip;
|
package/lib/parts/chip.js
CHANGED
|
@@ -5,31 +5,108 @@ import PropTypes from 'prop-types';
|
|
|
5
5
|
import cn from 'classnames';
|
|
6
6
|
import styles from './chip-list.p.module.css.js';
|
|
7
7
|
import { useChipListContext } from './chip-list-context.js';
|
|
8
|
-
const ChipTag = /*#__PURE__*/forwardRef(
|
|
8
|
+
const ChipTag = /*#__PURE__*/forwardRef( // eslint-disable-next-line complexity
|
|
9
|
+
(_ref, ref) => {
|
|
10
|
+
let {
|
|
11
|
+
selected,
|
|
12
|
+
onValueChange,
|
|
13
|
+
itemId,
|
|
14
|
+
tabIndex,
|
|
15
|
+
children,
|
|
16
|
+
value: chipValue,
|
|
17
|
+
onClick,
|
|
18
|
+
onKeyDown,
|
|
19
|
+
href,
|
|
20
|
+
...restProps
|
|
21
|
+
} = _ref;
|
|
9
22
|
const {
|
|
10
|
-
disabled
|
|
23
|
+
disabled,
|
|
24
|
+
pattern,
|
|
25
|
+
name: hiddenInputName,
|
|
26
|
+
rovingTabIndex
|
|
11
27
|
} = useChipListContext();
|
|
28
|
+
let resolvedTabIndex = disabled ? -1 : tabIndex;
|
|
29
|
+
|
|
30
|
+
if (pattern === 'radiogroup' || pattern === 'group') {
|
|
31
|
+
const labelProps = { ...restProps
|
|
32
|
+
};
|
|
33
|
+
return /*#__PURE__*/React.createElement("label", {
|
|
34
|
+
ref: ref,
|
|
35
|
+
...labelProps
|
|
36
|
+
}, /*#__PURE__*/React.createElement("input", {
|
|
37
|
+
type: pattern === 'group' ? 'checkbox' : 'radio',
|
|
38
|
+
value: String(chipValue),
|
|
39
|
+
onChange: onValueChange,
|
|
40
|
+
onClick: onClick,
|
|
41
|
+
onKeyDown: onKeyDown,
|
|
42
|
+
className: styles.hiddenInput,
|
|
43
|
+
checked: selected,
|
|
44
|
+
disabled: disabled,
|
|
45
|
+
name: hiddenInputName,
|
|
46
|
+
tabIndex: resolvedTabIndex
|
|
47
|
+
}), children);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const handleNavigationClick = e => {
|
|
51
|
+
onClick?.(e);
|
|
52
|
+
onValueChange();
|
|
53
|
+
};
|
|
12
54
|
|
|
13
|
-
|
|
55
|
+
const handleNavigationKeyDown = e => {
|
|
56
|
+
onKeyDown?.(e);
|
|
57
|
+
|
|
58
|
+
if (pattern === 'tablist' && typeof itemId !== 'undefined') {
|
|
59
|
+
rovingTabIndex?.onTabKeyDown(e, itemId);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (e.key === ' ') {
|
|
63
|
+
e.target.click();
|
|
64
|
+
e.preventDefault();
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
const isTablist = pattern === 'tablist';
|
|
69
|
+
const autoRole = isTablist ? 'tab' : undefined;
|
|
70
|
+
const autoAriaCurrent = selected && !isTablist ? 'page' : undefined;
|
|
71
|
+
const autoAriaSelected = isTablist ? selected : undefined;
|
|
72
|
+
|
|
73
|
+
if (isTablist && !disabled) {
|
|
74
|
+
resolvedTabIndex = itemId === rovingTabIndex?.currentTabStopId ? 0 : -1;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (typeof href !== 'undefined') {
|
|
14
78
|
return /*#__PURE__*/React.createElement("a", {
|
|
15
79
|
ref: ref,
|
|
16
|
-
...
|
|
17
|
-
|
|
18
|
-
|
|
80
|
+
...restProps,
|
|
81
|
+
href: href,
|
|
82
|
+
role: restProps.role ?? autoRole,
|
|
83
|
+
"aria-current": restProps['aria-current'] ?? autoAriaCurrent,
|
|
84
|
+
"aria-selected": restProps['aria-selected'] ?? autoAriaSelected,
|
|
85
|
+
"aria-disabled": disabled || undefined,
|
|
86
|
+
onClick: handleNavigationClick,
|
|
87
|
+
onKeyDown: handleNavigationKeyDown,
|
|
88
|
+
tabIndex: resolvedTabIndex
|
|
89
|
+
}, children);
|
|
19
90
|
}
|
|
20
91
|
|
|
21
92
|
return /*#__PURE__*/React.createElement("button", {
|
|
22
93
|
ref: ref,
|
|
23
|
-
...
|
|
94
|
+
...restProps,
|
|
95
|
+
role: restProps.role ?? autoRole,
|
|
96
|
+
"aria-current": restProps['aria-current'] ?? autoAriaCurrent,
|
|
97
|
+
"aria-selected": restProps['aria-selected'] ?? autoAriaSelected,
|
|
24
98
|
disabled: disabled,
|
|
99
|
+
onClick: handleNavigationClick,
|
|
100
|
+
onKeyDown: handleNavigationKeyDown,
|
|
101
|
+
tabIndex: resolvedTabIndex,
|
|
25
102
|
type: "button"
|
|
26
|
-
},
|
|
103
|
+
}, children);
|
|
27
104
|
});
|
|
28
105
|
ChipTag.displayName = 'ChipTag'; // check for ignored jsx values and empty string, more info https://reactjs.org/docs/jsx-in-depth.html#booleans-null-and-undefined-are-ignored
|
|
29
106
|
|
|
30
107
|
const isWithoutChildren = children => children === null || typeof children === 'undefined' || children === false || children === true || children === '';
|
|
31
108
|
|
|
32
|
-
const Chip = /*#__PURE__*/forwardRef((
|
|
109
|
+
const Chip = /*#__PURE__*/forwardRef((_ref2, ref) => {
|
|
33
110
|
let {
|
|
34
111
|
value,
|
|
35
112
|
className,
|
|
@@ -37,11 +114,9 @@ const Chip = /*#__PURE__*/forwardRef((_ref, ref) => {
|
|
|
37
114
|
icon,
|
|
38
115
|
iconPosition = 'left',
|
|
39
116
|
itemId,
|
|
40
|
-
onClick,
|
|
41
|
-
onKeyDown,
|
|
42
117
|
['data-e2e']: e2eId,
|
|
43
118
|
...restProps
|
|
44
|
-
} =
|
|
119
|
+
} = _ref2;
|
|
45
120
|
const {
|
|
46
121
|
onChange,
|
|
47
122
|
selectedIds
|
|
@@ -55,24 +130,10 @@ const Chip = /*#__PURE__*/forwardRef((_ref, ref) => {
|
|
|
55
130
|
[styles.selected]: selected,
|
|
56
131
|
[styles.withoutText]: isWithoutText
|
|
57
132
|
}, iconPosition === 'right' ? styles.alignIconRight : styles.alignIconLeft, className),
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
onChange(value);
|
|
64
|
-
},
|
|
65
|
-
onKeyDown: e => {
|
|
66
|
-
if (e.key === ' ') {
|
|
67
|
-
e.target.click();
|
|
68
|
-
e.preventDefault();
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
if (onKeyDown) {
|
|
72
|
-
onKeyDown(e);
|
|
73
|
-
}
|
|
74
|
-
},
|
|
75
|
-
role: "tab",
|
|
133
|
+
onValueChange: () => onChange(value),
|
|
134
|
+
itemId: itemId,
|
|
135
|
+
selected: selected,
|
|
136
|
+
value: value,
|
|
76
137
|
tabIndex: restProps.tabIndex ?? 0,
|
|
77
138
|
ref: ref,
|
|
78
139
|
"data-e2e": e2eId,
|
package/lib/parts/types.d.ts
CHANGED
|
@@ -1,9 +1,19 @@
|
|
|
1
|
+
import type React from 'react';
|
|
1
2
|
export declare type ChipListSizeType = 'l' | 'm' | 's' | 'xs';
|
|
2
3
|
export declare type ChipListModeType = 'classic' | 'rock';
|
|
3
4
|
export declare type ChipListAlignItemsType = 'left' | 'center' | 'right';
|
|
5
|
+
export declare type ChipListResolvedPatternType = 'radiogroup' | 'group' | 'navigation' | 'tablist';
|
|
6
|
+
export declare type ChipListPatternType = 'radiogroup' | 'navigation' | 'tablist' | 'auto';
|
|
7
|
+
export declare type ChipListBasePatternType = ChipListPatternType | 'group';
|
|
4
8
|
export declare type ChipIconPosition = 'left' | 'right';
|
|
5
9
|
export declare type ChipListContextType<V> = {
|
|
6
10
|
onChange: (value: V) => void;
|
|
7
11
|
selectedIds?: number[];
|
|
8
12
|
disabled?: boolean;
|
|
13
|
+
pattern?: ChipListResolvedPatternType;
|
|
14
|
+
name?: string;
|
|
15
|
+
rovingTabIndex?: {
|
|
16
|
+
currentTabStopId: number;
|
|
17
|
+
onTabKeyDown: (e: React.KeyboardEvent<HTMLElement>, itemId: number) => void;
|
|
18
|
+
};
|
|
9
19
|
};
|
|
@@ -7,4 +7,8 @@ export declare type UseItemsIdsOpts<V> = {
|
|
|
7
7
|
export declare const useItemsIds: <V>({ children, compareValues, value }: UseItemsIdsOpts<V>) => {
|
|
8
8
|
childrenWithValues: (string | number | React.ReactElement<any, string | React.JSXElementConstructor<any>> | React.ReactFragment | React.ReactPortal)[];
|
|
9
9
|
selectedIds: number[];
|
|
10
|
+
hasHref: boolean;
|
|
11
|
+
hasControls: boolean;
|
|
12
|
+
allItemsHaveControls: boolean;
|
|
13
|
+
tabRefs: React.MutableRefObject<Map<number, HTMLElement>>;
|
|
10
14
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useMemo, cloneElement } from 'react';
|
|
1
|
+
import React, { useRef, useCallback, useMemo, cloneElement } from 'react';
|
|
2
2
|
import { deepMap } from './deep-map.js';
|
|
3
3
|
import Chip from './chip.js';
|
|
4
4
|
|
|
@@ -6,27 +6,72 @@ function patchItemIfNeeded(_ref) {
|
|
|
6
6
|
let {
|
|
7
7
|
child,
|
|
8
8
|
itemId,
|
|
9
|
-
childValue
|
|
9
|
+
childValue,
|
|
10
|
+
ref
|
|
10
11
|
} = _ref;
|
|
11
12
|
return /*#__PURE__*/cloneElement(child, {
|
|
12
13
|
itemId,
|
|
13
|
-
value: childValue
|
|
14
|
+
value: childValue,
|
|
15
|
+
ref
|
|
14
16
|
});
|
|
15
17
|
}
|
|
16
18
|
|
|
19
|
+
const setRef = (ref, value) => {
|
|
20
|
+
if (typeof ref === 'function') {
|
|
21
|
+
ref(value);
|
|
22
|
+
} else if (ref) {
|
|
23
|
+
ref.current = value;
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const getElementRef = child => child.ref;
|
|
28
|
+
|
|
17
29
|
const hasElValue = el => el.props?.value !== null && typeof el.props?.value !== 'undefined';
|
|
18
30
|
|
|
31
|
+
const hasElHref = el => typeof el.props?.href !== 'undefined';
|
|
32
|
+
|
|
33
|
+
const hasElAriaControls = el => typeof el.props?.['aria-controls'] !== 'undefined';
|
|
34
|
+
|
|
19
35
|
const useItemsIds = _ref2 => {
|
|
20
36
|
let {
|
|
21
37
|
children,
|
|
22
38
|
compareValues,
|
|
23
39
|
value
|
|
24
40
|
} = _ref2;
|
|
25
|
-
const
|
|
41
|
+
const tabRefs = useRef(new Map());
|
|
42
|
+
const createChipRef = useCallback((itemId, childRef) => node => {
|
|
43
|
+
if (node) {
|
|
44
|
+
tabRefs.current.set(itemId, node);
|
|
45
|
+
} else {
|
|
46
|
+
tabRefs.current.delete(itemId);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
setRef(childRef, node);
|
|
50
|
+
}, []);
|
|
51
|
+
const {
|
|
52
|
+
childrenWithValues,
|
|
53
|
+
selectedIds,
|
|
54
|
+
hasHref,
|
|
55
|
+
hasControls,
|
|
56
|
+
allItemsHaveControls
|
|
57
|
+
} = useMemo(() => {
|
|
26
58
|
let counter = 0;
|
|
27
59
|
const currentSelectedItemIds = [];
|
|
60
|
+
let currentHasHref = false;
|
|
61
|
+
let currentHasControls = false;
|
|
62
|
+
let currentAllItemsHaveControls = true;
|
|
28
63
|
const items = deepMap(children, child => {
|
|
29
64
|
if (child.type === Chip) {
|
|
65
|
+
if (hasElHref(child)) {
|
|
66
|
+
currentHasHref = true;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (hasElAriaControls(child)) {
|
|
70
|
+
currentHasControls = true;
|
|
71
|
+
} else {
|
|
72
|
+
currentAllItemsHaveControls = false;
|
|
73
|
+
}
|
|
74
|
+
|
|
30
75
|
const childValue = hasElValue(child) ? child.props.value : counter;
|
|
31
76
|
const isSelectedItem = compareValues(value, childValue);
|
|
32
77
|
|
|
@@ -37,7 +82,8 @@ const useItemsIds = _ref2 => {
|
|
|
37
82
|
const patchedItem = patchItemIfNeeded({
|
|
38
83
|
child,
|
|
39
84
|
itemId: counter,
|
|
40
|
-
childValue
|
|
85
|
+
childValue,
|
|
86
|
+
ref: createChipRef(counter, getElementRef(child))
|
|
41
87
|
});
|
|
42
88
|
counter += 1;
|
|
43
89
|
return patchedItem;
|
|
@@ -45,11 +91,21 @@ const useItemsIds = _ref2 => {
|
|
|
45
91
|
return child;
|
|
46
92
|
}
|
|
47
93
|
});
|
|
48
|
-
return
|
|
49
|
-
|
|
94
|
+
return {
|
|
95
|
+
childrenWithValues: React.Children.toArray(items),
|
|
96
|
+
selectedIds: currentSelectedItemIds,
|
|
97
|
+
hasHref: currentHasHref,
|
|
98
|
+
hasControls: currentHasControls,
|
|
99
|
+
allItemsHaveControls: counter > 0 && currentAllItemsHaveControls
|
|
100
|
+
};
|
|
101
|
+
}, [children, value, compareValues, createChipRef]);
|
|
50
102
|
return {
|
|
51
103
|
childrenWithValues,
|
|
52
|
-
selectedIds
|
|
104
|
+
selectedIds,
|
|
105
|
+
hasHref,
|
|
106
|
+
hasControls,
|
|
107
|
+
allItemsHaveControls,
|
|
108
|
+
tabRefs
|
|
53
109
|
};
|
|
54
110
|
};
|
|
55
111
|
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export declare const useRovingTabIndex: ({ enabled, selectedId, tabRefs }: {
|
|
3
|
+
enabled: boolean;
|
|
4
|
+
selectedId?: number;
|
|
5
|
+
tabRefs?: React.MutableRefObject<Map<number, HTMLElement>>;
|
|
6
|
+
}) => {
|
|
7
|
+
currentTabStopId: number;
|
|
8
|
+
onTabKeyDown: (e: React.KeyboardEvent<HTMLElement>, itemId: number) => void;
|
|
9
|
+
};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import _includesInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/includes";
|
|
2
|
+
import React from 'react'; // eslint-disable-next-line complexity
|
|
3
|
+
|
|
4
|
+
const getNextItemId = _ref => {
|
|
5
|
+
let {
|
|
6
|
+
currentItemId,
|
|
7
|
+
itemsCount,
|
|
8
|
+
key
|
|
9
|
+
} = _ref;
|
|
10
|
+
|
|
11
|
+
if (itemsCount <= 0) {
|
|
12
|
+
return currentItemId;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
if (key === 'Home') {
|
|
16
|
+
return 0;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
if (key === 'End') {
|
|
20
|
+
return itemsCount - 1;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (key === 'ArrowLeft') {
|
|
24
|
+
return currentItemId <= 0 ? itemsCount - 1 : currentItemId - 1;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (key === 'ArrowRight') {
|
|
28
|
+
return currentItemId >= itemsCount - 1 ? 0 : currentItemId + 1;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return currentItemId;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const useRovingTabIndex = _ref2 => {
|
|
35
|
+
let {
|
|
36
|
+
enabled,
|
|
37
|
+
selectedId,
|
|
38
|
+
tabRefs
|
|
39
|
+
} = _ref2;
|
|
40
|
+
const [currentTabStopId, setCurrentTabStopId] = React.useState(selectedId ?? 0);
|
|
41
|
+
React.useEffect(() => {
|
|
42
|
+
if (typeof selectedId !== 'undefined') {
|
|
43
|
+
setCurrentTabStopId(selectedId);
|
|
44
|
+
}
|
|
45
|
+
}, [selectedId]);
|
|
46
|
+
const onTabKeyDown = React.useCallback((e, itemId) => {
|
|
47
|
+
var _context;
|
|
48
|
+
|
|
49
|
+
if (!enabled) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (!_includesInstanceProperty(_context = ['ArrowLeft', 'ArrowRight', 'Home', 'End']).call(_context, e.key)) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const itemsCount = tabRefs?.current.size ?? 0;
|
|
58
|
+
const nextItemId = getNextItemId({
|
|
59
|
+
currentItemId: itemId,
|
|
60
|
+
itemsCount,
|
|
61
|
+
key: e.key
|
|
62
|
+
});
|
|
63
|
+
e.preventDefault();
|
|
64
|
+
setCurrentTabStopId(nextItemId);
|
|
65
|
+
tabRefs?.current.get(nextItemId)?.focus();
|
|
66
|
+
}, [enabled, tabRefs]);
|
|
67
|
+
return {
|
|
68
|
+
currentTabStopId,
|
|
69
|
+
onTabKeyDown
|
|
70
|
+
};
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export { useRovingTabIndex };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import React, { useRef } from 'react';
|
|
2
|
+
|
|
3
|
+
const useFallbackId = () => {
|
|
4
|
+
const id = useRef(null);
|
|
5
|
+
|
|
6
|
+
if (id.current === null) {
|
|
7
|
+
id.current = useFallbackId.counter++;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
return id.current.toString();
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
useFallbackId.counter = 0;
|
|
14
|
+
const useSafeId = React.useId ?? useFallbackId;
|
|
15
|
+
export { useSafeId };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rescui/chip-list",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "JetBrains",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"devDependencies": {
|
|
27
27
|
"@rescui/colors": "^0.3.0",
|
|
28
28
|
"@rescui/scripts": "^0.5.1",
|
|
29
|
-
"@rescui/typography": "^0.
|
|
29
|
+
"@rescui/typography": "^0.27.0",
|
|
30
30
|
"@rescui/visual-regression": "^0.1.4"
|
|
31
31
|
},
|
|
32
32
|
"scripts": {
|
|
@@ -34,5 +34,5 @@
|
|
|
34
34
|
"build-pcss-api": "rescui-scripts build-pcss-api --file public-api.p.css"
|
|
35
35
|
},
|
|
36
36
|
"nx": {},
|
|
37
|
-
"gitHead": "
|
|
37
|
+
"gitHead": "e9aedd97a4cc372540ec8d75dda4f122baacca10"
|
|
38
38
|
}
|