@dbcdk/react-components 0.0.207 → 0.0.209

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 (36) hide show
  1. package/dist/client.cjs +10 -0
  2. package/dist/client.d.ts +4 -0
  3. package/dist/client.js +2 -0
  4. package/dist/components/listbox/Listbox.cjs +153 -0
  5. package/dist/components/listbox/Listbox.d.ts +22 -0
  6. package/dist/components/listbox/Listbox.js +146 -0
  7. package/dist/components/listbox/Listbox.module.css +97 -0
  8. package/dist/components/menu/Menu.cjs +7 -24
  9. package/dist/components/menu/Menu.js +7 -24
  10. package/dist/components/overlay/side-panel/SidePanel.cjs +80 -2
  11. package/dist/components/overlay/side-panel/SidePanel.js +80 -2
  12. package/dist/components/split-pane/SplitPane.cjs +22 -7
  13. package/dist/components/split-pane/SplitPane.d.ts +5 -2
  14. package/dist/components/split-pane/SplitPane.js +22 -7
  15. package/dist/components/split-pane/SplitPane.module.css +9 -0
  16. package/dist/components/split-pane/provider/SplitPaneContext.cjs +5 -2
  17. package/dist/components/split-pane/provider/SplitPaneContext.d.ts +3 -1
  18. package/dist/components/split-pane/provider/SplitPaneContext.js +5 -2
  19. package/dist/components/status-text/StatusText.cjs +27 -0
  20. package/dist/components/status-text/StatusText.d.ts +7 -0
  21. package/dist/components/status-text/StatusText.js +21 -0
  22. package/dist/components/status-text/StatusText.module.css +41 -0
  23. package/dist/components/tree-view/TreeNodeRow.cjs +70 -30
  24. package/dist/components/tree-view/TreeNodeRow.d.ts +6 -1
  25. package/dist/components/tree-view/TreeNodeRow.js +70 -30
  26. package/dist/components/tree-view/TreeView.cjs +107 -19
  27. package/dist/components/tree-view/TreeView.d.ts +1 -1
  28. package/dist/components/tree-view/TreeView.js +107 -19
  29. package/dist/components/tree-view/TreeView.module.css +47 -3
  30. package/dist/components/tree-view/types.d.ts +6 -0
  31. package/dist/hooks/useRovingFocus.cjs +45 -0
  32. package/dist/hooks/useRovingFocus.d.ts +10 -0
  33. package/dist/hooks/useRovingFocus.js +43 -0
  34. package/dist/index.css +2 -0
  35. package/dist/styles/css-helper-classes/typography.css +4 -0
  36. package/package.json +1 -1
@@ -21,8 +21,44 @@
21
21
  border-radius: var(--border-radius-default);
22
22
  }
23
23
 
24
+ .tree[data-size='md'] .row {
25
+ min-block-size: calc(var(--spacing-md) + var(--spacing-sm));
26
+ padding-inline-start: 0;
27
+ padding-inline-end: calc(var(--spacing-xs) - var(--spacing-2xs));
28
+ }
29
+
30
+ .tree[data-size='md'] .toggle,
31
+ .tree[data-size='md'] .labelButton {
32
+ box-sizing: border-box;
33
+ min-block-size: calc(var(--spacing-md) + var(--spacing-sm));
34
+ }
35
+
36
+ .tree[data-size='md'] .toggle {
37
+ justify-content: center;
38
+ align-self: stretch;
39
+ --tree-indent: calc(
40
+ var(--tree-depth) * (var(--spacing-md) + 2 * var(--spacing-2xs)) + var(--spacing-xs) -
41
+ var(--spacing-2xs)
42
+ );
43
+ inline-size: calc(var(--tree-indent) + var(--spacing-lg) + var(--spacing-sm));
44
+ padding-inline-start: var(--tree-indent);
45
+ padding-inline-end: 0;
46
+ }
47
+
48
+ .tree[data-size='md'] .errorRow {
49
+ padding-inline-start: calc(
50
+ (var(--tree-depth) + 1) * (var(--spacing-md) + 2 * var(--spacing-2xs)) + var(--spacing-xs) -
51
+ var(--spacing-2xs)
52
+ );
53
+ }
54
+
24
55
  .row[data-selected='true'] {
25
- background: color-mix(in oklab, var(--color-brand) 16%, transparent);
56
+ background: var(--color-status-info-bg);
57
+ }
58
+
59
+ .row[data-current='true'] {
60
+ background: var(--color-bg-surface-subtle);
61
+ font-weight: 600;
26
62
  }
27
63
 
28
64
  .toggle,
@@ -82,13 +118,21 @@
82
118
  padding-inline: var(--spacing-xs);
83
119
  }
84
120
 
85
- .row:hover .toggle:not(:disabled),
86
- .row:hover .labelButton,
121
+ .row:hover {
122
+ background: var(--color-bg-hover-subtle);
123
+ }
124
+
87
125
  .toggle:focus-visible,
88
126
  .labelButton:focus-visible {
89
127
  background: var(--color-bg-hover-subtle);
90
128
  }
91
129
 
130
+ .toggle:not(:disabled):hover,
131
+ .toggle:not(:disabled):focus-visible {
132
+ background: var(--color-bg-pressed-subtle);
133
+ color: var(--color-fg-default);
134
+ }
135
+
92
136
  .toggle:focus-visible,
93
137
  .labelButton:focus-visible {
94
138
  outline: none;
@@ -23,6 +23,7 @@ export type TreeNode<T = unknown> = {
23
23
  /** Fetches one node's children. Called once per node, the first time it's expanded (and again on retry after a failed load). Presence of this prop on TreeView is what switches it into lazy mode. */
24
24
  export type LoadTreeChildren<T = unknown> = (node: TreeNode<T>) => Promise<TreeNode<T>[]>;
25
25
  export type TreeViewProps<T = unknown> = {
26
+ size?: 'sm' | 'md';
26
27
  /** Top-level nodes. In eager mode every node's full subtree must already be present via `children`. In lazy mode only the nodes you already know about need to be here - deeper levels arrive via `loadChildren`. */
27
28
  data: TreeNode<T>[];
28
29
  /** Omit for eager mode. Provide for lazy mode. */
@@ -33,7 +34,11 @@ export type TreeViewProps<T = unknown> = {
33
34
  expandedIds?: string[];
34
35
  onExpandedIdsChange?: (ids: string[]) => void;
35
36
  selectedId?: string;
37
+ /** Marks the page's current record independently from the preview selection. */
38
+ currentId?: string;
36
39
  onSelectNode?: (node: TreeNode<T>) => void;
40
+ /** Expand branches when their labels are activated, without collapsing already-open branches. */
41
+ expandOnSelect?: boolean;
37
42
  /** Customize how a node's row content renders; defaults to `node.icon` + `node.label`. */
38
43
  renderLabel?: (node: TreeNode<T>) => ReactNode;
39
44
  /** Allows node labels to wrap onto multiple lines. Set to false to truncate them to one line. */
@@ -42,5 +47,6 @@ export type TreeViewProps<T = unknown> = {
42
47
  /** Formats the error shown under a node whose `loadChildren` call rejected. */
43
48
  loadErrorMessage?: (error: unknown, node: TreeNode<T>) => ReactNode;
44
49
  className?: string;
50
+ 'aria-label'?: string;
45
51
  'data-testid'?: string;
46
52
  };
@@ -0,0 +1,45 @@
1
+ 'use strict';
2
+
3
+ var react = require('react');
4
+
5
+ function useRovingFocus({
6
+ containerRef,
7
+ itemSelector,
8
+ loop = false,
9
+ resolveCurrentItem,
10
+ onNavigate
11
+ }) {
12
+ return react.useCallback(
13
+ (event) => {
14
+ const container = containerRef.current;
15
+ if (!container) return;
16
+ const items = Array.from(container.querySelectorAll(itemSelector));
17
+ if (items.length === 0) return;
18
+ const focused = document.activeElement;
19
+ const currentItem = items.includes(focused) ? focused : resolveCurrentItem == null ? void 0 : resolveCurrentItem(focused, items);
20
+ const currentIndex = currentItem ? items.indexOf(currentItem) : -1;
21
+ let nextIndex = null;
22
+ if (event.key === "ArrowDown") {
23
+ nextIndex = currentIndex < 0 ? 0 : currentIndex + 1;
24
+ if (loop && nextIndex >= items.length) nextIndex = 0;
25
+ else if (nextIndex >= items.length) nextIndex = items.length - 1;
26
+ } else if (event.key === "ArrowUp") {
27
+ nextIndex = currentIndex < 0 ? items.length - 1 : currentIndex - 1;
28
+ if (loop && nextIndex < 0) nextIndex = items.length - 1;
29
+ else if (nextIndex < 0) nextIndex = 0;
30
+ } else if (event.key === "Home") {
31
+ nextIndex = 0;
32
+ } else if (event.key === "End") {
33
+ nextIndex = items.length - 1;
34
+ }
35
+ if (nextIndex === null) return;
36
+ event.preventDefault();
37
+ const nextItem = items[nextIndex];
38
+ nextItem.focus();
39
+ onNavigate == null ? void 0 : onNavigate(nextItem);
40
+ },
41
+ [containerRef, itemSelector, loop, onNavigate, resolveCurrentItem]
42
+ );
43
+ }
44
+
45
+ exports.useRovingFocus = useRovingFocus;
@@ -0,0 +1,10 @@
1
+ import { type KeyboardEvent, type RefObject } from 'react';
2
+ type UseRovingFocusOptions<T extends HTMLElement> = {
3
+ containerRef: RefObject<T | null>;
4
+ itemSelector: string;
5
+ loop?: boolean;
6
+ resolveCurrentItem?: (focused: HTMLElement, items: HTMLElement[]) => HTMLElement | undefined;
7
+ onNavigate?: (item: HTMLElement) => void;
8
+ };
9
+ export declare function useRovingFocus<T extends HTMLElement>({ containerRef, itemSelector, loop, resolveCurrentItem, onNavigate, }: UseRovingFocusOptions<T>): (event: KeyboardEvent) => void;
10
+ export {};
@@ -0,0 +1,43 @@
1
+ import { useCallback } from 'react';
2
+
3
+ function useRovingFocus({
4
+ containerRef,
5
+ itemSelector,
6
+ loop = false,
7
+ resolveCurrentItem,
8
+ onNavigate
9
+ }) {
10
+ return useCallback(
11
+ (event) => {
12
+ const container = containerRef.current;
13
+ if (!container) return;
14
+ const items = Array.from(container.querySelectorAll(itemSelector));
15
+ if (items.length === 0) return;
16
+ const focused = document.activeElement;
17
+ const currentItem = items.includes(focused) ? focused : resolveCurrentItem == null ? void 0 : resolveCurrentItem(focused, items);
18
+ const currentIndex = currentItem ? items.indexOf(currentItem) : -1;
19
+ let nextIndex = null;
20
+ if (event.key === "ArrowDown") {
21
+ nextIndex = currentIndex < 0 ? 0 : currentIndex + 1;
22
+ if (loop && nextIndex >= items.length) nextIndex = 0;
23
+ else if (nextIndex >= items.length) nextIndex = items.length - 1;
24
+ } else if (event.key === "ArrowUp") {
25
+ nextIndex = currentIndex < 0 ? items.length - 1 : currentIndex - 1;
26
+ if (loop && nextIndex < 0) nextIndex = items.length - 1;
27
+ else if (nextIndex < 0) nextIndex = 0;
28
+ } else if (event.key === "Home") {
29
+ nextIndex = 0;
30
+ } else if (event.key === "End") {
31
+ nextIndex = items.length - 1;
32
+ }
33
+ if (nextIndex === null) return;
34
+ event.preventDefault();
35
+ const nextItem = items[nextIndex];
36
+ nextItem.focus();
37
+ onNavigate == null ? void 0 : onNavigate(nextItem);
38
+ },
39
+ [containerRef, itemSelector, loop, onNavigate, resolveCurrentItem]
40
+ );
41
+ }
42
+
43
+ export { useRovingFocus };
package/dist/index.css CHANGED
@@ -42,6 +42,7 @@
42
42
  @import './components/json-viewer/JsonViewer.module.css';
43
43
  @import './components/lightbox/Lightbox.module.css';
44
44
  @import './components/line-viewer/LineViewer.module.css';
45
+ @import './components/listbox/Listbox.module.css';
45
46
  @import './components/media-card/MediaCard.module.css';
46
47
  @import './components/menu/Menu.module.css';
47
48
  @import './components/meta-bar/MetaBar.module.css';
@@ -71,6 +72,7 @@
71
72
  @import './components/split-pane/SplitPane.module.css';
72
73
  @import './components/stack/Stack.module.css';
73
74
  @import './components/state-page/StatePage.module.css';
75
+ @import './components/status-text/StatusText.module.css';
74
76
  @import './components/table/Table.module.css';
75
77
  @import './components/table/components/column-resizer/ColumnResizer.module.css';
76
78
  @import './components/table/components/empty-state/EmptyState.module.css';
@@ -6,6 +6,10 @@
6
6
  font-weight: var(--font-weight-semibold);
7
7
  }
8
8
 
9
+ .dbc-normal-text {
10
+ font-weight: var(--font-weight-default);
11
+ }
12
+
9
13
  .dbc-prose :is(p, ol, li) {
10
14
  line-height: var(--line-height-relaxed);
11
15
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dbcdk/react-components",
3
- "version": "0.0.207",
3
+ "version": "0.0.209",
4
4
  "description": "Reusable React components for DBC projects",
5
5
  "license": "ISC",
6
6
  "author": "",