@windrun-huaiin/third-ui 29.0.3 → 29.1.0
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/fuma/base/custom-header.js +6 -5
- package/dist/fuma/base/custom-header.mjs +6 -5
- package/dist/main/alert-dialog/confirm-dialog.d.ts +3 -1
- package/dist/main/alert-dialog/confirm-dialog.js +7 -2
- package/dist/main/alert-dialog/confirm-dialog.mjs +8 -3
- package/dist/main/alert-dialog/high-priority-confirm-dialog.d.ts +2 -1
- package/dist/main/alert-dialog/high-priority-confirm-dialog.js +5 -2
- package/dist/main/alert-dialog/high-priority-confirm-dialog.mjs +5 -2
- package/dist/main/alert-dialog/undoable-confirm-dialog.d.ts +3 -1
- package/dist/main/alert-dialog/undoable-confirm-dialog.js +9 -3
- package/dist/main/alert-dialog/undoable-confirm-dialog.mjs +9 -3
- package/dist/main/features.js +2 -2
- package/dist/main/features.mjs +1 -1
- package/dist/main/footer.js +1 -1
- package/dist/main/footer.mjs +1 -1
- package/dist/main/usage.js +2 -2
- package/dist/main/usage.mjs +1 -1
- package/package.json +4 -4
- package/src/fuma/base/custom-header.tsx +10 -4
- package/src/main/alert-dialog/confirm-dialog.tsx +12 -4
- package/src/main/alert-dialog/high-priority-confirm-dialog.tsx +7 -1
- package/src/main/alert-dialog/undoable-confirm-dialog.tsx +14 -5
- package/src/main/features.tsx +1 -1
- package/src/main/footer.tsx +2 -2
- package/src/main/usage.tsx +1 -1
|
@@ -16,6 +16,7 @@ var button = require('fumadocs-ui/components/ui/button');
|
|
|
16
16
|
var i18n = require('fumadocs-ui/contexts/i18n');
|
|
17
17
|
var headerThemeSwitch = require('./header-theme-switch.js');
|
|
18
18
|
|
|
19
|
+
const PrefetchLinkItem = shared.LinkItem;
|
|
19
20
|
const DEFAULT_DESKTOP_ACTIONS = [
|
|
20
21
|
'search',
|
|
21
22
|
'theme',
|
|
@@ -163,7 +164,7 @@ const navItemVariants = classVarianceAuthority.cva('[&_svg]:size-4', {
|
|
|
163
164
|
},
|
|
164
165
|
});
|
|
165
166
|
function NavbarLinkItem(_a) {
|
|
166
|
-
var _b;
|
|
167
|
+
var _b, _c;
|
|
167
168
|
var { item } = _a, props = tslib.__rest(_a, ["item"]);
|
|
168
169
|
if (item.type === 'custom')
|
|
169
170
|
return jsxRuntime.jsx("div", Object.assign({}, props, { children: item.children }));
|
|
@@ -179,11 +180,11 @@ function NavbarLinkItem(_a) {
|
|
|
179
180
|
});
|
|
180
181
|
return (jsxRuntime.jsxs(navigationMenu.NavigationMenuItem, { children: [jsxRuntime.jsx(navigationMenu.NavigationMenuTrigger, Object.assign({}, props, { className: utils.cn(navItemVariants(), 'rounded-md', props.className), children: item.url ? (jsxRuntime.jsx(Link, { href: item.url, prefetch: (_b = item.prefetch) !== null && _b !== void 0 ? _b : false, external: item.external, children: item.text })) : (item.text) })), jsxRuntime.jsx(navigationMenu.NavigationMenuContent, { className: "grid grid-cols-1 gap-2 p-4 md:grid-cols-2 lg:grid-cols-3", children: children })] }));
|
|
181
182
|
}
|
|
182
|
-
return (jsxRuntime.jsx(navigationMenu.NavigationMenuItem, { children: jsxRuntime.jsx(navigationMenu.NavigationMenuLink, { asChild: true, children: jsxRuntime.jsx(
|
|
183
|
+
return (jsxRuntime.jsx(navigationMenu.NavigationMenuItem, { children: jsxRuntime.jsx(navigationMenu.NavigationMenuLink, { asChild: true, children: jsxRuntime.jsx(PrefetchLinkItem, Object.assign({ item: item, prefetch: (_c = item.prefetch) !== null && _c !== void 0 ? _c : false, "aria-label": item.type === 'icon' ? item.label : undefined }, props, { className: utils.cn(navItemVariants({ variant: item.type }), props.className), children: item.type === 'icon' ? item.icon : item.text })) }) }));
|
|
183
184
|
}
|
|
184
185
|
const Menu = navigationMenu.NavigationMenuItem;
|
|
185
186
|
function MenuLinkItem(_a) {
|
|
186
|
-
var _b, _c;
|
|
187
|
+
var _b, _c, _d;
|
|
187
188
|
var { item } = _a, props = tslib.__rest(_a, ["item"]);
|
|
188
189
|
if (item.type === 'custom')
|
|
189
190
|
return jsxRuntime.jsx("div", { className: utils.cn('grid', props.className), children: item.children });
|
|
@@ -191,7 +192,7 @@ function MenuLinkItem(_a) {
|
|
|
191
192
|
const header = (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [item.icon, item.text] }));
|
|
192
193
|
return (jsxRuntime.jsxs("div", { className: utils.cn('mb-4 flex flex-col', props.className), children: [jsxRuntime.jsx("p", { className: "mb-1 text-sm text-fd-muted-foreground", children: item.url ? (jsxRuntime.jsx(navigationMenu.NavigationMenuLink, { asChild: true, children: jsxRuntime.jsx(Link, { href: item.url, prefetch: (_b = item.prefetch) !== null && _b !== void 0 ? _b : false, external: item.external, children: header }) })) : (header) }), item.items.map((child, i) => (jsxRuntime.jsx(MenuLinkItem, { item: child }, i)))] }));
|
|
193
194
|
}
|
|
194
|
-
return (jsxRuntime.jsx(navigationMenu.NavigationMenuLink, { asChild: true, children: jsxRuntime.jsxs(
|
|
195
|
+
return (jsxRuntime.jsx(navigationMenu.NavigationMenuLink, { asChild: true, children: jsxRuntime.jsxs(PrefetchLinkItem, { item: item, prefetch: (_c = item.prefetch) !== null && _c !== void 0 ? _c : false, className: utils.cn({
|
|
195
196
|
main: 'inline-flex items-center gap-2 py-1.5 transition-colors hover:text-fd-popover-foreground/50 data-[active=true]:font-medium data-[active=true]:text-fd-primary [&_svg]:size-4',
|
|
196
197
|
icon: button.buttonVariants({
|
|
197
198
|
size: 'icon',
|
|
@@ -201,7 +202,7 @@ function MenuLinkItem(_a) {
|
|
|
201
202
|
color: 'secondary',
|
|
202
203
|
className: 'gap-1.5 [&_svg]:size-4',
|
|
203
204
|
}),
|
|
204
|
-
}[(
|
|
205
|
+
}[(_d = item.type) !== null && _d !== void 0 ? _d : 'main'], props.className), "aria-label": item.type === 'icon' ? item.label : undefined, children: [item.icon, item.type === 'icon' ? undefined : item.text] }) }));
|
|
205
206
|
}
|
|
206
207
|
function MenuTrigger(_a) {
|
|
207
208
|
var { enableHover = false } = _a, props = tslib.__rest(_a, ["enableHover"]);
|
|
@@ -14,6 +14,7 @@ import { buttonVariants } from 'fumadocs-ui/components/ui/button';
|
|
|
14
14
|
import { useI18n } from 'fumadocs-ui/contexts/i18n';
|
|
15
15
|
import { HeaderThemeSwitch } from './header-theme-switch.mjs';
|
|
16
16
|
|
|
17
|
+
const PrefetchLinkItem = LinkItem;
|
|
17
18
|
const DEFAULT_DESKTOP_ACTIONS = [
|
|
18
19
|
'search',
|
|
19
20
|
'theme',
|
|
@@ -161,7 +162,7 @@ const navItemVariants = cva('[&_svg]:size-4', {
|
|
|
161
162
|
},
|
|
162
163
|
});
|
|
163
164
|
function NavbarLinkItem(_a) {
|
|
164
|
-
var _b;
|
|
165
|
+
var _b, _c;
|
|
165
166
|
var { item } = _a, props = __rest(_a, ["item"]);
|
|
166
167
|
if (item.type === 'custom')
|
|
167
168
|
return jsx("div", Object.assign({}, props, { children: item.children }));
|
|
@@ -177,11 +178,11 @@ function NavbarLinkItem(_a) {
|
|
|
177
178
|
});
|
|
178
179
|
return (jsxs(NavigationMenuItem, { children: [jsx(NavigationMenuTrigger, Object.assign({}, props, { className: cn(navItemVariants(), 'rounded-md', props.className), children: item.url ? (jsx(Link, { href: item.url, prefetch: (_b = item.prefetch) !== null && _b !== void 0 ? _b : false, external: item.external, children: item.text })) : (item.text) })), jsx(NavigationMenuContent, { className: "grid grid-cols-1 gap-2 p-4 md:grid-cols-2 lg:grid-cols-3", children: children })] }));
|
|
179
180
|
}
|
|
180
|
-
return (jsx(NavigationMenuItem, { children: jsx(NavigationMenuLink, { asChild: true, children: jsx(
|
|
181
|
+
return (jsx(NavigationMenuItem, { children: jsx(NavigationMenuLink, { asChild: true, children: jsx(PrefetchLinkItem, Object.assign({ item: item, prefetch: (_c = item.prefetch) !== null && _c !== void 0 ? _c : false, "aria-label": item.type === 'icon' ? item.label : undefined }, props, { className: cn(navItemVariants({ variant: item.type }), props.className), children: item.type === 'icon' ? item.icon : item.text })) }) }));
|
|
181
182
|
}
|
|
182
183
|
const Menu = NavigationMenuItem;
|
|
183
184
|
function MenuLinkItem(_a) {
|
|
184
|
-
var _b, _c;
|
|
185
|
+
var _b, _c, _d;
|
|
185
186
|
var { item } = _a, props = __rest(_a, ["item"]);
|
|
186
187
|
if (item.type === 'custom')
|
|
187
188
|
return jsx("div", { className: cn('grid', props.className), children: item.children });
|
|
@@ -189,7 +190,7 @@ function MenuLinkItem(_a) {
|
|
|
189
190
|
const header = (jsxs(Fragment, { children: [item.icon, item.text] }));
|
|
190
191
|
return (jsxs("div", { className: cn('mb-4 flex flex-col', props.className), children: [jsx("p", { className: "mb-1 text-sm text-fd-muted-foreground", children: item.url ? (jsx(NavigationMenuLink, { asChild: true, children: jsx(Link, { href: item.url, prefetch: (_b = item.prefetch) !== null && _b !== void 0 ? _b : false, external: item.external, children: header }) })) : (header) }), item.items.map((child, i) => (jsx(MenuLinkItem, { item: child }, i)))] }));
|
|
191
192
|
}
|
|
192
|
-
return (jsx(NavigationMenuLink, { asChild: true, children: jsxs(
|
|
193
|
+
return (jsx(NavigationMenuLink, { asChild: true, children: jsxs(PrefetchLinkItem, { item: item, prefetch: (_c = item.prefetch) !== null && _c !== void 0 ? _c : false, className: cn({
|
|
193
194
|
main: 'inline-flex items-center gap-2 py-1.5 transition-colors hover:text-fd-popover-foreground/50 data-[active=true]:font-medium data-[active=true]:text-fd-primary [&_svg]:size-4',
|
|
194
195
|
icon: buttonVariants({
|
|
195
196
|
size: 'icon',
|
|
@@ -199,7 +200,7 @@ function MenuLinkItem(_a) {
|
|
|
199
200
|
color: 'secondary',
|
|
200
201
|
className: 'gap-1.5 [&_svg]:size-4',
|
|
201
202
|
}),
|
|
202
|
-
}[(
|
|
203
|
+
}[(_d = item.type) !== null && _d !== void 0 ? _d : 'main'], props.className), "aria-label": item.type === 'icon' ? item.label : undefined, children: [item.icon, item.type === 'icon' ? undefined : item.text] }) }));
|
|
203
204
|
}
|
|
204
205
|
function MenuTrigger(_a) {
|
|
205
206
|
var { enableHover = false } = _a, props = __rest(_a, ["enableHover"]);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
export type ConfirmDialogType = 'normal' | 'danger';
|
|
3
|
+
export type ConfirmDialogEmphasis = 'confirm' | 'cancel';
|
|
3
4
|
interface ConfirmDialogProps {
|
|
4
5
|
open: boolean;
|
|
5
6
|
onOpenChange: (open: boolean) => void;
|
|
@@ -8,8 +9,9 @@ interface ConfirmDialogProps {
|
|
|
8
9
|
description: React.ReactNode;
|
|
9
10
|
cancelText?: string;
|
|
10
11
|
confirmText?: string;
|
|
12
|
+
emphasis?: ConfirmDialogEmphasis;
|
|
11
13
|
onCancel?: () => void;
|
|
12
14
|
onConfirm?: () => void;
|
|
13
15
|
}
|
|
14
|
-
export declare function ConfirmDialog({ open, onOpenChange, type, title, description, cancelText, confirmText, onCancel, onConfirm, }: ConfirmDialogProps): import("react/jsx-runtime").JSX.Element;
|
|
16
|
+
export declare function ConfirmDialog({ open, onOpenChange, type, title, description, cancelText, confirmText, emphasis, onCancel, onConfirm, }: ConfirmDialogProps): import("react/jsx-runtime").JSX.Element;
|
|
15
17
|
export {};
|
|
@@ -24,14 +24,19 @@ const confirmTypeClassMap = {
|
|
|
24
24
|
Icon: icons.CircleAlertIcon,
|
|
25
25
|
},
|
|
26
26
|
};
|
|
27
|
-
function ConfirmDialog({ open, onOpenChange, type = 'normal', title, description, cancelText = 'Cancel', confirmText = 'Confirm', onCancel, onConfirm, }) {
|
|
27
|
+
function ConfirmDialog({ open, onOpenChange, type = 'normal', title, description, cancelText = 'Cancel', confirmText = 'Confirm', emphasis = 'confirm', onCancel, onConfirm, }) {
|
|
28
28
|
const typeClass = confirmTypeClassMap[type];
|
|
29
29
|
const Icon = typeClass.Icon;
|
|
30
|
+
const cancelButtonClass = emphasis === 'cancel' ? typeClass.action : dialogStyles.secondaryButtonClass;
|
|
31
|
+
const confirmButtonClass = emphasis === 'cancel' ? dialogStyles.secondaryButtonClass : typeClass.action;
|
|
30
32
|
const handleCancel = () => {
|
|
31
33
|
onOpenChange(false);
|
|
32
34
|
onCancel === null || onCancel === void 0 ? void 0 : onCancel();
|
|
33
35
|
};
|
|
34
|
-
|
|
36
|
+
const handleClose = () => {
|
|
37
|
+
onOpenChange(false);
|
|
38
|
+
};
|
|
39
|
+
return (jsxRuntime.jsx(ui.AlertDialog, { open: open, onOpenChange: onOpenChange, children: jsxRuntime.jsxs(ui.AlertDialogContent, { className: utils.cn(dialogStyles.dialogContentClass, typeClass.content), overlayClassName: dialogStyles.dialogThemedOverlayClass, onOverlayClick: handleClose, children: [jsxRuntime.jsxs("div", { className: dialogStyles.dialogHeaderClass, children: [jsxRuntime.jsx(ui.AlertDialogTitle, { asChild: true, children: jsxRuntime.jsxs("div", { className: dialogStyles.dialogTitleClass, children: [jsxRuntime.jsx("span", { className: utils.cn('inline-flex size-9 shrink-0 items-center justify-center rounded-full ring-1', typeClass.iconWrap), children: jsxRuntime.jsx(Icon, { className: utils.cn('size-5', typeClass.icon) }) }), jsxRuntime.jsx("span", { className: "min-w-0 truncate", children: title })] }) }), jsxRuntime.jsx("button", { type: "button", className: dialogStyles.closeButtonClass, onClick: handleClose, "aria-label": "Close", children: jsxRuntime.jsx(icons.XIcon, { className: "size-4" }) })] }), jsxRuntime.jsx(ui.AlertDialogDescription, { className: dialogStyles.dialogDescriptionClass, children: description }), jsxRuntime.jsxs("div", { className: dialogStyles.dialogFooterClass, children: [jsxRuntime.jsx(ui.AlertDialogCancel, { className: cancelButtonClass, onClick: handleCancel, children: cancelText }), jsxRuntime.jsx(ui.AlertDialogAction, { className: confirmButtonClass, onClick: () => {
|
|
35
40
|
onOpenChange(false);
|
|
36
41
|
onConfirm === null || onConfirm === void 0 ? void 0 : onConfirm();
|
|
37
42
|
}, children: confirmText })] })] }) }));
|
|
@@ -4,7 +4,7 @@ import { CircleAlertIcon, CircleQuestionMarkIcon, XIcon } from '@windrun-huaiin/
|
|
|
4
4
|
import { themeBgColor, themeIconColor } from '@windrun-huaiin/base-ui/lib';
|
|
5
5
|
import { AlertDialog, AlertDialogContent, AlertDialogTitle, AlertDialogDescription, AlertDialogCancel, AlertDialogAction } from '@windrun-huaiin/base-ui/ui';
|
|
6
6
|
import { cn } from '@windrun-huaiin/lib/utils';
|
|
7
|
-
import { dangerButtonClass, primaryButtonClass, dialogThemedOverlayClass, dialogHeaderClass, dialogTitleClass, closeButtonClass, dialogDescriptionClass, dialogFooterClass,
|
|
7
|
+
import { dangerButtonClass, primaryButtonClass, secondaryButtonClass, dialogThemedOverlayClass, dialogHeaderClass, dialogTitleClass, closeButtonClass, dialogDescriptionClass, dialogFooterClass, dialogContentClass } from './dialog-styles.mjs';
|
|
8
8
|
|
|
9
9
|
const confirmTypeClassMap = {
|
|
10
10
|
normal: {
|
|
@@ -22,14 +22,19 @@ const confirmTypeClassMap = {
|
|
|
22
22
|
Icon: CircleAlertIcon,
|
|
23
23
|
},
|
|
24
24
|
};
|
|
25
|
-
function ConfirmDialog({ open, onOpenChange, type = 'normal', title, description, cancelText = 'Cancel', confirmText = 'Confirm', onCancel, onConfirm, }) {
|
|
25
|
+
function ConfirmDialog({ open, onOpenChange, type = 'normal', title, description, cancelText = 'Cancel', confirmText = 'Confirm', emphasis = 'confirm', onCancel, onConfirm, }) {
|
|
26
26
|
const typeClass = confirmTypeClassMap[type];
|
|
27
27
|
const Icon = typeClass.Icon;
|
|
28
|
+
const cancelButtonClass = emphasis === 'cancel' ? typeClass.action : secondaryButtonClass;
|
|
29
|
+
const confirmButtonClass = emphasis === 'cancel' ? secondaryButtonClass : typeClass.action;
|
|
28
30
|
const handleCancel = () => {
|
|
29
31
|
onOpenChange(false);
|
|
30
32
|
onCancel === null || onCancel === void 0 ? void 0 : onCancel();
|
|
31
33
|
};
|
|
32
|
-
|
|
34
|
+
const handleClose = () => {
|
|
35
|
+
onOpenChange(false);
|
|
36
|
+
};
|
|
37
|
+
return (jsx(AlertDialog, { open: open, onOpenChange: onOpenChange, children: jsxs(AlertDialogContent, { className: cn(dialogContentClass, typeClass.content), overlayClassName: dialogThemedOverlayClass, onOverlayClick: handleClose, children: [jsxs("div", { className: dialogHeaderClass, children: [jsx(AlertDialogTitle, { asChild: true, children: jsxs("div", { className: dialogTitleClass, children: [jsx("span", { className: cn('inline-flex size-9 shrink-0 items-center justify-center rounded-full ring-1', typeClass.iconWrap), children: jsx(Icon, { className: cn('size-5', typeClass.icon) }) }), jsx("span", { className: "min-w-0 truncate", children: title })] }) }), jsx("button", { type: "button", className: closeButtonClass, onClick: handleClose, "aria-label": "Close", children: jsx(XIcon, { className: "size-4" }) })] }), jsx(AlertDialogDescription, { className: dialogDescriptionClass, children: description }), jsxs("div", { className: dialogFooterClass, children: [jsx(AlertDialogCancel, { className: cancelButtonClass, onClick: handleCancel, children: cancelText }), jsx(AlertDialogAction, { className: confirmButtonClass, onClick: () => {
|
|
33
38
|
onOpenChange(false);
|
|
34
39
|
onConfirm === null || onConfirm === void 0 ? void 0 : onConfirm();
|
|
35
40
|
}, children: confirmText })] })] }) }));
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
interface HighPriorityConfirmDialogProps {
|
|
3
3
|
open: boolean;
|
|
4
|
+
onOpenChange: (open: boolean) => void;
|
|
4
5
|
onCancel: () => void;
|
|
5
6
|
onConfirm: () => void;
|
|
6
7
|
title: string;
|
|
@@ -8,5 +9,5 @@ interface HighPriorityConfirmDialogProps {
|
|
|
8
9
|
confirmText?: string;
|
|
9
10
|
cancelText?: string;
|
|
10
11
|
}
|
|
11
|
-
export declare function HighPriorityConfirmDialog({ open, onCancel, onConfirm, title, description, confirmText, cancelText, }: HighPriorityConfirmDialogProps): React.ReactPortal | null;
|
|
12
|
+
export declare function HighPriorityConfirmDialog({ open, onOpenChange, onCancel, onConfirm, title, description, confirmText, cancelText, }: HighPriorityConfirmDialogProps): React.ReactPortal | null;
|
|
12
13
|
export {};
|
|
@@ -9,7 +9,7 @@ var utils = require('@windrun-huaiin/lib/utils');
|
|
|
9
9
|
var dialogStyles = require('./dialog-styles.js');
|
|
10
10
|
var lib = require('@windrun-huaiin/base-ui/lib');
|
|
11
11
|
|
|
12
|
-
function HighPriorityConfirmDialog({ open, onCancel, onConfirm, title, description, confirmText = "Confirm", cancelText = "Cancel", }) {
|
|
12
|
+
function HighPriorityConfirmDialog({ open, onOpenChange, onCancel, onConfirm, title, description, confirmText = "Confirm", cancelText = "Cancel", }) {
|
|
13
13
|
const [mounted, setMounted] = React.useState(false);
|
|
14
14
|
React.useEffect(() => {
|
|
15
15
|
// Ensure portal target exists and prevent hydration mismatch
|
|
@@ -17,7 +17,10 @@ function HighPriorityConfirmDialog({ open, onCancel, onConfirm, title, descripti
|
|
|
17
17
|
}, []);
|
|
18
18
|
if (!open || !mounted)
|
|
19
19
|
return null;
|
|
20
|
-
|
|
20
|
+
const handleClose = () => {
|
|
21
|
+
onOpenChange(false);
|
|
22
|
+
};
|
|
23
|
+
return reactDom.createPortal(jsxRuntime.jsx("div", { className: "fixed inset-0 z-10000 flex items-center justify-center bg-black/60 backdrop-blur-sm animate-in fade-in duration-300", children: jsxRuntime.jsxs("div", { className: utils.cn(dialogStyles.highPrioritySurfaceClass, "scale-100"), role: "dialog", "aria-modal": "true", onClick: (e) => e.stopPropagation(), children: [jsxRuntime.jsxs("div", { className: dialogStyles.dialogHeaderClass, children: [jsxRuntime.jsxs("h3", { className: dialogStyles.highPriorityTitleClass, children: [jsxRuntime.jsx("span", { className: utils.cn('inline-flex size-9 shrink-0 items-center justify-center rounded-full ring-1', lib.themeBgColor, lib.themeBorderColor), children: jsxRuntime.jsx(icons.FAQSIcon, { className: utils.cn('size-5', lib.themeIconColor) }) }), jsxRuntime.jsx("span", { className: "min-w-0 truncate", children: title })] }), jsxRuntime.jsx("button", { type: "button", className: dialogStyles.closeButtonClass, onClick: handleClose, "aria-label": "Close", children: jsxRuntime.jsx(icons.XIcon, { className: "size-4" }) })] }), jsxRuntime.jsx("div", { className: dialogStyles.dialogDescriptionClass, children: description }), jsxRuntime.jsxs("div", { className: dialogStyles.dialogFooterClass, children: [jsxRuntime.jsx("button", { type: "button", onClick: onCancel, className: dialogStyles.secondaryButtonClass, children: cancelText }), jsxRuntime.jsx("button", { type: "button", onClick: onConfirm, className: utils.cn(dialogStyles.primaryButtonClass, "hover:scale-105 active:scale-95"), children: confirmText })] })] }) }), document.body);
|
|
21
24
|
}
|
|
22
25
|
|
|
23
26
|
exports.HighPriorityConfirmDialog = HighPriorityConfirmDialog;
|
|
@@ -7,7 +7,7 @@ import { cn } from '@windrun-huaiin/lib/utils';
|
|
|
7
7
|
import { dialogHeaderClass, highPriorityTitleClass, closeButtonClass, dialogDescriptionClass, dialogFooterClass, secondaryButtonClass, primaryButtonClass, highPrioritySurfaceClass } from './dialog-styles.mjs';
|
|
8
8
|
import { themeIconColor, themeBgColor, themeBorderColor } from '@windrun-huaiin/base-ui/lib';
|
|
9
9
|
|
|
10
|
-
function HighPriorityConfirmDialog({ open, onCancel, onConfirm, title, description, confirmText = "Confirm", cancelText = "Cancel", }) {
|
|
10
|
+
function HighPriorityConfirmDialog({ open, onOpenChange, onCancel, onConfirm, title, description, confirmText = "Confirm", cancelText = "Cancel", }) {
|
|
11
11
|
const [mounted, setMounted] = useState(false);
|
|
12
12
|
useEffect(() => {
|
|
13
13
|
// Ensure portal target exists and prevent hydration mismatch
|
|
@@ -15,7 +15,10 @@ function HighPriorityConfirmDialog({ open, onCancel, onConfirm, title, descripti
|
|
|
15
15
|
}, []);
|
|
16
16
|
if (!open || !mounted)
|
|
17
17
|
return null;
|
|
18
|
-
|
|
18
|
+
const handleClose = () => {
|
|
19
|
+
onOpenChange(false);
|
|
20
|
+
};
|
|
21
|
+
return createPortal(jsx("div", { className: "fixed inset-0 z-10000 flex items-center justify-center bg-black/60 backdrop-blur-sm animate-in fade-in duration-300", children: jsxs("div", { className: cn(highPrioritySurfaceClass, "scale-100"), role: "dialog", "aria-modal": "true", onClick: (e) => e.stopPropagation(), children: [jsxs("div", { className: dialogHeaderClass, children: [jsxs("h3", { className: highPriorityTitleClass, children: [jsx("span", { className: cn('inline-flex size-9 shrink-0 items-center justify-center rounded-full ring-1', themeBgColor, themeBorderColor), children: jsx(FAQSIcon, { className: cn('size-5', themeIconColor) }) }), jsx("span", { className: "min-w-0 truncate", children: title })] }), jsx("button", { type: "button", className: closeButtonClass, onClick: handleClose, "aria-label": "Close", children: jsx(XIcon, { className: "size-4" }) })] }), jsx("div", { className: dialogDescriptionClass, children: description }), jsxs("div", { className: dialogFooterClass, children: [jsx("button", { type: "button", onClick: onCancel, className: secondaryButtonClass, children: cancelText }), jsx("button", { type: "button", onClick: onConfirm, className: cn(primaryButtonClass, "hover:scale-105 active:scale-95"), children: confirmText })] })] }) }), document.body);
|
|
19
22
|
}
|
|
20
23
|
|
|
21
24
|
export { HighPriorityConfirmDialog };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import type { ConfirmDialogEmphasis } from './confirm-dialog';
|
|
2
3
|
export interface UndoableConfirmDialogProps {
|
|
3
4
|
open: boolean;
|
|
4
5
|
onOpenChange: (open: boolean) => void;
|
|
@@ -9,9 +10,10 @@ export interface UndoableConfirmDialogProps {
|
|
|
9
10
|
cancelText?: string;
|
|
10
11
|
confirmText?: string;
|
|
11
12
|
undoText?: string;
|
|
13
|
+
emphasis?: ConfirmDialogEmphasis;
|
|
12
14
|
countdownSeconds?: number;
|
|
13
15
|
onCancel?: () => void;
|
|
14
16
|
onConfirm: () => void | Promise<void>;
|
|
15
17
|
onUndo?: () => void;
|
|
16
18
|
}
|
|
17
|
-
export declare function UndoableConfirmDialog({ open, onOpenChange, title, description, pendingTitle, pendingDescription, cancelText, confirmText, undoText, countdownSeconds, onCancel, onConfirm, onUndo, }: UndoableConfirmDialogProps): import("react/jsx-runtime").JSX.Element;
|
|
19
|
+
export declare function UndoableConfirmDialog({ open, onOpenChange, title, description, pendingTitle, pendingDescription, cancelText, confirmText, undoText, emphasis, countdownSeconds, onCancel, onConfirm, onUndo, }: UndoableConfirmDialogProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -10,13 +10,15 @@ var ui = require('@windrun-huaiin/base-ui/ui');
|
|
|
10
10
|
var utils = require('@windrun-huaiin/lib/utils');
|
|
11
11
|
var dialogStyles = require('./dialog-styles.js');
|
|
12
12
|
|
|
13
|
-
function UndoableConfirmDialog({ open, onOpenChange, title, description, pendingTitle, pendingDescription, cancelText = 'Cancel', confirmText = 'Delete', undoText = 'Undo', countdownSeconds = 5, onCancel, onConfirm, onUndo, }) {
|
|
13
|
+
function UndoableConfirmDialog({ open, onOpenChange, title, description, pendingTitle, pendingDescription, cancelText = 'Cancel', confirmText = 'Delete', undoText = 'Undo', emphasis = 'confirm', countdownSeconds = 5, onCancel, onConfirm, onUndo, }) {
|
|
14
14
|
const safeCountdownSeconds = Math.max(1, Math.floor(countdownSeconds));
|
|
15
15
|
const [pending, setPending] = React.useState(false);
|
|
16
16
|
const [remainingSeconds, setRemainingSeconds] = React.useState(safeCountdownSeconds);
|
|
17
17
|
const [confirming, setConfirming] = React.useState(false);
|
|
18
18
|
const timeoutRef = React.useRef(null);
|
|
19
19
|
const intervalRef = React.useRef(null);
|
|
20
|
+
const cancelButtonClass = emphasis === 'cancel' ? dialogStyles.dangerButtonClass : dialogStyles.secondaryButtonClass;
|
|
21
|
+
const confirmButtonClass = emphasis === 'cancel' ? dialogStyles.secondaryButtonClass : dialogStyles.dangerButtonClass;
|
|
20
22
|
const clearTimers = React.useCallback(() => {
|
|
21
23
|
if (timeoutRef.current) {
|
|
22
24
|
window.clearTimeout(timeoutRef.current);
|
|
@@ -68,6 +70,10 @@ function UndoableConfirmDialog({ open, onOpenChange, title, description, pending
|
|
|
68
70
|
onOpenChange(false);
|
|
69
71
|
onCancel === null || onCancel === void 0 ? void 0 : onCancel();
|
|
70
72
|
};
|
|
73
|
+
const handleClose = React.useCallback(() => {
|
|
74
|
+
resetState();
|
|
75
|
+
onOpenChange(false);
|
|
76
|
+
}, [onOpenChange, resetState]);
|
|
71
77
|
const handleUndo = () => {
|
|
72
78
|
resetState();
|
|
73
79
|
onOpenChange(false);
|
|
@@ -77,11 +83,11 @@ function UndoableConfirmDialog({ open, onOpenChange, title, description, pending
|
|
|
77
83
|
const displayDescription = pending ? pendingDescription !== null && pendingDescription !== void 0 ? pendingDescription : description : description;
|
|
78
84
|
return (jsxRuntime.jsx(ui.AlertDialog, { open: open, onOpenChange: (nextOpen) => {
|
|
79
85
|
if (!nextOpen) {
|
|
80
|
-
|
|
86
|
+
handleClose();
|
|
81
87
|
return;
|
|
82
88
|
}
|
|
83
89
|
onOpenChange(nextOpen);
|
|
84
|
-
}, children: jsxRuntime.jsxs(ui.AlertDialogContent, { className: utils.cn(dialogStyles.dialogContentClass, 'border-red-300 dark:border-red-700'), overlayClassName: dialogStyles.dialogThemedOverlayClass, onOverlayClick: pending ? undefined :
|
|
90
|
+
}, children: jsxRuntime.jsxs(ui.AlertDialogContent, { className: utils.cn(dialogStyles.dialogContentClass, 'border-red-300 dark:border-red-700'), overlayClassName: dialogStyles.dialogThemedOverlayClass, onOverlayClick: pending ? undefined : handleClose, children: [jsxRuntime.jsxs("div", { className: dialogStyles.dialogHeaderClass, children: [jsxRuntime.jsx(ui.AlertDialogTitle, { asChild: true, children: jsxRuntime.jsxs("div", { className: dialogStyles.dialogTitleClass, children: [jsxRuntime.jsx("span", { className: "inline-flex size-9 shrink-0 items-center justify-center rounded-full bg-red-100 text-red-600 ring-1 ring-red-200 dark:bg-red-950 dark:text-red-300 dark:ring-red-900", children: pending ? jsxRuntime.jsx(icons.Trash2Icon, { className: "size-5" }) : jsxRuntime.jsx(icons.CircleAlertIcon, { className: "size-5" }) }), jsxRuntime.jsx("span", { className: "min-w-0 truncate", children: displayTitle })] }) }), jsxRuntime.jsx("button", { type: "button", className: dialogStyles.closeButtonClass, onClick: handleClose, "aria-label": "Close", disabled: confirming, children: jsxRuntime.jsx(icons.XIcon, { className: "size-4" }) })] }), jsxRuntime.jsx(ui.AlertDialogDescription, { className: utils.cn(dialogStyles.dialogDescriptionClass, 'min-h-[44px]'), children: jsxRuntime.jsx("span", { children: displayDescription }) }), jsxRuntime.jsx("div", { className: "flex h-12 items-center justify-center py-1", children: jsxRuntime.jsxs("div", { className: "flex items-baseline justify-center gap-2", children: [jsxRuntime.jsx("span", { className: utils.cn('text-4xl font-black leading-none tabular-nums', pending && 'animate-bounce', lib.themeIconColor), children: pending ? remainingSeconds : safeCountdownSeconds }), jsxRuntime.jsx("span", { className: utils.cn('text-sm font-bold', lib.themeIconColor), children: "s" })] }) }), jsxRuntime.jsx("div", { className: utils.cn(dialogStyles.dialogFooterClass, 'min-h-[88px] sm:min-h-10 sm:items-center'), children: pending ? (jsxRuntime.jsxs("button", { type: "button", onClick: handleUndo, className: dialogStyles.secondaryButtonClass, disabled: confirming, children: [jsxRuntime.jsx(icons.Undo2Icon, { className: "mr-1.5 size-4" }), undoText] })) : (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("button", { type: "button", onClick: handleCancel, className: cancelButtonClass, children: cancelText }), jsxRuntime.jsx("button", { type: "button", onClick: startCountdown, className: confirmButtonClass, children: confirmText })] })) })] }) }));
|
|
85
91
|
}
|
|
86
92
|
|
|
87
93
|
exports.UndoableConfirmDialog = UndoableConfirmDialog;
|
|
@@ -8,13 +8,15 @@ import { AlertDialog, AlertDialogContent, AlertDialogTitle, AlertDialogDescripti
|
|
|
8
8
|
import { cn } from '@windrun-huaiin/lib/utils';
|
|
9
9
|
import { dialogThemedOverlayClass, dialogHeaderClass, dialogTitleClass, closeButtonClass, dialogDescriptionClass, secondaryButtonClass, dangerButtonClass, dialogFooterClass, dialogContentClass } from './dialog-styles.mjs';
|
|
10
10
|
|
|
11
|
-
function UndoableConfirmDialog({ open, onOpenChange, title, description, pendingTitle, pendingDescription, cancelText = 'Cancel', confirmText = 'Delete', undoText = 'Undo', countdownSeconds = 5, onCancel, onConfirm, onUndo, }) {
|
|
11
|
+
function UndoableConfirmDialog({ open, onOpenChange, title, description, pendingTitle, pendingDescription, cancelText = 'Cancel', confirmText = 'Delete', undoText = 'Undo', emphasis = 'confirm', countdownSeconds = 5, onCancel, onConfirm, onUndo, }) {
|
|
12
12
|
const safeCountdownSeconds = Math.max(1, Math.floor(countdownSeconds));
|
|
13
13
|
const [pending, setPending] = React__default.useState(false);
|
|
14
14
|
const [remainingSeconds, setRemainingSeconds] = React__default.useState(safeCountdownSeconds);
|
|
15
15
|
const [confirming, setConfirming] = React__default.useState(false);
|
|
16
16
|
const timeoutRef = React__default.useRef(null);
|
|
17
17
|
const intervalRef = React__default.useRef(null);
|
|
18
|
+
const cancelButtonClass = emphasis === 'cancel' ? dangerButtonClass : secondaryButtonClass;
|
|
19
|
+
const confirmButtonClass = emphasis === 'cancel' ? secondaryButtonClass : dangerButtonClass;
|
|
18
20
|
const clearTimers = React__default.useCallback(() => {
|
|
19
21
|
if (timeoutRef.current) {
|
|
20
22
|
window.clearTimeout(timeoutRef.current);
|
|
@@ -66,6 +68,10 @@ function UndoableConfirmDialog({ open, onOpenChange, title, description, pending
|
|
|
66
68
|
onOpenChange(false);
|
|
67
69
|
onCancel === null || onCancel === void 0 ? void 0 : onCancel();
|
|
68
70
|
};
|
|
71
|
+
const handleClose = React__default.useCallback(() => {
|
|
72
|
+
resetState();
|
|
73
|
+
onOpenChange(false);
|
|
74
|
+
}, [onOpenChange, resetState]);
|
|
69
75
|
const handleUndo = () => {
|
|
70
76
|
resetState();
|
|
71
77
|
onOpenChange(false);
|
|
@@ -75,11 +81,11 @@ function UndoableConfirmDialog({ open, onOpenChange, title, description, pending
|
|
|
75
81
|
const displayDescription = pending ? pendingDescription !== null && pendingDescription !== void 0 ? pendingDescription : description : description;
|
|
76
82
|
return (jsx(AlertDialog, { open: open, onOpenChange: (nextOpen) => {
|
|
77
83
|
if (!nextOpen) {
|
|
78
|
-
|
|
84
|
+
handleClose();
|
|
79
85
|
return;
|
|
80
86
|
}
|
|
81
87
|
onOpenChange(nextOpen);
|
|
82
|
-
}, children: jsxs(AlertDialogContent, { className: cn(dialogContentClass, 'border-red-300 dark:border-red-700'), overlayClassName: dialogThemedOverlayClass, onOverlayClick: pending ? undefined :
|
|
88
|
+
}, children: jsxs(AlertDialogContent, { className: cn(dialogContentClass, 'border-red-300 dark:border-red-700'), overlayClassName: dialogThemedOverlayClass, onOverlayClick: pending ? undefined : handleClose, children: [jsxs("div", { className: dialogHeaderClass, children: [jsx(AlertDialogTitle, { asChild: true, children: jsxs("div", { className: dialogTitleClass, children: [jsx("span", { className: "inline-flex size-9 shrink-0 items-center justify-center rounded-full bg-red-100 text-red-600 ring-1 ring-red-200 dark:bg-red-950 dark:text-red-300 dark:ring-red-900", children: pending ? jsx(Trash2Icon, { className: "size-5" }) : jsx(CircleAlertIcon, { className: "size-5" }) }), jsx("span", { className: "min-w-0 truncate", children: displayTitle })] }) }), jsx("button", { type: "button", className: closeButtonClass, onClick: handleClose, "aria-label": "Close", disabled: confirming, children: jsx(XIcon, { className: "size-4" }) })] }), jsx(AlertDialogDescription, { className: cn(dialogDescriptionClass, 'min-h-[44px]'), children: jsx("span", { children: displayDescription }) }), jsx("div", { className: "flex h-12 items-center justify-center py-1", children: jsxs("div", { className: "flex items-baseline justify-center gap-2", children: [jsx("span", { className: cn('text-4xl font-black leading-none tabular-nums', pending && 'animate-bounce', themeIconColor), children: pending ? remainingSeconds : safeCountdownSeconds }), jsx("span", { className: cn('text-sm font-bold', themeIconColor), children: "s" })] }) }), jsx("div", { className: cn(dialogFooterClass, 'min-h-[88px] sm:min-h-10 sm:items-center'), children: pending ? (jsxs("button", { type: "button", onClick: handleUndo, className: secondaryButtonClass, disabled: confirming, children: [jsx(Undo2Icon, { className: "mr-1.5 size-4" }), undoText] })) : (jsxs(Fragment, { children: [jsx("button", { type: "button", onClick: handleCancel, className: cancelButtonClass, children: cancelText }), jsx("button", { type: "button", onClick: startCountdown, className: confirmButtonClass, children: confirmText })] })) })] }) }));
|
|
83
89
|
}
|
|
84
90
|
|
|
85
91
|
export { UndoableConfirmDialog };
|
package/dist/main/features.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
var tslib = require('tslib');
|
|
4
4
|
var jsxRuntime = require('react/jsx-runtime');
|
|
5
5
|
var server = require('next-intl/server');
|
|
6
|
-
var
|
|
6
|
+
var shared = require('@windrun-huaiin/base-ui/components/shared');
|
|
7
7
|
var lib = require('@windrun-huaiin/base-ui/lib');
|
|
8
8
|
var utils = require('@windrun-huaiin/lib/utils');
|
|
9
9
|
var richTextExpert = require('./rich-text-expert.js');
|
|
@@ -26,7 +26,7 @@ function Features(_a) {
|
|
|
26
26
|
}))
|
|
27
27
|
};
|
|
28
28
|
return (jsxRuntime.jsxs("section", { id: "features", className: utils.cn(sectionLayout.responsiveSection, sectionClassName), children: [jsxRuntime.jsxs("h2", { className: "text-3xl md:text-4xl font-bold text-center mb-4", children: [data.title, " ", jsxRuntime.jsx("span", { className: lib.themeIconColor, children: data.eyesOn })] }), jsxRuntime.jsx("p", { className: "text-center text-gray-600 dark:text-gray-400 mb-12 text-base sm:text-lg mx-auto max-w-3xl", children: data.description }), jsxRuntime.jsx("div", { className: "grid grid-cols-1 md:grid-cols-3 gap-8 gap-y-12", children: data.items.map((feature) => {
|
|
29
|
-
const Icon =
|
|
29
|
+
const Icon = shared.getGlobalIcon(feature.iconKey);
|
|
30
30
|
return (jsxRuntime.jsxs("div", { "data-feature-id": feature.id, className: utils.cn("bg-white dark:bg-gray-800/60 p-8 rounded-xl border border-gray-200 dark:border-gray-700 hover:border-current transition shadow-sm dark:shadow-none", lib.themeIconColor), children: [jsxRuntime.jsx("div", { className: "text-4xl mb-4 flex items-center justify-start", children: jsxRuntime.jsx(Icon, { className: "w-8 h-8" }) }), jsxRuntime.jsx("h3", { className: "text-xl font-semibold mb-3 text-gray-900 dark:text-gray-100", children: feature.title }), jsxRuntime.jsx("p", { className: "text-gray-700 dark:text-gray-300", children: feature.description })] }, feature.id));
|
|
31
31
|
}) })] }));
|
|
32
32
|
});
|
package/dist/main/features.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { __awaiter } from 'tslib';
|
|
2
2
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
3
3
|
import { getTranslations } from 'next-intl/server';
|
|
4
|
-
import { getGlobalIcon } from '@windrun-huaiin/base-ui/components/
|
|
4
|
+
import { getGlobalIcon } from '@windrun-huaiin/base-ui/components/shared';
|
|
5
5
|
import { themeIconColor } from '@windrun-huaiin/base-ui/lib';
|
|
6
6
|
import { cn } from '@windrun-huaiin/lib/utils';
|
|
7
7
|
import { richText } from './rich-text-expert.mjs';
|
package/dist/main/footer.js
CHANGED
|
@@ -23,7 +23,7 @@ function Footer(_a) {
|
|
|
23
23
|
clickToCopyText: tIntl.safeT(tFooter, 'clickToCopy', 'Click to copy'),
|
|
24
24
|
copiedText: tIntl.safeT(tFooter, 'copied', 'Copied!'),
|
|
25
25
|
};
|
|
26
|
-
return (jsxRuntime.jsxs("div", { className: "mb-10 w-full mx-auto", children: [jsxRuntime.jsx("div", { className: utils.cn("w-full border-current border-t", lib.themeIconColor) }), jsxRuntime.jsx("footer", { children: jsxRuntime.jsxs("div", { className: "w-full flex flex-col items-center justify-center px-4 py-8 space-y-3", children: [jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center justify-center gap-x-2 gap-y-2 text-xs sm:text-sm sm:gap-x-6", children: [jsxRuntime.jsxs(Link, { href: utils.getAsNeededLocalizedUrl(locale, "/legal/terms", localePrefixAsNeeded, defaultLocale), className: "flex items-center space-x-1 hover:underline", children: [jsxRuntime.jsx(icons.ReceiptTextIcon, { className: "h-3.5 w-3.5" }), jsxRuntime.jsx("span", { children: data.terms })] }), jsxRuntime.jsxs(Link, { href: utils.getAsNeededLocalizedUrl(locale, "/legal/privacy", localePrefixAsNeeded, defaultLocale), className: "flex items-center space-x-1 hover:underline", children: [jsxRuntime.jsx(icons.ShieldUserIcon, { className: "h-3.5 w-3.5" }), jsxRuntime.jsx("span", { children: data.privacy })] }), jsxRuntime.jsxs(footerEmail.FooterEmail, { email: data.email, clickToCopyText: data.clickToCopyText, copiedText: data.copiedText, children: [jsxRuntime.jsx(icons.MailIcon, { className: "h-3.5 w-3.5" }), jsxRuntime.jsx("span", { children: data.contactUs })] })] }), jsxRuntime.jsx("div", { className: "text-xs sm:text-sm text-center", children: jsxRuntime.jsx("span", { children: data.copyright }) })] }) })] }));
|
|
26
|
+
return (jsxRuntime.jsxs("div", { className: "mb-10 w-full mx-auto", children: [jsxRuntime.jsx("div", { className: utils.cn("w-full border-current border-t", lib.themeIconColor) }), jsxRuntime.jsx("footer", { children: jsxRuntime.jsxs("div", { className: "w-full flex flex-col items-center justify-center px-4 py-8 space-y-3", children: [jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center justify-center gap-x-2 gap-y-2 text-xs sm:text-sm sm:gap-x-6", children: [jsxRuntime.jsxs(Link, { prefetch: false, href: utils.getAsNeededLocalizedUrl(locale, "/legal/terms", localePrefixAsNeeded, defaultLocale), className: "flex items-center space-x-1 hover:underline", children: [jsxRuntime.jsx(icons.ReceiptTextIcon, { className: "h-3.5 w-3.5" }), jsxRuntime.jsx("span", { children: data.terms })] }), jsxRuntime.jsxs(Link, { prefetch: false, href: utils.getAsNeededLocalizedUrl(locale, "/legal/privacy", localePrefixAsNeeded, defaultLocale), className: "flex items-center space-x-1 hover:underline", children: [jsxRuntime.jsx(icons.ShieldUserIcon, { className: "h-3.5 w-3.5" }), jsxRuntime.jsx("span", { children: data.privacy })] }), jsxRuntime.jsxs(footerEmail.FooterEmail, { email: data.email, clickToCopyText: data.clickToCopyText, copiedText: data.copiedText, children: [jsxRuntime.jsx(icons.MailIcon, { className: "h-3.5 w-3.5" }), jsxRuntime.jsx("span", { children: data.contactUs })] })] }), jsxRuntime.jsx("div", { className: "text-xs sm:text-sm text-center", children: jsxRuntime.jsx("span", { children: data.copyright }) })] }) })] }));
|
|
27
27
|
});
|
|
28
28
|
}
|
|
29
29
|
|
package/dist/main/footer.mjs
CHANGED
|
@@ -21,7 +21,7 @@ function Footer(_a) {
|
|
|
21
21
|
clickToCopyText: safeT(tFooter, 'clickToCopy', 'Click to copy'),
|
|
22
22
|
copiedText: safeT(tFooter, 'copied', 'Copied!'),
|
|
23
23
|
};
|
|
24
|
-
return (jsxs("div", { className: "mb-10 w-full mx-auto", children: [jsx("div", { className: cn("w-full border-current border-t", themeIconColor) }), jsx("footer", { children: jsxs("div", { className: "w-full flex flex-col items-center justify-center px-4 py-8 space-y-3", children: [jsxs("div", { className: "flex flex-wrap items-center justify-center gap-x-2 gap-y-2 text-xs sm:text-sm sm:gap-x-6", children: [jsxs(Link, { href: getAsNeededLocalizedUrl(locale, "/legal/terms", localePrefixAsNeeded, defaultLocale), className: "flex items-center space-x-1 hover:underline", children: [jsx(ReceiptTextIcon, { className: "h-3.5 w-3.5" }), jsx("span", { children: data.terms })] }), jsxs(Link, { href: getAsNeededLocalizedUrl(locale, "/legal/privacy", localePrefixAsNeeded, defaultLocale), className: "flex items-center space-x-1 hover:underline", children: [jsx(ShieldUserIcon, { className: "h-3.5 w-3.5" }), jsx("span", { children: data.privacy })] }), jsxs(FooterEmail, { email: data.email, clickToCopyText: data.clickToCopyText, copiedText: data.copiedText, children: [jsx(MailIcon, { className: "h-3.5 w-3.5" }), jsx("span", { children: data.contactUs })] })] }), jsx("div", { className: "text-xs sm:text-sm text-center", children: jsx("span", { children: data.copyright }) })] }) })] }));
|
|
24
|
+
return (jsxs("div", { className: "mb-10 w-full mx-auto", children: [jsx("div", { className: cn("w-full border-current border-t", themeIconColor) }), jsx("footer", { children: jsxs("div", { className: "w-full flex flex-col items-center justify-center px-4 py-8 space-y-3", children: [jsxs("div", { className: "flex flex-wrap items-center justify-center gap-x-2 gap-y-2 text-xs sm:text-sm sm:gap-x-6", children: [jsxs(Link, { prefetch: false, href: getAsNeededLocalizedUrl(locale, "/legal/terms", localePrefixAsNeeded, defaultLocale), className: "flex items-center space-x-1 hover:underline", children: [jsx(ReceiptTextIcon, { className: "h-3.5 w-3.5" }), jsx("span", { children: data.terms })] }), jsxs(Link, { prefetch: false, href: getAsNeededLocalizedUrl(locale, "/legal/privacy", localePrefixAsNeeded, defaultLocale), className: "flex items-center space-x-1 hover:underline", children: [jsx(ShieldUserIcon, { className: "h-3.5 w-3.5" }), jsx("span", { children: data.privacy })] }), jsxs(FooterEmail, { email: data.email, clickToCopyText: data.clickToCopyText, copiedText: data.copiedText, children: [jsx(MailIcon, { className: "h-3.5 w-3.5" }), jsx("span", { children: data.contactUs })] })] }), jsx("div", { className: "text-xs sm:text-sm text-center", children: jsx("span", { children: data.copyright }) })] }) })] }));
|
|
25
25
|
});
|
|
26
26
|
}
|
|
27
27
|
|
package/dist/main/usage.js
CHANGED
|
@@ -4,7 +4,7 @@ var tslib = require('tslib');
|
|
|
4
4
|
var jsxRuntime = require('react/jsx-runtime');
|
|
5
5
|
var server = require('next-intl/server');
|
|
6
6
|
var utils = require('@windrun-huaiin/lib/utils');
|
|
7
|
-
var
|
|
7
|
+
var shared = require('@windrun-huaiin/base-ui/components/shared');
|
|
8
8
|
var lib = require('@windrun-huaiin/base-ui/lib');
|
|
9
9
|
var richTextExpert = require('./rich-text-expert.js');
|
|
10
10
|
var sectionLayout = require('./section-layout.js');
|
|
@@ -27,7 +27,7 @@ function Usage(_a) {
|
|
|
27
27
|
}))
|
|
28
28
|
};
|
|
29
29
|
return (jsxRuntime.jsxs("section", { id: "usage", className: utils.cn(sectionLayout.responsiveSection, sectionClassName), children: [jsxRuntime.jsxs("h2", { className: "text-3xl md:text-4xl font-bold text-center mb-4", children: [data.title, " ", jsxRuntime.jsx("span", { className: lib.themeIconColor, children: data.eyesOn })] }), jsxRuntime.jsx("p", { className: "text-center text-gray-600 dark:text-gray-400 mb-12 text-base sm:text-lg mx-auto max-w-3xl", children: data.description }), jsxRuntime.jsx("div", { className: "bg-gray-50 dark:bg-gray-800/60 border border-gray-200 dark:border-gray-700 rounded-2xl p-8 md:p-12 shadow-sm dark:shadow-none", children: jsxRuntime.jsx("div", { className: "grid grid-cols-1 md:grid-cols-3 gap-8 gap-y-12", children: data.steps.map((step) => {
|
|
30
|
-
const Icon =
|
|
30
|
+
const Icon = shared.getGlobalIcon(step.iconKey);
|
|
31
31
|
return (jsxRuntime.jsxs("div", { "data-usage-step": step.id, className: "flex items-start", children: [jsxRuntime.jsx("div", { className: "shrink-0 mr-4", children: jsxRuntime.jsx(Icon, { className: "w-8 h-8" }) }), jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("h3", { className: "text-xl font-semibold mb-3 text-gray-900 dark:text-gray-100 flex items-center", children: `${step.stepNumber}. ${step.title}` }), jsxRuntime.jsx("p", { className: "text-gray-700 dark:text-gray-300", children: step.description })] })] }, step.id));
|
|
32
32
|
}) }) })] }));
|
|
33
33
|
});
|
package/dist/main/usage.mjs
CHANGED
|
@@ -2,7 +2,7 @@ import { __awaiter } from 'tslib';
|
|
|
2
2
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
3
3
|
import { getTranslations } from 'next-intl/server';
|
|
4
4
|
import { cn } from '@windrun-huaiin/lib/utils';
|
|
5
|
-
import { getGlobalIcon } from '@windrun-huaiin/base-ui/components/
|
|
5
|
+
import { getGlobalIcon } from '@windrun-huaiin/base-ui/components/shared';
|
|
6
6
|
import { themeIconColor } from '@windrun-huaiin/base-ui/lib';
|
|
7
7
|
import { richText } from './rich-text-expert.mjs';
|
|
8
8
|
import { responsiveSection } from './section-layout.mjs';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@windrun-huaiin/third-ui",
|
|
3
|
-
"version": "29.0
|
|
3
|
+
"version": "29.1.0",
|
|
4
4
|
"description": "Third-party integrated UI components for windrun-huaiin projects",
|
|
5
5
|
"exports": {
|
|
6
6
|
"./clerk": {
|
|
@@ -227,9 +227,9 @@
|
|
|
227
227
|
"tslib": "^2.8.1",
|
|
228
228
|
"unified": "^11.0.5",
|
|
229
229
|
"zod": "^4.3.6",
|
|
230
|
-
"@windrun-huaiin/base-ui": "^29.0.
|
|
231
|
-
"@windrun-huaiin/
|
|
232
|
-
"@windrun-huaiin/
|
|
230
|
+
"@windrun-huaiin/base-ui": "^29.0.2",
|
|
231
|
+
"@windrun-huaiin/contracts": "^29.0.0",
|
|
232
|
+
"@windrun-huaiin/lib": "^29.0.0"
|
|
233
233
|
},
|
|
234
234
|
"peerDependencies": {
|
|
235
235
|
"clsx": "^2.1.1",
|
|
@@ -43,6 +43,10 @@ export type NavbarCSSVars = CSSProperties & {
|
|
|
43
43
|
'--fd-nav-max-width'?: string;
|
|
44
44
|
};
|
|
45
45
|
|
|
46
|
+
const PrefetchLinkItem = LinkItem as (
|
|
47
|
+
props: ComponentProps<typeof LinkItem> & { prefetch?: boolean },
|
|
48
|
+
) => ReactNode;
|
|
49
|
+
|
|
46
50
|
export interface CustomHomeHeaderProps extends HomeLayoutProps {
|
|
47
51
|
/**
|
|
48
52
|
* Banner height in rem units
|
|
@@ -527,8 +531,9 @@ function NavbarLinkItem({
|
|
|
527
531
|
return (
|
|
528
532
|
<NavigationMenuItem>
|
|
529
533
|
<NavigationMenuLink asChild>
|
|
530
|
-
<
|
|
534
|
+
<PrefetchLinkItem
|
|
531
535
|
item={item}
|
|
536
|
+
prefetch={item.prefetch ?? false}
|
|
532
537
|
aria-label={item.type === 'icon' ? item.label : undefined}
|
|
533
538
|
{...props}
|
|
534
539
|
className={cn(
|
|
@@ -537,7 +542,7 @@ function NavbarLinkItem({
|
|
|
537
542
|
)}
|
|
538
543
|
>
|
|
539
544
|
{item.type === 'icon' ? item.icon : item.text}
|
|
540
|
-
</
|
|
545
|
+
</PrefetchLinkItem>
|
|
541
546
|
</NavigationMenuLink>
|
|
542
547
|
</NavigationMenuItem>
|
|
543
548
|
);
|
|
@@ -585,8 +590,9 @@ function MenuLinkItem({
|
|
|
585
590
|
|
|
586
591
|
return (
|
|
587
592
|
<NavigationMenuLink asChild>
|
|
588
|
-
<
|
|
593
|
+
<PrefetchLinkItem
|
|
589
594
|
item={item}
|
|
595
|
+
prefetch={item.prefetch ?? false}
|
|
590
596
|
className={cn(
|
|
591
597
|
{
|
|
592
598
|
main: 'inline-flex items-center gap-2 py-1.5 transition-colors hover:text-fd-popover-foreground/50 data-[active=true]:font-medium data-[active=true]:text-fd-primary [&_svg]:size-4',
|
|
@@ -605,7 +611,7 @@ function MenuLinkItem({
|
|
|
605
611
|
>
|
|
606
612
|
{item.icon}
|
|
607
613
|
{item.type === 'icon' ? undefined : item.text}
|
|
608
|
-
</
|
|
614
|
+
</PrefetchLinkItem>
|
|
609
615
|
</NavigationMenuLink>
|
|
610
616
|
);
|
|
611
617
|
}
|
|
@@ -26,6 +26,7 @@ import {
|
|
|
26
26
|
} from './dialog-styles';
|
|
27
27
|
|
|
28
28
|
export type ConfirmDialogType = 'normal' | 'danger';
|
|
29
|
+
export type ConfirmDialogEmphasis = 'confirm' | 'cancel';
|
|
29
30
|
|
|
30
31
|
interface ConfirmDialogProps {
|
|
31
32
|
open: boolean;
|
|
@@ -35,6 +36,7 @@ interface ConfirmDialogProps {
|
|
|
35
36
|
description: React.ReactNode;
|
|
36
37
|
cancelText?: string;
|
|
37
38
|
confirmText?: string;
|
|
39
|
+
emphasis?: ConfirmDialogEmphasis;
|
|
38
40
|
onCancel?: () => void;
|
|
39
41
|
onConfirm?: () => void;
|
|
40
42
|
}
|
|
@@ -70,23 +72,29 @@ export function ConfirmDialog({
|
|
|
70
72
|
description,
|
|
71
73
|
cancelText = 'Cancel',
|
|
72
74
|
confirmText = 'Confirm',
|
|
75
|
+
emphasis = 'confirm',
|
|
73
76
|
onCancel,
|
|
74
77
|
onConfirm,
|
|
75
78
|
}: ConfirmDialogProps) {
|
|
76
79
|
const typeClass = confirmTypeClassMap[type];
|
|
77
80
|
const Icon = typeClass.Icon;
|
|
81
|
+
const cancelButtonClass = emphasis === 'cancel' ? typeClass.action : secondaryButtonClass;
|
|
82
|
+
const confirmButtonClass = emphasis === 'cancel' ? secondaryButtonClass : typeClass.action;
|
|
78
83
|
|
|
79
84
|
const handleCancel = () => {
|
|
80
85
|
onOpenChange(false);
|
|
81
86
|
onCancel?.();
|
|
82
87
|
};
|
|
88
|
+
const handleClose = () => {
|
|
89
|
+
onOpenChange(false);
|
|
90
|
+
};
|
|
83
91
|
|
|
84
92
|
return (
|
|
85
93
|
<AlertDialog open={open} onOpenChange={onOpenChange}>
|
|
86
94
|
<AlertDialogContent
|
|
87
95
|
className={cn(dialogContentClass, typeClass.content)}
|
|
88
96
|
overlayClassName={dialogThemedOverlayClass}
|
|
89
|
-
onOverlayClick={
|
|
97
|
+
onOverlayClick={handleClose}
|
|
90
98
|
>
|
|
91
99
|
<div className={dialogHeaderClass}>
|
|
92
100
|
<AlertDialogTitle asChild>
|
|
@@ -100,7 +108,7 @@ export function ConfirmDialog({
|
|
|
100
108
|
<button
|
|
101
109
|
type="button"
|
|
102
110
|
className={closeButtonClass}
|
|
103
|
-
onClick={
|
|
111
|
+
onClick={handleClose}
|
|
104
112
|
aria-label="Close"
|
|
105
113
|
>
|
|
106
114
|
<XIcon className="size-4" />
|
|
@@ -112,11 +120,11 @@ export function ConfirmDialog({
|
|
|
112
120
|
</AlertDialogDescription>
|
|
113
121
|
|
|
114
122
|
<div className={dialogFooterClass}>
|
|
115
|
-
<AlertDialogCancel className={
|
|
123
|
+
<AlertDialogCancel className={cancelButtonClass} onClick={handleCancel}>
|
|
116
124
|
{cancelText}
|
|
117
125
|
</AlertDialogCancel>
|
|
118
126
|
<AlertDialogAction
|
|
119
|
-
className={
|
|
127
|
+
className={confirmButtonClass}
|
|
120
128
|
onClick={() => {
|
|
121
129
|
onOpenChange(false);
|
|
122
130
|
onConfirm?.();
|
|
@@ -18,6 +18,7 @@ import { themeBgColor, themeBorderColor, themeIconColor } from "@windrun-huaiin/
|
|
|
18
18
|
|
|
19
19
|
interface HighPriorityConfirmDialogProps {
|
|
20
20
|
open: boolean;
|
|
21
|
+
onOpenChange: (open: boolean) => void;
|
|
21
22
|
onCancel: () => void;
|
|
22
23
|
onConfirm: () => void;
|
|
23
24
|
title: string;
|
|
@@ -28,6 +29,7 @@ interface HighPriorityConfirmDialogProps {
|
|
|
28
29
|
|
|
29
30
|
export function HighPriorityConfirmDialog({
|
|
30
31
|
open,
|
|
32
|
+
onOpenChange,
|
|
31
33
|
onCancel,
|
|
32
34
|
onConfirm,
|
|
33
35
|
title,
|
|
@@ -44,6 +46,10 @@ export function HighPriorityConfirmDialog({
|
|
|
44
46
|
|
|
45
47
|
if (!open || !mounted) return null;
|
|
46
48
|
|
|
49
|
+
const handleClose = () => {
|
|
50
|
+
onOpenChange(false);
|
|
51
|
+
};
|
|
52
|
+
|
|
47
53
|
return createPortal(
|
|
48
54
|
<div className="fixed inset-0 z-10000 flex items-center justify-center bg-black/60 backdrop-blur-sm animate-in fade-in duration-300">
|
|
49
55
|
<div
|
|
@@ -62,7 +68,7 @@ export function HighPriorityConfirmDialog({
|
|
|
62
68
|
<button
|
|
63
69
|
type="button"
|
|
64
70
|
className={closeButtonClass}
|
|
65
|
-
onClick={
|
|
71
|
+
onClick={handleClose}
|
|
66
72
|
aria-label="Close"
|
|
67
73
|
>
|
|
68
74
|
<XIcon className="size-4" />
|
|
@@ -21,6 +21,7 @@ import {
|
|
|
21
21
|
dialogTitleClass,
|
|
22
22
|
secondaryButtonClass,
|
|
23
23
|
} from './dialog-styles';
|
|
24
|
+
import type { ConfirmDialogEmphasis } from './confirm-dialog';
|
|
24
25
|
|
|
25
26
|
export interface UndoableConfirmDialogProps {
|
|
26
27
|
open: boolean;
|
|
@@ -32,6 +33,7 @@ export interface UndoableConfirmDialogProps {
|
|
|
32
33
|
cancelText?: string;
|
|
33
34
|
confirmText?: string;
|
|
34
35
|
undoText?: string;
|
|
36
|
+
emphasis?: ConfirmDialogEmphasis;
|
|
35
37
|
countdownSeconds?: number;
|
|
36
38
|
onCancel?: () => void;
|
|
37
39
|
onConfirm: () => void | Promise<void>;
|
|
@@ -48,6 +50,7 @@ export function UndoableConfirmDialog({
|
|
|
48
50
|
cancelText = 'Cancel',
|
|
49
51
|
confirmText = 'Delete',
|
|
50
52
|
undoText = 'Undo',
|
|
53
|
+
emphasis = 'confirm',
|
|
51
54
|
countdownSeconds = 5,
|
|
52
55
|
onCancel,
|
|
53
56
|
onConfirm,
|
|
@@ -59,6 +62,8 @@ export function UndoableConfirmDialog({
|
|
|
59
62
|
const [confirming, setConfirming] = React.useState(false);
|
|
60
63
|
const timeoutRef = React.useRef<number | null>(null);
|
|
61
64
|
const intervalRef = React.useRef<number | null>(null);
|
|
65
|
+
const cancelButtonClass = emphasis === 'cancel' ? dangerButtonClass : secondaryButtonClass;
|
|
66
|
+
const confirmButtonClass = emphasis === 'cancel' ? secondaryButtonClass : dangerButtonClass;
|
|
62
67
|
|
|
63
68
|
const clearTimers = React.useCallback(() => {
|
|
64
69
|
if (timeoutRef.current) {
|
|
@@ -121,6 +126,10 @@ export function UndoableConfirmDialog({
|
|
|
121
126
|
onOpenChange(false);
|
|
122
127
|
onCancel?.();
|
|
123
128
|
};
|
|
129
|
+
const handleClose = React.useCallback(() => {
|
|
130
|
+
resetState();
|
|
131
|
+
onOpenChange(false);
|
|
132
|
+
}, [onOpenChange, resetState]);
|
|
124
133
|
|
|
125
134
|
const handleUndo = () => {
|
|
126
135
|
resetState();
|
|
@@ -133,7 +142,7 @@ export function UndoableConfirmDialog({
|
|
|
133
142
|
return (
|
|
134
143
|
<AlertDialog open={open} onOpenChange={(nextOpen) => {
|
|
135
144
|
if (!nextOpen) {
|
|
136
|
-
|
|
145
|
+
handleClose();
|
|
137
146
|
return;
|
|
138
147
|
}
|
|
139
148
|
|
|
@@ -142,7 +151,7 @@ export function UndoableConfirmDialog({
|
|
|
142
151
|
<AlertDialogContent
|
|
143
152
|
className={cn(dialogContentClass, 'border-red-300 dark:border-red-700')}
|
|
144
153
|
overlayClassName={dialogThemedOverlayClass}
|
|
145
|
-
onOverlayClick={pending ? undefined :
|
|
154
|
+
onOverlayClick={pending ? undefined : handleClose}
|
|
146
155
|
>
|
|
147
156
|
<div className={dialogHeaderClass}>
|
|
148
157
|
<AlertDialogTitle asChild>
|
|
@@ -156,7 +165,7 @@ export function UndoableConfirmDialog({
|
|
|
156
165
|
<button
|
|
157
166
|
type="button"
|
|
158
167
|
className={closeButtonClass}
|
|
159
|
-
onClick={
|
|
168
|
+
onClick={handleClose}
|
|
160
169
|
aria-label="Close"
|
|
161
170
|
disabled={confirming}
|
|
162
171
|
>
|
|
@@ -195,14 +204,14 @@ export function UndoableConfirmDialog({
|
|
|
195
204
|
<button
|
|
196
205
|
type="button"
|
|
197
206
|
onClick={handleCancel}
|
|
198
|
-
className={
|
|
207
|
+
className={cancelButtonClass}
|
|
199
208
|
>
|
|
200
209
|
{cancelText}
|
|
201
210
|
</button>
|
|
202
211
|
<button
|
|
203
212
|
type="button"
|
|
204
213
|
onClick={startCountdown}
|
|
205
|
-
className={
|
|
214
|
+
className={confirmButtonClass}
|
|
206
215
|
>
|
|
207
216
|
{confirmText}
|
|
208
217
|
</button>
|
package/src/main/features.tsx
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getTranslations } from 'next-intl/server';
|
|
2
|
-
import { getGlobalIcon } from '@windrun-huaiin/base-ui/components/
|
|
2
|
+
import { getGlobalIcon } from '@windrun-huaiin/base-ui/components/shared';
|
|
3
3
|
import type { globalLucideIcons } from '@windrun-huaiin/base-ui/icons';
|
|
4
4
|
import { themeIconColor } from '@windrun-huaiin/base-ui/lib';
|
|
5
5
|
import { cn } from '@windrun-huaiin/lib/utils';
|
package/src/main/footer.tsx
CHANGED
|
@@ -45,11 +45,11 @@ export async function Footer({ locale, localePrefixAsNeeded = true, defaultLocal
|
|
|
45
45
|
<footer>
|
|
46
46
|
<div className="w-full flex flex-col items-center justify-center px-4 py-8 space-y-3">
|
|
47
47
|
<div className="flex flex-wrap items-center justify-center gap-x-2 gap-y-2 text-xs sm:text-sm sm:gap-x-6">
|
|
48
|
-
<Link href={getAsNeededLocalizedUrl(locale, "/legal/terms", localePrefixAsNeeded, defaultLocale)} className="flex items-center space-x-1 hover:underline">
|
|
48
|
+
<Link prefetch={false} href={getAsNeededLocalizedUrl(locale, "/legal/terms", localePrefixAsNeeded, defaultLocale)} className="flex items-center space-x-1 hover:underline">
|
|
49
49
|
<ReceiptTextIcon className="h-3.5 w-3.5"/>
|
|
50
50
|
<span>{data.terms}</span>
|
|
51
51
|
</Link>
|
|
52
|
-
<Link href={getAsNeededLocalizedUrl(locale, "/legal/privacy", localePrefixAsNeeded, defaultLocale)} className="flex items-center space-x-1 hover:underline">
|
|
52
|
+
<Link prefetch={false} href={getAsNeededLocalizedUrl(locale, "/legal/privacy", localePrefixAsNeeded, defaultLocale)} className="flex items-center space-x-1 hover:underline">
|
|
53
53
|
<ShieldUserIcon className="h-3.5 w-3.5"/>
|
|
54
54
|
<span>{data.privacy}</span>
|
|
55
55
|
</Link>
|
package/src/main/usage.tsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { getTranslations } from 'next-intl/server';
|
|
2
2
|
import { cn } from '@windrun-huaiin/lib/utils';
|
|
3
|
-
import { globalLucideIcons as icons, getGlobalIcon } from '@windrun-huaiin/base-ui/components/
|
|
3
|
+
import { globalLucideIcons as icons, getGlobalIcon } from '@windrun-huaiin/base-ui/components/shared';
|
|
4
4
|
import { themeIconColor } from '@windrun-huaiin/base-ui/lib';
|
|
5
5
|
import { richText } from './rich-text-expert';
|
|
6
6
|
import { responsiveSection } from './section-layout';
|