@dbcdk/react-components 0.0.185 → 0.0.186

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.
Files changed (65) hide show
  1. package/dist/client.cjs +28 -0
  2. package/dist/client.d.ts +4 -0
  3. package/dist/client.js +4 -0
  4. package/dist/components/accordion/components/AccordionRow.cjs +2 -36
  5. package/dist/components/accordion/components/AccordionRow.js +2 -36
  6. package/dist/components/button-select/ButtonSelect.cjs +30 -21
  7. package/dist/components/button-select/ButtonSelect.d.ts +8 -4
  8. package/dist/components/button-select/ButtonSelect.js +30 -21
  9. package/dist/components/page/Page.module.css +1 -0
  10. package/dist/components/pagination/Pagination.module.css +1 -0
  11. package/dist/components/panel/Panel.module.css +0 -1
  12. package/dist/components/popover/Popover.cjs +1 -1
  13. package/dist/components/popover/Popover.js +1 -1
  14. package/dist/components/print-friendly/PrintFriendlyCard.cjs +39 -0
  15. package/dist/components/print-friendly/PrintFriendlyCard.d.ts +23 -0
  16. package/dist/components/print-friendly/PrintFriendlyCard.js +37 -0
  17. package/dist/components/print-friendly/PrintFriendlyMetaBar.cjs +25 -0
  18. package/dist/components/print-friendly/PrintFriendlyMetaBar.d.ts +19 -0
  19. package/dist/components/print-friendly/PrintFriendlyMetaBar.js +23 -0
  20. package/dist/components/print-friendly/PrintFriendlyTable.cjs +51 -0
  21. package/dist/components/print-friendly/PrintFriendlyTable.d.ts +34 -0
  22. package/dist/components/print-friendly/PrintFriendlyTable.js +49 -0
  23. package/dist/components/print-friendly/components/AccumulationFooter.cjs +42 -0
  24. package/dist/components/print-friendly/components/AccumulationFooter.d.ts +9 -0
  25. package/dist/components/print-friendly/components/AccumulationFooter.js +40 -0
  26. package/dist/components/print-friendly/emptyValue.cjs +9 -0
  27. package/dist/components/print-friendly/emptyValue.d.ts +2 -0
  28. package/dist/components/print-friendly/emptyValue.js +6 -0
  29. package/dist/components/print-friendly/printSelection.cjs +14 -0
  30. package/dist/components/print-friendly/printSelection.d.ts +19 -0
  31. package/dist/components/print-friendly/printSelection.js +10 -0
  32. package/dist/components/stack/Stack.cjs +6 -5
  33. package/dist/components/stack/Stack.d.ts +2 -1
  34. package/dist/components/stack/Stack.js +6 -5
  35. package/dist/components/table/Table.cjs +20 -4
  36. package/dist/components/table/Table.js +21 -5
  37. package/dist/components/table/Table.module.css +6 -0
  38. package/dist/components/table/Table.types.d.ts +1 -0
  39. package/dist/components/table/components/TableHeader.cjs +1 -0
  40. package/dist/components/table/components/TableHeader.js +1 -0
  41. package/dist/components/tabs/Tabs.cjs +49 -39
  42. package/dist/components/tabs/Tabs.d.ts +3 -1
  43. package/dist/components/tabs/Tabs.js +49 -39
  44. package/dist/components/tabs/Tabs.module.css +24 -6
  45. package/dist/components/timeline/Timeline.cjs +102 -0
  46. package/dist/components/timeline/Timeline.d.ts +60 -0
  47. package/dist/components/timeline/Timeline.js +96 -0
  48. package/dist/components/timeline/Timeline.module.css +22 -0
  49. package/dist/components/timeline/components/TimelineRow.cjs +147 -0
  50. package/dist/components/timeline/components/TimelineRow.d.ts +15 -0
  51. package/dist/components/timeline/components/TimelineRow.js +141 -0
  52. package/dist/components/timeline/components/TimelineRow.module.css +195 -0
  53. package/dist/hooks/useCollapsibleHeight.cjs +41 -0
  54. package/dist/hooks/useCollapsibleHeight.d.ts +6 -0
  55. package/dist/hooks/useCollapsibleHeight.js +39 -0
  56. package/dist/hooks/useViewportFill.cjs +11 -3
  57. package/dist/hooks/useViewportFill.js +11 -3
  58. package/dist/index.cjs +7 -0
  59. package/dist/index.css +2 -0
  60. package/dist/index.d.ts +1 -0
  61. package/dist/index.js +1 -0
  62. package/dist/styles/styles.css +74 -2
  63. package/dist/styles.css +74 -2
  64. package/dist/utils/date/formatDate.d.ts +3 -2
  65. package/package.json +1 -1
package/dist/client.cjs CHANGED
@@ -25,6 +25,9 @@ var usePersistentState = require('./hooks/usePersistentState');
25
25
  var Chip = require('./components/chip/Chip');
26
26
  var Panel = require('./components/panel/Panel');
27
27
  var Card = require('./components/card/Card');
28
+ var PrintFriendlyCard = require('./components/print-friendly/PrintFriendlyCard');
29
+ var PrintFriendlyMetaBar = require('./components/print-friendly/PrintFriendlyMetaBar');
30
+ var PrintFriendlyTable = require('./components/print-friendly/PrintFriendlyTable');
28
31
  var CardContainer = require('./components/card-container/CardContainer');
29
32
  var SkeletonLoaderItem = require('./components/skeleton-loader/skeleton-loader-item/SkeletonLoaderItem');
30
33
  var SkeletonLoader = require('./components/skeleton-loader/SkeletonLoader');
@@ -81,6 +84,7 @@ var RadioButton = require('./components/forms/radio-buttons/RadioButton');
81
84
  var RadioButtonGroup = require('./components/forms/radio-buttons/RadioButtonGroup');
82
85
  var IntervalSelect = require('./components/interval-select/IntervalSelect');
83
86
  var Accordion = require('./components/accordion/Accordion');
87
+ var Timeline = require('./components/timeline/Timeline');
84
88
  var StatePage = require('./components/state-page/StatePage');
85
89
  var StickyFooterLayout = require('./components/sticky-footer-layout/StickyFooterLayout');
86
90
  var Typeahead = require('./components/forms/typeahead/Typeahead');
@@ -243,6 +247,24 @@ Object.keys(Card).forEach(function (k) {
243
247
  get: function () { return Card[k]; }
244
248
  });
245
249
  });
250
+ Object.keys(PrintFriendlyCard).forEach(function (k) {
251
+ if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
252
+ enumerable: true,
253
+ get: function () { return PrintFriendlyCard[k]; }
254
+ });
255
+ });
256
+ Object.keys(PrintFriendlyMetaBar).forEach(function (k) {
257
+ if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
258
+ enumerable: true,
259
+ get: function () { return PrintFriendlyMetaBar[k]; }
260
+ });
261
+ });
262
+ Object.keys(PrintFriendlyTable).forEach(function (k) {
263
+ if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
264
+ enumerable: true,
265
+ get: function () { return PrintFriendlyTable[k]; }
266
+ });
267
+ });
246
268
  Object.keys(CardContainer).forEach(function (k) {
247
269
  if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
248
270
  enumerable: true,
@@ -579,6 +601,12 @@ Object.keys(Accordion).forEach(function (k) {
579
601
  get: function () { return Accordion[k]; }
580
602
  });
581
603
  });
604
+ Object.keys(Timeline).forEach(function (k) {
605
+ if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
606
+ enumerable: true,
607
+ get: function () { return Timeline[k]; }
608
+ });
609
+ });
582
610
  Object.keys(StatePage).forEach(function (k) {
583
611
  if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
584
612
  enumerable: true,
package/dist/client.d.ts CHANGED
@@ -22,6 +22,9 @@ export * from './hooks/usePersistentState';
22
22
  export * from './components/chip/Chip';
23
23
  export * from './components/panel/Panel';
24
24
  export * from './components/card/Card';
25
+ export * from './components/print-friendly/PrintFriendlyCard';
26
+ export * from './components/print-friendly/PrintFriendlyMetaBar';
27
+ export * from './components/print-friendly/PrintFriendlyTable';
25
28
  export * from './components/card-container/CardContainer';
26
29
  export * from './components/skeleton-loader/skeleton-loader-item/SkeletonLoaderItem';
27
30
  export * from './components/skeleton-loader/SkeletonLoader';
@@ -78,6 +81,7 @@ export * from './components/forms/radio-buttons/RadioButton';
78
81
  export * from './components/forms/radio-buttons/RadioButtonGroup';
79
82
  export * from './components/interval-select/IntervalSelect';
80
83
  export * from './components/accordion/Accordion';
84
+ export * from './components/timeline/Timeline';
81
85
  export * from './components/state-page/StatePage';
82
86
  export * from './components/sticky-footer-layout/StickyFooterLayout';
83
87
  export * from './components/forms/typeahead/Typeahead';
package/dist/client.js CHANGED
@@ -23,6 +23,9 @@ export * from './hooks/usePersistentState';
23
23
  export * from './components/chip/Chip';
24
24
  export * from './components/panel/Panel';
25
25
  export * from './components/card/Card';
26
+ export * from './components/print-friendly/PrintFriendlyCard';
27
+ export * from './components/print-friendly/PrintFriendlyMetaBar';
28
+ export * from './components/print-friendly/PrintFriendlyTable';
26
29
  export * from './components/card-container/CardContainer';
27
30
  export * from './components/skeleton-loader/skeleton-loader-item/SkeletonLoaderItem';
28
31
  export * from './components/skeleton-loader/SkeletonLoader';
@@ -79,6 +82,7 @@ export * from './components/forms/radio-buttons/RadioButton';
79
82
  export * from './components/forms/radio-buttons/RadioButtonGroup';
80
83
  export * from './components/interval-select/IntervalSelect';
81
84
  export * from './components/accordion/Accordion';
85
+ export * from './components/timeline/Timeline';
82
86
  export * from './components/state-page/StatePage';
83
87
  export * from './components/sticky-footer-layout/StickyFooterLayout';
84
88
  export * from './components/forms/typeahead/Typeahead';
@@ -4,47 +4,13 @@ var jsxRuntime = require('react/jsx-runtime');
4
4
  var lucideReact = require('lucide-react');
5
5
  var react = require('react');
6
6
  var Headline = require('../../../components/headline/Headline');
7
+ var useCollapsibleHeight = require('../../../hooks/useCollapsibleHeight');
7
8
  var styles = require('./AccordionRow.module.css');
8
9
 
9
10
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
10
11
 
11
12
  var styles__default = /*#__PURE__*/_interopDefault(styles);
12
13
 
13
- function useCollapsibleHeight(isOpen, shouldAnimate) {
14
- const innerRef = react.useRef(null);
15
- const [height, setHeight] = react.useState("0px");
16
- const prevIsOpenRef = react.useRef(isOpen);
17
- react.useLayoutEffect(() => {
18
- var _a, _b;
19
- const el = innerRef.current;
20
- if (!el) return;
21
- const prevIsOpen = prevIsOpenRef.current;
22
- prevIsOpenRef.current = isOpen;
23
- const isOpenChanged = prevIsOpen !== isOpen;
24
- const prefersReduced = typeof window !== "undefined" && ((_b = (_a = window.matchMedia) == null ? void 0 : _a.call(window, "(prefers-reduced-motion: reduce)")) == null ? void 0 : _b.matches);
25
- if (!shouldAnimate || prefersReduced || !isOpenChanged) {
26
- setHeight(isOpen ? "auto" : "0px");
27
- return;
28
- }
29
- if (isOpen) {
30
- setHeight("0px");
31
- requestAnimationFrame(() => {
32
- setHeight(`${el.scrollHeight}px`);
33
- });
34
- } else {
35
- setHeight(`${el.scrollHeight}px`);
36
- requestAnimationFrame(() => {
37
- setHeight("0px");
38
- });
39
- }
40
- }, [isOpen, shouldAnimate]);
41
- function onTransitionEnd(e) {
42
- if (e.propertyName !== "height") return;
43
- if (!innerRef.current) return;
44
- if (isOpen) setHeight("auto");
45
- }
46
- return { innerRef, height, onTransitionEnd };
47
- }
48
14
  function AccordionRow({
49
15
  uid,
50
16
  index,
@@ -60,7 +26,7 @@ function AccordionRow({
60
26
  const headlineWeight = variant === "outlined" ? 400 : 500;
61
27
  const buttonId = `${uid}-acc-btn-${index}`;
62
28
  const panelId = `${uid}-acc-panel-${index}`;
63
- const { innerRef, height, onTransitionEnd } = useCollapsibleHeight(isOpen, shouldAnimate);
29
+ const { innerRef, height, onTransitionEnd } = useCollapsibleHeight.useCollapsibleHeight(isOpen, shouldAnimate);
64
30
  const [hasBeenOpened, setHasBeenOpened] = react.useState(isOpen);
65
31
  const shouldRenderChildren = renderMode === "eager" || isOpen || hasBeenOpened;
66
32
  function handleToggle() {
@@ -1,44 +1,10 @@
1
1
  import { jsxs, jsx } from 'react/jsx-runtime';
2
2
  import { ChevronDown } from 'lucide-react';
3
- import { useState, useRef, useLayoutEffect } from 'react';
3
+ import { useState } from 'react';
4
4
  import { Headline } from '../../../components/headline/Headline';
5
+ import { useCollapsibleHeight } from '../../../hooks/useCollapsibleHeight';
5
6
  import styles from './AccordionRow.module.css';
6
7
 
7
- function useCollapsibleHeight(isOpen, shouldAnimate) {
8
- const innerRef = useRef(null);
9
- const [height, setHeight] = useState("0px");
10
- const prevIsOpenRef = useRef(isOpen);
11
- useLayoutEffect(() => {
12
- var _a, _b;
13
- const el = innerRef.current;
14
- if (!el) return;
15
- const prevIsOpen = prevIsOpenRef.current;
16
- prevIsOpenRef.current = isOpen;
17
- const isOpenChanged = prevIsOpen !== isOpen;
18
- const prefersReduced = typeof window !== "undefined" && ((_b = (_a = window.matchMedia) == null ? void 0 : _a.call(window, "(prefers-reduced-motion: reduce)")) == null ? void 0 : _b.matches);
19
- if (!shouldAnimate || prefersReduced || !isOpenChanged) {
20
- setHeight(isOpen ? "auto" : "0px");
21
- return;
22
- }
23
- if (isOpen) {
24
- setHeight("0px");
25
- requestAnimationFrame(() => {
26
- setHeight(`${el.scrollHeight}px`);
27
- });
28
- } else {
29
- setHeight(`${el.scrollHeight}px`);
30
- requestAnimationFrame(() => {
31
- setHeight("0px");
32
- });
33
- }
34
- }, [isOpen, shouldAnimate]);
35
- function onTransitionEnd(e) {
36
- if (e.propertyName !== "height") return;
37
- if (!innerRef.current) return;
38
- if (isOpen) setHeight("auto");
39
- }
40
- return { innerRef, height, onTransitionEnd };
41
- }
42
8
  function AccordionRow({
43
9
  uid,
44
10
  index,
@@ -9,27 +9,36 @@ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
9
9
 
10
10
  var styles__default = /*#__PURE__*/_interopDefault(styles);
11
11
 
12
- function ButtonSelect({
13
- options,
14
- value,
15
- onChange,
16
- size = "md",
17
- disabled
18
- }) {
19
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles__default.default.group, role: "group", children: options.map((option) => /* @__PURE__ */ jsxRuntime.jsx(
20
- Button.Button,
21
- {
22
- className: option.value === value ? `${styles__default.default.btn} ${styles__default.default.btnSelected}` : styles__default.default.btn,
23
- variant: "outlined",
24
- shape: "default",
25
- size,
26
- active: option.value === value,
27
- disabled: disabled || option.disabled,
28
- onClick: () => onChange(option.value),
29
- children: option.label
30
- },
31
- option.value
32
- )) });
12
+ function ButtonSelect(props) {
13
+ const { options, size = "md", disabled } = props;
14
+ const selectedValues = Array.isArray(props.value) ? props.value : [props.value];
15
+ function handleSelect(optionValue) {
16
+ if (props.multiple) {
17
+ const currentValues = Array.isArray(props.value) ? props.value : [props.value];
18
+ const nextValue = currentValues.includes(optionValue) ? currentValues.filter((current) => current !== optionValue) : [...currentValues, optionValue];
19
+ props.onChange(nextValue);
20
+ return;
21
+ }
22
+ props.onChange(optionValue);
23
+ }
24
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles__default.default.group, role: "group", children: options.map((option) => {
25
+ const isSelected = selectedValues.includes(option.value);
26
+ return /* @__PURE__ */ jsxRuntime.jsx(
27
+ Button.Button,
28
+ {
29
+ className: isSelected ? `${styles__default.default.btn} ${styles__default.default.btnSelected}` : styles__default.default.btn,
30
+ variant: "outlined",
31
+ shape: "default",
32
+ size,
33
+ active: isSelected,
34
+ "aria-pressed": isSelected,
35
+ disabled: disabled || option.disabled,
36
+ onClick: () => handleSelect(option.value),
37
+ children: option.label
38
+ },
39
+ option.value
40
+ );
41
+ }) });
33
42
  }
34
43
 
35
44
  exports.ButtonSelect = ButtonSelect;
@@ -6,11 +6,15 @@ export interface ButtonSelectOption<T extends string = string> {
6
6
  label: React.ReactNode;
7
7
  disabled?: boolean;
8
8
  }
9
- export interface ButtonSelectProps<T extends string = string> {
9
+ interface ButtonSelectBaseProps<T extends string = string> {
10
10
  options: ButtonSelectOption<T>[];
11
- value: T;
12
- onChange: (value: T) => void;
13
11
  size?: ButtonSize;
14
12
  disabled?: boolean;
15
13
  }
16
- export declare function ButtonSelect<T extends string>({ options, value, onChange, size, disabled, }: ButtonSelectProps<T>): JSX.Element;
14
+ export interface ButtonSelectProps<T extends string = string> extends ButtonSelectBaseProps<T> {
15
+ value: T | T[];
16
+ onChange: (value: T | T[]) => void;
17
+ multiple?: boolean;
18
+ }
19
+ export declare function ButtonSelect<T extends string>(props: ButtonSelectProps<T>): JSX.Element;
20
+ export {};
@@ -3,27 +3,36 @@ import { jsx } from 'react/jsx-runtime';
3
3
  import { Button } from '../../components/button/Button';
4
4
  import styles from './ButtonSelect.module.css';
5
5
 
6
- function ButtonSelect({
7
- options,
8
- value,
9
- onChange,
10
- size = "md",
11
- disabled
12
- }) {
13
- return /* @__PURE__ */ jsx("div", { className: styles.group, role: "group", children: options.map((option) => /* @__PURE__ */ jsx(
14
- Button,
15
- {
16
- className: option.value === value ? `${styles.btn} ${styles.btnSelected}` : styles.btn,
17
- variant: "outlined",
18
- shape: "default",
19
- size,
20
- active: option.value === value,
21
- disabled: disabled || option.disabled,
22
- onClick: () => onChange(option.value),
23
- children: option.label
24
- },
25
- option.value
26
- )) });
6
+ function ButtonSelect(props) {
7
+ const { options, size = "md", disabled } = props;
8
+ const selectedValues = Array.isArray(props.value) ? props.value : [props.value];
9
+ function handleSelect(optionValue) {
10
+ if (props.multiple) {
11
+ const currentValues = Array.isArray(props.value) ? props.value : [props.value];
12
+ const nextValue = currentValues.includes(optionValue) ? currentValues.filter((current) => current !== optionValue) : [...currentValues, optionValue];
13
+ props.onChange(nextValue);
14
+ return;
15
+ }
16
+ props.onChange(optionValue);
17
+ }
18
+ return /* @__PURE__ */ jsx("div", { className: styles.group, role: "group", children: options.map((option) => {
19
+ const isSelected = selectedValues.includes(option.value);
20
+ return /* @__PURE__ */ jsx(
21
+ Button,
22
+ {
23
+ className: isSelected ? `${styles.btn} ${styles.btnSelected}` : styles.btn,
24
+ variant: "outlined",
25
+ shape: "default",
26
+ size,
27
+ active: isSelected,
28
+ "aria-pressed": isSelected,
29
+ disabled: disabled || option.disabled,
30
+ onClick: () => handleSelect(option.value),
31
+ children: option.label
32
+ },
33
+ option.value
34
+ );
35
+ }) });
27
36
  }
28
37
 
29
38
  export { ButtonSelect };
@@ -63,6 +63,7 @@
63
63
  .content {
64
64
  min-height: 0;
65
65
  min-width: 0;
66
+ padding-block-end: var(--spacing-lg);
66
67
  overflow: auto;
67
68
  }
68
69
 
@@ -1,6 +1,7 @@
1
1
  .container {
2
2
  display: flex;
3
3
  gap: var(--spacing-xxs);
4
+ flex-wrap: wrap;
4
5
  align-items: center;
5
6
  justify-content: center;
6
7
  margin: 0 auto;
@@ -2,7 +2,6 @@
2
2
  border: var(--border-width-thin) solid var(--color-border-subtle);
3
3
  border-radius: var(--border-radius-md);
4
4
  background-color: var(--color-bg-surface);
5
- box-shadow: var(--shadow-md);
6
5
  box-sizing: border-box;
7
6
  display: flex;
8
7
  flex-direction: column;
@@ -267,7 +267,7 @@ const Popover = React.forwardRef(function Popover2({
267
267
  if (lastCloseReasonRef.current === "outside") return;
268
268
  (_b = (_a = triggerElRef.current) == null ? void 0 : _a.focus) == null ? void 0 : _b.call(_a);
269
269
  }, [isOpen, returnFocus]);
270
- const chevronClassName = variant === "header" ? styles__default.default.chevronHeader : "dbc-muted-text";
270
+ const chevronClassName = variant === "header" ? styles__default.default.chevronHeader : void 0;
271
271
  const icon = isOpen ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronUp, { className: chevronClassName, size: 20 }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: chevronClassName, size: 20 });
272
272
  const setOverlayRef = React__namespace.useCallback(
273
273
  (node) => {
@@ -243,7 +243,7 @@ const Popover = forwardRef(function Popover2({
243
243
  if (lastCloseReasonRef.current === "outside") return;
244
244
  (_b = (_a = triggerElRef.current) == null ? void 0 : _a.focus) == null ? void 0 : _b.call(_a);
245
245
  }, [isOpen, returnFocus]);
246
- const chevronClassName = variant === "header" ? styles.chevronHeader : "dbc-muted-text";
246
+ const chevronClassName = variant === "header" ? styles.chevronHeader : void 0;
247
247
  const icon = isOpen ? /* @__PURE__ */ jsx(ChevronUp, { className: chevronClassName, size: 20 }) : /* @__PURE__ */ jsx(ChevronDown, { className: chevronClassName, size: 20 });
248
248
  const setOverlayRef = React.useCallback(
249
249
  (node) => {
@@ -0,0 +1,39 @@
1
+ 'use client';
2
+ 'use strict';
3
+
4
+ var jsxRuntime = require('react/jsx-runtime');
5
+ var react = require('react');
6
+ var emptyValue = require('./emptyValue');
7
+
8
+ function PrintFriendlyCard({
9
+ title,
10
+ rows = [],
11
+ containerCy,
12
+ emptyPlaceholder = emptyValue.EMPTY_VALUE_PLACEHOLDER,
13
+ showEmpty = true
14
+ }) {
15
+ const isEmpty = react.useMemo(
16
+ () => rows.every((row) => emptyValue.isValueEmpty(typeof row.value === "function" ? row.value() : row.value)),
17
+ [rows]
18
+ );
19
+ if (isEmpty && !showEmpty) return null;
20
+ function renderValue(row) {
21
+ const value = typeof row.value === "function" ? row.value() : row.value;
22
+ if (emptyValue.isValueEmpty(value) && row.showEmptyPlaceholder !== false) {
23
+ return emptyPlaceholder;
24
+ }
25
+ return value;
26
+ }
27
+ return /* @__PURE__ */ jsxRuntime.jsxs("section", { children: [
28
+ title ? /* @__PURE__ */ jsxRuntime.jsx("h4", { children: title }) : null,
29
+ /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cy": containerCy, children: rows.map((row) => /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cy": row.dataCy, children: [
30
+ /* @__PURE__ */ jsxRuntime.jsxs("strong", { children: [
31
+ row.label,
32
+ ":"
33
+ ] }),
34
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: renderValue(row) })
35
+ ] }, row.key)) })
36
+ ] });
37
+ }
38
+
39
+ exports.PrintFriendlyCard = PrintFriendlyCard;
@@ -0,0 +1,23 @@
1
+ import { type JSX, type ReactNode } from 'react';
2
+ export interface PrintFriendlyCardRow {
3
+ key: string | number;
4
+ label: ReactNode;
5
+ value: ReactNode | (() => ReactNode);
6
+ dataCy?: string;
7
+ showEmptyPlaceholder?: boolean;
8
+ }
9
+ interface PrintFriendlyCardProps {
10
+ title?: string;
11
+ rows?: PrintFriendlyCardRow[];
12
+ containerCy?: string;
13
+ emptyPlaceholder?: string;
14
+ showEmpty?: boolean;
15
+ }
16
+ /**
17
+ * Displays key-value pairs in a compact card, optimized for print: tight
18
+ * spacing, a clear heading, and strong label/value separation. Empty values
19
+ * fall back to a placeholder rather than leaving a blank line; set
20
+ * `showEmpty={false}` to hide the whole card instead when every row is empty.
21
+ */
22
+ export declare function PrintFriendlyCard({ title, rows, containerCy, emptyPlaceholder, showEmpty, }: PrintFriendlyCardProps): JSX.Element | null;
23
+ export {};
@@ -0,0 +1,37 @@
1
+ 'use client';
2
+ import { jsxs, jsx } from 'react/jsx-runtime';
3
+ import { useMemo } from 'react';
4
+ import { isValueEmpty, EMPTY_VALUE_PLACEHOLDER } from './emptyValue';
5
+
6
+ function PrintFriendlyCard({
7
+ title,
8
+ rows = [],
9
+ containerCy,
10
+ emptyPlaceholder = EMPTY_VALUE_PLACEHOLDER,
11
+ showEmpty = true
12
+ }) {
13
+ const isEmpty = useMemo(
14
+ () => rows.every((row) => isValueEmpty(typeof row.value === "function" ? row.value() : row.value)),
15
+ [rows]
16
+ );
17
+ if (isEmpty && !showEmpty) return null;
18
+ function renderValue(row) {
19
+ const value = typeof row.value === "function" ? row.value() : row.value;
20
+ if (isValueEmpty(value) && row.showEmptyPlaceholder !== false) {
21
+ return emptyPlaceholder;
22
+ }
23
+ return value;
24
+ }
25
+ return /* @__PURE__ */ jsxs("section", { children: [
26
+ title ? /* @__PURE__ */ jsx("h4", { children: title }) : null,
27
+ /* @__PURE__ */ jsx("div", { "data-cy": containerCy, children: rows.map((row) => /* @__PURE__ */ jsxs("div", { "data-cy": row.dataCy, children: [
28
+ /* @__PURE__ */ jsxs("strong", { children: [
29
+ row.label,
30
+ ":"
31
+ ] }),
32
+ /* @__PURE__ */ jsx("div", { children: renderValue(row) })
33
+ ] }, row.key)) })
34
+ ] });
35
+ }
36
+
37
+ export { PrintFriendlyCard };
@@ -0,0 +1,25 @@
1
+ 'use client';
2
+ 'use strict';
3
+
4
+ var jsxRuntime = require('react/jsx-runtime');
5
+
6
+ function PrintFriendlyMetaBar({
7
+ items = [],
8
+ dataCy
9
+ }) {
10
+ if (!items.length) return null;
11
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cy": dataCy, children: [
12
+ items.map((item, index) => /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
13
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
14
+ item.label,
15
+ ":"
16
+ ] }),
17
+ " ",
18
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: item.value }),
19
+ index < items.length - 1 ? /* @__PURE__ */ jsxRuntime.jsx("span", { children: "\xA0\xA0" }) : null
20
+ ] }, item.key)),
21
+ /* @__PURE__ */ jsxRuntime.jsx("hr", {})
22
+ ] });
23
+ }
24
+
25
+ exports.PrintFriendlyMetaBar = PrintFriendlyMetaBar;
@@ -0,0 +1,19 @@
1
+ import type { JSX, ReactNode } from 'react';
2
+ export interface PrintFriendlyMetaItem {
3
+ key: string | number;
4
+ label: ReactNode;
5
+ value: ReactNode;
6
+ }
7
+ interface PrintFriendlyMetaBarProps {
8
+ items?: PrintFriendlyMetaItem[];
9
+ dataCy?: string;
10
+ }
11
+ /**
12
+ * A horizontal bar of label/value pairs, styled for print rather than
13
+ * screen: a visible divider and generous spacing instead of a subtle dot
14
+ * separator, so it reads well on paper. Pair with a `page-break-before`
15
+ * class (see styles/styles.css) on a wrapping element to start each one on
16
+ * its own page.
17
+ */
18
+ export declare function PrintFriendlyMetaBar({ items, dataCy, }: PrintFriendlyMetaBarProps): JSX.Element | null;
19
+ export {};
@@ -0,0 +1,23 @@
1
+ 'use client';
2
+ import { jsxs, jsx } from 'react/jsx-runtime';
3
+
4
+ function PrintFriendlyMetaBar({
5
+ items = [],
6
+ dataCy
7
+ }) {
8
+ if (!items.length) return null;
9
+ return /* @__PURE__ */ jsxs("div", { "data-cy": dataCy, children: [
10
+ items.map((item, index) => /* @__PURE__ */ jsxs("span", { children: [
11
+ /* @__PURE__ */ jsxs("span", { children: [
12
+ item.label,
13
+ ":"
14
+ ] }),
15
+ " ",
16
+ /* @__PURE__ */ jsx("span", { children: item.value }),
17
+ index < items.length - 1 ? /* @__PURE__ */ jsx("span", { children: "\xA0\xA0" }) : null
18
+ ] }, item.key)),
19
+ /* @__PURE__ */ jsx("hr", {})
20
+ ] });
21
+ }
22
+
23
+ export { PrintFriendlyMetaBar };
@@ -0,0 +1,51 @@
1
+ 'use client';
2
+ 'use strict';
3
+
4
+ var jsxRuntime = require('react/jsx-runtime');
5
+ var react = require('react');
6
+ var AccumulationFooter = require('./components/AccumulationFooter');
7
+ var emptyValue = require('./emptyValue');
8
+
9
+ function PrintFriendlyTable({
10
+ rows = [],
11
+ cols = [],
12
+ tableCy,
13
+ id
14
+ }) {
15
+ const safeRows = react.useMemo(
16
+ () => rows.filter((row) => row.renderEmpty !== false || !emptyValue.isValueEmpty(row.value)),
17
+ [rows]
18
+ );
19
+ return /* @__PURE__ */ jsxRuntime.jsx("section", { children: /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsxs("table", { "data-cy": tableCy, id, children: [
20
+ cols.length ? /* @__PURE__ */ jsxRuntime.jsx("thead", { children: /* @__PURE__ */ jsxRuntime.jsx("tr", { children: cols.map((col) => /* @__PURE__ */ jsxRuntime.jsx("th", { style: { width: col.width, textAlign: col.alignment }, children: col.label }, col.key)) }) }) : /* @__PURE__ */ jsxRuntime.jsxs("colgroup", { children: [
21
+ /* @__PURE__ */ jsxRuntime.jsx("col", {}),
22
+ /* @__PURE__ */ jsxRuntime.jsx("col", {})
23
+ ] }),
24
+ /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: safeRows.map((row) => {
25
+ var _a;
26
+ return /* @__PURE__ */ jsxRuntime.jsx("tr", { "data-cy": row.dataCy, children: cols.length ? cols.map((col) => {
27
+ var _a2;
28
+ return /* @__PURE__ */ jsxRuntime.jsx(
29
+ "td",
30
+ {
31
+ style: {
32
+ textAlign: col.alignment,
33
+ whiteSpace: col.fitContent ? "nowrap" : void 0
34
+ },
35
+ children: (_a2 = row[col.key]) != null ? _a2 : emptyValue.EMPTY_VALUE_PLACEHOLDER
36
+ },
37
+ col.key
38
+ );
39
+ }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
40
+ /* @__PURE__ */ jsxRuntime.jsxs("th", { style: { whiteSpace: "nowrap" }, scope: "row", children: [
41
+ row.label,
42
+ ":"
43
+ ] }),
44
+ /* @__PURE__ */ jsxRuntime.jsx("td", { children: (_a = row.value) != null ? _a : emptyValue.EMPTY_VALUE_PLACEHOLDER })
45
+ ] }) }, row.key);
46
+ }) }),
47
+ /* @__PURE__ */ jsxRuntime.jsx(AccumulationFooter.AccumulationFooter, { rows: safeRows, cols })
48
+ ] }) }) });
49
+ }
50
+
51
+ exports.PrintFriendlyTable = PrintFriendlyTable;
@@ -0,0 +1,34 @@
1
+ import { type JSX, type ReactNode } from 'react';
2
+ export interface PrintFriendlyTableCol {
3
+ key: string;
4
+ label: ReactNode;
5
+ width?: string | number;
6
+ alignment?: 'left' | 'right' | 'center';
7
+ fitContent?: boolean;
8
+ accumulate?: boolean;
9
+ }
10
+ export interface PrintFriendlyTableRow {
11
+ key: string | number;
12
+ dataCy?: string;
13
+ /** Used when no `cols` are given: a plain label/value row. */
14
+ label?: ReactNode;
15
+ value?: ReactNode;
16
+ /** If false, the row is omitted entirely when its value is empty. */
17
+ renderEmpty?: boolean;
18
+ /** Used when `cols` are given: one field per column key. */
19
+ [columnKey: string]: unknown;
20
+ }
21
+ interface PrintFriendlyTableProps {
22
+ rows?: PrintFriendlyTableRow[];
23
+ cols?: PrintFriendlyTableCol[];
24
+ tableCy?: string;
25
+ id?: string | number;
26
+ }
27
+ /**
28
+ * Renders a table optimized for printing: controlled spacing that avoids
29
+ * overflow on paper, and rows with an empty value omitted (unless
30
+ * `renderEmpty` is set) so printouts don't carry empty clutter. Columns
31
+ * flagged `accumulate` get a totals row via AccumulationFooter.
32
+ */
33
+ export declare function PrintFriendlyTable({ rows, cols, tableCy, id, }: PrintFriendlyTableProps): JSX.Element;
34
+ export {};