@dbcdk/react-components 0.0.108 → 0.0.110

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/dist/client.cjs +14 -0
  2. package/dist/client.d.ts +2 -0
  3. package/dist/client.js +2 -0
  4. package/dist/components/button/Button.module.css +3 -0
  5. package/dist/components/card/Card.module.css +4 -1
  6. package/dist/components/forms/file-upload/FileUpload.cjs +117 -0
  7. package/dist/components/forms/file-upload/FileUpload.d.ts +15 -0
  8. package/dist/components/forms/file-upload/FileUpload.js +111 -0
  9. package/dist/components/forms/file-upload/FileUpload.module.css +75 -0
  10. package/dist/components/lightbox/Lightbox.cjs +219 -0
  11. package/dist/components/lightbox/Lightbox.d.ts +21 -0
  12. package/dist/components/lightbox/Lightbox.js +213 -0
  13. package/dist/components/lightbox/Lightbox.module.css +161 -0
  14. package/dist/components/menu/Menu.cjs +42 -5
  15. package/dist/components/menu/Menu.d.ts +3 -0
  16. package/dist/components/menu/Menu.js +42 -5
  17. package/dist/components/metric-tile/MetricTile.cjs +9 -2
  18. package/dist/components/metric-tile/MetricTile.d.ts +4 -2
  19. package/dist/components/metric-tile/MetricTile.js +9 -2
  20. package/dist/components/metric-tile/MetricTile.module.css +19 -15
  21. package/dist/components/overlay/tooltip/Tooltip.cjs +30 -8
  22. package/dist/components/overlay/tooltip/Tooltip.d.ts +4 -5
  23. package/dist/components/overlay/tooltip/Tooltip.js +31 -9
  24. package/dist/components/table/Table.cjs +3 -1
  25. package/dist/components/table/Table.d.ts +1 -1
  26. package/dist/components/table/Table.js +3 -1
  27. package/dist/components/table/Table.module.css +29 -4
  28. package/dist/components/table/Table.types.d.ts +1 -0
  29. package/dist/components/table/components/TableRow.cjs +9 -2
  30. package/dist/components/table/components/TableRow.js +9 -2
  31. package/dist/index.css +2 -0
  32. package/dist/styles/styles.css +4 -0
  33. package/dist/styles/themes/dbc/colors.css +27 -0
  34. package/dist/styles.css +4 -0
  35. package/package.json +1 -1
package/dist/client.cjs CHANGED
@@ -84,6 +84,8 @@ var Grid = require('./components/grid/Grid');
84
84
  var Alert = require('./components/alert/Alert');
85
85
  var InlineStatus = require('./components/inline-status/InlineStatus');
86
86
  var MediaCard = require('./components/media-card/MediaCard');
87
+ var Lightbox = require('./components/lightbox/Lightbox');
88
+ var FileUpload = require('./components/forms/file-upload/FileUpload');
87
89
 
88
90
 
89
91
 
@@ -585,3 +587,15 @@ Object.keys(MediaCard).forEach(function (k) {
585
587
  get: function () { return MediaCard[k]; }
586
588
  });
587
589
  });
590
+ Object.keys(Lightbox).forEach(function (k) {
591
+ if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
592
+ enumerable: true,
593
+ get: function () { return Lightbox[k]; }
594
+ });
595
+ });
596
+ Object.keys(FileUpload).forEach(function (k) {
597
+ if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
598
+ enumerable: true,
599
+ get: function () { return FileUpload[k]; }
600
+ });
601
+ });
package/dist/client.d.ts CHANGED
@@ -81,3 +81,5 @@ export * from './components/grid/Grid';
81
81
  export * from './components/alert/Alert';
82
82
  export * from './components/inline-status/InlineStatus';
83
83
  export * from './components/media-card/MediaCard';
84
+ export * from './components/lightbox/Lightbox';
85
+ export * from './components/forms/file-upload/FileUpload';
package/dist/client.js CHANGED
@@ -82,3 +82,5 @@ export * from './components/grid/Grid';
82
82
  export * from './components/alert/Alert';
83
83
  export * from './components/inline-status/InlineStatus';
84
84
  export * from './components/media-card/MediaCard';
85
+ export * from './components/lightbox/Lightbox';
86
+ export * from './components/forms/file-upload/FileUpload';
@@ -108,6 +108,9 @@
108
108
  padding-inline: var(--spacing-sm);
109
109
  }
110
110
 
111
+ .button.sm {
112
+ gap: var(--spacing-xxs);
113
+ }
111
114
  .button.sm svg {
112
115
  inline-size: var(--icon-size-sm);
113
116
  block-size: var(--icon-size-sm);
@@ -70,7 +70,10 @@
70
70
  --card-padding: var(--spacing-xl);
71
71
  }
72
72
 
73
- .md .content,
73
+ .md .content {
74
+ gap: var(--spacing-md);
75
+ }
76
+
74
77
  .lg .content {
75
78
  gap: var(--spacing-lg);
76
79
  }
@@ -0,0 +1,117 @@
1
+ 'use client';
2
+ 'use strict';
3
+
4
+ var jsxRuntime = require('react/jsx-runtime');
5
+ var lucideReact = require('lucide-react');
6
+ var react = require('react');
7
+ var styles = require('./FileUpload.module.css');
8
+ var InputContainer = require('../input-container/InputContainer');
9
+
10
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
11
+
12
+ var styles__default = /*#__PURE__*/_interopDefault(styles);
13
+
14
+ function FileUpload({
15
+ label,
16
+ labelAction,
17
+ error,
18
+ helpText,
19
+ helpTextAddition,
20
+ orientation = "vertical",
21
+ labelWidth,
22
+ fullWidth = false,
23
+ required,
24
+ modified,
25
+ onChange,
26
+ children,
27
+ hint,
28
+ height,
29
+ minWidth,
30
+ width,
31
+ maxWidth,
32
+ id,
33
+ disabled,
34
+ className,
35
+ ...inputProps
36
+ }) {
37
+ const reactId = react.useId();
38
+ const inputId = id != null ? id : `file-upload-${reactId}`;
39
+ const inputRef = react.useRef(null);
40
+ const [dragging, setDragging] = react.useState(false);
41
+ function handleDragOver(e) {
42
+ e.preventDefault();
43
+ if (!disabled) setDragging(true);
44
+ }
45
+ function handleDragLeave(e) {
46
+ if (!e.currentTarget.contains(e.relatedTarget)) setDragging(false);
47
+ }
48
+ function handleDrop(e) {
49
+ e.preventDefault();
50
+ setDragging(false);
51
+ if (disabled) return;
52
+ if (inputRef.current) {
53
+ const dt = e.dataTransfer;
54
+ const files = dt.files;
55
+ onChange == null ? void 0 : onChange(files.length > 0 ? files : null);
56
+ }
57
+ }
58
+ return /* @__PURE__ */ jsxRuntime.jsx(
59
+ InputContainer.InputContainer,
60
+ {
61
+ label,
62
+ labelAction,
63
+ htmlFor: inputId,
64
+ error,
65
+ helpText,
66
+ helpTextAddition,
67
+ orientation,
68
+ labelWidth,
69
+ fullWidth,
70
+ required,
71
+ modified,
72
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
73
+ "label",
74
+ {
75
+ htmlFor: inputId,
76
+ className: [
77
+ styles__default.default.dropzone,
78
+ dragging ? styles__default.default.dragging : "",
79
+ disabled ? styles__default.default.disabled : "",
80
+ error ? styles__default.default.hasError : "",
81
+ fullWidth ? styles__default.default.fullWidth : "",
82
+ className != null ? className : ""
83
+ ].filter(Boolean).join(" "),
84
+ style: {
85
+ ...height != null ? { height } : void 0,
86
+ ...minWidth != null ? { minWidth } : void 0,
87
+ ...width != null ? { width } : void 0,
88
+ ...maxWidth != null ? { maxWidth } : void 0
89
+ },
90
+ onDragOver: handleDragOver,
91
+ onDragLeave: handleDragLeave,
92
+ onDrop: handleDrop,
93
+ children: [
94
+ /* @__PURE__ */ jsxRuntime.jsx(
95
+ "input",
96
+ {
97
+ ...inputProps,
98
+ ref: inputRef,
99
+ id: inputId,
100
+ type: "file",
101
+ disabled,
102
+ className: styles__default.default.input,
103
+ onChange: (e) => onChange == null ? void 0 : onChange(e.target.files)
104
+ }
105
+ ),
106
+ children != null ? children : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
107
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.UploadCloud, { className: styles__default.default.icon, "aria-hidden": true }),
108
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: styles__default.default.hint, children: hint != null ? hint : "Tr\xE6k filer hertil eller klik for at v\xE6lge" })
109
+ ] })
110
+ ]
111
+ }
112
+ )
113
+ }
114
+ );
115
+ }
116
+
117
+ exports.FileUpload = FileUpload;
@@ -0,0 +1,15 @@
1
+ import type { InputHTMLAttributes, ReactNode } from 'react';
2
+ import type { InputContainerProps } from '../input-container/InputContainer';
3
+ export interface FileUploadProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'size' | 'width' | 'onChange'>, Omit<InputContainerProps, 'children' | 'htmlFor' | 'size'> {
4
+ onChange?: (files: FileList | null) => void;
5
+ /** Custom content to replace the default icon + text hint */
6
+ children?: ReactNode;
7
+ /** Short hint shown below the icon when no custom children */
8
+ hint?: string;
9
+ fullWidth?: boolean;
10
+ height?: number | string;
11
+ minWidth?: string | number;
12
+ width?: string | number;
13
+ maxWidth?: string | number;
14
+ }
15
+ export declare function FileUpload({ label, labelAction, error, helpText, helpTextAddition, orientation, labelWidth, fullWidth, required, modified, onChange, children, hint, height, minWidth, width, maxWidth, id, disabled, className, ...inputProps }: FileUploadProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,111 @@
1
+ 'use client';
2
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
3
+ import { UploadCloud } from 'lucide-react';
4
+ import { useId, useRef, useState } from 'react';
5
+ import styles from './FileUpload.module.css';
6
+ import { InputContainer } from '../input-container/InputContainer';
7
+
8
+ function FileUpload({
9
+ label,
10
+ labelAction,
11
+ error,
12
+ helpText,
13
+ helpTextAddition,
14
+ orientation = "vertical",
15
+ labelWidth,
16
+ fullWidth = false,
17
+ required,
18
+ modified,
19
+ onChange,
20
+ children,
21
+ hint,
22
+ height,
23
+ minWidth,
24
+ width,
25
+ maxWidth,
26
+ id,
27
+ disabled,
28
+ className,
29
+ ...inputProps
30
+ }) {
31
+ const reactId = useId();
32
+ const inputId = id != null ? id : `file-upload-${reactId}`;
33
+ const inputRef = useRef(null);
34
+ const [dragging, setDragging] = useState(false);
35
+ function handleDragOver(e) {
36
+ e.preventDefault();
37
+ if (!disabled) setDragging(true);
38
+ }
39
+ function handleDragLeave(e) {
40
+ if (!e.currentTarget.contains(e.relatedTarget)) setDragging(false);
41
+ }
42
+ function handleDrop(e) {
43
+ e.preventDefault();
44
+ setDragging(false);
45
+ if (disabled) return;
46
+ if (inputRef.current) {
47
+ const dt = e.dataTransfer;
48
+ const files = dt.files;
49
+ onChange == null ? void 0 : onChange(files.length > 0 ? files : null);
50
+ }
51
+ }
52
+ return /* @__PURE__ */ jsx(
53
+ InputContainer,
54
+ {
55
+ label,
56
+ labelAction,
57
+ htmlFor: inputId,
58
+ error,
59
+ helpText,
60
+ helpTextAddition,
61
+ orientation,
62
+ labelWidth,
63
+ fullWidth,
64
+ required,
65
+ modified,
66
+ children: /* @__PURE__ */ jsxs(
67
+ "label",
68
+ {
69
+ htmlFor: inputId,
70
+ className: [
71
+ styles.dropzone,
72
+ dragging ? styles.dragging : "",
73
+ disabled ? styles.disabled : "",
74
+ error ? styles.hasError : "",
75
+ fullWidth ? styles.fullWidth : "",
76
+ className != null ? className : ""
77
+ ].filter(Boolean).join(" "),
78
+ style: {
79
+ ...height != null ? { height } : void 0,
80
+ ...minWidth != null ? { minWidth } : void 0,
81
+ ...width != null ? { width } : void 0,
82
+ ...maxWidth != null ? { maxWidth } : void 0
83
+ },
84
+ onDragOver: handleDragOver,
85
+ onDragLeave: handleDragLeave,
86
+ onDrop: handleDrop,
87
+ children: [
88
+ /* @__PURE__ */ jsx(
89
+ "input",
90
+ {
91
+ ...inputProps,
92
+ ref: inputRef,
93
+ id: inputId,
94
+ type: "file",
95
+ disabled,
96
+ className: styles.input,
97
+ onChange: (e) => onChange == null ? void 0 : onChange(e.target.files)
98
+ }
99
+ ),
100
+ children != null ? children : /* @__PURE__ */ jsxs(Fragment, { children: [
101
+ /* @__PURE__ */ jsx(UploadCloud, { className: styles.icon, "aria-hidden": true }),
102
+ /* @__PURE__ */ jsx("span", { className: styles.hint, children: hint != null ? hint : "Tr\xE6k filer hertil eller klik for at v\xE6lge" })
103
+ ] })
104
+ ]
105
+ }
106
+ )
107
+ }
108
+ );
109
+ }
110
+
111
+ export { FileUpload };
@@ -0,0 +1,75 @@
1
+ .dropzone {
2
+ display: inline-flex;
3
+ flex-direction: column;
4
+ align-items: center;
5
+ justify-content: center;
6
+ gap: var(--spacing-xs);
7
+ padding: var(--spacing-xl) var(--spacing-lg);
8
+ background: var(--color-bg-surface);
9
+ border: var(--border-width-thin) dashed var(--color-border-default);
10
+ border-radius: var(--border-radius-default);
11
+ cursor: pointer;
12
+ color: var(--color-fg-muted);
13
+ font-family: var(--font-family);
14
+ font-size: var(--font-size-sm);
15
+ text-align: center;
16
+ box-sizing: border-box;
17
+ transition:
18
+ background-color var(--transition-fast) var(--ease-standard),
19
+ border-color var(--transition-fast) var(--ease-standard),
20
+ color var(--transition-fast) var(--ease-standard);
21
+ }
22
+
23
+ .fullWidth {
24
+ width: 100%;
25
+ }
26
+
27
+ .dropzone:hover:not(.disabled) {
28
+ background-color: var(--color-bg-selected);
29
+ border-color: var(--color-border-selected);
30
+ color: var(--color-fg-default);
31
+ }
32
+
33
+ .dragging {
34
+ background-color: var(--color-bg-selected);
35
+ border-color: var(--color-border-selected);
36
+ color: var(--color-fg-default);
37
+ box-shadow: inset 0 0 0 1px var(--color-border-selected);
38
+ }
39
+
40
+ .hasError {
41
+ border-color: var(--color-status-error);
42
+ }
43
+
44
+ .hasError:hover:not(.disabled) {
45
+ border-color: var(--color-status-error);
46
+ background-color: var(--color-status-error-bg);
47
+ }
48
+
49
+ .disabled {
50
+ background-color: var(--color-disabled-bg);
51
+ border-color: var(--color-disabled-border);
52
+ color: var(--color-disabled-fg);
53
+ cursor: not-allowed;
54
+ }
55
+
56
+ .input {
57
+ position: absolute;
58
+ width: 1px;
59
+ height: 1px;
60
+ opacity: 0;
61
+ overflow: hidden;
62
+ clip: rect(0 0 0 0);
63
+ white-space: nowrap;
64
+ }
65
+
66
+ .icon {
67
+ width: var(--icon-size-lg);
68
+ height: var(--icon-size-lg);
69
+ stroke-width: 1.5;
70
+ flex-shrink: 0;
71
+ }
72
+
73
+ .hint {
74
+ line-height: var(--line-height-normal);
75
+ }
@@ -0,0 +1,219 @@
1
+ 'use client';
2
+ 'use strict';
3
+
4
+ var jsxRuntime = require('react/jsx-runtime');
5
+ var lucideReact = require('lucide-react');
6
+ var react = require('react');
7
+ var client = require('../../client');
8
+ var styles = require('./Lightbox.module.css');
9
+ var Button = require('../button/Button');
10
+
11
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
12
+
13
+ var styles__default = /*#__PURE__*/_interopDefault(styles);
14
+
15
+ function extFromMime(mime) {
16
+ var _a;
17
+ const map = {
18
+ "image/jpeg": "jpg",
19
+ "image/png": "png",
20
+ "image/webp": "webp",
21
+ "image/gif": "gif"
22
+ };
23
+ return (_a = mime && map[mime]) != null ? _a : "jpg";
24
+ }
25
+ function Lightbox({
26
+ items,
27
+ title,
28
+ initialIndex = 0,
29
+ thumbnailHeight = 300,
30
+ showDownload = true,
31
+ getDownloadFilename,
32
+ buttonAddition,
33
+ trigger
34
+ }) {
35
+ var _a;
36
+ const dialogRef = react.useRef(null);
37
+ const [open, setOpen] = react.useState(false);
38
+ const [index, setIndex] = react.useState(initialIndex);
39
+ const [downloading, setDownloading] = react.useState(false);
40
+ const current = items[index];
41
+ const multiple = items.length > 1;
42
+ react.useEffect(() => {
43
+ setIndex((i) => Math.min(Math.max(i, 0), Math.max(items.length - 1, 0)));
44
+ }, [items.length]);
45
+ const openAt = react.useCallback((i = 0) => {
46
+ setIndex(i);
47
+ setOpen(true);
48
+ }, []);
49
+ const close = react.useCallback(() => {
50
+ var _a2;
51
+ setDownloading(false);
52
+ (_a2 = dialogRef.current) == null ? void 0 : _a2.close();
53
+ setOpen(false);
54
+ }, []);
55
+ const prev = react.useCallback(() => {
56
+ setIndex((i) => (i - 1 + items.length) % items.length);
57
+ }, [items.length]);
58
+ const next = react.useCallback(() => {
59
+ setIndex((i) => (i + 1) % items.length);
60
+ }, [items.length]);
61
+ react.useEffect(() => {
62
+ const dialog = dialogRef.current;
63
+ if (!dialog) return;
64
+ if (open && !dialog.open) dialog.showModal();
65
+ else if (!open && dialog.open) dialog.close();
66
+ }, [open]);
67
+ react.useEffect(() => {
68
+ const dialog = dialogRef.current;
69
+ if (!dialog) return;
70
+ const onCancel = (e) => {
71
+ e.preventDefault();
72
+ close();
73
+ };
74
+ const onClose = () => {
75
+ setOpen(false);
76
+ setDownloading(false);
77
+ };
78
+ dialog.addEventListener("cancel", onCancel);
79
+ dialog.addEventListener("close", onClose);
80
+ return () => {
81
+ dialog.removeEventListener("cancel", onCancel);
82
+ dialog.removeEventListener("close", onClose);
83
+ };
84
+ }, [close]);
85
+ react.useEffect(() => {
86
+ if (!open || !multiple) return;
87
+ const onKeyDown = (e) => {
88
+ if (e.key === "ArrowLeft") prev();
89
+ if (e.key === "ArrowRight") next();
90
+ };
91
+ window.addEventListener("keydown", onKeyDown);
92
+ return () => window.removeEventListener("keydown", onKeyDown);
93
+ }, [open, multiple, prev, next]);
94
+ const download = react.useCallback(async () => {
95
+ var _a2;
96
+ if (!(current == null ? void 0 : current.downloadSrc)) return;
97
+ setDownloading(true);
98
+ try {
99
+ const res = await fetch(current.downloadSrc, { cache: "no-store" });
100
+ if (!res.ok) throw new Error(`HTTP ${res.status}`);
101
+ const blob = await res.blob();
102
+ const objectUrl = URL.createObjectURL(blob);
103
+ const ext = extFromMime((_a2 = current.mimeType) != null ? _a2 : blob.type);
104
+ const filename = getDownloadFilename ? getDownloadFilename(current, index) : `image-${index + 1}.${ext}`;
105
+ const a = document.createElement("a");
106
+ a.href = objectUrl;
107
+ a.download = filename;
108
+ document.body.appendChild(a);
109
+ a.click();
110
+ a.remove();
111
+ URL.revokeObjectURL(objectUrl);
112
+ } catch (err) {
113
+ console.warn("[Lightbox] download failed", err);
114
+ } finally {
115
+ setDownloading(false);
116
+ }
117
+ }, [current, index, getDownloadFilename]);
118
+ if (!items.length) return null;
119
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
120
+ trigger ? trigger(openAt) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles__default.default.thumbnails, children: items.map((item, i) => {
121
+ var _a2;
122
+ return /* @__PURE__ */ jsxRuntime.jsxs(
123
+ "button",
124
+ {
125
+ type: "button",
126
+ className: styles__default.default.thumbnailBtn,
127
+ onClick: () => openAt(i),
128
+ "aria-label": (_a2 = item.title) != null ? _a2 : `Billede ${i + 1}`,
129
+ children: [
130
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles__default.default.thumbnailImg, style: { height: thumbnailHeight }, children: item.thumbnail }),
131
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles__default.default.thumbnailMeta, children: /* @__PURE__ */ jsxRuntime.jsx(
132
+ client.MetaBar,
133
+ {
134
+ items: [
135
+ { label: "H\xF8jde", value: item.height != null ? `${item.height}px` : "-" },
136
+ { label: "Bredde", value: item.width != null ? `${item.width}px` : "-" }
137
+ ]
138
+ }
139
+ ) })
140
+ ]
141
+ },
142
+ i
143
+ );
144
+ }) }),
145
+ /* @__PURE__ */ jsxRuntime.jsx(
146
+ "dialog",
147
+ {
148
+ ref: dialogRef,
149
+ "aria-label": title != null ? title : "Lightbox",
150
+ tabIndex: -1,
151
+ className: styles__default.default.dialog,
152
+ onClick: (e) => {
153
+ if (e.target === e.currentTarget) close();
154
+ },
155
+ children: current && /* @__PURE__ */ jsxRuntime.jsxs(
156
+ "div",
157
+ {
158
+ className: styles__default.default.panel,
159
+ "data-surface": "inverse",
160
+ onClick: (e) => {
161
+ if (e.target === e.currentTarget) close();
162
+ },
163
+ children: [
164
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: styles__default.default.toolbar, children: [
165
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: styles__default.default.toolbarInfo, children: [
166
+ title && /* @__PURE__ */ jsxRuntime.jsx("span", { className: styles__default.default.titleMain, children: title }),
167
+ current.title && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: styles__default.default.titleItem, children: [
168
+ title ? "\xB7 " : "",
169
+ current.title
170
+ ] }),
171
+ multiple && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: styles__default.default.counter, children: [
172
+ title || current.title ? "\xB7 " : "",
173
+ index + 1,
174
+ "/",
175
+ items.length
176
+ ] })
177
+ ] }),
178
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: styles__default.default.toolbarActions, children: [
179
+ buttonAddition && /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles__default.default.buttonAdditionSlot, children: buttonAddition }),
180
+ showDownload && current.downloadSrc && /* @__PURE__ */ jsxRuntime.jsx(
181
+ Button.Button,
182
+ {
183
+ variant: "outlined",
184
+ size: "sm",
185
+ icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Download, { size: 16 }),
186
+ onClick: download,
187
+ loading: downloading,
188
+ "aria-label": "Download",
189
+ children: "Download"
190
+ }
191
+ ),
192
+ /* @__PURE__ */ jsxRuntime.jsx(
193
+ Button.Button,
194
+ {
195
+ variant: "outlined",
196
+ size: "sm",
197
+ icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { size: 16 }),
198
+ onClick: close,
199
+ "aria-label": "Luk",
200
+ children: "Luk"
201
+ }
202
+ )
203
+ ] })
204
+ ] }),
205
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles__default.default.imageArea, children: (_a = current.preview) != null ? _a : current.thumbnail }),
206
+ multiple && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: styles__default.default.nav, children: [
207
+ /* @__PURE__ */ jsxRuntime.jsx(Button.Button, { variant: "outlined", size: "sm", onClick: prev, "aria-label": "Forrige billede", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronLeft, { size: 20 }) }),
208
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: styles__default.default.navHint, children: "\u2190 \u2192 \xB7 Esc" }),
209
+ /* @__PURE__ */ jsxRuntime.jsx(Button.Button, { variant: "outlined", size: "sm", onClick: next, "aria-label": "N\xE6ste billede", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { size: 20 }) })
210
+ ] })
211
+ ]
212
+ }
213
+ )
214
+ }
215
+ )
216
+ ] });
217
+ }
218
+
219
+ exports.Lightbox = Lightbox;
@@ -0,0 +1,21 @@
1
+ import type { ReactElement, ReactNode } from 'react';
2
+ export type LightboxItem = {
3
+ thumbnail: ReactNode;
4
+ preview?: ReactNode;
5
+ title?: string;
6
+ downloadSrc?: string;
7
+ mimeType?: string;
8
+ width?: number;
9
+ height?: number;
10
+ };
11
+ export interface LightboxProps {
12
+ items: LightboxItem[];
13
+ title?: string;
14
+ initialIndex?: number;
15
+ thumbnailHeight?: number;
16
+ showDownload?: boolean;
17
+ getDownloadFilename?: (item: LightboxItem, index: number) => string;
18
+ buttonAddition?: ReactNode;
19
+ trigger?: (open: (index?: number) => void) => ReactNode;
20
+ }
21
+ export declare function Lightbox({ items, title, initialIndex, thumbnailHeight, showDownload, getDownloadFilename, buttonAddition, trigger, }: LightboxProps): ReactElement | null;