@dbcdk/react-components 0.0.187 → 0.0.189
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/badge/Badge.cjs +28 -0
- package/dist/components/badge/Badge.d.ts +16 -0
- package/dist/components/badge/Badge.js +21 -0
- package/dist/components/badge/Badge.module.css +53 -0
- package/dist/components/chip/Chip.module.css +2 -1
- package/dist/components/circle/Circle.module.css +4 -0
- package/dist/components/forms/input-container/InputContainer.cjs +11 -4
- package/dist/components/forms/input-container/InputContainer.d.ts +1 -1
- package/dist/components/forms/input-container/InputContainer.js +11 -4
- package/dist/components/forms/text-area/Textarea.cjs +2 -1
- package/dist/components/forms/text-area/Textarea.js +2 -1
- package/dist/components/metric-tile/MetricTile.cjs +25 -0
- package/dist/components/metric-tile/MetricTile.d.ts +1 -0
- package/dist/components/metric-tile/MetricTile.js +25 -0
- package/dist/components/metric-tile/MetricTile.module.css +8 -0
- package/dist/components/overlay/tooltip/TooltipProvider.cjs +9 -5
- package/dist/components/overlay/tooltip/TooltipProvider.js +9 -5
- package/dist/components/table/Table.cjs +1 -0
- package/dist/components/table/Table.js +1 -0
- package/dist/components/table/Table.module.css +10 -5
- package/dist/components/table/components/TableHeader.cjs +2 -0
- package/dist/components/table/components/TableHeader.d.ts +2 -1
- package/dist/components/table/components/TableHeader.js +2 -0
- package/dist/components/table/components/TableHeaderCell.cjs +2 -1
- package/dist/components/table/components/TableHeaderCell.d.ts +2 -1
- package/dist/components/table/components/TableHeaderCell.js +3 -2
- package/dist/components/table/components/table-settings/TableSettings.cjs +74 -67
- package/dist/components/table/components/table-settings/TableSettings.d.ts +13 -4
- package/dist/components/table/components/table-settings/TableSettings.js +75 -69
- package/dist/components/tabs/Tabs.module.css +34 -4
- package/dist/index.cjs +7 -0
- package/dist/index.css +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/styles/styles.css +7 -0
- package/dist/styles.css +7 -0
- package/package.json +1 -1
package/dist/client.cjs
CHANGED
|
@@ -34,6 +34,7 @@ var SkeletonLoader = require('./components/skeleton-loader/SkeletonLoader');
|
|
|
34
34
|
var Page = require('./components/page/Page');
|
|
35
35
|
var Breadcrumbs = require('./components/breadcrumbs/Breadcrumbs');
|
|
36
36
|
var Circle = require('./components/circle/Circle');
|
|
37
|
+
var Badge = require('./components/badge/Badge');
|
|
37
38
|
var Checkbox = require('./components/forms/checkbox/Checkbox');
|
|
38
39
|
var Switch = require('./components/forms/switch/Switch');
|
|
39
40
|
var Table = require('./components/table/Table');
|
|
@@ -301,6 +302,12 @@ Object.keys(Circle).forEach(function (k) {
|
|
|
301
302
|
get: function () { return Circle[k]; }
|
|
302
303
|
});
|
|
303
304
|
});
|
|
305
|
+
Object.keys(Badge).forEach(function (k) {
|
|
306
|
+
if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
|
|
307
|
+
enumerable: true,
|
|
308
|
+
get: function () { return Badge[k]; }
|
|
309
|
+
});
|
|
310
|
+
});
|
|
304
311
|
Object.keys(Checkbox).forEach(function (k) {
|
|
305
312
|
if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
|
|
306
313
|
enumerable: true,
|
package/dist/client.d.ts
CHANGED
|
@@ -31,6 +31,7 @@ export * from './components/skeleton-loader/SkeletonLoader';
|
|
|
31
31
|
export * from './components/page/Page';
|
|
32
32
|
export * from './components/breadcrumbs/Breadcrumbs';
|
|
33
33
|
export * from './components/circle/Circle';
|
|
34
|
+
export * from './components/badge/Badge';
|
|
34
35
|
export * from './components/forms/checkbox/Checkbox';
|
|
35
36
|
export * from './components/forms/switch/Switch';
|
|
36
37
|
export * from './components/table/Table';
|
package/dist/client.js
CHANGED
|
@@ -32,6 +32,7 @@ export * from './components/skeleton-loader/SkeletonLoader';
|
|
|
32
32
|
export * from './components/page/Page';
|
|
33
33
|
export * from './components/breadcrumbs/Breadcrumbs';
|
|
34
34
|
export * from './components/circle/Circle';
|
|
35
|
+
export * from './components/badge/Badge';
|
|
35
36
|
export * from './components/forms/checkbox/Checkbox';
|
|
36
37
|
export * from './components/forms/switch/Switch';
|
|
37
38
|
export * from './components/table/Table';
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
+
var styles = require('./Badge.module.css');
|
|
5
|
+
|
|
6
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
7
|
+
|
|
8
|
+
var styles__default = /*#__PURE__*/_interopDefault(styles);
|
|
9
|
+
|
|
10
|
+
function formatBadgeCount(count, max) {
|
|
11
|
+
return count > max ? `${max}+` : String(count);
|
|
12
|
+
}
|
|
13
|
+
function Badge({
|
|
14
|
+
children,
|
|
15
|
+
count,
|
|
16
|
+
max = 99,
|
|
17
|
+
severity = "error",
|
|
18
|
+
dot = false
|
|
19
|
+
}) {
|
|
20
|
+
const showBadge = dot || typeof count === "number" && count > 0;
|
|
21
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("span", { className: styles__default.default.wrapper, children: [
|
|
22
|
+
children,
|
|
23
|
+
showBadge && /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${styles__default.default.badge} ${styles__default.default[severity]}`, "data-dot": dot || void 0, children: !dot && typeof count === "number" ? formatBadgeCount(count, max) : null })
|
|
24
|
+
] });
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
exports.Badge = Badge;
|
|
28
|
+
exports.formatBadgeCount = formatBadgeCount;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { ReactNode, JSX } from 'react';
|
|
2
|
+
import { Severity } from '../../constants/severity.types';
|
|
3
|
+
interface BadgeProps {
|
|
4
|
+
/** The element the badge is overlaid on top of, e.g. an icon. */
|
|
5
|
+
children: ReactNode;
|
|
6
|
+
/** Shown inside the badge, capped at `max`. Omit (with `dot` false) to render nothing. */
|
|
7
|
+
count?: number;
|
|
8
|
+
/** Counts above this render as `${max}+`. */
|
|
9
|
+
max?: number;
|
|
10
|
+
severity?: Severity;
|
|
11
|
+
/** Render a plain dot instead of a count - use when only "something changed" matters, not how much. */
|
|
12
|
+
dot?: boolean;
|
|
13
|
+
}
|
|
14
|
+
export declare function formatBadgeCount(count: number, max: number): string;
|
|
15
|
+
export declare function Badge({ children, count, max, severity, dot, }: BadgeProps): JSX.Element;
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
|
+
import styles from './Badge.module.css';
|
|
3
|
+
|
|
4
|
+
function formatBadgeCount(count, max) {
|
|
5
|
+
return count > max ? `${max}+` : String(count);
|
|
6
|
+
}
|
|
7
|
+
function Badge({
|
|
8
|
+
children,
|
|
9
|
+
count,
|
|
10
|
+
max = 99,
|
|
11
|
+
severity = "error",
|
|
12
|
+
dot = false
|
|
13
|
+
}) {
|
|
14
|
+
const showBadge = dot || typeof count === "number" && count > 0;
|
|
15
|
+
return /* @__PURE__ */ jsxs("span", { className: styles.wrapper, children: [
|
|
16
|
+
children,
|
|
17
|
+
showBadge && /* @__PURE__ */ jsx("span", { className: `${styles.badge} ${styles[severity]}`, "data-dot": dot || void 0, children: !dot && typeof count === "number" ? formatBadgeCount(count, max) : null })
|
|
18
|
+
] });
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export { Badge, formatBadgeCount };
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
.wrapper {
|
|
2
|
+
position: relative;
|
|
3
|
+
display: inline-flex;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
.badge {
|
|
7
|
+
box-sizing: border-box;
|
|
8
|
+
block-size: 14px;
|
|
9
|
+
min-inline-size: 14px;
|
|
10
|
+
padding-inline: var(--spacing-2xs);
|
|
11
|
+
border-radius: var(--border-radius-rounded);
|
|
12
|
+
font-size: 12px;
|
|
13
|
+
color: var(--color-fg-inverse);
|
|
14
|
+
pointer-events: none;
|
|
15
|
+
justify-content: center;
|
|
16
|
+
align-items: center;
|
|
17
|
+
line-height: 1;
|
|
18
|
+
display: inline-flex;
|
|
19
|
+
position: absolute;
|
|
20
|
+
top: 0;
|
|
21
|
+
right: 0;
|
|
22
|
+
transform: translate(50%, -30%);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.badge[data-dot='true'] {
|
|
26
|
+
min-inline-size: 8px;
|
|
27
|
+
inline-size: 8px;
|
|
28
|
+
block-size: 8px;
|
|
29
|
+
padding-inline: 0;
|
|
30
|
+
border-radius: var(--border-radius-round);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.neutral {
|
|
34
|
+
background-color: var(--color-neutral);
|
|
35
|
+
}
|
|
36
|
+
.brand {
|
|
37
|
+
background-color: var(--color-brand);
|
|
38
|
+
}
|
|
39
|
+
.accent {
|
|
40
|
+
background-color: var(--color-accent);
|
|
41
|
+
}
|
|
42
|
+
.success {
|
|
43
|
+
background-color: var(--color-status-success);
|
|
44
|
+
}
|
|
45
|
+
.warning {
|
|
46
|
+
background-color: var(--color-status-warning);
|
|
47
|
+
}
|
|
48
|
+
.error {
|
|
49
|
+
background-color: var(--color-status-error);
|
|
50
|
+
}
|
|
51
|
+
.info {
|
|
52
|
+
background-color: var(--color-status-info);
|
|
53
|
+
}
|
|
@@ -93,6 +93,7 @@
|
|
|
93
93
|
.sm {
|
|
94
94
|
height: var(--component-size-xs);
|
|
95
95
|
font-size: var(--font-size-xs);
|
|
96
|
+
padding-inline: var(--spacing-xs);
|
|
96
97
|
}
|
|
97
98
|
|
|
98
99
|
.md {
|
|
@@ -109,7 +110,7 @@
|
|
|
109
110
|
.neutral {
|
|
110
111
|
/* Tinted from the current foreground color instead of a fixed gray, so it
|
|
111
112
|
stays visible whether it's sitting on a white panel or a muted toolbar. */
|
|
112
|
-
--chip-bg: color-mix(in srgb, var(--color-fg-default)
|
|
113
|
+
--chip-bg: color-mix(in srgb, var(--color-fg-default) 8%, transparent);
|
|
113
114
|
--chip-fg: var(--color-fg-default);
|
|
114
115
|
--chip-border: transparent;
|
|
115
116
|
--chip-outlined-border: var(--color-border-subtle);
|
|
@@ -21,6 +21,7 @@ function InputContainer({
|
|
|
21
21
|
orientation = "horizontal",
|
|
22
22
|
size = "md",
|
|
23
23
|
labelWidth = "160px",
|
|
24
|
+
labelAlignment = "center",
|
|
24
25
|
modified = false
|
|
25
26
|
}) {
|
|
26
27
|
const renderLabelRow = (label || labelAction) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `${styles__default.default.labelRow} dbc-flex dbc-items-center dbc-gap-md`, children: [
|
|
@@ -59,10 +60,16 @@ function InputContainer({
|
|
|
59
60
|
width: fullWidth ? "100%" : void 0
|
|
60
61
|
},
|
|
61
62
|
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `${styles__default.default.horizontal} dbc-flex dbc-flex-column dbc-gap-xs`, "data-size": size, children: [
|
|
62
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
63
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
64
|
+
"div",
|
|
65
|
+
{
|
|
66
|
+
className: `${styles__default.default.labelContainer} dbc-flex ${labelAlignment === "top" ? "dbc-items-start" : "dbc-items-center"} dbc-gap-xs`,
|
|
67
|
+
children: [
|
|
68
|
+
renderLabelRow,
|
|
69
|
+
children
|
|
70
|
+
]
|
|
71
|
+
}
|
|
72
|
+
),
|
|
66
73
|
renderMessageRow
|
|
67
74
|
] })
|
|
68
75
|
}
|
|
@@ -15,4 +15,4 @@ export interface InputContainerProps {
|
|
|
15
15
|
labelAlignment?: 'top' | 'center';
|
|
16
16
|
modified?: boolean;
|
|
17
17
|
}
|
|
18
|
-
export declare function InputContainer({ label, labelAction, htmlFor, error, helpText, helpTextAddition, fullWidth, required, children, orientation, size, labelWidth, modified, }: InputContainerProps): React.ReactElement;
|
|
18
|
+
export declare function InputContainer({ label, labelAction, htmlFor, error, helpText, helpTextAddition, fullWidth, required, children, orientation, size, labelWidth, labelAlignment, modified, }: InputContainerProps): React.ReactElement;
|
|
@@ -15,6 +15,7 @@ function InputContainer({
|
|
|
15
15
|
orientation = "horizontal",
|
|
16
16
|
size = "md",
|
|
17
17
|
labelWidth = "160px",
|
|
18
|
+
labelAlignment = "center",
|
|
18
19
|
modified = false
|
|
19
20
|
}) {
|
|
20
21
|
const renderLabelRow = (label || labelAction) && /* @__PURE__ */ jsxs("div", { className: `${styles.labelRow} dbc-flex dbc-items-center dbc-gap-md`, children: [
|
|
@@ -53,10 +54,16 @@ function InputContainer({
|
|
|
53
54
|
width: fullWidth ? "100%" : void 0
|
|
54
55
|
},
|
|
55
56
|
children: /* @__PURE__ */ jsxs("div", { className: `${styles.horizontal} dbc-flex dbc-flex-column dbc-gap-xs`, "data-size": size, children: [
|
|
56
|
-
/* @__PURE__ */ jsxs(
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
57
|
+
/* @__PURE__ */ jsxs(
|
|
58
|
+
"div",
|
|
59
|
+
{
|
|
60
|
+
className: `${styles.labelContainer} dbc-flex ${labelAlignment === "top" ? "dbc-items-start" : "dbc-items-center"} dbc-gap-xs`,
|
|
61
|
+
children: [
|
|
62
|
+
renderLabelRow,
|
|
63
|
+
children
|
|
64
|
+
]
|
|
65
|
+
}
|
|
66
|
+
),
|
|
60
67
|
renderMessageRow
|
|
61
68
|
] })
|
|
62
69
|
}
|
|
@@ -28,6 +28,7 @@ const Textarea = function Textarea2({
|
|
|
28
28
|
label,
|
|
29
29
|
error,
|
|
30
30
|
helpText,
|
|
31
|
+
helpTextAddition,
|
|
31
32
|
orientation = "horizontal",
|
|
32
33
|
labelWidth = "160px",
|
|
33
34
|
fullWidth = false,
|
|
@@ -97,7 +98,7 @@ const Textarea = function Textarea2({
|
|
|
97
98
|
htmlFor: textareaId,
|
|
98
99
|
error,
|
|
99
100
|
helpText,
|
|
100
|
-
helpTextAddition: showCount ? `${value == null ? void 0 : value.length} tegn i denne boks` : void 0,
|
|
101
|
+
helpTextAddition: helpTextAddition != null ? helpTextAddition : showCount ? `${value == null ? void 0 : value.length} tegn i denne boks` : void 0,
|
|
101
102
|
orientation,
|
|
102
103
|
labelWidth,
|
|
103
104
|
fullWidth,
|
|
@@ -22,6 +22,7 @@ const Textarea = function Textarea2({
|
|
|
22
22
|
label,
|
|
23
23
|
error,
|
|
24
24
|
helpText,
|
|
25
|
+
helpTextAddition,
|
|
25
26
|
orientation = "horizontal",
|
|
26
27
|
labelWidth = "160px",
|
|
27
28
|
fullWidth = false,
|
|
@@ -91,7 +92,7 @@ const Textarea = function Textarea2({
|
|
|
91
92
|
htmlFor: textareaId,
|
|
92
93
|
error,
|
|
93
94
|
helpText,
|
|
94
|
-
helpTextAddition: showCount ? `${value == null ? void 0 : value.length} tegn i denne boks` : void 0,
|
|
95
|
+
helpTextAddition: helpTextAddition != null ? helpTextAddition : showCount ? `${value == null ? void 0 : value.length} tegn i denne boks` : void 0,
|
|
95
96
|
orientation,
|
|
96
97
|
labelWidth,
|
|
97
98
|
fullWidth,
|
|
@@ -51,6 +51,7 @@ const MetricTileBase = ({
|
|
|
51
51
|
label,
|
|
52
52
|
icon,
|
|
53
53
|
value,
|
|
54
|
+
onClick,
|
|
54
55
|
tooltip,
|
|
55
56
|
size = "md",
|
|
56
57
|
variant = "filled",
|
|
@@ -69,14 +70,38 @@ const MetricTileBase = ({
|
|
|
69
70
|
const resolvedValue = (_b = (_a = slots.Value) == null ? void 0 : _a.props.children) != null ? _b : value;
|
|
70
71
|
const resolvedAdornment = (_c = slots.Adornment) == null ? void 0 : _c.props.children;
|
|
71
72
|
const showValueRow = resolvedValue != null || resolvedAdornment != null;
|
|
73
|
+
const isClickable = onClick != null;
|
|
74
|
+
const handleKeyDown = (event) => {
|
|
75
|
+
if (!isClickable) return;
|
|
76
|
+
if (event.key === "Enter") {
|
|
77
|
+
event.preventDefault();
|
|
78
|
+
onClick == null ? void 0 : onClick();
|
|
79
|
+
}
|
|
80
|
+
if (event.key === " ") {
|
|
81
|
+
event.preventDefault();
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
const handleKeyUp = (event) => {
|
|
85
|
+
if (!isClickable) return;
|
|
86
|
+
if (event.key === " ") {
|
|
87
|
+
event.preventDefault();
|
|
88
|
+
onClick == null ? void 0 : onClick();
|
|
89
|
+
}
|
|
90
|
+
};
|
|
72
91
|
return /* @__PURE__ */ jsxRuntime.jsx(client.Tooltip, { content: tooltip, placement: "bottom", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
73
92
|
"span",
|
|
74
93
|
{
|
|
75
94
|
className: styles__default.default.tile,
|
|
95
|
+
role: isClickable ? "button" : void 0,
|
|
96
|
+
tabIndex: isClickable ? 0 : void 0,
|
|
76
97
|
"data-severity": severity,
|
|
77
98
|
"data-size": size,
|
|
78
99
|
"data-variant": variant,
|
|
100
|
+
"data-clickable": isClickable ? "true" : void 0,
|
|
79
101
|
style,
|
|
102
|
+
onClick,
|
|
103
|
+
onKeyDown: handleKeyDown,
|
|
104
|
+
onKeyUp: handleKeyUp,
|
|
80
105
|
children: [
|
|
81
106
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: styles__default.default.labelRow, children: [
|
|
82
107
|
icon != null ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: styles__default.default.icon, children: icon }) : null,
|
|
@@ -45,6 +45,7 @@ const MetricTileBase = ({
|
|
|
45
45
|
label,
|
|
46
46
|
icon,
|
|
47
47
|
value,
|
|
48
|
+
onClick,
|
|
48
49
|
tooltip,
|
|
49
50
|
size = "md",
|
|
50
51
|
variant = "filled",
|
|
@@ -63,14 +64,38 @@ const MetricTileBase = ({
|
|
|
63
64
|
const resolvedValue = (_b = (_a = slots.Value) == null ? void 0 : _a.props.children) != null ? _b : value;
|
|
64
65
|
const resolvedAdornment = (_c = slots.Adornment) == null ? void 0 : _c.props.children;
|
|
65
66
|
const showValueRow = resolvedValue != null || resolvedAdornment != null;
|
|
67
|
+
const isClickable = onClick != null;
|
|
68
|
+
const handleKeyDown = (event) => {
|
|
69
|
+
if (!isClickable) return;
|
|
70
|
+
if (event.key === "Enter") {
|
|
71
|
+
event.preventDefault();
|
|
72
|
+
onClick == null ? void 0 : onClick();
|
|
73
|
+
}
|
|
74
|
+
if (event.key === " ") {
|
|
75
|
+
event.preventDefault();
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
const handleKeyUp = (event) => {
|
|
79
|
+
if (!isClickable) return;
|
|
80
|
+
if (event.key === " ") {
|
|
81
|
+
event.preventDefault();
|
|
82
|
+
onClick == null ? void 0 : onClick();
|
|
83
|
+
}
|
|
84
|
+
};
|
|
66
85
|
return /* @__PURE__ */ jsx(Tooltip, { content: tooltip, placement: "bottom", children: /* @__PURE__ */ jsxs(
|
|
67
86
|
"span",
|
|
68
87
|
{
|
|
69
88
|
className: styles.tile,
|
|
89
|
+
role: isClickable ? "button" : void 0,
|
|
90
|
+
tabIndex: isClickable ? 0 : void 0,
|
|
70
91
|
"data-severity": severity,
|
|
71
92
|
"data-size": size,
|
|
72
93
|
"data-variant": variant,
|
|
94
|
+
"data-clickable": isClickable ? "true" : void 0,
|
|
73
95
|
style,
|
|
96
|
+
onClick,
|
|
97
|
+
onKeyDown: handleKeyDown,
|
|
98
|
+
onKeyUp: handleKeyUp,
|
|
74
99
|
children: [
|
|
75
100
|
/* @__PURE__ */ jsxs("span", { className: styles.labelRow, children: [
|
|
76
101
|
icon != null ? /* @__PURE__ */ jsx("span", { className: styles.icon, children: icon }) : null,
|
|
@@ -19,6 +19,14 @@
|
|
|
19
19
|
cursor: default;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
+
.tile[data-clickable='true'] {
|
|
23
|
+
cursor: pointer;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.tile[data-clickable='true']:focus-visible {
|
|
27
|
+
box-shadow: var(--focus-ring);
|
|
28
|
+
}
|
|
29
|
+
|
|
22
30
|
.tile[data-size='sm'] {
|
|
23
31
|
gap: 1px;
|
|
24
32
|
padding: 6px var(--spacing-sm);
|
|
@@ -119,7 +119,7 @@ function TooltipLayer() {
|
|
|
119
119
|
const triggerRect = trigger.getBoundingClientRect();
|
|
120
120
|
const bubbleRect = bubble.getBoundingClientRect();
|
|
121
121
|
if (bubbleRect.width === 0 || bubbleRect.height === 0) {
|
|
122
|
-
|
|
122
|
+
setVisible((prev) => prev ? false : prev);
|
|
123
123
|
if (rafRef.current) cancelAnimationFrame(rafRef.current);
|
|
124
124
|
rafRef.current = requestAnimationFrame(recompute);
|
|
125
125
|
return;
|
|
@@ -158,13 +158,17 @@ function TooltipLayer() {
|
|
|
158
158
|
lastPlacementRef.current = chosen;
|
|
159
159
|
setPlacement(chosen);
|
|
160
160
|
}
|
|
161
|
-
|
|
162
|
-
}, [active == null ? void 0 : active.open, active == null ? void 0 : active.triggerEl, active == null ? void 0 : active.placement, active == null ? void 0 : active.offset
|
|
161
|
+
setVisible((prev) => prev ? prev : true);
|
|
162
|
+
}, [active == null ? void 0 : active.open, active == null ? void 0 : active.triggerEl, active == null ? void 0 : active.placement, active == null ? void 0 : active.offset]);
|
|
163
163
|
react.useEffect(() => {
|
|
164
164
|
const nextOpen = !!(active == null ? void 0 : active.open);
|
|
165
165
|
setOpen((prev) => prev === nextOpen ? prev : nextOpen);
|
|
166
|
-
if (nextOpen)
|
|
167
|
-
|
|
166
|
+
if (nextOpen) {
|
|
167
|
+
setVisible(false);
|
|
168
|
+
} else {
|
|
169
|
+
setVisible(false);
|
|
170
|
+
lastActiveIdRef.current = null;
|
|
171
|
+
}
|
|
168
172
|
}, [active == null ? void 0 : active.open]);
|
|
169
173
|
react.useLayoutEffect(() => {
|
|
170
174
|
var _a;
|
|
@@ -113,7 +113,7 @@ function TooltipLayer() {
|
|
|
113
113
|
const triggerRect = trigger.getBoundingClientRect();
|
|
114
114
|
const bubbleRect = bubble.getBoundingClientRect();
|
|
115
115
|
if (bubbleRect.width === 0 || bubbleRect.height === 0) {
|
|
116
|
-
|
|
116
|
+
setVisible((prev) => prev ? false : prev);
|
|
117
117
|
if (rafRef.current) cancelAnimationFrame(rafRef.current);
|
|
118
118
|
rafRef.current = requestAnimationFrame(recompute);
|
|
119
119
|
return;
|
|
@@ -152,13 +152,17 @@ function TooltipLayer() {
|
|
|
152
152
|
lastPlacementRef.current = chosen;
|
|
153
153
|
setPlacement(chosen);
|
|
154
154
|
}
|
|
155
|
-
|
|
156
|
-
}, [active == null ? void 0 : active.open, active == null ? void 0 : active.triggerEl, active == null ? void 0 : active.placement, active == null ? void 0 : active.offset
|
|
155
|
+
setVisible((prev) => prev ? prev : true);
|
|
156
|
+
}, [active == null ? void 0 : active.open, active == null ? void 0 : active.triggerEl, active == null ? void 0 : active.placement, active == null ? void 0 : active.offset]);
|
|
157
157
|
useEffect(() => {
|
|
158
158
|
const nextOpen = !!(active == null ? void 0 : active.open);
|
|
159
159
|
setOpen((prev) => prev === nextOpen ? prev : nextOpen);
|
|
160
|
-
if (nextOpen)
|
|
161
|
-
|
|
160
|
+
if (nextOpen) {
|
|
161
|
+
setVisible(false);
|
|
162
|
+
} else {
|
|
163
|
+
setVisible(false);
|
|
164
|
+
lastActiveIdRef.current = null;
|
|
165
|
+
}
|
|
162
166
|
}, [active == null ? void 0 : active.open]);
|
|
163
167
|
useLayoutEffect(() => {
|
|
164
168
|
var _a;
|
|
@@ -58,6 +58,7 @@
|
|
|
58
58
|
--table-component-cell-fg: var(--table-cell-fg);
|
|
59
59
|
--table-component-cell-border: var(--table-border-subtle);
|
|
60
60
|
--table-component-divider: var(--table-divider);
|
|
61
|
+
--table-row-actions-reserve-inline: calc(var(--component-size-md) + 4px + var(--spacing-2xs));
|
|
61
62
|
|
|
62
63
|
display: flex;
|
|
63
64
|
flex-direction: column;
|
|
@@ -188,13 +189,13 @@
|
|
|
188
189
|
}
|
|
189
190
|
|
|
190
191
|
.md .headerCell {
|
|
191
|
-
padding-block: var(--spacing-
|
|
192
|
-
padding-inline: var(--spacing-
|
|
192
|
+
padding-block: var(--spacing-xxs);
|
|
193
|
+
padding-inline: var(--spacing-xs);
|
|
193
194
|
}
|
|
194
195
|
|
|
195
196
|
.md .cell {
|
|
196
|
-
padding-block: var(--spacing-
|
|
197
|
-
padding-inline: var(--spacing-
|
|
197
|
+
padding-block: var(--spacing-xxs);
|
|
198
|
+
padding-inline: var(--spacing-xs);
|
|
198
199
|
}
|
|
199
200
|
|
|
200
201
|
.sm .headerCell {
|
|
@@ -371,6 +372,10 @@
|
|
|
371
372
|
justify-content: flex-start;
|
|
372
373
|
}
|
|
373
374
|
|
|
375
|
+
.thMainWithActionsReserve {
|
|
376
|
+
padding-inline-end: var(--table-row-actions-reserve-inline);
|
|
377
|
+
}
|
|
378
|
+
|
|
374
379
|
.thMainRight {
|
|
375
380
|
justify-content: flex-end;
|
|
376
381
|
}
|
|
@@ -620,7 +625,7 @@
|
|
|
620
625
|
}
|
|
621
626
|
|
|
622
627
|
.cellContentWithActions {
|
|
623
|
-
padding-inline-end:
|
|
628
|
+
padding-inline-end: var(--table-row-actions-reserve-inline);
|
|
624
629
|
}
|
|
625
630
|
|
|
626
631
|
.contextMenuTrigger:hover,
|
|
@@ -13,6 +13,7 @@ function TableHeader({
|
|
|
13
13
|
columns,
|
|
14
14
|
hasSelection,
|
|
15
15
|
selectionMode,
|
|
16
|
+
hasRowContextMenu,
|
|
16
17
|
allRowsSelected,
|
|
17
18
|
onSelectAllRows,
|
|
18
19
|
sortById,
|
|
@@ -42,6 +43,7 @@ function TableHeader({
|
|
|
42
43
|
{
|
|
43
44
|
column,
|
|
44
45
|
index,
|
|
46
|
+
reserveInlineEnd: hasRowContextMenu && index === columns.length - 1,
|
|
45
47
|
sortById,
|
|
46
48
|
sortDirection,
|
|
47
49
|
onSortChange,
|
|
@@ -4,6 +4,7 @@ type Props<T> = {
|
|
|
4
4
|
columns: ColumnItem<T>[];
|
|
5
5
|
hasSelection: boolean;
|
|
6
6
|
selectionMode: 'single' | 'multiple';
|
|
7
|
+
hasRowContextMenu: boolean;
|
|
7
8
|
allRowsSelected?: boolean;
|
|
8
9
|
onSelectAllRows?: (isSelected: boolean) => void;
|
|
9
10
|
sortById?: string;
|
|
@@ -12,5 +13,5 @@ type Props<T> = {
|
|
|
12
13
|
headerExtras?: (args: HeaderExtrasArgs<T>) => ReactNode;
|
|
13
14
|
stickyTop?: string;
|
|
14
15
|
};
|
|
15
|
-
export declare function TableHeader<T>({ columns, hasSelection, selectionMode, allRowsSelected, onSelectAllRows, sortById, sortDirection, onSortChange, headerExtras, stickyTop, }: Props<T>): React.ReactNode;
|
|
16
|
+
export declare function TableHeader<T>({ columns, hasSelection, selectionMode, hasRowContextMenu, allRowsSelected, onSelectAllRows, sortById, sortDirection, onSortChange, headerExtras, stickyTop, }: Props<T>): React.ReactNode;
|
|
16
17
|
export {};
|
|
@@ -7,6 +7,7 @@ function TableHeader({
|
|
|
7
7
|
columns,
|
|
8
8
|
hasSelection,
|
|
9
9
|
selectionMode,
|
|
10
|
+
hasRowContextMenu,
|
|
10
11
|
allRowsSelected,
|
|
11
12
|
onSelectAllRows,
|
|
12
13
|
sortById,
|
|
@@ -36,6 +37,7 @@ function TableHeader({
|
|
|
36
37
|
{
|
|
37
38
|
column,
|
|
38
39
|
index,
|
|
40
|
+
reserveInlineEnd: hasRowContextMenu && index === columns.length - 1,
|
|
39
41
|
sortById,
|
|
40
42
|
sortDirection,
|
|
41
43
|
onSortChange,
|
|
@@ -13,6 +13,7 @@ var styles__default = /*#__PURE__*/_interopDefault(styles);
|
|
|
13
13
|
function TableHeaderCell({
|
|
14
14
|
column,
|
|
15
15
|
index,
|
|
16
|
+
reserveInlineEnd = false,
|
|
16
17
|
sortById,
|
|
17
18
|
sortDirection,
|
|
18
19
|
onSortChange,
|
|
@@ -37,7 +38,7 @@ function TableHeaderCell({
|
|
|
37
38
|
"data-divider": column.divider,
|
|
38
39
|
"data-column-index": index,
|
|
39
40
|
children: [
|
|
40
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: alignClasses.inner, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: alignClasses.main, children: column.sortable ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
41
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: alignClasses.inner, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: table_classes.cx(alignClasses.main, reserveInlineEnd && styles__default.default.thMainWithActionsReserve), children: column.sortable ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
41
42
|
"button",
|
|
42
43
|
{
|
|
43
44
|
type: "button",
|
|
@@ -3,10 +3,11 @@ import type { ColumnItem, SortDirection } from '../Table.types';
|
|
|
3
3
|
type Props<T> = {
|
|
4
4
|
column: ColumnItem<T>;
|
|
5
5
|
index: number;
|
|
6
|
+
reserveInlineEnd?: boolean;
|
|
6
7
|
sortById?: string;
|
|
7
8
|
sortDirection?: SortDirection;
|
|
8
9
|
onSortChange?: (column: ColumnItem<T>, direction: SortDirection) => void;
|
|
9
10
|
extraContent?: ReactNode;
|
|
10
11
|
};
|
|
11
|
-
export declare function TableHeaderCell<T>({ column, index, sortById, sortDirection, onSortChange, extraContent, }: Props<T>): ReactNode;
|
|
12
|
+
export declare function TableHeaderCell<T>({ column, index, reserveInlineEnd, sortById, sortDirection, onSortChange, extraContent, }: Props<T>): ReactNode;
|
|
12
13
|
export {};
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
2
|
import { ArrowUp, ArrowDown } from 'lucide-react';
|
|
3
|
-
import { getAlignValue, getHeaderAlignClasses } from '../table.classes';
|
|
3
|
+
import { getAlignValue, getHeaderAlignClasses, cx } from '../table.classes';
|
|
4
4
|
import styles from '../Table.module.css';
|
|
5
5
|
import { isActiveSort, getAriaSort, getHeaderLabel, shouldToggleOnKey, getNextSortDirection } from '../table.utils';
|
|
6
6
|
|
|
7
7
|
function TableHeaderCell({
|
|
8
8
|
column,
|
|
9
9
|
index,
|
|
10
|
+
reserveInlineEnd = false,
|
|
10
11
|
sortById,
|
|
11
12
|
sortDirection,
|
|
12
13
|
onSortChange,
|
|
@@ -31,7 +32,7 @@ function TableHeaderCell({
|
|
|
31
32
|
"data-divider": column.divider,
|
|
32
33
|
"data-column-index": index,
|
|
33
34
|
children: [
|
|
34
|
-
/* @__PURE__ */ jsx("div", { className: alignClasses.inner, children: /* @__PURE__ */ jsx("div", { className: alignClasses.main, children: column.sortable ? /* @__PURE__ */ jsxs(
|
|
35
|
+
/* @__PURE__ */ jsx("div", { className: alignClasses.inner, children: /* @__PURE__ */ jsx("div", { className: cx(alignClasses.main, reserveInlineEnd && styles.thMainWithActionsReserve), children: column.sortable ? /* @__PURE__ */ jsxs(
|
|
35
36
|
"button",
|
|
36
37
|
{
|
|
37
38
|
type: "button",
|
|
@@ -8,7 +8,7 @@ var Button = require('../../../button/Button');
|
|
|
8
8
|
var Menu = require('../../../menu/Menu');
|
|
9
9
|
var Popover = require('../../../popover/Popover');
|
|
10
10
|
|
|
11
|
-
function
|
|
11
|
+
function TableSettingsMenuSection({
|
|
12
12
|
viewMode,
|
|
13
13
|
handleChangeViewMode,
|
|
14
14
|
columns = [],
|
|
@@ -17,12 +17,12 @@ function TableSettings({
|
|
|
17
17
|
columnsLabel = "Kolonner",
|
|
18
18
|
allPresetLabel = "Alle",
|
|
19
19
|
standardPresetLabel = "Standard",
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
additionalSettings,
|
|
21
|
+
close
|
|
22
22
|
}) {
|
|
23
|
-
const handleViewModeChange = (mode,
|
|
23
|
+
const handleViewModeChange = (mode, close2) => {
|
|
24
24
|
handleChangeViewMode(mode === "wrapped" ? "compact" : "wrapped");
|
|
25
|
-
|
|
25
|
+
close2 == null ? void 0 : close2();
|
|
26
26
|
};
|
|
27
27
|
const hideableColumns = react.useMemo(() => columns.filter((c) => c.enableHiding !== false), [columns]);
|
|
28
28
|
const allPresetIds = react.useMemo(() => hideableColumns.map((c) => c.id), [hideableColumns]);
|
|
@@ -63,6 +63,73 @@ function TableSettings({
|
|
|
63
63
|
return hideableColumns.every((c) => c.id && visibleSet.has(c.id) === std.has(c.id));
|
|
64
64
|
}, [hideableColumns, visibleSet, standardPresetIds]);
|
|
65
65
|
const presetRadioName = "table-columns-preset";
|
|
66
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
67
|
+
additionalSettings == null ? void 0 : additionalSettings(close),
|
|
68
|
+
/* @__PURE__ */ jsxRuntime.jsx(Menu.Menu.Item, { active: viewMode === "wrapped", children: /* @__PURE__ */ jsxRuntime.jsxs("button", { type: "button", onClick: () => handleViewModeChange(viewMode, close), children: [
|
|
69
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ListChevronsUpDown, {}),
|
|
70
|
+
"Ombryd tekst"
|
|
71
|
+
] }) }),
|
|
72
|
+
hideableColumns.length > 0 && onVisibleColumnIdsChange ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
73
|
+
/* @__PURE__ */ jsxRuntime.jsx(Menu.Menu.Separator, {}),
|
|
74
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: { padding: "6px 10px", fontSize: 12, opacity: 0.7 }, children: columnsLabel }),
|
|
75
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
76
|
+
Menu.Menu.RadioItem,
|
|
77
|
+
{
|
|
78
|
+
name: presetRadioName,
|
|
79
|
+
value: "all",
|
|
80
|
+
checked: isAllActive,
|
|
81
|
+
label: allPresetLabel,
|
|
82
|
+
onValueChange: () => {
|
|
83
|
+
setVisibleIds(
|
|
84
|
+
allPresetIds.filter((id) => typeof id === "string" && Boolean(id))
|
|
85
|
+
);
|
|
86
|
+
close == null ? void 0 : close();
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
),
|
|
90
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
91
|
+
Menu.Menu.RadioItem,
|
|
92
|
+
{
|
|
93
|
+
name: presetRadioName,
|
|
94
|
+
value: "standard",
|
|
95
|
+
checked: isStandardActive,
|
|
96
|
+
label: standardPresetLabel,
|
|
97
|
+
onValueChange: () => {
|
|
98
|
+
setVisibleIds(
|
|
99
|
+
standardPresetIds.filter(
|
|
100
|
+
(id) => typeof id === "string" && Boolean(id)
|
|
101
|
+
)
|
|
102
|
+
);
|
|
103
|
+
close == null ? void 0 : close();
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
),
|
|
107
|
+
/* @__PURE__ */ jsxRuntime.jsx(Menu.Menu.Separator, {}),
|
|
108
|
+
hideableColumns.map((col) => {
|
|
109
|
+
const isVisible = col.id ? visibleSet.has(col.id) : false;
|
|
110
|
+
const disableUncheckingLast = isVisible && visibleCount <= 1;
|
|
111
|
+
const label = col.header;
|
|
112
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
113
|
+
Menu.Menu.CheckItem,
|
|
114
|
+
{
|
|
115
|
+
checked: isVisible,
|
|
116
|
+
disabled: disableUncheckingLast,
|
|
117
|
+
label,
|
|
118
|
+
onCheckedChange: (nextChecked) => {
|
|
119
|
+
if (disableUncheckingLast) return;
|
|
120
|
+
toggleColumn(col.id, nextChecked);
|
|
121
|
+
}
|
|
122
|
+
},
|
|
123
|
+
col.id
|
|
124
|
+
);
|
|
125
|
+
})
|
|
126
|
+
] }) : null
|
|
127
|
+
] });
|
|
128
|
+
}
|
|
129
|
+
function TableSettings({
|
|
130
|
+
buttonSize = "sm",
|
|
131
|
+
...sectionProps
|
|
132
|
+
}) {
|
|
66
133
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
67
134
|
Popover.Popover,
|
|
68
135
|
{
|
|
@@ -70,70 +137,10 @@ function TableSettings({
|
|
|
70
137
|
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Settings, {}),
|
|
71
138
|
icon
|
|
72
139
|
] }),
|
|
73
|
-
children: (close) => /* @__PURE__ */ jsxRuntime.
|
|
74
|
-
additionalSettings == null ? void 0 : additionalSettings(close),
|
|
75
|
-
/* @__PURE__ */ jsxRuntime.jsx(Menu.Menu.Item, { active: viewMode === "wrapped", children: /* @__PURE__ */ jsxRuntime.jsxs("button", { type: "button", onClick: () => handleViewModeChange(viewMode, close), children: [
|
|
76
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ListChevronsUpDown, {}),
|
|
77
|
-
"Ombryd tekst"
|
|
78
|
-
] }) }),
|
|
79
|
-
hideableColumns.length > 0 && onVisibleColumnIdsChange ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
80
|
-
/* @__PURE__ */ jsxRuntime.jsx(Menu.Menu.Separator, {}),
|
|
81
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { style: { padding: "6px 10px", fontSize: 12, opacity: 0.7 }, children: columnsLabel }),
|
|
82
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
83
|
-
Menu.Menu.RadioItem,
|
|
84
|
-
{
|
|
85
|
-
name: presetRadioName,
|
|
86
|
-
value: "all",
|
|
87
|
-
checked: isAllActive,
|
|
88
|
-
label: allPresetLabel,
|
|
89
|
-
onValueChange: () => {
|
|
90
|
-
setVisibleIds(
|
|
91
|
-
allPresetIds.filter((id) => typeof id === "string" && Boolean(id))
|
|
92
|
-
);
|
|
93
|
-
close == null ? void 0 : close();
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
),
|
|
97
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
98
|
-
Menu.Menu.RadioItem,
|
|
99
|
-
{
|
|
100
|
-
name: presetRadioName,
|
|
101
|
-
value: "standard",
|
|
102
|
-
checked: isStandardActive,
|
|
103
|
-
label: standardPresetLabel,
|
|
104
|
-
onValueChange: () => {
|
|
105
|
-
setVisibleIds(
|
|
106
|
-
standardPresetIds.filter(
|
|
107
|
-
(id) => typeof id === "string" && Boolean(id)
|
|
108
|
-
)
|
|
109
|
-
);
|
|
110
|
-
close == null ? void 0 : close();
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
),
|
|
114
|
-
/* @__PURE__ */ jsxRuntime.jsx(Menu.Menu.Separator, {}),
|
|
115
|
-
hideableColumns.map((col) => {
|
|
116
|
-
const isVisible = col.id ? visibleSet.has(col.id) : false;
|
|
117
|
-
const disableUncheckingLast = isVisible && visibleCount <= 1;
|
|
118
|
-
const label = col.header;
|
|
119
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
120
|
-
Menu.Menu.CheckItem,
|
|
121
|
-
{
|
|
122
|
-
checked: isVisible,
|
|
123
|
-
disabled: disableUncheckingLast,
|
|
124
|
-
label,
|
|
125
|
-
onCheckedChange: (nextChecked) => {
|
|
126
|
-
if (disableUncheckingLast) return;
|
|
127
|
-
toggleColumn(col.id, nextChecked);
|
|
128
|
-
}
|
|
129
|
-
},
|
|
130
|
-
col.id
|
|
131
|
-
);
|
|
132
|
-
})
|
|
133
|
-
] }) : null
|
|
134
|
-
] })
|
|
140
|
+
children: (close) => /* @__PURE__ */ jsxRuntime.jsx(Menu.Menu, { children: /* @__PURE__ */ jsxRuntime.jsx(TableSettingsMenuSection, { ...sectionProps, close }) })
|
|
135
141
|
}
|
|
136
142
|
);
|
|
137
143
|
}
|
|
138
144
|
|
|
139
145
|
exports.TableSettings = TableSettings;
|
|
146
|
+
exports.TableSettingsMenuSection = TableSettingsMenuSection;
|
|
@@ -2,7 +2,7 @@ import { ColumnDef } from '@tanstack/react-table';
|
|
|
2
2
|
import type { JSX, ReactNode } from 'react';
|
|
3
3
|
import { ViewMode } from '../../../../hooks/useTableSettings';
|
|
4
4
|
import { ButtonSize } from '../../../button/Button';
|
|
5
|
-
interface
|
|
5
|
+
export interface TableSettingsMenuSectionProps<T extends Record<string, any>> {
|
|
6
6
|
handleChangeViewMode: (mode: ViewMode) => void;
|
|
7
7
|
viewMode: ViewMode;
|
|
8
8
|
columns?: ColumnDef<T>[];
|
|
@@ -11,8 +11,17 @@ interface TableSettingsProps<T extends Record<string, any>> {
|
|
|
11
11
|
columnsLabel?: string;
|
|
12
12
|
allPresetLabel?: string;
|
|
13
13
|
standardPresetLabel?: string;
|
|
14
|
-
buttonSize?: ButtonSize;
|
|
15
14
|
additionalSettings?: (close?: () => void) => ReactNode;
|
|
15
|
+
/** Called after an action closes the surrounding menu/popover, if any. */
|
|
16
|
+
close?: () => void;
|
|
17
|
+
}
|
|
18
|
+
export interface TableSettingsProps<T extends Record<string, any>> extends Omit<TableSettingsMenuSectionProps<T>, 'close'> {
|
|
19
|
+
buttonSize?: ButtonSize;
|
|
16
20
|
}
|
|
17
|
-
|
|
18
|
-
|
|
21
|
+
/**
|
|
22
|
+
* The table settings menu items (view mode toggle + column visibility), with
|
|
23
|
+
* no `Menu`/`Popover`/trigger wrapper. Use this to fold table settings into
|
|
24
|
+
* another menu; use `TableSettings` for the standalone button + popover.
|
|
25
|
+
*/
|
|
26
|
+
export declare function TableSettingsMenuSection<T extends Record<string, any>>({ viewMode, handleChangeViewMode, columns, visibleColumnIds, onVisibleColumnIdsChange, columnsLabel, allPresetLabel, standardPresetLabel, additionalSettings, close, }: TableSettingsMenuSectionProps<T>): JSX.Element;
|
|
27
|
+
export declare function TableSettings<T extends Record<string, any>>({ buttonSize, ...sectionProps }: TableSettingsProps<T>): JSX.Element;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import {
|
|
2
|
+
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
3
3
|
import { ListChevronsUpDown, Settings } from 'lucide-react';
|
|
4
4
|
import { useMemo } from 'react';
|
|
5
5
|
import { Button } from '../../../button/Button';
|
|
6
6
|
import { Menu } from '../../../menu/Menu';
|
|
7
7
|
import { Popover } from '../../../popover/Popover';
|
|
8
8
|
|
|
9
|
-
function
|
|
9
|
+
function TableSettingsMenuSection({
|
|
10
10
|
viewMode,
|
|
11
11
|
handleChangeViewMode,
|
|
12
12
|
columns = [],
|
|
@@ -15,12 +15,12 @@ function TableSettings({
|
|
|
15
15
|
columnsLabel = "Kolonner",
|
|
16
16
|
allPresetLabel = "Alle",
|
|
17
17
|
standardPresetLabel = "Standard",
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
additionalSettings,
|
|
19
|
+
close
|
|
20
20
|
}) {
|
|
21
|
-
const handleViewModeChange = (mode,
|
|
21
|
+
const handleViewModeChange = (mode, close2) => {
|
|
22
22
|
handleChangeViewMode(mode === "wrapped" ? "compact" : "wrapped");
|
|
23
|
-
|
|
23
|
+
close2 == null ? void 0 : close2();
|
|
24
24
|
};
|
|
25
25
|
const hideableColumns = useMemo(() => columns.filter((c) => c.enableHiding !== false), [columns]);
|
|
26
26
|
const allPresetIds = useMemo(() => hideableColumns.map((c) => c.id), [hideableColumns]);
|
|
@@ -61,6 +61,73 @@ function TableSettings({
|
|
|
61
61
|
return hideableColumns.every((c) => c.id && visibleSet.has(c.id) === std.has(c.id));
|
|
62
62
|
}, [hideableColumns, visibleSet, standardPresetIds]);
|
|
63
63
|
const presetRadioName = "table-columns-preset";
|
|
64
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
65
|
+
additionalSettings == null ? void 0 : additionalSettings(close),
|
|
66
|
+
/* @__PURE__ */ jsx(Menu.Item, { active: viewMode === "wrapped", children: /* @__PURE__ */ jsxs("button", { type: "button", onClick: () => handleViewModeChange(viewMode, close), children: [
|
|
67
|
+
/* @__PURE__ */ jsx(ListChevronsUpDown, {}),
|
|
68
|
+
"Ombryd tekst"
|
|
69
|
+
] }) }),
|
|
70
|
+
hideableColumns.length > 0 && onVisibleColumnIdsChange ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
71
|
+
/* @__PURE__ */ jsx(Menu.Separator, {}),
|
|
72
|
+
/* @__PURE__ */ jsx("div", { style: { padding: "6px 10px", fontSize: 12, opacity: 0.7 }, children: columnsLabel }),
|
|
73
|
+
/* @__PURE__ */ jsx(
|
|
74
|
+
Menu.RadioItem,
|
|
75
|
+
{
|
|
76
|
+
name: presetRadioName,
|
|
77
|
+
value: "all",
|
|
78
|
+
checked: isAllActive,
|
|
79
|
+
label: allPresetLabel,
|
|
80
|
+
onValueChange: () => {
|
|
81
|
+
setVisibleIds(
|
|
82
|
+
allPresetIds.filter((id) => typeof id === "string" && Boolean(id))
|
|
83
|
+
);
|
|
84
|
+
close == null ? void 0 : close();
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
),
|
|
88
|
+
/* @__PURE__ */ jsx(
|
|
89
|
+
Menu.RadioItem,
|
|
90
|
+
{
|
|
91
|
+
name: presetRadioName,
|
|
92
|
+
value: "standard",
|
|
93
|
+
checked: isStandardActive,
|
|
94
|
+
label: standardPresetLabel,
|
|
95
|
+
onValueChange: () => {
|
|
96
|
+
setVisibleIds(
|
|
97
|
+
standardPresetIds.filter(
|
|
98
|
+
(id) => typeof id === "string" && Boolean(id)
|
|
99
|
+
)
|
|
100
|
+
);
|
|
101
|
+
close == null ? void 0 : close();
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
),
|
|
105
|
+
/* @__PURE__ */ jsx(Menu.Separator, {}),
|
|
106
|
+
hideableColumns.map((col) => {
|
|
107
|
+
const isVisible = col.id ? visibleSet.has(col.id) : false;
|
|
108
|
+
const disableUncheckingLast = isVisible && visibleCount <= 1;
|
|
109
|
+
const label = col.header;
|
|
110
|
+
return /* @__PURE__ */ jsx(
|
|
111
|
+
Menu.CheckItem,
|
|
112
|
+
{
|
|
113
|
+
checked: isVisible,
|
|
114
|
+
disabled: disableUncheckingLast,
|
|
115
|
+
label,
|
|
116
|
+
onCheckedChange: (nextChecked) => {
|
|
117
|
+
if (disableUncheckingLast) return;
|
|
118
|
+
toggleColumn(col.id, nextChecked);
|
|
119
|
+
}
|
|
120
|
+
},
|
|
121
|
+
col.id
|
|
122
|
+
);
|
|
123
|
+
})
|
|
124
|
+
] }) : null
|
|
125
|
+
] });
|
|
126
|
+
}
|
|
127
|
+
function TableSettings({
|
|
128
|
+
buttonSize = "sm",
|
|
129
|
+
...sectionProps
|
|
130
|
+
}) {
|
|
64
131
|
return /* @__PURE__ */ jsx(
|
|
65
132
|
Popover,
|
|
66
133
|
{
|
|
@@ -68,70 +135,9 @@ function TableSettings({
|
|
|
68
135
|
/* @__PURE__ */ jsx(Settings, {}),
|
|
69
136
|
icon
|
|
70
137
|
] }),
|
|
71
|
-
children: (close) => /* @__PURE__ */
|
|
72
|
-
additionalSettings == null ? void 0 : additionalSettings(close),
|
|
73
|
-
/* @__PURE__ */ jsx(Menu.Item, { active: viewMode === "wrapped", children: /* @__PURE__ */ jsxs("button", { type: "button", onClick: () => handleViewModeChange(viewMode, close), children: [
|
|
74
|
-
/* @__PURE__ */ jsx(ListChevronsUpDown, {}),
|
|
75
|
-
"Ombryd tekst"
|
|
76
|
-
] }) }),
|
|
77
|
-
hideableColumns.length > 0 && onVisibleColumnIdsChange ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
78
|
-
/* @__PURE__ */ jsx(Menu.Separator, {}),
|
|
79
|
-
/* @__PURE__ */ jsx("div", { style: { padding: "6px 10px", fontSize: 12, opacity: 0.7 }, children: columnsLabel }),
|
|
80
|
-
/* @__PURE__ */ jsx(
|
|
81
|
-
Menu.RadioItem,
|
|
82
|
-
{
|
|
83
|
-
name: presetRadioName,
|
|
84
|
-
value: "all",
|
|
85
|
-
checked: isAllActive,
|
|
86
|
-
label: allPresetLabel,
|
|
87
|
-
onValueChange: () => {
|
|
88
|
-
setVisibleIds(
|
|
89
|
-
allPresetIds.filter((id) => typeof id === "string" && Boolean(id))
|
|
90
|
-
);
|
|
91
|
-
close == null ? void 0 : close();
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
),
|
|
95
|
-
/* @__PURE__ */ jsx(
|
|
96
|
-
Menu.RadioItem,
|
|
97
|
-
{
|
|
98
|
-
name: presetRadioName,
|
|
99
|
-
value: "standard",
|
|
100
|
-
checked: isStandardActive,
|
|
101
|
-
label: standardPresetLabel,
|
|
102
|
-
onValueChange: () => {
|
|
103
|
-
setVisibleIds(
|
|
104
|
-
standardPresetIds.filter(
|
|
105
|
-
(id) => typeof id === "string" && Boolean(id)
|
|
106
|
-
)
|
|
107
|
-
);
|
|
108
|
-
close == null ? void 0 : close();
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
),
|
|
112
|
-
/* @__PURE__ */ jsx(Menu.Separator, {}),
|
|
113
|
-
hideableColumns.map((col) => {
|
|
114
|
-
const isVisible = col.id ? visibleSet.has(col.id) : false;
|
|
115
|
-
const disableUncheckingLast = isVisible && visibleCount <= 1;
|
|
116
|
-
const label = col.header;
|
|
117
|
-
return /* @__PURE__ */ jsx(
|
|
118
|
-
Menu.CheckItem,
|
|
119
|
-
{
|
|
120
|
-
checked: isVisible,
|
|
121
|
-
disabled: disableUncheckingLast,
|
|
122
|
-
label,
|
|
123
|
-
onCheckedChange: (nextChecked) => {
|
|
124
|
-
if (disableUncheckingLast) return;
|
|
125
|
-
toggleColumn(col.id, nextChecked);
|
|
126
|
-
}
|
|
127
|
-
},
|
|
128
|
-
col.id
|
|
129
|
-
);
|
|
130
|
-
})
|
|
131
|
-
] }) : null
|
|
132
|
-
] })
|
|
138
|
+
children: (close) => /* @__PURE__ */ jsx(Menu, { children: /* @__PURE__ */ jsx(TableSettingsMenuSection, { ...sectionProps, close }) })
|
|
133
139
|
}
|
|
134
140
|
);
|
|
135
141
|
}
|
|
136
142
|
|
|
137
|
-
export { TableSettings };
|
|
143
|
+
export { TableSettings, TableSettingsMenuSection };
|
|
@@ -32,14 +32,23 @@
|
|
|
32
32
|
|
|
33
33
|
.tabButtons {
|
|
34
34
|
display: flex;
|
|
35
|
-
flex-wrap:
|
|
35
|
+
flex-wrap: nowrap;
|
|
36
|
+
overflow-x: auto;
|
|
37
|
+
/* Explicit, not just tidy: leaving this "visible" would compute to "auto"
|
|
38
|
+
too (overflow-x auto + overflow-y visible isn't a valid combination per
|
|
39
|
+
spec), silently turning on a vertical scrollbar/clip that's never needed
|
|
40
|
+
here. */
|
|
41
|
+
overflow-y: hidden;
|
|
36
42
|
min-width: 0;
|
|
37
43
|
}
|
|
38
44
|
|
|
39
|
-
/* Extra content next to the tab buttons, pushed into the free space on the
|
|
45
|
+
/* Extra content next to the tab buttons, pushed into the free space on the
|
|
46
|
+
right. It takes the space it needs — .tabButtons scrolls instead of
|
|
47
|
+
squeezing it. */
|
|
40
48
|
.tabListAddition {
|
|
41
49
|
display: flex;
|
|
42
50
|
align-items: center;
|
|
51
|
+
flex-shrink: 0;
|
|
43
52
|
gap: var(--spacing-sm);
|
|
44
53
|
margin-inline-start: auto;
|
|
45
54
|
padding-inline-start: var(--spacing-md);
|
|
@@ -49,6 +58,7 @@
|
|
|
49
58
|
.tab {
|
|
50
59
|
display: flex;
|
|
51
60
|
align-items: stretch;
|
|
61
|
+
flex-shrink: 0;
|
|
52
62
|
border-radius: 0;
|
|
53
63
|
border-block-end: 2px solid var(--color-border-default);
|
|
54
64
|
}
|
|
@@ -134,6 +144,7 @@
|
|
|
134
144
|
align-items: center;
|
|
135
145
|
justify-content: center;
|
|
136
146
|
align-self: stretch;
|
|
147
|
+
flex-shrink: 0;
|
|
137
148
|
|
|
138
149
|
color: var(--color-fg-muted);
|
|
139
150
|
background: none;
|
|
@@ -209,7 +220,17 @@
|
|
|
209
220
|
}
|
|
210
221
|
|
|
211
222
|
.filled > .tabList {
|
|
212
|
-
|
|
223
|
+
position: relative;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
.filled > .tabList::after {
|
|
227
|
+
content: '';
|
|
228
|
+
position: absolute;
|
|
229
|
+
inset-inline: 0;
|
|
230
|
+
inset-block-end: 0;
|
|
231
|
+
block-size: 1px;
|
|
232
|
+
background: var(--color-border-subtle);
|
|
233
|
+
pointer-events: none;
|
|
213
234
|
}
|
|
214
235
|
|
|
215
236
|
/* One continuous backdrop behind the whole button row, so the curved gap
|
|
@@ -238,7 +259,7 @@
|
|
|
238
259
|
|
|
239
260
|
.filled > .tabList > .tabButtons > .tab {
|
|
240
261
|
border: 1px solid transparent;
|
|
241
|
-
border-block-end:
|
|
262
|
+
border-block-end-width: 1px;
|
|
242
263
|
color: var(--color-fg-muted);
|
|
243
264
|
position: relative;
|
|
244
265
|
transition:
|
|
@@ -265,6 +286,15 @@
|
|
|
265
286
|
color: var(--color-fg-default);
|
|
266
287
|
}
|
|
267
288
|
|
|
289
|
+
.filled > .tabList > .tabButtons > .tab.active::after {
|
|
290
|
+
content: '';
|
|
291
|
+
position: absolute;
|
|
292
|
+
inset-inline: -1px;
|
|
293
|
+
inset-block-end: -1px;
|
|
294
|
+
block-size: 1px;
|
|
295
|
+
background: var(--color-bg-surface);
|
|
296
|
+
}
|
|
297
|
+
|
|
268
298
|
.filled > .tabContent {
|
|
269
299
|
background: var(--color-bg-surface);
|
|
270
300
|
border: 1px solid var(--color-border-subtle);
|
package/dist/index.cjs
CHANGED
|
@@ -18,6 +18,7 @@ var SkeletonLoader = require('./components/skeleton-loader/SkeletonLoader');
|
|
|
18
18
|
var Page = require('./components/page/Page');
|
|
19
19
|
var Breadcrumbs = require('./components/breadcrumbs/Breadcrumbs');
|
|
20
20
|
var Circle = require('./components/circle/Circle');
|
|
21
|
+
var Badge = require('./components/badge/Badge');
|
|
21
22
|
var chartColors = require('./constants/chart-colors');
|
|
22
23
|
var chartColors_types = require('./constants/chart-colors.types');
|
|
23
24
|
var severity_types = require('./constants/severity.types');
|
|
@@ -159,6 +160,12 @@ Object.keys(Circle).forEach(function (k) {
|
|
|
159
160
|
get: function () { return Circle[k]; }
|
|
160
161
|
});
|
|
161
162
|
});
|
|
163
|
+
Object.keys(Badge).forEach(function (k) {
|
|
164
|
+
if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
|
|
165
|
+
enumerable: true,
|
|
166
|
+
get: function () { return Badge[k]; }
|
|
167
|
+
});
|
|
168
|
+
});
|
|
162
169
|
Object.keys(chartColors).forEach(function (k) {
|
|
163
170
|
if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
|
|
164
171
|
enumerable: true,
|
package/dist/index.css
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
@import './components/app-header/AppHeader.module.css';
|
|
7
7
|
@import './components/attribute-chip/AttributeChip.module.css';
|
|
8
8
|
@import './components/avatar/Avatar.module.css';
|
|
9
|
+
@import './components/badge/Badge.module.css';
|
|
9
10
|
@import './components/breadcrumbs/Breadcrumbs.module.css';
|
|
10
11
|
@import './components/button-select/ButtonSelect.module.css';
|
|
11
12
|
@import './components/button/Button.module.css';
|
package/dist/index.d.ts
CHANGED
|
@@ -16,6 +16,7 @@ export * from './components/skeleton-loader/SkeletonLoader';
|
|
|
16
16
|
export * from './components/page/Page';
|
|
17
17
|
export * from './components/breadcrumbs/Breadcrumbs';
|
|
18
18
|
export * from './components/circle/Circle';
|
|
19
|
+
export * from './components/badge/Badge';
|
|
19
20
|
export * from './constants/chart-colors';
|
|
20
21
|
export * from './constants/chart-colors.types';
|
|
21
22
|
export * from './constants/severity.types';
|
package/dist/index.js
CHANGED
|
@@ -16,6 +16,7 @@ export * from './components/skeleton-loader/SkeletonLoader';
|
|
|
16
16
|
export * from './components/page/Page';
|
|
17
17
|
export * from './components/breadcrumbs/Breadcrumbs';
|
|
18
18
|
export * from './components/circle/Circle';
|
|
19
|
+
export * from './components/badge/Badge';
|
|
19
20
|
export * from './constants/chart-colors';
|
|
20
21
|
export * from './constants/chart-colors.types';
|
|
21
22
|
export * from './constants/severity.types';
|
package/dist/styles/styles.css
CHANGED
|
@@ -303,8 +303,15 @@ tr.dbc-table--hover:hover td:last-child {
|
|
|
303
303
|
Scrollbars
|
|
304
304
|
========================================================================== */
|
|
305
305
|
|
|
306
|
+
/* Firefox equivalent of the thin, muted webkit scrollbar below. */
|
|
307
|
+
* {
|
|
308
|
+
scrollbar-width: thin;
|
|
309
|
+
scrollbar-color: var(--color-border-strong) transparent;
|
|
310
|
+
}
|
|
311
|
+
|
|
306
312
|
::-webkit-scrollbar {
|
|
307
313
|
width: 10px;
|
|
314
|
+
height: 10px;
|
|
308
315
|
}
|
|
309
316
|
|
|
310
317
|
::-webkit-scrollbar-track {
|
package/dist/styles.css
CHANGED
|
@@ -303,8 +303,15 @@ tr.dbc-table--hover:hover td:last-child {
|
|
|
303
303
|
Scrollbars
|
|
304
304
|
========================================================================== */
|
|
305
305
|
|
|
306
|
+
/* Firefox equivalent of the thin, muted webkit scrollbar below. */
|
|
307
|
+
* {
|
|
308
|
+
scrollbar-width: thin;
|
|
309
|
+
scrollbar-color: var(--color-border-strong) transparent;
|
|
310
|
+
}
|
|
311
|
+
|
|
306
312
|
::-webkit-scrollbar {
|
|
307
313
|
width: 10px;
|
|
314
|
+
height: 10px;
|
|
308
315
|
}
|
|
309
316
|
|
|
310
317
|
::-webkit-scrollbar-track {
|