@teamturing/react-kit 2.19.46 → 2.20.1

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.
@@ -1,10 +1,8 @@
1
1
  import { ElementType, InputHTMLAttributes, ReactNode, Ref } from 'react';
2
+ import { OverlayProps } from '../Overlay';
2
3
  import { OverlayPopperProps } from '../OverlayPopper';
3
4
  import { TextInputProps } from '../TextInput';
4
- type Props<T extends {
5
- label: string;
6
- value?: string | number | readonly string[];
7
- }> = {
5
+ type Props<T> = {
8
6
  /**
9
7
  * TODO asdf
10
8
  */
@@ -13,24 +11,25 @@ type Props<T extends {
13
11
  * 입력 창 앞에 보여질 시각적 요소를 정의합니다. Icon, Text, Image 등이 될 수 있습니다.
14
12
  */
15
13
  leadingVisual?: ElementType | ReactNode;
14
+ /**
15
+ * 입력 창 뒤에 보여질 시각적 요소를 정의합니다. Icon, Text, Image 등이 될 수 있습니다.
16
+ * Default: chevron down icon
17
+ */
18
+ trailingVisual?: ElementType | ReactNode;
16
19
  children: (selectionHandler: {
17
20
  handleSelect: (item: T) => void;
18
21
  }, overlayHandler: {
19
22
  isOpen: boolean;
20
23
  closeOverlay: () => void;
21
24
  }) => ReactNode;
22
- onChange?: (item: T) => void;
25
+ overlayProps?: Pick<OverlayProps, 'size' | 'maxHeight'>;
23
26
  searchInputProps?: Pick<TextInputProps, 'placeholder' | 'trailingVisual' | 'trailingAction' | 'onChange'>;
24
- renderValue?: (value: T['value']) => ReactNode;
25
- } & Pick<OverlayPopperProps, 'focusTrapSettings' | 'focusZoneSettings' | 'onClose' | 'onOpen'> & Pick<InputHTMLAttributes<HTMLInputElement>, 'id' | 'disabled' | 'onClick' | 'placeholder' | 'value'>;
26
- declare const SearchSelectInput: <T extends {
27
- label: string;
28
- value: string | number | readonly string[];
29
- }>({ validationStatus, leadingVisual: LeadingVisual, children, onChange, focusTrapSettings, focusZoneSettings, onOpen, onClose, searchInputProps, value, renderValue, ...props }: Props<T>, ref: Ref<HTMLInputElement>) => import("react/jsx-runtime").JSX.Element;
30
- declare const _default: <T extends {
31
- label: string;
32
- value: string | number | readonly string[];
33
- }>(props: {
27
+ value?: T;
28
+ renderValue?: (value: T) => ReactNode;
29
+ onChange?: (item: T) => void;
30
+ } & Pick<OverlayPopperProps, 'focusTrapSettings' | 'focusZoneSettings' | 'onClose' | 'onOpen'> & Pick<InputHTMLAttributes<HTMLInputElement>, 'id' | 'disabled' | 'onClick' | 'placeholder'>;
31
+ declare const SearchSelectInput: <T>({ validationStatus, leadingVisual: LeadingVisual, trailingVisual: TrailingVisual, children, focusTrapSettings, focusZoneSettings, onOpen, onClose, overlayProps: propOverlayProps, searchInputProps, value, renderValue, onChange, ...props }: Props<T>, ref: Ref<HTMLInputElement>) => import("react/jsx-runtime").JSX.Element;
32
+ declare const _default: <T>(props: {
34
33
  /**
35
34
  * TODO asdf
36
35
  */
@@ -39,16 +38,23 @@ declare const _default: <T extends {
39
38
  * 입력 창 앞에 보여질 시각적 요소를 정의합니다. Icon, Text, Image 등이 될 수 있습니다.
40
39
  */
41
40
  leadingVisual?: string | number | boolean | import("react").ComponentClass<any, any> | import("react").FunctionComponent<any> | import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>> | Iterable<ReactNode> | import("react").ReactPortal | null | undefined;
41
+ /**
42
+ * 입력 창 뒤에 보여질 시각적 요소를 정의합니다. Icon, Text, Image 등이 될 수 있습니다.
43
+ * Default: chevron down icon
44
+ */
45
+ trailingVisual?: string | number | boolean | import("react").ComponentClass<any, any> | import("react").FunctionComponent<any> | import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>> | Iterable<ReactNode> | import("react").ReactPortal | null | undefined;
42
46
  children: (selectionHandler: {
43
47
  handleSelect: (item: T) => void;
44
48
  }, overlayHandler: {
45
49
  isOpen: boolean;
46
50
  closeOverlay: () => void;
47
51
  }) => ReactNode;
48
- onChange?: ((item: T) => void) | undefined;
52
+ overlayProps?: Pick<OverlayProps, "maxHeight" | "size"> | undefined;
49
53
  searchInputProps?: Pick<TextInputProps, "placeholder" | "onChange" | "trailingVisual" | "trailingAction"> | undefined;
50
- renderValue?: ((value: T["value"]) => ReactNode) | undefined;
51
- } & Pick<OverlayPopperProps, "onClose" | "focusZoneSettings" | "focusTrapSettings" | "onOpen"> & Pick<InputHTMLAttributes<HTMLInputElement>, "disabled" | "placeholder" | "value" | "id" | "onClick"> & {
54
+ value?: T | undefined;
55
+ renderValue?: ((value: T) => ReactNode) | undefined;
56
+ onChange?: ((item: T) => void) | undefined;
57
+ } & Pick<OverlayPopperProps, "onClose" | "focusZoneSettings" | "focusTrapSettings" | "onOpen"> & Pick<InputHTMLAttributes<HTMLInputElement>, "disabled" | "placeholder" | "id" | "onClick"> & {
52
58
  ref?: Ref<HTMLInputElement> | undefined;
53
59
  }) => ReturnType<typeof SearchSelectInput>;
54
60
  export default _default;
package/dist/index.js CHANGED
@@ -21587,18 +21587,23 @@ var TextInput$1 = Object.assign( /*#__PURE__*/React.forwardRef(TextInput), {
21587
21587
  const SearchSelectInput = ({
21588
21588
  validationStatus,
21589
21589
  leadingVisual: LeadingVisual,
21590
+ trailingVisual: TrailingVisual,
21590
21591
  children,
21591
- onChange,
21592
21592
  focusTrapSettings,
21593
21593
  focusZoneSettings,
21594
21594
  onOpen,
21595
21595
  onClose,
21596
+ overlayProps: propOverlayProps,
21596
21597
  searchInputProps,
21597
21598
  value,
21598
- renderValue = value => value?.toString(),
21599
+ renderValue = value => /*#__PURE__*/jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, {
21600
+ children: value
21601
+ }),
21602
+ onChange,
21599
21603
  ...props
21600
21604
  }, ref) => {
21601
21605
  const theme = styled.useTheme();
21606
+ const isVisibleValueExist = value && isArray$1(value) && !isNullable(renderValue(value)) ? value.length > 0 : value && !isNullable(renderValue(value));
21602
21607
  const hasLeadingVisual = !isNullable(LeadingVisual);
21603
21608
  const valueInputRef = useProvidedOrCreatedRef(ref);
21604
21609
  const labelInputRef = React.useRef(null);
@@ -21621,7 +21626,7 @@ const SearchSelectInput = ({
21621
21626
  * ! 일단 Custom onChange를 만들어서 해결.
21622
21627
  */
21623
21628
  const nativeInputValueSetter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, 'value')?.set;
21624
- nativeInputValueSetter?.call(valueInputRef.current, item.value.toString());
21629
+ nativeInputValueSetter?.call(valueInputRef.current, item);
21625
21630
  onChange?.(item);
21626
21631
  }
21627
21632
  };
@@ -21666,8 +21671,9 @@ const SearchSelectInput = ({
21666
21671
  renderOverlay: (overlayProps, overlayHandler, {
21667
21672
  elements
21668
21673
  }) => /*#__PURE__*/jsxRuntimeExports.jsxs(Overlay$1, {
21674
+ ...propOverlayProps,
21669
21675
  ...overlayProps,
21670
- maxHeight: 200,
21676
+ maxHeight: 300,
21671
21677
  sx: {
21672
21678
  display: 'flex',
21673
21679
  flexDirection: 'column'
@@ -21676,6 +21682,12 @@ const SearchSelectInput = ({
21676
21682
  ...overlayProps.style,
21677
21683
  width: elements?.reference?.getBoundingClientRect().width
21678
21684
  },
21685
+ onKeyDown: e => {
21686
+ if (e.code === 'Escape') {
21687
+ e.stopPropagation();
21688
+ overlayHandler.closeOverlay();
21689
+ }
21690
+ },
21679
21691
  children: [/*#__PURE__*/jsxRuntimeExports.jsx(Space, {
21680
21692
  p: 2,
21681
21693
  sx: {
@@ -21690,6 +21702,7 @@ const SearchSelectInput = ({
21690
21702
  if (e.code === 'Enter' && activeDescendantRef.current) {
21691
21703
  const activeDescendantEvent = new KeyboardEvent(e.type, e.nativeEvent);
21692
21704
  activeDescendantRef.current?.dispatchEvent(activeDescendantEvent);
21705
+ e.preventDefault();
21693
21706
  }
21694
21707
  },
21695
21708
  ...searchInputProps
@@ -21707,22 +21720,18 @@ const SearchSelectInput = ({
21707
21720
  }, overlayHandler)
21708
21721
  })]
21709
21722
  }),
21710
- children: (popperProps, {
21711
- openOverlay
21712
- }) => /*#__PURE__*/jsxRuntimeExports.jsxs(TextInputWrapper, {
21713
- ...popperProps,
21714
- tabIndex: disabled ? -1 : 0,
21723
+ children: popperProps => /*#__PURE__*/jsxRuntimeExports.jsxs(TextInputWrapper, {
21724
+ ...(disabled ? {} : {
21725
+ ...popperProps,
21726
+ onClick: e => {
21727
+ focusInput();
21728
+ popperProps.onClick?.(e);
21729
+ }
21730
+ }),
21731
+ tabIndex: -1,
21715
21732
  disabled: disabled,
21716
- onClick: focusInput,
21717
21733
  hasLeadingVisual: hasLeadingVisual,
21718
21734
  validationStatus: validationStatus,
21719
- onKeyDown: e => {
21720
- if (['ArrowUp', 'ArrowDown'].includes(e.key)) {
21721
- e.preventDefault();
21722
- openOverlay();
21723
- }
21724
- e.stopPropagation();
21725
- },
21726
21735
  children: [/*#__PURE__*/jsxRuntimeExports.jsx(View, {
21727
21736
  sx: {
21728
21737
  'flexShrink': 0,
@@ -21747,12 +21756,10 @@ const SearchSelectInput = ({
21747
21756
  paddingLeft: hasLeadingVisual ? 2 : 4,
21748
21757
  whiteSpace: 'pre',
21749
21758
  textOverflow: 'ellipsis',
21750
- width: '100%'
21759
+ width: '100%',
21760
+ cursor: disabled ? 'not-allowed' : 'default'
21751
21761
  },
21752
- onClick: e => {
21753
- popperProps.onClick?.(e);
21754
- },
21755
- children: [!isNullable(renderValue(value)) ? /*#__PURE__*/jsxRuntimeExports.jsx(View, {
21762
+ children: [isVisibleValueExist ? /*#__PURE__*/jsxRuntimeExports.jsx(View, {
21756
21763
  sx: {
21757
21764
  flex: '0 1 auto',
21758
21765
  maxWidth: '100%',
@@ -21760,20 +21767,20 @@ const SearchSelectInput = ({
21760
21767
  whiteSpace: 'pre',
21761
21768
  overflow: 'hidden'
21762
21769
  },
21763
- children: renderValue(value)
21770
+ children: value && renderValue(value)
21764
21771
  }) : null, /*#__PURE__*/jsxRuntimeExports.jsx(BaseInput, {
21765
21772
  id: id,
21766
21773
  ref: labelInputRef,
21767
21774
  readOnly: true,
21768
21775
  onChange: noop$2,
21769
21776
  autoComplete: 'off',
21770
- tabIndex: -1,
21777
+ disabled: disabled,
21771
21778
  onClick: e => {
21772
21779
  props.onClick?.(e);
21773
21780
  },
21774
- placeholder: !isNullable(renderValue(value)) ? '' : placeholder
21781
+ placeholder: isVisibleValueExist ? '' : placeholder
21775
21782
  })]
21776
- }), /*#__PURE__*/jsxRuntimeExports.jsx(StyledIcon, {
21783
+ }), /*#__PURE__*/jsxRuntimeExports.jsx(View, {
21777
21784
  sx: {
21778
21785
  position: 'absolute',
21779
21786
  top: '50%',
@@ -21781,9 +21788,11 @@ const SearchSelectInput = ({
21781
21788
  right: 4,
21782
21789
  pointerEvents: 'none'
21783
21790
  },
21784
- icon: SvgChevronDown,
21785
- color: disabled ? 'icon/disabled' : 'icon/neutral/bolder',
21786
- size: 16
21791
+ children: typeof TrailingVisual !== 'string' && reactIsExports.isValidElementType(TrailingVisual) ? /*#__PURE__*/jsxRuntimeExports.jsx(TrailingVisual, {}) : TrailingVisual ? TrailingVisual : /*#__PURE__*/jsxRuntimeExports.jsx(StyledIcon, {
21792
+ icon: SvgChevronDown,
21793
+ color: disabled ? 'icon/disabled' : 'icon/neutral/bolder',
21794
+ size: 16
21795
+ })
21787
21796
  }), /*#__PURE__*/jsxRuntimeExports.jsx(BaseInput, {
21788
21797
  ref: e => {
21789
21798
  isFunction$1(ref) ? ref(e) : null;
@@ -2,6 +2,7 @@ import { forwardRef, useRef } from 'react';
2
2
  import SvgChevronDown from '../../packages/icons/esm/ChevronDown.js';
3
3
  import SvgSearch from '../../packages/icons/esm/Search.js';
4
4
  import { forcePixelValue } from '../../packages/utils/esm/forcePixelValue.js';
5
+ import { isArray } from '../../packages/utils/esm/isArray.js';
5
6
  import { isFunction } from '../../packages/utils/esm/isFunction.js';
6
7
  import { isNullable } from '../../packages/utils/esm/isNullable.js';
7
8
  import { noop } from '../../packages/utils/esm/noop.js';
@@ -21,18 +22,23 @@ import { j as jsxRuntimeExports } from '../../node_modules/react/jsx-runtime.js'
21
22
  const SearchSelectInput = ({
22
23
  validationStatus,
23
24
  leadingVisual: LeadingVisual,
25
+ trailingVisual: TrailingVisual,
24
26
  children,
25
- onChange,
26
27
  focusTrapSettings,
27
28
  focusZoneSettings,
28
29
  onOpen,
29
30
  onClose,
31
+ overlayProps: propOverlayProps,
30
32
  searchInputProps,
31
33
  value,
32
- renderValue = value => value?.toString(),
34
+ renderValue = value => /*#__PURE__*/jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, {
35
+ children: value
36
+ }),
37
+ onChange,
33
38
  ...props
34
39
  }, ref) => {
35
40
  const theme = useTheme();
41
+ const isVisibleValueExist = value && isArray(value) && !isNullable(renderValue(value)) ? value.length > 0 : value && !isNullable(renderValue(value));
36
42
  const hasLeadingVisual = !isNullable(LeadingVisual);
37
43
  const valueInputRef = useProvidedOrCreatedRef(ref);
38
44
  const labelInputRef = useRef(null);
@@ -55,7 +61,7 @@ const SearchSelectInput = ({
55
61
  * ! 일단 Custom onChange를 만들어서 해결.
56
62
  */
57
63
  const nativeInputValueSetter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, 'value')?.set;
58
- nativeInputValueSetter?.call(valueInputRef.current, item.value.toString());
64
+ nativeInputValueSetter?.call(valueInputRef.current, item);
59
65
  onChange?.(item);
60
66
  }
61
67
  };
@@ -100,8 +106,9 @@ const SearchSelectInput = ({
100
106
  renderOverlay: (overlayProps, overlayHandler, {
101
107
  elements
102
108
  }) => /*#__PURE__*/jsxRuntimeExports.jsxs(Overlay, {
109
+ ...propOverlayProps,
103
110
  ...overlayProps,
104
- maxHeight: 200,
111
+ maxHeight: 300,
105
112
  sx: {
106
113
  display: 'flex',
107
114
  flexDirection: 'column'
@@ -110,6 +117,12 @@ const SearchSelectInput = ({
110
117
  ...overlayProps.style,
111
118
  width: elements?.reference?.getBoundingClientRect().width
112
119
  },
120
+ onKeyDown: e => {
121
+ if (e.code === 'Escape') {
122
+ e.stopPropagation();
123
+ overlayHandler.closeOverlay();
124
+ }
125
+ },
113
126
  children: [/*#__PURE__*/jsxRuntimeExports.jsx(Space, {
114
127
  p: 2,
115
128
  sx: {
@@ -124,6 +137,7 @@ const SearchSelectInput = ({
124
137
  if (e.code === 'Enter' && activeDescendantRef.current) {
125
138
  const activeDescendantEvent = new KeyboardEvent(e.type, e.nativeEvent);
126
139
  activeDescendantRef.current?.dispatchEvent(activeDescendantEvent);
140
+ e.preventDefault();
127
141
  }
128
142
  },
129
143
  ...searchInputProps
@@ -141,22 +155,18 @@ const SearchSelectInput = ({
141
155
  }, overlayHandler)
142
156
  })]
143
157
  }),
144
- children: (popperProps, {
145
- openOverlay
146
- }) => /*#__PURE__*/jsxRuntimeExports.jsxs(TextInputWrapper, {
147
- ...popperProps,
148
- tabIndex: disabled ? -1 : 0,
158
+ children: popperProps => /*#__PURE__*/jsxRuntimeExports.jsxs(TextInputWrapper, {
159
+ ...(disabled ? {} : {
160
+ ...popperProps,
161
+ onClick: e => {
162
+ focusInput();
163
+ popperProps.onClick?.(e);
164
+ }
165
+ }),
166
+ tabIndex: -1,
149
167
  disabled: disabled,
150
- onClick: focusInput,
151
168
  hasLeadingVisual: hasLeadingVisual,
152
169
  validationStatus: validationStatus,
153
- onKeyDown: e => {
154
- if (['ArrowUp', 'ArrowDown'].includes(e.key)) {
155
- e.preventDefault();
156
- openOverlay();
157
- }
158
- e.stopPropagation();
159
- },
160
170
  children: [/*#__PURE__*/jsxRuntimeExports.jsx(View, {
161
171
  sx: {
162
172
  'flexShrink': 0,
@@ -181,12 +191,10 @@ const SearchSelectInput = ({
181
191
  paddingLeft: hasLeadingVisual ? 2 : 4,
182
192
  whiteSpace: 'pre',
183
193
  textOverflow: 'ellipsis',
184
- width: '100%'
194
+ width: '100%',
195
+ cursor: disabled ? 'not-allowed' : 'default'
185
196
  },
186
- onClick: e => {
187
- popperProps.onClick?.(e);
188
- },
189
- children: [!isNullable(renderValue(value)) ? /*#__PURE__*/jsxRuntimeExports.jsx(View, {
197
+ children: [isVisibleValueExist ? /*#__PURE__*/jsxRuntimeExports.jsx(View, {
190
198
  sx: {
191
199
  flex: '0 1 auto',
192
200
  maxWidth: '100%',
@@ -194,20 +202,20 @@ const SearchSelectInput = ({
194
202
  whiteSpace: 'pre',
195
203
  overflow: 'hidden'
196
204
  },
197
- children: renderValue(value)
205
+ children: value && renderValue(value)
198
206
  }) : null, /*#__PURE__*/jsxRuntimeExports.jsx(BaseInput, {
199
207
  id: id,
200
208
  ref: labelInputRef,
201
209
  readOnly: true,
202
210
  onChange: noop,
203
211
  autoComplete: 'off',
204
- tabIndex: -1,
212
+ disabled: disabled,
205
213
  onClick: e => {
206
214
  props.onClick?.(e);
207
215
  },
208
- placeholder: !isNullable(renderValue(value)) ? '' : placeholder
216
+ placeholder: isVisibleValueExist ? '' : placeholder
209
217
  })]
210
- }), /*#__PURE__*/jsxRuntimeExports.jsx(StyledIcon, {
218
+ }), /*#__PURE__*/jsxRuntimeExports.jsx(View, {
211
219
  sx: {
212
220
  position: 'absolute',
213
221
  top: '50%',
@@ -215,9 +223,11 @@ const SearchSelectInput = ({
215
223
  right: 4,
216
224
  pointerEvents: 'none'
217
225
  },
218
- icon: SvgChevronDown,
219
- color: disabled ? 'icon/disabled' : 'icon/neutral/bolder',
220
- size: 16
226
+ children: typeof TrailingVisual !== 'string' && reactIsExports.isValidElementType(TrailingVisual) ? /*#__PURE__*/jsxRuntimeExports.jsx(TrailingVisual, {}) : TrailingVisual ? TrailingVisual : /*#__PURE__*/jsxRuntimeExports.jsx(StyledIcon, {
227
+ icon: SvgChevronDown,
228
+ color: disabled ? 'icon/disabled' : 'icon/neutral/bolder',
229
+ size: 16
230
+ })
221
231
  }), /*#__PURE__*/jsxRuntimeExports.jsx(BaseInput, {
222
232
  ref: e => {
223
233
  isFunction(ref) ? ref(e) : null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@teamturing/react-kit",
3
- "version": "2.19.46",
3
+ "version": "2.20.1",
4
4
  "description": "React components, hooks for create teamturing web application",
5
5
  "author": "Sungchang Park <psch300@gmail.com> (https://github.com/psch300)",
6
6
  "homepage": "https://github.com/weareteamturing/bombe#readme",
@@ -57,6 +57,7 @@
57
57
  "@primer/behaviors": "^1.3.6",
58
58
  "@teamturing/icons": "^1.25.1",
59
59
  "@teamturing/token-studio": "^1.2.2",
60
+ "@teamturing/utils": "^1.2.0",
60
61
  "framer-motion": "^10.16.4",
61
62
  "lodash.debounce": "^4.0.8",
62
63
  "lodash.throttle": "^4.1.1",
@@ -65,5 +66,5 @@
65
66
  "react-textarea-autosize": "^8.5.3",
66
67
  "styled-system": "^5.1.5"
67
68
  },
68
- "gitHead": "1cd63d66b40289a82a276112e2b0c37f30b9c588"
69
+ "gitHead": "d009d5b6544ea3579d0b4093fd449422d1352261"
69
70
  }