@teamturing/react-kit 2.19.14 → 2.19.15

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/dist/index.js CHANGED
@@ -18869,6 +18869,7 @@ const Dialog = ({
18869
18869
  isOpen,
18870
18870
  onDismiss,
18871
18871
  size = 'm',
18872
+ initialFocusRef,
18872
18873
  sx
18873
18874
  }, ref) => {
18874
18875
  const handleDismiss = React.useCallback(() => onDismiss?.(), [onDismiss]);
@@ -18891,7 +18892,7 @@ const Dialog = ({
18891
18892
  }, [handleDismiss]);
18892
18893
  useFocusTrap({
18893
18894
  containerRef: dialogRef,
18894
- initialFocusRef: closeButtonRef,
18895
+ initialFocusRef: initialFocusRef || closeButtonRef,
18895
18896
  disabled: !isOpen
18896
18897
  });
18897
18898
  React.useEffect(() => {
@@ -20922,116 +20923,118 @@ const OverlayPopper = ({
20922
20923
  });
20923
20924
  };
20924
20925
 
20925
- const OverlaySelectInput = ({
20926
+ const TextInputTrailingAction = ({
20927
+ icon: Icon,
20928
+ disabled,
20929
+ ...props
20930
+ }, ref) => /*#__PURE__*/jsxRuntimeExports.jsx(BaseTextInputTrailingAction, {
20931
+ ref: ref,
20932
+ ...props,
20933
+ disabled: disabled,
20934
+ "aria-disabled": disabled,
20935
+ children: /*#__PURE__*/jsxRuntimeExports.jsx(Icon, {})
20936
+ });
20937
+ const BaseTextInputTrailingAction = styled__default.default(UnstyledButton)`
20938
+ display: inline-flex;
20939
+ padding: ${({
20940
+ theme
20941
+ }) => forcePixelValue(theme.space[2])};
20942
+ background-color: ${({
20943
+ theme
20944
+ }) => theme.colors['bg/neutral/subtler']};
20945
+ border-radius: ${({
20946
+ theme
20947
+ }) => forcePixelValue(theme.radii.full)};
20948
+
20949
+ & svg {
20950
+ width: ${forcePixelValue(16)};
20951
+ height: ${forcePixelValue(16)};
20952
+ color: ${({
20953
+ theme
20954
+ }) => theme.colors['icon/neutral/bolder']};
20955
+ }
20956
+
20957
+ &:hover {
20958
+ background-color: ${({
20959
+ theme
20960
+ }) => theme.colors['bg/neutral/subtler/hovered']};
20961
+ }
20962
+
20963
+ &[aria-disabled='true'] {
20964
+ cursor: not-allowed;
20965
+ & svg {
20966
+ color: ${({
20967
+ theme
20968
+ }) => theme.colors['icon/disabled']};
20969
+ }
20970
+ }
20971
+
20972
+ ${sx}
20973
+ `;
20974
+ var TextInputTrailingAction$1 = /*#__PURE__*/React.forwardRef(TextInputTrailingAction);
20975
+
20976
+ const TextInput = ({
20977
+ type = 'text',
20978
+ disabled,
20926
20979
  validationStatus,
20927
20980
  leadingVisual: LeadingVisual,
20928
- children,
20929
- onChange,
20930
- focusTrapSettings,
20931
- focusZoneSettings,
20932
- onOpen,
20933
- onClose,
20981
+ trailingVisual: TrailingVisual,
20982
+ trailingAction,
20934
20983
  ...props
20935
20984
  }, ref) => {
20936
- const valueInputRef = useProvidedOrCreatedRef(ref);
20937
- const labelInputRef = React.useRef(null);
20985
+ const inputRef = useProvidedOrCreatedRef(ref);
20938
20986
  const focusInput = () => {
20939
- labelInputRef.current?.focus();
20940
- };
20941
- const {
20942
- id,
20943
- disabled,
20944
- placeholder
20945
- } = props;
20946
- const handleSelect = item => {
20947
- if (labelInputRef.current && valueInputRef.current) {
20948
- labelInputRef.current.setAttribute('value', item.label);
20949
-
20950
- /**
20951
- * ! valueInput의 native onChange를 trigger하려고 했으나 작동하지 않음.
20952
- * ! 일단 Custom onChange를 만들어서 해결.
20953
- */
20954
- const nativeInputValueSetter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, 'value')?.set;
20955
- nativeInputValueSetter?.call(valueInputRef.current, item.value.toString());
20956
- onChange?.(item);
20957
- }
20987
+ inputRef.current?.focus();
20958
20988
  };
20959
- return /*#__PURE__*/jsxRuntimeExports.jsx(OverlayPopper, {
20960
- focusTrapSettings: focusTrapSettings,
20961
- focusZoneSettings: focusZoneSettings,
20962
- onOpen: onOpen,
20963
- onClose: onClose,
20964
- renderOverlay: (overlayProps, _, {
20965
- elements
20966
- }) => /*#__PURE__*/jsxRuntimeExports.jsx(Overlay$1, {
20967
- ...overlayProps,
20968
- style: {
20969
- ...overlayProps.style,
20970
- width: elements?.reference?.getBoundingClientRect().width
20989
+ return /*#__PURE__*/jsxRuntimeExports.jsxs(TextInputWrapper$1, {
20990
+ disabled: disabled,
20991
+ onClick: focusInput,
20992
+ hasLeadingVisual: !isNullable(LeadingVisual),
20993
+ hasTrailingVisual: !isNullable(TrailingVisual),
20994
+ hasTrailingAction: !isNullable(trailingAction),
20995
+ validationStatus: validationStatus,
20996
+ children: [/*#__PURE__*/jsxRuntimeExports.jsx(View, {
20997
+ sx: {
20998
+ 'flexShrink': 0,
20999
+ 'fontSize': 'xxs',
21000
+ 'fontWeight': 'medium',
21001
+ 'color': color$1['text/neutral'],
21002
+ '& > svg': {
21003
+ display: 'block',
21004
+ width: 16,
21005
+ height: 16,
21006
+ color: color$1['icon/neutral/bold']
21007
+ }
20971
21008
  },
20972
- children: children?.({
20973
- handleSelect
20974
- })
20975
- }),
20976
- children: (popperProps, {
20977
- openOverlay
20978
- }) => /*#__PURE__*/jsxRuntimeExports.jsxs(TextInputWrapper$1, {
20979
- ...popperProps,
20980
- tabIndex: disabled ? -1 : 0,
21009
+ children: typeof LeadingVisual !== 'string' && reactIsExports.isValidElementType(LeadingVisual) ? /*#__PURE__*/jsxRuntimeExports.jsx(LeadingVisual, {}) : LeadingVisual
21010
+ }), /*#__PURE__*/jsxRuntimeExports.jsx(BaseInput$1, {
21011
+ ref: e => {
21012
+ isFunction(ref) ? ref(e) : null;
21013
+ inputRef.current = e;
21014
+ },
21015
+ type: type,
20981
21016
  disabled: disabled,
20982
- onClick: focusInput,
20983
- hasLeadingVisual: !isNullable(LeadingVisual),
20984
- validationStatus: validationStatus,
20985
- onKeyDown: e => {
20986
- if (['ArrowUp', 'ArrowDown'].includes(e.key)) {
20987
- e.preventDefault();
20988
- openOverlay();
21017
+ ...props
21018
+ }), /*#__PURE__*/jsxRuntimeExports.jsxs(View, {
21019
+ sx: {
21020
+ 'display': 'flex',
21021
+ 'alignItems': 'center',
21022
+ 'columnGap': 2,
21023
+ 'flexShrink': 0,
21024
+ 'fontSize': 'xxs',
21025
+ 'fontWeight': 'medium',
21026
+ 'color': color$1['text/neutral'],
21027
+ '& > svg': {
21028
+ display: 'block',
21029
+ width: 16,
21030
+ height: 16,
21031
+ color: color$1['icon/neutral/bold']
20989
21032
  }
20990
21033
  },
20991
- children: [/*#__PURE__*/jsxRuntimeExports.jsx(View, {
20992
- sx: {
20993
- 'flexShrink': 0,
20994
- 'fontSize': 'xxs',
20995
- 'fontWeight': 'medium',
20996
- 'color': 'text/neutral',
20997
- '& > svg': {
20998
- display: 'block',
20999
- width: 16,
21000
- height: 16,
21001
- color: 'icon/neutral/bold'
21002
- }
21003
- },
21004
- children: typeof LeadingVisual !== 'string' && reactIsExports.isValidElementType(LeadingVisual) ? /*#__PURE__*/jsxRuntimeExports.jsx(LeadingVisual, {}) : LeadingVisual
21005
- }), /*#__PURE__*/jsxRuntimeExports.jsx(BaseInput$1, {
21006
- id: id,
21007
- ref: labelInputRef,
21008
- onChange: noop$2,
21009
- autoComplete: 'off',
21010
- tabIndex: -1,
21011
- onClick: e => {
21012
- popperProps.onClick?.(e);
21013
- props.onClick?.(e);
21014
- },
21015
- placeholder: placeholder
21016
- }), /*#__PURE__*/jsxRuntimeExports.jsx(StyledIcon, {
21017
- sx: {
21018
- position: 'absolute',
21019
- top: '50%',
21020
- transform: 'translateY(-50%)',
21021
- right: 4,
21022
- pointerEvents: 'none'
21023
- },
21024
- icon: SvgChevronDown,
21025
- color: disabled ? 'icon/disabled' : 'icon/neutral/bolder',
21026
- size: 16
21027
- }), /*#__PURE__*/jsxRuntimeExports.jsx(BaseInput$1, {
21028
- ref: e => {
21029
- isFunction(ref) ? ref(e) : null;
21030
- valueInputRef.current = e;
21031
- },
21032
- type: 'hidden'
21033
- })]
21034
- })
21034
+ children: [typeof TrailingVisual !== 'string' && reactIsExports.isValidElementType(TrailingVisual) ? /*#__PURE__*/jsxRuntimeExports.jsx(TrailingVisual, {}) : TrailingVisual, trailingAction ? /*#__PURE__*/React.cloneElement(trailingAction, {
21035
+ disabled: disabled
21036
+ }) : null]
21037
+ })]
21035
21038
  });
21036
21039
  };
21037
21040
  const TextInputWrapper$1 = styled__default.default.div`
@@ -21048,10 +21051,7 @@ const TextInputWrapper$1 = styled__default.default.div`
21048
21051
  background-color: ${({
21049
21052
  theme
21050
21053
  }) => theme.colors['bg/input']};
21051
- cursor: default;
21052
- input {
21053
- cursor: default;
21054
- }
21054
+ cursor: text;
21055
21055
  display: inline-flex;
21056
21056
  align-items: center;
21057
21057
 
@@ -21106,7 +21106,7 @@ const TextInputWrapper$1 = styled__default.default.div`
21106
21106
  }
21107
21107
  `}
21108
21108
 
21109
- ${props => props.validationStatus !== 'error' && !props.disabled && styled.css`
21109
+ ${props => props.validationStatus !== 'error' && styled.css`
21110
21110
  &:focus-within {
21111
21111
  &:after {
21112
21112
  border-color: ${({
@@ -21137,6 +21137,21 @@ const TextInputWrapper$1 = styled__default.default.div`
21137
21137
  }
21138
21138
  `}
21139
21139
 
21140
+ ${props => props.hasTrailingVisual && styled.css`
21141
+ padding-right: ${forcePixelValue(props.theme.space[4])};
21142
+ `}
21143
+
21144
+ ${props => props.hasTrailingAction && styled.css`
21145
+ padding-right: ${forcePixelValue(props.theme.space[2])};
21146
+ `}
21147
+
21148
+ ${props => (props.hasTrailingVisual || props.hasTrailingAction) && styled.css`
21149
+ input {
21150
+ padding-right: ${forcePixelValue(props.theme.space[2])};
21151
+ }
21152
+ `}
21153
+
21154
+
21140
21155
  transition: color 100ms, background-color 100ms;
21141
21156
  &:after {
21142
21157
  transition: border-color 100ms;
@@ -21164,102 +21179,226 @@ const BaseInput$1 = styled__default.default(UnstyledInput$1)`
21164
21179
  }) => forcePixelValue(theme.space[3])};
21165
21180
  padding-right: ${({
21166
21181
  theme
21167
- }) => forcePixelValue(theme.space[10])};
21182
+ }) => forcePixelValue(theme.space[4])};
21168
21183
  padding-bottom: ${({
21169
21184
  theme
21170
21185
  }) => forcePixelValue(theme.space[3])};
21171
21186
  padding-left: ${({
21172
21187
  theme
21173
21188
  }) => forcePixelValue(theme.space[4])};
21174
-
21175
- white-space: pre;
21176
- text-overflow: ellipsis;
21177
21189
  `;
21178
- var OverlaySelectInput$1 = /*#__PURE__*/React.forwardRef(OverlaySelectInput);
21179
-
21180
- const SelectOption = ({
21181
- children: propChildren,
21182
- ...props
21183
- }) => {
21184
- const children = isNullable(propChildren) ? props.label : propChildren;
21185
- return /*#__PURE__*/jsxRuntimeExports.jsx(BaseSelectOption, {
21186
- ...props,
21187
- children: children
21188
- });
21189
- };
21190
- const BaseSelectOption = styled__default.default.option``;
21190
+ var TextInput$1 = Object.assign( /*#__PURE__*/React.forwardRef(TextInput), {
21191
+ TrailingAction: TextInputTrailingAction$1
21192
+ });
21191
21193
 
21192
- const Select = ({
21193
- children,
21194
- disabled,
21194
+ const SearchSelectInput = ({
21195
21195
  validationStatus,
21196
21196
  leadingVisual: LeadingVisual,
21197
- placeholder = '옵션 선택',
21197
+ children,
21198
+ onChange,
21199
+ focusTrapSettings,
21200
+ focusZoneSettings,
21201
+ onOpen,
21202
+ onClose,
21203
+ searchInputProps,
21204
+ value,
21205
+ renderValue = value => value?.toString(),
21198
21206
  ...props
21199
21207
  }, ref) => {
21200
- const PLACEHOLDER_VALUE = '';
21201
- const selectRef = useProvidedOrCreatedRef(ref);
21202
- const [isValueEmpty, setIsValueEmpty] = React.useState(isNullable(props.value) || props.value === PLACEHOLDER_VALUE);
21203
- const focusSelect = () => {
21204
- selectRef.current?.focus();
21208
+ const theme = styled.useTheme();
21209
+ const hasLeadingVisual = !isNullable(LeadingVisual);
21210
+ const valueInputRef = useProvidedOrCreatedRef(ref);
21211
+ const labelInputRef = React.useRef(null);
21212
+ const focusInput = () => {
21213
+ labelInputRef.current?.focus();
21205
21214
  };
21206
- return /*#__PURE__*/jsxRuntimeExports.jsxs(SelectWrapper, {
21207
- disabled: disabled,
21208
- onClick: focusSelect,
21209
- hasLeadingVisual: !isNullable(LeadingVisual),
21210
- validationStatus: validationStatus,
21211
- isValueEmpty: isValueEmpty,
21212
- children: [/*#__PURE__*/jsxRuntimeExports.jsx(View, {
21213
- sx: {
21214
- 'flexShrink': 0,
21215
- 'fontSize': 'xxs',
21216
- 'fontWeight': 'medium',
21217
- 'color': 'text/neutral',
21218
- '& > svg': {
21219
- display: 'block',
21220
- width: 16,
21221
- height: 16,
21222
- color: 'icon/neutral/bold'
21215
+ const {
21216
+ id,
21217
+ disabled,
21218
+ placeholder
21219
+ } = props;
21220
+ const handleSelect = item => {
21221
+ if (labelInputRef.current && valueInputRef.current) {
21222
+ /**
21223
+ * ! valueInput의 native onChange를 trigger하려고 했으나 작동하지 않음.
21224
+ * ! 일단 Custom onChange를 만들어서 해결.
21225
+ */
21226
+ const nativeInputValueSetter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, 'value')?.set;
21227
+ nativeInputValueSetter?.call(valueInputRef.current, item.value.toString());
21228
+ onChange?.(item);
21229
+ }
21230
+ };
21231
+ const listContainerRef = React.useRef(null);
21232
+ const searchInputRef = React.useRef(null);
21233
+ const activeDescendantRef = React.useRef();
21234
+ return /*#__PURE__*/jsxRuntimeExports.jsx(OverlayPopper, {
21235
+ focusTrapSettings: {
21236
+ initialFocusRef: searchInputRef,
21237
+ restoreFocusOnCleanUp: true,
21238
+ ...focusTrapSettings
21239
+ },
21240
+ focusZoneSettings: {
21241
+ containerRef: listContainerRef,
21242
+ activeDescendantFocus: searchInputRef,
21243
+ focusOutBehavior: 'stop',
21244
+ onActiveDescendantChanged: (current, previous) => {
21245
+ activeDescendantRef.current = current;
21246
+ if (current && listContainerRef.current) {
21247
+ current.style.backgroundColor = theme.colors['bg/selected/subtle'];
21248
+ scrollIntoView({
21249
+ childrenRef: current,
21250
+ scrollContainerRef: listContainerRef.current,
21251
+ options: {
21252
+ behavior: 'auto',
21253
+ direction: 'vertical',
21254
+ offset: 0
21255
+ }
21256
+ });
21257
+ }
21258
+ if (previous && current !== previous) {
21259
+ previous.style.backgroundColor = '';
21223
21260
  }
21224
21261
  },
21225
- children: typeof LeadingVisual !== 'string' && reactIsExports.isValidElementType(LeadingVisual) ? /*#__PURE__*/jsxRuntimeExports.jsx(LeadingVisual, {}) : LeadingVisual
21226
- }), /*#__PURE__*/jsxRuntimeExports.jsxs(BaseSelect, {
21227
- ref: e => {
21228
- isFunction(ref) ? ref(e) : null;
21229
- selectRef.current = e;
21262
+ focusableElementFilter: elem => {
21263
+ return elem instanceof HTMLElement;
21230
21264
  },
21231
- placeholder: placeholder,
21265
+ ...focusZoneSettings
21266
+ },
21267
+ onOpen: onOpen,
21268
+ onClose: onClose,
21269
+ renderOverlay: (overlayProps, overlayHandler, {
21270
+ elements
21271
+ }) => /*#__PURE__*/jsxRuntimeExports.jsxs(Overlay$1, {
21272
+ ...overlayProps,
21273
+ maxHeight: 200,
21274
+ sx: {
21275
+ display: 'flex',
21276
+ flexDirection: 'column'
21277
+ },
21278
+ style: {
21279
+ ...overlayProps.style,
21280
+ width: elements?.reference?.getBoundingClientRect().width
21281
+ },
21282
+ children: [/*#__PURE__*/jsxRuntimeExports.jsx(Space, {
21283
+ p: 2,
21284
+ sx: {
21285
+ flexGrow: 0,
21286
+ flexShrink: 0,
21287
+ flexBasis: 'auto'
21288
+ },
21289
+ children: /*#__PURE__*/jsxRuntimeExports.jsx(TextInput$1, {
21290
+ ref: searchInputRef,
21291
+ leadingVisual: SvgSearch,
21292
+ onKeyDown: e => {
21293
+ if (e.code === 'Enter' && activeDescendantRef.current) {
21294
+ const activeDescendantEvent = new KeyboardEvent(e.type, e.nativeEvent);
21295
+ activeDescendantRef.current?.dispatchEvent(activeDescendantEvent);
21296
+ }
21297
+ },
21298
+ ...searchInputProps
21299
+ })
21300
+ }), /*#__PURE__*/jsxRuntimeExports.jsx(HorizontalDivider, {}), /*#__PURE__*/jsxRuntimeExports.jsx(View, {
21301
+ ref: listContainerRef,
21302
+ sx: {
21303
+ flexGrow: 1,
21304
+ flexShrink: 1,
21305
+ flexBasis: 'auto',
21306
+ overflowY: 'auto'
21307
+ },
21308
+ children: children?.({
21309
+ handleSelect
21310
+ }, overlayHandler)
21311
+ })]
21312
+ }),
21313
+ children: (popperProps, {
21314
+ openOverlay
21315
+ }) => /*#__PURE__*/jsxRuntimeExports.jsxs(TextInputWrapper, {
21316
+ ...popperProps,
21317
+ tabIndex: disabled ? -1 : 0,
21232
21318
  disabled: disabled,
21233
- ...props,
21234
- onChange: e => {
21235
- props.onChange?.(e);
21236
- if (!e.defaultPrevented) {
21237
- if (e.target.value === PLACEHOLDER_VALUE) {
21238
- setIsValueEmpty(true);
21239
- } else {
21240
- setIsValueEmpty(false);
21241
- }
21319
+ onClick: focusInput,
21320
+ hasLeadingVisual: hasLeadingVisual,
21321
+ validationStatus: validationStatus,
21322
+ onKeyDown: e => {
21323
+ if (['ArrowUp', 'ArrowDown'].includes(e.key)) {
21324
+ e.preventDefault();
21325
+ openOverlay();
21242
21326
  }
21327
+ e.stopPropagation();
21243
21328
  },
21244
- children: [/*#__PURE__*/jsxRuntimeExports.jsx(SelectOption, {
21245
- label: placeholder,
21246
- value: PLACEHOLDER_VALUE
21247
- }), children]
21248
- }), /*#__PURE__*/jsxRuntimeExports.jsx(StyledIcon, {
21249
- sx: {
21250
- position: 'absolute',
21251
- top: '50%',
21252
- transform: 'translateY(-50%)',
21253
- right: 4,
21254
- pointerEvents: 'none'
21255
- },
21256
- icon: SvgChevronDown,
21257
- color: disabled ? 'icon/disabled' : 'icon/neutral/bolder',
21258
- size: 16
21259
- })]
21329
+ children: [/*#__PURE__*/jsxRuntimeExports.jsx(View, {
21330
+ sx: {
21331
+ 'flexShrink': 0,
21332
+ 'fontSize': 'xxs',
21333
+ 'fontWeight': 'medium',
21334
+ 'color': 'text/neutral',
21335
+ '& > svg': {
21336
+ display: 'block',
21337
+ width: 16,
21338
+ height: 16,
21339
+ color: 'icon/neutral/bold'
21340
+ }
21341
+ },
21342
+ children: typeof LeadingVisual !== 'string' && reactIsExports.isValidElementType(LeadingVisual) ? /*#__PURE__*/jsxRuntimeExports.jsx(LeadingVisual, {}) : LeadingVisual
21343
+ }), /*#__PURE__*/jsxRuntimeExports.jsxs(View, {
21344
+ sx: {
21345
+ display: 'flex',
21346
+ alignItems: 'center',
21347
+ paddingTop: 3,
21348
+ paddingRight: 10,
21349
+ paddingBottom: 3,
21350
+ paddingLeft: hasLeadingVisual ? 2 : 4,
21351
+ whiteSpace: 'pre',
21352
+ textOverflow: 'ellipsis',
21353
+ width: '100%'
21354
+ },
21355
+ onClick: e => {
21356
+ popperProps.onClick?.(e);
21357
+ },
21358
+ children: [!isNullable(renderValue(value)) ? /*#__PURE__*/jsxRuntimeExports.jsx(View, {
21359
+ sx: {
21360
+ flex: '0 1 auto',
21361
+ maxWidth: '100%',
21362
+ textOverflow: 'ellipsis',
21363
+ whiteSpace: 'pre',
21364
+ overflow: 'hidden'
21365
+ },
21366
+ children: renderValue(value)
21367
+ }) : null, /*#__PURE__*/jsxRuntimeExports.jsx(BaseInput, {
21368
+ id: id,
21369
+ ref: labelInputRef,
21370
+ readOnly: true,
21371
+ onChange: noop$2,
21372
+ autoComplete: 'off',
21373
+ tabIndex: -1,
21374
+ onClick: e => {
21375
+ props.onClick?.(e);
21376
+ },
21377
+ placeholder: !isNullable(renderValue(value)) ? '' : placeholder
21378
+ })]
21379
+ }), /*#__PURE__*/jsxRuntimeExports.jsx(StyledIcon, {
21380
+ sx: {
21381
+ position: 'absolute',
21382
+ top: '50%',
21383
+ transform: 'translateY(-50%)',
21384
+ right: 4,
21385
+ pointerEvents: 'none'
21386
+ },
21387
+ icon: SvgChevronDown,
21388
+ color: disabled ? 'icon/disabled' : 'icon/neutral/bolder',
21389
+ size: 16
21390
+ }), /*#__PURE__*/jsxRuntimeExports.jsx(BaseInput, {
21391
+ ref: e => {
21392
+ isFunction(ref) ? ref(e) : null;
21393
+ valueInputRef.current = e;
21394
+ },
21395
+ type: 'hidden',
21396
+ defaultValue: value
21397
+ })]
21398
+ })
21260
21399
  });
21261
21400
  };
21262
- const SelectWrapper = styled__default.default.div`
21401
+ const TextInputWrapper = styled__default.default.div`
21263
21402
  position: relative;
21264
21403
  width: ${forcePixelValue('100%')};
21265
21404
  border-width: ${forcePixelValue(1)};
@@ -21273,6 +21412,12 @@ const SelectWrapper = styled__default.default.div`
21273
21412
  background-color: ${({
21274
21413
  theme
21275
21414
  }) => theme.colors['bg/input']};
21415
+ cursor: default;
21416
+ input {
21417
+ cursor: default;
21418
+
21419
+ flex: 1;
21420
+ }
21276
21421
  display: inline-flex;
21277
21422
  align-items: center;
21278
21423
 
@@ -21288,16 +21433,11 @@ const SelectWrapper = styled__default.default.div`
21288
21433
  color: ${({
21289
21434
  theme
21290
21435
  }) => theme.colors['text/neutral']};
21291
-
21292
- /**
21293
- * placeholder style
21294
- */
21295
- ${({
21296
- theme,
21297
- isValueEmpty
21298
- }) => isValueEmpty ? styled.css`
21299
- color: ${theme.colors['text/neutral/subtlest']};
21300
- ` : null}
21436
+ input::placeholder {
21437
+ color: ${({
21438
+ theme
21439
+ }) => theme.colors['text/neutral/subtlest']};
21440
+ }
21301
21441
 
21302
21442
  &:after {
21303
21443
  content: '';
@@ -21332,7 +21472,7 @@ const SelectWrapper = styled__default.default.div`
21332
21472
  }
21333
21473
  `}
21334
21474
 
21335
- ${props => props.validationStatus !== 'error' && styled.css`
21475
+ ${props => props.validationStatus !== 'error' && !props.disabled && styled.css`
21336
21476
  &:focus-within {
21337
21477
  &:after {
21338
21478
  border-color: ${({
@@ -21347,28 +21487,25 @@ const SelectWrapper = styled__default.default.div`
21347
21487
  background-color: ${props.theme.colors['bg/disabled']};
21348
21488
  color: ${props.theme.colors['text/disabled']};
21349
21489
 
21350
- select::placeholder {
21490
+ input::placeholder {
21351
21491
  color: ${props.theme.colors['text/disabled']};
21352
21492
  }
21353
21493
 
21354
- select {
21494
+ input {
21355
21495
  cursor: not-allowed;
21356
21496
  }
21357
21497
  `};
21358
21498
 
21359
21499
  ${props => props.hasLeadingVisual && styled.css`
21360
21500
  padding-left: ${forcePixelValue(props.theme.space[4])};
21361
- select {
21362
- padding-left: ${forcePixelValue(props.theme.space[2])};
21363
- }
21364
21501
  `}
21365
21502
 
21366
- transition: background-color 100ms;
21503
+ transition: color 100ms, background-color 100ms;
21367
21504
  &:after {
21368
21505
  transition: border-color 100ms;
21369
21506
  }
21370
21507
  `;
21371
- const UnstyledSelect = styled__default.default.select`
21508
+ const UnstyledInput = styled__default.default.input`
21372
21509
  font-size: inherit;
21373
21510
  font-weight: inherit;
21374
21511
  line-height: inherit;
@@ -21376,154 +21513,104 @@ const UnstyledSelect = styled__default.default.select`
21376
21513
  border-radius: inherit;
21377
21514
  color: inherit;
21378
21515
  transition: inherit;
21516
+ width: 100%;
21379
21517
 
21380
21518
  border: 0;
21519
+ padding: 0;
21381
21520
  background-color: transparent;
21382
- width: 100%;
21383
21521
  &:focus {
21384
21522
  outline: 0;
21385
21523
  }
21386
-
21387
- appearance: none;
21388
- -webkit-appearance: none;
21389
- -moz-appearance: none;
21390
21524
  `;
21391
- const BaseSelect = styled__default.default(UnstyledSelect)`
21392
- padding-top: ${({
21393
- theme
21394
- }) => forcePixelValue(theme.space[3])};
21395
- padding-right: ${({
21396
- theme
21397
- }) => forcePixelValue(theme.space[10])};
21398
- padding-bottom: ${({
21399
- theme
21400
- }) => forcePixelValue(theme.space[3])};
21401
- padding-left: ${({
21402
- theme
21403
- }) => forcePixelValue(theme.space[4])};
21404
-
21525
+ const BaseInput = styled__default.default(UnstyledInput)`
21405
21526
  white-space: pre;
21406
21527
  text-overflow: ellipsis;
21407
21528
  `;
21408
- var Select$1 = Object.assign( /*#__PURE__*/React.forwardRef(Select), {
21409
- Option: SelectOption
21410
- });
21529
+ var SearchSelectInput$1 = /*#__PURE__*/React.forwardRef(SearchSelectInput);
21411
21530
 
21412
- const TextInputTrailingAction = ({
21413
- icon: Icon,
21414
- disabled,
21531
+ const SelectOption = ({
21532
+ children: propChildren,
21415
21533
  ...props
21416
- }, ref) => /*#__PURE__*/jsxRuntimeExports.jsx(BaseTextInputTrailingAction, {
21417
- ref: ref,
21418
- ...props,
21419
- disabled: disabled,
21420
- "aria-disabled": disabled,
21421
- children: /*#__PURE__*/jsxRuntimeExports.jsx(Icon, {})
21422
- });
21423
- const BaseTextInputTrailingAction = styled__default.default(UnstyledButton)`
21424
- display: inline-flex;
21425
- padding: ${({
21426
- theme
21427
- }) => forcePixelValue(theme.space[2])};
21428
- background-color: ${({
21429
- theme
21430
- }) => theme.colors['bg/neutral/subtler']};
21431
- border-radius: ${({
21432
- theme
21433
- }) => forcePixelValue(theme.radii.full)};
21434
-
21435
- & svg {
21436
- width: ${forcePixelValue(16)};
21437
- height: ${forcePixelValue(16)};
21438
- color: ${({
21439
- theme
21440
- }) => theme.colors['icon/neutral/bolder']};
21441
- }
21442
-
21443
- &:hover {
21444
- background-color: ${({
21445
- theme
21446
- }) => theme.colors['bg/neutral/subtler/hovered']};
21447
- }
21448
-
21449
- &[aria-disabled='true'] {
21450
- cursor: not-allowed;
21451
- & svg {
21452
- color: ${({
21453
- theme
21454
- }) => theme.colors['icon/disabled']};
21455
- }
21456
- }
21457
-
21458
- ${sx}
21459
- `;
21460
- var TextInputTrailingAction$1 = /*#__PURE__*/React.forwardRef(TextInputTrailingAction);
21534
+ }) => {
21535
+ const children = isNullable(propChildren) ? props.label : propChildren;
21536
+ return /*#__PURE__*/jsxRuntimeExports.jsx(BaseSelectOption, {
21537
+ ...props,
21538
+ children: children
21539
+ });
21540
+ };
21541
+ const BaseSelectOption = styled__default.default.option``;
21461
21542
 
21462
- const TextInput = ({
21463
- type = 'text',
21543
+ const Select = ({
21544
+ children,
21464
21545
  disabled,
21465
21546
  validationStatus,
21466
21547
  leadingVisual: LeadingVisual,
21467
- trailingVisual: TrailingVisual,
21468
- trailingAction,
21548
+ placeholder = '옵션 선택',
21469
21549
  ...props
21470
21550
  }, ref) => {
21471
- const inputRef = useProvidedOrCreatedRef(ref);
21472
- const focusInput = () => {
21473
- inputRef.current?.focus();
21551
+ const PLACEHOLDER_VALUE = '';
21552
+ const selectRef = useProvidedOrCreatedRef(ref);
21553
+ const [isValueEmpty, setIsValueEmpty] = React.useState(isNullable(props.value) || props.value === PLACEHOLDER_VALUE);
21554
+ const focusSelect = () => {
21555
+ selectRef.current?.focus();
21474
21556
  };
21475
- return /*#__PURE__*/jsxRuntimeExports.jsxs(TextInputWrapper, {
21557
+ return /*#__PURE__*/jsxRuntimeExports.jsxs(SelectWrapper, {
21476
21558
  disabled: disabled,
21477
- onClick: focusInput,
21559
+ onClick: focusSelect,
21478
21560
  hasLeadingVisual: !isNullable(LeadingVisual),
21479
- hasTrailingVisual: !isNullable(TrailingVisual),
21480
- hasTrailingAction: !isNullable(trailingAction),
21481
21561
  validationStatus: validationStatus,
21562
+ isValueEmpty: isValueEmpty,
21482
21563
  children: [/*#__PURE__*/jsxRuntimeExports.jsx(View, {
21483
21564
  sx: {
21484
21565
  'flexShrink': 0,
21485
21566
  'fontSize': 'xxs',
21486
21567
  'fontWeight': 'medium',
21487
- 'color': color$1['text/neutral'],
21568
+ 'color': 'text/neutral',
21488
21569
  '& > svg': {
21489
21570
  display: 'block',
21490
21571
  width: 16,
21491
21572
  height: 16,
21492
- color: color$1['icon/neutral/bold']
21573
+ color: 'icon/neutral/bold'
21493
21574
  }
21494
21575
  },
21495
21576
  children: typeof LeadingVisual !== 'string' && reactIsExports.isValidElementType(LeadingVisual) ? /*#__PURE__*/jsxRuntimeExports.jsx(LeadingVisual, {}) : LeadingVisual
21496
- }), /*#__PURE__*/jsxRuntimeExports.jsx(BaseInput, {
21577
+ }), /*#__PURE__*/jsxRuntimeExports.jsxs(BaseSelect, {
21497
21578
  ref: e => {
21498
21579
  isFunction(ref) ? ref(e) : null;
21499
- inputRef.current = e;
21580
+ selectRef.current = e;
21500
21581
  },
21501
- type: type,
21582
+ placeholder: placeholder,
21502
21583
  disabled: disabled,
21503
- ...props
21504
- }), /*#__PURE__*/jsxRuntimeExports.jsxs(View, {
21505
- sx: {
21506
- 'display': 'flex',
21507
- 'alignItems': 'center',
21508
- 'columnGap': 2,
21509
- 'flexShrink': 0,
21510
- 'fontSize': 'xxs',
21511
- 'fontWeight': 'medium',
21512
- 'color': color$1['text/neutral'],
21513
- '& > svg': {
21514
- display: 'block',
21515
- width: 16,
21516
- height: 16,
21517
- color: color$1['icon/neutral/bold']
21584
+ ...props,
21585
+ onChange: e => {
21586
+ props.onChange?.(e);
21587
+ if (!e.defaultPrevented) {
21588
+ if (e.target.value === PLACEHOLDER_VALUE) {
21589
+ setIsValueEmpty(true);
21590
+ } else {
21591
+ setIsValueEmpty(false);
21592
+ }
21518
21593
  }
21519
21594
  },
21520
- children: [typeof TrailingVisual !== 'string' && reactIsExports.isValidElementType(TrailingVisual) ? /*#__PURE__*/jsxRuntimeExports.jsx(TrailingVisual, {}) : TrailingVisual, trailingAction ? /*#__PURE__*/React.cloneElement(trailingAction, {
21521
- disabled: disabled
21522
- }) : null]
21595
+ children: [/*#__PURE__*/jsxRuntimeExports.jsx(SelectOption, {
21596
+ label: placeholder,
21597
+ value: PLACEHOLDER_VALUE
21598
+ }), children]
21599
+ }), /*#__PURE__*/jsxRuntimeExports.jsx(StyledIcon, {
21600
+ sx: {
21601
+ position: 'absolute',
21602
+ top: '50%',
21603
+ transform: 'translateY(-50%)',
21604
+ right: 4,
21605
+ pointerEvents: 'none'
21606
+ },
21607
+ icon: SvgChevronDown,
21608
+ color: disabled ? 'icon/disabled' : 'icon/neutral/bolder',
21609
+ size: 16
21523
21610
  })]
21524
21611
  });
21525
21612
  };
21526
- const TextInputWrapper = styled__default.default.div`
21613
+ const SelectWrapper = styled__default.default.div`
21527
21614
  position: relative;
21528
21615
  width: ${forcePixelValue('100%')};
21529
21616
  border-width: ${forcePixelValue(1)};
@@ -21537,7 +21624,6 @@ const TextInputWrapper = styled__default.default.div`
21537
21624
  background-color: ${({
21538
21625
  theme
21539
21626
  }) => theme.colors['bg/input']};
21540
- cursor: text;
21541
21627
  display: inline-flex;
21542
21628
  align-items: center;
21543
21629
 
@@ -21553,11 +21639,16 @@ const TextInputWrapper = styled__default.default.div`
21553
21639
  color: ${({
21554
21640
  theme
21555
21641
  }) => theme.colors['text/neutral']};
21556
- input::placeholder {
21557
- color: ${({
21558
- theme
21559
- }) => theme.colors['text/neutral/subtlest']};
21560
- }
21642
+
21643
+ /**
21644
+ * placeholder style
21645
+ */
21646
+ ${({
21647
+ theme,
21648
+ isValueEmpty
21649
+ }) => isValueEmpty ? styled.css`
21650
+ color: ${theme.colors['text/neutral/subtlest']};
21651
+ ` : null}
21561
21652
 
21562
21653
  &:after {
21563
21654
  content: '';
@@ -21607,43 +21698,28 @@ const TextInputWrapper = styled__default.default.div`
21607
21698
  background-color: ${props.theme.colors['bg/disabled']};
21608
21699
  color: ${props.theme.colors['text/disabled']};
21609
21700
 
21610
- input::placeholder {
21701
+ select::placeholder {
21611
21702
  color: ${props.theme.colors['text/disabled']};
21612
21703
  }
21613
21704
 
21614
- input {
21705
+ select {
21615
21706
  cursor: not-allowed;
21616
21707
  }
21617
21708
  `};
21618
21709
 
21619
21710
  ${props => props.hasLeadingVisual && styled.css`
21620
21711
  padding-left: ${forcePixelValue(props.theme.space[4])};
21621
- input {
21712
+ select {
21622
21713
  padding-left: ${forcePixelValue(props.theme.space[2])};
21623
21714
  }
21624
21715
  `}
21625
21716
 
21626
- ${props => props.hasTrailingVisual && styled.css`
21627
- padding-right: ${forcePixelValue(props.theme.space[4])};
21628
- `}
21629
-
21630
- ${props => props.hasTrailingAction && styled.css`
21631
- padding-right: ${forcePixelValue(props.theme.space[2])};
21632
- `}
21633
-
21634
- ${props => (props.hasTrailingVisual || props.hasTrailingAction) && styled.css`
21635
- input {
21636
- padding-right: ${forcePixelValue(props.theme.space[2])};
21637
- }
21638
- `}
21639
-
21640
-
21641
- transition: color 100ms, background-color 100ms;
21717
+ transition: background-color 100ms;
21642
21718
  &:after {
21643
21719
  transition: border-color 100ms;
21644
21720
  }
21645
21721
  `;
21646
- const UnstyledInput = styled__default.default.input`
21722
+ const UnstyledSelect = styled__default.default.select`
21647
21723
  font-size: inherit;
21648
21724
  font-weight: inherit;
21649
21725
  line-height: inherit;
@@ -21658,23 +21734,30 @@ const UnstyledInput = styled__default.default.input`
21658
21734
  &:focus {
21659
21735
  outline: 0;
21660
21736
  }
21737
+
21738
+ appearance: none;
21739
+ -webkit-appearance: none;
21740
+ -moz-appearance: none;
21661
21741
  `;
21662
- const BaseInput = styled__default.default(UnstyledInput)`
21742
+ const BaseSelect = styled__default.default(UnstyledSelect)`
21663
21743
  padding-top: ${({
21664
21744
  theme
21665
21745
  }) => forcePixelValue(theme.space[3])};
21666
21746
  padding-right: ${({
21667
21747
  theme
21668
- }) => forcePixelValue(theme.space[4])};
21748
+ }) => forcePixelValue(theme.space[10])};
21669
21749
  padding-bottom: ${({
21670
21750
  theme
21671
21751
  }) => forcePixelValue(theme.space[3])};
21672
21752
  padding-left: ${({
21673
21753
  theme
21674
21754
  }) => forcePixelValue(theme.space[4])};
21755
+
21756
+ white-space: pre;
21757
+ text-overflow: ellipsis;
21675
21758
  `;
21676
- var TextInput$1 = Object.assign( /*#__PURE__*/React.forwardRef(TextInput), {
21677
- TrailingAction: TextInputTrailingAction$1
21759
+ var Select$1 = Object.assign( /*#__PURE__*/React.forwardRef(Select), {
21760
+ Option: SelectOption
21678
21761
  });
21679
21762
 
21680
21763
  const FormControlCaption = ({
@@ -21833,7 +21916,7 @@ const FormControl = ({
21833
21916
  successMessage: FormControlSuccessMessage
21834
21917
  }
21835
21918
  });
21836
- const inputComponentCandidates = [TextInput$1, Select$1, OverlaySelectInput$1, Checkbox$1, ...additionalInputComponentCandidates];
21919
+ const inputComponentCandidates = [TextInput$1, Select$1, SearchSelectInput$1, Checkbox$1, ...additionalInputComponentCandidates];
21837
21920
  const InputComponent = restComponents.find(component => inputComponentCandidates.some(candidate => /*#__PURE__*/React.isValidElement(component) && component.type === candidate));
21838
21921
  const isHorizontalLayoutNeeded = /*#__PURE__*/React.isValidElement(InputComponent) && InputComponent.type === Checkbox$1;
21839
21922
  return /*#__PURE__*/jsxRuntimeExports.jsx(FormControlContext.Provider, {
@@ -22008,6 +22091,7 @@ const Pagination = ({
22008
22091
  onPreviousClick = noop$2,
22009
22092
  onNextClick = noop$2,
22010
22093
  renderPage = (page, i) => /*#__PURE__*/jsxRuntimeExports.jsx(PaginationPage, {
22094
+ type: 'button',
22011
22095
  onClick: () => onPageClick(page, i),
22012
22096
  selected: i === currentPageIndex,
22013
22097
  children: page.label
@@ -22049,6 +22133,7 @@ const Pagination = ({
22049
22133
  sx: sx,
22050
22134
  children: [renderPreviousPageDirection({
22051
22135
  previousPageDirectionProps: {
22136
+ type: 'button',
22052
22137
  onClick: () => onPreviousClick(currentPageIndex),
22053
22138
  disabled: currentPageIndex === 0
22054
22139
  }
@@ -22086,6 +22171,7 @@ const Pagination = ({
22086
22171
  originalIndex
22087
22172
  }) => renderPaginationPage(page, originalIndex))], renderNextPageDirection({
22088
22173
  nextPageDirectionProps: {
22174
+ type: 'button',
22089
22175
  onClick: () => onNextClick(currentPageIndex),
22090
22176
  disabled: currentPageIndex === totalPageCount - 1
22091
22177
  }
@@ -22293,6 +22379,7 @@ const Pill = ({
22293
22379
  hasRemoveButton: !isNullable(propOnRemove),
22294
22380
  disabled: disabled,
22295
22381
  ...props,
22382
+ type: 'button',
22296
22383
  children: [typeof LeadingVisual !== 'string' && reactIsExports.isValidElementType(LeadingVisual) ? /*#__PURE__*/jsxRuntimeExports.jsx(LeadingVisual, {}) : LeadingVisual, /*#__PURE__*/jsxRuntimeExports.jsx("span", {
22297
22384
  title: children?.toString(),
22298
22385
  children: children
@@ -24237,9 +24324,9 @@ exports.ItemList = ItemList;
24237
24324
  exports.MotionView = MotionView;
24238
24325
  exports.Overlay = Overlay$1;
24239
24326
  exports.OverlayPopper = OverlayPopper;
24240
- exports.OverlaySelectInput = OverlaySelectInput$1;
24241
24327
  exports.Pagination = index$3;
24242
24328
  exports.Pill = index$2;
24329
+ exports.SearchSelectInput = SearchSelectInput$1;
24243
24330
  exports.Select = Select$1;
24244
24331
  exports.Space = Space;
24245
24332
  exports.Spinner = Spinner;