pixelize-design-library 3.0.0 → 3.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/CHANGELOG.md +64 -1
- package/COMPONENT-GOTCHAS.md +37 -13
- package/DESIGN-GUIDE.md +4 -1
- package/dist/Components/NotificationBell/NotificationBellProps.d.ts +3 -3
- package/dist/Components/NotificationBell/NotificationItem.d.ts +1 -1
- package/dist/Components/NotificationBell/NotificationItem.js +1 -1
- package/dist/Components/NotificationBell/NotificationList.d.ts +1 -1
- package/dist/Components/NotificationBell/NotificationList.js +1 -1
- package/dist/Components/NotificationBell/NotificationPanel.d.ts +1 -1
- package/dist/Components/NotificationBell/NotificationPanel.js +1 -1
- package/dist/Components/NotificationCenter/center/CenterPanel.d.ts +15 -0
- package/dist/Components/NotificationCenter/center/CenterPanel.js +87 -0
- package/dist/Components/NotificationCenter/center/NotificationCenter.d.ts +4 -0
- package/dist/Components/NotificationCenter/center/NotificationCenter.js +130 -0
- package/dist/Components/NotificationCenter/center/NotificationCenterProps.d.ts +71 -0
- package/dist/Components/NotificationCenter/center/NotificationCenterProps.js +2 -0
- package/dist/Components/NotificationCenter/center/PanelRows.d.ts +10 -0
- package/dist/Components/NotificationCenter/center/PanelRows.js +35 -0
- package/dist/Components/NotificationCenter/center/PanelStates.d.ts +17 -0
- package/dist/Components/NotificationCenter/center/PanelStates.js +21 -0
- package/dist/Components/NotificationCenter/center/centerLabels.d.ts +4 -0
- package/dist/Components/NotificationCenter/center/centerLabels.js +38 -0
- package/dist/Components/NotificationCenter/center/useArrivals.d.ts +14 -0
- package/dist/Components/NotificationCenter/center/useArrivals.js +71 -0
- package/dist/Components/NotificationCenter/center/useIsSheet.d.ts +2 -0
- package/dist/Components/NotificationCenter/center/useIsSheet.js +20 -0
- package/dist/Components/NotificationCenter/core/NotificationCenterProvider.d.ts +17 -0
- package/dist/Components/NotificationCenter/core/NotificationCenterProvider.js +46 -0
- package/dist/Components/NotificationCenter/core/NotificationEngineProps.d.ts +182 -0
- package/dist/Components/NotificationCenter/core/NotificationEngineProps.js +2 -0
- package/dist/Components/NotificationCenter/core/NotificationSourceProps.d.ts +284 -0
- package/dist/Components/NotificationCenter/core/NotificationSourceProps.js +2 -0
- package/dist/Components/NotificationCenter/core/actionError.d.ts +4 -0
- package/dist/Components/NotificationCenter/core/actionError.js +45 -0
- package/dist/Components/NotificationCenter/core/format.d.ts +4 -0
- package/dist/Components/NotificationCenter/core/format.js +91 -0
- package/dist/Components/NotificationCenter/core/grouping.d.ts +14 -0
- package/dist/Components/NotificationCenter/core/grouping.js +102 -0
- package/dist/Components/NotificationCenter/core/labels.d.ts +6 -0
- package/dist/Components/NotificationCenter/core/labels.js +94 -0
- package/dist/Components/NotificationCenter/core/overlay.d.ts +109 -0
- package/dist/Components/NotificationCenter/core/overlay.js +281 -0
- package/dist/Components/NotificationCenter/core/useNotificationEngine.d.ts +13 -0
- package/dist/Components/NotificationCenter/core/useNotificationEngine.js +415 -0
- package/dist/Components/NotificationCenter/inbox/InboxList.d.ts +17 -0
- package/dist/Components/NotificationCenter/inbox/InboxList.js +25 -0
- package/dist/Components/NotificationCenter/inbox/InboxStates.d.ts +17 -0
- package/dist/Components/NotificationCenter/inbox/InboxStates.js +27 -0
- package/dist/Components/NotificationCenter/inbox/NotificationInbox.d.ts +4 -0
- package/dist/Components/NotificationCenter/inbox/NotificationInbox.js +434 -0
- package/dist/Components/NotificationCenter/inbox/NotificationInboxProps.d.ts +106 -0
- package/dist/Components/NotificationCenter/inbox/NotificationInboxProps.js +2 -0
- package/dist/Components/NotificationCenter/inbox/ShortcutsDialog.d.ts +8 -0
- package/dist/Components/NotificationCenter/inbox/ShortcutsDialog.js +63 -0
- package/dist/Components/NotificationCenter/inbox/inboxLabels.d.ts +4 -0
- package/dist/Components/NotificationCenter/inbox/inboxLabels.js +56 -0
- package/dist/Components/NotificationCenter/inbox/inboxModel.d.ts +17 -0
- package/dist/Components/NotificationCenter/inbox/inboxModel.js +47 -0
- package/dist/Components/NotificationCenter/inbox/useControllable.d.ts +1 -0
- package/dist/Components/NotificationCenter/inbox/useControllable.js +15 -0
- package/dist/Components/NotificationCenter/index.d.ts +8 -0
- package/dist/Components/NotificationCenter/index.js +26 -0
- package/dist/Components/NotificationCenter/preferences/NotificationPreferences.d.ts +4 -0
- package/dist/Components/NotificationCenter/preferences/NotificationPreferences.js +72 -0
- package/dist/Components/NotificationCenter/preferences/NotificationPreferencesProps.d.ts +111 -0
- package/dist/Components/NotificationCenter/preferences/NotificationPreferencesProps.js +2 -0
- package/dist/Components/NotificationCenter/preferences/PreferenceCells.d.ts +16 -0
- package/dist/Components/NotificationCenter/preferences/PreferenceCells.js +35 -0
- package/dist/Components/NotificationCenter/preferences/PreferenceGroups.d.ts +15 -0
- package/dist/Components/NotificationCenter/preferences/PreferenceGroups.js +26 -0
- package/dist/Components/NotificationCenter/preferences/preferencesLabels.d.ts +2 -0
- package/dist/Components/NotificationCenter/preferences/preferencesLabels.js +28 -0
- package/dist/Components/NotificationCenter/preferences/useAutosave.d.ts +8 -0
- package/dist/Components/NotificationCenter/preferences/useAutosave.js +41 -0
- package/dist/Components/NotificationCenter/row/NotificationDetail.d.ts +4 -0
- package/dist/Components/NotificationCenter/row/NotificationDetail.js +65 -0
- package/dist/Components/NotificationCenter/row/NotificationDetailProps.d.ts +15 -0
- package/dist/Components/NotificationCenter/row/NotificationDetailProps.js +2 -0
- package/dist/Components/NotificationCenter/row/NotificationRow.d.ts +3 -0
- package/dist/Components/NotificationCenter/row/NotificationRow.js +124 -0
- package/dist/Components/NotificationCenter/row/NotificationRowProps.d.ts +33 -0
- package/dist/Components/NotificationCenter/row/NotificationRowProps.js +2 -0
- package/dist/Components/NotificationCenter/row/ReasonForm.d.ts +14 -0
- package/dist/Components/NotificationCenter/row/ReasonForm.js +59 -0
- package/dist/Components/NotificationCenter/row/RowActions.d.ts +16 -0
- package/dist/Components/NotificationCenter/row/RowActions.js +36 -0
- package/dist/Components/NotificationCenter/row/RowQuickActions.d.ts +17 -0
- package/dist/Components/NotificationCenter/row/RowQuickActions.js +57 -0
- package/dist/Components/NotificationCenter/row/RowStatus.d.ts +10 -0
- package/dist/Components/NotificationCenter/row/RowStatus.js +42 -0
- package/dist/Components/NotificationCenter/row/category.d.ts +8 -0
- package/dist/Components/NotificationCenter/row/category.js +13 -0
- package/dist/Components/NotificationCenter/row/rowMenu.d.ts +14 -0
- package/dist/Components/NotificationCenter/row/rowMenu.js +37 -0
- package/dist/Components/NotificationCenter/row/rowParts.d.ts +40 -0
- package/dist/Components/NotificationCenter/row/rowParts.js +72 -0
- package/dist/Components/NotificationCenter/row/rowStyles.d.ts +11 -0
- package/dist/Components/NotificationCenter/row/rowStyles.js +25 -0
- package/dist/Components/SegmentedControl/segmentedInk.d.ts +4 -0
- package/dist/Components/SegmentedControl/segmentedInk.js +16 -2
- package/dist/Components/SideBar/SecondaryBar.js +2 -2
- package/dist/Components/SideBar/SideBar.js +18 -8
- package/dist/Components/SideBar/SideBarProps.d.ts +4 -2
- package/dist/Components/SideBar/components/MenuItemBox.d.ts +0 -2
- package/dist/Components/SideBar/components/MenuItemBox.js +2 -3
- package/dist/Components/SideBar/components/MenuItems.js +2 -2
- package/dist/Components/SideBar/components/PinnedSection.js +3 -4
- package/dist/Components/SideBar/sidebarScale.d.ts +0 -2
- package/dist/Components/SideBar/sidebarScale.js +0 -2
- package/dist/Components/Switch/Switch.d.ts +1 -1
- package/dist/Components/Switch/Switch.js +2 -2
- package/dist/Components/Switch/SwitchProps.d.ts +3 -0
- package/dist/Components/Toggle/TableToggle.js +4 -5
- package/dist/Components/Toggle/tableToggleInk.d.ts +7 -0
- package/dist/Components/Toggle/tableToggleInk.js +28 -0
- package/dist/esm/Components/NotificationBell/NotificationItem.js +1 -1
- package/dist/esm/Components/NotificationBell/NotificationList.js +1 -1
- package/dist/esm/Components/NotificationBell/NotificationPanel.js +1 -1
- package/dist/esm/Components/NotificationCenter/center/CenterPanel.js +81 -0
- package/dist/esm/Components/NotificationCenter/center/NotificationCenter.js +92 -0
- package/dist/esm/Components/NotificationCenter/center/NotificationCenterProps.js +1 -0
- package/dist/esm/Components/NotificationCenter/center/PanelRows.js +28 -0
- package/dist/esm/Components/NotificationCenter/center/PanelStates.js +11 -0
- package/dist/esm/Components/NotificationCenter/center/centerLabels.js +34 -0
- package/dist/esm/Components/NotificationCenter/center/useArrivals.js +67 -0
- package/dist/esm/Components/NotificationCenter/center/useIsSheet.js +16 -0
- package/dist/esm/Components/NotificationCenter/core/NotificationCenterProvider.js +35 -0
- package/dist/esm/Components/NotificationCenter/core/NotificationEngineProps.js +1 -0
- package/dist/esm/Components/NotificationCenter/core/NotificationSourceProps.js +1 -0
- package/dist/esm/Components/NotificationCenter/core/actionError.js +39 -0
- package/dist/esm/Components/NotificationCenter/core/format.js +87 -0
- package/dist/esm/Components/NotificationCenter/core/grouping.js +88 -0
- package/dist/esm/Components/NotificationCenter/core/labels.js +88 -0
- package/dist/esm/Components/NotificationCenter/core/overlay.js +274 -0
- package/dist/esm/Components/NotificationCenter/core/useNotificationEngine.js +408 -0
- package/dist/esm/Components/NotificationCenter/inbox/InboxList.js +18 -0
- package/dist/esm/Components/NotificationCenter/inbox/InboxStates.js +18 -0
- package/dist/esm/Components/NotificationCenter/inbox/NotificationInbox.js +396 -0
- package/dist/esm/Components/NotificationCenter/inbox/NotificationInboxProps.js +1 -0
- package/dist/esm/Components/NotificationCenter/inbox/ShortcutsDialog.js +23 -0
- package/dist/esm/Components/NotificationCenter/inbox/inboxLabels.js +52 -0
- package/dist/esm/Components/NotificationCenter/inbox/inboxModel.js +37 -0
- package/dist/esm/Components/NotificationCenter/inbox/useControllable.js +11 -0
- package/dist/esm/Components/NotificationCenter/index.js +8 -0
- package/dist/esm/Components/NotificationCenter/preferences/NotificationPreferences.js +67 -0
- package/dist/esm/Components/NotificationCenter/preferences/NotificationPreferencesProps.js +1 -0
- package/dist/esm/Components/NotificationCenter/preferences/PreferenceCells.js +27 -0
- package/dist/esm/Components/NotificationCenter/preferences/PreferenceGroups.js +21 -0
- package/dist/esm/Components/NotificationCenter/preferences/preferencesLabels.js +24 -0
- package/dist/esm/Components/NotificationCenter/preferences/useAutosave.js +37 -0
- package/dist/esm/Components/NotificationCenter/row/NotificationDetail.js +60 -0
- package/dist/esm/Components/NotificationCenter/row/NotificationDetailProps.js +1 -0
- package/dist/esm/Components/NotificationCenter/row/NotificationRow.js +119 -0
- package/dist/esm/Components/NotificationCenter/row/NotificationRowProps.js +1 -0
- package/dist/esm/Components/NotificationCenter/row/ReasonForm.js +52 -0
- package/dist/esm/Components/NotificationCenter/row/RowActions.js +28 -0
- package/dist/esm/Components/NotificationCenter/row/RowQuickActions.js +49 -0
- package/dist/esm/Components/NotificationCenter/row/RowStatus.js +35 -0
- package/dist/esm/Components/NotificationCenter/row/category.js +9 -0
- package/dist/esm/Components/NotificationCenter/row/rowMenu.js +30 -0
- package/dist/esm/Components/NotificationCenter/row/rowParts.js +59 -0
- package/dist/esm/Components/NotificationCenter/row/rowStyles.js +19 -0
- package/dist/esm/Components/SegmentedControl/segmentedInk.js +15 -2
- package/dist/esm/Components/SideBar/SecondaryBar.js +3 -3
- package/dist/esm/Components/SideBar/SideBar.js +18 -8
- package/dist/esm/Components/SideBar/components/MenuItemBox.js +2 -3
- package/dist/esm/Components/SideBar/components/MenuItems.js +2 -2
- package/dist/esm/Components/SideBar/components/PinnedSection.js +3 -4
- package/dist/esm/Components/SideBar/sidebarScale.js +0 -2
- package/dist/esm/Components/Switch/Switch.js +2 -2
- package/dist/esm/Components/Toggle/TableToggle.js +4 -5
- package/dist/esm/Components/Toggle/tableToggleInk.js +24 -0
- package/dist/esm/index.js +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +16 -3
- package/package.json +1 -1
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
7
|
+
const react_1 = require("react");
|
|
8
|
+
const react_2 = require("@chakra-ui/react");
|
|
9
|
+
const lucide_react_1 = require("lucide-react");
|
|
10
|
+
const Primitives_1 = require("../../Primitives/Primitives");
|
|
11
|
+
const Avatar_1 = __importDefault(require("../../Avatar/Avatar"));
|
|
12
|
+
const Button_1 = __importDefault(require("../../Button/Button"));
|
|
13
|
+
const DescriptionList_1 = __importDefault(require("../../DescriptionList/DescriptionList"));
|
|
14
|
+
const EmptyState_1 = __importDefault(require("../../EmptyState/EmptyState"));
|
|
15
|
+
const Tag_1 = __importDefault(require("../../Tag/Tag"));
|
|
16
|
+
const useCustomTheme_1 = require("../../../Theme/useCustomTheme");
|
|
17
|
+
const focusRing_styles_1 = require("../../../Theme/chakra/focusRing.styles");
|
|
18
|
+
const planeStep_1 = require("../../../Theme/tokens/builders/planeStep");
|
|
19
|
+
const borderWidths_1 = require("../../../Theme/tokens/primitives/borderWidths");
|
|
20
|
+
const radii_1 = require("../../../Theme/tokens/primitives/radii");
|
|
21
|
+
const NotificationCenterProvider_1 = require("../core/NotificationCenterProvider");
|
|
22
|
+
const category_1 = require("./category");
|
|
23
|
+
const ReasonForm_1 = require("./ReasonForm");
|
|
24
|
+
const RowActions_1 = require("./RowActions");
|
|
25
|
+
const RowStatus_1 = require("./RowStatus");
|
|
26
|
+
const rowParts_1 = require("./rowParts");
|
|
27
|
+
const rowMenu_1 = require("./rowMenu");
|
|
28
|
+
const rowStyles_1 = require("./rowStyles");
|
|
29
|
+
/** One notification in full for a reading pane or a phone screen; text only, never markup. */
|
|
30
|
+
const NotificationDetail = ({ item, variant = "desktop", onBack, titleRef }) => {
|
|
31
|
+
var _a, _b, _c;
|
|
32
|
+
const { colors } = (0, useCustomTheme_1.useCustomTheme)();
|
|
33
|
+
const shared = (0, NotificationCenterProvider_1.useNotificationShared)();
|
|
34
|
+
const { labels, format, now, categories, features, isOffline, appName, actions } = shared;
|
|
35
|
+
const { entry, state } = item;
|
|
36
|
+
const titleId = (0, react_1.useId)();
|
|
37
|
+
const [asking, setAsking] = (0, react_1.useState)(null);
|
|
38
|
+
const isPhone = variant === "phone";
|
|
39
|
+
const size = isPhone ? "md" : "sm";
|
|
40
|
+
const iconPx = (0, rowStyles_1.iconSizeFor)(size);
|
|
41
|
+
const category = (0, category_1.categoryFor)(categories, entry.category, labels.otherCategory);
|
|
42
|
+
const tile = (0, rowParts_1.useToneTile)(category.tone);
|
|
43
|
+
const isUnread = entry.isRead === false;
|
|
44
|
+
const actionList = (0, rowMenu_1.visibleActionsFor)(entry, features);
|
|
45
|
+
const decides = actionList.some(rowMenu_1.isDecision);
|
|
46
|
+
const days = format.daysSince(entry.createdAt, now);
|
|
47
|
+
const isWaiting = state.zone === "needsYou" && decides && days >= rowStyles_1.WAITING_AFTER_DAYS;
|
|
48
|
+
const request = state.reasonRequest;
|
|
49
|
+
const askingAction = asking && asking.id === entry.id ? asking.action : undefined;
|
|
50
|
+
const requested = request ? actionList.find((action) => action.id === request.actionId) : undefined;
|
|
51
|
+
const formAction = state.status === "open" ? (askingAction !== null && askingAction !== void 0 ? askingAction : requested) : undefined;
|
|
52
|
+
const isQuiet = state.status === "open";
|
|
53
|
+
const plane = colors.surfaceRaised;
|
|
54
|
+
const closeForm = () => {
|
|
55
|
+
setAsking(null);
|
|
56
|
+
if (request)
|
|
57
|
+
actions.clearReasonRequest(entry.id);
|
|
58
|
+
};
|
|
59
|
+
const archiveButton = features.archive && state.zone === "activity" ? ((0, jsx_runtime_1.jsx)(Button_1.default, { size: size, variant: entry.blocked ? "outline" : "ghost", colorScheme: "gray", leftIcon: (0, jsx_runtime_1.jsx)(lucide_react_1.Archive, { size: iconPx, "aria-hidden": "true" }), label: labels.archive, isDisabled: isOffline, sx: (0, rowStyles_1.touchTargetFor)(size), "data-testid": (0, rowStyles_1.testIdFor)(entry, "archive"), onClick: () => actions.archive([entry.id]) })) : null;
|
|
60
|
+
return ((0, jsx_runtime_1.jsxs)(react_2.chakra.article, { "aria-labelledby": titleId, display: "flex", flexDirection: "column", gap: 4, px: isPhone ? 4 : 8, pt: isPhone ? 2 : 6, pb: 8, maxW: "47.5rem", "data-testid": (0, rowStyles_1.testIdFor)(entry, "detail"), children: [isPhone && onBack && ((0, jsx_runtime_1.jsx)(Primitives_1.Box, { mx: -2, children: (0, jsx_runtime_1.jsx)(Button_1.default, { size: "md", variant: "ghost", colorScheme: "gray", leftIcon: (0, jsx_runtime_1.jsx)(lucide_react_1.ArrowLeft, { size: (0, rowStyles_1.iconSizeFor)("md"), "aria-hidden": "true" }), label: labels.back, sx: (0, rowStyles_1.touchTargetFor)("md"), onClick: onBack }) })), (0, jsx_runtime_1.jsxs)(Primitives_1.Box, { as: "header", display: "grid", gap: 1.5, children: [(0, jsx_runtime_1.jsxs)(Primitives_1.Flex, { wrap: "wrap", align: "center", gap: 1.5, fontSize: "xs", fontWeight: 500, color: colors.textMuted, children: [(0, jsx_runtime_1.jsx)(Primitives_1.Flex, { boxSize: "1.25rem", align: "center", justify: "center", borderRadius: radii_1.RADIUS_ROLE.option, bg: tile.bg, color: tile.fg, "aria-hidden": "true", children: (0, jsx_runtime_1.jsx)(Primitives_1.Icon, { as: category.icon, boxSize: "0.75rem" }) }), (0, jsx_runtime_1.jsx)("span", { children: category.label }), entry.eyebrow && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("span", { "aria-hidden": "true", children: "\u00B7" }), (0, jsx_runtime_1.jsx)(react_2.chakra.span, { fontFamily: "mono", children: entry.eyebrow })] })), isUnread && (0, jsx_runtime_1.jsx)(Tag_1.default, { size: "xs", colorScheme: "primary", label: labels.unread })] }), (0, jsx_runtime_1.jsx)(Primitives_1.Heading, { as: "h2", id: titleId, ref: titleRef, tabIndex: -1, fontSize: "lg", fontWeight: 500, lineHeight: "1.4", color: colors.text[800], borderRadius: "sm", sx: { textWrap: "balance", "&:focus-visible": (0, focusRing_styles_1.focusVisibleRing)(colors) }, children: (0, jsx_runtime_1.jsx)(rowParts_1.TitleText, { parts: entry.title, isUnread: true }) }), (0, jsx_runtime_1.jsxs)(Primitives_1.Flex, { wrap: "wrap", align: "center", gap: 2, fontSize: "xs-plus", color: colors.textMuted, children: [entry.actor && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(Avatar_1.default, { name: entry.actor.name, src: entry.actor.avatarUrl, size: "xs" }), (0, jsx_runtime_1.jsx)("span", { children: entry.actor.name }), (0, jsx_runtime_1.jsx)("span", { "aria-hidden": "true", children: "\u00B7" })] })), (0, jsx_runtime_1.jsx)(react_2.chakra.time, { dateTime: format.iso(entry.createdAt), children: format.absolute(entry.createdAt, now) }), isWaiting && (0, jsx_runtime_1.jsx)(Tag_1.default, { size: "xs", tone: "warning", leadingIcon: lucide_react_1.Hourglass, label: labels.waiting(days) })] })] }), entry.blocked ? ((0, jsx_runtime_1.jsx)(Primitives_1.Box, { borderRadius: radii_1.RADIUS_ROLE.control, bg: colors.backgroundColor.subtle, children: (0, jsx_runtime_1.jsx)(EmptyState_1.default, { icon: lucide_react_1.Lock, size: "sm", titleAs: "h3", title: labels.blockedTitle, description: entry.blocked, action: archiveButton }) })) : ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [entry.context && ((0, jsx_runtime_1.jsx)(Primitives_1.Text, { mt: -2, fontSize: "xs-plus", color: colors.textMuted, children: entry.context })), ((_a = entry.body) !== null && _a !== void 0 ? _a : entry.preview) && ((0, jsx_runtime_1.jsx)(Primitives_1.Text, { fontSize: "sm", lineHeight: "1.65", color: colors.text[800], maxW: "65ch", whiteSpace: "pre-line", children: (_b = entry.body) !== null && _b !== void 0 ? _b : entry.preview })), entry.change && (0, jsx_runtime_1.jsx)(rowParts_1.ChangeChips, { change: entry.change, labels: labels }), entry.fields && entry.fields.length > 0 && ((0, jsx_runtime_1.jsx)(Primitives_1.Box, { p: 4, borderRadius: radii_1.RADIUS_ROLE.control, bg: colors.backgroundColor.subtle, children: (0, jsx_runtime_1.jsx)(DescriptionList_1.default, { items: entry.fields.map(([label, value]) => ({ label, value })), layout: isPhone ? "stacked" : "inline", columns: { base: 1 } }) })), state.status !== "open" ? ((0, jsx_runtime_1.jsx)(RowStatus_1.RowStatus, { item: item, shared: shared, size: size })) : formAction ? ((0, jsx_runtime_1.jsx)(Primitives_1.Box, { maxW: "32.5rem", children: (0, jsx_runtime_1.jsx)(ReasonForm_1.ReasonForm, { entry: entry, action: formAction, labels: labels, size: size, isOffline: isOffline, serverMessage: request ? ((_c = request.message) !== null && _c !== void 0 ? _c : labels.reasonRequiredMessage) : undefined, onCancel: closeForm, onSubmit: (reason) => {
|
|
61
|
+
setAsking(null);
|
|
62
|
+
actions.decide([entry.id], formAction, reason);
|
|
63
|
+
} }) })) : (actionList.length > 0 && ((0, jsx_runtime_1.jsxs)(Primitives_1.Box, { display: "grid", gap: 2, children: [(0, jsx_runtime_1.jsx)(RowActions_1.RowActions, { entry: entry, actionList: actionList, shared: shared, size: size, emphasis: "detail", onAsk: (action) => setAsking({ id: entry.id, action }) }), isOffline && decides && (0, jsx_runtime_1.jsx)(RowActions_1.OfflineNote, { text: labels.offlineMessage })] })))] })), (0, jsx_runtime_1.jsxs)(Primitives_1.Flex, { wrap: "wrap", gap: 2, pt: 4, borderTop: `${borderWidths_1.BORDER_WIDTHS.hairline} solid ${(0, planeStep_1.ruleOn)(colors, plane)}`, children: [!entry.blocked && ((0, jsx_runtime_1.jsx)(Button_1.default, { size: size, variant: decides ? "outline" : "solid", colorScheme: decides ? "gray" : "primary", rightIcon: (0, jsx_runtime_1.jsx)(lucide_react_1.ExternalLink, { size: iconPx, "aria-hidden": "true" }), label: labels.openIn(appName), sx: (0, rowStyles_1.touchTargetFor)(size), "data-testid": (0, rowStyles_1.testIdFor)(entry, "open"), onClick: (event) => actions.open(entry, event) })), isQuiet && features.markRead && entry.isRead !== undefined && ((0, jsx_runtime_1.jsx)(Button_1.default, { size: size, variant: "ghost", colorScheme: "gray", leftIcon: isUnread ? (0, jsx_runtime_1.jsx)(lucide_react_1.MailOpen, { size: iconPx, "aria-hidden": "true" }) : (0, jsx_runtime_1.jsx)(lucide_react_1.Mail, { size: iconPx, "aria-hidden": "true" }), label: isUnread ? labels.markRead : labels.markUnread, isDisabled: isOffline, sx: (0, rowStyles_1.touchTargetFor)(size), "data-testid": (0, rowStyles_1.testIdFor)(entry, "read"), onClick: () => actions.setRead([entry.id], isUnread) })), isQuiet && !entry.blocked && archiveButton, isQuiet && features.restore && state.zone === "archived" && ((0, jsx_runtime_1.jsx)(Button_1.default, { size: size, variant: "ghost", colorScheme: "gray", leftIcon: (0, jsx_runtime_1.jsx)(lucide_react_1.ArchiveRestore, { size: iconPx, "aria-hidden": "true" }), label: labels.restore, isDisabled: isOffline, sx: (0, rowStyles_1.touchTargetFor)(size), "data-testid": (0, rowStyles_1.testIdFor)(entry, "restore"), onClick: () => actions.restore([entry.id]) }))] })] }));
|
|
64
|
+
};
|
|
65
|
+
exports.default = NotificationDetail;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Ref } from "react";
|
|
2
|
+
import type { LiveNotificationEntry } from "../core/NotificationEngineProps";
|
|
3
|
+
/** Density: desktop uses 32px buttons, phone 40px with 44px touch targets and a Back button. */
|
|
4
|
+
export type NotificationDetailVariant = "desktop" | "phone";
|
|
5
|
+
/** One entry in full: facts, the decision, and Open in, read and archive actions. Reads the nearest `NotificationCenterProvider`. */
|
|
6
|
+
export interface NotificationDetailProps {
|
|
7
|
+
/** A live entry from `useNotificationCenter()`. */
|
|
8
|
+
item: LiveNotificationEntry;
|
|
9
|
+
/** Defaults to "desktop". */
|
|
10
|
+
variant?: NotificationDetailVariant;
|
|
11
|
+
/** Shows the Back button on phone. */
|
|
12
|
+
onBack?: () => void;
|
|
13
|
+
/** Ref to the focusable title, so opening an entry can move focus to it. */
|
|
14
|
+
titleRef?: Ref<HTMLHeadingElement>;
|
|
15
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { NotificationRowProps } from "./NotificationRowProps";
|
|
2
|
+
declare const _default: import("react").MemoExoticComponent<({ item, variant, isSelected, isChecked, onCheckedChange, isThreadChild, thread, isThreadOpen, onThreadToggle, initialReasonActionId, onOpen, linkRef, }: NotificationRowProps) => import("react/jsx-runtime").JSX.Element>;
|
|
3
|
+
export default _default;
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
7
|
+
const react_1 = require("react");
|
|
8
|
+
const react_2 = require("@chakra-ui/react");
|
|
9
|
+
const lucide_react_1 = require("lucide-react");
|
|
10
|
+
const Primitives_1 = require("../../Primitives/Primitives");
|
|
11
|
+
const Button_1 = __importDefault(require("../../Button/Button"));
|
|
12
|
+
const Checkbox_1 = __importDefault(require("../../Checkbox/Checkbox"));
|
|
13
|
+
const VisuallyHidden_1 = __importDefault(require("../../VisuallyHidden/VisuallyHidden"));
|
|
14
|
+
const useCustomTheme_1 = require("../../../Theme/useCustomTheme");
|
|
15
|
+
const rowStates_1 = require("../../../Theme/tokens/builders/rowStates");
|
|
16
|
+
const focusRing_styles_1 = require("../../../Theme/chakra/focusRing.styles");
|
|
17
|
+
const motion_1 = require("../../../Theme/chakra/motion");
|
|
18
|
+
const motion_2 = require("../../../Theme/tokens/primitives/motion");
|
|
19
|
+
const radii_1 = require("../../../Theme/tokens/primitives/radii");
|
|
20
|
+
const NotificationCenterProvider_1 = require("../core/NotificationCenterProvider");
|
|
21
|
+
const grouping_1 = require("../core/grouping");
|
|
22
|
+
const category_1 = require("./category");
|
|
23
|
+
const ReasonForm_1 = require("./ReasonForm");
|
|
24
|
+
const RowActions_1 = require("./RowActions");
|
|
25
|
+
const RowQuickActions_1 = require("./RowQuickActions");
|
|
26
|
+
const RowStatus_1 = require("./RowStatus");
|
|
27
|
+
const rowParts_1 = require("./rowParts");
|
|
28
|
+
const rowMenu_1 = require("./rowMenu");
|
|
29
|
+
const rowStyles_1 = require("./rowStyles");
|
|
30
|
+
const COLLAPSE = (0, motion_2.transitionFor)(["grid-template-rows", "opacity"], "base");
|
|
31
|
+
const HIDE = `${COLLAPSE}, visibility ${motion_2.MOTION_MS.base}ms step-end`;
|
|
32
|
+
const SHOW = `${COLLAPSE}, visibility ${motion_2.MOTION_MS.base}ms step-start`;
|
|
33
|
+
const isPlainClick = (event) => event.button === 0 && !event.metaKey && !event.ctrlKey && !event.shiftKey && !event.altKey;
|
|
34
|
+
/** One notification as a list row: lead avatar or tile, title, context, decisions with undo, and hover actions. */
|
|
35
|
+
const NotificationRow = ({ item, variant = "panel", isSelected = false, isChecked = false, onCheckedChange, isThreadChild = false, thread, isThreadOpen = false, onThreadToggle, initialReasonActionId, onOpen, linkRef, }) => {
|
|
36
|
+
var _a;
|
|
37
|
+
const { colors } = (0, useCustomTheme_1.useCustomTheme)();
|
|
38
|
+
const shared = (0, NotificationCenterProvider_1.useNotificationShared)();
|
|
39
|
+
const { labels, format, now, categories, features, isOffline, actions } = shared;
|
|
40
|
+
const { entry, state } = item;
|
|
41
|
+
const [askingId, setAskingId] = (0, react_1.useState)(initialReasonActionId);
|
|
42
|
+
const rows = (0, react_1.useMemo)(() => (0, rowStates_1.listRowBackgrounds)(colors), [colors]);
|
|
43
|
+
const size = rowStyles_1.ROW_BUTTON_SIZE[variant];
|
|
44
|
+
const isPhone = variant === "phone";
|
|
45
|
+
const isUnread = entry.isRead === false;
|
|
46
|
+
const isHidden = state.isHidden;
|
|
47
|
+
const category = (0, category_1.categoryFor)(categories, entry.category, labels.otherCategory);
|
|
48
|
+
const title = (0, grouping_1.plainTitle)(entry.title);
|
|
49
|
+
const actionList = (0, rowMenu_1.visibleActionsFor)(entry, features);
|
|
50
|
+
const days = format.daysSince(entry.createdAt, now);
|
|
51
|
+
const hasDecision = actionList.some((action) => action.href === undefined);
|
|
52
|
+
const waitingDays = state.zone === "needsYou" && hasDecision && days >= rowStyles_1.WAITING_AFTER_DAYS ? days : null;
|
|
53
|
+
const request = state.reasonRequest;
|
|
54
|
+
const formActionId = askingId !== undefined ? askingId : request ? request.actionId : undefined;
|
|
55
|
+
const formAction = state.status === "open" && formActionId !== undefined
|
|
56
|
+
? actionList.find((action) => action.id === formActionId)
|
|
57
|
+
: undefined;
|
|
58
|
+
const isQuiet = state.status === "open" && formAction === undefined;
|
|
59
|
+
const quick = isQuiet ? (0, rowMenu_1.quickActionsFor)(item, (0, rowMenu_1.rowScope)(item, thread, isThreadOpen), shared) : [];
|
|
60
|
+
const rest = thread ? thread.rest.length : 0;
|
|
61
|
+
const resting = isSelected || isChecked ? rows.selected : colors.surfaceRaised;
|
|
62
|
+
const hover = isSelected || isChecked ? rows.selectedActive : rows.active;
|
|
63
|
+
const open = (event) => {
|
|
64
|
+
if (onOpen)
|
|
65
|
+
onOpen(item, event);
|
|
66
|
+
else
|
|
67
|
+
actions.open(entry, event);
|
|
68
|
+
};
|
|
69
|
+
const onLinkClick = (event) => {
|
|
70
|
+
if (entry.href !== undefined) {
|
|
71
|
+
if (!isPlainClick(event))
|
|
72
|
+
return;
|
|
73
|
+
event.preventDefault();
|
|
74
|
+
}
|
|
75
|
+
open(event);
|
|
76
|
+
};
|
|
77
|
+
const closeForm = () => {
|
|
78
|
+
setAskingId(undefined);
|
|
79
|
+
if (request)
|
|
80
|
+
actions.clearReasonRequest(entry.id);
|
|
81
|
+
};
|
|
82
|
+
const sendForm = (action, reason) => {
|
|
83
|
+
setAskingId(undefined);
|
|
84
|
+
actions.decide([entry.id], action, reason);
|
|
85
|
+
};
|
|
86
|
+
const linkSx = {
|
|
87
|
+
flex: 1,
|
|
88
|
+
minW: 0,
|
|
89
|
+
textAlign: "left",
|
|
90
|
+
fontSize: "sm",
|
|
91
|
+
lineHeight: "1.43",
|
|
92
|
+
color: "inherit",
|
|
93
|
+
textDecoration: "none",
|
|
94
|
+
"&::after": {
|
|
95
|
+
content: '""',
|
|
96
|
+
position: "absolute",
|
|
97
|
+
inset: 0,
|
|
98
|
+
zIndex: 1,
|
|
99
|
+
borderRadius: radii_1.RADIUS_ROLE.option,
|
|
100
|
+
},
|
|
101
|
+
"&:focus-visible": { outline: "none" },
|
|
102
|
+
"&:focus-visible::after": {
|
|
103
|
+
boxShadow: (0, focusRing_styles_1.insetFocusRingShadow)(colors),
|
|
104
|
+
outline: "2px solid transparent",
|
|
105
|
+
outlineOffset: "-2px",
|
|
106
|
+
},
|
|
107
|
+
};
|
|
108
|
+
const linkBody = ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [isUnread && (0, jsx_runtime_1.jsx)(VisuallyHidden_1.default, { children: `${labels.unread}. ` }), entry.eyebrow && ((0, jsx_runtime_1.jsxs)(react_2.chakra.span, { fontFamily: "mono", fontSize: "xs", fontWeight: 500, color: colors.textMuted, children: [entry.eyebrow, " "] })), (0, jsx_runtime_1.jsx)(rowParts_1.TitleText, { parts: entry.title, isUnread: isUnread })] }));
|
|
109
|
+
return ((0, jsx_runtime_1.jsx)(react_2.chakra.li, { listStyleType: "none", display: "grid", gridTemplateRows: isHidden ? "0fr" : "1fr", opacity: isHidden ? 0 : 1, visibility: isHidden ? "hidden" : "visible", "aria-hidden": isHidden ? true : undefined, "data-testid": entry.testId, "data-notification-id": entry.id, "data-status": state.status, sx: {
|
|
110
|
+
transition: isHidden ? HIDE : SHOW,
|
|
111
|
+
contentVisibility: "auto",
|
|
112
|
+
containIntrinsicSize: "auto 4.5rem",
|
|
113
|
+
...(0, motion_1.reducedMotionSx)(),
|
|
114
|
+
}, children: (0, jsx_runtime_1.jsx)(Primitives_1.Box, { minH: 0, overflow: "hidden", children: (0, jsx_runtime_1.jsxs)(Primitives_1.Flex, { position: "relative", align: "flex-start", gap: variant === "inbox" ? 2.5 : 3, pt: isPhone ? 3 : 2.5, pb: isPhone ? 3 : 2.5, pr: isPhone ? 2 : 3, pl: isThreadChild ? 16 : 5, borderRadius: radii_1.RADIUS_ROLE.option, bg: resting, sx: {
|
|
115
|
+
[rowParts_1.ROW_PLANE_VAR]: resting,
|
|
116
|
+
transition: (0, motion_2.transitionFor)(["background-color"]),
|
|
117
|
+
"&:hover": { bg: hover, [rowParts_1.ROW_PLANE_VAR]: hover },
|
|
118
|
+
[`&:hover ${RowQuickActions_1.QUICK_SELECTOR}, &:focus-within ${RowQuickActions_1.QUICK_SELECTOR}`]: { opacity: 1 },
|
|
119
|
+
...(0, motion_1.reducedMotionSx)(),
|
|
120
|
+
}, children: [isSelected && ((0, jsx_runtime_1.jsx)(Primitives_1.Box, { position: "absolute", left: 0, top: 2, bottom: 2, w: "0.1875rem", borderRightRadius: "sm", bg: colors.primary[500], "aria-hidden": "true" })), isUnread && ((0, jsx_runtime_1.jsx)(Primitives_1.Box, { position: "absolute", left: isThreadChild ? "3.125rem" : "0.4375rem", top: isThreadChild ? "0.875rem" : isPhone ? "1.125rem" : "1rem", boxSize: "0.5rem", borderRadius: "full", bg: colors.accentText, "aria-hidden": "true", "data-testid": (0, rowStyles_1.testIdFor)(entry, "dot") })), onCheckedChange && ((0, jsx_runtime_1.jsx)(Primitives_1.Box, { position: "relative", zIndex: 2, mt: 1, sx: rowStyles_1.CHECKBOX_TOUCH_TARGET_SX, children: (0, jsx_runtime_1.jsx)(Checkbox_1.default, { isChecked: isChecked, "aria-label": labels.select(title), onChange: (event) => onCheckedChange(item, event.target.checked) }) })), (0, jsx_runtime_1.jsx)(rowParts_1.RowLeading, { entry: entry, category: category, size: isThreadChild ? "xs" : isPhone ? "md" : "sm" }), (0, jsx_runtime_1.jsxs)(Primitives_1.Box, { flex: 1, minW: 0, children: [(0, jsx_runtime_1.jsxs)(Primitives_1.Flex, { align: "baseline", gap: 2, children: [entry.href !== undefined ? ((0, jsx_runtime_1.jsx)(react_2.chakra.a, { ref: linkRef, href: entry.href, "aria-current": isSelected ? "true" : undefined, "data-testid": (0, rowStyles_1.testIdFor)(entry, "link"), onClick: onLinkClick, sx: linkSx, children: linkBody })) : ((0, jsx_runtime_1.jsx)(react_2.chakra.button, { ref: linkRef, type: "button", "aria-current": isSelected ? "true" : undefined, "data-testid": (0, rowStyles_1.testIdFor)(entry, "link"), onClick: onLinkClick, sx: linkSx, children: linkBody })), (0, jsx_runtime_1.jsx)(rowParts_1.RowTime, { at: entry.createdAt, now: now, format: format })] }), (0, jsx_runtime_1.jsx)(rowParts_1.RowContext, { entry: entry, waitingDays: waitingDays, labels: labels }), entry.preview && (0, jsx_runtime_1.jsx)(rowParts_1.RowPreview, { text: entry.preview, isLarge: isPhone }), entry.change && ((0, jsx_runtime_1.jsx)(Primitives_1.Box, { mt: 1.5, children: (0, jsx_runtime_1.jsx)(rowParts_1.ChangeChips, { change: entry.change, labels: labels }) })), formAction ? ((0, jsx_runtime_1.jsx)(ReasonForm_1.ReasonForm, { entry: entry, action: formAction, labels: labels, size: size, isOffline: isOffline, serverMessage: request ? ((_a = request.message) !== null && _a !== void 0 ? _a : labels.reasonRequiredMessage) : undefined, onCancel: closeForm, onSubmit: (reason) => sendForm(formAction, reason) })) : (state.status === "open" &&
|
|
121
|
+
actionList.length > 0 && ((0, jsx_runtime_1.jsx)(RowActions_1.RowActions, { entry: entry, actionList: actionList, shared: shared, size: size, emphasis: "row", onAsk: (action) => setAskingId(action.id) }))), (0, jsx_runtime_1.jsx)(RowStatus_1.RowStatus, { item: item, shared: shared, size: size }), thread && rest > 0 && onThreadToggle && ((0, jsx_runtime_1.jsx)(Primitives_1.Box, { position: "relative", zIndex: 2, mt: 2, children: (0, jsx_runtime_1.jsx)(Button_1.default, { size: "xs", variant: "link", leftIcon: isThreadOpen ? ((0, jsx_runtime_1.jsx)(lucide_react_1.ChevronDown, { size: (0, rowStyles_1.iconSizeFor)("xs"), "aria-hidden": "true" })) : ((0, jsx_runtime_1.jsx)(lucide_react_1.ChevronRight, { size: (0, rowStyles_1.iconSizeFor)("xs"), "aria-hidden": "true" })), label: isThreadOpen ? labels.threadHide(rest) : labels.threadShow(rest), "aria-expanded": isThreadOpen, "data-testid": (0, rowStyles_1.testIdFor)(entry, "thread"), onClick: () => onThreadToggle(thread) }) }))] }), quick.length > 0 &&
|
|
122
|
+
(isPhone ? ((0, jsx_runtime_1.jsx)(RowQuickActions_1.RowMoreMenu, { entry: entry, items: quick, isOffline: isOffline, label: labels.moreActions(title) })) : ((0, jsx_runtime_1.jsx)(RowQuickActions_1.RowQuickActions, { entry: entry, items: quick, isOffline: isOffline })))] }) }) }));
|
|
123
|
+
};
|
|
124
|
+
exports.default = (0, react_1.memo)(NotificationRow);
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { KeyboardEvent, MouseEvent, RefCallback } from "react";
|
|
2
|
+
import type { LiveNotificationEntry, NotificationThread } from "../core/NotificationEngineProps";
|
|
3
|
+
/** Density: panel rows carry 24px buttons, inbox rows 32px, phone rows 40px with 44px touch targets. */
|
|
4
|
+
export type NotificationRowVariant = "panel" | "inbox" | "phone";
|
|
5
|
+
/** The click or key press that opened a row. */
|
|
6
|
+
export type NotificationRowOpenEvent = MouseEvent<HTMLElement> | KeyboardEvent<HTMLElement>;
|
|
7
|
+
/** One entry as a list row; reads labels and actions from the nearest `NotificationCenterProvider`. Render it inside a `ul`. */
|
|
8
|
+
export interface NotificationRowProps {
|
|
9
|
+
/** A live entry from `useNotificationCenter().lists`; rows skip re-rendering while it is unchanged. */
|
|
10
|
+
item: LiveNotificationEntry;
|
|
11
|
+
/** Defaults to "panel". */
|
|
12
|
+
variant?: NotificationRowVariant;
|
|
13
|
+
/** The entry shown in the reading pane: tinted, with a rail and `aria-current` on its link. */
|
|
14
|
+
isSelected?: boolean;
|
|
15
|
+
/** The bulk-selection checkbox state; only shown with `onCheckedChange`. */
|
|
16
|
+
isChecked?: boolean;
|
|
17
|
+
/** Shows the selection checkbox; pass one stable function for every row. */
|
|
18
|
+
onCheckedChange?: (item: LiveNotificationEntry, checked: boolean) => void;
|
|
19
|
+
/** An older entry inside an open thread: indented, with a 24px avatar. */
|
|
20
|
+
isThreadChild?: boolean;
|
|
21
|
+
/** Set on a thread's lead row; while closed, its read and archive buttons cover the whole thread. */
|
|
22
|
+
thread?: NotificationThread;
|
|
23
|
+
/** Whether the thread's older entries are showing. */
|
|
24
|
+
isThreadOpen?: boolean;
|
|
25
|
+
/** Shows the thread toggle; pass one stable function for every row. */
|
|
26
|
+
onThreadToggle?: (thread: NotificationThread) => void;
|
|
27
|
+
/** Opens the reason form for this action on mount, e.g. from a keyboard shortcut. */
|
|
28
|
+
initialReasonActionId?: string;
|
|
29
|
+
/** Replaces opening through `onOpen`, e.g. to show the entry in a reading pane; modifier clicks still open a new tab. */
|
|
30
|
+
onOpen?: (item: LiveNotificationEntry, event: NotificationRowOpenEvent) => void;
|
|
31
|
+
/** Callback ref to the row's link (an `a`, or a `button` without `href`), for roving focus in a list. */
|
|
32
|
+
linkRef?: RefCallback<HTMLElement>;
|
|
33
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { NotificationAction, NotificationEntry, NotificationLabels } from "../core/NotificationSourceProps";
|
|
2
|
+
import { type RowButtonSize } from "./rowStyles";
|
|
3
|
+
interface ReasonFormProps {
|
|
4
|
+
entry: NotificationEntry;
|
|
5
|
+
action: NotificationAction;
|
|
6
|
+
labels: NotificationLabels;
|
|
7
|
+
size: RowButtonSize;
|
|
8
|
+
isOffline: boolean;
|
|
9
|
+
serverMessage?: string;
|
|
10
|
+
onCancel: () => void;
|
|
11
|
+
onSubmit: (reason: string) => void;
|
|
12
|
+
}
|
|
13
|
+
export declare const ReasonForm: ({ entry, action, labels, size, isOffline, serverMessage, onCancel, onSubmit, }: ReasonFormProps) => import("react/jsx-runtime").JSX.Element;
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.ReasonForm = void 0;
|
|
7
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
8
|
+
const react_1 = require("react");
|
|
9
|
+
const react_2 = require("@chakra-ui/react");
|
|
10
|
+
const lucide_react_1 = require("lucide-react");
|
|
11
|
+
const Primitives_1 = require("../../Primitives/Primitives");
|
|
12
|
+
const Button_1 = __importDefault(require("../../Button/Button"));
|
|
13
|
+
const InputTextArea_1 = __importDefault(require("../../InputTextArea/InputTextArea"));
|
|
14
|
+
const Kbd_1 = __importDefault(require("../../Kbd/Kbd"));
|
|
15
|
+
const useCustomTheme_1 = require("../../../Theme/useCustomTheme");
|
|
16
|
+
const rowStyles_1 = require("./rowStyles");
|
|
17
|
+
const ReasonForm = ({ entry, action, labels, size, isOffline, serverMessage, onCancel, onSubmit, }) => {
|
|
18
|
+
var _a;
|
|
19
|
+
const { colors } = (0, useCustomTheme_1.useCustomTheme)();
|
|
20
|
+
const id = (0, react_1.useId)();
|
|
21
|
+
const hintId = `${id}-hint`;
|
|
22
|
+
const field = (0, react_1.useRef)(null);
|
|
23
|
+
const [text, setText] = (0, react_1.useState)("");
|
|
24
|
+
const [touched, setTouched] = (0, react_1.useState)(false);
|
|
25
|
+
const isServerRequest = serverMessage !== undefined;
|
|
26
|
+
const isRequired = action.reason === "required" || isServerRequest;
|
|
27
|
+
const isNegative = action.intent === "negative";
|
|
28
|
+
const isMissing = isRequired && !text.trim();
|
|
29
|
+
const missingMessage = isNegative ? labels.reasonMissingNegative : labels.reasonMissing;
|
|
30
|
+
const errorText = touched && isMissing ? missingMessage : isServerRequest && !text.trim() ? serverMessage : undefined;
|
|
31
|
+
(0, react_1.useEffect)(() => {
|
|
32
|
+
if (field.current)
|
|
33
|
+
field.current.focus();
|
|
34
|
+
}, []);
|
|
35
|
+
const submit = () => {
|
|
36
|
+
setTouched(true);
|
|
37
|
+
if (isMissing) {
|
|
38
|
+
if (field.current)
|
|
39
|
+
field.current.focus();
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
onSubmit(text.trim());
|
|
43
|
+
};
|
|
44
|
+
const onKeyDown = (event) => {
|
|
45
|
+
if (event.key === "Escape") {
|
|
46
|
+
event.stopPropagation();
|
|
47
|
+
onCancel();
|
|
48
|
+
}
|
|
49
|
+
else if (event.key === "Enter" && (event.metaKey || event.ctrlKey)) {
|
|
50
|
+
event.preventDefault();
|
|
51
|
+
submit();
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
return ((0, jsx_runtime_1.jsxs)(react_2.chakra.form, { noValidate: true, position: "relative", zIndex: 2, display: "grid", gap: 1.5, mt: 2.5, onSubmit: (event) => {
|
|
55
|
+
event.preventDefault();
|
|
56
|
+
submit();
|
|
57
|
+
}, children: [(0, jsx_runtime_1.jsxs)(react_2.chakra.label, { htmlFor: id, fontSize: "xs-plus", fontWeight: 500, color: colors.text[700], children: [(_a = action.reasonLabel) !== null && _a !== void 0 ? _a : labels.reasonLabel, !isRequired && ((0, jsx_runtime_1.jsxs)(react_2.chakra.span, { fontWeight: 400, color: colors.textMuted, children: [" ", labels.reasonOptional] }))] }), (0, jsx_runtime_1.jsx)(InputTextArea_1.default, { ref: field, id: id, rows: 2, size: size === "md" ? "md" : "sm", resize: "vertical", value: text, error: errorText !== undefined, "aria-describedby": hintId, placeholder: isNegative ? labels.reasonPlaceholder : undefined, onChange: (event) => setText(event.target.value), onKeyDown: onKeyDown }), (0, jsx_runtime_1.jsx)(Primitives_1.Flex, { id: hintId, align: "center", wrap: "wrap", gap: 1, fontSize: "xs", fontWeight: errorText !== undefined ? 500 : 400, color: errorText !== undefined ? colors.semanticText.error : colors.textMuted, children: errorText !== undefined ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(Primitives_1.Icon, { as: lucide_react_1.CircleAlert, boxSize: "0.75rem", "aria-hidden": "true" }), errorText] })) : ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(Kbd_1.default, { size: "xs", children: labels.keyCtrl }), (0, jsx_runtime_1.jsx)(Kbd_1.default, { size: "xs", children: labels.keyEnter }), (0, jsx_runtime_1.jsxs)("span", { children: [labels.toSend, " \u00B7"] }), (0, jsx_runtime_1.jsx)(Kbd_1.default, { size: "xs", children: labels.keyEsc }), (0, jsx_runtime_1.jsx)("span", { children: labels.toCancel })] })) }), (0, jsx_runtime_1.jsxs)(Primitives_1.Flex, { justify: "flex-end", gap: 2, children: [(0, jsx_runtime_1.jsx)(Button_1.default, { size: size, variant: "ghost", colorScheme: "gray", label: labels.cancel, sx: (0, rowStyles_1.touchTargetFor)(size), onClick: onCancel }), (0, jsx_runtime_1.jsx)(Button_1.default, { type: "submit", size: size, variant: "solid", colorScheme: isNegative ? "red" : "primary", label: action.label, "aria-label": labels.actionName(action.label, entry.subject), isDisabled: isOffline, sx: (0, rowStyles_1.touchTargetFor)(size), "data-testid": entry.testId ? `${entry.testId}-${action.id}-send` : undefined })] })] }));
|
|
58
|
+
};
|
|
59
|
+
exports.ReasonForm = ReasonForm;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { NotificationAction, NotificationEntry } from "../core/NotificationSourceProps";
|
|
2
|
+
import type { NotificationShared } from "../core/useNotificationEngine";
|
|
3
|
+
import { type RowButtonSize } from "./rowStyles";
|
|
4
|
+
interface RowActionsProps {
|
|
5
|
+
entry: NotificationEntry;
|
|
6
|
+
actionList: NotificationAction[];
|
|
7
|
+
shared: NotificationShared;
|
|
8
|
+
size: RowButtonSize;
|
|
9
|
+
emphasis: "row" | "detail";
|
|
10
|
+
onAsk: (action: NotificationAction) => void;
|
|
11
|
+
}
|
|
12
|
+
export declare const OfflineNote: ({ text }: {
|
|
13
|
+
text: string;
|
|
14
|
+
}) => import("react/jsx-runtime").JSX.Element;
|
|
15
|
+
export declare const RowActions: ({ entry, actionList, shared, size, emphasis, onAsk }: RowActionsProps) => import("react/jsx-runtime").JSX.Element;
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.RowActions = exports.OfflineNote = void 0;
|
|
7
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
8
|
+
const lucide_react_1 = require("lucide-react");
|
|
9
|
+
const Primitives_1 = require("../../Primitives/Primitives");
|
|
10
|
+
const Button_1 = __importDefault(require("../../Button/Button"));
|
|
11
|
+
const useCustomTheme_1 = require("../../../Theme/useCustomTheme");
|
|
12
|
+
const rowMenu_1 = require("./rowMenu");
|
|
13
|
+
const rowStyles_1 = require("./rowStyles");
|
|
14
|
+
const OfflineNote = ({ text }) => {
|
|
15
|
+
const { colors } = (0, useCustomTheme_1.useCustomTheme)();
|
|
16
|
+
return ((0, jsx_runtime_1.jsxs)(Primitives_1.Flex, { as: "span", display: "inline-flex", align: "center", gap: 1, fontSize: "xs", color: colors.textMuted, children: [(0, jsx_runtime_1.jsx)(Primitives_1.Icon, { as: lucide_react_1.WifiOff, boxSize: "0.75rem", "aria-hidden": "true" }), text] }));
|
|
17
|
+
};
|
|
18
|
+
exports.OfflineNote = OfflineNote;
|
|
19
|
+
const RowActions = ({ entry, actionList, shared, size, emphasis, onAsk }) => {
|
|
20
|
+
const { labels, actions, isOffline } = shared;
|
|
21
|
+
const iconPx = (0, rowStyles_1.iconSizeFor)(size);
|
|
22
|
+
return ((0, jsx_runtime_1.jsxs)(Primitives_1.Flex, { position: "relative", zIndex: 2, wrap: "wrap", align: "center", gap: 2, mt: emphasis === "row" ? 2.5 : 0, children: [actionList.map((action) => {
|
|
23
|
+
const isLink = !(0, rowMenu_1.isDecision)(action);
|
|
24
|
+
const isStrong = emphasis === "detail" && (action.intent === "positive" || action.intent === "primary");
|
|
25
|
+
return ((0, jsx_runtime_1.jsx)(Button_1.default, { size: size, variant: isStrong ? "solid" : "outline", colorScheme: isStrong ? "primary" : "gray", label: action.label, "aria-label": labels.actionName(action.label, entry.subject), leftIcon: !isLink && action.intent === "positive" ? (0, jsx_runtime_1.jsx)(lucide_react_1.Check, { size: iconPx, "aria-hidden": "true" }) : undefined, rightIcon: isLink ? (0, jsx_runtime_1.jsx)(lucide_react_1.ChevronRight, { size: iconPx, "aria-hidden": "true" }) : undefined, isDisabled: isOffline && !isLink, sx: (0, rowStyles_1.touchTargetFor)(size), "data-testid": (0, rowStyles_1.testIdFor)(entry, action.id), onClick: (event) => {
|
|
26
|
+
event.stopPropagation();
|
|
27
|
+
if (isLink)
|
|
28
|
+
actions.open(entry, event, action);
|
|
29
|
+
else if (action.reason)
|
|
30
|
+
onAsk(action);
|
|
31
|
+
else
|
|
32
|
+
actions.decide([entry.id], action);
|
|
33
|
+
} }, action.id));
|
|
34
|
+
}), isOffline && actionList.some(rowMenu_1.isDecision) && (0, jsx_runtime_1.jsx)(exports.OfflineNote, { text: labels.offlineNote })] }));
|
|
35
|
+
};
|
|
36
|
+
exports.RowActions = RowActions;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { NotificationEntry } from "../core/NotificationSourceProps";
|
|
2
|
+
import type { RowQuickAction } from "./rowMenu";
|
|
3
|
+
export declare const QUICK_SELECTOR = "[data-nc-quick]";
|
|
4
|
+
interface QuickActionsProps {
|
|
5
|
+
entry: NotificationEntry;
|
|
6
|
+
items: RowQuickAction[];
|
|
7
|
+
isOffline: boolean;
|
|
8
|
+
}
|
|
9
|
+
export declare const RowQuickActions: ({ entry, items, isOffline }: QuickActionsProps) => import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
interface MoreMenuProps {
|
|
11
|
+
entry: NotificationEntry;
|
|
12
|
+
items: RowQuickAction[];
|
|
13
|
+
isOffline: boolean;
|
|
14
|
+
label: string;
|
|
15
|
+
}
|
|
16
|
+
export declare const RowMoreMenu: ({ entry, items, isOffline, label }: MoreMenuProps) => import("react/jsx-runtime").JSX.Element;
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.RowMoreMenu = exports.RowQuickActions = exports.QUICK_SELECTOR = void 0;
|
|
7
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
8
|
+
const lucide_react_1 = require("lucide-react");
|
|
9
|
+
const Primitives_1 = require("../../Primitives/Primitives");
|
|
10
|
+
const IconButton_1 = __importDefault(require("../../IconButton/IconButton"));
|
|
11
|
+
const ToolTip_1 = __importDefault(require("../../ToolTip/ToolTip"));
|
|
12
|
+
const DropDown_1 = __importDefault(require("../../Dropdown/DropDown"));
|
|
13
|
+
const useCustomTheme_1 = require("../../../Theme/useCustomTheme");
|
|
14
|
+
const borderWidths_1 = require("../../../Theme/tokens/primitives/borderWidths");
|
|
15
|
+
const radii_1 = require("../../../Theme/tokens/primitives/radii");
|
|
16
|
+
const motion_1 = require("../../../Theme/tokens/primitives/motion");
|
|
17
|
+
const motion_2 = require("../../../Theme/chakra/motion");
|
|
18
|
+
const rowStyles_1 = require("./rowStyles");
|
|
19
|
+
exports.QUICK_SELECTOR = "[data-nc-quick]";
|
|
20
|
+
const RowQuickActions = ({ entry, items, isOffline }) => {
|
|
21
|
+
const { colors } = (0, useCustomTheme_1.useCustomTheme)();
|
|
22
|
+
return ((0, jsx_runtime_1.jsx)(Primitives_1.Flex, { "data-nc-quick": "", position: "absolute", top: "0.375rem", right: "0.375rem", zIndex: 2, gap: "0.125rem", p: "0.125rem", borderRadius: radii_1.RADIUS_ROLE.control, bg: colors.surfaceRaised, border: `${borderWidths_1.BORDER_WIDTHS.hairline} solid ${colors.boxborder[200]}`, boxShadow: "sm", opacity: 0, sx: {
|
|
23
|
+
transition: (0, motion_1.transitionFor)(["opacity"]),
|
|
24
|
+
"@media (hover: none)": {
|
|
25
|
+
position: "relative",
|
|
26
|
+
top: "auto",
|
|
27
|
+
right: "auto",
|
|
28
|
+
opacity: 1,
|
|
29
|
+
alignSelf: "flex-start",
|
|
30
|
+
border: "none",
|
|
31
|
+
boxShadow: "none",
|
|
32
|
+
bg: "transparent",
|
|
33
|
+
},
|
|
34
|
+
...(0, motion_2.reducedMotionSx)(),
|
|
35
|
+
}, children: items.map((item) => ((0, jsx_runtime_1.jsx)(ToolTip_1.default, { label: item.label, children: (0, jsx_runtime_1.jsx)(IconButton_1.default, { size: "xs", variant: "ghost", colorScheme: "gray", "aria-label": item.label, icon: (0, jsx_runtime_1.jsx)(Primitives_1.Icon, { as: item.icon, boxSize: `${(0, rowStyles_1.iconSizeFor)("xs") / 16}rem`, "aria-hidden": "true" }), isDisabled: isOffline, "data-testid": (0, rowStyles_1.testIdFor)(entry, item.id), onClick: (event) => {
|
|
36
|
+
event.stopPropagation();
|
|
37
|
+
item.run();
|
|
38
|
+
} }) }, item.id))) }));
|
|
39
|
+
};
|
|
40
|
+
exports.RowQuickActions = RowQuickActions;
|
|
41
|
+
const RowMoreMenu = ({ entry, items, isOffline, label }) => {
|
|
42
|
+
const trigger = {
|
|
43
|
+
variant: "ghost",
|
|
44
|
+
colorScheme: "gray",
|
|
45
|
+
px: 0,
|
|
46
|
+
minW: "2.5rem",
|
|
47
|
+
isDisabled: isOffline,
|
|
48
|
+
sx: rowStyles_1.TOUCH_TARGET_SX,
|
|
49
|
+
"data-testid": (0, rowStyles_1.testIdFor)(entry, "more"),
|
|
50
|
+
};
|
|
51
|
+
return ((0, jsx_runtime_1.jsx)(Primitives_1.Flex, { position: "relative", zIndex: 2, flexShrink: 0, mt: "-0.5rem", mr: "-0.5rem", children: (0, jsx_runtime_1.jsx)(DropDown_1.default, { size: "md", options: items.map((item) => ({ id: item.id, label: item.label, image: item.icon })), handleOptionSelect: (id) => {
|
|
52
|
+
const hit = items.find((item) => item.id === id);
|
|
53
|
+
if (hit)
|
|
54
|
+
hit.run();
|
|
55
|
+
}, DropdownIcon: (0, jsx_runtime_1.jsx)(lucide_react_1.Ellipsis, { size: (0, rowStyles_1.iconSizeFor)("md"), "aria-hidden": "true" }), isVisibleIconShow: false, ariaLabel: label, buttonProps: trigger }) }));
|
|
56
|
+
};
|
|
57
|
+
exports.RowMoreMenu = RowMoreMenu;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { LiveNotificationEntry } from "../core/NotificationEngineProps";
|
|
2
|
+
import type { NotificationShared } from "../core/useNotificationEngine";
|
|
3
|
+
import { type RowButtonSize } from "./rowStyles";
|
|
4
|
+
interface RowStatusProps {
|
|
5
|
+
item: LiveNotificationEntry;
|
|
6
|
+
shared: NotificationShared;
|
|
7
|
+
size: RowButtonSize;
|
|
8
|
+
}
|
|
9
|
+
export declare const RowStatus: ({ item, shared, size }: RowStatusProps) => import("react/jsx-runtime").JSX.Element | null;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.RowStatus = void 0;
|
|
7
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
8
|
+
const react_1 = require("@chakra-ui/react");
|
|
9
|
+
const lucide_react_1 = require("lucide-react");
|
|
10
|
+
const Primitives_1 = require("../../Primitives/Primitives");
|
|
11
|
+
const Button_1 = __importDefault(require("../../Button/Button"));
|
|
12
|
+
const Spinner_1 = __importDefault(require("../../Spinner/Spinner"));
|
|
13
|
+
const useCustomTheme_1 = require("../../../Theme/useCustomTheme");
|
|
14
|
+
const tone_1 = require("../../../Theme/tokens/builders/tone");
|
|
15
|
+
const radii_1 = require("../../../Theme/tokens/primitives/radii");
|
|
16
|
+
const rowStyles_1 = require("./rowStyles");
|
|
17
|
+
const StatusLine = ({ tone, icon, role, children }) => {
|
|
18
|
+
const { colors } = (0, useCustomTheme_1.useCustomTheme)();
|
|
19
|
+
const soft = (0, tone_1.resolveSoftTone)(colors, (0, tone_1.toneScale)(colors, tone), colors.surfaceRaised);
|
|
20
|
+
return ((0, jsx_runtime_1.jsxs)(Primitives_1.Flex, { role: role, position: "relative", zIndex: 2, wrap: "wrap", align: "center", columnGap: 2, rowGap: 1.5, mt: 2.5, px: 2.5, py: 1.5, borderRadius: radii_1.RADIUS_ROLE.control, bg: soft.bg, color: soft.fg, fontSize: "xs-plus", lineHeight: "1.45", onClick: (event) => event.stopPropagation(), children: [icon, children] }));
|
|
21
|
+
};
|
|
22
|
+
const glyph = (as) => (0, jsx_runtime_1.jsx)(Primitives_1.Icon, { as: as, boxSize: "0.875rem", flexShrink: 0, "aria-hidden": "true" });
|
|
23
|
+
const LINK_SX = { color: "inherit", fontWeight: 600 };
|
|
24
|
+
const RowStatus = ({ item, shared, size }) => {
|
|
25
|
+
const { entry, state } = item;
|
|
26
|
+
const { labels, actions, isOffline } = shared;
|
|
27
|
+
const { decision, error } = state;
|
|
28
|
+
if (!decision || state.status === "open")
|
|
29
|
+
return null;
|
|
30
|
+
if (state.status === "failed") {
|
|
31
|
+
return ((0, jsx_runtime_1.jsxs)(StatusLine, { tone: "error", icon: glyph(lucide_react_1.CircleAlert), role: "alert", children: [(0, jsx_runtime_1.jsxs)(react_1.chakra.span, { fontWeight: 500, children: [(0, jsx_runtime_1.jsx)(react_1.chakra.strong, { fontWeight: 600, children: labels.couldNot(decision.label) }), " ", error && error.message ? error.message : labels.failedMessage] }), (0, jsx_runtime_1.jsx)(Button_1.default, { size: size, variant: "outline", colorScheme: "gray", leftIcon: (0, jsx_runtime_1.jsx)(lucide_react_1.RefreshCw, { size: (0, rowStyles_1.iconSizeFor)(size), "aria-hidden": "true" }), label: labels.retry, "aria-label": labels.actionName(labels.retry, entry.subject), isDisabled: isOffline, ml: "auto", sx: (0, rowStyles_1.touchTargetFor)(size), "data-testid": (0, rowStyles_1.testIdFor)(entry, "retry"), onClick: () => actions.retry(entry.id) })] }));
|
|
32
|
+
}
|
|
33
|
+
if (state.status === "denied") {
|
|
34
|
+
const isForbidden = error !== undefined && error.kind === "forbidden";
|
|
35
|
+
const fallback = isForbidden ? labels.forbiddenMessage : labels.conflictMessage;
|
|
36
|
+
return ((0, jsx_runtime_1.jsxs)(StatusLine, { tone: "info", icon: glyph(isForbidden ? lucide_react_1.Lock : lucide_react_1.Info), children: [(0, jsx_runtime_1.jsx)(react_1.chakra.span, { fontWeight: 500, children: error && error.message ? error.message : fallback }), (0, jsx_runtime_1.jsx)(Button_1.default, { size: "xs", variant: "link", label: labels.dismiss, "aria-label": labels.actionName(labels.dismiss, entry.subject), sx: LINK_SX, "data-testid": (0, rowStyles_1.testIdFor)(entry, "dismiss"), onClick: () => actions.dismiss(entry.id) })] }));
|
|
37
|
+
}
|
|
38
|
+
const isNegative = decision.intent === "negative";
|
|
39
|
+
const isSending = state.status === "sending";
|
|
40
|
+
return ((0, jsx_runtime_1.jsxs)(StatusLine, { tone: isNegative ? "neutral" : "success", icon: isSending ? (0, jsx_runtime_1.jsx)(Spinner_1.default, { size: "xs", color: "currentColor", "aria-hidden": "true" }) : glyph(isNegative ? lucide_react_1.CircleX : lucide_react_1.CircleCheck), children: [(0, jsx_runtime_1.jsx)(react_1.chakra.span, { fontWeight: 500, children: isSending ? labels.sending : decision.doneLabel }), state.status === "undo" && ((0, jsx_runtime_1.jsx)(Button_1.default, { size: "xs", variant: "link", label: labels.undo, "aria-label": labels.actionName(labels.undo, entry.subject), sx: LINK_SX, "data-testid": (0, rowStyles_1.testIdFor)(entry, "undo"), onClick: () => actions.undo(entry.id) })), decision.reason && ((0, jsx_runtime_1.jsx)(react_1.chakra.span, { flexBasis: "100%", pl: "1.375rem", fontStyle: "italic", opacity: 0.85, children: labels.reasonQuote(decision.reason) }))] }));
|
|
41
|
+
};
|
|
42
|
+
exports.RowStatus = RowStatus;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { NotificationCategories, NotificationCategory } from "../core/NotificationSourceProps";
|
|
2
|
+
import type { Tone } from "../../../Theme/tokens/builders/tone";
|
|
3
|
+
export interface ResolvedCategory {
|
|
4
|
+
label: string;
|
|
5
|
+
icon: NotificationCategory["icon"];
|
|
6
|
+
tone: Tone;
|
|
7
|
+
}
|
|
8
|
+
export declare const categoryFor: (categories: NotificationCategories, key: string, otherLabel: string) => ResolvedCategory;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.categoryFor = void 0;
|
|
4
|
+
const lucide_react_1 = require("lucide-react");
|
|
5
|
+
const grouping_1 = require("../core/grouping");
|
|
6
|
+
const categoryFor = (categories, key, otherLabel) => {
|
|
7
|
+
var _a;
|
|
8
|
+
const category = (0, grouping_1.findCategory)(categories, key);
|
|
9
|
+
if (!category)
|
|
10
|
+
return { label: otherLabel, icon: lucide_react_1.Bell, tone: "neutral" };
|
|
11
|
+
return { label: category.label, icon: category.icon, tone: (_a = category.tone) !== null && _a !== void 0 ? _a : "neutral" };
|
|
12
|
+
};
|
|
13
|
+
exports.categoryFor = categoryFor;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ElementType } from "react";
|
|
2
|
+
import type { NotificationAction, NotificationEntry } from "../core/NotificationSourceProps";
|
|
3
|
+
import type { LiveNotificationEntry, NotificationFeatures, NotificationThread } from "../core/NotificationEngineProps";
|
|
4
|
+
import type { NotificationShared } from "../core/useNotificationEngine";
|
|
5
|
+
export interface RowQuickAction {
|
|
6
|
+
id: string;
|
|
7
|
+
label: string;
|
|
8
|
+
icon: ElementType;
|
|
9
|
+
run: () => void;
|
|
10
|
+
}
|
|
11
|
+
export declare const rowScope: (item: LiveNotificationEntry, thread: NotificationThread | undefined, isThreadOpen: boolean) => LiveNotificationEntry[];
|
|
12
|
+
export declare const quickActionsFor: (item: LiveNotificationEntry, scope: LiveNotificationEntry[], shared: NotificationShared) => RowQuickAction[];
|
|
13
|
+
export declare const visibleActionsFor: (entry: NotificationEntry, features: NotificationFeatures) => NotificationAction[];
|
|
14
|
+
export declare const isDecision: (action: NotificationAction) => boolean;
|