@diwauhris/ui 1.6.0 → 1.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/assets/ui.css +53 -4
- package/lib/index.cjs +396 -53
- package/lib/index.mjs +392 -54
- package/lib/types/ui-library/gallery/column-manager/ColumnManager.d.ts +66 -0
- package/lib/types/ui-library/gallery/pagination/Pagination.d.ts +17 -1
- package/lib/types/ui-library/gallery/status-dot/MaskedValue.d.ts +54 -0
- package/lib/types/ui-library/gallery/status-page/StatusPage.d.ts +112 -0
- package/lib/types/ui-library/gallery/validation-summary/ValidationSummary.d.ts +23 -1
- package/lib/types/ui-library/index.d.ts +6 -0
- package/package.json +1 -1
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* StatusPage — Design System Component
|
|
3
|
+
*
|
|
4
|
+
* Full-page status screen for 404, 403, 500, and custom states.
|
|
5
|
+
*
|
|
6
|
+
* Signature element: the status code itself rendered as a large Barlow
|
|
7
|
+
* watermark behind the heading — brand typography as the primary visual,
|
|
8
|
+
* no icon-in-a-circle required.
|
|
9
|
+
*
|
|
10
|
+
* Layout: full-page centered on bg-surface-page, no card wrapper.
|
|
11
|
+
* Motion: content block enters with .os-slide-up (respects prefers-reduced-motion).
|
|
12
|
+
* Watermark stays static — animating it would be distracting.
|
|
13
|
+
*
|
|
14
|
+
* No routing logic in this component. Action buttons accept onClick/href;
|
|
15
|
+
* the consumer wires navigation (e.g. useNavigate from react-router-dom).
|
|
16
|
+
*
|
|
17
|
+
* Usage:
|
|
18
|
+
* <StatusPage
|
|
19
|
+
* {...STATUS_PAGE_PRESETS.notFound}
|
|
20
|
+
* primaryAction={{ label: 'Go to Dashboard', onClick: () => navigate('/dashboard') }}
|
|
21
|
+
* secondaryAction={{ label: 'Go Back', onClick: () => navigate(-1) }}
|
|
22
|
+
* />
|
|
23
|
+
*
|
|
24
|
+
* Accessibility:
|
|
25
|
+
* - Heading is <h1> — appropriate for a full-page status screen.
|
|
26
|
+
* - Watermark is aria-hidden="true" — decorative; the heading communicates the state.
|
|
27
|
+
* - Action buttons have descriptive labels via the `label` prop.
|
|
28
|
+
* - The watermark is opacity-[0.07] and has no contrast requirement (aria-hidden).
|
|
29
|
+
*/
|
|
30
|
+
import type { ReactNode } from 'react';
|
|
31
|
+
export interface StatusPageAction {
|
|
32
|
+
/** Button label */
|
|
33
|
+
label: string;
|
|
34
|
+
/**
|
|
35
|
+
* Click handler — consumer wires navigation.
|
|
36
|
+
* Example: () => navigate('/dashboard')
|
|
37
|
+
*/
|
|
38
|
+
onClick?: () => void;
|
|
39
|
+
/**
|
|
40
|
+
* Renders an <a> tag instead of <button> when provided.
|
|
41
|
+
* Use for external links (e.g. a status-page URL) or non-SPA navigation.
|
|
42
|
+
*/
|
|
43
|
+
href?: string;
|
|
44
|
+
}
|
|
45
|
+
export interface StatusPageProps {
|
|
46
|
+
/**
|
|
47
|
+
* Short eyebrow label shown above the heading.
|
|
48
|
+
* Rendered in the brand-sky uppercase tracking style.
|
|
49
|
+
* Example: "404 — Not Found"
|
|
50
|
+
* Omit to skip the eyebrow row.
|
|
51
|
+
*/
|
|
52
|
+
eyebrow?: string;
|
|
53
|
+
/** Main heading. Rendered as <h1>. Required. */
|
|
54
|
+
title: string;
|
|
55
|
+
/** Body description below the heading. Rendered as <p>. Required. */
|
|
56
|
+
description: string;
|
|
57
|
+
/**
|
|
58
|
+
* Status code string used as the large typographic watermark
|
|
59
|
+
* rendered behind the heading (e.g. "404", "403", "500").
|
|
60
|
+
* When omitted and `icon` is provided, the icon renders as the
|
|
61
|
+
* background mark instead.
|
|
62
|
+
*/
|
|
63
|
+
code?: string;
|
|
64
|
+
/**
|
|
65
|
+
* Lucide icon used as the background mark when `code` is not set.
|
|
66
|
+
* Ignored when `code` is provided.
|
|
67
|
+
* Pass with aria-hidden="true"; rendered at large size automatically.
|
|
68
|
+
*/
|
|
69
|
+
icon?: ReactNode;
|
|
70
|
+
/** Primary action — rendered as Button variant="primary". */
|
|
71
|
+
primaryAction?: StatusPageAction;
|
|
72
|
+
/**
|
|
73
|
+
* Secondary action — rendered as Button variant="outline".
|
|
74
|
+
* Omit for single-action states.
|
|
75
|
+
*/
|
|
76
|
+
secondaryAction?: StatusPageAction;
|
|
77
|
+
/** Additional class on the root wrapper. */
|
|
78
|
+
className?: string;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Named presets for the three common status states.
|
|
82
|
+
* Each preset supplies code, eyebrow, title, and description.
|
|
83
|
+
* Consumer always provides actions — presets never include navigation.
|
|
84
|
+
*
|
|
85
|
+
* Usage:
|
|
86
|
+
* <StatusPage
|
|
87
|
+
* {...STATUS_PAGE_PRESETS.notFound}
|
|
88
|
+
* primaryAction={{ label: 'Go to Dashboard', onClick: () => navigate('/dashboard') }}
|
|
89
|
+
* secondaryAction={{ label: 'Go Back', onClick: () => navigate(-1) }}
|
|
90
|
+
* />
|
|
91
|
+
*/
|
|
92
|
+
export declare const STATUS_PAGE_PRESETS: {
|
|
93
|
+
readonly notFound: {
|
|
94
|
+
readonly code: "404";
|
|
95
|
+
readonly eyebrow: "404 — Not Found";
|
|
96
|
+
readonly title: "Page Not Found";
|
|
97
|
+
readonly description: "The page you're looking for doesn't exist or may have been moved.";
|
|
98
|
+
};
|
|
99
|
+
readonly forbidden: {
|
|
100
|
+
readonly code: "403";
|
|
101
|
+
readonly eyebrow: "403 — Access Restricted";
|
|
102
|
+
readonly title: "Access Restricted";
|
|
103
|
+
readonly description: "You don't have permission to view this page. Contact your system administrator if you need access.";
|
|
104
|
+
};
|
|
105
|
+
readonly serverError: {
|
|
106
|
+
readonly code: "500";
|
|
107
|
+
readonly eyebrow: "500 — Server Error";
|
|
108
|
+
readonly title: "Something Went Wrong";
|
|
109
|
+
readonly description: "We encountered an unexpected problem. Please try again or return to the dashboard.";
|
|
110
|
+
};
|
|
111
|
+
};
|
|
112
|
+
export declare function StatusPage({ eyebrow, title, description, code, icon, primaryAction, secondaryAction, className, }: StatusPageProps): import("react").JSX.Element;
|
|
@@ -17,6 +17,13 @@
|
|
|
17
17
|
* setIssues([{ field: 'Employee ID', message: 'is required' }]);
|
|
18
18
|
* // Render:
|
|
19
19
|
* <ValidationSummary issues={issues} />
|
|
20
|
+
*
|
|
21
|
+
* // With scroll-to-field (wizard steps):
|
|
22
|
+
* <ValidationSummary
|
|
23
|
+
* issues={issues}
|
|
24
|
+
* fieldIds={{ 'Employee ID': 'employee-id-input', 'Position': 'position-select' }}
|
|
25
|
+
* fieldLabels={{ 'Employee ID': 'Employee ID', 'Position': 'Position Title' }}
|
|
26
|
+
* />
|
|
20
27
|
*/
|
|
21
28
|
export interface ValidationIssue {
|
|
22
29
|
/** Human-readable field label. */
|
|
@@ -32,8 +39,23 @@ export interface ValidationSummaryProps {
|
|
|
32
39
|
* Default: "Review these fields before saving"
|
|
33
40
|
*/
|
|
34
41
|
heading?: string;
|
|
42
|
+
/**
|
|
43
|
+
* Maps issue.field → the DOM element id that the user should be
|
|
44
|
+
* scrolled to when they click the error.
|
|
45
|
+
* When provided, each matching issue renders as a clickable link
|
|
46
|
+
* that scrolls to and focuses the target element.
|
|
47
|
+
* Issues with no matching key render as plain text.
|
|
48
|
+
*/
|
|
49
|
+
fieldIds?: Record<string, string>;
|
|
50
|
+
/**
|
|
51
|
+
* Maps issue.field → a human-friendly display label.
|
|
52
|
+
* When provided, the display label replaces the raw field key in
|
|
53
|
+
* the rendered message. Useful when the field key is a code/ID and
|
|
54
|
+
* the label is the visible form field name.
|
|
55
|
+
*/
|
|
56
|
+
fieldLabels?: Record<string, string>;
|
|
35
57
|
/** Additional class on the root element. */
|
|
36
58
|
className?: string;
|
|
37
59
|
}
|
|
38
|
-
export declare function ValidationSummary({ issues, heading, className, }: ValidationSummaryProps): import("react").JSX.Element | null;
|
|
60
|
+
export declare function ValidationSummary({ issues, heading, fieldIds, fieldLabels, className, }: ValidationSummaryProps): import("react").JSX.Element | null;
|
|
39
61
|
export type { ValidationIssue as ValidationSummaryIssue };
|
|
@@ -106,6 +106,8 @@ export { Timeline, TimelineItem, TimelineValueCard, TimelineFooter, TimelineEmpt
|
|
|
106
106
|
export type { TimelineProps, TimelineItemProps, TimelineValueCardProps, TimelineFooterProps, TimelineEmptyStateProps } from './gallery/timeline/Timeline';
|
|
107
107
|
export { EmptyState } from './gallery/empty-state/EmptyState';
|
|
108
108
|
export type { EmptyStateProps } from './gallery/empty-state/EmptyState';
|
|
109
|
+
export { StatusPage, STATUS_PAGE_PRESETS } from './gallery/status-page/StatusPage';
|
|
110
|
+
export type { StatusPageProps, StatusPageAction } from './gallery/status-page/StatusPage';
|
|
109
111
|
export { EmployeeCard } from './gallery/employee-card/EmployeeCard';
|
|
110
112
|
export type { EmployeeCardProps, EmployeeCardMeta } from './gallery/employee-card/EmployeeCard';
|
|
111
113
|
export { TreeView } from './gallery/tree-view/TreeView';
|
|
@@ -142,6 +144,10 @@ export { Statistic } from './gallery/stat-card/Statistic';
|
|
|
142
144
|
export type { StatisticProps, StatisticTrend, StatisticVariant } from './gallery/stat-card/Statistic';
|
|
143
145
|
export { StatusDot } from './gallery/status-dot/StatusDot';
|
|
144
146
|
export type { StatusDotProps, StatusDotStatus } from './gallery/status-dot/StatusDot';
|
|
147
|
+
export { ColumnManager, applyColumnOrder } from './gallery/column-manager/ColumnManager';
|
|
148
|
+
export type { ColumnManagerProps, ColumnManagerColumn } from './gallery/column-manager/ColumnManager';
|
|
149
|
+
export { MaskedValue } from './gallery/status-dot/MaskedValue';
|
|
150
|
+
export type { MaskedValueProps } from './gallery/status-dot/MaskedValue';
|
|
145
151
|
export { Toaster, toast } from 'sonner';
|
|
146
152
|
export { statusMenuItems } from './gallery/status-actions/statusActions';
|
|
147
153
|
export type { ActionMenuItem, Lifecycle, StatusTransitionRequest, StatusMenuOptions } from './gallery/status-actions/statusActions';
|