oneslash-design-system 1.1.2 → 1.1.4
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/components/button.tsx +3 -1
- package/components/modal.tsx +30 -12
- package/dist/components/alert.d.ts +9 -0
- package/dist/components/alert.jsx +38 -0
- package/dist/components/button.d.ts +13 -0
- package/dist/components/button.jsx +141 -0
- package/dist/components/checkBox.d.ts +7 -0
- package/dist/components/checkBox.jsx +29 -0
- package/dist/components/emptyBox.d.ts +7 -0
- package/dist/components/emptyBox.jsx +17 -0
- package/dist/components/iconButton.d.ts +11 -0
- package/dist/components/iconButton.jsx +126 -0
- package/dist/components/loadingScreen.d.ts +3 -0
- package/dist/components/loadingScreen.jsx +14 -0
- package/dist/components/menuItem.d.ts +10 -0
- package/dist/components/menuItem.jsx +96 -0
- package/dist/components/modal.d.ts +11 -0
- package/dist/components/modal.jsx +47 -0
- package/dist/components/popover.d.ts +10 -0
- package/dist/components/popover.jsx +52 -0
- package/dist/components/tab.d.ts +12 -0
- package/dist/components/tab.jsx +113 -0
- package/dist/components/tag.d.ts +15 -0
- package/dist/components/tag.jsx +123 -0
- package/dist/components/textField.d.ts +20 -0
- package/dist/components/textField.jsx +55 -0
- package/dist/components/timeStamp.d.ts +7 -0
- package/dist/components/timeStamp.jsx +58 -0
- package/dist/components/tooltip.d.ts +7 -0
- package/dist/components/tooltip.jsx +41 -0
- package/dist/components/userImage.d.ts +7 -0
- package/dist/components/userImage.jsx +13 -0
- package/dist/designTokens.d.ts +354 -0
- package/dist/designTokens.js +232 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.js +17 -0
- package/dist/output.css +102 -0
- package/dist/tailwind.config.d.ts +3 -0
- package/dist/tailwind.config.js +202 -0
- package/package.json +4 -2
- package/tsconfig.json +10 -16
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
interface ModalProps {
|
|
3
|
+
isOpen: boolean;
|
|
4
|
+
title?: string;
|
|
5
|
+
children: React.ReactNode;
|
|
6
|
+
onClose: () => void;
|
|
7
|
+
actions?: React.ReactNode;
|
|
8
|
+
size?: 'medium' | 'large';
|
|
9
|
+
}
|
|
10
|
+
export default function Modal({ isOpen, title, children, onClose, actions, size, }: ModalProps): React.JSX.Element | null;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import React, { useEffect } from 'react';
|
|
3
|
+
export default function Modal(_a) {
|
|
4
|
+
var isOpen = _a.isOpen, title = _a.title, children = _a.children, onClose = _a.onClose, actions = _a.actions, _b = _a.size, size = _b === void 0 ? 'medium' : _b;
|
|
5
|
+
if (!isOpen)
|
|
6
|
+
return null;
|
|
7
|
+
// close modal by clicking elsewhere
|
|
8
|
+
var handleOverlayClick = function (e) {
|
|
9
|
+
if (e.target === e.currentTarget) {
|
|
10
|
+
onClose();
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
// close modal by esc keypress
|
|
14
|
+
useEffect(function () {
|
|
15
|
+
var handleKeyDown = function (e) {
|
|
16
|
+
if (e.key === 'Escape') {
|
|
17
|
+
onClose();
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
window.addEventListener('keydown', handleKeyDown);
|
|
21
|
+
return function () {
|
|
22
|
+
window.removeEventListener('keydown', handleKeyDown);
|
|
23
|
+
};
|
|
24
|
+
}, [onClose]);
|
|
25
|
+
// Determine width based on size prop
|
|
26
|
+
var modalWidth = size === 'large' ? 'w-[1200px]' : 'w-[600px]';
|
|
27
|
+
var maxWidth = size === 'large' ? '1200px' : '600px';
|
|
28
|
+
return (<div className="fixed inset-[-32px] bg-black bg-opacity-50 flex items-center justify-center z-50" onClick={handleOverlayClick} role="dialog" aria-labelledby="modal-title" aria-modal="true" tabIndex={-1}>
|
|
29
|
+
<div className={"bg-light-background-default dark:bg-dark-background-default p-6 rounded-[8px] space-y-4 ".concat(modalWidth)} style={{
|
|
30
|
+
maxWidth: maxWidth,
|
|
31
|
+
width: 'calc(100vw - 64px)',
|
|
32
|
+
maxHeight: '800px',
|
|
33
|
+
height: 'auto',
|
|
34
|
+
overflowY: 'auto',
|
|
35
|
+
}}>
|
|
36
|
+
{title && (<h2 id="modal-title" className="text-h6">
|
|
37
|
+
{title}
|
|
38
|
+
</h2>)}
|
|
39
|
+
<div className="text-body1 space-y-4">
|
|
40
|
+
{children}
|
|
41
|
+
</div>
|
|
42
|
+
{actions && (<div className="flex justify-between">
|
|
43
|
+
{actions}
|
|
44
|
+
</div>)}
|
|
45
|
+
</div>
|
|
46
|
+
</div>);
|
|
47
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
interface PopoverProps {
|
|
3
|
+
id?: string;
|
|
4
|
+
anchorEl?: HTMLElement | null;
|
|
5
|
+
open: boolean;
|
|
6
|
+
onClose: () => void;
|
|
7
|
+
children: React.ReactNode;
|
|
8
|
+
}
|
|
9
|
+
export default function Popover({ id, anchorEl, open, onClose, children, }: PopoverProps): React.ReactPortal | null;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
var __assign = (this && this.__assign) || function () {
|
|
3
|
+
__assign = Object.assign || function(t) {
|
|
4
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
5
|
+
s = arguments[i];
|
|
6
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
7
|
+
t[p] = s[p];
|
|
8
|
+
}
|
|
9
|
+
return t;
|
|
10
|
+
};
|
|
11
|
+
return __assign.apply(this, arguments);
|
|
12
|
+
};
|
|
13
|
+
import React, { useState, useEffect } from 'react';
|
|
14
|
+
import { createPortal } from 'react-dom';
|
|
15
|
+
import { usePopper } from 'react-popper';
|
|
16
|
+
export default function Popover(_a) {
|
|
17
|
+
var id = _a.id, anchorEl = _a.anchorEl, open = _a.open, onClose = _a.onClose, children = _a.children;
|
|
18
|
+
var _b = useState(null), popoverElement = _b[0], setPopoverElement = _b[1];
|
|
19
|
+
var _c = useState(false), hasMounted = _c[0], setHasMounted = _c[1];
|
|
20
|
+
// Initialize Popper.js
|
|
21
|
+
var _d = usePopper(anchorEl, popoverElement, {
|
|
22
|
+
placement: 'bottom-start', // Default placement, can be customized
|
|
23
|
+
modifiers: [
|
|
24
|
+
{ name: 'offset', options: { offset: [0, 8] } }, // Offset for spacing between anchor and popover
|
|
25
|
+
],
|
|
26
|
+
}), styles = _d.styles, attributes = _d.attributes;
|
|
27
|
+
// Handle outside clicks to close the popover
|
|
28
|
+
useEffect(function () {
|
|
29
|
+
var handleClickOutside = function (event) {
|
|
30
|
+
if (popoverElement && !popoverElement.contains(event.target) && anchorEl) {
|
|
31
|
+
onClose();
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
if (open) {
|
|
35
|
+
document.addEventListener('mousedown', handleClickOutside);
|
|
36
|
+
}
|
|
37
|
+
return function () {
|
|
38
|
+
document.removeEventListener('mousedown', handleClickOutside);
|
|
39
|
+
};
|
|
40
|
+
}, [open, anchorEl, popoverElement, onClose]);
|
|
41
|
+
// Ensure popover is only rendered after the component mounts
|
|
42
|
+
useEffect(function () {
|
|
43
|
+
setHasMounted(true);
|
|
44
|
+
}, []);
|
|
45
|
+
if (!open || !hasMounted || !anchorEl)
|
|
46
|
+
return null;
|
|
47
|
+
// Render popover in a portal to prevent layout shifts and positioning issues
|
|
48
|
+
return createPortal(<div id={id} ref={setPopoverElement} style={__assign(__assign({}, styles.popper), { display: open ? 'block' : 'none' })} {...attributes.popper} className="bg-light-background-accent100 dark:bg-dark-background-accent100 rounded-[8px] shadow-lg p-2" role="dialog">
|
|
49
|
+
{children}
|
|
50
|
+
</div>, document.body // Mounting the popover in the document body for isolation
|
|
51
|
+
);
|
|
52
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
type TabProps = {
|
|
3
|
+
label: string;
|
|
4
|
+
href?: string;
|
|
5
|
+
isSelected: boolean;
|
|
6
|
+
onClickTab: () => void;
|
|
7
|
+
onClickActionIcon?: any;
|
|
8
|
+
decoIcon?: string;
|
|
9
|
+
actionIcon?: string;
|
|
10
|
+
};
|
|
11
|
+
export default function Tab({ label, href, isSelected, onClickTab, onClickActionIcon, decoIcon, actionIcon }: TabProps): React.JSX.Element;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
12
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
13
|
+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
14
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
15
|
+
function step(op) {
|
|
16
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
17
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
18
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
19
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
20
|
+
switch (op[0]) {
|
|
21
|
+
case 0: case 1: t = op; break;
|
|
22
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
23
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
24
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
25
|
+
default:
|
|
26
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
27
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
28
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
29
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
30
|
+
if (t[2]) _.ops.pop();
|
|
31
|
+
_.trys.pop(); continue;
|
|
32
|
+
}
|
|
33
|
+
op = body.call(thisArg, _);
|
|
34
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
35
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
import React, { useState, useEffect, useCallback } from 'react';
|
|
39
|
+
import { useRouter, usePathname } from 'next/navigation';
|
|
40
|
+
export default function Tab(_a) {
|
|
41
|
+
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();
|
|
45
|
+
var _b = useState(null), IconLeft = _b[0], setIconLeft = _b[1];
|
|
46
|
+
var _c = useState(null), IconRight = _c[0], setIconRight = _c[1];
|
|
47
|
+
// Load icon dynamically
|
|
48
|
+
var loadIcon = useCallback(function (iconName) { return __awaiter(_this, void 0, void 0, function () {
|
|
49
|
+
var module_1, Icon, error_1;
|
|
50
|
+
return __generator(this, function (_a) {
|
|
51
|
+
switch (_a.label) {
|
|
52
|
+
case 0:
|
|
53
|
+
if (!iconName)
|
|
54
|
+
return [2 /*return*/, null];
|
|
55
|
+
_a.label = 1;
|
|
56
|
+
case 1:
|
|
57
|
+
_a.trys.push([1, 3, , 4]);
|
|
58
|
+
return [4 /*yield*/, import('@heroicons/react/24/outline')];
|
|
59
|
+
case 2:
|
|
60
|
+
module_1 = _a.sent();
|
|
61
|
+
Icon = module_1[iconName];
|
|
62
|
+
return [2 /*return*/, Icon || null];
|
|
63
|
+
case 3:
|
|
64
|
+
error_1 = _a.sent();
|
|
65
|
+
console.error("Failed to load icon ".concat(iconName, ":"), error_1);
|
|
66
|
+
return [2 /*return*/, null];
|
|
67
|
+
case 4: return [2 /*return*/];
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
}); }, []);
|
|
71
|
+
useEffect(function () {
|
|
72
|
+
var fetchIcons = function () { return __awaiter(_this, void 0, void 0, function () {
|
|
73
|
+
var _a, _b;
|
|
74
|
+
return __generator(this, function (_c) {
|
|
75
|
+
switch (_c.label) {
|
|
76
|
+
case 0:
|
|
77
|
+
if (!decoIcon) return [3 /*break*/, 2];
|
|
78
|
+
_a = setIconLeft;
|
|
79
|
+
return [4 /*yield*/, loadIcon(decoIcon)];
|
|
80
|
+
case 1:
|
|
81
|
+
_a.apply(void 0, [_c.sent()]);
|
|
82
|
+
_c.label = 2;
|
|
83
|
+
case 2:
|
|
84
|
+
if (!actionIcon) return [3 /*break*/, 4];
|
|
85
|
+
_b = setIconRight;
|
|
86
|
+
return [4 /*yield*/, loadIcon(actionIcon)];
|
|
87
|
+
case 3:
|
|
88
|
+
_b.apply(void 0, [_c.sent()]);
|
|
89
|
+
_c.label = 4;
|
|
90
|
+
case 4: return [2 /*return*/];
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
}); };
|
|
94
|
+
fetchIcons();
|
|
95
|
+
}, [decoIcon, actionIcon, loadIcon]);
|
|
96
|
+
var handleClick = function () {
|
|
97
|
+
onClickTab();
|
|
98
|
+
if (href) {
|
|
99
|
+
router.push(href);
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
return (<div className={"\n flex items-center space-x-2 p-2 rounded-[8px] cursor-pointer justify-start\n ".concat(isSelected
|
|
103
|
+
? 'bg-light-primary-main dark:bg-dark-primary-main text-light-text-contrast dark:text-dark-text-contrast'
|
|
104
|
+
: 'bg-light-action-selected dark:bg-dark-action-selected hover:bg-light-background-default dark:hover:bg-dark-action-hover', "\n ")} onClick={handleClick}>
|
|
105
|
+
{IconLeft && <IconLeft className="w-5 h-5"/>}
|
|
106
|
+
<span className="whitespace-nowrap text-body1 px-2">
|
|
107
|
+
{label}
|
|
108
|
+
</span>
|
|
109
|
+
{IconRight && (<div onClick={onClickActionIcon} className="cursor-pointer">
|
|
110
|
+
<IconRight className="w-5 h-5"/>
|
|
111
|
+
</div>)}
|
|
112
|
+
</div>);
|
|
113
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import * as HeroIcons from '@heroicons/react/24/outline';
|
|
3
|
+
interface TagProps {
|
|
4
|
+
key?: any;
|
|
5
|
+
variant: "contained" | "textOnly";
|
|
6
|
+
size: "medium" | "small";
|
|
7
|
+
state?: "enabled" | "selected";
|
|
8
|
+
label: any;
|
|
9
|
+
iconName?: keyof typeof HeroIcons;
|
|
10
|
+
isDeletable?: keyof typeof HeroIcons;
|
|
11
|
+
onClick?: any;
|
|
12
|
+
color?: 'default' | 'info';
|
|
13
|
+
}
|
|
14
|
+
export default function Tag({ key, variant, size, state, label, iconName, isDeletable, onClick, color, }: TagProps): React.JSX.Element;
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
12
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
13
|
+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
14
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
15
|
+
function step(op) {
|
|
16
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
17
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
18
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
19
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
20
|
+
switch (op[0]) {
|
|
21
|
+
case 0: case 1: t = op; break;
|
|
22
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
23
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
24
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
25
|
+
default:
|
|
26
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
27
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
28
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
29
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
30
|
+
if (t[2]) _.ops.pop();
|
|
31
|
+
_.trys.pop(); continue;
|
|
32
|
+
}
|
|
33
|
+
op = body.call(thisArg, _);
|
|
34
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
35
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
import React, { useState, useEffect, useCallback } from 'react';
|
|
39
|
+
export default function Tag(_a) {
|
|
40
|
+
var _this = this;
|
|
41
|
+
var key = _a.key, variant = _a.variant, size = _a.size, state = _a.state, label = _a.label, iconName = _a.iconName, isDeletable = _a.isDeletable, onClick = _a.onClick, _b = _a.color, color = _b === void 0 ? 'default' : _b;
|
|
42
|
+
var _c = useState(false), isHovered = _c[0], setIsHovered = _c[1];
|
|
43
|
+
var _d = useState(null), Icon = _d[0], setIcon = _d[1];
|
|
44
|
+
var _e = useState(null), DeleteIcon = _e[0], setDeleteIcon = _e[1];
|
|
45
|
+
var loadIcon = useCallback(function (iconName) { return __awaiter(_this, void 0, void 0, function () {
|
|
46
|
+
var module_1, Icon_1, error_1;
|
|
47
|
+
return __generator(this, function (_a) {
|
|
48
|
+
switch (_a.label) {
|
|
49
|
+
case 0:
|
|
50
|
+
if (!iconName)
|
|
51
|
+
return [2 /*return*/, null];
|
|
52
|
+
_a.label = 1;
|
|
53
|
+
case 1:
|
|
54
|
+
_a.trys.push([1, 3, , 4]);
|
|
55
|
+
return [4 /*yield*/, import('@heroicons/react/24/outline')];
|
|
56
|
+
case 2:
|
|
57
|
+
module_1 = _a.sent();
|
|
58
|
+
Icon_1 = module_1[iconName];
|
|
59
|
+
return [2 /*return*/, Icon_1 || null];
|
|
60
|
+
case 3:
|
|
61
|
+
error_1 = _a.sent();
|
|
62
|
+
console.error("Failed to load icon ".concat(iconName, ":"), error_1);
|
|
63
|
+
return [2 /*return*/, null];
|
|
64
|
+
case 4: return [2 /*return*/];
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
}); }, []);
|
|
68
|
+
useEffect(function () {
|
|
69
|
+
var fetchIcons = function () { return __awaiter(_this, void 0, void 0, function () {
|
|
70
|
+
var _a, _b;
|
|
71
|
+
return __generator(this, function (_c) {
|
|
72
|
+
switch (_c.label) {
|
|
73
|
+
case 0:
|
|
74
|
+
if (!(typeof iconName === 'string')) return [3 /*break*/, 2];
|
|
75
|
+
_a = setIcon;
|
|
76
|
+
return [4 /*yield*/, loadIcon(iconName)];
|
|
77
|
+
case 1:
|
|
78
|
+
_a.apply(void 0, [_c.sent()]);
|
|
79
|
+
_c.label = 2;
|
|
80
|
+
case 2:
|
|
81
|
+
if (!(typeof isDeletable === 'string')) return [3 /*break*/, 4];
|
|
82
|
+
_b = setDeleteIcon;
|
|
83
|
+
return [4 /*yield*/, loadIcon(isDeletable)];
|
|
84
|
+
case 3:
|
|
85
|
+
_b.apply(void 0, [_c.sent()]);
|
|
86
|
+
_c.label = 4;
|
|
87
|
+
case 4: return [2 /*return*/];
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
}); };
|
|
91
|
+
fetchIcons();
|
|
92
|
+
}, [iconName, isDeletable, loadIcon]);
|
|
93
|
+
// size and padding
|
|
94
|
+
var sizeClasses = size === 'medium' ? 'text-body2 px-2 py-1' : 'text-caption px-2 py-[3px]';
|
|
95
|
+
// bg color
|
|
96
|
+
var bgClasses = variant === 'contained'
|
|
97
|
+
? (color === 'info'
|
|
98
|
+
? 'bg-light-info-main dark:bg-dark-info-main' // info
|
|
99
|
+
: 'bg-light-background-accent200 dark:bg-dark-background-accent200') // default
|
|
100
|
+
: ''; // textOnly
|
|
101
|
+
// font color
|
|
102
|
+
var fontClasses = variant === 'textOnly'
|
|
103
|
+
? (color === 'info'
|
|
104
|
+
? 'text-light-info-main dark:text-dark-info-main' // info
|
|
105
|
+
: 'text-light-text-primary dark:text-dark-text-primary') // default
|
|
106
|
+
: 'text-light-text-primary dark:text-dark-text-primary'; // contained
|
|
107
|
+
// state
|
|
108
|
+
var stateClasses = state === 'selected'
|
|
109
|
+
? 'bg-light-accent-main dark:bg-dark-accent-main text-white'
|
|
110
|
+
: 'cursor-pointer';
|
|
111
|
+
// hover
|
|
112
|
+
var hoverClasses = isHovered ? (variant === 'contained' ? 'hover:bg-dark-background-accent300' : '') : '';
|
|
113
|
+
return (<div className={"flex items-center space-x-1 rounded-full \n ".concat(sizeClasses, " ").concat(bgClasses, " ").concat(fontClasses, " ").concat(stateClasses, " ").concat(hoverClasses, " \n transition-colors duration-300 ease-in-out")} onMouseEnter={function () { return setIsHovered(true); }} onMouseLeave={function () { return setIsHovered(false); }} onClick={onClick}>
|
|
114
|
+
{Icon && <Icon className="w-4 h-4"/>}
|
|
115
|
+
<span>{label}</span>
|
|
116
|
+
{isDeletable && (<button className="ml-2 text-red-500" onClick={function (e) {
|
|
117
|
+
e.stopPropagation();
|
|
118
|
+
// Handle delete action
|
|
119
|
+
}}>
|
|
120
|
+
{DeleteIcon && <DeleteIcon className="w-4 h-4"/>}
|
|
121
|
+
</button>)}
|
|
122
|
+
</div>);
|
|
123
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
interface TextFieldProps {
|
|
3
|
+
id: string;
|
|
4
|
+
label?: string;
|
|
5
|
+
value: string;
|
|
6
|
+
onChange: (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => void;
|
|
7
|
+
onBlur?: (e: React.FocusEvent<HTMLInputElement | HTMLTextAreaElement>) => void;
|
|
8
|
+
onFocus?: (e: React.FocusEvent<HTMLInputElement | HTMLTextAreaElement>) => void;
|
|
9
|
+
onKeyDown?: (e: React.KeyboardEvent<HTMLInputElement | HTMLTextAreaElement>) => void;
|
|
10
|
+
autoFocus?: boolean;
|
|
11
|
+
iconLeft?: React.ReactNode;
|
|
12
|
+
iconRight?: React.ReactNode | React.ComponentType<any>;
|
|
13
|
+
multiline?: boolean;
|
|
14
|
+
maxRows?: number;
|
|
15
|
+
disabled?: boolean;
|
|
16
|
+
error?: boolean;
|
|
17
|
+
}
|
|
18
|
+
export default function TextField({ id, label, value, onChange, onBlur, onFocus, onKeyDown, autoFocus, // Accept the autoFocus prop with default value
|
|
19
|
+
iconLeft, iconRight, multiline, maxRows, disabled, error, }: TextFieldProps): React.JSX.Element;
|
|
20
|
+
export {};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import React, { useState } from 'react';
|
|
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, _b = _a.autoFocus, autoFocus = _b === void 0 ? false : _b, // Accept the autoFocus prop with default value
|
|
5
|
+
iconLeft = _a.iconLeft, iconRight = _a.iconRight, _c = _a.multiline, multiline = _c === void 0 ? false : _c, _d = _a.maxRows, maxRows = _d === void 0 ? 6 : _d, _e = _a.disabled, disabled = _e === void 0 ? false : _e, _f = _a.error, error = _f === void 0 ? false : _f;
|
|
6
|
+
var _g = useState(false), isFocused = _g[0], setIsFocused = _g[1];
|
|
7
|
+
var baseClasses = 'w-full border rounded-[8px] p-2';
|
|
8
|
+
var bgColor = 'bg-light-background-default dark:bg-dark-background-default transition-colors duration-300 ease-in-out';
|
|
9
|
+
var borderColor = 'border-light-outlinedBorder-active dark:border-dark-outlinedBorder-active';
|
|
10
|
+
var containerClasses = "\n ".concat(bgColor, "\n ").concat(borderColor, "\n ").concat(baseClasses, "\n ").concat(disabled ? 'bg-gray-200 cursor-not-allowed' : '', "\n ").concat(error ? 'border-red-500 focus:ring-red-500' : '', "\n ").concat(isFocused ? 'focus:border-light-accent-main focus:dark:border-dark-accent-main outline-none' : '', "\n ").concat(!disabled && !error ? 'hover:border-light-outlinedBorder-hover' : '', "\n border-gray-300\n ");
|
|
11
|
+
var renderIconRight = function () {
|
|
12
|
+
if (React.isValidElement(iconRight)) {
|
|
13
|
+
return iconRight;
|
|
14
|
+
}
|
|
15
|
+
if (typeof iconRight === 'function') {
|
|
16
|
+
return React.createElement(iconRight);
|
|
17
|
+
}
|
|
18
|
+
return null;
|
|
19
|
+
};
|
|
20
|
+
return (<div className="flex flex-col w-full">
|
|
21
|
+
{label && (<label htmlFor={id} className="mb-1 text-body2 text-light-text-secondary dark:text-dark-text-secondary">
|
|
22
|
+
{label}
|
|
23
|
+
</label>)}
|
|
24
|
+
<div className="relative">
|
|
25
|
+
{iconLeft && (<span className="absolute inset-y-0 left-0 pl-3 flex items-center">
|
|
26
|
+
{iconLeft}
|
|
27
|
+
</span>)}
|
|
28
|
+
{iconRight && (<span className="absolute inset-y-0 right-0 pr-3 flex items-center">
|
|
29
|
+
{renderIconRight()}
|
|
30
|
+
</span>)}
|
|
31
|
+
{multiline ? (<textarea id={id} rows={maxRows} className={containerClasses} value={value} onChange={onChange} onFocus={function (e) {
|
|
32
|
+
setIsFocused(true);
|
|
33
|
+
if (onFocus)
|
|
34
|
+
onFocus(e);
|
|
35
|
+
}} onBlur={function (e) {
|
|
36
|
+
setIsFocused(false);
|
|
37
|
+
if (onBlur)
|
|
38
|
+
onBlur(e);
|
|
39
|
+
}} onKeyDown={onKeyDown} autoFocus={autoFocus} // Pass autoFocus to textarea
|
|
40
|
+
disabled={disabled}/>) : (<input id={id} type="text" className={containerClasses} value={value} onChange={onChange} onFocus={function (e) {
|
|
41
|
+
setIsFocused(true);
|
|
42
|
+
if (onFocus)
|
|
43
|
+
onFocus(e);
|
|
44
|
+
}} onBlur={function (e) {
|
|
45
|
+
setIsFocused(false);
|
|
46
|
+
if (onBlur)
|
|
47
|
+
onBlur(e);
|
|
48
|
+
}} onKeyDown={onKeyDown} autoFocus={autoFocus} // Pass autoFocus to input
|
|
49
|
+
disabled={disabled}/>)}
|
|
50
|
+
</div>
|
|
51
|
+
{error && (<p className="mt-1 text-light-error-main text-body2">
|
|
52
|
+
This field is required
|
|
53
|
+
</p>)}
|
|
54
|
+
</div>);
|
|
55
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
export default function TimeStamp(_a) {
|
|
4
|
+
var createdAt = _a.createdAt, dateFormat = _a.dateFormat;
|
|
5
|
+
// absolute timestamp
|
|
6
|
+
var absoluteTimeStamp = function (createdAt) {
|
|
7
|
+
var date = new Date(createdAt);
|
|
8
|
+
var month = (date.getMonth() + 1).toString().padStart(2, '0');
|
|
9
|
+
var day = date.getDate().toString().padStart(2, '0');
|
|
10
|
+
var year = date.getFullYear();
|
|
11
|
+
var hours = date.getHours();
|
|
12
|
+
var minutes = date.getMinutes();
|
|
13
|
+
var formattedHours = hours.toString().padStart(2, '0');
|
|
14
|
+
var formattedMinutes = minutes.toString().padStart(2, '0');
|
|
15
|
+
var daysOfWeek = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
|
|
16
|
+
var dayOfWeek = daysOfWeek[date.getDay()];
|
|
17
|
+
return "".concat(month, "/").concat(day, "/").concat(year, " ").concat(dayOfWeek, " ").concat(formattedHours, ":").concat(formattedMinutes);
|
|
18
|
+
};
|
|
19
|
+
// relative timestamp
|
|
20
|
+
var relativeTimeStamp = function (createdAt) {
|
|
21
|
+
var date = new Date(createdAt);
|
|
22
|
+
var now = new Date();
|
|
23
|
+
var diff = now.getTime() - date.getTime();
|
|
24
|
+
var seconds = Math.floor(diff / 1000);
|
|
25
|
+
var minutes = Math.floor(seconds / 60);
|
|
26
|
+
var hours = Math.floor(minutes / 60);
|
|
27
|
+
var days = Math.floor(hours / 24);
|
|
28
|
+
var weeks = Math.floor(days / 7);
|
|
29
|
+
var months = Math.floor(days / 30);
|
|
30
|
+
var years = Math.floor(days / 365);
|
|
31
|
+
if (years > 0) {
|
|
32
|
+
return "".concat(years, " year").concat(years > 1 ? 's' : '', " ago");
|
|
33
|
+
}
|
|
34
|
+
else if (months > 0) {
|
|
35
|
+
return "".concat(months, " month").concat(months > 1 ? 's' : '', " ago");
|
|
36
|
+
}
|
|
37
|
+
else if (weeks > 0) {
|
|
38
|
+
return "".concat(weeks, " week").concat(weeks > 1 ? 's' : '', " ago");
|
|
39
|
+
}
|
|
40
|
+
else if (days > 0) {
|
|
41
|
+
return "".concat(days, " day").concat(days > 1 ? 's' : '', " ago");
|
|
42
|
+
}
|
|
43
|
+
else if (hours > 0) {
|
|
44
|
+
return "".concat(hours, " hour").concat(hours > 1 ? 's' : '', " ago");
|
|
45
|
+
}
|
|
46
|
+
else if (minutes > 0) {
|
|
47
|
+
return "".concat(minutes, " minute").concat(minutes > 1 ? 's' : '', " ago");
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
return "".concat(seconds, " second").concat(seconds > 1 ? 's' : '', " ago");
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
var timeStamp = dateFormat === 'absolute' ? absoluteTimeStamp(createdAt) : relativeTimeStamp(createdAt);
|
|
54
|
+
return (<p className="text-caption text-light-text-secondary dark:text-dark-text-secondary">
|
|
55
|
+
{timeStamp}
|
|
56
|
+
</p>);
|
|
57
|
+
}
|
|
58
|
+
;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import React, { useState, useRef, useEffect } from 'react';
|
|
3
|
+
export default function Tooltip(_a) {
|
|
4
|
+
var title = _a.title, children = _a.children;
|
|
5
|
+
var _b = useState(false), visible = _b[0], setVisible = _b[1];
|
|
6
|
+
var _c = useState('bottom'), position = _c[0], setPosition = _c[1];
|
|
7
|
+
var tooltipRef = useRef(null);
|
|
8
|
+
var buttonRef = useRef(null);
|
|
9
|
+
useEffect(function () {
|
|
10
|
+
var handlePosition = function () {
|
|
11
|
+
if (tooltipRef.current && buttonRef.current) {
|
|
12
|
+
var tooltipRect = tooltipRef.current.getBoundingClientRect();
|
|
13
|
+
var buttonRect = buttonRef.current.getBoundingClientRect();
|
|
14
|
+
// Check if there's enough space below; if not, place tooltip above
|
|
15
|
+
if (window.innerHeight - buttonRect.bottom < tooltipRect.height + 8) {
|
|
16
|
+
setPosition('top');
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
setPosition('bottom');
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
if (visible) {
|
|
24
|
+
handlePosition();
|
|
25
|
+
}
|
|
26
|
+
}, [visible]);
|
|
27
|
+
var handleClick = function () {
|
|
28
|
+
setVisible(false); // Hide tooltip on click
|
|
29
|
+
};
|
|
30
|
+
return (<div ref={buttonRef} onMouseEnter={function () { return setVisible(true); }} onMouseLeave={function () { return setVisible(false); }} onClick={handleClick} className="relative inline-block">
|
|
31
|
+
{children}
|
|
32
|
+
{visible && (<div ref={tooltipRef} className={"absolute whitespace-nowrap text-caption rounded-[8px] py-1 px-2 z-50\n dark:bg-light-background-accent300 bg-dark-background-accent300 \n dark:text-light-text-primary text-dark-text-primary\n\t\t\t\t\t\t\t".concat(position === 'bottom' ? 'mt-1' : 'mb-1')} style={{
|
|
33
|
+
bottom: position === 'top' ? '100%' : undefined,
|
|
34
|
+
top: position === 'bottom' ? '100%' : undefined,
|
|
35
|
+
left: '50%',
|
|
36
|
+
transform: 'translateX(-50%)',
|
|
37
|
+
}}>
|
|
38
|
+
{title}
|
|
39
|
+
</div>)}
|
|
40
|
+
</div>);
|
|
41
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
export default function UserImage(_a) {
|
|
4
|
+
var userHandle = _a.userHandle, userImgUrl = _a.userImgUrl;
|
|
5
|
+
var defaultInitial = userHandle.charAt(0).toUpperCase();
|
|
6
|
+
return (<div className="flex items-center justify-center w-6 h-6 rounded-full overflow-hidden
|
|
7
|
+
bg-light-background-accent200 dark:bg-dark-background-accent200
|
|
8
|
+
text-light-text-secondary dark:text-dark-text-secondary ">
|
|
9
|
+
{userImgUrl ? (<img src={userImgUrl} alt={userHandle} className="w-full h-full object-cover rounded-full"/>) : (<span className="text-body1">
|
|
10
|
+
{defaultInitial}
|
|
11
|
+
</span>)}
|
|
12
|
+
</div>);
|
|
13
|
+
}
|