@dbcdk/react-components 0.0.118 → 0.0.120
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/components/button/Button.module.css +2 -2
- package/dist/components/lightbox/Lightbox.cjs +94 -23
- package/dist/components/lightbox/Lightbox.d.ts +14 -1
- package/dist/components/lightbox/Lightbox.js +95 -24
- package/dist/components/lightbox/Lightbox.module.css +56 -3
- package/dist/components/segmented-progress-bar/SegmentedProgressBar.cjs +4 -1
- package/dist/components/segmented-progress-bar/SegmentedProgressBar.js +4 -1
- package/package.json +1 -1
|
@@ -153,13 +153,13 @@
|
|
|
153
153
|
}
|
|
154
154
|
|
|
155
155
|
.default {
|
|
156
|
-
background-color: var(--
|
|
156
|
+
background-color: var(--opac-bg-default);
|
|
157
157
|
color: var(--color-fg-default);
|
|
158
158
|
border-color: transparent;
|
|
159
159
|
}
|
|
160
160
|
|
|
161
161
|
.default:hover {
|
|
162
|
-
background-color: var(--
|
|
162
|
+
background-color: var(--opac-bg-dark);
|
|
163
163
|
border-color: transparent;
|
|
164
164
|
}
|
|
165
165
|
|
|
@@ -5,8 +5,10 @@ var jsxRuntime = require('react/jsx-runtime');
|
|
|
5
5
|
var lucideReact = require('lucide-react');
|
|
6
6
|
var react = require('react');
|
|
7
7
|
var client = require('../../client');
|
|
8
|
+
var Popover = require('../../components/popover/Popover');
|
|
8
9
|
var styles = require('./Lightbox.module.css');
|
|
9
10
|
var Button = require('../button/Button');
|
|
11
|
+
var Menu = require('../menu/Menu');
|
|
10
12
|
|
|
11
13
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
12
14
|
|
|
@@ -30,7 +32,8 @@ function Lightbox({
|
|
|
30
32
|
showDownload = true,
|
|
31
33
|
getDownloadFilename,
|
|
32
34
|
buttonAddition,
|
|
33
|
-
trigger
|
|
35
|
+
trigger,
|
|
36
|
+
getContextMenuItems
|
|
34
37
|
}) {
|
|
35
38
|
var _a;
|
|
36
39
|
const dialogRef = react.useRef(null);
|
|
@@ -119,28 +122,38 @@ function Lightbox({
|
|
|
119
122
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
120
123
|
trigger ? trigger(openAt) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles__default.default.thumbnails, children: items.map((item, i) => {
|
|
121
124
|
var _a2;
|
|
122
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
123
|
-
"
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: styles__default.default.thumbnailImg, style: { height: thumbnailHeight }, children: item.thumbnail })
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
125
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: styles__default.default.thumbnailCard, children: [
|
|
126
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: styles__default.default.thumbnailMedia, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
127
|
+
"button",
|
|
128
|
+
{
|
|
129
|
+
type: "button",
|
|
130
|
+
className: styles__default.default.thumbnailBtn,
|
|
131
|
+
onClick: () => openAt(i),
|
|
132
|
+
"aria-label": (_a2 = item.title) != null ? _a2 : `Billede ${i + 1}`,
|
|
133
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles__default.default.thumbnailImg, style: { height: thumbnailHeight }, children: item.thumbnail })
|
|
134
|
+
}
|
|
135
|
+
) }),
|
|
136
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: styles__default.default.thumbnailFooter, children: [
|
|
137
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: styles__default.default.thumbnailMeta, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
138
|
+
client.MetaBar,
|
|
139
|
+
{
|
|
140
|
+
items: [
|
|
141
|
+
{ value: item.height != null ? `H:${item.height}px` : "-" },
|
|
142
|
+
{ value: item.width != null ? `B:${item.width}px` : "-" }
|
|
143
|
+
]
|
|
144
|
+
}
|
|
145
|
+
) }),
|
|
146
|
+
getContextMenuItems ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
147
|
+
ThumbnailContextMenu,
|
|
148
|
+
{
|
|
149
|
+
item,
|
|
150
|
+
index: i,
|
|
151
|
+
open: () => openAt(i),
|
|
152
|
+
getItems: getContextMenuItems
|
|
153
|
+
}
|
|
154
|
+
) : null
|
|
155
|
+
] })
|
|
156
|
+
] }, i);
|
|
144
157
|
}) }),
|
|
145
158
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
146
159
|
"dialog",
|
|
@@ -215,5 +228,63 @@ function Lightbox({
|
|
|
215
228
|
)
|
|
216
229
|
] });
|
|
217
230
|
}
|
|
231
|
+
function ThumbnailContextMenu({
|
|
232
|
+
item,
|
|
233
|
+
index,
|
|
234
|
+
open,
|
|
235
|
+
getItems
|
|
236
|
+
}) {
|
|
237
|
+
const menuItems = getItems({ item, index, open });
|
|
238
|
+
if (!menuItems.length) return null;
|
|
239
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
240
|
+
Popover.Popover,
|
|
241
|
+
{
|
|
242
|
+
matchTriggerWidth: false,
|
|
243
|
+
minWidth: "180px",
|
|
244
|
+
trigger: (toggle, _icon, isOpen) => {
|
|
245
|
+
var _a;
|
|
246
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
247
|
+
Button.Button,
|
|
248
|
+
{
|
|
249
|
+
type: "button",
|
|
250
|
+
size: "sm",
|
|
251
|
+
variant: "inline",
|
|
252
|
+
className: styles__default.default.thumbnailMenuTrigger,
|
|
253
|
+
"aria-label": `Flere handlinger for ${(_a = item.title) != null ? _a : `billede ${index + 1}`}`,
|
|
254
|
+
"aria-haspopup": "menu",
|
|
255
|
+
"aria-expanded": isOpen ? true : false,
|
|
256
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MoreHorizontal, { size: 16 }),
|
|
257
|
+
onClick: (e) => {
|
|
258
|
+
e.stopPropagation();
|
|
259
|
+
toggle(e);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
);
|
|
263
|
+
},
|
|
264
|
+
children: (close) => /* @__PURE__ */ jsxRuntime.jsx(Menu.Menu, { children: menuItems.map((menuItem, menuItemIndex) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
265
|
+
Menu.Menu.Item,
|
|
266
|
+
{
|
|
267
|
+
active: menuItem.active,
|
|
268
|
+
selected: menuItem.selected,
|
|
269
|
+
disabled: menuItem.disabled,
|
|
270
|
+
variant: menuItem.variant,
|
|
271
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
272
|
+
"button",
|
|
273
|
+
{
|
|
274
|
+
type: "button",
|
|
275
|
+
onClick: (e) => {
|
|
276
|
+
e.stopPropagation();
|
|
277
|
+
menuItem.onClick();
|
|
278
|
+
close();
|
|
279
|
+
},
|
|
280
|
+
children: menuItem.label
|
|
281
|
+
}
|
|
282
|
+
)
|
|
283
|
+
},
|
|
284
|
+
menuItemIndex
|
|
285
|
+
)) })
|
|
286
|
+
}
|
|
287
|
+
);
|
|
288
|
+
}
|
|
218
289
|
|
|
219
290
|
exports.Lightbox = Lightbox;
|
|
@@ -8,6 +8,14 @@ export type LightboxItem = {
|
|
|
8
8
|
width?: number;
|
|
9
9
|
height?: number;
|
|
10
10
|
};
|
|
11
|
+
export type LightboxContextMenuItem = {
|
|
12
|
+
label: ReactNode;
|
|
13
|
+
onClick: () => void;
|
|
14
|
+
active?: boolean;
|
|
15
|
+
selected?: boolean;
|
|
16
|
+
disabled?: boolean;
|
|
17
|
+
variant?: 'default' | 'danger';
|
|
18
|
+
};
|
|
11
19
|
export interface LightboxProps {
|
|
12
20
|
items: LightboxItem[];
|
|
13
21
|
title?: string;
|
|
@@ -17,5 +25,10 @@ export interface LightboxProps {
|
|
|
17
25
|
getDownloadFilename?: (item: LightboxItem, index: number) => string;
|
|
18
26
|
buttonAddition?: ReactNode;
|
|
19
27
|
trigger?: (open: (index?: number) => void) => ReactNode;
|
|
28
|
+
getContextMenuItems?: (args: {
|
|
29
|
+
item: LightboxItem;
|
|
30
|
+
index: number;
|
|
31
|
+
open: () => void;
|
|
32
|
+
}) => LightboxContextMenuItem[];
|
|
20
33
|
}
|
|
21
|
-
export declare function Lightbox({ items, title, initialIndex, thumbnailHeight, showDownload, getDownloadFilename, buttonAddition, trigger, }: LightboxProps): ReactElement | null;
|
|
34
|
+
export declare function Lightbox({ items, title, initialIndex, thumbnailHeight, showDownload, getDownloadFilename, buttonAddition, trigger, getContextMenuItems, }: LightboxProps): ReactElement | null;
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
3
|
-
import { Download, X, ChevronLeft, ChevronRight } from 'lucide-react';
|
|
3
|
+
import { Download, X, ChevronLeft, ChevronRight, MoreHorizontal } from 'lucide-react';
|
|
4
4
|
import { useRef, useState, useEffect, useCallback } from 'react';
|
|
5
5
|
import { MetaBar } from '../../client';
|
|
6
|
+
import { Popover } from '../../components/popover/Popover';
|
|
6
7
|
import styles from './Lightbox.module.css';
|
|
7
8
|
import { Button } from '../button/Button';
|
|
9
|
+
import { Menu } from '../menu/Menu';
|
|
8
10
|
|
|
9
11
|
function extFromMime(mime) {
|
|
10
12
|
var _a;
|
|
@@ -24,7 +26,8 @@ function Lightbox({
|
|
|
24
26
|
showDownload = true,
|
|
25
27
|
getDownloadFilename,
|
|
26
28
|
buttonAddition,
|
|
27
|
-
trigger
|
|
29
|
+
trigger,
|
|
30
|
+
getContextMenuItems
|
|
28
31
|
}) {
|
|
29
32
|
var _a;
|
|
30
33
|
const dialogRef = useRef(null);
|
|
@@ -113,28 +116,38 @@ function Lightbox({
|
|
|
113
116
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
114
117
|
trigger ? trigger(openAt) : /* @__PURE__ */ jsx("div", { className: styles.thumbnails, children: items.map((item, i) => {
|
|
115
118
|
var _a2;
|
|
116
|
-
return /* @__PURE__ */ jsxs(
|
|
117
|
-
"
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
/* @__PURE__ */ jsx("div", { className: styles.thumbnailImg, style: { height: thumbnailHeight }, children: item.thumbnail })
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
119
|
+
return /* @__PURE__ */ jsxs("div", { className: styles.thumbnailCard, children: [
|
|
120
|
+
/* @__PURE__ */ jsx("div", { className: styles.thumbnailMedia, children: /* @__PURE__ */ jsx(
|
|
121
|
+
"button",
|
|
122
|
+
{
|
|
123
|
+
type: "button",
|
|
124
|
+
className: styles.thumbnailBtn,
|
|
125
|
+
onClick: () => openAt(i),
|
|
126
|
+
"aria-label": (_a2 = item.title) != null ? _a2 : `Billede ${i + 1}`,
|
|
127
|
+
children: /* @__PURE__ */ jsx("div", { className: styles.thumbnailImg, style: { height: thumbnailHeight }, children: item.thumbnail })
|
|
128
|
+
}
|
|
129
|
+
) }),
|
|
130
|
+
/* @__PURE__ */ jsxs("div", { className: styles.thumbnailFooter, children: [
|
|
131
|
+
/* @__PURE__ */ jsx("div", { className: styles.thumbnailMeta, children: /* @__PURE__ */ jsx(
|
|
132
|
+
MetaBar,
|
|
133
|
+
{
|
|
134
|
+
items: [
|
|
135
|
+
{ value: item.height != null ? `H:${item.height}px` : "-" },
|
|
136
|
+
{ value: item.width != null ? `B:${item.width}px` : "-" }
|
|
137
|
+
]
|
|
138
|
+
}
|
|
139
|
+
) }),
|
|
140
|
+
getContextMenuItems ? /* @__PURE__ */ jsx(
|
|
141
|
+
ThumbnailContextMenu,
|
|
142
|
+
{
|
|
143
|
+
item,
|
|
144
|
+
index: i,
|
|
145
|
+
open: () => openAt(i),
|
|
146
|
+
getItems: getContextMenuItems
|
|
147
|
+
}
|
|
148
|
+
) : null
|
|
149
|
+
] })
|
|
150
|
+
] }, i);
|
|
138
151
|
}) }),
|
|
139
152
|
/* @__PURE__ */ jsx(
|
|
140
153
|
"dialog",
|
|
@@ -209,5 +222,63 @@ function Lightbox({
|
|
|
209
222
|
)
|
|
210
223
|
] });
|
|
211
224
|
}
|
|
225
|
+
function ThumbnailContextMenu({
|
|
226
|
+
item,
|
|
227
|
+
index,
|
|
228
|
+
open,
|
|
229
|
+
getItems
|
|
230
|
+
}) {
|
|
231
|
+
const menuItems = getItems({ item, index, open });
|
|
232
|
+
if (!menuItems.length) return null;
|
|
233
|
+
return /* @__PURE__ */ jsx(
|
|
234
|
+
Popover,
|
|
235
|
+
{
|
|
236
|
+
matchTriggerWidth: false,
|
|
237
|
+
minWidth: "180px",
|
|
238
|
+
trigger: (toggle, _icon, isOpen) => {
|
|
239
|
+
var _a;
|
|
240
|
+
return /* @__PURE__ */ jsx(
|
|
241
|
+
Button,
|
|
242
|
+
{
|
|
243
|
+
type: "button",
|
|
244
|
+
size: "sm",
|
|
245
|
+
variant: "inline",
|
|
246
|
+
className: styles.thumbnailMenuTrigger,
|
|
247
|
+
"aria-label": `Flere handlinger for ${(_a = item.title) != null ? _a : `billede ${index + 1}`}`,
|
|
248
|
+
"aria-haspopup": "menu",
|
|
249
|
+
"aria-expanded": isOpen ? true : false,
|
|
250
|
+
icon: /* @__PURE__ */ jsx(MoreHorizontal, { size: 16 }),
|
|
251
|
+
onClick: (e) => {
|
|
252
|
+
e.stopPropagation();
|
|
253
|
+
toggle(e);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
);
|
|
257
|
+
},
|
|
258
|
+
children: (close) => /* @__PURE__ */ jsx(Menu, { children: menuItems.map((menuItem, menuItemIndex) => /* @__PURE__ */ jsx(
|
|
259
|
+
Menu.Item,
|
|
260
|
+
{
|
|
261
|
+
active: menuItem.active,
|
|
262
|
+
selected: menuItem.selected,
|
|
263
|
+
disabled: menuItem.disabled,
|
|
264
|
+
variant: menuItem.variant,
|
|
265
|
+
children: /* @__PURE__ */ jsx(
|
|
266
|
+
"button",
|
|
267
|
+
{
|
|
268
|
+
type: "button",
|
|
269
|
+
onClick: (e) => {
|
|
270
|
+
e.stopPropagation();
|
|
271
|
+
menuItem.onClick();
|
|
272
|
+
close();
|
|
273
|
+
},
|
|
274
|
+
children: menuItem.label
|
|
275
|
+
}
|
|
276
|
+
)
|
|
277
|
+
},
|
|
278
|
+
menuItemIndex
|
|
279
|
+
)) })
|
|
280
|
+
}
|
|
281
|
+
);
|
|
282
|
+
}
|
|
212
283
|
|
|
213
284
|
export { Lightbox };
|
|
@@ -5,16 +5,32 @@
|
|
|
5
5
|
gap: var(--spacing-md);
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
+
.thumbnailCard {
|
|
9
|
+
display: flex;
|
|
10
|
+
flex-direction: column;
|
|
11
|
+
gap: var(--spacing-xs);
|
|
12
|
+
min-width: 0;
|
|
13
|
+
max-width: 100%;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.thumbnailMedia {
|
|
17
|
+
position: relative;
|
|
18
|
+
display: flex;
|
|
19
|
+
min-width: 0;
|
|
20
|
+
max-width: 100%;
|
|
21
|
+
}
|
|
22
|
+
|
|
8
23
|
.thumbnailBtn {
|
|
9
24
|
background: none;
|
|
10
25
|
border: none;
|
|
11
26
|
padding: 0;
|
|
12
27
|
cursor: pointer;
|
|
13
|
-
display:
|
|
14
|
-
flex-direction: column;
|
|
15
|
-
gap: var(--spacing-xs);
|
|
28
|
+
display: block;
|
|
16
29
|
flex: none;
|
|
17
30
|
text-align: left;
|
|
31
|
+
position: relative;
|
|
32
|
+
min-width: 0;
|
|
33
|
+
max-width: 100%;
|
|
18
34
|
}
|
|
19
35
|
|
|
20
36
|
.thumbnailImg {
|
|
@@ -25,6 +41,8 @@
|
|
|
25
41
|
transition:
|
|
26
42
|
transform var(--transition-fast) var(--ease-standard),
|
|
27
43
|
box-shadow var(--transition-fast) var(--ease-standard);
|
|
44
|
+
min-width: 0;
|
|
45
|
+
max-width: 100%;
|
|
28
46
|
}
|
|
29
47
|
|
|
30
48
|
.thumbnailBtn:hover .thumbnailImg {
|
|
@@ -34,12 +52,47 @@
|
|
|
34
52
|
.thumbnailImg > img {
|
|
35
53
|
height: 100%;
|
|
36
54
|
width: auto;
|
|
55
|
+
max-width: 100%;
|
|
37
56
|
display: block;
|
|
38
57
|
}
|
|
39
58
|
|
|
40
59
|
.thumbnailMeta {
|
|
60
|
+
flex: 1 1 auto;
|
|
41
61
|
display: flex;
|
|
42
62
|
gap: var(--spacing-2xs);
|
|
63
|
+
min-width: 0;
|
|
64
|
+
max-width: 100%;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
.thumbnailMeta > div {
|
|
68
|
+
min-width: 0;
|
|
69
|
+
max-width: 100%;
|
|
70
|
+
overflow: hidden;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.thumbnailMeta > div > span,
|
|
74
|
+
.thumbnailMeta > div > span > span {
|
|
75
|
+
min-width: 0;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.thumbnailMeta > div > span:not([aria-hidden='true']) {
|
|
79
|
+
max-width: 100%;
|
|
80
|
+
overflow: hidden;
|
|
81
|
+
white-space: nowrap;
|
|
82
|
+
text-overflow: ellipsis;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.thumbnailFooter {
|
|
86
|
+
display: flex;
|
|
87
|
+
align-items: center;
|
|
88
|
+
gap: var(--spacing-xs);
|
|
89
|
+
min-width: 0;
|
|
90
|
+
max-width: 100%;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
.thumbnailMenuTrigger {
|
|
94
|
+
flex: 0 0 auto;
|
|
95
|
+
min-width: 0;
|
|
43
96
|
}
|
|
44
97
|
|
|
45
98
|
.dialog {
|
|
@@ -17,6 +17,9 @@ const sizeTokenMap = {
|
|
|
17
17
|
md: "var(--component-size-md)",
|
|
18
18
|
lg: "var(--component-size-lg)"
|
|
19
19
|
};
|
|
20
|
+
function formatNumberDa(value) {
|
|
21
|
+
return value.toLocaleString("da-DK");
|
|
22
|
+
}
|
|
20
23
|
function SegmentWithTooltip({
|
|
21
24
|
seg,
|
|
22
25
|
index,
|
|
@@ -77,7 +80,7 @@ const SegmentedProgressBar = ({
|
|
|
77
80
|
const autoNumbers = (() => {
|
|
78
81
|
const base = segments.map((s) => s.value || 0);
|
|
79
82
|
if (showRemainder) base.push(remainder);
|
|
80
|
-
return base.join("/");
|
|
83
|
+
return base.map(formatNumberDa).join("/");
|
|
81
84
|
})();
|
|
82
85
|
const filteredSegments = computedSegments.filter((x) => x.value > 0);
|
|
83
86
|
const rootClass = [styles__default.default.container, className].filter(Boolean).join(" ");
|
|
@@ -11,6 +11,9 @@ const sizeTokenMap = {
|
|
|
11
11
|
md: "var(--component-size-md)",
|
|
12
12
|
lg: "var(--component-size-lg)"
|
|
13
13
|
};
|
|
14
|
+
function formatNumberDa(value) {
|
|
15
|
+
return value.toLocaleString("da-DK");
|
|
16
|
+
}
|
|
14
17
|
function SegmentWithTooltip({
|
|
15
18
|
seg,
|
|
16
19
|
index,
|
|
@@ -71,7 +74,7 @@ const SegmentedProgressBar = ({
|
|
|
71
74
|
const autoNumbers = (() => {
|
|
72
75
|
const base = segments.map((s) => s.value || 0);
|
|
73
76
|
if (showRemainder) base.push(remainder);
|
|
74
|
-
return base.join("/");
|
|
77
|
+
return base.map(formatNumberDa).join("/");
|
|
75
78
|
})();
|
|
76
79
|
const filteredSegments = computedSegments.filter((x) => x.value > 0);
|
|
77
80
|
const rootClass = [styles.container, className].filter(Boolean).join(" ");
|