@teamturing/react-kit 2.59.2 → 2.60.0

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,10 @@
1
+ import { InputHTMLAttributes } from 'react';
2
+ import { ButtonProps } from '../Button';
3
+ type Props = {
4
+ buttonProps?: Pick<ButtonProps, 'children' | 'variant' | 'size' | 'leadingIcon' | 'trailingIcon'>;
5
+ } & Omit<InputHTMLAttributes<HTMLInputElement>, 'type'>;
6
+ declare const _default: import("react").ForwardRefExoticComponent<{
7
+ buttonProps?: Pick<ButtonProps, "size" | "children" | "variant" | "leadingIcon" | "trailingIcon"> | undefined;
8
+ } & Omit<InputHTMLAttributes<HTMLInputElement>, "type"> & import("react").RefAttributes<HTMLInputElement>>;
9
+ export default _default;
10
+ export type { Props as UploadInputProps };
package/dist/index.d.ts CHANGED
@@ -101,6 +101,8 @@ export { default as Toast } from './core/Toast';
101
101
  export type { ToastProps } from './core/Toast';
102
102
  export { default as Tooltip } from './core/Tooltip';
103
103
  export type { TooltipProps } from './core/Tooltip';
104
+ export { default as UploadInput } from './core/UploadInput';
105
+ export type { UploadInputProps } from './core/UploadInput';
104
106
  export { default as View } from './core/View';
105
107
  export type { ViewProps } from './core/View';
106
108
  export { default as UnstyledButton } from './core/_UnstyledButton';
package/dist/index.js CHANGED
@@ -1115,7 +1115,7 @@ const UnstyledTable = styled__default.default.table`
1115
1115
 
1116
1116
  ${sx}
1117
1117
  `;
1118
- var index$e = Object.assign(UnstyledTable, {
1118
+ var index$f = Object.assign(UnstyledTable, {
1119
1119
  Head: UnstyledTableHead,
1120
1120
  Body: UnstyledTableBody,
1121
1121
  Row: UnstyledTableRow,
@@ -1795,7 +1795,7 @@ const BaseActionList = styled__default.default.ul`
1795
1795
 
1796
1796
  ${sx}
1797
1797
  `;
1798
- var index$d = Object.assign(ActionList, {
1798
+ var index$e = Object.assign(ActionList, {
1799
1799
  Item: ActionListItem,
1800
1800
  SectionDivider: ActionListSectionDivider,
1801
1801
  SectionHeader: ActionListSectionHeader
@@ -2545,7 +2545,7 @@ const BaseAvatarGroup = styled__default.default.ol`
2545
2545
 
2546
2546
  ${sx}
2547
2547
  `;
2548
- var index$c = Object.assign( /*#__PURE__*/React.forwardRef(AvatarGroup), {
2548
+ var index$d = Object.assign( /*#__PURE__*/React.forwardRef(AvatarGroup), {
2549
2549
  Item: AvatarGroupItem$1
2550
2550
  });
2551
2551
 
@@ -2699,7 +2699,7 @@ const BreadcrumbsItemWrapper = styled__default.default.span`
2699
2699
  }
2700
2700
  }
2701
2701
  `;
2702
- var index$b = Object.assign(Breadcrumbs, {
2702
+ var index$c = Object.assign(Breadcrumbs, {
2703
2703
  Item: BreadcrumbsItem
2704
2704
  });
2705
2705
 
@@ -3790,7 +3790,7 @@ const TextInputWrapper$1 = styled__default.default.div`
3790
3790
 
3791
3791
  ${sx}
3792
3792
  `;
3793
- const UnstyledInput$1 = styled__default.default.input`
3793
+ const UnstyledInput$2 = styled__default.default.input`
3794
3794
  font-size: inherit;
3795
3795
  font-weight: inherit;
3796
3796
  line-height: inherit;
@@ -3806,7 +3806,7 @@ const UnstyledInput$1 = styled__default.default.input`
3806
3806
  outline: 0;
3807
3807
  }
3808
3808
  `;
3809
- const BaseInput$1 = styled__default.default(UnstyledInput$1)`
3809
+ const BaseInput$1 = styled__default.default(UnstyledInput$2)`
3810
3810
  padding-top: ${({
3811
3811
  theme
3812
3812
  }) => utils.forcePixelValue(theme.space[3])};
@@ -4164,7 +4164,7 @@ const TextInputWrapper = styled__default.default.div`
4164
4164
  transition: border-color 100ms;
4165
4165
  }
4166
4166
  `;
4167
- const UnstyledInput = styled__default.default.input`
4167
+ const UnstyledInput$1 = styled__default.default.input`
4168
4168
  font-size: inherit;
4169
4169
  font-weight: inherit;
4170
4170
  line-height: inherit;
@@ -4181,7 +4181,7 @@ const UnstyledInput = styled__default.default.input`
4181
4181
  outline: 0;
4182
4182
  }
4183
4183
  `;
4184
- const BaseInput = styled__default.default(UnstyledInput)`
4184
+ const BaseInput = styled__default.default(UnstyledInput$1)`
4185
4185
  white-space: pre;
4186
4186
  text-overflow: ellipsis;
4187
4187
  `;
@@ -5419,7 +5419,7 @@ const CheckboxOrRadioGroupFormControl = ({
5419
5419
  })
5420
5420
  });
5421
5421
  };
5422
- var index$a = Object.assign( /*#__PURE__*/React.forwardRef(CheckboxOrRadioGroupFormControl), {
5422
+ var index$b = Object.assign( /*#__PURE__*/React.forwardRef(CheckboxOrRadioGroupFormControl), {
5423
5423
  Label: CheckboxOrRadioGroupFormControlLabel,
5424
5424
  Caption: CheckboxOrRadioGroupFormControlCaption,
5425
5425
  ErrorMessage: CheckboxOrRadioGroupFormControlErrorMessage,
@@ -5656,7 +5656,7 @@ const BaseClickArea = styled__default.default(View)`
5656
5656
  }) => disabled ? 'not-allowed' : 'pointer'};
5657
5657
  }
5658
5658
  `;
5659
- var index$9 = /*#__PURE__*/React.forwardRef(ClickArea);
5659
+ var index$a = /*#__PURE__*/React.forwardRef(ClickArea);
5660
5660
 
5661
5661
  const CounterBadge = ({
5662
5662
  variant = 'red',
@@ -5861,7 +5861,7 @@ const BaseDatagrid = styled__default.default.div`
5861
5861
 
5862
5862
  border-radius: inherit;
5863
5863
  `;
5864
- var index$8 = Object.assign(Datagrid, {
5864
+ var index$9 = Object.assign(Datagrid, {
5865
5865
  Header: DatagridHeader,
5866
5866
  Subheader: DatagridSubheader,
5867
5867
  Body: DatagridBody,
@@ -6433,7 +6433,7 @@ const BaseDialog = styled__default.default.div(({
6433
6433
  overflow: 'hidden',
6434
6434
  margin: 'auto'
6435
6435
  }), sx);
6436
- var index$7 = Object.assign( /*#__PURE__*/React.forwardRef(Dialog), {
6436
+ var index$8 = Object.assign( /*#__PURE__*/React.forwardRef(Dialog), {
6437
6437
  UnstyledHeader: UnstyledDialogHeader,
6438
6438
  UnstyledBody: UnstyledDialogBody,
6439
6439
  UnstyledFooter: UnstyledDialogFooter,
@@ -6760,7 +6760,7 @@ const BaseDrawer = styled__default.default.div(({
6760
6760
  }
6761
6761
  }
6762
6762
  }), sx);
6763
- var index$6 = Object.assign( /*#__PURE__*/React.forwardRef(Drawer), {
6763
+ var index$7 = Object.assign( /*#__PURE__*/React.forwardRef(Drawer), {
6764
6764
  UnstyledHeader: UnstyledDrawerHeader,
6765
6765
  UnstyledBody: UnstyledDrawerBody,
6766
6766
  UnstyledFooter: UnstyledDrawerFooter,
@@ -7243,7 +7243,7 @@ const BaseFlash = styled__default.default.div`
7243
7243
 
7244
7244
  ${sx}
7245
7245
  `;
7246
- var index$5 = /*#__PURE__*/React.forwardRef(Flash);
7246
+ var index$6 = /*#__PURE__*/React.forwardRef(Flash);
7247
7247
 
7248
7248
  const GradientText = styled__default.default(Text)(({
7249
7249
  theme
@@ -7401,7 +7401,7 @@ const BaseIconToggleButton = styled__default.default(UnstyledButton)(({
7401
7401
  }
7402
7402
  }
7403
7403
  }), sx);
7404
- var index$4 = /*#__PURE__*/React.forwardRef(IconToggleButton);
7404
+ var index$5 = /*#__PURE__*/React.forwardRef(IconToggleButton);
7405
7405
 
7406
7406
  const Pagination = ({
7407
7407
  pages: propPages,
@@ -7664,7 +7664,7 @@ const PaginationTruncationIndicator = styled__default.default.div`
7664
7664
 
7665
7665
  ${sx}
7666
7666
  `;
7667
- var index$3 = Object.assign(Pagination, {
7667
+ var index$4 = Object.assign(Pagination, {
7668
7668
  Page: PaginationPage,
7669
7669
  PageDirection: PaginationPageDirection,
7670
7670
  TruncationIndicator: PaginationTruncationIndicator
@@ -7879,7 +7879,7 @@ const BasePill = styled__default.default(UnstyledButton)`
7879
7879
 
7880
7880
  ${sx}
7881
7881
  `;
7882
- var index$2 = /*#__PURE__*/React.forwardRef(Pill);
7882
+ var index$3 = /*#__PURE__*/React.forwardRef(Pill);
7883
7883
 
7884
7884
  const Stack = /*#__PURE__*/React.forwardRef(({
7885
7885
  gapX = 0,
@@ -8276,7 +8276,7 @@ const Tab = ({
8276
8276
  })
8277
8277
  });
8278
8278
  };
8279
- var index$1 = Object.assign(Tab, {
8279
+ var index$2 = Object.assign(Tab, {
8280
8280
  Item: TabItem
8281
8281
  });
8282
8282
 
@@ -8394,6 +8394,209 @@ const BaseToast = styled__default.default.div(({
8394
8394
  }
8395
8395
  }));
8396
8396
 
8397
+ const UploadInput = ({
8398
+ buttonProps: propsButtonProps,
8399
+ placeholder = '파일을 끌어다 놓으세요',
8400
+ accept,
8401
+ disabled,
8402
+ ...props
8403
+ }, ref) => {
8404
+ const defaultButtonProps = {
8405
+ children: '파일 선택',
8406
+ size: 's',
8407
+ variant: 'neutral'
8408
+ };
8409
+ const buttonProps = {
8410
+ ...defaultButtonProps,
8411
+ ...propsButtonProps
8412
+ };
8413
+ const inputRef = React.useRef(null);
8414
+ const handleButtonClick = () => {
8415
+ inputRef.current?.click();
8416
+ };
8417
+ const handleDragOver = e => e.preventDefault();
8418
+ const handleDragEnter = e => {
8419
+ if (e.currentTarget.contains(e.relatedTarget)) return;
8420
+ e.currentTarget?.classList.add('upload-input__wrapper__active');
8421
+ };
8422
+ const handleDragLeave = e => {
8423
+ if (e.currentTarget.contains(e.relatedTarget)) return;
8424
+ e.currentTarget?.classList.remove('upload-input__wrapper__active');
8425
+ };
8426
+ const handleDrop = e => {
8427
+ e.preventDefault();
8428
+ const files = e.dataTransfer?.files ?? [];
8429
+ if (files.length < 1) return;
8430
+ if (!props.multiple && files.length > 1) {
8431
+ e.currentTarget?.classList.remove('upload-input__wrapper__active');
8432
+ return;
8433
+ }
8434
+ const isAcceptableFile = new RegExp((accept || '*').replace(/\*/g, '.*').replace(/,/g, '|').replace(/\s/g, '')).test(files[0].type);
8435
+ if (!isAcceptableFile) return;
8436
+ e.currentTarget?.classList.remove('upload-input__wrapper__active');
8437
+ if (inputRef && inputRef.current && files) {
8438
+ const currentFiles = inputRef.current.files;
8439
+ if (files.length !== currentFiles?.length) {
8440
+ inputRef.current.files = files;
8441
+ inputRef.current.dispatchEvent(new Event('change', {
8442
+ bubbles: true
8443
+ }));
8444
+ return;
8445
+ }
8446
+ const isSameFiles = Array.from(files).every((file, index) => {
8447
+ const currentFile = currentFiles?.item(index);
8448
+ return file.name === currentFile?.name && file.size === currentFile?.size && file.lastModified === currentFile?.lastModified;
8449
+ });
8450
+ if (isSameFiles) return;
8451
+ inputRef.current.files = files;
8452
+ inputRef.current.dispatchEvent(new Event('change', {
8453
+ bubbles: true
8454
+ }));
8455
+ }
8456
+ };
8457
+ React.useImperativeHandle(ref, () => inputRef.current, []);
8458
+ return /*#__PURE__*/jsxRuntime.jsxs(UploadInputWrapper, {
8459
+ disabled: disabled,
8460
+ ...(disabled ? {} : {
8461
+ onDragOver: handleDragOver,
8462
+ onDragEnter: handleDragEnter,
8463
+ onDragLeave: handleDragLeave,
8464
+ onDrop: handleDrop
8465
+ }),
8466
+ children: [/*#__PURE__*/jsxRuntime.jsx(icons.ShareIcon, {}), /*#__PURE__*/jsxRuntime.jsx("span", {
8467
+ children: placeholder
8468
+ }), /*#__PURE__*/jsxRuntime.jsx(Button, {
8469
+ type: 'button',
8470
+ ...buttonProps,
8471
+ onClick: handleButtonClick,
8472
+ disabled: disabled
8473
+ }), /*#__PURE__*/jsxRuntime.jsx(UnstyledInput, {
8474
+ ref: inputRef,
8475
+ ...props,
8476
+ type: 'file',
8477
+ hidden: true,
8478
+ accept: accept,
8479
+ tabIndex: -1,
8480
+ disabled: disabled
8481
+ })]
8482
+ });
8483
+ };
8484
+ const UploadInputWrapper = styled__default.default.div`
8485
+ width: 100%;
8486
+
8487
+ display: flex;
8488
+ flex-direction: column;
8489
+ align-items: center;
8490
+ justify-content: center;
8491
+ row-gap: ${({
8492
+ theme
8493
+ }) => utils.forcePixelValue(theme.space[2])};
8494
+ padding: ${({
8495
+ theme
8496
+ }) => utils.forcePixelValue(theme.space[4])};
8497
+
8498
+ & > svg {
8499
+ width: 16px;
8500
+ height: 16px;
8501
+ color: ${({
8502
+ theme
8503
+ }) => theme.colors['icon/neutral/bold']};
8504
+ }
8505
+
8506
+ & > span {
8507
+ font-size: ${({
8508
+ theme
8509
+ }) => utils.forcePixelValue(theme.fontSizes.xs)};
8510
+ font-weight: ${({
8511
+ theme
8512
+ }) => theme.fontWeights.medium};
8513
+ line-height: ${({
8514
+ theme
8515
+ }) => theme.lineHeights[2]};
8516
+ color: ${({
8517
+ theme
8518
+ }) => theme.colors['text/neutral/subtlest']};
8519
+ }
8520
+
8521
+ border-width: ${utils.forcePixelValue(1)};
8522
+ border-style: dashed;
8523
+ border-color: ${({
8524
+ theme
8525
+ }) => theme.colors['border/neutral/bolder']};
8526
+ border-radius: ${({
8527
+ theme
8528
+ }) => utils.forcePixelValue(theme.radii.xs)};
8529
+ background-color: ${({
8530
+ theme
8531
+ }) => theme.colors['bg/neutral/subtlest']};
8532
+
8533
+ &.upload-input__wrapper__active {
8534
+ background-color: ${({
8535
+ theme
8536
+ }) => theme.colors['bg/selected/subtle']};
8537
+ }
8538
+
8539
+ position: relative;
8540
+ &:after {
8541
+ content: '';
8542
+ position: absolute;
8543
+ top: ${utils.forcePixelValue(-1)};
8544
+ right: ${utils.forcePixelValue(-1)};
8545
+ bottom: ${utils.forcePixelValue(-1)};
8546
+ left: ${utils.forcePixelValue(-1)};
8547
+
8548
+ border: ${utils.forcePixelValue(2)} solid transparent;
8549
+ border-radius: ${({
8550
+ theme
8551
+ }) => utils.forcePixelValue(theme.radii.xs)};
8552
+ pointer-events: none;
8553
+ }
8554
+ &:focus-within {
8555
+ &:after {
8556
+ border-color: ${({
8557
+ theme
8558
+ }) => theme.colors['border/focused']};
8559
+ }
8560
+ }
8561
+
8562
+ & > button:focus-visible {
8563
+ outline: none;
8564
+ }
8565
+
8566
+ ${({
8567
+ theme,
8568
+ disabled
8569
+ }) => disabled ? {
8570
+ 'cursor': 'not-allowed',
8571
+ 'backgroundColor': theme.colors['bg/disabled'],
8572
+ '& > svg': {
8573
+ color: theme.colors['icon/disabled']
8574
+ },
8575
+ '& > span': {
8576
+ color: theme.colors['text/disabled']
8577
+ }
8578
+ } : {}}
8579
+
8580
+ transition: background-color 200ms ease-in-out;
8581
+ `;
8582
+ const UnstyledInput = styled__default.default.input`
8583
+ font-size: inherit;
8584
+ font-weight: inherit;
8585
+ line-height: inherit;
8586
+ font-family: inherit;
8587
+ border-radius: inherit;
8588
+ color: inherit;
8589
+ transition: inherit;
8590
+
8591
+ border: 0;
8592
+ background-color: transparent;
8593
+ width: 100%;
8594
+ &:focus {
8595
+ outline: 0;
8596
+ }
8597
+ `;
8598
+ var index$1 = /*#__PURE__*/React.forwardRef(UploadInput);
8599
+
8397
8600
  const useMediaQuery = query => {
8398
8601
  const getMatches = query => {
8399
8602
  /**
@@ -8731,40 +8934,40 @@ Object.defineProperty(exports, 'AnimatePresence', {
8731
8934
  enumerable: true,
8732
8935
  get: function () { return framerMotion.AnimatePresence; }
8733
8936
  });
8734
- exports.ActionList = index$d;
8937
+ exports.ActionList = index$e;
8735
8938
  exports.Avatar = Avatar;
8736
- exports.AvatarGroup = index$c;
8939
+ exports.AvatarGroup = index$d;
8737
8940
  exports.BadgeAttacher = BadgeAttacher;
8738
- exports.Breadcrumbs = index$b;
8941
+ exports.Breadcrumbs = index$c;
8739
8942
  exports.Button = Button;
8740
8943
  exports.Card = Card;
8741
8944
  exports.Checkbox = Checkbox$1;
8742
8945
  exports.CheckboxGroup = CheckboxGroup$1;
8743
- exports.CheckboxOrRadioGroupFormControl = index$a;
8946
+ exports.CheckboxOrRadioGroupFormControl = index$b;
8744
8947
  exports.Chip = Chip;
8745
- exports.ClickArea = index$9;
8948
+ exports.ClickArea = index$a;
8746
8949
  exports.CounterBadge = CounterBadge;
8747
- exports.Datagrid = index$8;
8950
+ exports.Datagrid = index$9;
8748
8951
  exports.DescriptionList = DescriptionList;
8749
- exports.Dialog = index$7;
8750
- exports.Drawer = index$6;
8952
+ exports.Dialog = index$8;
8953
+ exports.Drawer = index$7;
8751
8954
  exports.EmptyState = EmptyState;
8752
8955
  exports.EnigmaUI = index;
8753
8956
  exports.FileItem = FileItem;
8754
- exports.Flash = index$5;
8957
+ exports.Flash = index$6;
8755
8958
  exports.FormControl = FormControl$1;
8756
8959
  exports.GradientText = GradientText;
8757
8960
  exports.Grid = Grid$1;
8758
8961
  exports.HorizontalDivider = HorizontalDivider;
8759
8962
  exports.IconButton = IconButton;
8760
- exports.IconToggleButton = index$4;
8963
+ exports.IconToggleButton = index$5;
8761
8964
  exports.Image = Image;
8762
8965
  exports.ItemList = ItemList;
8763
8966
  exports.MotionView = MotionView;
8764
8967
  exports.Overlay = Overlay$1;
8765
8968
  exports.OverlayPopper = OverlayPopper;
8766
- exports.Pagination = index$3;
8767
- exports.Pill = index$2;
8969
+ exports.Pagination = index$4;
8970
+ exports.Pill = index$3;
8768
8971
  exports.Radio = Radio$1;
8769
8972
  exports.RadioGroup = RadioGroup$1;
8770
8973
  exports.SearchSelectInput = SearchSelectInput$1;
@@ -8774,7 +8977,7 @@ exports.Spinner = Spinner;
8774
8977
  exports.Stack = Stack$1;
8775
8978
  exports.StyledIcon = StyledIcon;
8776
8979
  exports.Switch = Switch$1;
8777
- exports.Tab = index$1;
8980
+ exports.Tab = index$2;
8778
8981
  exports.Text = Text;
8779
8982
  exports.TextInput = TextInput$1;
8780
8983
  exports.Textarea = Textarea;
@@ -8782,7 +8985,8 @@ exports.ThemeProvider = ThemeProvider;
8782
8985
  exports.Toast = Toast;
8783
8986
  exports.Tooltip = Tooltip;
8784
8987
  exports.UnstyledButton = UnstyledButton;
8785
- exports.UnstyledTable = index$e;
8988
+ exports.UnstyledTable = index$f;
8989
+ exports.UploadInput = index$1;
8786
8990
  exports.View = View;
8787
8991
  exports.columnGap = columnGap;
8788
8992
  exports.gap = gap;
@@ -0,0 +1,211 @@
1
+ import { ShareIcon } from '@teamturing/icons';
2
+ import { forcePixelValue } from '@teamturing/utils';
3
+ import { forwardRef, useRef, useImperativeHandle } from 'react';
4
+ import styled from 'styled-components';
5
+ import Button from '../Button/index.js';
6
+ import { jsxs, jsx } from 'react/jsx-runtime';
7
+
8
+ const UploadInput = ({
9
+ buttonProps: propsButtonProps,
10
+ placeholder = '파일을 끌어다 놓으세요',
11
+ accept,
12
+ disabled,
13
+ ...props
14
+ }, ref) => {
15
+ const defaultButtonProps = {
16
+ children: '파일 선택',
17
+ size: 's',
18
+ variant: 'neutral'
19
+ };
20
+ const buttonProps = {
21
+ ...defaultButtonProps,
22
+ ...propsButtonProps
23
+ };
24
+ const inputRef = useRef(null);
25
+ const handleButtonClick = () => {
26
+ inputRef.current?.click();
27
+ };
28
+ const handleDragOver = e => e.preventDefault();
29
+ const handleDragEnter = e => {
30
+ if (e.currentTarget.contains(e.relatedTarget)) return;
31
+ e.currentTarget?.classList.add('upload-input__wrapper__active');
32
+ };
33
+ const handleDragLeave = e => {
34
+ if (e.currentTarget.contains(e.relatedTarget)) return;
35
+ e.currentTarget?.classList.remove('upload-input__wrapper__active');
36
+ };
37
+ const handleDrop = e => {
38
+ e.preventDefault();
39
+ const files = e.dataTransfer?.files ?? [];
40
+ if (files.length < 1) return;
41
+ if (!props.multiple && files.length > 1) {
42
+ e.currentTarget?.classList.remove('upload-input__wrapper__active');
43
+ return;
44
+ }
45
+ const isAcceptableFile = new RegExp((accept || '*').replace(/\*/g, '.*').replace(/,/g, '|').replace(/\s/g, '')).test(files[0].type);
46
+ if (!isAcceptableFile) return;
47
+ e.currentTarget?.classList.remove('upload-input__wrapper__active');
48
+ if (inputRef && inputRef.current && files) {
49
+ const currentFiles = inputRef.current.files;
50
+ if (files.length !== currentFiles?.length) {
51
+ inputRef.current.files = files;
52
+ inputRef.current.dispatchEvent(new Event('change', {
53
+ bubbles: true
54
+ }));
55
+ return;
56
+ }
57
+ const isSameFiles = Array.from(files).every((file, index) => {
58
+ const currentFile = currentFiles?.item(index);
59
+ return file.name === currentFile?.name && file.size === currentFile?.size && file.lastModified === currentFile?.lastModified;
60
+ });
61
+ if (isSameFiles) return;
62
+ inputRef.current.files = files;
63
+ inputRef.current.dispatchEvent(new Event('change', {
64
+ bubbles: true
65
+ }));
66
+ }
67
+ };
68
+ useImperativeHandle(ref, () => inputRef.current, []);
69
+ return /*#__PURE__*/jsxs(UploadInputWrapper, {
70
+ disabled: disabled,
71
+ ...(disabled ? {} : {
72
+ onDragOver: handleDragOver,
73
+ onDragEnter: handleDragEnter,
74
+ onDragLeave: handleDragLeave,
75
+ onDrop: handleDrop
76
+ }),
77
+ children: [/*#__PURE__*/jsx(ShareIcon, {}), /*#__PURE__*/jsx("span", {
78
+ children: placeholder
79
+ }), /*#__PURE__*/jsx(Button, {
80
+ type: 'button',
81
+ ...buttonProps,
82
+ onClick: handleButtonClick,
83
+ disabled: disabled
84
+ }), /*#__PURE__*/jsx(UnstyledInput, {
85
+ ref: inputRef,
86
+ ...props,
87
+ type: 'file',
88
+ hidden: true,
89
+ accept: accept,
90
+ tabIndex: -1,
91
+ disabled: disabled
92
+ })]
93
+ });
94
+ };
95
+ const UploadInputWrapper = styled.div`
96
+ width: 100%;
97
+
98
+ display: flex;
99
+ flex-direction: column;
100
+ align-items: center;
101
+ justify-content: center;
102
+ row-gap: ${({
103
+ theme
104
+ }) => forcePixelValue(theme.space[2])};
105
+ padding: ${({
106
+ theme
107
+ }) => forcePixelValue(theme.space[4])};
108
+
109
+ & > svg {
110
+ width: 16px;
111
+ height: 16px;
112
+ color: ${({
113
+ theme
114
+ }) => theme.colors['icon/neutral/bold']};
115
+ }
116
+
117
+ & > span {
118
+ font-size: ${({
119
+ theme
120
+ }) => forcePixelValue(theme.fontSizes.xs)};
121
+ font-weight: ${({
122
+ theme
123
+ }) => theme.fontWeights.medium};
124
+ line-height: ${({
125
+ theme
126
+ }) => theme.lineHeights[2]};
127
+ color: ${({
128
+ theme
129
+ }) => theme.colors['text/neutral/subtlest']};
130
+ }
131
+
132
+ border-width: ${forcePixelValue(1)};
133
+ border-style: dashed;
134
+ border-color: ${({
135
+ theme
136
+ }) => theme.colors['border/neutral/bolder']};
137
+ border-radius: ${({
138
+ theme
139
+ }) => forcePixelValue(theme.radii.xs)};
140
+ background-color: ${({
141
+ theme
142
+ }) => theme.colors['bg/neutral/subtlest']};
143
+
144
+ &.upload-input__wrapper__active {
145
+ background-color: ${({
146
+ theme
147
+ }) => theme.colors['bg/selected/subtle']};
148
+ }
149
+
150
+ position: relative;
151
+ &:after {
152
+ content: '';
153
+ position: absolute;
154
+ top: ${forcePixelValue(-1)};
155
+ right: ${forcePixelValue(-1)};
156
+ bottom: ${forcePixelValue(-1)};
157
+ left: ${forcePixelValue(-1)};
158
+
159
+ border: ${forcePixelValue(2)} solid transparent;
160
+ border-radius: ${({
161
+ theme
162
+ }) => forcePixelValue(theme.radii.xs)};
163
+ pointer-events: none;
164
+ }
165
+ &:focus-within {
166
+ &:after {
167
+ border-color: ${({
168
+ theme
169
+ }) => theme.colors['border/focused']};
170
+ }
171
+ }
172
+
173
+ & > button:focus-visible {
174
+ outline: none;
175
+ }
176
+
177
+ ${({
178
+ theme,
179
+ disabled
180
+ }) => disabled ? {
181
+ 'cursor': 'not-allowed',
182
+ 'backgroundColor': theme.colors['bg/disabled'],
183
+ '& > svg': {
184
+ color: theme.colors['icon/disabled']
185
+ },
186
+ '& > span': {
187
+ color: theme.colors['text/disabled']
188
+ }
189
+ } : {}}
190
+
191
+ transition: background-color 200ms ease-in-out;
192
+ `;
193
+ const UnstyledInput = styled.input`
194
+ font-size: inherit;
195
+ font-weight: inherit;
196
+ line-height: inherit;
197
+ font-family: inherit;
198
+ border-radius: inherit;
199
+ color: inherit;
200
+ transition: inherit;
201
+
202
+ border: 0;
203
+ background-color: transparent;
204
+ width: 100%;
205
+ &:focus {
206
+ outline: 0;
207
+ }
208
+ `;
209
+ var index = /*#__PURE__*/forwardRef(UploadInput);
210
+
211
+ export { index as default };
package/esm/index.js CHANGED
@@ -49,6 +49,7 @@ export { default as TextInput } from './core/TextInput/index.js';
49
49
  export { default as ThemeProvider } from './core/ThemeProvider/index.js';
50
50
  export { default as Toast } from './core/Toast/index.js';
51
51
  export { default as Tooltip } from './core/Tooltip/index.js';
52
+ export { default as UploadInput } from './core/UploadInput/index.js';
52
53
  export { default as View } from './core/View/index.js';
53
54
  export { default as UnstyledButton } from './core/_UnstyledButton.js';
54
55
  export { default as EnigmaUI } from './enigma/EnigmaUI/index.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@teamturing/react-kit",
3
- "version": "2.59.2",
3
+ "version": "2.60.0",
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",
@@ -64,5 +64,5 @@
64
64
  "react-textarea-autosize": "^8.5.3",
65
65
  "styled-system": "^5.1.5"
66
66
  },
67
- "gitHead": "e3aee774b2fa8b4016b97cdbcc21eb5df93b01b7"
67
+ "gitHead": "7f481703b05fc102b053df24bcceca284c1c72ec"
68
68
  }