@primer/components 0.0.0-2021927182958 → 0.0.0-2021927184638
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/CHANGELOG.md +5 -5
- package/dist/browser.esm.js +15 -13
- package/dist/browser.esm.js.map +1 -1
- package/dist/browser.umd.js +34 -32
- package/dist/browser.umd.js.map +1 -1
- package/lib/TextInputWithTokens.d.ts +0 -4
- package/lib/TextInputWithTokens.js +48 -81
- package/lib/Token/Token.js +13 -2
- package/lib/Token/TokenBase.js +0 -4
- package/lib/Token/_RemoveTokenButton.js +15 -2
- package/lib/_TextInputWrapper.js +1 -1
- package/lib-esm/TextInputWithTokens.d.ts +0 -4
- package/lib-esm/TextInputWithTokens.js +48 -81
- package/lib-esm/Token/Token.js +13 -2
- package/lib-esm/Token/TokenBase.js +0 -4
- package/lib-esm/Token/_RemoveTokenButton.js +11 -2
- package/lib-esm/_TextInputWrapper.js +1 -1
- package/package.json +1 -1
@@ -32,10 +32,6 @@ declare const TextInputWithTokens: React.ForwardRefExoticComponent<Pick<{
|
|
32
32
|
* Whether the remove buttons should be rendered in the tokens
|
33
33
|
*/
|
34
34
|
hideTokenRemoveButtons?: boolean | undefined;
|
35
|
-
/**
|
36
|
-
* The number of tokens to display before truncating
|
37
|
-
*/
|
38
|
-
visibleTokenCount?: number | undefined;
|
39
35
|
} & Pick<Omit<Pick<{
|
40
36
|
[x: string]: any;
|
41
37
|
[x: number]: any;
|
@@ -25,7 +25,7 @@ var _TextInputWrapper = _interopRequireDefault(require("./_TextInputWrapper"));
|
|
25
25
|
|
26
26
|
var _Box = _interopRequireDefault(require("./Box"));
|
27
27
|
|
28
|
-
var
|
28
|
+
var _iterateFocusableElements = require("./utils/iterateFocusableElements");
|
29
29
|
|
30
30
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
31
31
|
|
@@ -35,13 +35,7 @@ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj &&
|
|
35
35
|
|
36
36
|
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
37
37
|
|
38
|
-
|
39
|
-
small: 0,
|
40
|
-
medium: 1,
|
41
|
-
large: 1,
|
42
|
-
extralarge: 2
|
43
|
-
}; // using forwardRef is important so that other components (ex. Autocomplete) can use the ref
|
44
|
-
|
38
|
+
// using forwardRef is important so that other components (ex. Autocomplete) can use the ref
|
45
39
|
function TextInputWithTokensInnerComponent({
|
46
40
|
icon: IconComponent,
|
47
41
|
contrast,
|
@@ -61,11 +55,9 @@ function TextInputWithTokensInnerComponent({
|
|
61
55
|
minWidth: minWidthProp,
|
62
56
|
maxWidth: maxWidthProp,
|
63
57
|
variant: variantProp,
|
64
|
-
visibleTokenCount,
|
65
58
|
...rest
|
66
59
|
}, externalRef) {
|
67
60
|
const {
|
68
|
-
onBlur,
|
69
61
|
onFocus,
|
70
62
|
onKeyDown,
|
71
63
|
...inputPropsRest
|
@@ -74,7 +66,6 @@ function TextInputWithTokensInnerComponent({
|
|
74
66
|
const localInputRef = (0, _react.useRef)(null);
|
75
67
|
const combinedInputRef = (0, _useCombinedRefs.useCombinedRefs)(localInputRef, ref);
|
76
68
|
const [selectedTokenIndex, setSelectedTokenIndex] = (0, _react.useState)();
|
77
|
-
const [tokensAreTruncated, setTokensAreTruncated] = (0, _react.useState)(Boolean(visibleTokenCount));
|
78
69
|
const {
|
79
70
|
containerRef
|
80
71
|
} = (0, _useFocusZone.useFocusZone)({
|
@@ -109,70 +100,56 @@ function TextInputWithTokensInnerComponent({
|
|
109
100
|
}, [selectedTokenIndex]);
|
110
101
|
|
111
102
|
const handleTokenRemove = tokenId => {
|
112
|
-
onTokenRemove(tokenId);
|
113
|
-
|
114
|
-
if (selectedTokenIndex) {
|
115
|
-
var _containerRef$current2;
|
103
|
+
onTokenRemove(tokenId); // HACK: wait a tick for the the token node to be removed from the DOM
|
116
104
|
|
117
|
-
|
118
|
-
|
119
|
-
}
|
120
|
-
};
|
105
|
+
setTimeout(() => {
|
106
|
+
var _containerRef$current2, _containerRef$current3;
|
121
107
|
|
122
|
-
|
123
|
-
|
124
|
-
};
|
108
|
+
const nextElementToFocus = (_containerRef$current2 = containerRef.current) === null || _containerRef$current2 === void 0 ? void 0 : _containerRef$current2.children[selectedTokenIndex || 0]; // when removing the first token by keying "Backspace" or "Delete",
|
109
|
+
// `nextFocusableElement` is the div that wraps the input
|
125
110
|
|
126
|
-
|
127
|
-
setSelectedTokenIndex(undefined); // HACK: wait a tick and check the focused element before hiding truncated tokens
|
128
|
-
// this prevents the tokens from hiding when the user is moving focus between tokens,
|
129
|
-
// but still hides the tokens when the user blurs the token by tabbing out or clicking somewhere else on the page
|
111
|
+
const firstFocusable = nextElementToFocus && (0, _iterateFocusableElements.isFocusable)(nextElementToFocus) ? nextElementToFocus : Array.from(((_containerRef$current3 = containerRef.current) === null || _containerRef$current3 === void 0 ? void 0 : _containerRef$current3.children) || []).find(el => (0, _iterateFocusableElements.isFocusable)(el));
|
130
112
|
|
131
|
-
|
132
|
-
|
113
|
+
if (firstFocusable) {
|
114
|
+
firstFocusable.focus();
|
115
|
+
} else {
|
116
|
+
var _ref$current;
|
133
117
|
|
134
|
-
|
135
|
-
|
118
|
+
// if there are no tokens left, focus the input
|
119
|
+
(_ref$current = ref.current) === null || _ref$current === void 0 ? void 0 : _ref$current.focus();
|
136
120
|
}
|
137
121
|
}, 0);
|
138
122
|
};
|
139
123
|
|
140
|
-
const
|
141
|
-
|
142
|
-
var _ref$current;
|
143
|
-
|
144
|
-
(_ref$current = ref.current) === null || _ref$current === void 0 ? void 0 : _ref$current.focus();
|
145
|
-
}
|
124
|
+
const handleTokenFocus = tokenIndex => () => {
|
125
|
+
setSelectedTokenIndex(tokenIndex);
|
146
126
|
};
|
147
127
|
|
148
|
-
const
|
149
|
-
onFocus && onFocus(event);
|
128
|
+
const handleTokenBlur = () => {
|
150
129
|
setSelectedTokenIndex(undefined);
|
151
|
-
visibleTokenCount && setTokensAreTruncated(false);
|
152
130
|
};
|
153
131
|
|
154
|
-
const
|
155
|
-
|
156
|
-
|
157
|
-
// but still hides the tokens when the user blurs the input by tabbing out or clicking somewhere else on the page
|
132
|
+
const handleTokenKeyUp = e => {
|
133
|
+
if (e.key === 'Escape') {
|
134
|
+
var _ref$current2;
|
158
135
|
|
159
|
-
|
160
|
-
|
136
|
+
(_ref$current2 = ref.current) === null || _ref$current2 === void 0 ? void 0 : _ref$current2.focus();
|
137
|
+
}
|
138
|
+
};
|
161
139
|
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
}, 0);
|
140
|
+
const handleInputFocus = e => {
|
141
|
+
onFocus && onFocus(e);
|
142
|
+
setSelectedTokenIndex(undefined);
|
166
143
|
};
|
167
144
|
|
168
145
|
const handleInputKeyDown = e => {
|
169
|
-
var _ref$
|
146
|
+
var _ref$current3;
|
170
147
|
|
171
148
|
if (onKeyDown) {
|
172
149
|
onKeyDown(e);
|
173
150
|
}
|
174
151
|
|
175
|
-
if ((_ref$
|
152
|
+
if ((_ref$current3 = ref.current) !== null && _ref$current3 !== void 0 && _ref$current3.value) {
|
176
153
|
return;
|
177
154
|
}
|
178
155
|
|
@@ -193,24 +170,13 @@ function TextInputWithTokensInnerComponent({
|
|
193
170
|
|
194
171
|
|
195
172
|
setTimeout(() => {
|
196
|
-
var _ref$
|
173
|
+
var _ref$current4;
|
197
174
|
|
198
|
-
(_ref$
|
175
|
+
(_ref$current4 = ref.current) === null || _ref$current4 === void 0 ? void 0 : _ref$current4.select();
|
199
176
|
}, 0);
|
200
177
|
}
|
201
178
|
};
|
202
179
|
|
203
|
-
const focusInput = () => {
|
204
|
-
var _combinedInputRef$cur;
|
205
|
-
|
206
|
-
(_combinedInputRef$cur = combinedInputRef.current) === null || _combinedInputRef$cur === void 0 ? void 0 : _combinedInputRef$cur.focus();
|
207
|
-
};
|
208
|
-
|
209
|
-
const preventTokenClickPropagation = event => {
|
210
|
-
event.stopPropagation();
|
211
|
-
};
|
212
|
-
|
213
|
-
const visibleTokens = tokensAreTruncated ? tokens.slice(0, visibleTokenCount) : tokens;
|
214
180
|
return /*#__PURE__*/_react.default.createElement(_TextInputWrapper.default, {
|
215
181
|
block: block,
|
216
182
|
className: className,
|
@@ -222,16 +188,7 @@ function TextInputWithTokensInnerComponent({
|
|
222
188
|
minWidth: minWidthProp,
|
223
189
|
maxWidth: maxWidthProp,
|
224
190
|
variant: variantProp,
|
225
|
-
|
226
|
-
onClick: focusInput,
|
227
|
-
sx: {
|
228
|
-
alignItems: 'center',
|
229
|
-
flexWrap: preventTokenWrapping ? 'nowrap' : 'wrap',
|
230
|
-
gap: '0.25rem',
|
231
|
-
'> *': {
|
232
|
-
flexShrink: 0
|
233
|
-
},
|
234
|
-
...(block ? {
|
191
|
+
sx: { ...(block ? {
|
235
192
|
display: 'flex',
|
236
193
|
width: '100%'
|
237
194
|
} : {}),
|
@@ -244,6 +201,21 @@ function TextInputWithTokensInnerComponent({
|
|
244
201
|
} : {}),
|
245
202
|
...sxProp
|
246
203
|
}
|
204
|
+
}, /*#__PURE__*/_react.default.createElement(_Box.default, {
|
205
|
+
ref: containerRef,
|
206
|
+
display: "flex",
|
207
|
+
sx: {
|
208
|
+
alignItems: 'center',
|
209
|
+
flexWrap: preventTokenWrapping ? 'nowrap' : 'wrap',
|
210
|
+
marginLeft: '-0.25rem',
|
211
|
+
marginBottom: '-0.25rem',
|
212
|
+
flexGrow: 1,
|
213
|
+
'> *': {
|
214
|
+
flexShrink: 0,
|
215
|
+
marginLeft: '0.25rem',
|
216
|
+
marginBottom: '0.25rem'
|
217
|
+
}
|
218
|
+
}
|
247
219
|
}, /*#__PURE__*/_react.default.createElement(_Box.default, {
|
248
220
|
sx: {
|
249
221
|
order: 1,
|
@@ -255,13 +227,12 @@ function TextInputWithTokensInnerComponent({
|
|
255
227
|
ref: combinedInputRef,
|
256
228
|
disabled: disabled,
|
257
229
|
onFocus: handleInputFocus,
|
258
|
-
onBlur: handleInputBlur,
|
259
230
|
onKeyDown: handleInputKeyDown,
|
260
231
|
type: "text",
|
261
232
|
sx: {
|
262
233
|
height: '100%'
|
263
234
|
}
|
264
|
-
}, inputPropsRest))), TokenComponent ?
|
235
|
+
}, inputPropsRest))), tokens.length && TokenComponent ? tokens.map(({
|
265
236
|
id,
|
266
237
|
...tokenRest
|
267
238
|
}, i) => /*#__PURE__*/_react.default.createElement(TokenComponent, _extends({
|
@@ -269,7 +240,6 @@ function TextInputWithTokensInnerComponent({
|
|
269
240
|
onFocus: handleTokenFocus(i),
|
270
241
|
onBlur: handleTokenBlur,
|
271
242
|
onKeyUp: handleTokenKeyUp,
|
272
|
-
onClick: preventTokenClickPropagation,
|
273
243
|
isSelected: selectedTokenIndex === i,
|
274
244
|
onRemove: () => {
|
275
245
|
handleTokenRemove(id);
|
@@ -277,10 +247,7 @@ function TextInputWithTokensInnerComponent({
|
|
277
247
|
hideRemoveButton: hideTokenRemoveButtons,
|
278
248
|
size: size,
|
279
249
|
tabIndex: 0
|
280
|
-
}, tokenRest))) : null
|
281
|
-
color: "fg.muted",
|
282
|
-
fontSize: size && overflowCountFontSizeMap[size]
|
283
|
-
}, "+", tokens.length - visibleTokens.length) : null);
|
250
|
+
}, tokenRest))) : null));
|
284
251
|
}
|
285
252
|
|
286
253
|
TextInputWithTokensInnerComponent.displayName = "TextInputWithTokensInnerComponent";
|
package/lib/Token/Token.js
CHANGED
@@ -39,7 +39,16 @@ const DefaultTokenStyled = (0, _styledComponents.default)(_TokenBase.default).wi
|
|
39
39
|
const LeadingVisualContainer = (0, _styledComponents.default)('span').withConfig({
|
40
40
|
displayName: "Token__LeadingVisualContainer",
|
41
41
|
componentId: "sc-1dg52pw-1"
|
42
|
-
})(["flex-shrink:0;line-height:0;"]
|
42
|
+
})(["flex-shrink:0;line-height:0;", ""], props => {
|
43
|
+
switch (props.size) {
|
44
|
+
case 'large':
|
45
|
+
case 'extralarge':
|
46
|
+
return (0, _styledComponents.css)(["margin-right:", ";"], (0, _constants.get)('space.2'));
|
47
|
+
|
48
|
+
default:
|
49
|
+
return (0, _styledComponents.css)(["margin-right:", ";"], (0, _constants.get)('space.1'));
|
50
|
+
}
|
51
|
+
});
|
43
52
|
const Token = /*#__PURE__*/(0, _react.forwardRef)((props, forwardedRef) => {
|
44
53
|
const {
|
45
54
|
as,
|
@@ -74,7 +83,9 @@ const Token = /*#__PURE__*/(0, _react.forwardRef)((props, forwardedRef) => {
|
|
74
83
|
isTokenInteractive: (0, _TokenBase.isTokenInteractive)(props)
|
75
84
|
}, !hasMultipleActionTargets ? interactiveTokenProps : {}, rest, {
|
76
85
|
ref: forwardedRef
|
77
|
-
}), LeadingVisual ? /*#__PURE__*/_react.default.createElement(LeadingVisualContainer,
|
86
|
+
}), LeadingVisual ? /*#__PURE__*/_react.default.createElement(LeadingVisualContainer, {
|
87
|
+
size: size
|
88
|
+
}, /*#__PURE__*/_react.default.createElement(LeadingVisual, null)) : null, /*#__PURE__*/_react.default.createElement(_TokenTextContainer.default, hasMultipleActionTargets ? interactiveTokenProps : {}, text), !hideRemoveButton && onRemove ? /*#__PURE__*/_react.default.createElement(_RemoveTokenButton.default, {
|
78
89
|
borderOffset: tokenBorderWidthPx,
|
79
90
|
onClick: onRemoveClick,
|
80
91
|
size: size,
|
package/lib/Token/TokenBase.js
CHANGED
@@ -38,7 +38,6 @@ const variants = (0, _styledSystem.variant)({
|
|
38
38
|
variants: {
|
39
39
|
small: {
|
40
40
|
fontSize: 0,
|
41
|
-
gap: 1,
|
42
41
|
height: tokenSizes.small,
|
43
42
|
// without setting lineHeight to match height, the "x" appears vertically mis-aligned
|
44
43
|
lineHeight: tokenSizes.small,
|
@@ -51,7 +50,6 @@ const variants = (0, _styledSystem.variant)({
|
|
51
50
|
},
|
52
51
|
medium: {
|
53
52
|
fontSize: 0,
|
54
|
-
gap: 1,
|
55
53
|
height: tokenSizes.medium,
|
56
54
|
lineHeight: tokenSizes.medium,
|
57
55
|
paddingLeft: 2,
|
@@ -61,7 +59,6 @@ const variants = (0, _styledSystem.variant)({
|
|
61
59
|
},
|
62
60
|
large: {
|
63
61
|
fontSize: 0,
|
64
|
-
gap: 2,
|
65
62
|
height: tokenSizes.large,
|
66
63
|
lineHeight: tokenSizes.large,
|
67
64
|
paddingLeft: 2,
|
@@ -71,7 +68,6 @@ const variants = (0, _styledSystem.variant)({
|
|
71
68
|
},
|
72
69
|
extralarge: {
|
73
70
|
fontSize: 1,
|
74
|
-
gap: 2,
|
75
71
|
height: tokenSizes.extralarge,
|
76
72
|
lineHeight: tokenSizes.extralarge,
|
77
73
|
paddingLeft: 3,
|
@@ -9,7 +9,7 @@ var _react = _interopRequireDefault(require("react"));
|
|
9
9
|
|
10
10
|
var _octiconsReact = require("@primer/octicons-react");
|
11
11
|
|
12
|
-
var _styledComponents =
|
12
|
+
var _styledComponents = _interopRequireWildcard(require("styled-components"));
|
13
13
|
|
14
14
|
var _styledSystem = require("styled-system");
|
15
15
|
|
@@ -19,6 +19,10 @@ var _sx = _interopRequireDefault(require("../sx"));
|
|
19
19
|
|
20
20
|
var _TokenBase = require("./TokenBase");
|
21
21
|
|
22
|
+
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
23
|
+
|
24
|
+
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
25
|
+
|
22
26
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
23
27
|
|
24
28
|
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
@@ -50,7 +54,16 @@ const getTokenButtonIconSize = size => parseInt(_TokenBase.tokenSizes[size || _T
|
|
50
54
|
const StyledTokenButton = _styledComponents.default.span.withConfig({
|
51
55
|
displayName: "_RemoveTokenButton__StyledTokenButton",
|
52
56
|
componentId: "sc-14lvcw1-0"
|
53
|
-
})(["background-color:transparent;font-family:inherit;color:currentColor;cursor:pointer;display:inline-flex;justify-content:center;align-items:center;user-select:none;appearance:none;text-decoration:none;padding:0;transform:", ";align-self:baseline;border:0;border-radius:999px
|
57
|
+
})(["background-color:transparent;font-family:inherit;color:currentColor;cursor:pointer;display:inline-flex;justify-content:center;align-items:center;user-select:none;appearance:none;text-decoration:none;padding:0;transform:", ";align-self:baseline;border:0;border-radius:999px;", " &:hover,&:focus{background-color:", ";}&:active{background-color:", ";}", " ", ""], props => `translate(${props.borderOffset}px, -${props.borderOffset}px)`, props => {
|
58
|
+
switch (props.size) {
|
59
|
+
case 'large':
|
60
|
+
case 'extralarge':
|
61
|
+
return (0, _styledComponents.css)(["margin-left:", ";"], (0, _constants.get)('space.2'));
|
62
|
+
|
63
|
+
default:
|
64
|
+
return (0, _styledComponents.css)(["margin-left:", ";"], (0, _constants.get)('space.1'));
|
65
|
+
}
|
66
|
+
}, (0, _constants.get)('colors.neutral.muted'), (0, _constants.get)('colors.neutral.subtle'), variants, _sx.default);
|
54
67
|
|
55
68
|
const RemoveTokenButton = ({
|
56
69
|
'aria-label': ariaLabel,
|
package/lib/_TextInputWrapper.js
CHANGED
@@ -39,7 +39,7 @@ const sizeVariants = (0, _styledSystem.variant)({
|
|
39
39
|
const TextInputWrapper = _styledComponents.default.span.withConfig({
|
40
40
|
displayName: "_TextInputWrapper__TextInputWrapper",
|
41
41
|
componentId: "sc-5vfcis-0"
|
42
|
-
})(["display:inline-flex;align-items:stretch;min-height:34px;font-size:", ";line-height:20px;color:", ";vertical-align:middle;background-repeat:no-repeat;background-position:right 8px center;border:1px solid ", ";border-radius:", ";outline:none;box-shadow:", ";
|
42
|
+
})(["display:inline-flex;align-items:stretch;min-height:34px;font-size:", ";line-height:20px;color:", ";vertical-align:middle;background-repeat:no-repeat;background-position:right 8px center;border:1px solid ", ";border-radius:", ";outline:none;box-shadow:", ";", " .TextInput-icon{align-self:center;color:", ";margin:0 ", ";flex-shrink:0;}&:focus-within{border-color:", ";box-shadow:", ";}", " ", " ", " @media (min-width:", "){font-size:", ";}", " ", " ", " ", " ", ";"], (0, _constants.get)('fontSizes.1'), (0, _constants.get)('colors.fg.default'), (0, _constants.get)('colors.border.default'), (0, _constants.get)('radii.2'), (0, _constants.get)('shadows.primer.shadow.inset'), props => {
|
43
43
|
if (props.hasIcon) {
|
44
44
|
return (0, _styledComponents.css)(["padding:0;"]);
|
45
45
|
} else {
|
@@ -32,10 +32,6 @@ declare const TextInputWithTokens: React.ForwardRefExoticComponent<Pick<{
|
|
32
32
|
* Whether the remove buttons should be rendered in the tokens
|
33
33
|
*/
|
34
34
|
hideTokenRemoveButtons?: boolean | undefined;
|
35
|
-
/**
|
36
|
-
* The number of tokens to display before truncating
|
37
|
-
*/
|
38
|
-
visibleTokenCount?: number | undefined;
|
39
35
|
} & Pick<Omit<Pick<{
|
40
36
|
[x: string]: any;
|
41
37
|
[x: number]: any;
|
@@ -10,15 +10,9 @@ import { useProvidedRefOrCreate } from './hooks';
|
|
10
10
|
import UnstyledTextInput from './_UnstyledTextInput';
|
11
11
|
import TextInputWrapper from './_TextInputWrapper';
|
12
12
|
import Box from './Box';
|
13
|
-
import
|
14
|
-
|
15
|
-
const overflowCountFontSizeMap = {
|
16
|
-
small: 0,
|
17
|
-
medium: 1,
|
18
|
-
large: 1,
|
19
|
-
extralarge: 2
|
20
|
-
}; // using forwardRef is important so that other components (ex. Autocomplete) can use the ref
|
13
|
+
import { isFocusable } from './utils/iterateFocusableElements'; // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
21
14
|
|
15
|
+
// using forwardRef is important so that other components (ex. Autocomplete) can use the ref
|
22
16
|
function TextInputWithTokensInnerComponent({
|
23
17
|
icon: IconComponent,
|
24
18
|
contrast,
|
@@ -38,11 +32,9 @@ function TextInputWithTokensInnerComponent({
|
|
38
32
|
minWidth: minWidthProp,
|
39
33
|
maxWidth: maxWidthProp,
|
40
34
|
variant: variantProp,
|
41
|
-
visibleTokenCount,
|
42
35
|
...rest
|
43
36
|
}, externalRef) {
|
44
37
|
const {
|
45
|
-
onBlur,
|
46
38
|
onFocus,
|
47
39
|
onKeyDown,
|
48
40
|
...inputPropsRest
|
@@ -51,7 +43,6 @@ function TextInputWithTokensInnerComponent({
|
|
51
43
|
const localInputRef = useRef(null);
|
52
44
|
const combinedInputRef = useCombinedRefs(localInputRef, ref);
|
53
45
|
const [selectedTokenIndex, setSelectedTokenIndex] = useState();
|
54
|
-
const [tokensAreTruncated, setTokensAreTruncated] = useState(Boolean(visibleTokenCount));
|
55
46
|
const {
|
56
47
|
containerRef
|
57
48
|
} = useFocusZone({
|
@@ -86,70 +77,56 @@ function TextInputWithTokensInnerComponent({
|
|
86
77
|
}, [selectedTokenIndex]);
|
87
78
|
|
88
79
|
const handleTokenRemove = tokenId => {
|
89
|
-
onTokenRemove(tokenId);
|
90
|
-
|
91
|
-
if (selectedTokenIndex) {
|
92
|
-
var _containerRef$current2;
|
80
|
+
onTokenRemove(tokenId); // HACK: wait a tick for the the token node to be removed from the DOM
|
93
81
|
|
94
|
-
|
95
|
-
|
96
|
-
}
|
97
|
-
};
|
82
|
+
setTimeout(() => {
|
83
|
+
var _containerRef$current2, _containerRef$current3;
|
98
84
|
|
99
|
-
|
100
|
-
|
101
|
-
};
|
85
|
+
const nextElementToFocus = (_containerRef$current2 = containerRef.current) === null || _containerRef$current2 === void 0 ? void 0 : _containerRef$current2.children[selectedTokenIndex || 0]; // when removing the first token by keying "Backspace" or "Delete",
|
86
|
+
// `nextFocusableElement` is the div that wraps the input
|
102
87
|
|
103
|
-
|
104
|
-
setSelectedTokenIndex(undefined); // HACK: wait a tick and check the focused element before hiding truncated tokens
|
105
|
-
// this prevents the tokens from hiding when the user is moving focus between tokens,
|
106
|
-
// but still hides the tokens when the user blurs the token by tabbing out or clicking somewhere else on the page
|
88
|
+
const firstFocusable = nextElementToFocus && isFocusable(nextElementToFocus) ? nextElementToFocus : Array.from(((_containerRef$current3 = containerRef.current) === null || _containerRef$current3 === void 0 ? void 0 : _containerRef$current3.children) || []).find(el => isFocusable(el));
|
107
89
|
|
108
|
-
|
109
|
-
|
90
|
+
if (firstFocusable) {
|
91
|
+
firstFocusable.focus();
|
92
|
+
} else {
|
93
|
+
var _ref$current;
|
110
94
|
|
111
|
-
|
112
|
-
|
95
|
+
// if there are no tokens left, focus the input
|
96
|
+
(_ref$current = ref.current) === null || _ref$current === void 0 ? void 0 : _ref$current.focus();
|
113
97
|
}
|
114
98
|
}, 0);
|
115
99
|
};
|
116
100
|
|
117
|
-
const
|
118
|
-
|
119
|
-
var _ref$current;
|
120
|
-
|
121
|
-
(_ref$current = ref.current) === null || _ref$current === void 0 ? void 0 : _ref$current.focus();
|
122
|
-
}
|
101
|
+
const handleTokenFocus = tokenIndex => () => {
|
102
|
+
setSelectedTokenIndex(tokenIndex);
|
123
103
|
};
|
124
104
|
|
125
|
-
const
|
126
|
-
onFocus && onFocus(event);
|
105
|
+
const handleTokenBlur = () => {
|
127
106
|
setSelectedTokenIndex(undefined);
|
128
|
-
visibleTokenCount && setTokensAreTruncated(false);
|
129
107
|
};
|
130
108
|
|
131
|
-
const
|
132
|
-
|
133
|
-
|
134
|
-
// but still hides the tokens when the user blurs the input by tabbing out or clicking somewhere else on the page
|
109
|
+
const handleTokenKeyUp = e => {
|
110
|
+
if (e.key === 'Escape') {
|
111
|
+
var _ref$current2;
|
135
112
|
|
136
|
-
|
137
|
-
|
113
|
+
(_ref$current2 = ref.current) === null || _ref$current2 === void 0 ? void 0 : _ref$current2.focus();
|
114
|
+
}
|
115
|
+
};
|
138
116
|
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
}, 0);
|
117
|
+
const handleInputFocus = e => {
|
118
|
+
onFocus && onFocus(e);
|
119
|
+
setSelectedTokenIndex(undefined);
|
143
120
|
};
|
144
121
|
|
145
122
|
const handleInputKeyDown = e => {
|
146
|
-
var _ref$
|
123
|
+
var _ref$current3;
|
147
124
|
|
148
125
|
if (onKeyDown) {
|
149
126
|
onKeyDown(e);
|
150
127
|
}
|
151
128
|
|
152
|
-
if ((_ref$
|
129
|
+
if ((_ref$current3 = ref.current) !== null && _ref$current3 !== void 0 && _ref$current3.value) {
|
153
130
|
return;
|
154
131
|
}
|
155
132
|
|
@@ -170,24 +147,13 @@ function TextInputWithTokensInnerComponent({
|
|
170
147
|
|
171
148
|
|
172
149
|
setTimeout(() => {
|
173
|
-
var _ref$
|
150
|
+
var _ref$current4;
|
174
151
|
|
175
|
-
(_ref$
|
152
|
+
(_ref$current4 = ref.current) === null || _ref$current4 === void 0 ? void 0 : _ref$current4.select();
|
176
153
|
}, 0);
|
177
154
|
}
|
178
155
|
};
|
179
156
|
|
180
|
-
const focusInput = () => {
|
181
|
-
var _combinedInputRef$cur;
|
182
|
-
|
183
|
-
(_combinedInputRef$cur = combinedInputRef.current) === null || _combinedInputRef$cur === void 0 ? void 0 : _combinedInputRef$cur.focus();
|
184
|
-
};
|
185
|
-
|
186
|
-
const preventTokenClickPropagation = event => {
|
187
|
-
event.stopPropagation();
|
188
|
-
};
|
189
|
-
|
190
|
-
const visibleTokens = tokensAreTruncated ? tokens.slice(0, visibleTokenCount) : tokens;
|
191
157
|
return /*#__PURE__*/React.createElement(TextInputWrapper, {
|
192
158
|
block: block,
|
193
159
|
className: className,
|
@@ -199,16 +165,7 @@ function TextInputWithTokensInnerComponent({
|
|
199
165
|
minWidth: minWidthProp,
|
200
166
|
maxWidth: maxWidthProp,
|
201
167
|
variant: variantProp,
|
202
|
-
|
203
|
-
onClick: focusInput,
|
204
|
-
sx: {
|
205
|
-
alignItems: 'center',
|
206
|
-
flexWrap: preventTokenWrapping ? 'nowrap' : 'wrap',
|
207
|
-
gap: '0.25rem',
|
208
|
-
'> *': {
|
209
|
-
flexShrink: 0
|
210
|
-
},
|
211
|
-
...(block ? {
|
168
|
+
sx: { ...(block ? {
|
212
169
|
display: 'flex',
|
213
170
|
width: '100%'
|
214
171
|
} : {}),
|
@@ -221,6 +178,21 @@ function TextInputWithTokensInnerComponent({
|
|
221
178
|
} : {}),
|
222
179
|
...sxProp
|
223
180
|
}
|
181
|
+
}, /*#__PURE__*/React.createElement(Box, {
|
182
|
+
ref: containerRef,
|
183
|
+
display: "flex",
|
184
|
+
sx: {
|
185
|
+
alignItems: 'center',
|
186
|
+
flexWrap: preventTokenWrapping ? 'nowrap' : 'wrap',
|
187
|
+
marginLeft: '-0.25rem',
|
188
|
+
marginBottom: '-0.25rem',
|
189
|
+
flexGrow: 1,
|
190
|
+
'> *': {
|
191
|
+
flexShrink: 0,
|
192
|
+
marginLeft: '0.25rem',
|
193
|
+
marginBottom: '0.25rem'
|
194
|
+
}
|
195
|
+
}
|
224
196
|
}, /*#__PURE__*/React.createElement(Box, {
|
225
197
|
sx: {
|
226
198
|
order: 1,
|
@@ -232,13 +204,12 @@ function TextInputWithTokensInnerComponent({
|
|
232
204
|
ref: combinedInputRef,
|
233
205
|
disabled: disabled,
|
234
206
|
onFocus: handleInputFocus,
|
235
|
-
onBlur: handleInputBlur,
|
236
207
|
onKeyDown: handleInputKeyDown,
|
237
208
|
type: "text",
|
238
209
|
sx: {
|
239
210
|
height: '100%'
|
240
211
|
}
|
241
|
-
}, inputPropsRest))), TokenComponent ?
|
212
|
+
}, inputPropsRest))), tokens.length && TokenComponent ? tokens.map(({
|
242
213
|
id,
|
243
214
|
...tokenRest
|
244
215
|
}, i) => /*#__PURE__*/React.createElement(TokenComponent, _extends({
|
@@ -246,7 +217,6 @@ function TextInputWithTokensInnerComponent({
|
|
246
217
|
onFocus: handleTokenFocus(i),
|
247
218
|
onBlur: handleTokenBlur,
|
248
219
|
onKeyUp: handleTokenKeyUp,
|
249
|
-
onClick: preventTokenClickPropagation,
|
250
220
|
isSelected: selectedTokenIndex === i,
|
251
221
|
onRemove: () => {
|
252
222
|
handleTokenRemove(id);
|
@@ -254,10 +224,7 @@ function TextInputWithTokensInnerComponent({
|
|
254
224
|
hideRemoveButton: hideTokenRemoveButtons,
|
255
225
|
size: size,
|
256
226
|
tabIndex: 0
|
257
|
-
}, tokenRest))) : null
|
258
|
-
color: "fg.muted",
|
259
|
-
fontSize: size && overflowCountFontSizeMap[size]
|
260
|
-
}, "+", tokens.length - visibleTokens.length) : null);
|
227
|
+
}, tokenRest))) : null));
|
261
228
|
}
|
262
229
|
|
263
230
|
TextInputWithTokensInnerComponent.displayName = "TextInputWithTokensInnerComponent";
|
package/lib-esm/Token/Token.js
CHANGED
@@ -19,7 +19,16 @@ const DefaultTokenStyled = styled(TokenBase).withConfig({
|
|
19
19
|
const LeadingVisualContainer = styled('span').withConfig({
|
20
20
|
displayName: "Token__LeadingVisualContainer",
|
21
21
|
componentId: "sc-1dg52pw-1"
|
22
|
-
})(["flex-shrink:0;line-height:0;"]
|
22
|
+
})(["flex-shrink:0;line-height:0;", ""], props => {
|
23
|
+
switch (props.size) {
|
24
|
+
case 'large':
|
25
|
+
case 'extralarge':
|
26
|
+
return css(["margin-right:", ";"], get('space.2'));
|
27
|
+
|
28
|
+
default:
|
29
|
+
return css(["margin-right:", ";"], get('space.1'));
|
30
|
+
}
|
31
|
+
});
|
23
32
|
const Token = /*#__PURE__*/forwardRef((props, forwardedRef) => {
|
24
33
|
const {
|
25
34
|
as,
|
@@ -54,7 +63,9 @@ const Token = /*#__PURE__*/forwardRef((props, forwardedRef) => {
|
|
54
63
|
isTokenInteractive: isTokenInteractive(props)
|
55
64
|
}, !hasMultipleActionTargets ? interactiveTokenProps : {}, rest, {
|
56
65
|
ref: forwardedRef
|
57
|
-
}), LeadingVisual ? /*#__PURE__*/React.createElement(LeadingVisualContainer,
|
66
|
+
}), LeadingVisual ? /*#__PURE__*/React.createElement(LeadingVisualContainer, {
|
67
|
+
size: size
|
68
|
+
}, /*#__PURE__*/React.createElement(LeadingVisual, null)) : null, /*#__PURE__*/React.createElement(TokenTextContainer, hasMultipleActionTargets ? interactiveTokenProps : {}, text), !hideRemoveButton && onRemove ? /*#__PURE__*/React.createElement(RemoveTokenButton, {
|
58
69
|
borderOffset: tokenBorderWidthPx,
|
59
70
|
onClick: onRemoveClick,
|
60
71
|
size: size,
|