@diwauhris/ui 1.7.18 → 1.7.20

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 CHANGED
@@ -809,6 +809,10 @@
809
809
  max-height: 6rem;
810
810
  }
811
811
 
812
+ .max-h-48 {
813
+ max-height: 12rem;
814
+ }
815
+
812
816
  .max-h-60 {
813
817
  max-height: 15rem;
814
818
  }
@@ -2899,6 +2903,10 @@
2899
2903
  background-color: rgb(255 255 255 / 0.75);
2900
2904
  }
2901
2905
 
2906
+ .bg-white\/95 {
2907
+ background-color: rgb(255 255 255 / 0.95);
2908
+ }
2909
+
2902
2910
  .bg-gradient-to-r {
2903
2911
  background-image: linear-gradient(to right, var(--tw-gradient-stops));
2904
2912
  }
@@ -3701,6 +3709,11 @@
3701
3709
  color: rgb(234 88 12 / var(--tw-text-opacity, 1));
3702
3710
  }
3703
3711
 
3712
+ .text-rose-300 {
3713
+ --tw-text-opacity: 1;
3714
+ color: rgb(253 164 175 / var(--tw-text-opacity, 1));
3715
+ }
3716
+
3704
3717
  .text-rose-300\/60 {
3705
3718
  color: rgb(253 164 175 / 0.6);
3706
3719
  }
@@ -4121,6 +4134,11 @@
4121
4134
  --tw-ring-offset-width: 2px;
4122
4135
  }
4123
4136
 
4137
+ .blur {
4138
+ --tw-blur: blur(8px);
4139
+ filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
4140
+ }
4141
+
4124
4142
  .drop-shadow {
4125
4143
  --tw-drop-shadow: drop-shadow(0 1px 2px rgb(0 0 0 / 0.1)) drop-shadow(0 1px 1px rgb(0 0 0 / 0.06));
4126
4144
  filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
package/lib/index.cjs CHANGED
@@ -3957,16 +3957,40 @@ function Menu({ trigger, items, ariaLabel = "Menu", align = "right", open: contr
3957
3957
  const [panelStyle, setPanelStyle] = (0, react.useState)({});
3958
3958
  (0, react.useEffect)(() => {
3959
3959
  if (!open || !triggerRef.current) return;
3960
- const rect = triggerRef.current.getBoundingClientRect();
3960
+ const GAP = 4;
3961
+ const MARGIN = 8;
3961
3962
  const PANEL_MIN_WIDTH = 176;
3962
- setPanelStyle({
3963
- position: "fixed",
3964
- top: rect.bottom + 4,
3965
- left: align === "left" ? rect.left : Math.max(0, rect.right - PANEL_MIN_WIDTH),
3966
- zIndex: 9999,
3967
- minWidth: Math.max(rect.width, PANEL_MIN_WIDTH)
3968
- });
3969
- }, [open, align]);
3963
+ const ROW_HEIGHT = 36;
3964
+ const HEADER_HEIGHT = 8;
3965
+ const reposition = () => {
3966
+ const trigger = triggerRef.current;
3967
+ if (!trigger) return;
3968
+ const rect = trigger.getBoundingClientRect();
3969
+ const panelHeight = panelRef.current?.offsetHeight ?? items.length * ROW_HEIGHT + HEADER_HEIGHT;
3970
+ const spaceBelow = window.innerHeight - rect.bottom;
3971
+ const flipUp = spaceBelow < panelHeight + GAP + MARGIN && rect.top > spaceBelow;
3972
+ setPanelStyle({
3973
+ position: "fixed",
3974
+ ...flipUp ? { bottom: Math.max(MARGIN, window.innerHeight - rect.top + GAP) } : { top: rect.bottom + GAP },
3975
+ left: align === "left" ? rect.left : Math.max(MARGIN, rect.right - PANEL_MIN_WIDTH),
3976
+ zIndex: 9999,
3977
+ minWidth: Math.max(rect.width, PANEL_MIN_WIDTH)
3978
+ });
3979
+ };
3980
+ reposition();
3981
+ const raf = window.requestAnimationFrame(reposition);
3982
+ window.addEventListener("scroll", reposition, true);
3983
+ window.addEventListener("resize", reposition);
3984
+ return () => {
3985
+ window.cancelAnimationFrame(raf);
3986
+ window.removeEventListener("scroll", reposition, true);
3987
+ window.removeEventListener("resize", reposition);
3988
+ };
3989
+ }, [
3990
+ open,
3991
+ align,
3992
+ items.length
3993
+ ]);
3970
3994
  (0, react.useEffect)(() => {
3971
3995
  if (!open) return;
3972
3996
  const handlePointerDown = (e) => {
@@ -4618,6 +4642,154 @@ function StatusPage({ eyebrow, title, description, code, icon, primaryAction, se
4618
4642
  });
4619
4643
  }
4620
4644
  //#endregion
4645
+ //#region src/ui-library/gallery/not-found-error/NotFoundError.tsx
4646
+ /**
4647
+ * NotFoundError — Design System Component
4648
+ *
4649
+ * Full-page 404 Not Found screen. Composes StatusPage internally using the
4650
+ * `notFound` preset. Navigation is the consumer's responsibility — wire it
4651
+ * via `primaryAction.onClick` and `secondaryAction.onClick`.
4652
+ *
4653
+ * No routing imports. Works with any router (React Router, Next.js, window.location).
4654
+ *
4655
+ * Usage:
4656
+ * import { NotFoundError } from '@diwauhris/ui';
4657
+ * import { useNavigate } from 'react-router-dom';
4658
+ *
4659
+ * function NotFoundPage() {
4660
+ * const navigate = useNavigate();
4661
+ * return (
4662
+ * <NotFoundError
4663
+ * primaryAction={{ label: 'Go to Dashboard', onClick: () => navigate('/dashboard') }}
4664
+ * secondaryAction={{ label: 'Go Back', onClick: () => navigate(-1) }}
4665
+ * />
4666
+ * );
4667
+ * }
4668
+ */
4669
+ function NotFoundError({ primaryAction, secondaryAction, className }) {
4670
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(StatusPage, {
4671
+ ...STATUS_PAGE_PRESETS.notFound,
4672
+ primaryAction,
4673
+ secondaryAction,
4674
+ className
4675
+ });
4676
+ }
4677
+ //#endregion
4678
+ //#region src/ui-library/gallery/forbidden-error/ForbiddenError.tsx
4679
+ /**
4680
+ * ForbiddenError — Design System Component
4681
+ *
4682
+ * Full-page 403 Access Restricted screen. Composes StatusPage internally
4683
+ * using the `forbidden` preset. Navigation is the consumer's responsibility
4684
+ * — wire it via `primaryAction.onClick` and `secondaryAction.onClick`.
4685
+ *
4686
+ * No routing imports. Works with any router (React Router, Next.js, window.location).
4687
+ *
4688
+ * Usage:
4689
+ * import { ForbiddenError } from '@diwauhris/ui';
4690
+ * import { useNavigate } from 'react-router-dom';
4691
+ *
4692
+ * function ForbiddenPage() {
4693
+ * const navigate = useNavigate();
4694
+ * return (
4695
+ * <ForbiddenError
4696
+ * primaryAction={{ label: 'Go to Dashboard', onClick: () => navigate('/dashboard') }}
4697
+ * secondaryAction={{ label: 'Go Back', onClick: () => navigate(-1) }}
4698
+ * />
4699
+ * );
4700
+ * }
4701
+ */
4702
+ function ForbiddenError({ primaryAction, secondaryAction, className }) {
4703
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(StatusPage, {
4704
+ ...STATUS_PAGE_PRESETS.forbidden,
4705
+ primaryAction,
4706
+ secondaryAction,
4707
+ className
4708
+ });
4709
+ }
4710
+ //#endregion
4711
+ //#region src/ui-library/gallery/application-error/ApplicationError.tsx
4712
+ /**
4713
+ * ApplicationError — Design System Component
4714
+ *
4715
+ * Full-page 500 / unexpected error screen. Composes StatusPage internally
4716
+ * using the `serverError` preset. Includes a dev-only collapsible details
4717
+ * panel (error message, stack trace, component stack) rendered only when
4718
+ * `import.meta.env.DEV && error !== undefined`.
4719
+ *
4720
+ * Navigation is the consumer's responsibility — wire onRetry and onDashboard.
4721
+ *
4722
+ * Two exports:
4723
+ *
4724
+ * ApplicationError — primary component. Consumer provides both callbacks.
4725
+ * Used as React Router `errorElement` (pair with useRouteError + useNavigate).
4726
+ *
4727
+ * ApplicationErrorFallback — convenience wrapper for ErrorBoundary usage.
4728
+ * Accepts onReset (maps to onRetry) and uses window.location.href for
4729
+ * dashboard navigation when outside router context.
4730
+ *
4731
+ * No routing imports in this file. Works with any router.
4732
+ *
4733
+ * Usage (router errorElement):
4734
+ * import { ApplicationError } from '@diwauhris/ui';
4735
+ * import { useRouteError, useNavigate } from 'react-router-dom';
4736
+ *
4737
+ * export function ErrorPage() {
4738
+ * const error = useRouteError();
4739
+ * const navigate = useNavigate();
4740
+ * return (
4741
+ * <ApplicationError
4742
+ * error={error}
4743
+ * onRetry={() => navigate(0)}
4744
+ * onDashboard={() => navigate('/dashboard')}
4745
+ * />
4746
+ * );
4747
+ * }
4748
+ *
4749
+ * Usage (ErrorBoundary fallback):
4750
+ * import { ApplicationErrorFallback } from '@diwauhris/ui';
4751
+ *
4752
+ * <ErrorBoundary fallbackRender={({ error, resetErrorBoundary }) => (
4753
+ * <ApplicationErrorFallback
4754
+ * error={error}
4755
+ * onReset={resetErrorBoundary}
4756
+ * />
4757
+ * )} />
4758
+ */
4759
+ function ApplicationError({ error, componentStack, errorId, onRetry, onDashboard, className }) {
4760
+ const showDevDetails = false;
4761
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4762
+ className,
4763
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(StatusPage, {
4764
+ ...STATUS_PAGE_PRESETS.serverError,
4765
+ primaryAction: {
4766
+ label: "Try Again",
4767
+ onClick: onRetry
4768
+ },
4769
+ secondaryAction: {
4770
+ label: "Go to Dashboard",
4771
+ onClick: onDashboard
4772
+ }
4773
+ }), showDevDetails]
4774
+ });
4775
+ }
4776
+ /**
4777
+ * Convenience wrapper for use with class-based ErrorBoundary components.
4778
+ * Outside router context — uses window.location.href for dashboard navigation.
4779
+ * Maps `onReset` to ApplicationError's `onRetry`.
4780
+ */
4781
+ function ApplicationErrorFallback({ error, componentStack, errorId, onReset }) {
4782
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ApplicationError, {
4783
+ error,
4784
+ componentStack,
4785
+ errorId,
4786
+ onRetry: onReset,
4787
+ onDashboard: () => {
4788
+ window.location.href = "/dashboard";
4789
+ }
4790
+ });
4791
+ }
4792
+ //#endregion
4621
4793
  //#region src/ui-library/gallery/employee-card/EmployeeCard.tsx
4622
4794
  function EmployeeCard({ name, role, avatarSrc, status, meta, actions, className = "" }) {
4623
4795
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("article", {
@@ -8608,6 +8780,8 @@ exports.AccordionItem = AccordionItem;
8608
8780
  exports.AccordionTrigger = AccordionTrigger;
8609
8781
  exports.ActivityFeed = ActivityFeed;
8610
8782
  exports.Alert = Alert;
8783
+ exports.ApplicationError = ApplicationError;
8784
+ exports.ApplicationErrorFallback = ApplicationErrorFallback;
8611
8785
  exports.ApprovalTimeline = ApprovalTimeline;
8612
8786
  exports.AreaChart = AreaChart;
8613
8787
  exports.Avatar = Avatar;
@@ -8645,6 +8819,7 @@ exports.FieldContext = FieldContext;
8645
8819
  exports.FieldInput = FieldInput;
8646
8820
  exports.FileUpload = FileUpload;
8647
8821
  exports.FilterChip = FilterChip;
8822
+ exports.ForbiddenError = ForbiddenError;
8648
8823
  exports.Heatmap = Heatmap;
8649
8824
  exports.IconButton = IconButton;
8650
8825
  exports.Input = Input;
@@ -8654,6 +8829,7 @@ exports.LineChart = LineChart;
8654
8829
  exports.MaskedValue = MaskedValue;
8655
8830
  exports.Menu = Menu;
8656
8831
  exports.Modal = Modal;
8832
+ exports.NotFoundError = NotFoundError;
8657
8833
  exports.OrgChart = OrgChart;
8658
8834
  exports.OrgUnitTree = OrgUnitTree;
8659
8835
  exports.OtpInput = OtpInput;
package/lib/index.mjs CHANGED
@@ -3933,16 +3933,40 @@ function Menu({ trigger, items, ariaLabel = "Menu", align = "right", open: contr
3933
3933
  const [panelStyle, setPanelStyle] = useState({});
3934
3934
  useEffect(() => {
3935
3935
  if (!open || !triggerRef.current) return;
3936
- const rect = triggerRef.current.getBoundingClientRect();
3936
+ const GAP = 4;
3937
+ const MARGIN = 8;
3937
3938
  const PANEL_MIN_WIDTH = 176;
3938
- setPanelStyle({
3939
- position: "fixed",
3940
- top: rect.bottom + 4,
3941
- left: align === "left" ? rect.left : Math.max(0, rect.right - PANEL_MIN_WIDTH),
3942
- zIndex: 9999,
3943
- minWidth: Math.max(rect.width, PANEL_MIN_WIDTH)
3944
- });
3945
- }, [open, align]);
3939
+ const ROW_HEIGHT = 36;
3940
+ const HEADER_HEIGHT = 8;
3941
+ const reposition = () => {
3942
+ const trigger = triggerRef.current;
3943
+ if (!trigger) return;
3944
+ const rect = trigger.getBoundingClientRect();
3945
+ const panelHeight = panelRef.current?.offsetHeight ?? items.length * ROW_HEIGHT + HEADER_HEIGHT;
3946
+ const spaceBelow = window.innerHeight - rect.bottom;
3947
+ const flipUp = spaceBelow < panelHeight + GAP + MARGIN && rect.top > spaceBelow;
3948
+ setPanelStyle({
3949
+ position: "fixed",
3950
+ ...flipUp ? { bottom: Math.max(MARGIN, window.innerHeight - rect.top + GAP) } : { top: rect.bottom + GAP },
3951
+ left: align === "left" ? rect.left : Math.max(MARGIN, rect.right - PANEL_MIN_WIDTH),
3952
+ zIndex: 9999,
3953
+ minWidth: Math.max(rect.width, PANEL_MIN_WIDTH)
3954
+ });
3955
+ };
3956
+ reposition();
3957
+ const raf = window.requestAnimationFrame(reposition);
3958
+ window.addEventListener("scroll", reposition, true);
3959
+ window.addEventListener("resize", reposition);
3960
+ return () => {
3961
+ window.cancelAnimationFrame(raf);
3962
+ window.removeEventListener("scroll", reposition, true);
3963
+ window.removeEventListener("resize", reposition);
3964
+ };
3965
+ }, [
3966
+ open,
3967
+ align,
3968
+ items.length
3969
+ ]);
3946
3970
  useEffect(() => {
3947
3971
  if (!open) return;
3948
3972
  const handlePointerDown = (e) => {
@@ -4594,6 +4618,107 @@ function StatusPage({ eyebrow, title, description, code, icon, primaryAction, se
4594
4618
  });
4595
4619
  }
4596
4620
  //#endregion
4621
+ //#region src/ui-library/gallery/not-found-error/NotFoundError.tsx
4622
+ /**
4623
+ * NotFoundError — Design System Component
4624
+ *
4625
+ * Full-page 404 Not Found screen. Composes StatusPage internally using the
4626
+ * `notFound` preset. Navigation is the consumer's responsibility — wire it
4627
+ * via `primaryAction.onClick` and `secondaryAction.onClick`.
4628
+ *
4629
+ * No routing imports. Works with any router (React Router, Next.js, window.location).
4630
+ *
4631
+ * Usage:
4632
+ * import { NotFoundError } from '@diwauhris/ui';
4633
+ * import { useNavigate } from 'react-router-dom';
4634
+ *
4635
+ * function NotFoundPage() {
4636
+ * const navigate = useNavigate();
4637
+ * return (
4638
+ * <NotFoundError
4639
+ * primaryAction={{ label: 'Go to Dashboard', onClick: () => navigate('/dashboard') }}
4640
+ * secondaryAction={{ label: 'Go Back', onClick: () => navigate(-1) }}
4641
+ * />
4642
+ * );
4643
+ * }
4644
+ */
4645
+ function NotFoundError({ primaryAction, secondaryAction, className }) {
4646
+ return /* @__PURE__ */ jsx(StatusPage, {
4647
+ ...STATUS_PAGE_PRESETS.notFound,
4648
+ primaryAction,
4649
+ secondaryAction,
4650
+ className
4651
+ });
4652
+ }
4653
+ //#endregion
4654
+ //#region src/ui-library/gallery/forbidden-error/ForbiddenError.tsx
4655
+ /**
4656
+ * ForbiddenError — Design System Component
4657
+ *
4658
+ * Full-page 403 Access Restricted screen. Composes StatusPage internally
4659
+ * using the `forbidden` preset. Navigation is the consumer's responsibility
4660
+ * — wire it via `primaryAction.onClick` and `secondaryAction.onClick`.
4661
+ *
4662
+ * No routing imports. Works with any router (React Router, Next.js, window.location).
4663
+ *
4664
+ * Usage:
4665
+ * import { ForbiddenError } from '@diwauhris/ui';
4666
+ * import { useNavigate } from 'react-router-dom';
4667
+ *
4668
+ * function ForbiddenPage() {
4669
+ * const navigate = useNavigate();
4670
+ * return (
4671
+ * <ForbiddenError
4672
+ * primaryAction={{ label: 'Go to Dashboard', onClick: () => navigate('/dashboard') }}
4673
+ * secondaryAction={{ label: 'Go Back', onClick: () => navigate(-1) }}
4674
+ * />
4675
+ * );
4676
+ * }
4677
+ */
4678
+ function ForbiddenError({ primaryAction, secondaryAction, className }) {
4679
+ return /* @__PURE__ */ jsx(StatusPage, {
4680
+ ...STATUS_PAGE_PRESETS.forbidden,
4681
+ primaryAction,
4682
+ secondaryAction,
4683
+ className
4684
+ });
4685
+ }
4686
+ //#endregion
4687
+ //#region src/ui-library/gallery/application-error/ApplicationError.tsx
4688
+ function ApplicationError({ error, componentStack, errorId, onRetry, onDashboard, className }) {
4689
+ const showDevDetails = false;
4690
+ return /* @__PURE__ */ jsxs("div", {
4691
+ className,
4692
+ children: [/* @__PURE__ */ jsx(StatusPage, {
4693
+ ...STATUS_PAGE_PRESETS.serverError,
4694
+ primaryAction: {
4695
+ label: "Try Again",
4696
+ onClick: onRetry
4697
+ },
4698
+ secondaryAction: {
4699
+ label: "Go to Dashboard",
4700
+ onClick: onDashboard
4701
+ }
4702
+ }), showDevDetails]
4703
+ });
4704
+ }
4705
+ /**
4706
+ * Convenience wrapper for use with class-based ErrorBoundary components.
4707
+ * Outside router context — uses window.location.href for dashboard navigation.
4708
+ * Maps `onReset` to ApplicationError's `onRetry`.
4709
+ */
4710
+ function ApplicationErrorFallback({ error, componentStack, errorId, onReset }) {
4711
+ return /* @__PURE__ */ jsx(ApplicationError, {
4712
+ error,
4713
+ componentStack,
4714
+ errorId,
4715
+ onRetry: onReset,
4716
+ onDashboard: () => {
4717
+ window.location.href = "/dashboard";
4718
+ }
4719
+ });
4720
+ }
4721
+ //#endregion
4597
4722
  //#region src/ui-library/gallery/employee-card/EmployeeCard.tsx
4598
4723
  function EmployeeCard({ name, role, avatarSrc, status, meta, actions, className = "" }) {
4599
4724
  return /* @__PURE__ */ jsxs("article", {
@@ -8578,4 +8703,4 @@ var shadow = {
8578
8703
  overlay: "shadow-xl"
8579
8704
  };
8580
8705
  //#endregion
8581
- export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, ActivityFeed, Alert, ApprovalTimeline, AreaChart, Avatar, Badge, BarChart, BarList, Breadcrumb, Button, CHART_PALETTE, Calendar, Card, CardContent, CardFooter, CardHeader, Checkbox, ColumnManager, Combobox, CommandPalette, ConfirmAction, ConfirmDialog, DatePicker, DescriptionItem, DescriptionList, Dialog, DialogBody, DialogFooter, Divider, Drawer, Dropdown, EmployeeCard, EmptyState, ErrorBanner, Field, FieldContext, FieldInput, FileUpload, FilterChip, Heatmap, IconButton, Input, IsoCubeBlock, Kanban, LineChart, MaskedValue, Menu, Modal, OrgChart, OrgUnitTree, OtpInput, PafTemplate, PageHeader, Pagination, PayslipTemplate, PermissionMatrix, Popover, PopoverContent, PopoverTrigger, Progress, RadioGroup, RadioItem, ReportTemplate, STATUS_PAGE_PRESETS, Search, Section, SegmentedControl, Select, SidebarGroup, SidebarItem, SidebarNav, SidebarSection, Skeleton, SkeletonAvatar, SkeletonCard, SkeletonTableRow, SkeletonText, Spinner, Statistic, StatusBadge, StatusDot, StatusPage, Stepper, Switch, Tab, TabList, TabPanel, TabPanels, Tabs, Textarea, TimekeepingTemplate, Timeline, TimelineEmptyState, TimelineFooter, TimelineItem, TimelineValueCard, Toaster, Toolbar, Tooltip, TreeView, ValidationSummary, applyColumnOrder, colors_exports as colors, dimension_exports as dimension, radius_exports as radius, shadow_exports as shadow, statusMenuItems, toast, typography_exports as typography, useFieldContext };
8706
+ export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, ActivityFeed, Alert, ApplicationError, ApplicationErrorFallback, ApprovalTimeline, AreaChart, Avatar, Badge, BarChart, BarList, Breadcrumb, Button, CHART_PALETTE, Calendar, Card, CardContent, CardFooter, CardHeader, Checkbox, ColumnManager, Combobox, CommandPalette, ConfirmAction, ConfirmDialog, DatePicker, DescriptionItem, DescriptionList, Dialog, DialogBody, DialogFooter, Divider, Drawer, Dropdown, EmployeeCard, EmptyState, ErrorBanner, Field, FieldContext, FieldInput, FileUpload, FilterChip, ForbiddenError, Heatmap, IconButton, Input, IsoCubeBlock, Kanban, LineChart, MaskedValue, Menu, Modal, NotFoundError, OrgChart, OrgUnitTree, OtpInput, PafTemplate, PageHeader, Pagination, PayslipTemplate, PermissionMatrix, Popover, PopoverContent, PopoverTrigger, Progress, RadioGroup, RadioItem, ReportTemplate, STATUS_PAGE_PRESETS, Search, Section, SegmentedControl, Select, SidebarGroup, SidebarItem, SidebarNav, SidebarSection, Skeleton, SkeletonAvatar, SkeletonCard, SkeletonTableRow, SkeletonText, Spinner, Statistic, StatusBadge, StatusDot, StatusPage, Stepper, Switch, Tab, TabList, TabPanel, TabPanels, Tabs, Textarea, TimekeepingTemplate, Timeline, TimelineEmptyState, TimelineFooter, TimelineItem, TimelineValueCard, Toaster, Toolbar, Tooltip, TreeView, ValidationSummary, applyColumnOrder, colors_exports as colors, dimension_exports as dimension, radius_exports as radius, shadow_exports as shadow, statusMenuItems, toast, typography_exports as typography, useFieldContext };
@@ -0,0 +1,96 @@
1
+ /**
2
+ * ApplicationError — Design System Component
3
+ *
4
+ * Full-page 500 / unexpected error screen. Composes StatusPage internally
5
+ * using the `serverError` preset. Includes a dev-only collapsible details
6
+ * panel (error message, stack trace, component stack) rendered only when
7
+ * `import.meta.env.DEV && error !== undefined`.
8
+ *
9
+ * Navigation is the consumer's responsibility — wire onRetry and onDashboard.
10
+ *
11
+ * Two exports:
12
+ *
13
+ * ApplicationError — primary component. Consumer provides both callbacks.
14
+ * Used as React Router `errorElement` (pair with useRouteError + useNavigate).
15
+ *
16
+ * ApplicationErrorFallback — convenience wrapper for ErrorBoundary usage.
17
+ * Accepts onReset (maps to onRetry) and uses window.location.href for
18
+ * dashboard navigation when outside router context.
19
+ *
20
+ * No routing imports in this file. Works with any router.
21
+ *
22
+ * Usage (router errorElement):
23
+ * import { ApplicationError } from '@diwauhris/ui';
24
+ * import { useRouteError, useNavigate } from 'react-router-dom';
25
+ *
26
+ * export function ErrorPage() {
27
+ * const error = useRouteError();
28
+ * const navigate = useNavigate();
29
+ * return (
30
+ * <ApplicationError
31
+ * error={error}
32
+ * onRetry={() => navigate(0)}
33
+ * onDashboard={() => navigate('/dashboard')}
34
+ * />
35
+ * );
36
+ * }
37
+ *
38
+ * Usage (ErrorBoundary fallback):
39
+ * import { ApplicationErrorFallback } from '@diwauhris/ui';
40
+ *
41
+ * <ErrorBoundary fallbackRender={({ error, resetErrorBoundary }) => (
42
+ * <ApplicationErrorFallback
43
+ * error={error}
44
+ * onReset={resetErrorBoundary}
45
+ * />
46
+ * )} />
47
+ */
48
+ export interface ApplicationErrorProps {
49
+ /**
50
+ * The caught error object.
51
+ * Used to extract message and stack in the dev-only details panel.
52
+ * Pass the value from useRouteError() or ErrorBoundary's error prop.
53
+ */
54
+ error?: unknown;
55
+ /**
56
+ * React component stack from ErrorInfo.componentStack.
57
+ * Shown in the dev panel when provided. Optional.
58
+ */
59
+ componentStack?: string;
60
+ /**
61
+ * Short error ID for support correlation (e.g. "ERR-A1B2C").
62
+ * Rendered below the action buttons when provided.
63
+ */
64
+ errorId?: string;
65
+ /**
66
+ * "Try Again" callback.
67
+ * Router usage: () => navigate(0)
68
+ * Boundary usage: onReset / resetErrorBoundary
69
+ */
70
+ onRetry: () => void;
71
+ /**
72
+ * "Go to Dashboard" callback.
73
+ * Router usage: () => navigate('/dashboard')
74
+ * Boundary usage: () => { window.location.href = '/dashboard'; }
75
+ */
76
+ onDashboard: () => void;
77
+ /** Additional class on the root wrapper. */
78
+ className?: string;
79
+ }
80
+ export interface ApplicationErrorFallbackProps {
81
+ /** The caught error object passed by the ErrorBoundary. */
82
+ error?: unknown;
83
+ /** React component stack from ErrorInfo.componentStack. */
84
+ componentStack?: string;
85
+ /** Short error ID for support correlation. */
86
+ errorId?: string;
87
+ /** Called when the user clicks "Try Again". Maps to onRetry. */
88
+ onReset: () => void;
89
+ }
90
+ export declare function ApplicationError({ error, componentStack, errorId, onRetry, onDashboard, className, }: ApplicationErrorProps): import("react").JSX.Element;
91
+ /**
92
+ * Convenience wrapper for use with class-based ErrorBoundary components.
93
+ * Outside router context — uses window.location.href for dashboard navigation.
94
+ * Maps `onReset` to ApplicationError's `onRetry`.
95
+ */
96
+ export declare function ApplicationErrorFallback({ error, componentStack, errorId, onReset, }: ApplicationErrorFallbackProps): import("react").JSX.Element;
@@ -0,0 +1,39 @@
1
+ /**
2
+ * ForbiddenError — Design System Component
3
+ *
4
+ * Full-page 403 Access Restricted screen. Composes StatusPage internally
5
+ * using the `forbidden` preset. Navigation is the consumer's responsibility
6
+ * — wire it via `primaryAction.onClick` and `secondaryAction.onClick`.
7
+ *
8
+ * No routing imports. Works with any router (React Router, Next.js, window.location).
9
+ *
10
+ * Usage:
11
+ * import { ForbiddenError } from '@diwauhris/ui';
12
+ * import { useNavigate } from 'react-router-dom';
13
+ *
14
+ * function ForbiddenPage() {
15
+ * const navigate = useNavigate();
16
+ * return (
17
+ * <ForbiddenError
18
+ * primaryAction={{ label: 'Go to Dashboard', onClick: () => navigate('/dashboard') }}
19
+ * secondaryAction={{ label: 'Go Back', onClick: () => navigate(-1) }}
20
+ * />
21
+ * );
22
+ * }
23
+ */
24
+ import type { StatusPageAction } from '../status-page/StatusPage';
25
+ export interface ForbiddenErrorProps {
26
+ /**
27
+ * Primary action button.
28
+ * Typically "Go to Dashboard" with onClick: () => navigate('/dashboard').
29
+ */
30
+ primaryAction: StatusPageAction;
31
+ /**
32
+ * Optional secondary action button.
33
+ * Typically "Go Back" with onClick: () => navigate(-1).
34
+ */
35
+ secondaryAction?: StatusPageAction;
36
+ /** Additional class on the root wrapper. */
37
+ className?: string;
38
+ }
39
+ export declare function ForbiddenError({ primaryAction, secondaryAction, className, }: ForbiddenErrorProps): import("react").JSX.Element;
@@ -0,0 +1,39 @@
1
+ /**
2
+ * NotFoundError — Design System Component
3
+ *
4
+ * Full-page 404 Not Found screen. Composes StatusPage internally using the
5
+ * `notFound` preset. Navigation is the consumer's responsibility — wire it
6
+ * via `primaryAction.onClick` and `secondaryAction.onClick`.
7
+ *
8
+ * No routing imports. Works with any router (React Router, Next.js, window.location).
9
+ *
10
+ * Usage:
11
+ * import { NotFoundError } from '@diwauhris/ui';
12
+ * import { useNavigate } from 'react-router-dom';
13
+ *
14
+ * function NotFoundPage() {
15
+ * const navigate = useNavigate();
16
+ * return (
17
+ * <NotFoundError
18
+ * primaryAction={{ label: 'Go to Dashboard', onClick: () => navigate('/dashboard') }}
19
+ * secondaryAction={{ label: 'Go Back', onClick: () => navigate(-1) }}
20
+ * />
21
+ * );
22
+ * }
23
+ */
24
+ import type { StatusPageAction } from '../status-page/StatusPage';
25
+ export interface NotFoundErrorProps {
26
+ /**
27
+ * Primary action button.
28
+ * Typically "Go to Dashboard" with onClick: () => navigate('/dashboard').
29
+ */
30
+ primaryAction: StatusPageAction;
31
+ /**
32
+ * Optional secondary action button.
33
+ * Typically "Go Back" with onClick: () => navigate(-1).
34
+ */
35
+ secondaryAction?: StatusPageAction;
36
+ /** Additional class on the root wrapper. */
37
+ className?: string;
38
+ }
39
+ export declare function NotFoundError({ primaryAction, secondaryAction, className, }: NotFoundErrorProps): import("react").JSX.Element;
@@ -110,6 +110,12 @@ export { EmptyState } from './gallery/empty-state/EmptyState';
110
110
  export type { EmptyStateProps } from './gallery/empty-state/EmptyState';
111
111
  export { StatusPage, STATUS_PAGE_PRESETS } from './gallery/status-page/StatusPage';
112
112
  export type { StatusPageProps, StatusPageAction } from './gallery/status-page/StatusPage';
113
+ export { NotFoundError } from './gallery/not-found-error/NotFoundError';
114
+ export type { NotFoundErrorProps } from './gallery/not-found-error/NotFoundError';
115
+ export { ForbiddenError } from './gallery/forbidden-error/ForbiddenError';
116
+ export type { ForbiddenErrorProps } from './gallery/forbidden-error/ForbiddenError';
117
+ export { ApplicationError, ApplicationErrorFallback } from './gallery/application-error/ApplicationError';
118
+ export type { ApplicationErrorProps, ApplicationErrorFallbackProps } from './gallery/application-error/ApplicationError';
113
119
  export { EmployeeCard } from './gallery/employee-card/EmployeeCard';
114
120
  export type { EmployeeCardProps, EmployeeCardMeta } from './gallery/employee-card/EmployeeCard';
115
121
  export { TreeView } from './gallery/tree-view/TreeView';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@diwauhris/ui",
3
3
  "private": false,
4
- "version": "1.7.18",
4
+ "version": "1.7.20",
5
5
  "type": "module",
6
6
  "description": "DIWA UHRIS UI component library — React + Tailwind CSS",
7
7
  "keywords": [