oneslash-design-system 1.2.24 → 1.2.26
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/components/alert.d.ts +4 -2
- package/dist/components/alert.jsx +18 -13
- package/dist/components/button.d.ts +3 -2
- package/dist/components/button.jsx +7 -3
- package/dist/components/checkBox.d.ts +2 -1
- package/dist/components/checkBox.jsx +13 -6
- package/dist/components/emptyBox.d.ts +2 -1
- package/dist/components/emptyBox.jsx +9 -4
- package/dist/components/icon.d.ts +12 -0
- package/dist/components/icon.jsx +30 -0
- package/dist/components/line.d.ts +7 -0
- package/dist/components/line.jsx +10 -0
- package/dist/components/menuItem.d.ts +4 -1
- package/dist/components/menuItem.jsx +17 -10
- package/dist/components/modal.d.ts +3 -2
- package/dist/components/modal.jsx +43 -23
- package/dist/components/radioGroup.d.ts +1 -0
- package/dist/components/radioGroup.jsx +4 -1
- package/dist/components/tab.d.ts +6 -1
- package/dist/components/tab.jsx +11 -9
- package/dist/components/tabsContainer.jsx +4 -1
- package/dist/components/tag.d.ts +7 -4
- package/dist/components/tag.jsx +105 -28
- package/dist/components/textField.d.ts +5 -2
- package/dist/components/textField.jsx +29 -16
- package/dist/components/textarea.d.ts +4 -2
- package/dist/components/textarea.jsx +31 -11
- package/dist/output.css +549 -446
- package/dist/stories/Alert.stories.d.ts +15 -0
- package/dist/stories/Alert.stories.jsx +121 -0
- package/dist/stories/Button.stories.d.ts +13 -0
- package/dist/stories/Button.stories.jsx +89 -0
- package/dist/stories/Checkbox.stories.d.ts +10 -0
- package/dist/stories/Checkbox.stories.jsx +45 -0
- package/dist/stories/EmptyBox.stories.d.ts +7 -0
- package/dist/stories/EmptyBox.stories.jsx +30 -0
- package/dist/stories/Icon.stories.d.ts +13 -0
- package/dist/stories/Icon.stories.jsx +130 -0
- package/dist/stories/IconButton.stories.d.ts +13 -0
- package/dist/stories/IconButton.stories.jsx +87 -0
- package/dist/stories/Line.stories.d.ts +9 -0
- package/dist/stories/Line.stories.jsx +64 -0
- package/dist/stories/Link.stories.d.ts +10 -0
- package/dist/stories/Link.stories.jsx +59 -0
- package/dist/stories/LoadingScreen.stories.d.ts +10 -0
- package/dist/stories/LoadingScreen.stories.jsx +39 -0
- package/dist/stories/Menu.stories.d.ts +8 -0
- package/dist/stories/Menu.stories.jsx +42 -0
- package/dist/stories/MenuItem.stories.d.ts +12 -0
- package/dist/stories/MenuItem.stories.jsx +70 -0
- package/dist/stories/Modal.stories.d.ts +10 -0
- package/dist/stories/Modal.stories.jsx +77 -0
- package/dist/stories/Navigation.stories.d.ts +7 -0
- package/dist/stories/Navigation.stories.jsx +31 -0
- package/dist/stories/Popover.stories.d.ts +7 -0
- package/dist/stories/Popover.stories.jsx +47 -0
- package/dist/stories/RadioGroup.stories.d.ts +8 -0
- package/dist/stories/RadioGroup.stories.jsx +53 -0
- package/dist/stories/Select.stories.d.ts +10 -0
- package/dist/stories/Select.stories.jsx +85 -0
- package/dist/stories/Tab.stories.d.ts +11 -0
- package/dist/stories/Tab.stories.jsx +63 -0
- package/dist/stories/Table.stories.d.ts +8 -0
- package/dist/stories/Table.stories.jsx +84 -0
- package/dist/stories/TabsContainer.stories.d.ts +10 -0
- package/dist/stories/TabsContainer.stories.jsx +52 -0
- package/dist/stories/Tag.stories.d.ts +19 -0
- package/dist/stories/Tag.stories.jsx +168 -0
- package/dist/stories/TextField.stories.d.ts +13 -0
- package/dist/stories/TextField.stories.jsx +96 -0
- package/dist/stories/Textarea.stories.d.ts +12 -0
- package/dist/stories/Textarea.stories.jsx +84 -0
- package/dist/stories/TimeStamp.stories.d.ts +16 -0
- package/dist/stories/TimeStamp.stories.jsx +140 -0
- package/dist/stories/Tooltip.stories.d.ts +9 -0
- package/dist/stories/Tooltip.stories.jsx +52 -0
- package/dist/stories/UserImage.stories.d.ts +10 -0
- package/dist/stories/UserImage.stories.jsx +46 -0
- package/dist/tailwind.config.js +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +10 -3
package/dist/components/tag.jsx
CHANGED
|
@@ -1,43 +1,120 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import React, { useState
|
|
3
|
-
import
|
|
2
|
+
import React, { useState } from 'react';
|
|
3
|
+
import { icons } from 'lucide-react';
|
|
4
|
+
var colorConfig = {
|
|
5
|
+
default: {
|
|
6
|
+
bg: 'bg-light-secondary-light dark:bg-dark-secondary-light',
|
|
7
|
+
text: 'text-light-text-primary dark:text-dark-text-primary',
|
|
8
|
+
textOnly: 'text-light-text-secondary dark:text-dark-text-secondary',
|
|
9
|
+
border: 'border-light-misc-divider dark:border-dark-misc-divider',
|
|
10
|
+
dot: 'bg-light-text-secondary dark:bg-dark-text-secondary',
|
|
11
|
+
hasBorderTextOnly: false,
|
|
12
|
+
},
|
|
13
|
+
success: {
|
|
14
|
+
bg: 'bg-light-success-main dark:bg-dark-success-main',
|
|
15
|
+
text: 'text-white dark:text-dark-text-primary',
|
|
16
|
+
textOnly: 'text-light-success-main dark:text-dark-success-main',
|
|
17
|
+
border: 'border-light-success-main dark:border-dark-success-main',
|
|
18
|
+
dot: 'bg-light-success-main dark:bg-dark-success-main',
|
|
19
|
+
hasBorderTextOnly: true,
|
|
20
|
+
},
|
|
21
|
+
warning: {
|
|
22
|
+
bg: 'bg-light-warning-main dark:bg-dark-warning-main',
|
|
23
|
+
text: 'text-white dark:text-dark-text-primary',
|
|
24
|
+
textOnly: 'text-light-warning-main dark:text-dark-warning-main',
|
|
25
|
+
border: 'border-light-warning-main dark:border-dark-warning-main',
|
|
26
|
+
dot: 'bg-light-warning-main dark:bg-dark-warning-main',
|
|
27
|
+
hasBorderTextOnly: true,
|
|
28
|
+
},
|
|
29
|
+
error: {
|
|
30
|
+
bg: 'bg-light-error-main dark:bg-dark-error-main',
|
|
31
|
+
text: 'text-white dark:text-dark-text-primary',
|
|
32
|
+
textOnly: 'text-light-error-main dark:text-dark-error-main',
|
|
33
|
+
border: 'border-light-error-main dark:border-dark-error-main',
|
|
34
|
+
dot: 'bg-light-error-main dark:bg-dark-error-main',
|
|
35
|
+
hasBorderTextOnly: true,
|
|
36
|
+
},
|
|
37
|
+
info: {
|
|
38
|
+
bg: 'bg-light-info-main dark:bg-dark-info-main',
|
|
39
|
+
text: 'text-white dark:text-dark-text-primary',
|
|
40
|
+
textOnly: 'text-light-info-main dark:text-dark-info-main',
|
|
41
|
+
border: 'border-light-info-main dark:border-dark-info-main',
|
|
42
|
+
dot: 'bg-light-info-main dark:bg-dark-info-main',
|
|
43
|
+
hasBorderTextOnly: true,
|
|
44
|
+
},
|
|
45
|
+
};
|
|
4
46
|
export default function Tag(_a) {
|
|
5
|
-
var variant = _a.variant, size = _a.size, _b = _a.state, state = _b === void 0 ? 'enabled' : _b, label = _a.label, iconName = _a.iconName, onClick = _a.onClick;
|
|
47
|
+
var variant = _a.variant, size = _a.size, _b = _a.state, state = _b === void 0 ? 'enabled' : _b, color = _a.color, label = _a.label, secondLabel = _a.secondLabel, iconName = _a.iconName, onClick = _a.onClick;
|
|
6
48
|
var _c = useState(false), isHovered = _c[0], setIsHovered = _c[1];
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
useEffect(function () {
|
|
10
|
-
if (iconName) {
|
|
11
|
-
setIcon(LucideIcons[iconName]);
|
|
12
|
-
}
|
|
13
|
-
}, [iconName]);
|
|
49
|
+
// Get icon directly from icons map
|
|
50
|
+
var Icon = iconName ? icons[iconName] : null;
|
|
14
51
|
// Size and padding
|
|
15
52
|
var sizeClasses = size === 'medium' ? 'text-body2 px-2 py-1' : 'text-caption px-2 py-[3px]';
|
|
16
53
|
// Selected state styles
|
|
17
54
|
var isSelected = state === 'selected';
|
|
55
|
+
// When color is provided, use color-based styling
|
|
56
|
+
var colorStyles = color ? colorConfig[color] : null;
|
|
18
57
|
// Background color
|
|
19
|
-
var bgClasses =
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
58
|
+
var bgClasses = '';
|
|
59
|
+
if (variant === 'dot') {
|
|
60
|
+
bgClasses = '';
|
|
61
|
+
}
|
|
62
|
+
else if (colorStyles) {
|
|
63
|
+
bgClasses = variant === 'contained' ? colorStyles.bg : '';
|
|
64
|
+
}
|
|
65
|
+
else if (isSelected && variant === 'contained') {
|
|
66
|
+
bgClasses = 'bg-light-accent-main dark:bg-dark-accent-main';
|
|
67
|
+
}
|
|
68
|
+
else if (variant === 'contained') {
|
|
69
|
+
bgClasses = 'bg-light-background-accent300 dark:bg-dark-background-accent300';
|
|
70
|
+
}
|
|
24
71
|
// Font color
|
|
25
|
-
var fontClasses =
|
|
26
|
-
|
|
27
|
-
|
|
72
|
+
var fontClasses = '';
|
|
73
|
+
if (variant === 'dot') {
|
|
74
|
+
fontClasses = 'text-light-text-primary dark:text-dark-text-primary';
|
|
75
|
+
}
|
|
76
|
+
else if (colorStyles) {
|
|
77
|
+
fontClasses = variant === 'textOnly' ? colorStyles.textOnly : colorStyles.text;
|
|
78
|
+
}
|
|
79
|
+
else if (isSelected) {
|
|
80
|
+
fontClasses = 'text-white';
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
fontClasses = 'text-light-text-primary dark:text-dark-text-primary';
|
|
84
|
+
}
|
|
28
85
|
// Border styles
|
|
29
|
-
var borderClasses =
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
86
|
+
var borderClasses = '';
|
|
87
|
+
if (variant === 'dot') {
|
|
88
|
+
borderClasses = '';
|
|
89
|
+
}
|
|
90
|
+
else if (colorStyles) {
|
|
91
|
+
if (variant === 'textOnly' && colorStyles.hasBorderTextOnly) {
|
|
92
|
+
borderClasses = "border ".concat(colorStyles.border);
|
|
93
|
+
}
|
|
94
|
+
else if (variant === 'contained') {
|
|
95
|
+
borderClasses = "border ".concat(colorStyles.border);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
else if (isSelected && variant === 'textOnly') {
|
|
99
|
+
borderClasses = 'border border-light-accent-main dark:border-dark-accent-main';
|
|
100
|
+
}
|
|
101
|
+
else if (variant === 'contained') {
|
|
102
|
+
borderClasses = 'border border-light-misc-divider dark:border-dark-misc-divider';
|
|
103
|
+
}
|
|
104
|
+
// Dot color
|
|
105
|
+
var dotColor = (colorStyles === null || colorStyles === void 0 ? void 0 : colorStyles.dot) || colorConfig.default.dot;
|
|
106
|
+
// Hover (only when not selected, no color, and onClick is provided)
|
|
107
|
+
var hoverClasses = !isSelected && !color && variant === 'contained' && isHovered && onClick
|
|
36
108
|
? 'bg-light-background-accent200 dark:bg-dark-background-accent200'
|
|
37
109
|
: '';
|
|
38
110
|
var cursorClass = onClick && !isSelected ? 'cursor-pointer' : '';
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
<span
|
|
111
|
+
var baseClasses = 'flex space-x-2 items-center gap-1 rounded-full whitespace-nowrap transition-colors duration-200 ease-in-out';
|
|
112
|
+
return (<div className={"".concat(baseClasses, " ").concat(sizeClasses, " ").concat(bgClasses, " ").concat(fontClasses, " ").concat(borderClasses, " ").concat(hoverClasses, " ").concat(cursorClass)} onMouseEnter={function () { return onClick && setIsHovered(true); }} onMouseLeave={function () { return onClick && setIsHovered(false); }} onClick={onClick}>
|
|
113
|
+
{variant === 'dot' && (<span className={"w-3 h-3 rounded-full flex-shrink-0 ".concat(dotColor)}/>)}
|
|
114
|
+
{Icon && variant !== 'dot' && <Icon className="w-4 h-4 flex-shrink-0" strokeWidth={2}/>}
|
|
115
|
+
<div className="flex flex-col text-center">
|
|
116
|
+
<span>{label}</span>
|
|
117
|
+
{secondLabel && (<span className="text-caption opacity-70">{secondLabel}</span>)}
|
|
118
|
+
</div>
|
|
42
119
|
</div>);
|
|
43
120
|
}
|
|
@@ -3,17 +3,20 @@ interface TextFieldProps {
|
|
|
3
3
|
id: string;
|
|
4
4
|
label?: string;
|
|
5
5
|
value: string;
|
|
6
|
+
type?: 'text' | 'password' | 'email' | 'number' | 'tel' | 'url' | 'search';
|
|
6
7
|
onChange: (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => void;
|
|
7
8
|
onBlur?: (e: React.FocusEvent<HTMLInputElement | HTMLTextAreaElement>) => void;
|
|
8
9
|
onFocus?: (e: React.FocusEvent<HTMLInputElement | HTMLTextAreaElement>) => void;
|
|
9
10
|
onKeyDown?: (e: React.KeyboardEvent<HTMLInputElement | HTMLTextAreaElement>) => void;
|
|
11
|
+
onSubmit?: () => void;
|
|
10
12
|
autoFocus?: boolean;
|
|
11
13
|
multiline?: boolean;
|
|
12
14
|
maxRows?: number;
|
|
13
15
|
disabled?: boolean;
|
|
14
16
|
error?: boolean;
|
|
17
|
+
required?: boolean;
|
|
15
18
|
size?: 'large' | 'medium' | 'small';
|
|
19
|
+
placeholder?: string;
|
|
16
20
|
}
|
|
17
|
-
export default function TextField({ id, label, value, onChange, onBlur, onFocus, onKeyDown, autoFocus,
|
|
18
|
-
multiline, maxRows, disabled, error, size, }: TextFieldProps): React.JSX.Element;
|
|
21
|
+
export default function TextField({ id, label, value, type, onChange, onBlur, onFocus, onKeyDown, onSubmit, autoFocus, multiline, maxRows, disabled, error, required, size, placeholder, }: TextFieldProps): React.JSX.Element;
|
|
19
22
|
export {};
|
|
@@ -1,20 +1,37 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import React, { useState } from 'react';
|
|
3
3
|
export default function TextField(_a) {
|
|
4
|
-
var id = _a.id, label = _a.label, value = _a.value, onChange = _a.onChange, onBlur = _a.onBlur, onFocus = _a.onFocus, onKeyDown = _a.onKeyDown,
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
var id = _a.id, label = _a.label, value = _a.value, _b = _a.type, type = _b === void 0 ? 'text' : _b, onChange = _a.onChange, onBlur = _a.onBlur, onFocus = _a.onFocus, onKeyDown = _a.onKeyDown, onSubmit = _a.onSubmit, _c = _a.autoFocus, autoFocus = _c === void 0 ? false : _c, _d = _a.multiline, multiline = _d === void 0 ? false : _d, _e = _a.maxRows, maxRows = _e === void 0 ? 6 : _e, _f = _a.disabled, disabled = _f === void 0 ? false : _f, _g = _a.error, error = _g === void 0 ? false : _g, _h = _a.required, required = _h === void 0 ? false : _h, _j = _a.size, size = _j === void 0 ? 'medium' : _j, placeholder = _a.placeholder;
|
|
5
|
+
var _k = useState(false), isFocused = _k[0], setIsFocused = _k[1];
|
|
6
|
+
var handleKeyDown = function (e) {
|
|
7
|
+
// Ctrl+Enter or Cmd+Enter to submit
|
|
8
|
+
if ((e.ctrlKey || e.metaKey) && e.key === 'Enter' && onSubmit) {
|
|
9
|
+
e.preventDefault();
|
|
10
|
+
onSubmit();
|
|
11
|
+
}
|
|
12
|
+
if (onKeyDown)
|
|
13
|
+
onKeyDown(e);
|
|
14
|
+
};
|
|
8
15
|
// Define classes for size: text size and padding
|
|
9
16
|
var sizeClasses = {
|
|
10
|
-
large: 'text-body1 p-
|
|
11
|
-
medium: 'text-body1 p-
|
|
12
|
-
small: 'text-body2 p-
|
|
17
|
+
large: 'text-body1 p-2 leading-[22px]', // body1 (16px), padding 8px
|
|
18
|
+
medium: 'text-body1 p-2 leading-[22px]', // body1 (16px), padding 8px
|
|
19
|
+
small: 'text-body2 p-2 leading-[18px]', // body2 (14px), padding 8px
|
|
13
20
|
}[size];
|
|
14
|
-
var baseClasses = 'w-full border rounded-[8px]';
|
|
21
|
+
var baseClasses = 'w-full border rounded-[8px] outline-none';
|
|
22
|
+
var textColor = 'text-light-text-primary dark:text-dark-text-primary';
|
|
15
23
|
var bgColor = 'bg-light-background-default dark:bg-dark-background-default transition-colors duration-200 ease-in-out';
|
|
16
|
-
|
|
17
|
-
var
|
|
24
|
+
// Border color logic: error > focused > default (misc-divider)
|
|
25
|
+
var getBorderColor = function () {
|
|
26
|
+
if (error) {
|
|
27
|
+
return 'border-light-error-main dark:border-dark-error-main';
|
|
28
|
+
}
|
|
29
|
+
if (isFocused) {
|
|
30
|
+
return 'border-light-text-primary dark:border-dark-text-primary';
|
|
31
|
+
}
|
|
32
|
+
return 'border-light-text-disabled dark:border-dark-text-disabled';
|
|
33
|
+
};
|
|
34
|
+
var containerClasses = "\n ".concat(bgColor, "\n ").concat(textColor, "\n ").concat(baseClasses, "\n ").concat(sizeClasses, "\n ").concat(getBorderColor(), "\n ").concat(disabled ? 'bg-light-actionBackground-disabled dark:bg-dark-actionBackground-disabled cursor-not-allowed' : '', "\n ");
|
|
18
35
|
return (<div className="flex flex-col w-full">
|
|
19
36
|
{label && (<label htmlFor={id} className="mb-1 text-body2 text-light-text-secondary dark:text-dark-text-secondary">
|
|
20
37
|
{label}
|
|
@@ -28,9 +45,7 @@ export default function TextField(_a) {
|
|
|
28
45
|
setIsFocused(false);
|
|
29
46
|
if (onBlur)
|
|
30
47
|
onBlur(e);
|
|
31
|
-
}} onKeyDown={
|
|
32
|
-
disabled={disabled} autoComplete="off" // Disable browser autocomplete/autofill
|
|
33
|
-
/>) : (<input id={id} type="text" className={containerClasses} value={value} onChange={onChange} onFocus={function (e) {
|
|
48
|
+
}} onKeyDown={handleKeyDown} autoFocus={autoFocus} disabled={disabled} required={required} autoComplete="off"/>) : (<input id={id} type={type} className={containerClasses} value={value} onChange={onChange} placeholder={placeholder} onFocus={function (e) {
|
|
34
49
|
setIsFocused(true);
|
|
35
50
|
if (onFocus)
|
|
36
51
|
onFocus(e);
|
|
@@ -38,9 +53,7 @@ export default function TextField(_a) {
|
|
|
38
53
|
setIsFocused(false);
|
|
39
54
|
if (onBlur)
|
|
40
55
|
onBlur(e);
|
|
41
|
-
}} onKeyDown={
|
|
42
|
-
disabled={disabled} autoComplete="off" // Disable browser autocomplete/autofill
|
|
43
|
-
/>)}
|
|
56
|
+
}} onKeyDown={handleKeyDown} autoFocus={autoFocus} disabled={disabled} required={required} autoComplete="off"/>)}
|
|
44
57
|
</div>
|
|
45
58
|
{error && (<p className="mt-1 text-light-error-main text-body2">
|
|
46
59
|
This field is required
|
|
@@ -7,11 +7,13 @@ interface TextareaProps {
|
|
|
7
7
|
onBlur?: (e: React.FocusEvent<HTMLTextAreaElement>) => void;
|
|
8
8
|
onFocus?: (e: React.FocusEvent<HTMLTextAreaElement>) => void;
|
|
9
9
|
onKeyDown?: (e: React.KeyboardEvent<HTMLTextAreaElement>) => void;
|
|
10
|
+
onSubmit?: () => void;
|
|
10
11
|
autoFocus?: boolean;
|
|
11
12
|
maxRows?: number;
|
|
12
13
|
disabled?: boolean;
|
|
13
14
|
error?: boolean;
|
|
14
|
-
size?: '
|
|
15
|
+
size?: 'medium' | 'small';
|
|
16
|
+
placeholder?: string;
|
|
15
17
|
}
|
|
16
|
-
export default function Textarea({ id, label, value, onChange, onBlur, onFocus, onKeyDown, autoFocus, maxRows, disabled, error, size, }: TextareaProps): React.JSX.Element;
|
|
18
|
+
export default function Textarea({ id, label, value, onChange, onBlur, onFocus, onKeyDown, onSubmit, autoFocus, maxRows, disabled, error, size, placeholder, }: TextareaProps): React.JSX.Element;
|
|
17
19
|
export {};
|
|
@@ -1,9 +1,18 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import React, { useEffect, useRef, useState } from 'react';
|
|
3
3
|
export default function Textarea(_a) {
|
|
4
|
-
var id = _a.id, label = _a.label, value = _a.value, onChange = _a.onChange, onBlur = _a.onBlur, onFocus = _a.onFocus, onKeyDown = _a.onKeyDown, _b = _a.autoFocus, autoFocus = _b === void 0 ? false : _b, _c = _a.maxRows, maxRows = _c === void 0 ? 6 : _c, _d = _a.disabled, disabled = _d === void 0 ? false : _d, _e = _a.error, error = _e === void 0 ? false : _e, _f = _a.size, size = _f === void 0 ? 'medium' : _f;
|
|
4
|
+
var id = _a.id, label = _a.label, value = _a.value, onChange = _a.onChange, onBlur = _a.onBlur, onFocus = _a.onFocus, onKeyDown = _a.onKeyDown, onSubmit = _a.onSubmit, _b = _a.autoFocus, autoFocus = _b === void 0 ? false : _b, _c = _a.maxRows, maxRows = _c === void 0 ? 6 : _c, _d = _a.disabled, disabled = _d === void 0 ? false : _d, _e = _a.error, error = _e === void 0 ? false : _e, _f = _a.size, size = _f === void 0 ? 'medium' : _f, placeholder = _a.placeholder;
|
|
5
5
|
var textareaRef = useRef(null);
|
|
6
6
|
var _g = useState(false), isFocused = _g[0], setIsFocused = _g[1];
|
|
7
|
+
var handleKeyDown = function (e) {
|
|
8
|
+
// Ctrl+Enter or Cmd+Enter to submit
|
|
9
|
+
if ((e.ctrlKey || e.metaKey) && e.key === 'Enter' && onSubmit) {
|
|
10
|
+
e.preventDefault();
|
|
11
|
+
onSubmit();
|
|
12
|
+
}
|
|
13
|
+
if (onKeyDown)
|
|
14
|
+
onKeyDown(e);
|
|
15
|
+
};
|
|
7
16
|
useEffect(function () {
|
|
8
17
|
var textarea = textareaRef.current;
|
|
9
18
|
if (!textarea)
|
|
@@ -15,8 +24,10 @@ export default function Textarea(_a) {
|
|
|
15
24
|
var scrollHeight = textarea.scrollHeight;
|
|
16
25
|
// Set height to scrollHeight, capped at maxRows, but at least 1 line
|
|
17
26
|
textarea.style.height = "".concat(Math.max(Math.min(scrollHeight, maxHeight), lineHeight), "px");
|
|
18
|
-
// Enable vertical scroll if content exceeds maxRows
|
|
19
|
-
textarea.style.overflowY = scrollHeight > maxHeight ? '
|
|
27
|
+
// Enable vertical scroll if content exceeds maxRows (hide scrollbar)
|
|
28
|
+
textarea.style.overflowY = scrollHeight > maxHeight ? 'scroll' : 'hidden';
|
|
29
|
+
textarea.style.scrollbarWidth = 'none'; // Firefox
|
|
30
|
+
textarea.style.msOverflowStyle = 'none'; // IE/Edge
|
|
20
31
|
};
|
|
21
32
|
// Set initial rows to 1 for single-line height
|
|
22
33
|
textarea.rows = 1;
|
|
@@ -26,20 +37,29 @@ export default function Textarea(_a) {
|
|
|
26
37
|
}, [maxRows]);
|
|
27
38
|
// Define classes for size: text size and padding
|
|
28
39
|
var sizeClasses = {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
small: 'text-body2 p-[3px] leading-[18px]', // body2 (14px), padding 4px(3 + border 1), height 28
|
|
40
|
+
medium: 'text-body1 p-2 leading-[22px]', // body1 (16px), padding 8px
|
|
41
|
+
small: 'text-body2 p-2 leading-[18px]', // body2 (14px), padding 8px
|
|
32
42
|
}[size];
|
|
33
|
-
var baseClasses = 'w-full border rounded-[8px]';
|
|
43
|
+
var baseClasses = 'w-full border rounded-[8px] outline-none [&::-webkit-scrollbar]:hidden';
|
|
44
|
+
var textColor = 'text-light-text-primary dark:text-dark-text-primary';
|
|
34
45
|
var bgColor = 'bg-light-background-default dark:bg-dark-background-default transition-colors duration-200 ease-in-out';
|
|
35
|
-
|
|
36
|
-
var
|
|
46
|
+
// Border color logic: error > focused > default (misc-divider)
|
|
47
|
+
var getBorderColor = function () {
|
|
48
|
+
if (error) {
|
|
49
|
+
return 'border-light-error-main dark:border-dark-error-main';
|
|
50
|
+
}
|
|
51
|
+
if (isFocused) {
|
|
52
|
+
return 'border-light-text-primary dark:border-dark-text-primary';
|
|
53
|
+
}
|
|
54
|
+
return 'border-light-text-disabled dark:border-dark-text-disabled';
|
|
55
|
+
};
|
|
56
|
+
var containerClasses = "\n ".concat(bgColor, "\n ").concat(textColor, "\n ").concat(baseClasses, "\n ").concat(sizeClasses, "\n ").concat(getBorderColor(), "\n ").concat(disabled ? 'bg-light-actionBackground-disabled dark:bg-dark-actionBackground-disabled cursor-not-allowed' : '', "\n ");
|
|
37
57
|
return (<div className="flex flex-col w-full">
|
|
38
58
|
{label && (<label htmlFor={id} className="mb-1 text-body2 text-light-text-secondary dark:text-dark-text-secondary">
|
|
39
59
|
{label}
|
|
40
60
|
</label>)}
|
|
41
61
|
<div className="relative">
|
|
42
|
-
<textarea ref={textareaRef} id={id} rows={1} className={containerClasses} value={value} onChange={onChange} onFocus={function (e) {
|
|
62
|
+
<textarea ref={textareaRef} id={id} rows={1} className={containerClasses} value={value} onChange={onChange} placeholder={placeholder} onFocus={function (e) {
|
|
43
63
|
setIsFocused(true);
|
|
44
64
|
if (onFocus)
|
|
45
65
|
onFocus(e);
|
|
@@ -47,7 +67,7 @@ export default function Textarea(_a) {
|
|
|
47
67
|
setIsFocused(false);
|
|
48
68
|
if (onBlur)
|
|
49
69
|
onBlur(e);
|
|
50
|
-
}} onKeyDown={
|
|
70
|
+
}} onKeyDown={handleKeyDown} autoFocus={autoFocus} disabled={disabled} autoComplete="off"/>
|
|
51
71
|
</div>
|
|
52
72
|
{error && (<p className="mt-1 text-light-error-main text-body2">
|
|
53
73
|
This field is required
|