uibee 2.8.7 → 2.9.1
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/src/components/confirm/confirmPopup.d.ts +12 -0
- package/dist/src/components/confirm/confirmPopup.js +18 -0
- package/dist/src/components/index.d.ts +1 -0
- package/dist/src/components/index.js +2 -0
- package/dist/src/components/navbar/navbar.d.ts +4 -3
- package/dist/src/components/navbar/navbar.js +12 -8
- package/dist/src/globals.css +97 -0
- package/package.json +1 -1
- package/src/components/confirm/confirmPopup.tsx +103 -0
- package/src/components/index.ts +4 -1
- package/src/components/navbar/navbar.tsx +46 -22
- package/src/types/components.d.ts +12 -0
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
type ConfirmPopupProps = {
|
|
2
|
+
isOpen: boolean;
|
|
3
|
+
header: string;
|
|
4
|
+
description?: string;
|
|
5
|
+
confirmText?: string;
|
|
6
|
+
cancelText?: string;
|
|
7
|
+
onConfirm: () => void;
|
|
8
|
+
onCancel: () => void;
|
|
9
|
+
variant?: 'danger' | 'warning' | 'default';
|
|
10
|
+
};
|
|
11
|
+
export default function ConfirmPopup({ isOpen, header, description, confirmText, cancelText, onConfirm, onCancel, variant, }: ConfirmPopupProps): import("react/jsx-runtime").JSX.Element | null;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { TriangleAlert } from 'lucide-react';
|
|
4
|
+
export default function ConfirmPopup({ isOpen, header, description, confirmText = 'Confirm', cancelText = 'Cancel', onConfirm, onCancel, variant = 'default', }) {
|
|
5
|
+
if (!isOpen)
|
|
6
|
+
return null;
|
|
7
|
+
const confirmBg = variant === 'danger'
|
|
8
|
+
? 'bg-red-700/80 outline-red-700 hover:bg-red-700'
|
|
9
|
+
: variant === 'warning'
|
|
10
|
+
? 'bg-yellow-600/80 outline-yellow-600 hover:bg-yellow-600'
|
|
11
|
+
: 'bg-login/70 outline-login hover:bg-login/90';
|
|
12
|
+
return (_jsxs("div", { role: 'dialog', "aria-modal": 'true', "aria-labelledby": 'confirm-popup-header', className: 'fixed inset-0 z-50 flex items-center justify-center', onClick: onCancel, children: [_jsx("div", { className: 'absolute inset-0 bg-black/60 backdrop-blur-sm' }), _jsxs("div", { className: '\n relative z-10 w-full max-w-md mx-4\n bg-login-800 border border-login-500/50 rounded-xl\n shadow-2xl p-6 flex flex-col gap-4\n ', onClick: (e) => e.stopPropagation(), children: [_jsxs("div", { className: 'flex items-center gap-3', children: [variant !== 'default' && (_jsx(TriangleAlert, { className: `w-6 h-6 shrink-0 ${variant === 'danger' ? 'stroke-red-400' : 'stroke-yellow-400'}` })), _jsx("h2", { id: 'confirm-popup-header', className: 'text-login-50 text-lg font-bold leading-snug', children: header })] }), description && (_jsx("p", { className: 'text-login-100 text-sm leading-relaxed', children: description })), _jsxs("div", { className: 'flex justify-end gap-3 mt-1', children: [_jsx("button", { type: 'button', onClick: onCancel, className: '\n cursor-pointer px-4 py-1.5 rounded-md text-sm font-medium\n bg-login-500/60 text-login-50 outline outline-login-500/60\n hover:bg-login-500/90 focus:outline-none select-none\n transition-colors duration-150\n ', children: cancelText }), _jsx("button", { type: 'button', onClick: onConfirm, className: `
|
|
13
|
+
cursor-pointer px-4 py-1.5 rounded-md text-sm font-bold
|
|
14
|
+
text-white outline focus:outline-none select-none
|
|
15
|
+
transition-colors duration-150
|
|
16
|
+
${confirmBg}
|
|
17
|
+
`, children: confirmText })] })] })] }));
|
|
18
|
+
}
|
|
@@ -20,3 +20,4 @@ export { default as LoginPage } from './login/loginPage';
|
|
|
20
20
|
export { default as Toaster, toast } from './toast/toaster';
|
|
21
21
|
export { default as Button } from './buttons/button';
|
|
22
22
|
export { default as Alert } from './alert/alert';
|
|
23
|
+
export { default as ConfirmPopup } from './confirm/confirmPopup';
|
|
@@ -7,10 +7,11 @@ export type NavbarProps = {
|
|
|
7
7
|
theme?: string;
|
|
8
8
|
disableThemeToggle?: boolean;
|
|
9
9
|
token?: string | null;
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
profilePath?: string;
|
|
11
|
+
loginPath: string;
|
|
12
|
+
logoutPath: string;
|
|
12
13
|
className?: string;
|
|
13
14
|
innerClassName?: string;
|
|
14
15
|
children: React.ReactNode;
|
|
15
16
|
};
|
|
16
|
-
export default function Navbar({ lang, onlyLogo, disableLanguageToggle, disableThemeToggle, token,
|
|
17
|
+
export default function Navbar({ lang, onlyLogo, disableLanguageToggle, disableThemeToggle, token, profilePath, loginPath, logoutPath, className, innerClassName, children, }: NavbarProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -11,10 +11,13 @@ function hamburgerStyle(isOpen, isSecond) {
|
|
|
11
11
|
? `top-6 ${isSecond ? 'rotate-45' : '-rotate-45'}`
|
|
12
12
|
: isSecond ? 'top-7' : 'top-4'}`;
|
|
13
13
|
}
|
|
14
|
-
export default function Navbar({ lang, onlyLogo, disableLanguageToggle, disableThemeToggle, token,
|
|
14
|
+
export default function Navbar({ lang, onlyLogo, disableLanguageToggle, disableThemeToggle, token, profilePath, loginPath, logoutPath, className, innerClassName, children, }) {
|
|
15
15
|
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
|
|
16
16
|
return (_jsx("div", { className: `${isMobileMenuOpen ? 'bg-[#181818f0]' : 'bg-[#18181899]'} backdrop-blur-xl fixed top-0 z-900 w-full ${className}`, children: _jsxs("div", { className: `flex w-full max-w-6xl m-auto p-2 transition duration-500 800px:justify-between 800px:p-4 ${isMobileMenuOpen ? 'h-screen bg-login-900/20 800px:h-20' : ''} ${innerClassName}
|
|
17
|
-
`, children: [_jsx("div", { className: 'block h-12 p-1 800px:p-0', children: _jsx(Link, { href: '/', onClick: () => setIsMobileMenuOpen(false), children: _jsx(LogoSmall, {}) }) }), onlyLogo ? null : (_jsxs(_Fragment, { children: [_jsx("nav", { className: 'hidden 800px:flex 800px:justify-between 800px:items-center 800px:w-fill max-w-200', children: children }), _jsxs("nav", { className: 'flex w-[calc(100vw-8rem)] justify-end h-12 800px:w-fit', children: [!disableThemeToggle &&
|
|
17
|
+
`, children: [_jsx("div", { className: 'block h-12 p-1 800px:p-0', children: _jsx(Link, { href: '/', onClick: () => setIsMobileMenuOpen(false), children: _jsx(LogoSmall, {}) }) }), onlyLogo ? null : (_jsxs(_Fragment, { children: [_jsx("nav", { className: 'hidden 800px:flex 800px:justify-between 800px:items-center 800px:w-fill max-w-200', children: children }), _jsxs("nav", { className: 'flex w-[calc(100vw-8rem)] justify-end h-12 800px:w-fit', children: [!disableThemeToggle &&
|
|
18
|
+
_jsx(ThemeToggle, {}), !disableLanguageToggle &&
|
|
19
|
+
_jsx(LanguageToggle, { language: lang }), !loginPath && !logoutPath &&
|
|
20
|
+
_jsx(AuthButton, { profilePath: profilePath, token: token, loginPath: loginPath, logoutPath: logoutPath })] }), _jsxs("button", { className: 'w-12 h-12 relative cursor-pointer bg-none border-none 800px:hidden', onClick: () => setIsMobileMenuOpen(!isMobileMenuOpen), children: [_jsx("div", { className: hamburgerStyle(isMobileMenuOpen) }), _jsx("div", { className: hamburgerStyle(isMobileMenuOpen, true) })] }), _jsx("nav", { className: `fixed top-16 w-[calc(100%-2rem)] max-w-140 mx-auto left-0 right-0 800px:hidden
|
|
18
21
|
transition-all duration-500 ease-in-out overflow-hidden
|
|
19
22
|
${isMobileMenuOpen ? 'max-h-[calc(100vh-4rem)] opacity-100' : 'max-h-0 opacity-0'}`, onClick: () => setIsMobileMenuOpen(false), children: React.Children.map(children, (child, index) => (_jsx("div", { className: `transition-all duration-500 ease-out ${isMobileMenuOpen
|
|
20
23
|
? 'opacity-100 transform translate-y-0'
|
|
@@ -22,10 +25,11 @@ export default function Navbar({ lang, onlyLogo, disableLanguageToggle, disableT
|
|
|
22
25
|
transitionDelay: isMobileMenuOpen ? `${index * 80}ms` : '0ms'
|
|
23
26
|
}, children: child }, index))) })] }))] }) }));
|
|
24
27
|
}
|
|
25
|
-
function AuthButton({
|
|
26
|
-
return (_jsx("div", { className: 'rounded-[0.3rem] hover:bg-login-300/20 h-12 w-12', children: token ? (_jsxs(_Fragment, { children: [
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
function AuthButton({ profilePath, logoutPath, loginPath, token }) {
|
|
29
|
+
return (_jsx("div", { className: 'rounded-[0.3rem] hover:bg-login-300/20 h-12 w-12', children: token ? (_jsxs(_Fragment, { children: [logoutPath &&
|
|
30
|
+
_jsx(Link, { href: logoutPath, prefetch: false, onClick: (e) => {
|
|
31
|
+
e.preventDefault();
|
|
32
|
+
window.location.href = logoutPath;
|
|
33
|
+
}, className: 'grid items-center justify-center h-full w-full', children: _jsx(LogOut, { size: 24 }) }), profilePath &&
|
|
34
|
+
_jsx(Link, { href: profilePath, className: 'grid items-center justify-center h-full w-full', children: _jsx(User, { size: 24 }) })] })) : (_jsx(Link, { href: loginPath, className: 'grid items-center justify-center h-full w-full', children: _jsx(User, { size: 24 }) })) }));
|
|
31
35
|
}
|
package/dist/src/globals.css
CHANGED
|
@@ -10,8 +10,11 @@
|
|
|
10
10
|
--color-red-200: oklch(88.5% 0.062 18.334);
|
|
11
11
|
--color-red-400: oklch(70.4% 0.191 22.216);
|
|
12
12
|
--color-red-500: oklch(63.7% 0.237 25.331);
|
|
13
|
+
--color-red-700: oklch(50.5% 0.213 27.518);
|
|
13
14
|
--color-red-900: oklch(39.6% 0.141 25.723);
|
|
15
|
+
--color-yellow-400: oklch(85.2% 0.199 91.936);
|
|
14
16
|
--color-yellow-500: oklch(79.5% 0.184 86.047);
|
|
17
|
+
--color-yellow-600: oklch(68.1% 0.162 75.834);
|
|
15
18
|
--color-green-500: oklch(72.3% 0.219 149.579);
|
|
16
19
|
--color-blue-500: oklch(62.3% 0.214 259.815);
|
|
17
20
|
--color-blue-600: oklch(54.6% 0.245 262.881);
|
|
@@ -46,6 +49,8 @@
|
|
|
46
49
|
--font-weight-bold: 700;
|
|
47
50
|
--font-weight-extrabold: 800;
|
|
48
51
|
--tracking-tight: -0.025em;
|
|
52
|
+
--leading-snug: 1.375;
|
|
53
|
+
--leading-relaxed: 1.625;
|
|
49
54
|
--radius-xs: 0.125rem;
|
|
50
55
|
--radius-sm: 0.25rem;
|
|
51
56
|
--radius-md: 0.375rem;
|
|
@@ -53,6 +58,7 @@
|
|
|
53
58
|
--radius-xl: 0.75rem;
|
|
54
59
|
--ease-out: cubic-bezier(0, 0, 0.2, 1);
|
|
55
60
|
--ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
|
|
61
|
+
--blur-sm: 8px;
|
|
56
62
|
--blur-xl: 24px;
|
|
57
63
|
--default-transition-duration: 150ms;
|
|
58
64
|
--default-transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
|
@@ -377,6 +383,9 @@
|
|
|
377
383
|
.m-auto {
|
|
378
384
|
margin: auto;
|
|
379
385
|
}
|
|
386
|
+
.mx-4 {
|
|
387
|
+
margin-inline: calc(var(--spacing) * 4);
|
|
388
|
+
}
|
|
380
389
|
.mx-auto {
|
|
381
390
|
margin-inline: auto;
|
|
382
391
|
}
|
|
@@ -1442,6 +1451,12 @@
|
|
|
1442
1451
|
.border-login-500 {
|
|
1443
1452
|
border-color: var(--color-login-500);
|
|
1444
1453
|
}
|
|
1454
|
+
.border-login-500\/50 {
|
|
1455
|
+
border-color: color-mix(in srgb, #323232 50%, transparent);
|
|
1456
|
+
@supports (color: color-mix(in lab, red, red)) {
|
|
1457
|
+
border-color: color-mix(in oklab, var(--color-login-500) 50%, transparent);
|
|
1458
|
+
}
|
|
1459
|
+
}
|
|
1445
1460
|
.border-red-500 {
|
|
1446
1461
|
border-color: var(--color-red-500);
|
|
1447
1462
|
}
|
|
@@ -1454,6 +1469,12 @@
|
|
|
1454
1469
|
.bg-\[\#18181899\] {
|
|
1455
1470
|
background-color: #18181899;
|
|
1456
1471
|
}
|
|
1472
|
+
.bg-black\/60 {
|
|
1473
|
+
background-color: color-mix(in srgb, #000 60%, transparent);
|
|
1474
|
+
@supports (color: color-mix(in lab, red, red)) {
|
|
1475
|
+
background-color: color-mix(in oklab, var(--color-black) 60%, transparent);
|
|
1476
|
+
}
|
|
1477
|
+
}
|
|
1457
1478
|
.bg-blue-600 {
|
|
1458
1479
|
background-color: var(--color-blue-600);
|
|
1459
1480
|
}
|
|
@@ -1478,6 +1499,12 @@
|
|
|
1478
1499
|
background-color: color-mix(in oklab, var(--color-login-500) 50%, transparent);
|
|
1479
1500
|
}
|
|
1480
1501
|
}
|
|
1502
|
+
.bg-login-500\/60 {
|
|
1503
|
+
background-color: color-mix(in srgb, #323232 60%, transparent);
|
|
1504
|
+
@supports (color: color-mix(in lab, red, red)) {
|
|
1505
|
+
background-color: color-mix(in oklab, var(--color-login-500) 60%, transparent);
|
|
1506
|
+
}
|
|
1507
|
+
}
|
|
1481
1508
|
.bg-login-500\/70 {
|
|
1482
1509
|
background-color: color-mix(in srgb, #323232 70%, transparent);
|
|
1483
1510
|
@supports (color: color-mix(in lab, red, red)) {
|
|
@@ -1514,6 +1541,12 @@
|
|
|
1514
1541
|
background-color: color-mix(in oklab, var(--color-login) 70%, transparent);
|
|
1515
1542
|
}
|
|
1516
1543
|
}
|
|
1544
|
+
.bg-red-700\/80 {
|
|
1545
|
+
background-color: color-mix(in srgb, oklch(50.5% 0.213 27.518) 80%, transparent);
|
|
1546
|
+
@supports (color: color-mix(in lab, red, red)) {
|
|
1547
|
+
background-color: color-mix(in oklab, var(--color-red-700) 80%, transparent);
|
|
1548
|
+
}
|
|
1549
|
+
}
|
|
1517
1550
|
.bg-red-900 {
|
|
1518
1551
|
background-color: var(--color-red-900);
|
|
1519
1552
|
}
|
|
@@ -1523,6 +1556,12 @@
|
|
|
1523
1556
|
.bg-white {
|
|
1524
1557
|
background-color: var(--color-white);
|
|
1525
1558
|
}
|
|
1559
|
+
.bg-yellow-600\/80 {
|
|
1560
|
+
background-color: color-mix(in srgb, oklch(68.1% 0.162 75.834) 80%, transparent);
|
|
1561
|
+
@supports (color: color-mix(in lab, red, red)) {
|
|
1562
|
+
background-color: color-mix(in oklab, var(--color-yellow-600) 80%, transparent);
|
|
1563
|
+
}
|
|
1564
|
+
}
|
|
1526
1565
|
.bg-linear-to-r {
|
|
1527
1566
|
--tw-gradient-position: to right;
|
|
1528
1567
|
@supports (background-image: linear-gradient(in lab, red, red)) {
|
|
@@ -1576,6 +1615,12 @@
|
|
|
1576
1615
|
.stroke-login-50 {
|
|
1577
1616
|
stroke: var(--color-login-50);
|
|
1578
1617
|
}
|
|
1618
|
+
.stroke-red-400 {
|
|
1619
|
+
stroke: var(--color-red-400);
|
|
1620
|
+
}
|
|
1621
|
+
.stroke-yellow-400 {
|
|
1622
|
+
stroke: var(--color-yellow-400);
|
|
1623
|
+
}
|
|
1579
1624
|
.stroke-\[3\.5px\] {
|
|
1580
1625
|
stroke-width: 3.5px;
|
|
1581
1626
|
}
|
|
@@ -1597,6 +1642,9 @@
|
|
|
1597
1642
|
.p-4 {
|
|
1598
1643
|
padding: calc(var(--spacing) * 4);
|
|
1599
1644
|
}
|
|
1645
|
+
.p-6 {
|
|
1646
|
+
padding: calc(var(--spacing) * 6);
|
|
1647
|
+
}
|
|
1600
1648
|
.p-8 {
|
|
1601
1649
|
padding: calc(var(--spacing) * 8);
|
|
1602
1650
|
}
|
|
@@ -1718,6 +1766,14 @@
|
|
|
1718
1766
|
--tw-leading: calc(var(--spacing) * 8);
|
|
1719
1767
|
line-height: calc(var(--spacing) * 8);
|
|
1720
1768
|
}
|
|
1769
|
+
.leading-relaxed {
|
|
1770
|
+
--tw-leading: var(--leading-relaxed);
|
|
1771
|
+
line-height: var(--leading-relaxed);
|
|
1772
|
+
}
|
|
1773
|
+
.leading-snug {
|
|
1774
|
+
--tw-leading: var(--leading-snug);
|
|
1775
|
+
line-height: var(--leading-snug);
|
|
1776
|
+
}
|
|
1721
1777
|
.font-bold {
|
|
1722
1778
|
--tw-font-weight: var(--font-weight-bold);
|
|
1723
1779
|
font-weight: var(--font-weight-bold);
|
|
@@ -1757,6 +1813,12 @@
|
|
|
1757
1813
|
.text-login\! {
|
|
1758
1814
|
color: var(--color-login) !important;
|
|
1759
1815
|
}
|
|
1816
|
+
.text-login-50 {
|
|
1817
|
+
color: var(--color-login-50);
|
|
1818
|
+
}
|
|
1819
|
+
.text-login-100 {
|
|
1820
|
+
color: var(--color-login-100);
|
|
1821
|
+
}
|
|
1760
1822
|
.text-login-200 {
|
|
1761
1823
|
color: var(--color-login-200);
|
|
1762
1824
|
}
|
|
@@ -1807,6 +1869,10 @@
|
|
|
1807
1869
|
.opacity-100 {
|
|
1808
1870
|
opacity: 100%;
|
|
1809
1871
|
}
|
|
1872
|
+
.shadow-2xl {
|
|
1873
|
+
--tw-shadow: 0 25px 50px -12px var(--tw-shadow-color, rgb(0 0 0 / 0.25));
|
|
1874
|
+
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
|
|
1875
|
+
}
|
|
1810
1876
|
.shadow-\[0_0\.1rem_0\.5rem_rgba\(3\,3\,3\,0\.5\)\] {
|
|
1811
1877
|
--tw-shadow: 0 0.1rem 0.5rem var(--tw-shadow-color, rgba(3,3,3,0.5));
|
|
1812
1878
|
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
|
|
@@ -1846,6 +1912,23 @@
|
|
|
1846
1912
|
.outline-login-500 {
|
|
1847
1913
|
outline-color: var(--color-login-500);
|
|
1848
1914
|
}
|
|
1915
|
+
.outline-login-500\/60 {
|
|
1916
|
+
outline-color: color-mix(in srgb, #323232 60%, transparent);
|
|
1917
|
+
@supports (color: color-mix(in lab, red, red)) {
|
|
1918
|
+
outline-color: color-mix(in oklab, var(--color-login-500) 60%, transparent);
|
|
1919
|
+
}
|
|
1920
|
+
}
|
|
1921
|
+
.outline-red-700 {
|
|
1922
|
+
outline-color: var(--color-red-700);
|
|
1923
|
+
}
|
|
1924
|
+
.outline-yellow-600 {
|
|
1925
|
+
outline-color: var(--color-yellow-600);
|
|
1926
|
+
}
|
|
1927
|
+
.backdrop-blur-sm {
|
|
1928
|
+
--tw-backdrop-blur: blur(var(--blur-sm));
|
|
1929
|
+
-webkit-backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);
|
|
1930
|
+
backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);
|
|
1931
|
+
}
|
|
1849
1932
|
.backdrop-blur-xl {
|
|
1850
1933
|
--tw-backdrop-blur: blur(var(--blur-xl));
|
|
1851
1934
|
-webkit-backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);
|
|
@@ -2215,6 +2298,20 @@
|
|
|
2215
2298
|
}
|
|
2216
2299
|
}
|
|
2217
2300
|
}
|
|
2301
|
+
.hover\:bg-red-700 {
|
|
2302
|
+
&:hover {
|
|
2303
|
+
@media (hover: hover) {
|
|
2304
|
+
background-color: var(--color-red-700);
|
|
2305
|
+
}
|
|
2306
|
+
}
|
|
2307
|
+
}
|
|
2308
|
+
.hover\:bg-yellow-600 {
|
|
2309
|
+
&:hover {
|
|
2310
|
+
@media (hover: hover) {
|
|
2311
|
+
background-color: var(--color-yellow-600);
|
|
2312
|
+
}
|
|
2313
|
+
}
|
|
2314
|
+
}
|
|
2218
2315
|
.hover\:text-login-200 {
|
|
2219
2316
|
&:hover {
|
|
2220
2317
|
@media (hover: hover) {
|
package/package.json
CHANGED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import { TriangleAlert } from 'lucide-react'
|
|
4
|
+
|
|
5
|
+
type ConfirmPopupProps = {
|
|
6
|
+
isOpen: boolean
|
|
7
|
+
header: string
|
|
8
|
+
description?: string
|
|
9
|
+
confirmText?: string
|
|
10
|
+
cancelText?: string
|
|
11
|
+
onConfirm: () => void
|
|
12
|
+
onCancel: () => void
|
|
13
|
+
variant?: 'danger' | 'warning' | 'default'
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export default function ConfirmPopup({
|
|
17
|
+
isOpen,
|
|
18
|
+
header,
|
|
19
|
+
description,
|
|
20
|
+
confirmText = 'Confirm',
|
|
21
|
+
cancelText = 'Cancel',
|
|
22
|
+
onConfirm,
|
|
23
|
+
onCancel,
|
|
24
|
+
variant = 'default',
|
|
25
|
+
}: ConfirmPopupProps) {
|
|
26
|
+
if (!isOpen) return null
|
|
27
|
+
|
|
28
|
+
const confirmBg =
|
|
29
|
+
variant === 'danger'
|
|
30
|
+
? 'bg-red-700/80 outline-red-700 hover:bg-red-700'
|
|
31
|
+
: variant === 'warning'
|
|
32
|
+
? 'bg-yellow-600/80 outline-yellow-600 hover:bg-yellow-600'
|
|
33
|
+
: 'bg-login/70 outline-login hover:bg-login/90'
|
|
34
|
+
|
|
35
|
+
return (
|
|
36
|
+
<div
|
|
37
|
+
role='dialog'
|
|
38
|
+
aria-modal='true'
|
|
39
|
+
aria-labelledby='confirm-popup-header'
|
|
40
|
+
className='fixed inset-0 z-50 flex items-center justify-center'
|
|
41
|
+
onClick={onCancel}
|
|
42
|
+
>
|
|
43
|
+
<div className='absolute inset-0 bg-black/60 backdrop-blur-sm' />
|
|
44
|
+
|
|
45
|
+
<div
|
|
46
|
+
className='
|
|
47
|
+
relative z-10 w-full max-w-md mx-4
|
|
48
|
+
bg-login-800 border border-login-500/50 rounded-xl
|
|
49
|
+
shadow-2xl p-6 flex flex-col gap-4
|
|
50
|
+
'
|
|
51
|
+
onClick={(e) => e.stopPropagation()}
|
|
52
|
+
>
|
|
53
|
+
<div className='flex items-center gap-3'>
|
|
54
|
+
{variant !== 'default' && (
|
|
55
|
+
<TriangleAlert
|
|
56
|
+
className={`w-6 h-6 shrink-0 ${variant === 'danger' ? 'stroke-red-400' : 'stroke-yellow-400'}`}
|
|
57
|
+
/>
|
|
58
|
+
)}
|
|
59
|
+
<h2
|
|
60
|
+
id='confirm-popup-header'
|
|
61
|
+
className='text-login-50 text-lg font-bold leading-snug'
|
|
62
|
+
>
|
|
63
|
+
{header}
|
|
64
|
+
</h2>
|
|
65
|
+
</div>
|
|
66
|
+
|
|
67
|
+
{description && (
|
|
68
|
+
<p className='text-login-100 text-sm leading-relaxed'>
|
|
69
|
+
{description}
|
|
70
|
+
</p>
|
|
71
|
+
)}
|
|
72
|
+
|
|
73
|
+
<div className='flex justify-end gap-3 mt-1'>
|
|
74
|
+
<button
|
|
75
|
+
type='button'
|
|
76
|
+
onClick={onCancel}
|
|
77
|
+
className='
|
|
78
|
+
cursor-pointer px-4 py-1.5 rounded-md text-sm font-medium
|
|
79
|
+
bg-login-500/60 text-login-50 outline outline-login-500/60
|
|
80
|
+
hover:bg-login-500/90 focus:outline-none select-none
|
|
81
|
+
transition-colors duration-150
|
|
82
|
+
'
|
|
83
|
+
>
|
|
84
|
+
{cancelText}
|
|
85
|
+
</button>
|
|
86
|
+
|
|
87
|
+
<button
|
|
88
|
+
type='button'
|
|
89
|
+
onClick={onConfirm}
|
|
90
|
+
className={`
|
|
91
|
+
cursor-pointer px-4 py-1.5 rounded-md text-sm font-bold
|
|
92
|
+
text-white outline focus:outline-none select-none
|
|
93
|
+
transition-colors duration-150
|
|
94
|
+
${confirmBg}
|
|
95
|
+
`}
|
|
96
|
+
>
|
|
97
|
+
{confirmText}
|
|
98
|
+
</button>
|
|
99
|
+
</div>
|
|
100
|
+
</div>
|
|
101
|
+
</div>
|
|
102
|
+
)
|
|
103
|
+
}
|
package/src/components/index.ts
CHANGED
|
@@ -36,4 +36,7 @@ export { default as Toaster, toast } from './toast/toaster'
|
|
|
36
36
|
export { default as Button } from './buttons/button'
|
|
37
37
|
|
|
38
38
|
// Alert
|
|
39
|
-
export { default as Alert } from './alert/alert'
|
|
39
|
+
export { default as Alert } from './alert/alert'
|
|
40
|
+
|
|
41
|
+
// Confirm
|
|
42
|
+
export { default as ConfirmPopup } from './confirm/confirmPopup'
|
|
@@ -24,8 +24,9 @@ export type NavbarProps = {
|
|
|
24
24
|
theme?: string
|
|
25
25
|
disableThemeToggle?: boolean
|
|
26
26
|
token?: string | null
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
profilePath?: string
|
|
28
|
+
loginPath: string
|
|
29
|
+
logoutPath: string
|
|
29
30
|
className?: string
|
|
30
31
|
innerClassName?: string
|
|
31
32
|
children: React.ReactNode
|
|
@@ -37,8 +38,9 @@ export default function Navbar({
|
|
|
37
38
|
disableLanguageToggle,
|
|
38
39
|
disableThemeToggle,
|
|
39
40
|
token,
|
|
40
|
-
|
|
41
|
-
|
|
41
|
+
profilePath,
|
|
42
|
+
loginPath,
|
|
43
|
+
logoutPath,
|
|
42
44
|
className,
|
|
43
45
|
innerClassName,
|
|
44
46
|
children,
|
|
@@ -69,9 +71,22 @@ export default function Navbar({
|
|
|
69
71
|
|
|
70
72
|
{/* Controls */}
|
|
71
73
|
<nav className='flex w-[calc(100vw-8rem)] justify-end h-12 800px:w-fit'>
|
|
72
|
-
{!disableThemeToggle &&
|
|
73
|
-
|
|
74
|
-
|
|
74
|
+
{!disableThemeToggle &&
|
|
75
|
+
<ThemeToggle />
|
|
76
|
+
}
|
|
77
|
+
{!disableLanguageToggle &&
|
|
78
|
+
<LanguageToggle
|
|
79
|
+
language={lang}
|
|
80
|
+
/>
|
|
81
|
+
}
|
|
82
|
+
{!loginPath && !logoutPath &&
|
|
83
|
+
<AuthButton
|
|
84
|
+
profilePath={profilePath}
|
|
85
|
+
token={token}
|
|
86
|
+
loginPath={loginPath}
|
|
87
|
+
logoutPath={logoutPath}
|
|
88
|
+
/>
|
|
89
|
+
}
|
|
75
90
|
</nav>
|
|
76
91
|
|
|
77
92
|
{/* Mobile Menu Button */}
|
|
@@ -111,26 +126,35 @@ export default function Navbar({
|
|
|
111
126
|
)
|
|
112
127
|
}
|
|
113
128
|
|
|
114
|
-
|
|
129
|
+
type AuthButtonProps = {
|
|
130
|
+
profilePath?: string
|
|
131
|
+
logoutPath: string
|
|
132
|
+
loginPath: string
|
|
133
|
+
token?: string | null
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function AuthButton({ profilePath, logoutPath, loginPath, token }: AuthButtonProps) {
|
|
115
137
|
|
|
116
138
|
return (
|
|
117
139
|
<div className='rounded-[0.3rem] hover:bg-login-300/20 h-12 w-12'>
|
|
118
140
|
{token ? (
|
|
119
141
|
<>
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
e
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
142
|
+
{logoutPath &&
|
|
143
|
+
<Link
|
|
144
|
+
href={logoutPath}
|
|
145
|
+
prefetch={false}
|
|
146
|
+
onClick={(e) => {
|
|
147
|
+
e.preventDefault()
|
|
148
|
+
window.location.href = logoutPath
|
|
149
|
+
}}
|
|
150
|
+
className='grid items-center justify-center h-full w-full'
|
|
151
|
+
>
|
|
152
|
+
<LogOut size={24} />
|
|
153
|
+
</Link>
|
|
154
|
+
}
|
|
155
|
+
{profilePath &&
|
|
132
156
|
<Link
|
|
133
|
-
href={
|
|
157
|
+
href={profilePath}
|
|
134
158
|
className='grid items-center justify-center h-full w-full'
|
|
135
159
|
>
|
|
136
160
|
<User size={24} />
|
|
@@ -139,7 +163,7 @@ function AuthButton({ profileURL, token }: { profileURL?: string, token?: string
|
|
|
139
163
|
</>
|
|
140
164
|
) : (
|
|
141
165
|
<Link
|
|
142
|
-
href=
|
|
166
|
+
href={loginPath}
|
|
143
167
|
className='grid items-center justify-center h-full w-full'
|
|
144
168
|
>
|
|
145
169
|
<User size={24} />
|
|
@@ -45,4 +45,16 @@ declare module 'uibee/components' {
|
|
|
45
45
|
}
|
|
46
46
|
export default function LanguageToggle(props: { lang: Language }): JSX.Element;
|
|
47
47
|
export default function ThemeSwitch(props: { className?: string }): JSX.Element;
|
|
48
|
+
|
|
49
|
+
export interface ConfirmPopupProps {
|
|
50
|
+
isOpen: boolean
|
|
51
|
+
header: string
|
|
52
|
+
description?: string
|
|
53
|
+
confirmText?: string
|
|
54
|
+
cancelText?: string
|
|
55
|
+
onConfirm: () => void
|
|
56
|
+
onCancel: () => void
|
|
57
|
+
variant?: 'danger' | 'warning' | 'default'
|
|
58
|
+
}
|
|
59
|
+
export function ConfirmPopup(props: ConfirmPopupProps): JSX.Element | null;
|
|
48
60
|
}
|