oneslash-design-system 1.2.18 → 1.2.20
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.jsx +7 -7
- package/dist/components/button.jsx +3 -3
- package/dist/components/emptyBox.jsx +2 -2
- package/dist/components/iconButton.d.ts +2 -3
- package/dist/components/iconButton.jsx +10 -10
- package/dist/components/menuItem.jsx +3 -3
- package/dist/components/select.jsx +4 -4
- package/dist/components/tab.jsx +3 -3
- package/dist/components/tag.d.ts +2 -2
- package/dist/components/tag.jsx +4 -4
- package/dist/components/timeStamp.d.ts +4 -1
- package/dist/components/timeStamp.jsx +50 -3
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import React, { useEffect, useState } from 'react';
|
|
3
|
-
import {
|
|
3
|
+
import { Info, AlertCircle, AlertTriangle, CheckCircle } from 'lucide-react';
|
|
4
4
|
import IconButton from './iconButton';
|
|
5
5
|
export default function Alert(_a) {
|
|
6
6
|
var open = _a.open, type = _a.type, message = _a.message, onClose = _a.onClose, _b = _a.showCloseButton, showCloseButton = _b === void 0 ? false : _b;
|
|
@@ -46,16 +46,16 @@ export default function Alert(_a) {
|
|
|
46
46
|
var getIcon = function () {
|
|
47
47
|
switch (type) {
|
|
48
48
|
case 'error':
|
|
49
|
-
return <
|
|
49
|
+
return <AlertCircle className="w-6 h-6" strokeWidth={2}/>;
|
|
50
50
|
case 'warning':
|
|
51
|
-
return <
|
|
51
|
+
return <AlertTriangle className="w-6 h-6" strokeWidth={2}/>;
|
|
52
52
|
case 'info':
|
|
53
|
-
return <
|
|
53
|
+
return <Info className="w-6 h-6" strokeWidth={2}/>;
|
|
54
54
|
case 'success':
|
|
55
|
-
return <
|
|
55
|
+
return <CheckCircle className="w-6 h-6" strokeWidth={2}/>;
|
|
56
56
|
case 'default':
|
|
57
57
|
default:
|
|
58
|
-
return <
|
|
58
|
+
return <Info className="w-6 h-6" strokeWidth={2}/>;
|
|
59
59
|
}
|
|
60
60
|
};
|
|
61
61
|
var bgColor;
|
|
@@ -86,7 +86,7 @@ export default function Alert(_a) {
|
|
|
86
86
|
<span className="body1">{message}</span>
|
|
87
87
|
</div>
|
|
88
88
|
{showCloseButton && (<div className="ml-4">
|
|
89
|
-
<IconButton color="iconOnly" state="enabled" size="small" iconName="
|
|
89
|
+
<IconButton color="iconOnly" state="enabled" size="small" iconName="X" onClick={handleClose}/>
|
|
90
90
|
</div>)}
|
|
91
91
|
</div>
|
|
92
92
|
</div>);
|
|
@@ -52,7 +52,7 @@ export default function Button(_a) {
|
|
|
52
52
|
_a.label = 1;
|
|
53
53
|
case 1:
|
|
54
54
|
_a.trys.push([1, 3, , 4]);
|
|
55
|
-
return [4 /*yield*/, import('
|
|
55
|
+
return [4 /*yield*/, import('lucide-react')];
|
|
56
56
|
case 2:
|
|
57
57
|
module_1 = _a.sent();
|
|
58
58
|
Icon = module_1[iconName];
|
|
@@ -125,11 +125,11 @@ export default function Button(_a) {
|
|
|
125
125
|
setIsHovered(false); }} onClick={onClickButton}>
|
|
126
126
|
{/* Group IconLeft and label in a flex container for left alignment */}
|
|
127
127
|
<div className="flex items-center">
|
|
128
|
-
{IconLeft && <IconLeft className={sizeIcon}/>}
|
|
128
|
+
{IconLeft && <IconLeft className={sizeIcon} strokeWidth={2}/>}
|
|
129
129
|
<div className="whitespace-nowrap overflow-hidden truncate px-2">{label}</div>
|
|
130
130
|
</div>
|
|
131
131
|
{IconRight && (<div onClick={onClickActionIcon} className="cursor-pointer">
|
|
132
|
-
<IconRight className={sizeIcon}/>
|
|
132
|
+
<IconRight className={sizeIcon} strokeWidth={2}/>
|
|
133
133
|
</div>)}
|
|
134
134
|
</button>);
|
|
135
135
|
}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import React from 'react';
|
|
3
|
-
import {
|
|
3
|
+
import { AlertCircle } from 'lucide-react';
|
|
4
4
|
export default function EmptyBox(_a) {
|
|
5
5
|
var text = _a.text, size = _a.size;
|
|
6
6
|
var color = 'text-light-text-disabled dark:text-dark-text-disabled';
|
|
7
7
|
var height = size === 'small' ? 'py-6' : 'h-full';
|
|
8
8
|
var iconSize = 'size-6';
|
|
9
9
|
return (<div className={"flex flex-col space-y-2 justify-center items-center w-full ".concat(height)}>
|
|
10
|
-
<
|
|
10
|
+
<AlertCircle className={"".concat(iconSize, " ").concat(color)} strokeWidth={2}/>
|
|
11
11
|
<p className={"text-body1 text-center ".concat(color)}>
|
|
12
12
|
{text}
|
|
13
13
|
</p>
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import * as
|
|
3
|
-
import * as HeroIcons20 from '@heroicons/react/20/solid';
|
|
2
|
+
import * as LucideIcons from 'lucide-react';
|
|
4
3
|
interface IconButtonProps {
|
|
5
4
|
color: "primary" | "secondary" | "tertiary" | "iconOnly";
|
|
6
5
|
state: "enabled" | "selected" | "disabled";
|
|
7
6
|
size: "large" | "medium" | "small";
|
|
8
|
-
iconName: keyof typeof
|
|
7
|
+
iconName: keyof typeof LucideIcons;
|
|
9
8
|
onClick?: any;
|
|
10
9
|
loading?: boolean;
|
|
11
10
|
}
|
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import React, { useState } from 'react';
|
|
3
|
-
import * as
|
|
4
|
-
import * as HeroIcons20 from '@heroicons/react/20/solid';
|
|
2
|
+
import React, { useState, useEffect } from 'react';
|
|
3
|
+
import * as LucideIcons from 'lucide-react';
|
|
5
4
|
import { LoadingSmall } from './loadingScreen';
|
|
6
5
|
export default function IconButton(_a) {
|
|
7
6
|
var color = _a.color, state = _a.state, size = _a.size, iconName = _a.iconName, onClick = _a.onClick, _b = _a.loading, loading = _b === void 0 ? false : _b;
|
|
8
7
|
var _c = useState(false), isHovered = _c[0], setIsHovered = _c[1];
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
var _d = useState(null), Icon = _d[0], setIcon = _d[1];
|
|
9
|
+
// Load icon from Lucide
|
|
10
|
+
useEffect(function () {
|
|
11
|
+
if (iconName) {
|
|
12
|
+
setIcon(LucideIcons[iconName]);
|
|
13
|
+
}
|
|
14
|
+
}, [iconName]);
|
|
13
15
|
// Size-based classes
|
|
14
16
|
var sizeClasses = {
|
|
15
17
|
large: 'p-2', // 8px padding
|
|
@@ -59,8 +61,6 @@ export default function IconButton(_a) {
|
|
|
59
61
|
: 'cursor-pointer';
|
|
60
62
|
return (<button className={"".concat(baseClasses, " ").concat(bgColor, " ").concat(iconColor, " ").concat(bgColorHover, " ").concat(stateClasses, " transition-colors duration-200 ease-in-out flex items-center justify-center")} disabled={state === 'disabled' || loading} // Disable button during loading
|
|
61
63
|
onMouseEnter={function () { return setIsHovered(true); }} onMouseLeave={function () { return setIsHovered(false); }} onClick={onClick} aria-label={loading ? 'Loading' : 'Reload'}>
|
|
62
|
-
{loading ? (<LoadingSmall size={size}/>
|
|
63
|
-
) : (Icon && <Icon className={iconSizeClasses[size]}/> // Show icon when not loading
|
|
64
|
-
)}
|
|
64
|
+
{loading ? (<LoadingSmall size={size}/>) : (Icon && <Icon className={iconSizeClasses[size]} strokeWidth={2}/>)}
|
|
65
65
|
</button>);
|
|
66
66
|
}
|
|
@@ -54,7 +54,7 @@ export default function MenuItem(_a) {
|
|
|
54
54
|
_a.label = 1;
|
|
55
55
|
case 1:
|
|
56
56
|
_a.trys.push([1, 3, , 4]);
|
|
57
|
-
return [4 /*yield*/, import('
|
|
57
|
+
return [4 /*yield*/, import('lucide-react')];
|
|
58
58
|
case 2:
|
|
59
59
|
module_1 = _a.sent();
|
|
60
60
|
IconComponent = module_1[iconName];
|
|
@@ -101,7 +101,7 @@ export default function MenuItem(_a) {
|
|
|
101
101
|
: 'hover:bg-light-background-accent200 hover:dark:bg-dark-background-accent200', "\n ").concat(className, "\n ")} style={{ width: '100%' }} onClick={onClick}>
|
|
102
102
|
{/* Left group: icon/userImg + label + tag with 8px gap */}
|
|
103
103
|
<div className="flex items-center gap-2">
|
|
104
|
-
{userImgUrl ? (<UserImage userHandle={userHandle || ''} userImgUrl={userImgUrl}/>) : (IconLeft && (<IconLeft className={"".concat(iconSize, " text-light-text-secondary dark:text-dark-text-secondary")}/>))}
|
|
104
|
+
{userImgUrl ? (<UserImage userHandle={userHandle || ''} userImgUrl={userImgUrl}/>) : (IconLeft && (<IconLeft className={"".concat(iconSize, " text-light-text-secondary dark:text-dark-text-secondary")} strokeWidth={2}/>))}
|
|
105
105
|
<span className={"whitespace-nowrap ".concat(labelClass, " text-light-text-primary dark:text-dark-text-primary")}>
|
|
106
106
|
{label}
|
|
107
107
|
</span>
|
|
@@ -109,7 +109,7 @@ export default function MenuItem(_a) {
|
|
|
109
109
|
</div>
|
|
110
110
|
|
|
111
111
|
{/* Right icon aligned to the right */}
|
|
112
|
-
{IconRight && (<IconRight className={"".concat(iconSize, " text-light-text-secondary dark:text-dark-text-secondary flex-shrink-0")}/>)}
|
|
112
|
+
{IconRight && (<IconRight className={"".concat(iconSize, " text-light-text-secondary dark:text-dark-text-secondary flex-shrink-0")} strokeWidth={2}/>)}
|
|
113
113
|
</div>);
|
|
114
114
|
return href ? <NextLink href={href}>{content}</NextLink> : content;
|
|
115
115
|
}
|
|
@@ -45,7 +45,7 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
|
45
45
|
return to.concat(ar || Array.prototype.slice.call(from));
|
|
46
46
|
};
|
|
47
47
|
import React, { useState, useEffect, useRef, useCallback } from 'react';
|
|
48
|
-
import {
|
|
48
|
+
import { ChevronDown } from 'lucide-react';
|
|
49
49
|
import Menu from './menu';
|
|
50
50
|
import MenuItem from './menuItem';
|
|
51
51
|
export default function Select(_a) {
|
|
@@ -73,7 +73,7 @@ export default function Select(_a) {
|
|
|
73
73
|
_a.label = 1;
|
|
74
74
|
case 1:
|
|
75
75
|
_a.trys.push([1, 3, , 4]);
|
|
76
|
-
return [4 /*yield*/, import('
|
|
76
|
+
return [4 /*yield*/, import('lucide-react')];
|
|
77
77
|
case 2:
|
|
78
78
|
module_1 = _a.sent();
|
|
79
79
|
IconComponent = module_1[iconName];
|
|
@@ -211,7 +211,7 @@ export default function Select(_a) {
|
|
|
211
211
|
{/* Content Container */}
|
|
212
212
|
<div className="flex items-center space-x-1 flex-1 overflow-hidden">
|
|
213
213
|
{/* Optional Decoration Icon */}
|
|
214
|
-
{DecoIcon && (<DecoIcon className={"w-6 h-6 flex-shrink-0 ".concat(getIconColor())}/>)}
|
|
214
|
+
{DecoIcon && (<DecoIcon className={"w-6 h-6 flex-shrink-0 ".concat(getIconColor())} strokeWidth={2}/>)}
|
|
215
215
|
|
|
216
216
|
{/* Display Text */}
|
|
217
217
|
<span className="text-body1 truncate">
|
|
@@ -220,7 +220,7 @@ export default function Select(_a) {
|
|
|
220
220
|
</div>
|
|
221
221
|
|
|
222
222
|
{/* Chevron Icon */}
|
|
223
|
-
<
|
|
223
|
+
<ChevronDown className={"\n w-6 h-6 flex-shrink-0 ml-1\n ".concat(getIconColor(), "\n transition-transform duration-200\n ").concat(isOpen ? 'transform rotate-180' : '', "\n ")} strokeWidth={2}/>
|
|
224
224
|
</div>
|
|
225
225
|
</div>
|
|
226
226
|
|
package/dist/components/tab.jsx
CHANGED
|
@@ -55,7 +55,7 @@ export default function Tab(_a) {
|
|
|
55
55
|
_a.label = 1;
|
|
56
56
|
case 1:
|
|
57
57
|
_a.trys.push([1, 3, , 4]);
|
|
58
|
-
return [4 /*yield*/, import('
|
|
58
|
+
return [4 /*yield*/, import('lucide-react')];
|
|
59
59
|
case 2:
|
|
60
60
|
module_1 = _a.sent();
|
|
61
61
|
Icon = module_1[iconName];
|
|
@@ -102,12 +102,12 @@ export default function Tab(_a) {
|
|
|
102
102
|
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
103
|
? 'bg-light-primary-dark dark:bg-dark-primary-dark text-light-text-contrast dark:text-dark-text-contrast'
|
|
104
104
|
: 'hover:bg-light-background-accent200 dark:hover:bg-dark-background-accent200', "\n ")} onClick={handleClick}>
|
|
105
|
-
{IconLeft && <IconLeft className="w-6 h-6"/>}
|
|
105
|
+
{IconLeft && <IconLeft className="w-6 h-6" strokeWidth={2}/>}
|
|
106
106
|
<span className="whitespace-nowrap text-body1 px-[6px]">
|
|
107
107
|
{label}
|
|
108
108
|
</span>
|
|
109
109
|
{IconRight && (<div onClick={onClickActionIcon} className="cursor-pointer">
|
|
110
|
-
<IconRight className="w-6 h-6"/>
|
|
110
|
+
<IconRight className="w-6 h-6" strokeWidth={2}/>
|
|
111
111
|
</div>)}
|
|
112
112
|
</div>);
|
|
113
113
|
}
|
package/dist/components/tag.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import * as
|
|
2
|
+
import * as LucideIcons from 'lucide-react';
|
|
3
3
|
interface TagProps {
|
|
4
4
|
variant: 'contained' | 'textOnly';
|
|
5
5
|
size: 'medium' | 'small';
|
|
6
6
|
state?: 'enabled' | 'selected';
|
|
7
7
|
label: React.ReactNode;
|
|
8
|
-
iconName?: keyof typeof
|
|
8
|
+
iconName?: keyof typeof LucideIcons;
|
|
9
9
|
onClick?: React.MouseEventHandler<HTMLDivElement>;
|
|
10
10
|
}
|
|
11
11
|
export default function Tag({ variant, size, state, label, iconName, onClick, }: TagProps): JSX.Element;
|
package/dist/components/tag.jsx
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import React, { useState, useEffect } from 'react';
|
|
3
|
-
import * as
|
|
3
|
+
import * as LucideIcons from 'lucide-react';
|
|
4
4
|
export default function Tag(_a) {
|
|
5
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;
|
|
6
6
|
var _c = useState(false), isHovered = _c[0], setIsHovered = _c[1];
|
|
7
7
|
var _d = useState(null), Icon = _d[0], setIcon = _d[1];
|
|
8
|
-
// Load icon directly from
|
|
8
|
+
// Load icon directly from Lucide
|
|
9
9
|
useEffect(function () {
|
|
10
10
|
if (iconName) {
|
|
11
|
-
setIcon(
|
|
11
|
+
setIcon(LucideIcons[iconName]);
|
|
12
12
|
}
|
|
13
13
|
}, [iconName]);
|
|
14
14
|
// Size and padding
|
|
@@ -37,7 +37,7 @@ export default function Tag(_a) {
|
|
|
37
37
|
: '';
|
|
38
38
|
var cursorClass = onClick && !isSelected ? 'cursor-pointer' : '';
|
|
39
39
|
return (<div className={"\n flex items-center space-x-1 rounded-full\n ".concat(sizeClasses, " ").concat(bgClasses, " ").concat(fontClasses, " ").concat(borderClasses, " ").concat(hoverClasses, " ").concat(cursorClass, "\n transition-colors duration-200 ease-in-out\n ")} onMouseEnter={function () { return onClick && setIsHovered(true); }} onMouseLeave={function () { return onClick && setIsHovered(false); }} onClick={onClick}>
|
|
40
|
-
{Icon && <Icon className="w-4 h-4"/>}
|
|
40
|
+
{Icon && <Icon className="w-4 h-4" strokeWidth={2}/>}
|
|
41
41
|
<span>{label}</span>
|
|
42
42
|
</div>);
|
|
43
43
|
}
|
|
@@ -2,6 +2,9 @@ import React from 'react';
|
|
|
2
2
|
interface TimeStampProps {
|
|
3
3
|
createdAt: string | number | Date;
|
|
4
4
|
dateFormat: 'absolute' | 'relative';
|
|
5
|
+
textSize?: 'small' | 'medium' | 'large';
|
|
6
|
+
textColor?: 'secondary' | 'primary';
|
|
7
|
+
data?: 'date-and-time' | 'date' | 'time';
|
|
5
8
|
}
|
|
6
|
-
export default function TimeStamp({ createdAt, dateFormat, }: TimeStampProps): React.JSX.Element;
|
|
9
|
+
export default function TimeStamp({ createdAt, dateFormat, textSize, textColor, data, }: TimeStampProps): React.JSX.Element;
|
|
7
10
|
export {};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import React from 'react';
|
|
3
3
|
export default function TimeStamp(_a) {
|
|
4
|
-
var createdAt = _a.createdAt, dateFormat = _a.dateFormat;
|
|
4
|
+
var createdAt = _a.createdAt, dateFormat = _a.dateFormat, _b = _a.textSize, textSize = _b === void 0 ? 'small' : _b, _c = _a.textColor, textColor = _c === void 0 ? 'secondary' : _c, _d = _a.data, data = _d === void 0 ? 'date-and-time' : _d;
|
|
5
5
|
// absolute timestamp
|
|
6
6
|
var absoluteTimeStamp = function (createdAt) {
|
|
7
7
|
var date = new Date(createdAt);
|
|
@@ -14,7 +14,17 @@ export default function TimeStamp(_a) {
|
|
|
14
14
|
var formattedMinutes = minutes.toString().padStart(2, '0');
|
|
15
15
|
var daysOfWeek = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
|
|
16
16
|
var dayOfWeek = daysOfWeek[date.getDay()];
|
|
17
|
-
|
|
17
|
+
var dateString = "".concat(month, "/").concat(day, "/").concat(year, " ").concat(dayOfWeek);
|
|
18
|
+
var timeString = "".concat(formattedHours, ":").concat(formattedMinutes);
|
|
19
|
+
if (data === 'date') {
|
|
20
|
+
return dateString;
|
|
21
|
+
}
|
|
22
|
+
else if (data === 'time') {
|
|
23
|
+
return timeString;
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
return "".concat(dateString, " ").concat(timeString);
|
|
27
|
+
}
|
|
18
28
|
};
|
|
19
29
|
// relative timestamp
|
|
20
30
|
var relativeTimeStamp = function (createdAt) {
|
|
@@ -28,6 +38,37 @@ export default function TimeStamp(_a) {
|
|
|
28
38
|
var weeks = Math.floor(days / 7);
|
|
29
39
|
var months = Math.floor(days / 30);
|
|
30
40
|
var years = Math.floor(days / 365);
|
|
41
|
+
// Date-based relativity (years, months, weeks, days)
|
|
42
|
+
if (data === 'date') {
|
|
43
|
+
if (years > 0) {
|
|
44
|
+
return "".concat(years, " year").concat(years > 1 ? 's' : '', " ago");
|
|
45
|
+
}
|
|
46
|
+
else if (months > 0) {
|
|
47
|
+
return "".concat(months, " month").concat(months > 1 ? 's' : '', " ago");
|
|
48
|
+
}
|
|
49
|
+
else if (weeks > 0) {
|
|
50
|
+
return "".concat(weeks, " week").concat(weeks > 1 ? 's' : '', " ago");
|
|
51
|
+
}
|
|
52
|
+
else if (days > 0) {
|
|
53
|
+
return "".concat(days, " day").concat(days > 1 ? 's' : '', " ago");
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
return 'today';
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
// Time-based relativity (hours, minutes, seconds)
|
|
60
|
+
if (data === 'time') {
|
|
61
|
+
if (hours > 0) {
|
|
62
|
+
return "".concat(hours, " hour").concat(hours > 1 ? 's' : '', " ago");
|
|
63
|
+
}
|
|
64
|
+
else if (minutes > 0) {
|
|
65
|
+
return "".concat(minutes, " minute").concat(minutes > 1 ? 's' : '', " ago");
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
return "".concat(seconds, " second").concat(seconds > 1 ? 's' : '', " ago");
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
// Default: date-and-time (full relativity)
|
|
31
72
|
if (years > 0) {
|
|
32
73
|
return "".concat(years, " year").concat(years > 1 ? 's' : '', " ago");
|
|
33
74
|
}
|
|
@@ -51,7 +92,13 @@ export default function TimeStamp(_a) {
|
|
|
51
92
|
}
|
|
52
93
|
};
|
|
53
94
|
var timeStamp = dateFormat === 'absolute' ? absoluteTimeStamp(createdAt) : relativeTimeStamp(createdAt);
|
|
54
|
-
|
|
95
|
+
// Determine text size class
|
|
96
|
+
var sizeClass = textSize === 'medium' ? 'text-body2' : textSize === 'large' ? 'text-body1' : 'text-caption';
|
|
97
|
+
// Determine text color classes
|
|
98
|
+
var colorClass = textColor === 'primary'
|
|
99
|
+
? 'text-light-text-primary dark:text-dark-text-primary'
|
|
100
|
+
: 'text-light-text-secondary dark:text-dark-text-secondary';
|
|
101
|
+
return (<p className={"".concat(sizeClass, " ").concat(colorClass)}>
|
|
55
102
|
{timeStamp}
|
|
56
103
|
</p>);
|
|
57
104
|
}
|