@primer/components 0.0.0-202197123143 → 0.0.0-20219715822

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.
@@ -0,0 +1,244 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+
8
+ var _react = _interopRequireWildcard(require("react"));
9
+
10
+ var _props = require("@styled-system/props");
11
+
12
+ var _styledComponents = _interopRequireDefault(require("styled-components"));
13
+
14
+ var _focusZone = require("./behaviors/focusZone");
15
+
16
+ var _useCombinedRefs = require("./hooks/useCombinedRefs");
17
+
18
+ var _useFocusZone = require("./hooks/useFocusZone");
19
+
20
+ var _Token = _interopRequireDefault(require("./Token/Token"));
21
+
22
+ var _TextInput = _interopRequireDefault(require("./TextInput"));
23
+
24
+ var _hooks = require("./hooks");
25
+
26
+ var _UnstyledTextInput = _interopRequireDefault(require("./_UnstyledTextInput"));
27
+
28
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
29
+
30
+ 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); }
31
+
32
+ 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; }
33
+
34
+ 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); }
35
+
36
+ const InputWrapper = _styledComponents.default.div.withConfig({
37
+ displayName: "TextInputWithTokens__InputWrapper",
38
+ componentId: "sc-8z94t5-0"
39
+ })(["order:1;flex-grow:1;"]); // eslint-disable-next-line @typescript-eslint/no-explicit-any
40
+
41
+
42
+ // The inner contents of `TextInputWithTokens` are separated so they may be passed to the `as`
43
+ // prop of the `TextInput` component
44
+ function TextInputWithTokensInnerComponent({
45
+ tokens,
46
+ onTokenRemove,
47
+ tokenComponent: TokenComponent,
48
+ size,
49
+ hideTokenRemoveButtons,
50
+ selectedTokenIndex,
51
+ setSelectedTokenIndex,
52
+ ...rest
53
+ }, externalRef) {
54
+ const ref = (0, _hooks.useProvidedRefOrCreate)(externalRef);
55
+ const {
56
+ onFocus,
57
+ onKeyDown,
58
+ ...inputPropsRest
59
+ } = (0, _props.omit)(rest);
60
+
61
+ const handleTokenFocus = tokenIndex => () => {
62
+ setSelectedTokenIndex(tokenIndex);
63
+ };
64
+
65
+ const handleTokenBlur = () => {
66
+ setSelectedTokenIndex(undefined);
67
+ };
68
+
69
+ const handleTokenKeyUp = event => {
70
+ if (event.key === 'Escape') {
71
+ var _ref$current;
72
+
73
+ (_ref$current = ref.current) === null || _ref$current === void 0 ? void 0 : _ref$current.focus();
74
+ }
75
+ };
76
+
77
+ const handleInputFocus = event => {
78
+ onFocus && onFocus(event);
79
+ setSelectedTokenIndex(undefined);
80
+ };
81
+
82
+ const handleInputKeyDown = event => {
83
+ var _ref$current2;
84
+
85
+ if (onKeyDown) {
86
+ onKeyDown(event);
87
+ }
88
+
89
+ if ((_ref$current2 = ref.current) !== null && _ref$current2 !== void 0 && _ref$current2.value) {
90
+ return;
91
+ }
92
+
93
+ const lastToken = tokens[tokens.length - 1];
94
+
95
+ if (event.key === 'Backspace' && lastToken) {
96
+ onTokenRemove(lastToken.id);
97
+
98
+ if (ref.current) {
99
+ // TODO: eliminate the first hack by making changes to the Autocomplete component
100
+ //
101
+ // HACKS:
102
+ // 1. Directly setting `ref.current.value` instead of updating state because the autocomplete
103
+ // highlight behavior doesn't work correctly if we update the value with a setState action in onChange
104
+ // 2. Adding an extra space so that when I backspace, it doesn't delete the last letter
105
+ ref.current.value = `${lastToken.text} `;
106
+ } // HACK: for some reason we need to wait a tick for `.select()` to work
107
+
108
+
109
+ setTimeout(() => {
110
+ var _ref$current3;
111
+
112
+ (_ref$current3 = ref.current) === null || _ref$current3 === void 0 ? void 0 : _ref$current3.select();
113
+ }, 0);
114
+ }
115
+ };
116
+
117
+ return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(InputWrapper, {
118
+ key: "inputWrapper"
119
+ }, /*#__PURE__*/_react.default.createElement(_UnstyledTextInput.default, _extends({
120
+ ref: ref,
121
+ onFocus: handleInputFocus,
122
+ onKeyDown: handleInputKeyDown,
123
+ type: "text",
124
+ sx: {
125
+ height: '100%'
126
+ }
127
+ }, inputPropsRest))), tokens.length && TokenComponent ? tokens.map(({
128
+ id,
129
+ ...tokenRest
130
+ }, i) => /*#__PURE__*/_react.default.createElement(TokenComponent, _extends({
131
+ key: id,
132
+ onFocus: handleTokenFocus(i),
133
+ onBlur: handleTokenBlur,
134
+ onKeyUp: handleTokenKeyUp,
135
+ isSelected: selectedTokenIndex === i,
136
+ onRemove: () => {
137
+ onTokenRemove(id);
138
+ },
139
+ hideRemoveButton: hideTokenRemoveButtons,
140
+ size: size,
141
+ tabIndex: 0
142
+ }, tokenRest))) : null);
143
+ } // using forwardRef is important so that other components (ex. Autocomplete) can use the ref
144
+
145
+
146
+ const TextInputWithTokensInnerComponentWithRef = /*#__PURE__*/_react.default.forwardRef(TextInputWithTokensInnerComponent);
147
+
148
+ function TextInputWithTokensComponent({
149
+ tokens,
150
+ onTokenRemove,
151
+ sx: sxProp,
152
+ ...props
153
+ }, ref) {
154
+ const localInputRef = (0, _react.useRef)(null);
155
+ const combinedInputRef = (0, _useCombinedRefs.useCombinedRefs)(localInputRef, ref);
156
+ const [selectedTokenIndex, setSelectedTokenIndex] = (0, _react.useState)();
157
+ const {
158
+ containerRef
159
+ } = (0, _useFocusZone.useFocusZone)({
160
+ focusOutBehavior: 'wrap',
161
+ bindKeys: _focusZone.FocusKeys.ArrowHorizontal | _focusZone.FocusKeys.HomeAndEnd,
162
+ focusableElementFilter: element => {
163
+ return !element.getAttributeNames().includes('aria-hidden');
164
+ },
165
+ getNextFocusable: direction => {
166
+ var _containerRef$current;
167
+
168
+ if (!selectedTokenIndex && selectedTokenIndex !== 0) {
169
+ return undefined;
170
+ }
171
+
172
+ let nextIndex = selectedTokenIndex + 1; // "+ 1" accounts for the first element: the text input
173
+
174
+ if (direction === 'next') {
175
+ nextIndex += 1;
176
+ }
177
+
178
+ if (direction === 'previous') {
179
+ nextIndex -= 1;
180
+ }
181
+
182
+ if (nextIndex > tokens.length || nextIndex < 1) {
183
+ return combinedInputRef.current || undefined;
184
+ }
185
+
186
+ return (_containerRef$current = containerRef.current) === null || _containerRef$current === void 0 ? void 0 : _containerRef$current.children[nextIndex];
187
+ }
188
+ }, [selectedTokenIndex]);
189
+
190
+ const handleTokenRemove = tokenId => {
191
+ onTokenRemove(tokenId);
192
+
193
+ if (selectedTokenIndex) {
194
+ var _containerRef$current2;
195
+
196
+ const nextElementToFocus = (_containerRef$current2 = containerRef.current) === null || _containerRef$current2 === void 0 ? void 0 : _containerRef$current2.children[selectedTokenIndex];
197
+ nextElementToFocus.focus();
198
+ }
199
+ };
200
+
201
+ return /*#__PURE__*/_react.default.createElement(_TextInput.default, _extends({
202
+ ref: combinedInputRef,
203
+ wrapperRef: containerRef,
204
+ as: TextInputWithTokensInnerComponentWithRef,
205
+ selectedTokenIndex: selectedTokenIndex,
206
+ setSelectedTokenIndex: setSelectedTokenIndex,
207
+ tokens: tokens,
208
+ onTokenRemove: handleTokenRemove,
209
+ sx: {
210
+ alignItems: 'center',
211
+ flexWrap: props.preventTokenWrapping ? 'nowrap' : 'wrap',
212
+ gap: '0.25rem',
213
+ '> *': {
214
+ flexShrink: 0
215
+ },
216
+ ...(props.block ? {
217
+ display: 'flex',
218
+ width: '100%'
219
+ } : {}),
220
+ ...(props.maxHeight ? {
221
+ maxHeight: props.maxHeight,
222
+ overflow: 'auto'
223
+ } : {}),
224
+ ...(props.preventTokenWrapping ? {
225
+ overflow: 'auto'
226
+ } : {}),
227
+ ...sxProp
228
+ }
229
+ }, props));
230
+ }
231
+
232
+ TextInputWithTokensComponent.displayName = "TextInputWithTokensComponent";
233
+
234
+ // using forwardRef is important so that other components (ex. Autocomplete) can use the ref
235
+ const TextInputWithTokens = /*#__PURE__*/_react.default.forwardRef(TextInputWithTokensComponent);
236
+
237
+ TextInputWithTokens.defaultProps = {
238
+ tokenComponent: _Token.default,
239
+ size: 'xlarge',
240
+ hideTokenRemoveButtons: false
241
+ };
242
+ TextInputWithTokens.displayName = 'TextInputWithTokens';
243
+ var _default = TextInputWithTokens;
244
+ exports.default = _default;
@@ -0,0 +1,2 @@
1
+ declare const UnstyledTextInput: import("styled-components").StyledComponent<"input", any, import("./sx").SxProp, never>;
2
+ export default UnstyledTextInput;
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+
8
+ var _styledComponents = _interopRequireDefault(require("styled-components"));
9
+
10
+ var _sx = _interopRequireDefault(require("./sx"));
11
+
12
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
13
+
14
+ const UnstyledTextInput = _styledComponents.default.input.withConfig({
15
+ displayName: "_UnstyledTextInput__UnstyledTextInput",
16
+ componentId: "sc-1jgl33s-0"
17
+ })(["border:0;font-size:inherit;font-family:inherit;background-color:transparent;-webkit-appearance:none;color:inherit;width:100%;&:focus{outline:0;}", ";"], _sx.default);
18
+
19
+ var _default = UnstyledTextInput;
20
+ exports.default = _default;
package/lib/index.d.ts CHANGED
@@ -98,6 +98,7 @@ export { default as TabNav } from './TabNav';
98
98
  export type { TabNavProps, TabNavLinkProps } from './TabNav';
99
99
  export { default as TextInput } from './TextInput';
100
100
  export type { TextInputProps } from './TextInput';
101
+ export { default as TextInputWithTokens } from './TextInputWithTokens';
101
102
  export { default as Text } from './Text';
102
103
  export type { TextProps } from './Text';
103
104
  export { default as Timeline } from './Timeline';
package/lib/index.js CHANGED
@@ -429,6 +429,12 @@ Object.defineProperty(exports, "TextInput", {
429
429
  return _TextInput.default;
430
430
  }
431
431
  });
432
+ Object.defineProperty(exports, "TextInputWithTokens", {
433
+ enumerable: true,
434
+ get: function () {
435
+ return _TextInputWithTokens.default;
436
+ }
437
+ });
432
438
  Object.defineProperty(exports, "Text", {
433
439
  enumerable: true,
434
440
  get: function () {
@@ -600,6 +606,8 @@ var _TabNav = _interopRequireDefault(require("./TabNav"));
600
606
 
601
607
  var _TextInput = _interopRequireDefault(require("./TextInput"));
602
608
 
609
+ var _TextInputWithTokens = _interopRequireDefault(require("./TextInputWithTokens"));
610
+
603
611
  var _Text = _interopRequireDefault(require("./Text"));
604
612
 
605
613
  var _Timeline = _interopRequireDefault(require("./Timeline"));
@@ -32,11 +32,14 @@ declare const _default: React.ForwardRefExoticComponent<Pick<SelectMenuInternalP
32
32
  Divider: import("styled-components").StyledComponent<"div", any, SystemCommonProps & SxProp, never>;
33
33
  Filter: React.ForwardRefExoticComponent<Pick<{
34
34
  value?: string | undefined;
35
- } & Pick<{
35
+ } & Omit<Pick<React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>, "key" | keyof React.InputHTMLAttributes<HTMLInputElement>> & {
36
+ ref?: ((instance: HTMLInputElement | null) => void) | React.RefObject<HTMLInputElement> | null | undefined;
37
+ }, string | number | symbol> & {
36
38
  className?: string | undefined;
37
39
  icon?: React.ComponentType<{
38
40
  className?: string | undefined;
39
41
  }> | undefined;
42
+ wrapperRef?: React.RefObject<HTMLSpanElement> | undefined;
40
43
  } & Pick<{
41
44
  color?: string | undefined;
42
45
  maxWidth?: import("styled-system").ResponsiveValue<import("csstype").Property.MaxWidth<import("styled-system").TLengthStyledSystem>, Required<import("styled-system").Theme<import("styled-system").TLengthStyledSystem>>> | undefined;
@@ -315,7 +318,9 @@ declare const _default: React.ForwardRefExoticComponent<Pick<SelectMenuInternalP
315
318
  } & {
316
319
  as?: string | React.ComponentType<any> | undefined;
317
320
  forwardedAs?: string | React.ComponentType<any> | undefined;
318
- }, string | number | symbol>, "maxWidth" | "minWidth" | "width" | "theme" | "className" | "block" | "icon" | "sx" | "disabled" | "variant" | "contrast">, string | number | symbol> & React.RefAttributes<HTMLInputElement>, string | number | symbol> & React.RefAttributes<HTMLInputElement>>;
321
+ }, string | number | symbol>, "maxWidth" | "minWidth" | "width" | "theme" | "className" | "block" | "icon" | "sx" | "disabled" | "variant" | "contrast" | "wrapperRef"> & {
322
+ as?: "input" | undefined;
323
+ }, string | number | symbol> & React.RefAttributes<HTMLInputElement>>;
319
324
  Footer: import("styled-components").StyledComponent<"footer", any, SystemCommonProps & SxProp, never>;
320
325
  Item: React.ForwardRefExoticComponent<Pick<{
321
326
  as?: React.ElementType<any> | undefined;
@@ -1,8 +1,9 @@
1
1
  import React from 'react';
2
2
  import { MaxWidthProps, MinWidthProps, WidthProps } from 'styled-system';
3
+ import { ForwardRefComponent as PolymorphicForwardRefComponent } from '@radix-ui/react-polymorphic';
3
4
  import { SxProp } from './sx';
4
5
  import { ComponentProps } from './utils/types';
5
- declare const Input: import("styled-components").StyledComponent<"input", any, {}, never>;
6
+ import UnstyledTextInput from './_UnstyledTextInput';
6
7
  declare const Wrapper: import("styled-components").StyledComponent<"span", any, {
7
8
  disabled?: boolean | undefined;
8
9
  hasIcon?: boolean | undefined;
@@ -15,8 +16,9 @@ declare type NonPassthroughProps = {
15
16
  icon?: React.ComponentType<{
16
17
  className?: string;
17
18
  }>;
19
+ wrapperRef?: React.RefObject<HTMLSpanElement>;
18
20
  } & Pick<ComponentProps<typeof Wrapper>, 'block' | 'contrast' | 'disabled' | 'sx' | 'theme' | 'width' | 'maxWidth' | 'minWidth' | 'variant'>;
19
- declare type TextInputInternalProps = NonPassthroughProps & Omit<React.ComponentPropsWithoutRef<typeof Input>, keyof NonPassthroughProps>;
20
- declare const TextInput: React.ForwardRefExoticComponent<Pick<TextInputInternalProps, string | number | symbol> & React.RefAttributes<HTMLInputElement>>;
21
+ declare type TextInputInternalProps = NonPassthroughProps & Omit<React.ComponentPropsWithoutRef<typeof UnstyledTextInput>, keyof NonPassthroughProps>;
22
+ declare const TextInput: PolymorphicForwardRefComponent<"input", TextInputInternalProps>;
21
23
  export declare type TextInputProps = ComponentProps<typeof TextInput>;
22
24
  export default TextInput;
@@ -6,6 +6,7 @@ import styled, { css } from 'styled-components';
6
6
  import { maxWidth, minWidth, variant, width } from 'styled-system';
7
7
  import { get } from './constants';
8
8
  import sx from './sx';
9
+ import UnstyledTextInput from './_UnstyledTextInput';
9
10
  const sizeVariants = variant({
10
11
  variants: {
11
12
  small: {
@@ -22,21 +23,16 @@ const sizeVariants = variant({
22
23
  }
23
24
  }
24
25
  });
25
- const Input = styled.input.withConfig({
26
- displayName: "TextInput__Input",
27
- componentId: "sc-1apmpmt-0"
28
- })(["border:0;font-size:inherit;font-family:inherit;background-color:transparent;-webkit-appearance:none;color:inherit;width:100%;&:focus{outline:0;}"]);
29
26
  const Wrapper = styled.span.withConfig({
30
27
  displayName: "TextInput__Wrapper",
31
- componentId: "sc-1apmpmt-1"
28
+ componentId: "sc-1apmpmt-0"
32
29
  })(["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 => {
33
30
  if (props.hasIcon) {
34
31
  return css(["padding:0;"]);
35
32
  } else {
36
33
  return css(["padding:6px 12px;"]);
37
34
  }
38
- }, get('colors.fg.muted'), get('space.2'), get('colors.accent.emphasis'), get('shadows.primer.shadow.focus'), props => props.contrast && css(["background-color:", ";"], get('colors.canvas.inset')), props => props.disabled && css(["color:", ";background-color:", ";border-color:", ";"], get('colors.fg.muted'), get('colors.input.disabledBg'), get('colors.border.default')), props => props.block && css(["display:block;width:100%;"]), get('breakpoints.1'), get('fontSizes.1'), width, minWidth, maxWidth, sizeVariants, sx); // Props that are not passed through to Input:
39
-
35
+ }, get('colors.fg.muted'), get('space.2'), get('colors.accent.emphasis'), get('shadows.primer.shadow.focus'), props => props.contrast && css(["background-color:", ";"], get('colors.canvas.inset')), props => props.disabled && css(["color:", ";background-color:", ";border-color:", ";"], get('colors.fg.muted'), get('colors.input.disabledBg'), get('colors.border.default')), props => props.block && css(["display:block;width:100%;"]), get('breakpoints.1'), get('fontSizes.1'), width, minWidth, maxWidth, sizeVariants, sx);
40
36
  // using forwardRef is important so that other components (ex. SelectMenu) can autofocus the input
41
37
  const TextInput = /*#__PURE__*/React.forwardRef(({
42
38
  icon: IconComponent,
@@ -50,6 +46,7 @@ const TextInput = /*#__PURE__*/React.forwardRef(({
50
46
  minWidth: minWidthProp,
51
47
  maxWidth: maxWidthProp,
52
48
  variant: variantProp,
49
+ wrapperRef,
53
50
  ...inputProps
54
51
  }, ref) => {
55
52
  // this class is necessary to style FilterSearch, plz no touchy!
@@ -65,10 +62,11 @@ const TextInput = /*#__PURE__*/React.forwardRef(({
65
62
  width: widthProp,
66
63
  minWidth: minWidthProp,
67
64
  maxWidth: maxWidthProp,
68
- variant: variantProp
65
+ variant: variantProp,
66
+ ref: wrapperRef
69
67
  }, IconComponent && /*#__PURE__*/React.createElement(IconComponent, {
70
68
  className: "TextInput-icon"
71
- }), /*#__PURE__*/React.createElement(Input, _extends({
69
+ }), /*#__PURE__*/React.createElement(UnstyledTextInput, _extends({
72
70
  ref: ref,
73
71
  disabled: disabled
74
72
  }, inputProps)));