@dbcdk/react-components 0.0.191 → 0.0.192
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/dist/client.cjs +7 -0
- package/dist/client.d.ts +1 -0
- package/dist/client.js +1 -0
- package/dist/components/forms/input/Input.module.css +93 -0
- package/dist/components/json-viewer/JsonViewer.cjs +2 -1
- package/dist/components/json-viewer/JsonViewer.js +3 -2
- package/dist/components/line-viewer/LineViewer.cjs +2 -1
- package/dist/components/line-viewer/LineViewer.js +3 -2
- package/dist/components/popover/Popover.cjs +2 -1
- package/dist/components/popover/Popover.d.ts +8 -1
- package/dist/components/popover/Popover.js +2 -1
- package/dist/components/search-box/SearchBox.cjs +10 -7
- package/dist/components/search-box/SearchBox.d.ts +7 -0
- package/dist/components/search-box/SearchBox.js +10 -7
- package/dist/components/sidebar/components/sidenav-filteirng/SidenavFiltering.cjs +2 -1
- package/dist/components/sidebar/components/sidenav-filteirng/SidenavFiltering.js +2 -1
- package/dist/components/tabs/Tabs.cjs +58 -56
- package/dist/components/tabs/Tabs.js +58 -56
- package/dist/components/tabs/Tabs.module.css +32 -16
- package/dist/components/timeline/Timeline.d.ts +1 -0
- package/dist/components/timeline/components/TimelineRow.cjs +1 -1
- package/dist/components/timeline/components/TimelineRow.js +1 -1
- package/dist/components/timeline/components/TimelineRow.module.css +4 -0
- package/dist/components/tree-view/TreeNodeRow.cjs +9 -1
- package/dist/components/tree-view/TreeNodeRow.d.ts +2 -1
- package/dist/components/tree-view/TreeNodeRow.js +9 -1
- package/dist/components/tree-view/TreeView.cjs +2 -0
- package/dist/components/tree-view/TreeView.d.ts +1 -1
- package/dist/components/tree-view/TreeView.js +2 -0
- package/dist/components/tree-view/TreeView.module.css +8 -0
- package/dist/components/tree-view/types.d.ts +2 -0
- package/dist/components/tree-view/useTreeExpansion.cjs +12 -2
- package/dist/components/tree-view/useTreeExpansion.d.ts +1 -0
- package/dist/components/tree-view/useTreeExpansion.js +12 -2
- package/dist/components/xml-viewer/XmlViewer.cjs +2 -1
- package/dist/components/xml-viewer/XmlViewer.js +3 -2
- package/dist/hooks/useTreeViewSettings.cjs +87 -0
- package/dist/hooks/useTreeViewSettings.d.ts +35 -0
- package/dist/hooks/useTreeViewSettings.js +84 -0
- package/package.json +1 -1
package/dist/client.cjs
CHANGED
|
@@ -22,6 +22,7 @@ var useColorScheme = require('./hooks/useColorScheme');
|
|
|
22
22
|
var useGetActiveTheme = require('./hooks/useGetActiveTheme');
|
|
23
23
|
var useTheme = require('./hooks/useTheme');
|
|
24
24
|
var usePersistentState = require('./hooks/usePersistentState');
|
|
25
|
+
var useTreeViewSettings = require('./hooks/useTreeViewSettings');
|
|
25
26
|
var Chip = require('./components/chip/Chip');
|
|
26
27
|
var Panel = require('./components/panel/Panel');
|
|
27
28
|
var Card = require('./components/card/Card');
|
|
@@ -231,6 +232,12 @@ Object.keys(usePersistentState).forEach(function (k) {
|
|
|
231
232
|
get: function () { return usePersistentState[k]; }
|
|
232
233
|
});
|
|
233
234
|
});
|
|
235
|
+
Object.keys(useTreeViewSettings).forEach(function (k) {
|
|
236
|
+
if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
|
|
237
|
+
enumerable: true,
|
|
238
|
+
get: function () { return useTreeViewSettings[k]; }
|
|
239
|
+
});
|
|
240
|
+
});
|
|
234
241
|
Object.keys(Chip).forEach(function (k) {
|
|
235
242
|
if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
|
|
236
243
|
enumerable: true,
|
package/dist/client.d.ts
CHANGED
|
@@ -19,6 +19,7 @@ export * from './hooks/useColorScheme';
|
|
|
19
19
|
export * from './hooks/useGetActiveTheme';
|
|
20
20
|
export * from './hooks/useTheme';
|
|
21
21
|
export * from './hooks/usePersistentState';
|
|
22
|
+
export * from './hooks/useTreeViewSettings';
|
|
22
23
|
export * from './components/chip/Chip';
|
|
23
24
|
export * from './components/panel/Panel';
|
|
24
25
|
export * from './components/card/Card';
|
package/dist/client.js
CHANGED
|
@@ -20,6 +20,7 @@ export * from './hooks/useColorScheme';
|
|
|
20
20
|
export * from './hooks/useGetActiveTheme';
|
|
21
21
|
export * from './hooks/useTheme';
|
|
22
22
|
export * from './hooks/usePersistentState';
|
|
23
|
+
export * from './hooks/useTreeViewSettings';
|
|
23
24
|
export * from './components/chip/Chip';
|
|
24
25
|
export * from './components/panel/Panel';
|
|
25
26
|
export * from './components/card/Card';
|
|
@@ -41,7 +41,12 @@
|
|
|
41
41
|
flex: 1 1 auto;
|
|
42
42
|
min-inline-size: 0;
|
|
43
43
|
inline-size: 100%;
|
|
44
|
+
/* Size classes also apply to the field; keep the input inside its border. */
|
|
45
|
+
max-block-size: 100%;
|
|
44
46
|
box-sizing: border-box;
|
|
47
|
+
/* Matches `.field`'s radius so the autofill box-shadow below (which paints
|
|
48
|
+
within this element's own box) doesn't show sharp corners under it. */
|
|
49
|
+
border-radius: inherit;
|
|
45
50
|
text-overflow: ellipsis;
|
|
46
51
|
color: var(--color-fg-default);
|
|
47
52
|
background: transparent;
|
|
@@ -59,6 +64,94 @@
|
|
|
59
64
|
color: var(--color-fg-subtle) !important;
|
|
60
65
|
}
|
|
61
66
|
|
|
67
|
+
/* Match the design system's selection color instead of the browser default. */
|
|
68
|
+
.input::selection {
|
|
69
|
+
background-color: var(--color-bg-selected);
|
|
70
|
+
color: var(--color-fg-default);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.input::-moz-selection {
|
|
74
|
+
background-color: var(--color-bg-selected);
|
|
75
|
+
color: var(--color-fg-default);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/* Neutralize the browser's native autofill tint (Chrome's light-blue fill,
|
|
79
|
+
applied via this pseudo-class) so a filled field keeps the field's normal
|
|
80
|
+
background instead of the browser's own color - this also fires for
|
|
81
|
+
Chrome's "previous values typed in this field" history dropdown, which
|
|
82
|
+
uses the same autofill styling even though it's not real autofill data.
|
|
83
|
+
The huge transition delay is the standard trick to stop Chrome animating
|
|
84
|
+
its own background/text color in on top of this.
|
|
85
|
+
|
|
86
|
+
The field overlay below keeps the focus ring above this opaque fill. */
|
|
87
|
+
.input:-webkit-autofill,
|
|
88
|
+
.input:-webkit-autofill:hover {
|
|
89
|
+
-webkit-text-fill-color: var(--color-fg-default);
|
|
90
|
+
-webkit-box-shadow: 0 0 0 1000px var(--color-bg-surface) inset;
|
|
91
|
+
box-shadow: 0 0 0 1000px var(--color-bg-surface) inset;
|
|
92
|
+
transition:
|
|
93
|
+
background-color 600000s 0s,
|
|
94
|
+
color 600000s 0s;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
.subtle .input:-webkit-autofill,
|
|
98
|
+
.subtle .input:-webkit-autofill:hover {
|
|
99
|
+
-webkit-box-shadow: 0 0 0 1000px var(--color-bg-toolbar) inset;
|
|
100
|
+
box-shadow: 0 0 0 1000px var(--color-bg-toolbar) inset;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.embedded .input:-webkit-autofill,
|
|
104
|
+
.embedded .input:-webkit-autofill:hover,
|
|
105
|
+
.embedded .input:-webkit-autofill:focus {
|
|
106
|
+
-webkit-box-shadow: 0 0 0 1000px transparent inset;
|
|
107
|
+
box-shadow: 0 0 0 1000px transparent inset;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
.header .input:-webkit-autofill,
|
|
111
|
+
.header .input:-webkit-autofill:hover {
|
|
112
|
+
-webkit-box-shadow: 0 0 0 1000px transparent inset;
|
|
113
|
+
box-shadow: 0 0 0 1000px transparent inset;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
.header .input:-webkit-autofill {
|
|
117
|
+
-webkit-text-fill-color: var(--color-navbar-fg);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/* Paint over the autofill fill using the whole field's geometry, including
|
|
121
|
+
adornments. A ring on the input itself creates an extra inner rectangle.
|
|
122
|
+
Keep this overlay non-interactive so clear buttons remain clickable. */
|
|
123
|
+
.field:has(.input:-webkit-autofill)::after {
|
|
124
|
+
content: '';
|
|
125
|
+
position: absolute;
|
|
126
|
+
inset: 0;
|
|
127
|
+
border-radius: inherit;
|
|
128
|
+
pointer-events: none;
|
|
129
|
+
box-shadow: inset 0 0 0 var(--border-width-thin)
|
|
130
|
+
var(--input-autofill-ring, var(--color-field-focus));
|
|
131
|
+
opacity: 0;
|
|
132
|
+
transition: opacity var(--transition-fast) var(--ease-standard);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
.field:has(.input:-webkit-autofill):focus-within:not([aria-disabled='true'])::after {
|
|
136
|
+
opacity: 1;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
.header {
|
|
140
|
+
--input-autofill-ring: var(--color-navbar-fg);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
.modified {
|
|
144
|
+
--input-autofill-ring: color-mix(
|
|
145
|
+
in srgb,
|
|
146
|
+
var(--color-status-warning-border) 55%,
|
|
147
|
+
var(--color-border-default)
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
.embedded:has(.input:-webkit-autofill)::after {
|
|
152
|
+
content: none;
|
|
153
|
+
}
|
|
154
|
+
|
|
62
155
|
.input:disabled {
|
|
63
156
|
background-color: transparent;
|
|
64
157
|
color: var(--color-disabled-fg);
|
|
@@ -12,6 +12,7 @@ var styles = require('./JsonViewer.module.css');
|
|
|
12
12
|
var useClipboardStatus = require('./useClipboardStatus');
|
|
13
13
|
var utils = require('./utils');
|
|
14
14
|
var Button = require('../button/Button');
|
|
15
|
+
var Icon = require('../icon/Icon');
|
|
15
16
|
|
|
16
17
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
17
18
|
|
|
@@ -151,7 +152,7 @@ function JsonViewer({
|
|
|
151
152
|
"aria-haspopup": "menu",
|
|
152
153
|
"aria-expanded": isOpen ? true : false,
|
|
153
154
|
onClick: toggle,
|
|
154
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.
|
|
155
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Icon.Icon, { customIcon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Settings2, { "aria-hidden": "true" }) })
|
|
155
156
|
}
|
|
156
157
|
),
|
|
157
158
|
children: (close) => /* @__PURE__ */ jsxRuntime.jsxs(Menu.Menu, { children: [
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
3
|
-
import { Search, X, ArrowDown, ArrowUp, ListTree, Braces, Sun, Moon, ClipboardCopy,
|
|
3
|
+
import { Search, X, ArrowDown, ArrowUp, ListTree, Braces, Sun, Moon, ClipboardCopy, Settings2 } from 'lucide-react';
|
|
4
4
|
import { useState, useId, useEffect, useMemo } from 'react';
|
|
5
5
|
import { Menu } from '../../components/menu/Menu';
|
|
6
6
|
import { Popover } from '../../components/popover/Popover';
|
|
@@ -10,6 +10,7 @@ import styles from './JsonViewer.module.css';
|
|
|
10
10
|
import { useClipboardStatus } from './useClipboardStatus';
|
|
11
11
|
import { normalizeSearch, isJsonValue, collectSearchMatches, collectExpandableNodeIds, collectInitiallyExpandedNodeIds } from './utils';
|
|
12
12
|
import { Button } from '../button/Button';
|
|
13
|
+
import { Icon } from '../icon/Icon';
|
|
13
14
|
|
|
14
15
|
const COPY_ALL_ID = "__json-viewer-copy-all__";
|
|
15
16
|
function JsonViewer({
|
|
@@ -145,7 +146,7 @@ function JsonViewer({
|
|
|
145
146
|
"aria-haspopup": "menu",
|
|
146
147
|
"aria-expanded": isOpen ? true : false,
|
|
147
148
|
onClick: toggle,
|
|
148
|
-
children: /* @__PURE__ */ jsx(
|
|
149
|
+
children: /* @__PURE__ */ jsx(Icon, { customIcon: /* @__PURE__ */ jsx(Settings2, { "aria-hidden": "true" }) })
|
|
149
150
|
}
|
|
150
151
|
),
|
|
151
152
|
children: (close) => /* @__PURE__ */ jsxs(Menu, { children: [
|
|
@@ -10,6 +10,7 @@ var usePersistentState = require('../../hooks/usePersistentState');
|
|
|
10
10
|
var styles = require('./LineViewer.module.css');
|
|
11
11
|
var tokenizeLineFormat = require('./tokenizeLineFormat');
|
|
12
12
|
var Button = require('../button/Button');
|
|
13
|
+
var Icon = require('../icon/Icon');
|
|
13
14
|
|
|
14
15
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
15
16
|
|
|
@@ -87,7 +88,7 @@ function LineViewer({
|
|
|
87
88
|
"aria-haspopup": "menu",
|
|
88
89
|
"aria-expanded": isOpen ? true : false,
|
|
89
90
|
onClick: toggle,
|
|
90
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.
|
|
91
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Icon.Icon, { customIcon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Settings2, { "aria-hidden": "true" }) })
|
|
91
92
|
}
|
|
92
93
|
),
|
|
93
94
|
children: (close) => /* @__PURE__ */ jsxRuntime.jsxs(Menu.Menu, { children: [
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
3
|
-
import { TextWrap, ListTree, Code2, Sun, Moon, ClipboardCopy,
|
|
3
|
+
import { TextWrap, ListTree, Code2, Sun, Moon, ClipboardCopy, Settings2 } from 'lucide-react';
|
|
4
4
|
import { useMemo, useRef } from 'react';
|
|
5
5
|
import { Menu } from '../../components/menu/Menu';
|
|
6
6
|
import { Popover } from '../../components/popover/Popover';
|
|
@@ -8,6 +8,7 @@ import { usePersistentState } from '../../hooks/usePersistentState';
|
|
|
8
8
|
import styles from './LineViewer.module.css';
|
|
9
9
|
import { tokenizeLineFormat } from './tokenizeLineFormat';
|
|
10
10
|
import { Button } from '../button/Button';
|
|
11
|
+
import { Icon } from '../icon/Icon';
|
|
11
12
|
|
|
12
13
|
const TOKEN_CLASS = {
|
|
13
14
|
tag: styles.tag,
|
|
@@ -81,7 +82,7 @@ function LineViewer({
|
|
|
81
82
|
"aria-haspopup": "menu",
|
|
82
83
|
"aria-expanded": isOpen ? true : false,
|
|
83
84
|
onClick: toggle,
|
|
84
|
-
children: /* @__PURE__ */ jsx(
|
|
85
|
+
children: /* @__PURE__ */ jsx(Icon, { customIcon: /* @__PURE__ */ jsx(Settings2, { "aria-hidden": "true" }) })
|
|
85
86
|
}
|
|
86
87
|
),
|
|
87
88
|
children: (close) => /* @__PURE__ */ jsxs(Menu, { children: [
|
|
@@ -145,7 +145,7 @@ const Popover = React.forwardRef(function Popover2({
|
|
|
145
145
|
React.useImperativeHandle(
|
|
146
146
|
ref,
|
|
147
147
|
() => ({
|
|
148
|
-
close: () => closePopover("api"),
|
|
148
|
+
close: (opts) => closePopover((opts == null ? void 0 : opts.returnFocus) === false ? "dismiss" : "api"),
|
|
149
149
|
open: openPopover,
|
|
150
150
|
isOpen: () => isOpen
|
|
151
151
|
}),
|
|
@@ -265,6 +265,7 @@ const Popover = React.forwardRef(function Popover2({
|
|
|
265
265
|
if (isOpen) return;
|
|
266
266
|
if (!returnFocus) return;
|
|
267
267
|
if (lastCloseReasonRef.current === "outside") return;
|
|
268
|
+
if (lastCloseReasonRef.current === "dismiss") return;
|
|
268
269
|
(_b = (_a = triggerElRef.current) == null ? void 0 : _a.focus) == null ? void 0 : _b.call(_a);
|
|
269
270
|
}, [isOpen, returnFocus]);
|
|
270
271
|
const chevronClassName = variant === "header" ? styles__default.default.chevronHeader : void 0;
|
|
@@ -22,7 +22,14 @@ export interface PopoverProps {
|
|
|
22
22
|
variant?: 'default' | 'header';
|
|
23
23
|
}
|
|
24
24
|
export interface PopoverHandle {
|
|
25
|
-
|
|
25
|
+
/**
|
|
26
|
+
* Pass `{ returnFocus: false }` to close without focus returning to the
|
|
27
|
+
* trigger afterward - e.g. when the caller is about to navigate away or
|
|
28
|
+
* move focus itself, so the trigger shouldn't reclaim it back.
|
|
29
|
+
*/
|
|
30
|
+
close: (opts?: {
|
|
31
|
+
returnFocus?: boolean;
|
|
32
|
+
}) => void;
|
|
26
33
|
open: () => void;
|
|
27
34
|
isOpen: () => boolean;
|
|
28
35
|
}
|
|
@@ -121,7 +121,7 @@ const Popover = forwardRef(function Popover2({
|
|
|
121
121
|
useImperativeHandle(
|
|
122
122
|
ref,
|
|
123
123
|
() => ({
|
|
124
|
-
close: () => closePopover("api"),
|
|
124
|
+
close: (opts) => closePopover((opts == null ? void 0 : opts.returnFocus) === false ? "dismiss" : "api"),
|
|
125
125
|
open: openPopover,
|
|
126
126
|
isOpen: () => isOpen
|
|
127
127
|
}),
|
|
@@ -241,6 +241,7 @@ const Popover = forwardRef(function Popover2({
|
|
|
241
241
|
if (isOpen) return;
|
|
242
242
|
if (!returnFocus) return;
|
|
243
243
|
if (lastCloseReasonRef.current === "outside") return;
|
|
244
|
+
if (lastCloseReasonRef.current === "dismiss") return;
|
|
244
245
|
(_b = (_a = triggerElRef.current) == null ? void 0 : _a.focus) == null ? void 0 : _b.call(_a);
|
|
245
246
|
}, [isOpen, returnFocus]);
|
|
246
247
|
const chevronClassName = variant === "header" ? styles.chevronHeader : void 0;
|
|
@@ -27,6 +27,7 @@ const SearchBox = react.forwardRef(function SearchBoxInner({
|
|
|
27
27
|
resultKeys,
|
|
28
28
|
resultTemplate,
|
|
29
29
|
initialTemplate,
|
|
30
|
+
initialTemplateOnly = false,
|
|
30
31
|
popoverMinWidth = "500px",
|
|
31
32
|
noResultText = "Ingen resultater",
|
|
32
33
|
loading,
|
|
@@ -99,34 +100,36 @@ const SearchBox = react.forwardRef(function SearchBoxInner({
|
|
|
99
100
|
}, [enableHotkey]);
|
|
100
101
|
const hasInitialTemplate = initialTemplate !== void 0 && initialTemplate !== null;
|
|
101
102
|
const hasQuery = draft.trim().length > 0;
|
|
102
|
-
const canShowPopover = hasQuery || hasInitialTemplate;
|
|
103
|
+
const canShowPopover = initialTemplateOnly ? !hasQuery && hasInitialTemplate : hasQuery || hasInitialTemplate;
|
|
103
104
|
const handleChange = react.useCallback(
|
|
104
105
|
(e) => {
|
|
105
106
|
var _a2, _b, _c;
|
|
106
107
|
const nextDraft = e.target.value;
|
|
107
108
|
const nextHasQuery = nextDraft.trim().length > 0;
|
|
108
109
|
setDraft(nextDraft);
|
|
109
|
-
|
|
110
|
+
const nextCanShow = initialTemplateOnly ? !nextHasQuery && hasInitialTemplate : nextHasQuery || hasInitialTemplate;
|
|
111
|
+
if (nextCanShow) {
|
|
110
112
|
if (!((_a2 = popoverRef.current) == null ? void 0 : _a2.isOpen())) (_b = popoverRef.current) == null ? void 0 : _b.open();
|
|
111
113
|
} else {
|
|
112
114
|
(_c = popoverRef.current) == null ? void 0 : _c.close();
|
|
113
115
|
}
|
|
114
116
|
onChange == null ? void 0 : onChange(e);
|
|
115
117
|
},
|
|
116
|
-
[hasInitialTemplate, onChange]
|
|
118
|
+
[hasInitialTemplate, initialTemplateOnly, onChange]
|
|
117
119
|
);
|
|
118
120
|
const handleSelect = react.useCallback(
|
|
119
121
|
(item) => {
|
|
120
122
|
onSelect == null ? void 0 : onSelect(item);
|
|
121
|
-
reset();
|
|
123
|
+
reset({ returnFocus: false });
|
|
124
|
+
onSearch == null ? void 0 : onSearch("");
|
|
122
125
|
},
|
|
123
|
-
[onSelect]
|
|
126
|
+
[onSelect, onSearch]
|
|
124
127
|
);
|
|
125
|
-
function reset() {
|
|
128
|
+
function reset(opts) {
|
|
126
129
|
var _a2;
|
|
127
130
|
setDraft("");
|
|
128
131
|
setActiveIndex(null);
|
|
129
|
-
(_a2 = popoverRef.current) == null ? void 0 : _a2.close();
|
|
132
|
+
(_a2 = popoverRef.current) == null ? void 0 : _a2.close(opts);
|
|
130
133
|
}
|
|
131
134
|
const handleClear = react.useCallback(() => {
|
|
132
135
|
var _a2;
|
|
@@ -15,6 +15,13 @@ export type SearchBoxProps<T extends Record<string, unknown>> = Omit<InputProps,
|
|
|
15
15
|
onSelect?: (item: T) => void;
|
|
16
16
|
displayPopover?: boolean;
|
|
17
17
|
initialTemplate?: React.ReactNode;
|
|
18
|
+
/**
|
|
19
|
+
* When true, the popover only ever shows `initialTemplate` (on an empty
|
|
20
|
+
* field) and never opens once there's a query - for a box with no live
|
|
21
|
+
* results/resultTemplate of its own (e.g. one that just navigates via a
|
|
22
|
+
* URL param), so it doesn't pop open an empty dropdown while typing.
|
|
23
|
+
*/
|
|
24
|
+
initialTemplateOnly?: boolean;
|
|
18
25
|
noResultText?: string;
|
|
19
26
|
popoverMinWidth?: string;
|
|
20
27
|
loading?: boolean;
|
|
@@ -21,6 +21,7 @@ const SearchBox = forwardRef(function SearchBoxInner({
|
|
|
21
21
|
resultKeys,
|
|
22
22
|
resultTemplate,
|
|
23
23
|
initialTemplate,
|
|
24
|
+
initialTemplateOnly = false,
|
|
24
25
|
popoverMinWidth = "500px",
|
|
25
26
|
noResultText = "Ingen resultater",
|
|
26
27
|
loading,
|
|
@@ -93,34 +94,36 @@ const SearchBox = forwardRef(function SearchBoxInner({
|
|
|
93
94
|
}, [enableHotkey]);
|
|
94
95
|
const hasInitialTemplate = initialTemplate !== void 0 && initialTemplate !== null;
|
|
95
96
|
const hasQuery = draft.trim().length > 0;
|
|
96
|
-
const canShowPopover = hasQuery || hasInitialTemplate;
|
|
97
|
+
const canShowPopover = initialTemplateOnly ? !hasQuery && hasInitialTemplate : hasQuery || hasInitialTemplate;
|
|
97
98
|
const handleChange = useCallback(
|
|
98
99
|
(e) => {
|
|
99
100
|
var _a2, _b, _c;
|
|
100
101
|
const nextDraft = e.target.value;
|
|
101
102
|
const nextHasQuery = nextDraft.trim().length > 0;
|
|
102
103
|
setDraft(nextDraft);
|
|
103
|
-
|
|
104
|
+
const nextCanShow = initialTemplateOnly ? !nextHasQuery && hasInitialTemplate : nextHasQuery || hasInitialTemplate;
|
|
105
|
+
if (nextCanShow) {
|
|
104
106
|
if (!((_a2 = popoverRef.current) == null ? void 0 : _a2.isOpen())) (_b = popoverRef.current) == null ? void 0 : _b.open();
|
|
105
107
|
} else {
|
|
106
108
|
(_c = popoverRef.current) == null ? void 0 : _c.close();
|
|
107
109
|
}
|
|
108
110
|
onChange == null ? void 0 : onChange(e);
|
|
109
111
|
},
|
|
110
|
-
[hasInitialTemplate, onChange]
|
|
112
|
+
[hasInitialTemplate, initialTemplateOnly, onChange]
|
|
111
113
|
);
|
|
112
114
|
const handleSelect = useCallback(
|
|
113
115
|
(item) => {
|
|
114
116
|
onSelect == null ? void 0 : onSelect(item);
|
|
115
|
-
reset();
|
|
117
|
+
reset({ returnFocus: false });
|
|
118
|
+
onSearch == null ? void 0 : onSearch("");
|
|
116
119
|
},
|
|
117
|
-
[onSelect]
|
|
120
|
+
[onSelect, onSearch]
|
|
118
121
|
);
|
|
119
|
-
function reset() {
|
|
122
|
+
function reset(opts) {
|
|
120
123
|
var _a2;
|
|
121
124
|
setDraft("");
|
|
122
125
|
setActiveIndex(null);
|
|
123
|
-
(_a2 = popoverRef.current) == null ? void 0 : _a2.close();
|
|
126
|
+
(_a2 = popoverRef.current) == null ? void 0 : _a2.close(opts);
|
|
124
127
|
}
|
|
125
128
|
const handleClear = useCallback(() => {
|
|
126
129
|
var _a2;
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
var jsxRuntime = require('react/jsx-runtime');
|
|
5
5
|
var lucideReact = require('lucide-react');
|
|
6
6
|
var React = require('react');
|
|
7
|
+
var Icon = require('../../../../components/icon/Icon');
|
|
7
8
|
var Button = require('../../../button/Button');
|
|
8
9
|
var Menu = require('../../../menu/Menu');
|
|
9
10
|
var Popover = require('../../../popover/Popover');
|
|
@@ -73,7 +74,7 @@ const SidenavFiltering = ({
|
|
|
73
74
|
variant: "outlined",
|
|
74
75
|
"aria-label": "\xC5bn indstillinger for sidemenu",
|
|
75
76
|
onClick: toggle,
|
|
76
|
-
icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Settings2, {})
|
|
77
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(Icon.Icon, { customIcon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Settings2, { "aria-hidden": "true" }) })
|
|
77
78
|
}
|
|
78
79
|
),
|
|
79
80
|
children: (close) => /* @__PURE__ */ jsxRuntime.jsx(Menu.Menu, { children: /* @__PURE__ */ jsxRuntime.jsx(Menu.Menu.Item, { active: wrapItemText, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
3
3
|
import { Search, Settings2 } from 'lucide-react';
|
|
4
4
|
import React from 'react';
|
|
5
|
+
import { Icon } from '../../../../components/icon/Icon';
|
|
5
6
|
import { Button } from '../../../button/Button';
|
|
6
7
|
import { Menu } from '../../../menu/Menu';
|
|
7
8
|
import { Popover } from '../../../popover/Popover';
|
|
@@ -67,7 +68,7 @@ const SidenavFiltering = ({
|
|
|
67
68
|
variant: "outlined",
|
|
68
69
|
"aria-label": "\xC5bn indstillinger for sidemenu",
|
|
69
70
|
onClick: toggle,
|
|
70
|
-
icon: /* @__PURE__ */ jsx(Settings2, {})
|
|
71
|
+
icon: /* @__PURE__ */ jsx(Icon, { customIcon: /* @__PURE__ */ jsx(Settings2, { "aria-hidden": "true" }) })
|
|
71
72
|
}
|
|
72
73
|
),
|
|
73
74
|
children: (close) => /* @__PURE__ */ jsx(Menu, { children: /* @__PURE__ */ jsx(Menu.Item, { active: wrapItemText, children: /* @__PURE__ */ jsx(
|
|
@@ -150,62 +150,64 @@ function Tabs({
|
|
|
150
150
|
) : null,
|
|
151
151
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: `${styles__default.default.tabs} ${styles__default.default[variant]} ${panelStyle ? styles__default.default.panelStyle : ""}`, children: [
|
|
152
152
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: styles__default.default.tabList, children: [
|
|
153
|
-
/* @__PURE__ */ jsxRuntime.
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
153
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: styles__default.default.tabStrip, children: [
|
|
154
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
155
|
+
"div",
|
|
156
|
+
{
|
|
157
|
+
className: onAddTab ? styles__default.default.tabButtons : `${styles__default.default.tabButtons} ${styles__default.default.tabButtonsEnd}`,
|
|
158
|
+
role: "tablist",
|
|
159
|
+
"aria-label": header != null ? header : "Tabs",
|
|
160
|
+
children: visibleTabs.map((tab, index) => {
|
|
161
|
+
const selected = index === activeIndex;
|
|
162
|
+
const tabDomId = `${uid}-tab-${String(tab.id)}`;
|
|
163
|
+
const panelDomId = `${uid}-panel-${String(tab.id)}`;
|
|
164
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `${styles__default.default.tab} ${selected ? styles__default.default.active : ""}`, children: [
|
|
165
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
166
|
+
"button",
|
|
167
|
+
{
|
|
168
|
+
id: tabDomId,
|
|
169
|
+
type: "button",
|
|
170
|
+
className: styles__default.default.tabButton,
|
|
171
|
+
role: "tab",
|
|
172
|
+
"aria-selected": selected,
|
|
173
|
+
"aria-controls": panelDomId,
|
|
174
|
+
tabIndex: selected ? 0 : -1,
|
|
175
|
+
disabled: tab.disabled,
|
|
176
|
+
onClick: () => setValue(tab.id),
|
|
177
|
+
onKeyDown: (e) => onKeyDownTab(e, index),
|
|
178
|
+
children: [
|
|
179
|
+
tab.headerIcon ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: styles__default.default.icon, children: tab.headerIcon }) : null,
|
|
180
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: styles__default.default.label, children: tab.header }),
|
|
181
|
+
tab.badge ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: styles__default.default.badge, children: /* @__PURE__ */ jsxRuntime.jsx(Chip.Chip, { size: "sm", children: tab.badge.toLocaleString("da-DK") }) }) : null
|
|
182
|
+
]
|
|
183
|
+
}
|
|
184
|
+
),
|
|
185
|
+
tab.removable && onRemoveTab ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
186
|
+
"button",
|
|
187
|
+
{
|
|
188
|
+
type: "button",
|
|
189
|
+
className: styles__default.default.removeTabButton,
|
|
190
|
+
"aria-label": `Fjern fane ${tab.header}`,
|
|
191
|
+
disabled: tab.disabled,
|
|
192
|
+
onClick: () => onRemoveTab(tab.id, tab, index),
|
|
193
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { "aria-hidden": "true" })
|
|
194
|
+
}
|
|
195
|
+
) : null
|
|
196
|
+
] }, tab.id);
|
|
197
|
+
})
|
|
198
|
+
}
|
|
199
|
+
),
|
|
200
|
+
onAddTab ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
201
|
+
"button",
|
|
202
|
+
{
|
|
203
|
+
type: "button",
|
|
204
|
+
className: styles__default.default.addTabButton,
|
|
205
|
+
onClick: onAddTab,
|
|
206
|
+
"aria-label": "Tilf\xF8j fane",
|
|
207
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { "aria-hidden": "true" })
|
|
208
|
+
}
|
|
209
|
+
) : null
|
|
210
|
+
] }),
|
|
209
211
|
tabListAddition ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles__default.default.tabListAddition, children: tabListAddition }) : null
|
|
210
212
|
] }),
|
|
211
213
|
/* @__PURE__ */ jsxRuntime.jsx(
|