oneslash-design-system 1.2.23 → 1.2.25
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 +2 -1
- package/dist/components/button.jsx +5 -2
- package/dist/components/checkBox.d.ts +3 -1
- package/dist/components/checkBox.jsx +28 -9
- 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/iconButton.jsx +28 -22
- package/dist/components/line.d.ts +7 -0
- package/dist/components/line.jsx +10 -0
- package/dist/components/link.d.ts +11 -0
- package/dist/components/link.jsx +59 -0
- package/dist/components/menuItem.d.ts +2 -1
- package/dist/components/menuItem.jsx +12 -7
- 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 +6 -3
- package/dist/components/tag.jsx +88 -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 +600 -385
- package/dist/stories/Alert.stories.d.ts +15 -0
- package/dist/stories/Alert.stories.jsx +121 -0
- package/dist/stories/Button.stories.d.ts +12 -0
- package/dist/stories/Button.stories.jsx +81 -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 +11 -0
- package/dist/stories/MenuItem.stories.jsx +62 -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 +17 -0
- package/dist/stories/Tag.stories.jsx +143 -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/tab.jsx
CHANGED
|
@@ -36,12 +36,9 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
|
36
36
|
}
|
|
37
37
|
};
|
|
38
38
|
import React, { useState, useEffect, useCallback } from 'react';
|
|
39
|
-
import { useRouter, usePathname } from 'next/navigation';
|
|
40
39
|
export default function Tab(_a) {
|
|
41
40
|
var _this = this;
|
|
42
|
-
var label = _a.label, href = _a.href, isSelected = _a.isSelected, onClickTab = _a.onClickTab, onClickActionIcon = _a.onClickActionIcon, decoIcon = _a.decoIcon, actionIcon = _a.actionIcon;
|
|
43
|
-
var router = useRouter();
|
|
44
|
-
var pathname = usePathname();
|
|
41
|
+
var label = _a.label, secondLabel = _a.secondLabel, href = _a.href, isSelected = _a.isSelected, onClickTab = _a.onClickTab, onClickActionIcon = _a.onClickActionIcon, decoIcon = _a.decoIcon, actionIcon = _a.actionIcon, router = _a.router;
|
|
45
42
|
var _b = useState(null), IconLeft = _b[0], setIconLeft = _b[1];
|
|
46
43
|
var _c = useState(null), IconRight = _c[0], setIconRight = _c[1];
|
|
47
44
|
// Load icon dynamically
|
|
@@ -95,17 +92,22 @@ export default function Tab(_a) {
|
|
|
95
92
|
}, [decoIcon, actionIcon, loadIcon]);
|
|
96
93
|
var handleClick = function () {
|
|
97
94
|
onClickTab();
|
|
98
|
-
if (href) {
|
|
95
|
+
if (href && router) {
|
|
99
96
|
router.push(href);
|
|
100
97
|
}
|
|
101
98
|
};
|
|
102
99
|
return (<div className={"\n flex items-center space-x-1 py-1 px-[6px] rounded-[8px] cursor-pointer justify-start transition-colors duration-200 ease-in-out\n ".concat(isSelected
|
|
103
100
|
? 'bg-light-primary-dark dark:bg-dark-primary-dark text-light-text-contrast dark:text-dark-text-contrast'
|
|
104
|
-
: 'hover:bg-light-background-accent200 dark:hover:bg-dark-background-accent200', "\n ")} onClick={handleClick}>
|
|
101
|
+
: 'text-light-text-primary dark:text-dark-text-primary hover:bg-light-background-accent200 dark:hover:bg-dark-background-accent200', "\n ")} onClick={handleClick}>
|
|
105
102
|
{IconLeft && <IconLeft className="w-6 h-6" strokeWidth={2}/>}
|
|
106
|
-
<
|
|
107
|
-
|
|
108
|
-
|
|
103
|
+
<div className="flex flex-col px-[6px] text-center">
|
|
104
|
+
<span className="whitespace-nowrap text-body1">
|
|
105
|
+
{label}
|
|
106
|
+
</span>
|
|
107
|
+
{secondLabel && (<span className="whitespace-nowrap text-body2 opacity-70">
|
|
108
|
+
{secondLabel}
|
|
109
|
+
</span>)}
|
|
110
|
+
</div>
|
|
109
111
|
{IconRight && (<div onClick={onClickActionIcon} className="cursor-pointer">
|
|
110
112
|
<IconRight className="w-6 h-6" strokeWidth={2}/>
|
|
111
113
|
</div>)}
|
|
@@ -3,7 +3,10 @@ import React from 'react';
|
|
|
3
3
|
export default function TabsContainer(_a) {
|
|
4
4
|
var children = _a.children;
|
|
5
5
|
var tabCount = React.Children.count(children);
|
|
6
|
-
return (<div className={"\n flex space-x-2 p-1 rounded-[12px]\n ".concat(tabCount > 0 ? 'bg-light-background-accent100 dark:bg-dark-background-accent100' : 'bg-transparent', "\n ")}
|
|
6
|
+
return (<div className={"\n flex space-x-2 p-1 rounded-[12px] overflow-x-auto\n ".concat(tabCount > 0 ? 'bg-light-background-accent100 dark:bg-dark-background-accent100' : 'bg-transparent', "\n ")} style={{
|
|
7
|
+
scrollbarWidth: 'none',
|
|
8
|
+
msOverflowStyle: 'none',
|
|
9
|
+
}}>
|
|
7
10
|
{children}
|
|
8
11
|
</div>);
|
|
9
12
|
}
|
package/dist/components/tag.d.ts
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import
|
|
2
|
+
import { icons } from 'lucide-react';
|
|
3
|
+
type IconName = keyof typeof icons;
|
|
3
4
|
interface TagProps {
|
|
4
5
|
variant: 'contained' | 'textOnly';
|
|
5
6
|
size: 'medium' | 'small';
|
|
6
7
|
state?: 'enabled' | 'selected';
|
|
8
|
+
color?: 'default' | 'success' | 'warning' | 'error' | 'info';
|
|
7
9
|
label: React.ReactNode;
|
|
8
|
-
|
|
10
|
+
secondLabel?: string;
|
|
11
|
+
iconName?: IconName;
|
|
9
12
|
onClick?: React.MouseEventHandler<HTMLDivElement>;
|
|
10
13
|
}
|
|
11
|
-
export default function Tag({ variant, size, state, label, iconName, onClick, }: TagProps): JSX.Element;
|
|
14
|
+
export default function Tag({ variant, size, state, color, label, secondLabel, iconName, onClick, }: TagProps): JSX.Element;
|
|
12
15
|
export {};
|
package/dist/components/tag.jsx
CHANGED
|
@@ -1,43 +1,103 @@
|
|
|
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
|
+
hasBorderTextOnly: false,
|
|
11
|
+
},
|
|
12
|
+
success: {
|
|
13
|
+
bg: 'bg-light-success-main dark:bg-dark-success-main',
|
|
14
|
+
text: 'text-light-text-primary dark:text-dark-text-primary',
|
|
15
|
+
textOnly: 'text-light-success-main dark:text-dark-success-main',
|
|
16
|
+
border: 'border-light-success-main dark:border-dark-success-main',
|
|
17
|
+
hasBorderTextOnly: true,
|
|
18
|
+
},
|
|
19
|
+
warning: {
|
|
20
|
+
bg: 'bg-light-warning-main dark:bg-dark-warning-main',
|
|
21
|
+
text: 'text-light-text-primary dark:text-dark-text-primary',
|
|
22
|
+
textOnly: 'text-light-warning-main dark:text-dark-warning-main',
|
|
23
|
+
border: 'border-light-warning-main dark:border-dark-warning-main',
|
|
24
|
+
hasBorderTextOnly: true,
|
|
25
|
+
},
|
|
26
|
+
error: {
|
|
27
|
+
bg: 'bg-light-error-main dark:bg-dark-error-main',
|
|
28
|
+
text: 'text-light-text-primary dark:text-dark-text-primary',
|
|
29
|
+
textOnly: 'text-light-error-main dark:text-dark-error-main',
|
|
30
|
+
border: 'border-light-error-main dark:border-dark-error-main',
|
|
31
|
+
hasBorderTextOnly: true,
|
|
32
|
+
},
|
|
33
|
+
info: {
|
|
34
|
+
bg: 'bg-light-info-main dark:bg-dark-info-main',
|
|
35
|
+
text: 'text-light-text-primary dark:text-dark-text-primary',
|
|
36
|
+
textOnly: 'text-light-info-main dark:text-dark-info-main',
|
|
37
|
+
border: 'border-light-info-main dark:border-dark-info-main',
|
|
38
|
+
hasBorderTextOnly: true,
|
|
39
|
+
},
|
|
40
|
+
};
|
|
4
41
|
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;
|
|
42
|
+
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
43
|
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]);
|
|
44
|
+
// Get icon directly from icons map
|
|
45
|
+
var Icon = iconName ? icons[iconName] : null;
|
|
14
46
|
// Size and padding
|
|
15
47
|
var sizeClasses = size === 'medium' ? 'text-body2 px-2 py-1' : 'text-caption px-2 py-[3px]';
|
|
16
48
|
// Selected state styles
|
|
17
49
|
var isSelected = state === 'selected';
|
|
50
|
+
// When color is provided, use color-based styling
|
|
51
|
+
var colorStyles = color ? colorConfig[color] : null;
|
|
18
52
|
// Background color
|
|
19
|
-
var bgClasses =
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
53
|
+
var bgClasses = '';
|
|
54
|
+
if (colorStyles) {
|
|
55
|
+
bgClasses = variant === 'contained' ? colorStyles.bg : '';
|
|
56
|
+
}
|
|
57
|
+
else if (isSelected && variant === 'contained') {
|
|
58
|
+
bgClasses = 'bg-light-accent-main dark:bg-dark-accent-main';
|
|
59
|
+
}
|
|
60
|
+
else if (variant === 'contained') {
|
|
61
|
+
bgClasses = 'bg-light-background-accent300 dark:bg-dark-background-accent300';
|
|
62
|
+
}
|
|
24
63
|
// Font color
|
|
25
|
-
var fontClasses =
|
|
26
|
-
|
|
27
|
-
|
|
64
|
+
var fontClasses = '';
|
|
65
|
+
if (colorStyles) {
|
|
66
|
+
fontClasses = variant === 'textOnly' ? colorStyles.textOnly : colorStyles.text;
|
|
67
|
+
}
|
|
68
|
+
else if (isSelected) {
|
|
69
|
+
fontClasses = 'text-white';
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
fontClasses = 'text-light-text-primary dark:text-dark-text-primary';
|
|
73
|
+
}
|
|
28
74
|
// Border styles
|
|
29
|
-
var borderClasses =
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
75
|
+
var borderClasses = '';
|
|
76
|
+
if (colorStyles) {
|
|
77
|
+
if (variant === 'textOnly' && colorStyles.hasBorderTextOnly) {
|
|
78
|
+
borderClasses = "border ".concat(colorStyles.border);
|
|
79
|
+
}
|
|
80
|
+
else if (variant === 'contained') {
|
|
81
|
+
borderClasses = "border ".concat(colorStyles.border);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
else if (isSelected && variant === 'textOnly') {
|
|
85
|
+
borderClasses = 'border border-light-accent-main dark:border-dark-accent-main';
|
|
86
|
+
}
|
|
87
|
+
else if (variant === 'contained') {
|
|
88
|
+
borderClasses = 'border border-light-misc-divider dark:border-dark-misc-divider';
|
|
89
|
+
}
|
|
90
|
+
// Hover (only when not selected, no color, and onClick is provided)
|
|
91
|
+
var hoverClasses = !isSelected && !color && variant === 'contained' && isHovered && onClick
|
|
36
92
|
? 'bg-light-background-accent200 dark:bg-dark-background-accent200'
|
|
37
93
|
: '';
|
|
38
94
|
var cursorClass = onClick && !isSelected ? 'cursor-pointer' : '';
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
<
|
|
95
|
+
var baseClasses = 'flex space-x-2 items-center gap-1 rounded-full whitespace-nowrap transition-colors duration-200 ease-in-out';
|
|
96
|
+
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}>
|
|
97
|
+
{Icon && <Icon className="w-4 h-4 flex-shrink-0" strokeWidth={2}/>}
|
|
98
|
+
<div className="flex flex-col text-center">
|
|
99
|
+
<span>{label}</span>
|
|
100
|
+
{secondLabel && (<span className="text-caption opacity-70">{secondLabel}</span>)}
|
|
101
|
+
</div>
|
|
42
102
|
</div>);
|
|
43
103
|
}
|
|
@@ -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
|