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.
Files changed (41) hide show
  1. package/components/button.tsx +3 -1
  2. package/components/modal.tsx +30 -12
  3. package/dist/components/alert.d.ts +9 -0
  4. package/dist/components/alert.jsx +38 -0
  5. package/dist/components/button.d.ts +13 -0
  6. package/dist/components/button.jsx +141 -0
  7. package/dist/components/checkBox.d.ts +7 -0
  8. package/dist/components/checkBox.jsx +29 -0
  9. package/dist/components/emptyBox.d.ts +7 -0
  10. package/dist/components/emptyBox.jsx +17 -0
  11. package/dist/components/iconButton.d.ts +11 -0
  12. package/dist/components/iconButton.jsx +126 -0
  13. package/dist/components/loadingScreen.d.ts +3 -0
  14. package/dist/components/loadingScreen.jsx +14 -0
  15. package/dist/components/menuItem.d.ts +10 -0
  16. package/dist/components/menuItem.jsx +96 -0
  17. package/dist/components/modal.d.ts +11 -0
  18. package/dist/components/modal.jsx +47 -0
  19. package/dist/components/popover.d.ts +10 -0
  20. package/dist/components/popover.jsx +52 -0
  21. package/dist/components/tab.d.ts +12 -0
  22. package/dist/components/tab.jsx +113 -0
  23. package/dist/components/tag.d.ts +15 -0
  24. package/dist/components/tag.jsx +123 -0
  25. package/dist/components/textField.d.ts +20 -0
  26. package/dist/components/textField.jsx +55 -0
  27. package/dist/components/timeStamp.d.ts +7 -0
  28. package/dist/components/timeStamp.jsx +58 -0
  29. package/dist/components/tooltip.d.ts +7 -0
  30. package/dist/components/tooltip.jsx +41 -0
  31. package/dist/components/userImage.d.ts +7 -0
  32. package/dist/components/userImage.jsx +13 -0
  33. package/dist/designTokens.d.ts +354 -0
  34. package/dist/designTokens.js +232 -0
  35. package/dist/index.d.ts +17 -0
  36. package/dist/index.js +17 -0
  37. package/dist/output.css +102 -0
  38. package/dist/tailwind.config.d.ts +3 -0
  39. package/dist/tailwind.config.js +202 -0
  40. package/package.json +4 -2
  41. package/tsconfig.json +10 -16
@@ -111,7 +111,9 @@ export default function Button({
111
111
  {IconLeft && (
112
112
  <IconLeft className={sizeIcon} />
113
113
  )}
114
- <div className="whitespace-nowrap px-2">{label}</div>
114
+ <div className="flex-1 whitespace-nowrap overflow-hidden truncate px-2">
115
+ {label}
116
+ </div>
115
117
  {IconRight && (
116
118
  <div onClick={onClickActionIcon} className="cursor-pointer">
117
119
  <IconRight className={sizeIcon} />
@@ -1,12 +1,13 @@
1
1
  'use client';
2
- import React, { useEffect } from 'react';
2
+ import React, { useEffect, useRef } from 'react';
3
3
 
4
4
  interface ModalProps {
5
5
  isOpen: boolean;
6
- title: string;
6
+ title?: string;
7
7
  children: React.ReactNode;
8
8
  onClose: () => void;
9
- actions: React.ReactNode;
9
+ actions?: React.ReactNode;
10
+ size?: 'medium' | 'large';
10
11
  }
11
12
 
12
13
  export default function Modal({
@@ -15,28 +16,37 @@ export default function Modal({
15
16
  children,
16
17
  onClose,
17
18
  actions,
19
+ size = 'medium', // Default size is medium
18
20
  }: ModalProps) {
21
+
19
22
  if (!isOpen) return null;
20
23
 
24
+ // close modal by clicking elsewhere
21
25
  const handleOverlayClick = (e: React.MouseEvent<HTMLDivElement>) => {
22
26
  if (e.target === e.currentTarget) {
23
27
  onClose();
24
28
  }
25
29
  };
26
30
 
31
+ // close modal by esc keypress
27
32
  useEffect(() => {
28
33
  const handleKeyDown = (e: KeyboardEvent) => {
29
34
  if (e.key === 'Escape') {
30
35
  onClose();
31
36
  }
32
37
  };
33
-
34
38
  window.addEventListener('keydown', handleKeyDown);
35
39
  return () => {
36
40
  window.removeEventListener('keydown', handleKeyDown);
37
41
  };
38
42
  }, [onClose]);
39
43
 
44
+ // Determine width based on size prop
45
+ const modalWidth = size === 'large' ? 'w-[1200px]' : 'w-[600px]';
46
+ const maxWidth = size === 'large' ? '1200px' : '600px';
47
+
48
+
49
+
40
50
  return (
41
51
  <div
42
52
  className="fixed inset-[-32px] bg-black bg-opacity-50 flex items-center justify-center z-50"
@@ -44,23 +54,31 @@ export default function Modal({
44
54
  role="dialog"
45
55
  aria-labelledby="modal-title"
46
56
  aria-modal="true"
57
+ tabIndex={-1}
47
58
  >
48
59
  <div
49
- className="bg-light-background-default dark:bg-dark-background-default p-6 rounded-[8px] space-y-4 w-[600px]"
60
+ className={`bg-light-background-default dark:bg-dark-background-default p-6 rounded-[8px] space-y-4 ${modalWidth}`}
50
61
  style={{
51
- maxHeight: 'calc(100vh - 64px)',
62
+ maxWidth,
63
+ width: 'calc(100vw - 64px)',
64
+ maxHeight: '800px',
65
+ height: 'auto',
52
66
  overflowY: 'auto',
53
67
  }}
54
68
  >
55
- <h2 id="modal-title" className="text-h6">
56
- {title}
57
- </h2>
69
+ {title && (
70
+ <h2 id="modal-title" className="text-h6">
71
+ {title}
72
+ </h2>
73
+ )}
58
74
  <div className="text-body1 space-y-4">
59
75
  {children}
60
76
  </div>
61
- <div className="flex justify-between">
62
- {actions}
63
- </div>
77
+ {actions && (
78
+ <div className="flex justify-between">
79
+ {actions}
80
+ </div>
81
+ )}
64
82
  </div>
65
83
  </div>
66
84
  );
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+ interface AlertProps {
3
+ open?: boolean;
4
+ type: 'success' | 'warning' | 'error' | 'info';
5
+ message: string;
6
+ onClose: () => void;
7
+ }
8
+ export default function Alert({ open, type, message, onClose }: AlertProps): React.JSX.Element | null;
9
+ export {};
@@ -0,0 +1,38 @@
1
+ 'use client';
2
+ import React, { useEffect } from 'react';
3
+ export default function Alert(_a) {
4
+ var open = _a.open, type = _a.type, message = _a.message, onClose = _a.onClose;
5
+ useEffect(function () {
6
+ if (open) {
7
+ var timer_1 = setTimeout(function () {
8
+ onClose();
9
+ }, 3000);
10
+ return function () { return clearTimeout(timer_1); };
11
+ }
12
+ }, [open, onClose]);
13
+ if (!open)
14
+ return null;
15
+ var bgColor;
16
+ switch (type) {
17
+ case 'error':
18
+ bgColor = 'bg-light-error-main dark:bg-dark-error-main';
19
+ break;
20
+ case 'warning':
21
+ bgColor = 'bg-light-warning-main dark:bg-dark-warning-main';
22
+ break;
23
+ case 'info':
24
+ bgColor = 'bg-light-info-main dark:bg-dark-info-main';
25
+ break;
26
+ case 'success':
27
+ bgColor = 'bg-light-success-main dark:bg-dark-success-main';
28
+ break;
29
+ }
30
+ return (<div className="fixed top-4 inset-x-0 z-50 flex justify-center">
31
+ <div className={"flex items-center justify-between w-full max-w-md p-4 rounded-[8px] shadow-lg text-light-text-contrast dark:text-dark-text-contrast ".concat(bgColor)}>
32
+ <span>{message}</span>
33
+ <button onClick={onClose} className="ml-4 text-xl font-bold">
34
+ &times;
35
+ </button>
36
+ </div>
37
+ </div>);
38
+ }
@@ -0,0 +1,13 @@
1
+ import React from 'react';
2
+ interface ButtonProps {
3
+ size: 'small' | 'medium' | 'large';
4
+ type: 'primary' | 'secondary' | 'tertiary' | 'textOnly';
5
+ state: 'enabled' | 'hovered' | 'focused' | 'disabled';
6
+ label: string;
7
+ decoIcon?: string;
8
+ actionIcon?: string;
9
+ onClickButton?: any;
10
+ onClickActionIcon?: () => void;
11
+ }
12
+ export default function Button({ size, type, state, label, decoIcon, actionIcon, onClickButton, onClickActionIcon, }: ButtonProps): React.JSX.Element;
13
+ export {};
@@ -0,0 +1,141 @@
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 Button(_a) {
40
+ var _this = this;
41
+ var size = _a.size, type = _a.type, state = _a.state, label = _a.label, decoIcon = _a.decoIcon, actionIcon = _a.actionIcon, onClickButton = _a.onClickButton, onClickActionIcon = _a.onClickActionIcon;
42
+ var _b = useState(false), isHovered = _b[0], setIsHovered = _b[1];
43
+ var _c = useState(null), IconLeft = _c[0], setIconLeft = _c[1];
44
+ var _d = useState(null), IconRight = _d[0], setIconRight = _d[1];
45
+ // Import icon dynamically
46
+ var loadIcon = useCallback(function (iconName) { return __awaiter(_this, void 0, void 0, function () {
47
+ var module_1, Icon, error_1;
48
+ return __generator(this, function (_a) {
49
+ switch (_a.label) {
50
+ case 0:
51
+ if (!iconName)
52
+ return [2 /*return*/, null];
53
+ _a.label = 1;
54
+ case 1:
55
+ _a.trys.push([1, 3, , 4]);
56
+ return [4 /*yield*/, import('@heroicons/react/24/outline')];
57
+ case 2:
58
+ module_1 = _a.sent();
59
+ Icon = module_1[iconName];
60
+ return [2 /*return*/, Icon || null];
61
+ case 3:
62
+ error_1 = _a.sent();
63
+ console.error("Failed to load icon ".concat(iconName, ":"), error_1);
64
+ return [2 /*return*/, null];
65
+ case 4: return [2 /*return*/];
66
+ }
67
+ });
68
+ }); }, []);
69
+ useEffect(function () {
70
+ var fetchIcons = function () { return __awaiter(_this, void 0, void 0, function () {
71
+ var _a, _b;
72
+ return __generator(this, function (_c) {
73
+ switch (_c.label) {
74
+ case 0:
75
+ if (!decoIcon) return [3 /*break*/, 2];
76
+ _a = setIconLeft;
77
+ return [4 /*yield*/, loadIcon(decoIcon)];
78
+ case 1:
79
+ _a.apply(void 0, [_c.sent()]);
80
+ _c.label = 2;
81
+ case 2:
82
+ if (!actionIcon) return [3 /*break*/, 4];
83
+ _b = setIconRight;
84
+ return [4 /*yield*/, loadIcon(actionIcon)];
85
+ case 3:
86
+ _b.apply(void 0, [_c.sent()]);
87
+ _c.label = 4;
88
+ case 4: return [2 /*return*/];
89
+ }
90
+ });
91
+ }); };
92
+ fetchIcons();
93
+ }, [decoIcon, actionIcon, loadIcon]);
94
+ // Define classes for size
95
+ var sizeClasses = {
96
+ large: 'text-body1 p-2',
97
+ medium: 'text-body1 p-1',
98
+ small: 'text-body2 p-1',
99
+ }[size];
100
+ // Define icon size classes
101
+ var sizeIcon = {
102
+ large: 'w-6 h-6',
103
+ medium: 'w-5 h-5',
104
+ small: 'w-4 h-4',
105
+ }[size];
106
+ // Define classes for button types
107
+ var baseTypeClasses = {
108
+ primary: 'bg-light-accent-main dark:bg-dark-accent-main text-light-text-primary dark:text-dark-text-contrast',
109
+ secondary: 'bg-light-primary-main dark:bg-dark-primary-main text-light-text-contrast dark:text-dark-text-contrast',
110
+ tertiary: 'bg-light-background-accent200 dark:bg-dark-background-accent200 text-light-text-primary dark:text-dark-text-primary',
111
+ textOnly: 'text-light-text-primary dark:text-dark-text-primary',
112
+ }[type];
113
+ var hoverTypeClasses = {
114
+ primary: 'hover:bg-light-accent-dark hover:dark:bg-dark-accent-dark',
115
+ secondary: 'hover:bg-light-primary-dark dark:hover:bg-dark-primary-dark',
116
+ tertiary: 'hover:bg-light-background-accent300 hover:dark:bg-dark-background-accent300',
117
+ textOnly: 'hover:bg-light-background-accent100 hover:dark:bg-dark-background-accent100',
118
+ }[type];
119
+ // State classes
120
+ var stateClasses = {
121
+ enabled: 'cursor-pointer',
122
+ focused: 'ring-2 ring-offset-4 ring-offset-light-background-default dark:ring-offset-dark-background-default ring-light-accent-main dark:ring-dark-accent-main',
123
+ disabled: type === 'textOnly'
124
+ ? 'cursor-not-allowed text-light-text-disabled dark:text-dark-text-disabled bg-transparent'
125
+ : 'cursor-not-allowed text-light-text-disabled dark:text-dark-text-disabled bg-light-actionBackground-disabled dark:bg-dark-actionBackground-disabled',
126
+ };
127
+ // Build the button classes dynamically
128
+ var buttonClasses = "\n flex flex-row space-x-2 items-center rounded-[8px]\n ".concat(sizeClasses, "\n ").concat(state === 'enabled' ? baseTypeClasses : '', "\n ").concat(state === 'focused' ? stateClasses.focused : '', "\n ").concat(state === 'disabled' ? stateClasses.disabled : baseTypeClasses, "\n ").concat(state !== 'disabled' && isHovered ? hoverTypeClasses : '', "\n ");
129
+ return (<button className={buttonClasses} onMouseEnter={function () { if (state !== 'disabled')
130
+ setIsHovered(true); }} onMouseLeave={function () { if (state !== 'disabled')
131
+ setIsHovered(false); }} onClick={onClickButton} // Button click action
132
+ >
133
+ {IconLeft && (<IconLeft className={sizeIcon}/>)}
134
+ <div className="flex-1 whitespace-nowrap overflow-hidden truncate px-2">
135
+ {label}
136
+ </div>
137
+ {IconRight && (<div onClick={onClickActionIcon} className="cursor-pointer">
138
+ <IconRight className={sizeIcon}/>
139
+ </div>)}
140
+ </button>);
141
+ }
@@ -0,0 +1,7 @@
1
+ interface CheckboxProps {
2
+ label?: string;
3
+ checked?: boolean;
4
+ onChange?: (checked: boolean) => void;
5
+ }
6
+ export default function Checkbox({ label, checked, onChange }: CheckboxProps): import("react").JSX.Element;
7
+ export {};
@@ -0,0 +1,29 @@
1
+ 'use client';
2
+ import { useState } from 'react';
3
+ export default function Checkbox(_a) {
4
+ var label = _a.label, _b = _a.checked, checked = _b === void 0 ? false : _b, onChange = _a.onChange;
5
+ var _c = useState(checked), isChecked = _c[0], setIsChecked = _c[1];
6
+ var handleToggle = function () {
7
+ var newChecked = !isChecked;
8
+ setIsChecked(newChecked);
9
+ if (onChange) {
10
+ onChange(newChecked);
11
+ }
12
+ };
13
+ return (<label className="flex items-center cursor-pointer">
14
+ <div onClick={handleToggle} className="relative flex items-center justify-center w-6 h-6 group">
15
+ {/* Circle behind the checkbox */}
16
+ <div className="absolute w-6 h-6 rounded-full group-hover:bg-light-action-selected dark:group-hover:bg-dark-action-selected transition-all"></div>
17
+
18
+ {/* Checkbox */}
19
+ <div className={"relative z-10 w-4 h-4 border-2 rounded ".concat(isChecked
20
+ ? 'bg-light-accent-main dark:bg-dark-accent-main border-none'
21
+ : 'border-light-text-secondary dark:border-dark-text-secondary', " flex items-center justify-center transition-colors")}>
22
+ {isChecked && (<svg className="w-3 h-3 text-light-text-contrast dark:text-dark-text-contrast" fill="none" stroke="currentColor" viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg">
23
+ <path strokeWidth="2" d="M1 6l4 3 6-7"/>
24
+ </svg>)}
25
+ </div>
26
+ </div>
27
+ {label && <span className="ml-2">{label}</span>}
28
+ </label>);
29
+ }
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ interface EmptyBoxProps {
3
+ text: string;
4
+ size: "small" | "large";
5
+ }
6
+ export default function EmptyBox({ text, size, }: EmptyBoxProps): React.JSX.Element;
7
+ export {};
@@ -0,0 +1,17 @@
1
+ 'use client';
2
+ import React from 'react';
3
+ import { ExclamationCircleIcon } from '@heroicons/react/24/outline';
4
+ export default function EmptyBox(_a) {
5
+ var text = _a.text, size = _a.size;
6
+ var color = 'text-light-text-disabled dark:text-dark-text-disabled';
7
+ var height = size === 'small'
8
+ ? 'py-6'
9
+ : 'h-full';
10
+ var iconSize = 'size-6';
11
+ return (<div className={"flex flex-col space-y-2 justify-center items-center w-full ".concat(height)}>
12
+ <ExclamationCircleIcon className={"".concat(iconSize, " ").concat(color)}/>
13
+ <p className={"text-body1 ".concat(color)} text-center>
14
+ {text}
15
+ </p>
16
+ </div>);
17
+ }
@@ -0,0 +1,11 @@
1
+ import React from 'react';
2
+ import * as HeroIcons from '@heroicons/react/24/outline';
3
+ interface IconButtonProps {
4
+ variant: "contained" | "iconOnly";
5
+ color: "primary" | "secondary";
6
+ state: "enabled" | "selected" | "disabled";
7
+ iconName: keyof typeof HeroIcons;
8
+ onClick?: any;
9
+ }
10
+ export default function IconButton({ variant, color, state, iconName, onClick, }: IconButtonProps): React.JSX.Element;
11
+ export {};
@@ -0,0 +1,126 @@
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 IconButton(_a) {
40
+ var _this = this;
41
+ var variant = _a.variant, color = _a.color, state = _a.state, iconName = _a.iconName, onClick = _a.onClick;
42
+ var _b = useState(false), isHovered = _b[0], setIsHovered = _b[1];
43
+ var _c = useState(null), Icon = _c[0], setIcon = _c[1];
44
+ // import icon
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
+ // Load icons on mount and when props change
69
+ useEffect(function () {
70
+ var fetchIcons = function () { return __awaiter(_this, void 0, void 0, function () {
71
+ var _a;
72
+ return __generator(this, function (_b) {
73
+ switch (_b.label) {
74
+ case 0:
75
+ if (!(typeof iconName === 'string')) return [3 /*break*/, 2];
76
+ _a = setIcon;
77
+ return [4 /*yield*/, loadIcon(iconName)];
78
+ case 1:
79
+ _a.apply(void 0, [_b.sent()]);
80
+ _b.label = 2;
81
+ case 2: return [2 /*return*/];
82
+ }
83
+ });
84
+ }); };
85
+ fetchIcons();
86
+ }, [iconName, loadIcon]);
87
+ // padding, corner
88
+ var baseClasses = variant === 'contained'
89
+ ? 'p-2 rounded-[8px] leading-none '
90
+ : 'p-2 rounded-[8px] leading-none ';
91
+ // bg color
92
+ var bgColor = variant === 'contained'
93
+ ? color === 'primary'
94
+ ? 'bg-light-primary-main dark:bg-dark-primary-main' // contained && primary
95
+ : 'bg-light-background-accent200 dark:bg-dark-background-accent200' // contained && secondary
96
+ : color === 'primary'
97
+ ? ' ' // textOnly && primary
98
+ : ' '; // textOnly && secondary
99
+ // bg color hover
100
+ var bgColorHover = variant === 'contained'
101
+ ? color === 'primary'
102
+ ? 'hover:bg-light-primary-dark hover:dark:bg-dark-primary-dark' // contained && primary
103
+ : 'hover:bg-light-background-accent300 hover:dark:bg-dark-background-accent300' // contained && secondary
104
+ : color === 'primary'
105
+ ? 'hover:bg-light-action-hover hover:dark:bg-dark-action-hover' // textOnly && primary
106
+ : 'hover:bg-light-action-hover hover:dark:bg-dark-action-hover'; // textOnly && secondary
107
+ // icon color
108
+ var iconColor = variant === 'contained'
109
+ ? color === 'primary'
110
+ ? 'text-light-primary-contrast dark:text-dark-primary-contrast' // contained && primary
111
+ : 'text-light-text-primary dark:text-dark-text-primary' // contained && secondary
112
+ : color === 'primary'
113
+ ? ' text-light-text-primary dark:text-dark-text-primary' // textOnly && primary
114
+ : ' text-light-text-primary dark:text-dark-text-primary'; // textOnly && secondary
115
+ // state
116
+ var stateClasses = state === 'disabled'
117
+ ? 'cursor-not-allowed opacity-50'
118
+ : state === 'selected'
119
+ ? 'cursor-pointer ring-2 ring-offset-2 ring-blue-500'
120
+ : isHovered
121
+ ? 'cursor-pointer hover:bg-opacity-75'
122
+ : 'cursor-pointer';
123
+ return (<button className={"".concat(baseClasses, " ").concat(bgColor, " ").concat(iconColor, " ").concat(bgColorHover, " ").concat(stateClasses, " transition-colors duration-300 ease-in-out")} disabled={state === 'disabled'} onMouseEnter={function () { return setIsHovered(true); }} onMouseLeave={function () { return setIsHovered(false); }} onClick={onClick}>
124
+ {Icon && <Icon className="size-6"/>}
125
+ </button>);
126
+ }
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ export default function LoadingScreen(): React.JSX.Element;
3
+ export declare function LoadingSmall(): React.JSX.Element;
@@ -0,0 +1,14 @@
1
+ 'use client';
2
+ import React from 'react';
3
+ export default function LoadingScreen() {
4
+ return (<div className="flex justify-center items-center h-full w-full min-h-[200px]">
5
+ <div className="w-12 h-12 border-4 border-t-transparent border-light-accent-main rounded-full animate-spin"></div>
6
+ </div>);
7
+ }
8
+ ;
9
+ export function LoadingSmall() {
10
+ return (<div className="flex justify-center items-center h-[40px] w-[40px]">
11
+ <div className="w-[40px] h-[40px] border-4 border-t-transparent border-light-accent-main rounded-full animate-spin"></div>
12
+ </div>);
13
+ }
14
+ ;
@@ -0,0 +1,10 @@
1
+ import React from 'react';
2
+ interface MenuItemProps {
3
+ href?: string;
4
+ iconName?: string;
5
+ label: string;
6
+ isSelected?: boolean;
7
+ onClick: any;
8
+ }
9
+ export default function MenuItem({ href, iconName, label, isSelected, onClick, }: MenuItemProps): React.JSX.Element;
10
+ export {};
@@ -0,0 +1,96 @@
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 NextLink from 'next/link';
40
+ export default function MenuItem(_a) {
41
+ var _this = this;
42
+ var _b = _a.href, href = _b === void 0 ? '#' : _b, iconName = _a.iconName, label = _a.label, isSelected = _a.isSelected, onClick = _a.onClick;
43
+ var _c = useState(null), Icon = _c[0], setIcon = _c[1];
44
+ // Import icon dynamically
45
+ var loadIcon = useCallback(function (iconName) { return __awaiter(_this, void 0, void 0, function () {
46
+ var module_1, IconComponent, 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
+ IconComponent = module_1[iconName];
59
+ return [2 /*return*/, IconComponent || 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 fetchIcon = function () { return __awaiter(_this, void 0, void 0, function () {
70
+ var _a;
71
+ return __generator(this, function (_b) {
72
+ switch (_b.label) {
73
+ case 0:
74
+ if (!iconName) return [3 /*break*/, 2];
75
+ _a = setIcon;
76
+ return [4 /*yield*/, loadIcon(iconName)];
77
+ case 1:
78
+ _a.apply(void 0, [_b.sent()]);
79
+ _b.label = 2;
80
+ case 2: return [2 /*return*/];
81
+ }
82
+ });
83
+ }); };
84
+ fetchIcon();
85
+ }, [iconName, loadIcon]);
86
+ return (<NextLink href={href}>
87
+ <div className={"\n flex items-center space-x-2 p-2 rounded-[8px] cursor-pointer justify-start\n ".concat(isSelected
88
+ ? 'bg-light-action-selected dark:bg-dark-action-selected'
89
+ : 'hover:bg-light-background-accent100 hover:dark:bg-dark-background-accent100', "\n ")} style={{ width: '100%' }} onClick={onClick}>
90
+ {Icon && <Icon className="w-6 h-6"/>}
91
+ <span className="whitespace-nowrap text-body1 px-2">
92
+ {label}
93
+ </span>
94
+ </div>
95
+ </NextLink>);
96
+ }