@primer/components 0.0.0-202192718387 → 0.0.0-2021927193941

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.
@@ -32,6 +32,10 @@ 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;
35
39
  } & Pick<Omit<Pick<{
36
40
  [x: string]: any;
37
41
  [x: number]: any;
@@ -25,6 +25,8 @@ var _TextInputWrapper = _interopRequireDefault(require("./_TextInputWrapper"));
25
25
 
26
26
  var _Box = _interopRequireDefault(require("./Box"));
27
27
 
28
+ var _Text = _interopRequireDefault(require("./Text"));
29
+
28
30
  var _iterateFocusableElements = require("./utils/iterateFocusableElements");
29
31
 
30
32
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
@@ -35,7 +37,13 @@ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj &&
35
37
 
36
38
  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
39
 
38
- // using forwardRef is important so that other components (ex. Autocomplete) can use the ref
40
+ const overflowCountFontSizeMap = {
41
+ small: 0,
42
+ medium: 1,
43
+ large: 1,
44
+ extralarge: 2
45
+ }; // using forwardRef is important so that other components (ex. Autocomplete) can use the ref
46
+
39
47
  function TextInputWithTokensInnerComponent({
40
48
  icon: IconComponent,
41
49
  contrast,
@@ -55,9 +63,11 @@ function TextInputWithTokensInnerComponent({
55
63
  minWidth: minWidthProp,
56
64
  maxWidth: maxWidthProp,
57
65
  variant: variantProp,
66
+ visibleTokenCount,
58
67
  ...rest
59
68
  }, externalRef) {
60
69
  const {
70
+ onBlur,
61
71
  onFocus,
62
72
  onKeyDown,
63
73
  ...inputPropsRest
@@ -66,6 +76,7 @@ function TextInputWithTokensInnerComponent({
66
76
  const localInputRef = (0, _react.useRef)(null);
67
77
  const combinedInputRef = (0, _useCombinedRefs.useCombinedRefs)(localInputRef, ref);
68
78
  const [selectedTokenIndex, setSelectedTokenIndex] = (0, _react.useState)();
79
+ const [tokensAreTruncated, setTokensAreTruncated] = (0, _react.useState)(Boolean(visibleTokenCount));
69
80
  const {
70
81
  containerRef
71
82
  } = (0, _useFocusZone.useFocusZone)({
@@ -126,20 +137,45 @@ function TextInputWithTokensInnerComponent({
126
137
  };
127
138
 
128
139
  const handleTokenBlur = () => {
129
- setSelectedTokenIndex(undefined);
140
+ setSelectedTokenIndex(undefined); // HACK: wait a tick and check the focused element before hiding truncated tokens
141
+ // this prevents the tokens from hiding when the user is moving focus between tokens,
142
+ // but still hides the tokens when the user blurs the token by tabbing out or clicking somewhere else on the page
143
+
144
+ setTimeout(() => {
145
+ var _containerRef$current4;
146
+
147
+ if (!((_containerRef$current4 = containerRef.current) !== null && _containerRef$current4 !== void 0 && _containerRef$current4.contains(document.activeElement)) && visibleTokenCount) {
148
+ setTokensAreTruncated(true);
149
+ }
150
+ }, 0);
130
151
  };
131
152
 
132
- const handleTokenKeyUp = e => {
133
- if (e.key === 'Escape') {
153
+ const handleTokenKeyUp = event => {
154
+ if (event.key === 'Escape') {
134
155
  var _ref$current2;
135
156
 
136
157
  (_ref$current2 = ref.current) === null || _ref$current2 === void 0 ? void 0 : _ref$current2.focus();
137
158
  }
138
159
  };
139
160
 
140
- const handleInputFocus = e => {
141
- onFocus && onFocus(e);
161
+ const handleInputFocus = event => {
162
+ onFocus && onFocus(event);
142
163
  setSelectedTokenIndex(undefined);
164
+ visibleTokenCount && setTokensAreTruncated(false);
165
+ };
166
+
167
+ const handleInputBlur = event => {
168
+ onBlur && onBlur(event); // HACK: wait a tick and check the focused element before hiding truncated tokens
169
+ // this prevents the tokens from hiding when the user is moving focus from the input to a token,
170
+ // but still hides the tokens when the user blurs the input by tabbing out or clicking somewhere else on the page
171
+
172
+ setTimeout(() => {
173
+ var _containerRef$current5;
174
+
175
+ if (!((_containerRef$current5 = containerRef.current) !== null && _containerRef$current5 !== void 0 && _containerRef$current5.contains(document.activeElement)) && visibleTokenCount) {
176
+ setTokensAreTruncated(true);
177
+ }
178
+ }, 0);
143
179
  };
144
180
 
145
181
  const handleInputKeyDown = e => {
@@ -177,6 +213,17 @@ function TextInputWithTokensInnerComponent({
177
213
  }
178
214
  };
179
215
 
216
+ const focusInput = () => {
217
+ var _combinedInputRef$cur;
218
+
219
+ (_combinedInputRef$cur = combinedInputRef.current) === null || _combinedInputRef$cur === void 0 ? void 0 : _combinedInputRef$cur.focus();
220
+ };
221
+
222
+ const preventTokenClickPropagation = event => {
223
+ event.stopPropagation();
224
+ };
225
+
226
+ const visibleTokens = tokensAreTruncated ? tokens.slice(0, visibleTokenCount) : tokens;
180
227
  return /*#__PURE__*/_react.default.createElement(_TextInputWrapper.default, {
181
228
  block: block,
182
229
  className: className,
@@ -188,15 +235,8 @@ function TextInputWithTokensInnerComponent({
188
235
  minWidth: minWidthProp,
189
236
  maxWidth: maxWidthProp,
190
237
  variant: variantProp,
191
- ref: containerRef,
192
- sx: {
193
- alignItems: 'center',
194
- flexWrap: preventTokenWrapping ? 'nowrap' : 'wrap',
195
- gap: '0.25rem',
196
- '> *': {
197
- flexShrink: 0
198
- },
199
- ...(block ? {
238
+ onClick: focusInput,
239
+ sx: { ...(block ? {
200
240
  display: 'flex',
201
241
  width: '100%'
202
242
  } : {}),
@@ -209,6 +249,21 @@ function TextInputWithTokensInnerComponent({
209
249
  } : {}),
210
250
  ...sxProp
211
251
  }
252
+ }, /*#__PURE__*/_react.default.createElement(_Box.default, {
253
+ ref: containerRef,
254
+ display: "flex",
255
+ sx: {
256
+ alignItems: 'center',
257
+ flexWrap: preventTokenWrapping ? 'nowrap' : 'wrap',
258
+ marginLeft: '-0.25rem',
259
+ marginBottom: '-0.25rem',
260
+ flexGrow: 1,
261
+ '> *': {
262
+ flexShrink: 0,
263
+ marginLeft: '0.25rem',
264
+ marginBottom: '0.25rem'
265
+ }
266
+ }
212
267
  }, /*#__PURE__*/_react.default.createElement(_Box.default, {
213
268
  sx: {
214
269
  order: 1,
@@ -220,12 +275,13 @@ function TextInputWithTokensInnerComponent({
220
275
  ref: combinedInputRef,
221
276
  disabled: disabled,
222
277
  onFocus: handleInputFocus,
278
+ onBlur: handleInputBlur,
223
279
  onKeyDown: handleInputKeyDown,
224
280
  type: "text",
225
281
  sx: {
226
282
  height: '100%'
227
283
  }
228
- }, inputPropsRest))), tokens.length && TokenComponent ? tokens.map(({
284
+ }, inputPropsRest))), TokenComponent ? visibleTokens.map(({
229
285
  id,
230
286
  ...tokenRest
231
287
  }, i) => /*#__PURE__*/_react.default.createElement(TokenComponent, _extends({
@@ -233,6 +289,7 @@ function TextInputWithTokensInnerComponent({
233
289
  onFocus: handleTokenFocus(i),
234
290
  onBlur: handleTokenBlur,
235
291
  onKeyUp: handleTokenKeyUp,
292
+ onClick: preventTokenClickPropagation,
236
293
  isSelected: selectedTokenIndex === i,
237
294
  onRemove: () => {
238
295
  handleTokenRemove(id);
@@ -240,7 +297,10 @@ function TextInputWithTokensInnerComponent({
240
297
  hideRemoveButton: hideTokenRemoveButtons,
241
298
  size: size,
242
299
  tabIndex: 0
243
- }, tokenRest))) : null);
300
+ }, tokenRest))) : null, tokensAreTruncated ? /*#__PURE__*/_react.default.createElement(_Text.default, {
301
+ color: "fg.muted",
302
+ fontSize: size && overflowCountFontSizeMap[size]
303
+ }, "+", tokens.length - visibleTokens.length) : null));
244
304
  }
245
305
 
246
306
  TextInputWithTokensInnerComponent.displayName = "TextInputWithTokensInnerComponent";
@@ -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, null, /*#__PURE__*/_react.default.createElement(LeadingVisual, null)) : null, /*#__PURE__*/_react.default.createElement(_TokenTextContainer.default, hasMultipleActionTargets ? interactiveTokenProps : {}, text), !hideRemoveButton && onRemove ? /*#__PURE__*/_react.default.createElement(_RemoveTokenButton.default, {
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,
@@ -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 = _interopRequireDefault(require("styled-components"));
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;&:hover,&:focus{background-color:", ";}&:active{background-color:", ";}", " ", ""], props => `translate(${props.borderOffset}px, -${props.borderOffset}px)`, (0, _constants.get)('colors.neutral.muted'), (0, _constants.get)('colors.neutral.subtle'), variants, _sx.default);
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,
@@ -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:", ";", " .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 => {
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:", ";cursor:text;", " .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,6 +32,10 @@ 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;
35
39
  } & Pick<Omit<Pick<{
36
40
  [x: string]: any;
37
41
  [x: number]: any;
@@ -10,9 +10,16 @@ import { useProvidedRefOrCreate } from './hooks';
10
10
  import UnstyledTextInput from './_UnstyledTextInput';
11
11
  import TextInputWrapper from './_TextInputWrapper';
12
12
  import Box from './Box';
13
+ import Text from './Text';
13
14
  import { isFocusable } from './utils/iterateFocusableElements'; // eslint-disable-next-line @typescript-eslint/no-explicit-any
14
15
 
15
- // using forwardRef is important so that other components (ex. Autocomplete) can use the ref
16
+ const overflowCountFontSizeMap = {
17
+ small: 0,
18
+ medium: 1,
19
+ large: 1,
20
+ extralarge: 2
21
+ }; // using forwardRef is important so that other components (ex. Autocomplete) can use the ref
22
+
16
23
  function TextInputWithTokensInnerComponent({
17
24
  icon: IconComponent,
18
25
  contrast,
@@ -32,9 +39,11 @@ function TextInputWithTokensInnerComponent({
32
39
  minWidth: minWidthProp,
33
40
  maxWidth: maxWidthProp,
34
41
  variant: variantProp,
42
+ visibleTokenCount,
35
43
  ...rest
36
44
  }, externalRef) {
37
45
  const {
46
+ onBlur,
38
47
  onFocus,
39
48
  onKeyDown,
40
49
  ...inputPropsRest
@@ -43,6 +52,7 @@ function TextInputWithTokensInnerComponent({
43
52
  const localInputRef = useRef(null);
44
53
  const combinedInputRef = useCombinedRefs(localInputRef, ref);
45
54
  const [selectedTokenIndex, setSelectedTokenIndex] = useState();
55
+ const [tokensAreTruncated, setTokensAreTruncated] = useState(Boolean(visibleTokenCount));
46
56
  const {
47
57
  containerRef
48
58
  } = useFocusZone({
@@ -103,20 +113,45 @@ function TextInputWithTokensInnerComponent({
103
113
  };
104
114
 
105
115
  const handleTokenBlur = () => {
106
- setSelectedTokenIndex(undefined);
116
+ setSelectedTokenIndex(undefined); // HACK: wait a tick and check the focused element before hiding truncated tokens
117
+ // this prevents the tokens from hiding when the user is moving focus between tokens,
118
+ // but still hides the tokens when the user blurs the token by tabbing out or clicking somewhere else on the page
119
+
120
+ setTimeout(() => {
121
+ var _containerRef$current4;
122
+
123
+ if (!((_containerRef$current4 = containerRef.current) !== null && _containerRef$current4 !== void 0 && _containerRef$current4.contains(document.activeElement)) && visibleTokenCount) {
124
+ setTokensAreTruncated(true);
125
+ }
126
+ }, 0);
107
127
  };
108
128
 
109
- const handleTokenKeyUp = e => {
110
- if (e.key === 'Escape') {
129
+ const handleTokenKeyUp = event => {
130
+ if (event.key === 'Escape') {
111
131
  var _ref$current2;
112
132
 
113
133
  (_ref$current2 = ref.current) === null || _ref$current2 === void 0 ? void 0 : _ref$current2.focus();
114
134
  }
115
135
  };
116
136
 
117
- const handleInputFocus = e => {
118
- onFocus && onFocus(e);
137
+ const handleInputFocus = event => {
138
+ onFocus && onFocus(event);
119
139
  setSelectedTokenIndex(undefined);
140
+ visibleTokenCount && setTokensAreTruncated(false);
141
+ };
142
+
143
+ const handleInputBlur = event => {
144
+ onBlur && onBlur(event); // HACK: wait a tick and check the focused element before hiding truncated tokens
145
+ // this prevents the tokens from hiding when the user is moving focus from the input to a token,
146
+ // but still hides the tokens when the user blurs the input by tabbing out or clicking somewhere else on the page
147
+
148
+ setTimeout(() => {
149
+ var _containerRef$current5;
150
+
151
+ if (!((_containerRef$current5 = containerRef.current) !== null && _containerRef$current5 !== void 0 && _containerRef$current5.contains(document.activeElement)) && visibleTokenCount) {
152
+ setTokensAreTruncated(true);
153
+ }
154
+ }, 0);
120
155
  };
121
156
 
122
157
  const handleInputKeyDown = e => {
@@ -154,6 +189,17 @@ function TextInputWithTokensInnerComponent({
154
189
  }
155
190
  };
156
191
 
192
+ const focusInput = () => {
193
+ var _combinedInputRef$cur;
194
+
195
+ (_combinedInputRef$cur = combinedInputRef.current) === null || _combinedInputRef$cur === void 0 ? void 0 : _combinedInputRef$cur.focus();
196
+ };
197
+
198
+ const preventTokenClickPropagation = event => {
199
+ event.stopPropagation();
200
+ };
201
+
202
+ const visibleTokens = tokensAreTruncated ? tokens.slice(0, visibleTokenCount) : tokens;
157
203
  return /*#__PURE__*/React.createElement(TextInputWrapper, {
158
204
  block: block,
159
205
  className: className,
@@ -165,15 +211,8 @@ function TextInputWithTokensInnerComponent({
165
211
  minWidth: minWidthProp,
166
212
  maxWidth: maxWidthProp,
167
213
  variant: variantProp,
168
- ref: containerRef,
169
- sx: {
170
- alignItems: 'center',
171
- flexWrap: preventTokenWrapping ? 'nowrap' : 'wrap',
172
- gap: '0.25rem',
173
- '> *': {
174
- flexShrink: 0
175
- },
176
- ...(block ? {
214
+ onClick: focusInput,
215
+ sx: { ...(block ? {
177
216
  display: 'flex',
178
217
  width: '100%'
179
218
  } : {}),
@@ -186,6 +225,21 @@ function TextInputWithTokensInnerComponent({
186
225
  } : {}),
187
226
  ...sxProp
188
227
  }
228
+ }, /*#__PURE__*/React.createElement(Box, {
229
+ ref: containerRef,
230
+ display: "flex",
231
+ sx: {
232
+ alignItems: 'center',
233
+ flexWrap: preventTokenWrapping ? 'nowrap' : 'wrap',
234
+ marginLeft: '-0.25rem',
235
+ marginBottom: '-0.25rem',
236
+ flexGrow: 1,
237
+ '> *': {
238
+ flexShrink: 0,
239
+ marginLeft: '0.25rem',
240
+ marginBottom: '0.25rem'
241
+ }
242
+ }
189
243
  }, /*#__PURE__*/React.createElement(Box, {
190
244
  sx: {
191
245
  order: 1,
@@ -197,12 +251,13 @@ function TextInputWithTokensInnerComponent({
197
251
  ref: combinedInputRef,
198
252
  disabled: disabled,
199
253
  onFocus: handleInputFocus,
254
+ onBlur: handleInputBlur,
200
255
  onKeyDown: handleInputKeyDown,
201
256
  type: "text",
202
257
  sx: {
203
258
  height: '100%'
204
259
  }
205
- }, inputPropsRest))), tokens.length && TokenComponent ? tokens.map(({
260
+ }, inputPropsRest))), TokenComponent ? visibleTokens.map(({
206
261
  id,
207
262
  ...tokenRest
208
263
  }, i) => /*#__PURE__*/React.createElement(TokenComponent, _extends({
@@ -210,6 +265,7 @@ function TextInputWithTokensInnerComponent({
210
265
  onFocus: handleTokenFocus(i),
211
266
  onBlur: handleTokenBlur,
212
267
  onKeyUp: handleTokenKeyUp,
268
+ onClick: preventTokenClickPropagation,
213
269
  isSelected: selectedTokenIndex === i,
214
270
  onRemove: () => {
215
271
  handleTokenRemove(id);
@@ -217,7 +273,10 @@ function TextInputWithTokensInnerComponent({
217
273
  hideRemoveButton: hideTokenRemoveButtons,
218
274
  size: size,
219
275
  tabIndex: 0
220
- }, tokenRest))) : null);
276
+ }, tokenRest))) : null, tokensAreTruncated ? /*#__PURE__*/React.createElement(Text, {
277
+ color: "fg.muted",
278
+ fontSize: size && overflowCountFontSizeMap[size]
279
+ }, "+", tokens.length - visibleTokens.length) : null));
221
280
  }
222
281
 
223
282
  TextInputWithTokensInnerComponent.displayName = "TextInputWithTokensInnerComponent";
@@ -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, null, /*#__PURE__*/React.createElement(LeadingVisual, null)) : null, /*#__PURE__*/React.createElement(TokenTextContainer, hasMultipleActionTargets ? interactiveTokenProps : {}, text), !hideRemoveButton && onRemove ? /*#__PURE__*/React.createElement(RemoveTokenButton, {
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,
@@ -20,7 +20,6 @@ const variants = variant({
20
20
  variants: {
21
21
  small: {
22
22
  fontSize: 0,
23
- gap: 1,
24
23
  height: tokenSizes.small,
25
24
  // without setting lineHeight to match height, the "x" appears vertically mis-aligned
26
25
  lineHeight: tokenSizes.small,
@@ -33,7 +32,6 @@ const variants = variant({
33
32
  },
34
33
  medium: {
35
34
  fontSize: 0,
36
- gap: 1,
37
35
  height: tokenSizes.medium,
38
36
  lineHeight: tokenSizes.medium,
39
37
  paddingLeft: 2,
@@ -43,7 +41,6 @@ const variants = variant({
43
41
  },
44
42
  large: {
45
43
  fontSize: 0,
46
- gap: 2,
47
44
  height: tokenSizes.large,
48
45
  lineHeight: tokenSizes.large,
49
46
  paddingLeft: 2,
@@ -53,7 +50,6 @@ const variants = variant({
53
50
  },
54
51
  extralarge: {
55
52
  fontSize: 1,
56
- gap: 2,
57
53
  height: tokenSizes.extralarge,
58
54
  lineHeight: tokenSizes.extralarge,
59
55
  paddingLeft: 3,
@@ -2,7 +2,7 @@ function _extends() { _extends = Object.assign || function (target) { for (var i
2
2
 
3
3
  import React from 'react';
4
4
  import { XIcon } from '@primer/octicons-react';
5
- import styled from 'styled-components';
5
+ import styled, { css } from 'styled-components';
6
6
  import { variant } from 'styled-system';
7
7
  import { get } from '../constants';
8
8
  import sx from '../sx';
@@ -34,7 +34,16 @@ const getTokenButtonIconSize = size => parseInt(tokenSizes[size || defaultTokenS
34
34
  const StyledTokenButton = styled.span.withConfig({
35
35
  displayName: "_RemoveTokenButton__StyledTokenButton",
36
36
  componentId: "sc-14lvcw1-0"
37
- })(["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)`, get('colors.neutral.muted'), get('colors.neutral.subtle'), variants, sx);
37
+ })(["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 => {
38
+ switch (props.size) {
39
+ case 'large':
40
+ case 'extralarge':
41
+ return css(["margin-left:", ";"], get('space.2'));
42
+
43
+ default:
44
+ return css(["margin-left:", ";"], get('space.1'));
45
+ }
46
+ }, get('colors.neutral.muted'), get('colors.neutral.subtle'), variants, sx);
38
47
 
39
48
  const RemoveTokenButton = ({
40
49
  'aria-label': ariaLabel,
@@ -21,7 +21,7 @@ const sizeVariants = variant({
21
21
  const TextInputWrapper = styled.span.withConfig({
22
22
  displayName: "_TextInputWrapper__TextInputWrapper",
23
23
  componentId: "sc-5vfcis-0"
24
- })(["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:", ";}", " ", " ", " ", " ", ";"], get('fontSizes.1'), get('colors.fg.default'), get('colors.border.default'), get('radii.2'), get('shadows.primer.shadow.inset'), props => {
24
+ })(["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:", ";cursor:text;", " .TextInput-icon{align-self:center;color:", ";margin:0 ", ";flex-shrink:0;}&:focus-within{border-color:", ";box-shadow:", ";}", " ", " ", " @media (min-width:", "){font-size:", ";}", " ", " ", " ", " ", ";"], get('fontSizes.1'), get('colors.fg.default'), get('colors.border.default'), get('radii.2'), get('shadows.primer.shadow.inset'), props => {
25
25
  if (props.hasIcon) {
26
26
  return css(["padding:0;"]);
27
27
  } else {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@primer/components",
3
- "version": "0.0.0-202192718387",
3
+ "version": "0.0.0-2021927193941",
4
4
  "description": "Primer react components",
5
5
  "main": "lib/index.js",
6
6
  "module": "lib-esm/index.js",
@@ -132,6 +132,7 @@
132
132
  "rollup-plugin-visualizer": "5.5.0",
133
133
  "semver": "7.3.5",
134
134
  "size-limit": "5.0.2",
135
+ "storybook-addon-performance": "0.16.1",
135
136
  "styled-components": "4.4.1",
136
137
  "typescript": "4.2.2"
137
138
  },