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,35 @@
|
|
|
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.PanelRows = void 0;
|
|
7
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
8
|
+
const react_1 = require("react");
|
|
9
|
+
const Primitives_1 = require("../../Primitives/Primitives");
|
|
10
|
+
const useCustomTheme_1 = require("../../../Theme/useCustomTheme");
|
|
11
|
+
const NotificationRow_1 = __importDefault(require("../row/NotificationRow"));
|
|
12
|
+
const PanelRows = ({ groups, variant, format, onOpenItem }) => {
|
|
13
|
+
const { colors } = (0, useCustomTheme_1.useCustomTheme)();
|
|
14
|
+
const idPrefix = (0, react_1.useId)();
|
|
15
|
+
const [openThreads, setOpenThreads] = (0, react_1.useState)(() => new Set());
|
|
16
|
+
const toggleThread = (0, react_1.useCallback)((thread) => {
|
|
17
|
+
setOpenThreads((current) => {
|
|
18
|
+
const next = new Set(current);
|
|
19
|
+
if (next.has(thread.key))
|
|
20
|
+
next.delete(thread.key);
|
|
21
|
+
else
|
|
22
|
+
next.add(thread.key);
|
|
23
|
+
return next;
|
|
24
|
+
});
|
|
25
|
+
}, []);
|
|
26
|
+
return ((0, jsx_runtime_1.jsx)(Primitives_1.Box, { pb: 2, children: groups.map((group) => {
|
|
27
|
+
const headingId = `${idPrefix}-${group.key}`;
|
|
28
|
+
return ((0, jsx_runtime_1.jsxs)(Primitives_1.Box, { as: "section", "aria-labelledby": group.label === null ? undefined : headingId, children: [group.label !== null && ((0, jsx_runtime_1.jsxs)(Primitives_1.Heading, { as: "h3", id: headingId, position: "sticky", top: 0, zIndex: 3, display: "flex", alignItems: "center", gap: 1.5, px: 4, pt: 3, pb: 1.5, bg: colors.surfaceRaised, color: colors.textMuted, fontSize: "0.6875rem", fontWeight: 600, letterSpacing: "0.06em", textTransform: "uppercase", children: [(0, jsx_runtime_1.jsx)("span", { children: group.label }), group.count > 0 && (0, jsx_runtime_1.jsx)("span", { children: format.number(group.count) })] })), (0, jsx_runtime_1.jsx)(Primitives_1.Box, { as: "ul", role: "list", listStyleType: "none", m: 0, px: "6px", display: "grid", gap: "2px", children: group.threads.map((thread) => {
|
|
29
|
+
const isOpen = openThreads.has(thread.key);
|
|
30
|
+
return ((0, jsx_runtime_1.jsxs)(react_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(NotificationRow_1.default, { item: thread.lead, variant: variant, thread: thread, isThreadOpen: isOpen, onThreadToggle: toggleThread, onOpen: onOpenItem }), isOpen &&
|
|
31
|
+
thread.rest.map((item) => ((0, jsx_runtime_1.jsx)(NotificationRow_1.default, { item: item, variant: variant, isThreadChild: true, onOpen: onOpenItem }, item.entry.id)))] }, thread.key));
|
|
32
|
+
}) })] }, group.key));
|
|
33
|
+
}) }));
|
|
34
|
+
};
|
|
35
|
+
exports.PanelRows = PanelRows;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { NotificationCenterLabels, NotificationCenterTab } from "./NotificationCenterProps";
|
|
2
|
+
export declare const PanelSkeleton: ({ isSheet }: {
|
|
3
|
+
isSheet: boolean;
|
|
4
|
+
}) => import("react/jsx-runtime").JSX.Element;
|
|
5
|
+
interface StateProps {
|
|
6
|
+
labels: NotificationCenterLabels;
|
|
7
|
+
}
|
|
8
|
+
export declare const PanelError: ({ labels, onRetry }: StateProps & {
|
|
9
|
+
onRetry: () => void;
|
|
10
|
+
}) => import("react/jsx-runtime").JSX.Element;
|
|
11
|
+
export declare const PanelNoAccess: ({ labels, appName }: StateProps & {
|
|
12
|
+
appName?: string;
|
|
13
|
+
}) => import("react/jsx-runtime").JSX.Element;
|
|
14
|
+
export declare const PanelEmpty: ({ labels, tab }: StateProps & {
|
|
15
|
+
tab: NotificationCenterTab;
|
|
16
|
+
}) => import("react/jsx-runtime").JSX.Element;
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,21 @@
|
|
|
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.PanelEmpty = exports.PanelNoAccess = exports.PanelError = exports.PanelSkeleton = 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 EmptyState_1 = __importDefault(require("../../EmptyState/EmptyState"));
|
|
11
|
+
const ErrorState_1 = __importDefault(require("../../QueryState/ErrorState"));
|
|
12
|
+
const Skeletons_1 = __importDefault(require("../../Skeletons/Skeletons"));
|
|
13
|
+
const SKELETON_ROWS = 4;
|
|
14
|
+
const PanelSkeleton = ({ isSheet }) => ((0, jsx_runtime_1.jsx)(Primitives_1.Box, { "aria-hidden": "true", py: 2, px: "6px", children: Array.from({ length: SKELETON_ROWS }, (_, index) => ((0, jsx_runtime_1.jsxs)(Primitives_1.Flex, { gap: 3, py: 2.5, pl: 5, pr: 3, children: [(0, jsx_runtime_1.jsx)(Skeletons_1.default, { type: "circle", size: isSheet ? "10" : "8" }), (0, jsx_runtime_1.jsxs)(Primitives_1.Flex, { flex: 1, direction: "column", gap: 2, pt: 1, children: [(0, jsx_runtime_1.jsx)(Skeletons_1.default, { type: "skeleton", height: "0.75rem", width: `${88 - index * 9}%` }), (0, jsx_runtime_1.jsx)(Skeletons_1.default, { type: "skeleton", height: "0.625rem", width: `${54 + index * 7}%` }), index % 2 === 0 && (0, jsx_runtime_1.jsx)(Skeletons_1.default, { type: "skeleton", height: index === 0 ? "1.5rem" : "0.625rem", width: "6rem" })] })] }, index))) }));
|
|
15
|
+
exports.PanelSkeleton = PanelSkeleton;
|
|
16
|
+
const PanelError = ({ labels, onRetry }) => ((0, jsx_runtime_1.jsx)(ErrorState_1.default, { size: "sm", title: labels.loadErrorTitle, description: labels.loadErrorDescription, retryLabel: labels.retry, onRetry: onRetry }));
|
|
17
|
+
exports.PanelError = PanelError;
|
|
18
|
+
const PanelNoAccess = ({ labels, appName }) => ((0, jsx_runtime_1.jsx)(Primitives_1.Box, { role: "status", children: (0, jsx_runtime_1.jsx)(EmptyState_1.default, { size: "sm", icon: lucide_react_1.Lock, colorScheme: "gray", title: labels.noAccessTitle, description: labels.noAccessDescription(appName) }) }));
|
|
19
|
+
exports.PanelNoAccess = PanelNoAccess;
|
|
20
|
+
const PanelEmpty = ({ labels, tab }) => tab === "needsYou" ? ((0, jsx_runtime_1.jsx)(EmptyState_1.default, { size: "sm", icon: lucide_react_1.CheckCircle2, colorScheme: "success", title: labels.emptyNeedsYouTitle, description: labels.emptyNeedsYouDescription })) : ((0, jsx_runtime_1.jsx)(EmptyState_1.default, { size: "sm", icon: lucide_react_1.Bell, title: labels.emptyActivityTitle, description: labels.emptyActivityDescription }));
|
|
21
|
+
exports.PanelEmpty = PanelEmpty;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { NotificationLabels } from "../core/NotificationSourceProps";
|
|
2
|
+
import type { NotificationFormatter } from "../core/NotificationEngineProps";
|
|
3
|
+
import type { NotificationCenterLabels } from "./NotificationCenterProps";
|
|
4
|
+
export declare const withCenterLabels: (shared: NotificationLabels, format: NotificationFormatter, overrides?: Partial<NotificationCenterLabels>) => NotificationCenterLabels;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.withCenterLabels = void 0;
|
|
4
|
+
const labels_1 = require("../core/labels");
|
|
5
|
+
const withCenterLabels = (shared, format, overrides = {}) => (0, labels_1.mergeDefined)({
|
|
6
|
+
...shared,
|
|
7
|
+
bell: ({ needsYou, unread }) => {
|
|
8
|
+
if (needsYou > 0)
|
|
9
|
+
return `Notifications, ${format.number(needsYou)} need you`;
|
|
10
|
+
if (unread > 0)
|
|
11
|
+
return `Notifications, ${format.number(unread)} unread`;
|
|
12
|
+
return "Notifications";
|
|
13
|
+
},
|
|
14
|
+
title: "Notifications",
|
|
15
|
+
needsYouTab: "Needs you",
|
|
16
|
+
activityTab: "Activity",
|
|
17
|
+
tabsLabel: "Notification lists",
|
|
18
|
+
markAllRead: "Mark all read",
|
|
19
|
+
openInbox: "Open inbox",
|
|
20
|
+
settings: "Notification settings",
|
|
21
|
+
close: "Close notifications",
|
|
22
|
+
loading: "Loading notifications",
|
|
23
|
+
loadErrorTitle: "Couldn't load notifications",
|
|
24
|
+
loadErrorDescription: "Check your connection, then try again. Nothing you did was lost.",
|
|
25
|
+
noAccessTitle: "Notifications aren't turned on for you",
|
|
26
|
+
noAccessDescription: (appName) => `Your ${appName !== null && appName !== void 0 ? appName : "workspace"} admin hasn't given your role access to notifications in this workspace.`,
|
|
27
|
+
emptyNeedsYouTitle: "You're all caught up",
|
|
28
|
+
emptyNeedsYouDescription: "Nothing is waiting for your decision.",
|
|
29
|
+
emptyActivityTitle: "No activity yet",
|
|
30
|
+
emptyActivityDescription: "Updates about your work and requests show up here.",
|
|
31
|
+
offlineBanner: (loadedAt) => loadedAt === undefined
|
|
32
|
+
? "You're offline. Changes are paused."
|
|
33
|
+
: `You're offline. These are from ${loadedAt}, and changes are paused.`,
|
|
34
|
+
newCount: (count) => `${format.number(count)} new`,
|
|
35
|
+
newCountName: (count) => `${format.number(count)} new notifications`,
|
|
36
|
+
overflowCount: (count) => `${format.number(count)}+`,
|
|
37
|
+
}, overrides);
|
|
38
|
+
exports.withCenterLabels = withCenterLabels;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type RefObject } from "react";
|
|
2
|
+
export declare const useArrivals: (ids: string[], scope: string, bodyRef: RefObject<HTMLElement>) => {
|
|
3
|
+
heldIds: string[];
|
|
4
|
+
reveal: () => void;
|
|
5
|
+
track: {
|
|
6
|
+
onPointerEnter: () => void;
|
|
7
|
+
onPointerLeave: () => void;
|
|
8
|
+
onFocus: () => void;
|
|
9
|
+
onBlur: (event: {
|
|
10
|
+
currentTarget: Element;
|
|
11
|
+
relatedTarget: EventTarget | null;
|
|
12
|
+
}) => void;
|
|
13
|
+
};
|
|
14
|
+
};
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useArrivals = void 0;
|
|
4
|
+
const react_1 = require("react");
|
|
5
|
+
const ROW_SELECTOR = "[data-notification-id]";
|
|
6
|
+
const FOCUS_SELECTOR = "a[href], button";
|
|
7
|
+
const useArrivals = (ids, scope, bodyRef) => {
|
|
8
|
+
const latest = (0, react_1.useRef)(ids);
|
|
9
|
+
latest.current = ids;
|
|
10
|
+
const known = (0, react_1.useRef)(new Set(ids));
|
|
11
|
+
const seenScope = (0, react_1.useRef)(scope);
|
|
12
|
+
const busy = (0, react_1.useRef)(false);
|
|
13
|
+
const [held, setHeld] = (0, react_1.useState)({ scope, ids: [] });
|
|
14
|
+
const key = ids.join();
|
|
15
|
+
(0, react_1.useEffect)(() => {
|
|
16
|
+
var _a, _b;
|
|
17
|
+
if (seenScope.current !== scope) {
|
|
18
|
+
seenScope.current = scope;
|
|
19
|
+
known.current = new Set(latest.current);
|
|
20
|
+
setHeld({ scope, ids: [] });
|
|
21
|
+
if (bodyRef.current)
|
|
22
|
+
bodyRef.current.scrollTop = 0;
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
const fresh = latest.current.filter((id) => !known.current.has(id));
|
|
26
|
+
if (!fresh.length)
|
|
27
|
+
return;
|
|
28
|
+
fresh.forEach((id) => known.current.add(id));
|
|
29
|
+
const scrolled = ((_b = (_a = bodyRef.current) === null || _a === void 0 ? void 0 : _a.scrollTop) !== null && _b !== void 0 ? _b : 0) > 4;
|
|
30
|
+
if (busy.current || scrolled)
|
|
31
|
+
setHeld((current) => ({ scope, ids: [...current.ids, ...fresh] }));
|
|
32
|
+
}, [key, scope, bodyRef]);
|
|
33
|
+
const heldIds = (0, react_1.useMemo)(() => {
|
|
34
|
+
if (held.scope !== scope)
|
|
35
|
+
return [];
|
|
36
|
+
const present = new Set(ids);
|
|
37
|
+
return held.ids.filter((id) => present.has(id));
|
|
38
|
+
}, [held, scope, ids]);
|
|
39
|
+
const reveal = (0, react_1.useCallback)(() => {
|
|
40
|
+
setHeld({ scope, ids: [] });
|
|
41
|
+
requestAnimationFrame(() => {
|
|
42
|
+
var _a;
|
|
43
|
+
const body = bodyRef.current;
|
|
44
|
+
if (!body)
|
|
45
|
+
return;
|
|
46
|
+
const row = [...body.querySelectorAll(ROW_SELECTOR)].find((node) => { var _a; return heldIds.includes((_a = node.dataset.notificationId) !== null && _a !== void 0 ? _a : ""); });
|
|
47
|
+
if (!row)
|
|
48
|
+
return;
|
|
49
|
+
const top = row.getBoundingClientRect().top - body.getBoundingClientRect().top;
|
|
50
|
+
body.scrollTop += top - 8;
|
|
51
|
+
(_a = row.querySelector(FOCUS_SELECTOR)) === null || _a === void 0 ? void 0 : _a.focus({ preventScroll: true });
|
|
52
|
+
});
|
|
53
|
+
}, [heldIds, scope, bodyRef]);
|
|
54
|
+
const track = (0, react_1.useMemo)(() => ({
|
|
55
|
+
onPointerEnter: () => {
|
|
56
|
+
busy.current = true;
|
|
57
|
+
},
|
|
58
|
+
onPointerLeave: () => {
|
|
59
|
+
busy.current = false;
|
|
60
|
+
},
|
|
61
|
+
onFocus: () => {
|
|
62
|
+
busy.current = true;
|
|
63
|
+
},
|
|
64
|
+
onBlur: (event) => {
|
|
65
|
+
if (!event.currentTarget.contains(event.relatedTarget))
|
|
66
|
+
busy.current = false;
|
|
67
|
+
},
|
|
68
|
+
}), []);
|
|
69
|
+
return { heldIds, reveal, track };
|
|
70
|
+
};
|
|
71
|
+
exports.useArrivals = useArrivals;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useIsSheet = void 0;
|
|
4
|
+
const react_1 = require("react");
|
|
5
|
+
const DESKTOP = "(min-width: 48em)";
|
|
6
|
+
const isNarrow = () => typeof window !== "undefined" && typeof window.matchMedia === "function" && !window.matchMedia(DESKTOP).matches;
|
|
7
|
+
const useIsSheet = (variant) => {
|
|
8
|
+
const [narrow, setNarrow] = (0, react_1.useState)(isNarrow);
|
|
9
|
+
(0, react_1.useEffect)(() => {
|
|
10
|
+
if (variant !== undefined || typeof window.matchMedia !== "function")
|
|
11
|
+
return undefined;
|
|
12
|
+
const query = window.matchMedia(DESKTOP);
|
|
13
|
+
const sync = () => setNarrow(!query.matches);
|
|
14
|
+
sync();
|
|
15
|
+
query.addEventListener("change", sync);
|
|
16
|
+
return () => query.removeEventListener("change", sync);
|
|
17
|
+
}, [variant]);
|
|
18
|
+
return variant === undefined ? narrow : variant === "sheet";
|
|
19
|
+
};
|
|
20
|
+
exports.useIsSheet = useIsSheet;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
import { type NotificationShared } from "./useNotificationEngine";
|
|
3
|
+
import type { NotificationCenterProviderProps, NotificationSourceBinding, NotificationSourceProps } from "./NotificationSourceProps";
|
|
4
|
+
import type { NotificationCenterValue } from "./NotificationEngineProps";
|
|
5
|
+
/** One overlay, one undo queue and one polite live region for every notification component inside it. */
|
|
6
|
+
export declare const NotificationCenterProvider: ({ children, ...source }: NotificationCenterProviderProps) => import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
/** The live lists, counts and actions of the nearest `NotificationCenterProvider`; throws outside one. */
|
|
8
|
+
export declare const useNotificationCenter: () => NotificationCenterValue;
|
|
9
|
+
export declare const useNotificationShared: () => NotificationShared;
|
|
10
|
+
export declare const hasNotificationSource: (binding: NotificationSourceBinding) => binding is NotificationSourceProps;
|
|
11
|
+
interface NotificationScopeProps {
|
|
12
|
+
source: NotificationSourceBinding;
|
|
13
|
+
children: ReactNode;
|
|
14
|
+
}
|
|
15
|
+
/** A component's own source props win with a private provider; without them it joins the provider above. */
|
|
16
|
+
export declare const NotificationScope: ({ source, children }: NotificationScopeProps) => import("react/jsx-runtime").JSX.Element;
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,46 @@
|
|
|
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.NotificationScope = exports.hasNotificationSource = exports.useNotificationShared = exports.useNotificationCenter = exports.NotificationCenterProvider = void 0;
|
|
7
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
8
|
+
const react_1 = require("react");
|
|
9
|
+
const VisuallyHidden_1 = __importDefault(require("../../VisuallyHidden/VisuallyHidden"));
|
|
10
|
+
const useNotificationEngine_1 = require("./useNotificationEngine");
|
|
11
|
+
const NotificationCenterContext = (0, react_1.createContext)(null);
|
|
12
|
+
const NotificationSharedContext = (0, react_1.createContext)(null);
|
|
13
|
+
const MISSING_PROVIDER = "This notification component has no data: pass entries, counts, categories and onOpen, or render it inside a NotificationCenterProvider.";
|
|
14
|
+
/** One overlay, one undo queue and one polite live region for every notification component inside it. */
|
|
15
|
+
const NotificationCenterProvider = ({ children, ...source }) => {
|
|
16
|
+
const { value, shared, announcement } = (0, useNotificationEngine_1.useNotificationEngine)(source);
|
|
17
|
+
return ((0, jsx_runtime_1.jsx)(NotificationCenterContext.Provider, { value: value, children: (0, jsx_runtime_1.jsxs)(NotificationSharedContext.Provider, { value: shared, children: [children, (0, jsx_runtime_1.jsx)(VisuallyHidden_1.default, { role: "status", "aria-live": "polite", "aria-atomic": "true", "data-testid": "notification-center-announcer", children: announcement })] }) }));
|
|
18
|
+
};
|
|
19
|
+
exports.NotificationCenterProvider = NotificationCenterProvider;
|
|
20
|
+
/** The live lists, counts and actions of the nearest `NotificationCenterProvider`; throws outside one. */
|
|
21
|
+
const useNotificationCenter = () => {
|
|
22
|
+
const value = (0, react_1.useContext)(NotificationCenterContext);
|
|
23
|
+
if (!value)
|
|
24
|
+
throw new Error(MISSING_PROVIDER);
|
|
25
|
+
return value;
|
|
26
|
+
};
|
|
27
|
+
exports.useNotificationCenter = useNotificationCenter;
|
|
28
|
+
const useNotificationShared = () => {
|
|
29
|
+
const value = (0, react_1.useContext)(NotificationSharedContext);
|
|
30
|
+
if (!value)
|
|
31
|
+
throw new Error(MISSING_PROVIDER);
|
|
32
|
+
return value;
|
|
33
|
+
};
|
|
34
|
+
exports.useNotificationShared = useNotificationShared;
|
|
35
|
+
const hasNotificationSource = (binding) => binding.entries !== undefined;
|
|
36
|
+
exports.hasNotificationSource = hasNotificationSource;
|
|
37
|
+
/** A component's own source props win with a private provider; without them it joins the provider above. */
|
|
38
|
+
const NotificationScope = ({ source, children }) => {
|
|
39
|
+
const parent = (0, react_1.useContext)(NotificationCenterContext);
|
|
40
|
+
if ((0, exports.hasNotificationSource)(source))
|
|
41
|
+
return (0, jsx_runtime_1.jsx)(exports.NotificationCenterProvider, { ...source, children: children });
|
|
42
|
+
if (!parent)
|
|
43
|
+
throw new Error(MISSING_PROVIDER);
|
|
44
|
+
return (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: children });
|
|
45
|
+
};
|
|
46
|
+
exports.NotificationScope = NotificationScope;
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import type { NotificationAction, NotificationActionError, NotificationActionIntent, NotificationCategories, NotificationCounts, NotificationEntry, NotificationExtraAction, NotificationLabels, NotificationLoadStatus, NotificationMarkAllScope, NotificationOpenEvent, NotificationZoneKey } from "./NotificationSourceProps";
|
|
2
|
+
/** Where a decision is: undo is the 6 s window, sending is in flight, resolved has folded away. */
|
|
3
|
+
export type NotificationRowStatus = "open" | "undo" | "sending" | "resolved" | "failed" | "denied";
|
|
4
|
+
/** The decision the person made, kept while it is undoable, in flight, failed or denied. */
|
|
5
|
+
export interface NotificationDecision {
|
|
6
|
+
/** The decided action's id. */
|
|
7
|
+
actionId: string;
|
|
8
|
+
/** The action's button text, for "Couldn't approve." */
|
|
9
|
+
label: string;
|
|
10
|
+
/** Past tense for the status line, e.g. "Approved". */
|
|
11
|
+
doneLabel: string;
|
|
12
|
+
/** The action's intent; negative decisions read in a neutral tone. */
|
|
13
|
+
intent: NotificationActionIntent;
|
|
14
|
+
/** The comment sent with it. */
|
|
15
|
+
reason?: string;
|
|
16
|
+
}
|
|
17
|
+
/** What the server asked for when it rejected a decision without a comment. */
|
|
18
|
+
export interface NotificationReasonRequest {
|
|
19
|
+
/** The action to reopen the reason form for. */
|
|
20
|
+
actionId: string;
|
|
21
|
+
/** The server's own words; without them the row shows `labels.reasonRequiredMessage`. */
|
|
22
|
+
message?: string;
|
|
23
|
+
}
|
|
24
|
+
/** What the overlay adds to one entry. */
|
|
25
|
+
export interface NotificationLiveState {
|
|
26
|
+
/** The list the entry shows in now, after optimistic changes. */
|
|
27
|
+
zone: NotificationZoneKey;
|
|
28
|
+
/** "open" unless a decision is underway or came back. */
|
|
29
|
+
status: NotificationRowStatus;
|
|
30
|
+
/** Set for every status but "open". */
|
|
31
|
+
decision?: NotificationDecision;
|
|
32
|
+
/** Why the decision failed or was denied. */
|
|
33
|
+
error?: NotificationActionError;
|
|
34
|
+
/** The server wants a comment: the row reopens the reason form for this action. */
|
|
35
|
+
reasonRequest?: NotificationReasonRequest;
|
|
36
|
+
/** Folding away: the row animates closed and leaves the accessibility tree. */
|
|
37
|
+
isHidden: boolean;
|
|
38
|
+
/** Still waiting on the person: a Needs-you entry that is open or failed. */
|
|
39
|
+
isPending: boolean;
|
|
40
|
+
}
|
|
41
|
+
/** One entry with the overlay applied; what every list renders. */
|
|
42
|
+
export interface LiveNotificationEntry {
|
|
43
|
+
/** The app's entry with the optimistic read and archive state applied. */
|
|
44
|
+
entry: NotificationEntry;
|
|
45
|
+
/** Status, list and visibility from the overlay. */
|
|
46
|
+
state: NotificationLiveState;
|
|
47
|
+
}
|
|
48
|
+
/** Live entries per list, newest first. Hidden entries stay in place so they can animate back. */
|
|
49
|
+
export interface NotificationZoneLists {
|
|
50
|
+
/** Decisions and unread `untilRead` entries. */
|
|
51
|
+
needsYou: LiveNotificationEntry[];
|
|
52
|
+
/** Everything else that is not archived. */
|
|
53
|
+
activity: LiveNotificationEntry[];
|
|
54
|
+
/** Archived entries; empty without `onArchive`. */
|
|
55
|
+
archived: LiveNotificationEntry[];
|
|
56
|
+
}
|
|
57
|
+
/** Which optional features the source turned on, one per callback. */
|
|
58
|
+
export interface NotificationFeatures {
|
|
59
|
+
/** `onAction` was passed. */
|
|
60
|
+
decide: boolean;
|
|
61
|
+
/** `onMarkRead` was passed. */
|
|
62
|
+
markRead: boolean;
|
|
63
|
+
/** `onMarkAllRead` was passed. */
|
|
64
|
+
markAllRead: boolean;
|
|
65
|
+
/** `onArchive` was passed. */
|
|
66
|
+
archive: boolean;
|
|
67
|
+
/** `onRestore` was passed. */
|
|
68
|
+
restore: boolean;
|
|
69
|
+
/** `onLoadMore` was passed. */
|
|
70
|
+
loadMore: boolean;
|
|
71
|
+
}
|
|
72
|
+
/** A thread: the newest entry of a `groupKey`, and the older ones behind it. */
|
|
73
|
+
export interface NotificationThread {
|
|
74
|
+
/** The lead entry's id. */
|
|
75
|
+
key: string;
|
|
76
|
+
/** The newest entry. */
|
|
77
|
+
lead: LiveNotificationEntry;
|
|
78
|
+
/** Older entries with the same `groupKey`, newest first; empty for a single entry. */
|
|
79
|
+
rest: LiveNotificationEntry[];
|
|
80
|
+
}
|
|
81
|
+
/** One heading and its threads: a category in Needs you, a day in Activity. */
|
|
82
|
+
export interface NotificationGroup {
|
|
83
|
+
/** A category key or a day bucket. */
|
|
84
|
+
key: string;
|
|
85
|
+
/** Null when Needs you holds a single category, so no heading repeats the tab. */
|
|
86
|
+
label: string | null;
|
|
87
|
+
/** Pending entries for a category group; 0 for a day group. */
|
|
88
|
+
count: number;
|
|
89
|
+
/** In list order. */
|
|
90
|
+
threads: NotificationThread[];
|
|
91
|
+
}
|
|
92
|
+
/** Activity's day headings. */
|
|
93
|
+
export type NotificationDayBucket = "today" | "yesterday" | "thisWeek" | "older";
|
|
94
|
+
/** Locale-aware date, time and number formatting; every function takes the current time explicitly. */
|
|
95
|
+
export interface NotificationFormatter {
|
|
96
|
+
/** "now", "5m", "3h", "2d", then a date such as "12 Oct". */
|
|
97
|
+
shortAge: (at: number, now: number) => string;
|
|
98
|
+
/** The spoken form: "just now", "5 minutes ago", then a full date and time. */
|
|
99
|
+
longAge: (at: number, now: number) => string;
|
|
100
|
+
/** "Today, 2:05 pm", "Yesterday, 2:05 pm", or a full date and time. */
|
|
101
|
+
absolute: (at: number, now: number) => string;
|
|
102
|
+
/** The Activity heading an entry falls under. */
|
|
103
|
+
dayBucket: (at: number, now: number) => NotificationDayBucket;
|
|
104
|
+
/** The heading text for a bucket. */
|
|
105
|
+
dayLabel: (bucket: NotificationDayBucket) => string;
|
|
106
|
+
/** Whole days between `at` and `now`, never negative. */
|
|
107
|
+
daysSince: (at: number, now: number) => number;
|
|
108
|
+
/** A count in the locale's digits and grouping. */
|
|
109
|
+
number: (value: number) => string;
|
|
110
|
+
/** The `dateTime` attribute value. */
|
|
111
|
+
iso: (at: number) => string;
|
|
112
|
+
}
|
|
113
|
+
/** Everything a notification layout can do; each call works whether or not its feature is on, doing nothing when it is off. */
|
|
114
|
+
export interface NotificationCenterActions {
|
|
115
|
+
/** Marks an unread entry read, then calls `onOpen`. */
|
|
116
|
+
open: (entry: NotificationEntry, event?: NotificationOpenEvent, action?: NotificationAction) => void;
|
|
117
|
+
/** Starts one undo window for the ids; several ids make one bulk decision with one toast. */
|
|
118
|
+
decide: (ids: string[], action: NotificationAction, reason?: string) => void;
|
|
119
|
+
/** Undoes the open window this entry belongs to. */
|
|
120
|
+
undo: (id: string) => void;
|
|
121
|
+
/** Undoes the most recent open window; false when there was none. */
|
|
122
|
+
undoLast: () => boolean;
|
|
123
|
+
/** Sends a failed decision again, at once. */
|
|
124
|
+
retry: (id: string) => void;
|
|
125
|
+
/** Clears a denied decision; the entry stays hidden until fresh data drops it. */
|
|
126
|
+
dismiss: (id: string) => void;
|
|
127
|
+
/** Closes a server request for a comment without sending. */
|
|
128
|
+
clearReasonRequest: (id: string) => void;
|
|
129
|
+
/** Read or unread, sent at once; a failure rolls back with a toast. */
|
|
130
|
+
setRead: (ids: string[], read: boolean) => void;
|
|
131
|
+
/** Marks the loaded matches read and sends the scope after the undo window. */
|
|
132
|
+
markAllRead: (scope: NotificationMarkAllScope) => void;
|
|
133
|
+
/** Activity entries only; sent after the undo window. */
|
|
134
|
+
archive: (ids: string[]) => void;
|
|
135
|
+
/** Archived entries back to Activity, sent at once. */
|
|
136
|
+
restore: (ids: string[]) => void;
|
|
137
|
+
/** The source's `extraActions` for an entry, or none. */
|
|
138
|
+
extraActionsFor: (entry: NotificationEntry) => NotificationExtraAction[];
|
|
139
|
+
/** Runs an extra action and toasts its outcome. */
|
|
140
|
+
runExtraAction: (entry: NotificationEntry, action: NotificationExtraAction) => void;
|
|
141
|
+
/** Calls `onLoadMore`. */
|
|
142
|
+
loadMore: () => void;
|
|
143
|
+
/** Calls `onRetry`. */
|
|
144
|
+
retryLoad: () => void;
|
|
145
|
+
/** Speaks a message through the shared polite live region. */
|
|
146
|
+
announce: (message: string) => void;
|
|
147
|
+
/** Sends every open undo window now, as on page hide. */
|
|
148
|
+
flush: () => void;
|
|
149
|
+
}
|
|
150
|
+
/** What `useNotificationCenter()` returns: the live lists, counts and every action. */
|
|
151
|
+
export interface NotificationCenterValue {
|
|
152
|
+
/** Live entries per list, newest first. */
|
|
153
|
+
lists: NotificationZoneLists;
|
|
154
|
+
/** Server counts moved by the overlay, never below 0. */
|
|
155
|
+
counts: NotificationCounts;
|
|
156
|
+
/** The source's categories. */
|
|
157
|
+
categories: NotificationCategories;
|
|
158
|
+
/** Which callbacks the source passed. */
|
|
159
|
+
features: NotificationFeatures;
|
|
160
|
+
/** The shared strings, defaults merged with the source's overrides. */
|
|
161
|
+
labels: NotificationLabels;
|
|
162
|
+
/** Formatting in the source's locale. */
|
|
163
|
+
format: NotificationFormatter;
|
|
164
|
+
/** The current time, refreshed every minute so relative times move. */
|
|
165
|
+
now: number;
|
|
166
|
+
/** The source's load state. */
|
|
167
|
+
status: NotificationLoadStatus;
|
|
168
|
+
/** True while offline; every change is disabled. */
|
|
169
|
+
isOffline: boolean;
|
|
170
|
+
/** When the loaded entries were fetched. */
|
|
171
|
+
loadedAt?: number;
|
|
172
|
+
/** As in "Open in hrms". */
|
|
173
|
+
appName?: string;
|
|
174
|
+
/** A next page exists. */
|
|
175
|
+
hasMore: boolean;
|
|
176
|
+
/** The next page is loading. */
|
|
177
|
+
isLoadingMore: boolean;
|
|
178
|
+
/** Every action, stable across renders. */
|
|
179
|
+
actions: NotificationCenterActions;
|
|
180
|
+
/** The live entry for an id, if loaded. */
|
|
181
|
+
find: (id: string) => LiveNotificationEntry | undefined;
|
|
182
|
+
}
|