@teamturing/react-kit 2.19.13 → 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(() => {
@@ -20840,7 +20841,9 @@ const OverlayPopper = ({
20840
20841
  renderOverlay,
20841
20842
  placement = 'bottom-start',
20842
20843
  focusZoneSettings,
20843
- focusTrapSettings
20844
+ focusTrapSettings,
20845
+ onOpen,
20846
+ onClose
20844
20847
  }) => {
20845
20848
  const {
20846
20849
  refs,
@@ -20861,11 +20864,23 @@ const OverlayPopper = ({
20861
20864
  } = useToggleHandler({
20862
20865
  initialState: false
20863
20866
  });
20864
- const handleDismiss = () => {
20867
+ const handleOverlayToggle = () => {
20868
+ if (!isOpen) onOpen?.();else onClose?.();
20869
+ toggleOverlay();
20870
+ };
20871
+ const handleOverlayOpen = () => {
20872
+ onOpen?.();
20873
+ openOverlay();
20874
+ };
20875
+ const handleOverlayClose = () => {
20876
+ onClose?.();
20865
20877
  closeOverlay();
20866
20878
  };
20879
+ const handleDismiss = () => {
20880
+ handleOverlayClose();
20881
+ };
20867
20882
  const defaultPopperProps = {
20868
- onClick: toggleOverlay,
20883
+ onClick: handleOverlayToggle,
20869
20884
  tabIndex: 0,
20870
20885
  ...{
20871
20886
  ref: refs.setReference
@@ -20875,7 +20890,7 @@ const OverlayPopper = ({
20875
20890
  ...defaultPopperProps
20876
20891
  }, {
20877
20892
  isOpen,
20878
- openOverlay
20893
+ openOverlay: handleOverlayOpen
20879
20894
  }) : React.Children.map(propChildren, child => /*#__PURE__*/React.cloneElement(child, {
20880
20895
  ...defaultPopperProps
20881
20896
  }));
@@ -20901,93 +20916,125 @@ const OverlayPopper = ({
20901
20916
  onDismiss: handleDismiss
20902
20917
  }, {
20903
20918
  isOpen,
20904
- closeOverlay
20919
+ closeOverlay: handleOverlayClose
20905
20920
  }, {
20906
20921
  elements
20907
20922
  })]
20908
20923
  });
20909
20924
  };
20910
20925
 
20911
- 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,
20912
20979
  validationStatus,
20913
20980
  leadingVisual: LeadingVisual,
20914
- children,
20981
+ trailingVisual: TrailingVisual,
20982
+ trailingAction,
20915
20983
  ...props
20916
20984
  }, ref) => {
20917
20985
  const inputRef = useProvidedOrCreatedRef(ref);
20918
20986
  const focusInput = () => {
20919
20987
  inputRef.current?.focus();
20920
20988
  };
20921
- const {
20922
- disabled
20923
- } = props;
20924
- return /*#__PURE__*/jsxRuntimeExports.jsx(OverlayPopper, {
20925
- renderOverlay: (overlayProps, _, {
20926
- elements
20927
- }) => /*#__PURE__*/jsxRuntimeExports.jsx(Overlay$1, {
20928
- ...overlayProps,
20929
- style: {
20930
- ...overlayProps.style,
20931
- 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
+ }
20932
21008
  },
20933
- children: children
20934
- }),
20935
- children: (popperProps, {
20936
- openOverlay
20937
- }) => /*#__PURE__*/jsxRuntimeExports.jsxs(TextInputWrapper$1, {
20938
- ...popperProps,
20939
- 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,
20940
21016
  disabled: disabled,
20941
- onClick: focusInput,
20942
- hasLeadingVisual: !isNullable(LeadingVisual),
20943
- validationStatus: validationStatus,
20944
- onKeyDown: e => {
20945
- if (['ArrowUp', 'ArrowDown'].includes(e.key)) {
20946
- e.preventDefault();
20947
- 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']
20948
21032
  }
20949
21033
  },
20950
- children: [/*#__PURE__*/jsxRuntimeExports.jsx(View, {
20951
- sx: {
20952
- 'flexShrink': 0,
20953
- 'fontSize': 'xxs',
20954
- 'fontWeight': 'medium',
20955
- 'color': 'text/neutral',
20956
- '& > svg': {
20957
- display: 'block',
20958
- width: 16,
20959
- height: 16,
20960
- color: 'icon/neutral/bold'
20961
- }
20962
- },
20963
- children: typeof LeadingVisual !== 'string' && reactIsExports.isValidElementType(LeadingVisual) ? /*#__PURE__*/jsxRuntimeExports.jsx(LeadingVisual, {}) : LeadingVisual
20964
- }), /*#__PURE__*/jsxRuntimeExports.jsx(BaseInput$1, {
20965
- ref: e => {
20966
- isFunction(ref) ? ref(e) : null;
20967
- inputRef.current = e;
20968
- },
20969
- value: '',
20970
- onChange: noop$2,
20971
- ...props,
20972
- autoComplete: 'off',
20973
- tabIndex: -1,
20974
- onClick: e => {
20975
- popperProps.onClick?.(e);
20976
- props.onClick?.(e);
20977
- }
20978
- }), /*#__PURE__*/jsxRuntimeExports.jsx(StyledIcon, {
20979
- sx: {
20980
- position: 'absolute',
20981
- top: '50%',
20982
- transform: 'translateY(-50%)',
20983
- right: 4,
20984
- pointerEvents: 'none'
20985
- },
20986
- icon: SvgChevronDown,
20987
- color: disabled ? 'icon/disabled' : 'icon/neutral/bolder',
20988
- size: 16
20989
- })]
20990
- })
21034
+ children: [typeof TrailingVisual !== 'string' && reactIsExports.isValidElementType(TrailingVisual) ? /*#__PURE__*/jsxRuntimeExports.jsx(TrailingVisual, {}) : TrailingVisual, trailingAction ? /*#__PURE__*/React.cloneElement(trailingAction, {
21035
+ disabled: disabled
21036
+ }) : null]
21037
+ })]
20991
21038
  });
20992
21039
  };
20993
21040
  const TextInputWrapper$1 = styled__default.default.div`
@@ -21004,10 +21051,7 @@ const TextInputWrapper$1 = styled__default.default.div`
21004
21051
  background-color: ${({
21005
21052
  theme
21006
21053
  }) => theme.colors['bg/input']};
21007
- cursor: default;
21008
- input {
21009
- cursor: default;
21010
- }
21054
+ cursor: text;
21011
21055
  display: inline-flex;
21012
21056
  align-items: center;
21013
21057
 
@@ -21062,7 +21106,7 @@ const TextInputWrapper$1 = styled__default.default.div`
21062
21106
  }
21063
21107
  `}
21064
21108
 
21065
- ${props => props.validationStatus !== 'error' && !props.disabled && styled.css`
21109
+ ${props => props.validationStatus !== 'error' && styled.css`
21066
21110
  &:focus-within {
21067
21111
  &:after {
21068
21112
  border-color: ${({
@@ -21093,6 +21137,21 @@ const TextInputWrapper$1 = styled__default.default.div`
21093
21137
  }
21094
21138
  `}
21095
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
+
21096
21155
  transition: color 100ms, background-color 100ms;
21097
21156
  &:after {
21098
21157
  transition: border-color 100ms;
@@ -21120,102 +21179,226 @@ const BaseInput$1 = styled__default.default(UnstyledInput$1)`
21120
21179
  }) => forcePixelValue(theme.space[3])};
21121
21180
  padding-right: ${({
21122
21181
  theme
21123
- }) => forcePixelValue(theme.space[10])};
21182
+ }) => forcePixelValue(theme.space[4])};
21124
21183
  padding-bottom: ${({
21125
21184
  theme
21126
21185
  }) => forcePixelValue(theme.space[3])};
21127
21186
  padding-left: ${({
21128
21187
  theme
21129
21188
  }) => forcePixelValue(theme.space[4])};
21130
-
21131
- white-space: pre;
21132
- text-overflow: ellipsis;
21133
21189
  `;
21134
- var OverlaySelectInput$1 = /*#__PURE__*/React.forwardRef(OverlaySelectInput);
21135
-
21136
- const SelectOption = ({
21137
- children: propChildren,
21138
- ...props
21139
- }) => {
21140
- const children = isNullable(propChildren) ? props.label : propChildren;
21141
- return /*#__PURE__*/jsxRuntimeExports.jsx(BaseSelectOption, {
21142
- ...props,
21143
- children: children
21144
- });
21145
- };
21146
- const BaseSelectOption = styled__default.default.option``;
21190
+ var TextInput$1 = Object.assign( /*#__PURE__*/React.forwardRef(TextInput), {
21191
+ TrailingAction: TextInputTrailingAction$1
21192
+ });
21147
21193
 
21148
- const Select = ({
21149
- children,
21150
- disabled,
21194
+ const SearchSelectInput = ({
21151
21195
  validationStatus,
21152
21196
  leadingVisual: LeadingVisual,
21153
- placeholder = '옵션 선택',
21197
+ children,
21198
+ onChange,
21199
+ focusTrapSettings,
21200
+ focusZoneSettings,
21201
+ onOpen,
21202
+ onClose,
21203
+ searchInputProps,
21204
+ value,
21205
+ renderValue = value => value?.toString(),
21154
21206
  ...props
21155
21207
  }, ref) => {
21156
- const PLACEHOLDER_VALUE = '';
21157
- const selectRef = useProvidedOrCreatedRef(ref);
21158
- const [isValueEmpty, setIsValueEmpty] = React.useState(isNullable(props.value) || props.value === PLACEHOLDER_VALUE);
21159
- const focusSelect = () => {
21160
- 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();
21161
21214
  };
21162
- return /*#__PURE__*/jsxRuntimeExports.jsxs(SelectWrapper, {
21163
- disabled: disabled,
21164
- onClick: focusSelect,
21165
- hasLeadingVisual: !isNullable(LeadingVisual),
21166
- validationStatus: validationStatus,
21167
- isValueEmpty: isValueEmpty,
21168
- children: [/*#__PURE__*/jsxRuntimeExports.jsx(View, {
21169
- sx: {
21170
- 'flexShrink': 0,
21171
- 'fontSize': 'xxs',
21172
- 'fontWeight': 'medium',
21173
- 'color': 'text/neutral',
21174
- '& > svg': {
21175
- display: 'block',
21176
- width: 16,
21177
- height: 16,
21178
- 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 = '';
21179
21260
  }
21180
21261
  },
21181
- children: typeof LeadingVisual !== 'string' && reactIsExports.isValidElementType(LeadingVisual) ? /*#__PURE__*/jsxRuntimeExports.jsx(LeadingVisual, {}) : LeadingVisual
21182
- }), /*#__PURE__*/jsxRuntimeExports.jsxs(BaseSelect, {
21183
- ref: e => {
21184
- isFunction(ref) ? ref(e) : null;
21185
- selectRef.current = e;
21262
+ focusableElementFilter: elem => {
21263
+ return elem instanceof HTMLElement;
21186
21264
  },
21187
- 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,
21188
21318
  disabled: disabled,
21189
- ...props,
21190
- onChange: e => {
21191
- props.onChange?.(e);
21192
- if (!e.defaultPrevented) {
21193
- if (e.target.value === PLACEHOLDER_VALUE) {
21194
- setIsValueEmpty(true);
21195
- } else {
21196
- setIsValueEmpty(false);
21197
- }
21319
+ onClick: focusInput,
21320
+ hasLeadingVisual: hasLeadingVisual,
21321
+ validationStatus: validationStatus,
21322
+ onKeyDown: e => {
21323
+ if (['ArrowUp', 'ArrowDown'].includes(e.key)) {
21324
+ e.preventDefault();
21325
+ openOverlay();
21198
21326
  }
21327
+ e.stopPropagation();
21199
21328
  },
21200
- children: [/*#__PURE__*/jsxRuntimeExports.jsx(SelectOption, {
21201
- label: placeholder,
21202
- value: PLACEHOLDER_VALUE
21203
- }), children]
21204
- }), /*#__PURE__*/jsxRuntimeExports.jsx(StyledIcon, {
21205
- sx: {
21206
- position: 'absolute',
21207
- top: '50%',
21208
- transform: 'translateY(-50%)',
21209
- right: 4,
21210
- pointerEvents: 'none'
21211
- },
21212
- icon: SvgChevronDown,
21213
- color: disabled ? 'icon/disabled' : 'icon/neutral/bolder',
21214
- size: 16
21215
- })]
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
+ })
21216
21399
  });
21217
21400
  };
21218
- const SelectWrapper = styled__default.default.div`
21401
+ const TextInputWrapper = styled__default.default.div`
21219
21402
  position: relative;
21220
21403
  width: ${forcePixelValue('100%')};
21221
21404
  border-width: ${forcePixelValue(1)};
@@ -21229,6 +21412,12 @@ const SelectWrapper = styled__default.default.div`
21229
21412
  background-color: ${({
21230
21413
  theme
21231
21414
  }) => theme.colors['bg/input']};
21415
+ cursor: default;
21416
+ input {
21417
+ cursor: default;
21418
+
21419
+ flex: 1;
21420
+ }
21232
21421
  display: inline-flex;
21233
21422
  align-items: center;
21234
21423
 
@@ -21244,16 +21433,11 @@ const SelectWrapper = styled__default.default.div`
21244
21433
  color: ${({
21245
21434
  theme
21246
21435
  }) => theme.colors['text/neutral']};
21247
-
21248
- /**
21249
- * placeholder style
21250
- */
21251
- ${({
21252
- theme,
21253
- isValueEmpty
21254
- }) => isValueEmpty ? styled.css`
21255
- color: ${theme.colors['text/neutral/subtlest']};
21256
- ` : null}
21436
+ input::placeholder {
21437
+ color: ${({
21438
+ theme
21439
+ }) => theme.colors['text/neutral/subtlest']};
21440
+ }
21257
21441
 
21258
21442
  &:after {
21259
21443
  content: '';
@@ -21288,7 +21472,7 @@ const SelectWrapper = styled__default.default.div`
21288
21472
  }
21289
21473
  `}
21290
21474
 
21291
- ${props => props.validationStatus !== 'error' && styled.css`
21475
+ ${props => props.validationStatus !== 'error' && !props.disabled && styled.css`
21292
21476
  &:focus-within {
21293
21477
  &:after {
21294
21478
  border-color: ${({
@@ -21303,28 +21487,25 @@ const SelectWrapper = styled__default.default.div`
21303
21487
  background-color: ${props.theme.colors['bg/disabled']};
21304
21488
  color: ${props.theme.colors['text/disabled']};
21305
21489
 
21306
- select::placeholder {
21490
+ input::placeholder {
21307
21491
  color: ${props.theme.colors['text/disabled']};
21308
21492
  }
21309
21493
 
21310
- select {
21494
+ input {
21311
21495
  cursor: not-allowed;
21312
21496
  }
21313
21497
  `};
21314
21498
 
21315
21499
  ${props => props.hasLeadingVisual && styled.css`
21316
21500
  padding-left: ${forcePixelValue(props.theme.space[4])};
21317
- select {
21318
- padding-left: ${forcePixelValue(props.theme.space[2])};
21319
- }
21320
21501
  `}
21321
21502
 
21322
- transition: background-color 100ms;
21503
+ transition: color 100ms, background-color 100ms;
21323
21504
  &:after {
21324
21505
  transition: border-color 100ms;
21325
21506
  }
21326
21507
  `;
21327
- const UnstyledSelect = styled__default.default.select`
21508
+ const UnstyledInput = styled__default.default.input`
21328
21509
  font-size: inherit;
21329
21510
  font-weight: inherit;
21330
21511
  line-height: inherit;
@@ -21332,154 +21513,104 @@ const UnstyledSelect = styled__default.default.select`
21332
21513
  border-radius: inherit;
21333
21514
  color: inherit;
21334
21515
  transition: inherit;
21516
+ width: 100%;
21335
21517
 
21336
21518
  border: 0;
21519
+ padding: 0;
21337
21520
  background-color: transparent;
21338
- width: 100%;
21339
21521
  &:focus {
21340
21522
  outline: 0;
21341
21523
  }
21342
-
21343
- appearance: none;
21344
- -webkit-appearance: none;
21345
- -moz-appearance: none;
21346
21524
  `;
21347
- const BaseSelect = styled__default.default(UnstyledSelect)`
21348
- padding-top: ${({
21349
- theme
21350
- }) => forcePixelValue(theme.space[3])};
21351
- padding-right: ${({
21352
- theme
21353
- }) => forcePixelValue(theme.space[10])};
21354
- padding-bottom: ${({
21355
- theme
21356
- }) => forcePixelValue(theme.space[3])};
21357
- padding-left: ${({
21358
- theme
21359
- }) => forcePixelValue(theme.space[4])};
21360
-
21525
+ const BaseInput = styled__default.default(UnstyledInput)`
21361
21526
  white-space: pre;
21362
21527
  text-overflow: ellipsis;
21363
21528
  `;
21364
- var Select$1 = Object.assign( /*#__PURE__*/React.forwardRef(Select), {
21365
- Option: SelectOption
21366
- });
21529
+ var SearchSelectInput$1 = /*#__PURE__*/React.forwardRef(SearchSelectInput);
21367
21530
 
21368
- const TextInputTrailingAction = ({
21369
- icon: Icon,
21370
- disabled,
21531
+ const SelectOption = ({
21532
+ children: propChildren,
21371
21533
  ...props
21372
- }, ref) => /*#__PURE__*/jsxRuntimeExports.jsx(BaseTextInputTrailingAction, {
21373
- ref: ref,
21374
- ...props,
21375
- disabled: disabled,
21376
- "aria-disabled": disabled,
21377
- children: /*#__PURE__*/jsxRuntimeExports.jsx(Icon, {})
21378
- });
21379
- const BaseTextInputTrailingAction = styled__default.default(UnstyledButton)`
21380
- display: inline-flex;
21381
- padding: ${({
21382
- theme
21383
- }) => forcePixelValue(theme.space[2])};
21384
- background-color: ${({
21385
- theme
21386
- }) => theme.colors['bg/neutral/subtler']};
21387
- border-radius: ${({
21388
- theme
21389
- }) => forcePixelValue(theme.radii.full)};
21390
-
21391
- & svg {
21392
- width: ${forcePixelValue(16)};
21393
- height: ${forcePixelValue(16)};
21394
- color: ${({
21395
- theme
21396
- }) => theme.colors['icon/neutral/bolder']};
21397
- }
21398
-
21399
- &:hover {
21400
- background-color: ${({
21401
- theme
21402
- }) => theme.colors['bg/neutral/subtler/hovered']};
21403
- }
21404
-
21405
- &[aria-disabled='true'] {
21406
- cursor: not-allowed;
21407
- & svg {
21408
- color: ${({
21409
- theme
21410
- }) => theme.colors['icon/disabled']};
21411
- }
21412
- }
21413
-
21414
- ${sx}
21415
- `;
21416
- 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``;
21417
21542
 
21418
- const TextInput = ({
21419
- type = 'text',
21543
+ const Select = ({
21544
+ children,
21420
21545
  disabled,
21421
21546
  validationStatus,
21422
21547
  leadingVisual: LeadingVisual,
21423
- trailingVisual: TrailingVisual,
21424
- trailingAction,
21548
+ placeholder = '옵션 선택',
21425
21549
  ...props
21426
21550
  }, ref) => {
21427
- const inputRef = useProvidedOrCreatedRef(ref);
21428
- const focusInput = () => {
21429
- 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();
21430
21556
  };
21431
- return /*#__PURE__*/jsxRuntimeExports.jsxs(TextInputWrapper, {
21557
+ return /*#__PURE__*/jsxRuntimeExports.jsxs(SelectWrapper, {
21432
21558
  disabled: disabled,
21433
- onClick: focusInput,
21559
+ onClick: focusSelect,
21434
21560
  hasLeadingVisual: !isNullable(LeadingVisual),
21435
- hasTrailingVisual: !isNullable(TrailingVisual),
21436
- hasTrailingAction: !isNullable(trailingAction),
21437
21561
  validationStatus: validationStatus,
21562
+ isValueEmpty: isValueEmpty,
21438
21563
  children: [/*#__PURE__*/jsxRuntimeExports.jsx(View, {
21439
21564
  sx: {
21440
21565
  'flexShrink': 0,
21441
21566
  'fontSize': 'xxs',
21442
21567
  'fontWeight': 'medium',
21443
- 'color': color$1['text/neutral'],
21568
+ 'color': 'text/neutral',
21444
21569
  '& > svg': {
21445
21570
  display: 'block',
21446
21571
  width: 16,
21447
21572
  height: 16,
21448
- color: color$1['icon/neutral/bold']
21573
+ color: 'icon/neutral/bold'
21449
21574
  }
21450
21575
  },
21451
21576
  children: typeof LeadingVisual !== 'string' && reactIsExports.isValidElementType(LeadingVisual) ? /*#__PURE__*/jsxRuntimeExports.jsx(LeadingVisual, {}) : LeadingVisual
21452
- }), /*#__PURE__*/jsxRuntimeExports.jsx(BaseInput, {
21577
+ }), /*#__PURE__*/jsxRuntimeExports.jsxs(BaseSelect, {
21453
21578
  ref: e => {
21454
21579
  isFunction(ref) ? ref(e) : null;
21455
- inputRef.current = e;
21580
+ selectRef.current = e;
21456
21581
  },
21457
- type: type,
21582
+ placeholder: placeholder,
21458
21583
  disabled: disabled,
21459
- ...props
21460
- }), /*#__PURE__*/jsxRuntimeExports.jsxs(View, {
21461
- sx: {
21462
- 'display': 'flex',
21463
- 'alignItems': 'center',
21464
- 'columnGap': 2,
21465
- 'flexShrink': 0,
21466
- 'fontSize': 'xxs',
21467
- 'fontWeight': 'medium',
21468
- 'color': color$1['text/neutral'],
21469
- '& > svg': {
21470
- display: 'block',
21471
- width: 16,
21472
- height: 16,
21473
- 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
+ }
21474
21593
  }
21475
21594
  },
21476
- children: [typeof TrailingVisual !== 'string' && reactIsExports.isValidElementType(TrailingVisual) ? /*#__PURE__*/jsxRuntimeExports.jsx(TrailingVisual, {}) : TrailingVisual, trailingAction ? /*#__PURE__*/React.cloneElement(trailingAction, {
21477
- disabled: disabled
21478
- }) : 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
21479
21610
  })]
21480
21611
  });
21481
21612
  };
21482
- const TextInputWrapper = styled__default.default.div`
21613
+ const SelectWrapper = styled__default.default.div`
21483
21614
  position: relative;
21484
21615
  width: ${forcePixelValue('100%')};
21485
21616
  border-width: ${forcePixelValue(1)};
@@ -21493,7 +21624,6 @@ const TextInputWrapper = styled__default.default.div`
21493
21624
  background-color: ${({
21494
21625
  theme
21495
21626
  }) => theme.colors['bg/input']};
21496
- cursor: text;
21497
21627
  display: inline-flex;
21498
21628
  align-items: center;
21499
21629
 
@@ -21509,11 +21639,16 @@ const TextInputWrapper = styled__default.default.div`
21509
21639
  color: ${({
21510
21640
  theme
21511
21641
  }) => theme.colors['text/neutral']};
21512
- input::placeholder {
21513
- color: ${({
21514
- theme
21515
- }) => theme.colors['text/neutral/subtlest']};
21516
- }
21642
+
21643
+ /**
21644
+ * placeholder style
21645
+ */
21646
+ ${({
21647
+ theme,
21648
+ isValueEmpty
21649
+ }) => isValueEmpty ? styled.css`
21650
+ color: ${theme.colors['text/neutral/subtlest']};
21651
+ ` : null}
21517
21652
 
21518
21653
  &:after {
21519
21654
  content: '';
@@ -21563,43 +21698,28 @@ const TextInputWrapper = styled__default.default.div`
21563
21698
  background-color: ${props.theme.colors['bg/disabled']};
21564
21699
  color: ${props.theme.colors['text/disabled']};
21565
21700
 
21566
- input::placeholder {
21701
+ select::placeholder {
21567
21702
  color: ${props.theme.colors['text/disabled']};
21568
21703
  }
21569
21704
 
21570
- input {
21705
+ select {
21571
21706
  cursor: not-allowed;
21572
21707
  }
21573
21708
  `};
21574
21709
 
21575
21710
  ${props => props.hasLeadingVisual && styled.css`
21576
21711
  padding-left: ${forcePixelValue(props.theme.space[4])};
21577
- input {
21712
+ select {
21578
21713
  padding-left: ${forcePixelValue(props.theme.space[2])};
21579
21714
  }
21580
21715
  `}
21581
21716
 
21582
- ${props => props.hasTrailingVisual && styled.css`
21583
- padding-right: ${forcePixelValue(props.theme.space[4])};
21584
- `}
21585
-
21586
- ${props => props.hasTrailingAction && styled.css`
21587
- padding-right: ${forcePixelValue(props.theme.space[2])};
21588
- `}
21589
-
21590
- ${props => (props.hasTrailingVisual || props.hasTrailingAction) && styled.css`
21591
- input {
21592
- padding-right: ${forcePixelValue(props.theme.space[2])};
21593
- }
21594
- `}
21595
-
21596
-
21597
- transition: color 100ms, background-color 100ms;
21717
+ transition: background-color 100ms;
21598
21718
  &:after {
21599
21719
  transition: border-color 100ms;
21600
21720
  }
21601
21721
  `;
21602
- const UnstyledInput = styled__default.default.input`
21722
+ const UnstyledSelect = styled__default.default.select`
21603
21723
  font-size: inherit;
21604
21724
  font-weight: inherit;
21605
21725
  line-height: inherit;
@@ -21614,23 +21734,30 @@ const UnstyledInput = styled__default.default.input`
21614
21734
  &:focus {
21615
21735
  outline: 0;
21616
21736
  }
21737
+
21738
+ appearance: none;
21739
+ -webkit-appearance: none;
21740
+ -moz-appearance: none;
21617
21741
  `;
21618
- const BaseInput = styled__default.default(UnstyledInput)`
21742
+ const BaseSelect = styled__default.default(UnstyledSelect)`
21619
21743
  padding-top: ${({
21620
21744
  theme
21621
21745
  }) => forcePixelValue(theme.space[3])};
21622
21746
  padding-right: ${({
21623
21747
  theme
21624
- }) => forcePixelValue(theme.space[4])};
21748
+ }) => forcePixelValue(theme.space[10])};
21625
21749
  padding-bottom: ${({
21626
21750
  theme
21627
21751
  }) => forcePixelValue(theme.space[3])};
21628
21752
  padding-left: ${({
21629
21753
  theme
21630
21754
  }) => forcePixelValue(theme.space[4])};
21755
+
21756
+ white-space: pre;
21757
+ text-overflow: ellipsis;
21631
21758
  `;
21632
- var TextInput$1 = Object.assign( /*#__PURE__*/React.forwardRef(TextInput), {
21633
- TrailingAction: TextInputTrailingAction$1
21759
+ var Select$1 = Object.assign( /*#__PURE__*/React.forwardRef(Select), {
21760
+ Option: SelectOption
21634
21761
  });
21635
21762
 
21636
21763
  const FormControlCaption = ({
@@ -21789,7 +21916,7 @@ const FormControl = ({
21789
21916
  successMessage: FormControlSuccessMessage
21790
21917
  }
21791
21918
  });
21792
- const inputComponentCandidates = [TextInput$1, Select$1, OverlaySelectInput$1, Checkbox$1, ...additionalInputComponentCandidates];
21919
+ const inputComponentCandidates = [TextInput$1, Select$1, SearchSelectInput$1, Checkbox$1, ...additionalInputComponentCandidates];
21793
21920
  const InputComponent = restComponents.find(component => inputComponentCandidates.some(candidate => /*#__PURE__*/React.isValidElement(component) && component.type === candidate));
21794
21921
  const isHorizontalLayoutNeeded = /*#__PURE__*/React.isValidElement(InputComponent) && InputComponent.type === Checkbox$1;
21795
21922
  return /*#__PURE__*/jsxRuntimeExports.jsx(FormControlContext.Provider, {
@@ -21964,6 +22091,7 @@ const Pagination = ({
21964
22091
  onPreviousClick = noop$2,
21965
22092
  onNextClick = noop$2,
21966
22093
  renderPage = (page, i) => /*#__PURE__*/jsxRuntimeExports.jsx(PaginationPage, {
22094
+ type: 'button',
21967
22095
  onClick: () => onPageClick(page, i),
21968
22096
  selected: i === currentPageIndex,
21969
22097
  children: page.label
@@ -22005,6 +22133,7 @@ const Pagination = ({
22005
22133
  sx: sx,
22006
22134
  children: [renderPreviousPageDirection({
22007
22135
  previousPageDirectionProps: {
22136
+ type: 'button',
22008
22137
  onClick: () => onPreviousClick(currentPageIndex),
22009
22138
  disabled: currentPageIndex === 0
22010
22139
  }
@@ -22042,6 +22171,7 @@ const Pagination = ({
22042
22171
  originalIndex
22043
22172
  }) => renderPaginationPage(page, originalIndex))], renderNextPageDirection({
22044
22173
  nextPageDirectionProps: {
22174
+ type: 'button',
22045
22175
  onClick: () => onNextClick(currentPageIndex),
22046
22176
  disabled: currentPageIndex === totalPageCount - 1
22047
22177
  }
@@ -22249,6 +22379,7 @@ const Pill = ({
22249
22379
  hasRemoveButton: !isNullable(propOnRemove),
22250
22380
  disabled: disabled,
22251
22381
  ...props,
22382
+ type: 'button',
22252
22383
  children: [typeof LeadingVisual !== 'string' && reactIsExports.isValidElementType(LeadingVisual) ? /*#__PURE__*/jsxRuntimeExports.jsx(LeadingVisual, {}) : LeadingVisual, /*#__PURE__*/jsxRuntimeExports.jsx("span", {
22253
22384
  title: children?.toString(),
22254
22385
  children: children
@@ -24193,9 +24324,9 @@ exports.ItemList = ItemList;
24193
24324
  exports.MotionView = MotionView;
24194
24325
  exports.Overlay = Overlay$1;
24195
24326
  exports.OverlayPopper = OverlayPopper;
24196
- exports.OverlaySelectInput = OverlaySelectInput$1;
24197
24327
  exports.Pagination = index$3;
24198
24328
  exports.Pill = index$2;
24329
+ exports.SearchSelectInput = SearchSelectInput$1;
24199
24330
  exports.Select = Select$1;
24200
24331
  exports.Space = Space;
24201
24332
  exports.Spinner = Spinner;