@emiketic/lib-mantine 1.0.0 → 1.0.2
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/index.js +215 -176
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +627 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +9 -5
- package/dist/index.cjs +0 -663
- package/dist/index.cjs.map +0 -1
- /package/dist/{index.d.cts → index.d.mts} +0 -0
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,627 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
// src/components/ClientOnly/index.tsx
|
|
4
|
+
import { useEffect, useState } from "react";
|
|
5
|
+
import { LoadingOverlay } from "@mantine/core";
|
|
6
|
+
import { jsx } from "react/jsx-runtime";
|
|
7
|
+
function ClientOnly({
|
|
8
|
+
children,
|
|
9
|
+
withLoader = false,
|
|
10
|
+
...delegated
|
|
11
|
+
}) {
|
|
12
|
+
const [hasMounted, setHasMounted] = useState(false);
|
|
13
|
+
useEffect(() => {
|
|
14
|
+
setHasMounted(true);
|
|
15
|
+
}, []);
|
|
16
|
+
if (!hasMounted) {
|
|
17
|
+
if (withLoader) {
|
|
18
|
+
return /* @__PURE__ */ jsx(LoadingOverlay, {});
|
|
19
|
+
}
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
return /* @__PURE__ */ jsx("div", { ...delegated, children });
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// src/components/ConfirmBar/index.tsx
|
|
26
|
+
import { Box, Button, Group } from "@mantine/core";
|
|
27
|
+
import { jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
28
|
+
function ConfirmBar({
|
|
29
|
+
onConfirm = () => {
|
|
30
|
+
},
|
|
31
|
+
onCancel = () => {
|
|
32
|
+
},
|
|
33
|
+
disabled = false,
|
|
34
|
+
loading = false,
|
|
35
|
+
labelProps,
|
|
36
|
+
color,
|
|
37
|
+
withCancel = true,
|
|
38
|
+
...props
|
|
39
|
+
}) {
|
|
40
|
+
return /* @__PURE__ */ jsx2(Box, { ...props, children: /* @__PURE__ */ jsxs(Group, { h: "100%", justify: "flex-end", align: "center", children: [
|
|
41
|
+
withCancel ? /* @__PURE__ */ jsx2(Button, { onClick: () => onCancel(), variant: "subtle", children: labelProps?.cancel ?? "Cancel" }) : null,
|
|
42
|
+
/* @__PURE__ */ jsx2(
|
|
43
|
+
Button,
|
|
44
|
+
{
|
|
45
|
+
onClick: () => onConfirm(),
|
|
46
|
+
disabled,
|
|
47
|
+
variant: "filled",
|
|
48
|
+
loading,
|
|
49
|
+
color,
|
|
50
|
+
children: labelProps?.confirm ?? "Confirm"
|
|
51
|
+
}
|
|
52
|
+
)
|
|
53
|
+
] }) });
|
|
54
|
+
}
|
|
55
|
+
var ConfirmBar_default = ConfirmBar;
|
|
56
|
+
|
|
57
|
+
// src/components/ContentLoader/index.tsx
|
|
58
|
+
import { Fragment } from "react";
|
|
59
|
+
import { Skeleton, Space, Stack } from "@mantine/core";
|
|
60
|
+
import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
61
|
+
function ContentLoader({
|
|
62
|
+
numberOfBars = 3,
|
|
63
|
+
numberOfBarGroups = 3,
|
|
64
|
+
barHeight = 15,
|
|
65
|
+
barSpacing = 6,
|
|
66
|
+
barGroupSpacing = "lg",
|
|
67
|
+
visible = true,
|
|
68
|
+
withCircle = false,
|
|
69
|
+
...props
|
|
70
|
+
}) {
|
|
71
|
+
if (!visible) {
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
return /* @__PURE__ */ jsxs2(Stack, { gap: "sm", px: "5rem", py: "md", ...props, children: [
|
|
75
|
+
withCircle ? /* @__PURE__ */ jsx3(Skeleton, { height: 70, circle: true, mb: "xl" }) : null,
|
|
76
|
+
Array.from({ length: numberOfBarGroups }).map((_, index) => /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
77
|
+
Array.from({ length: Math.ceil(numberOfBars / numberOfBarGroups) }).map((_2, index2) => /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
78
|
+
/* @__PURE__ */ jsx3(Skeleton, { height: barHeight, radius: "xl" }),
|
|
79
|
+
/* @__PURE__ */ jsx3(Skeleton, { height: barHeight, mt: barSpacing, radius: "xl" }),
|
|
80
|
+
/* @__PURE__ */ jsx3(Skeleton, { height: barHeight, mt: barSpacing, width: "70%", radius: "xl" })
|
|
81
|
+
] }, index2)),
|
|
82
|
+
/* @__PURE__ */ jsx3(Space, { h: barGroupSpacing })
|
|
83
|
+
] }, index))
|
|
84
|
+
] });
|
|
85
|
+
}
|
|
86
|
+
var ContentLoader_default = ContentLoader;
|
|
87
|
+
|
|
88
|
+
// src/components/ImageInput/index.tsx
|
|
89
|
+
import { useEffect as useEffect2, useState as useState2 } from "react";
|
|
90
|
+
import { ActionIcon, Avatar, FileInput, Group as Group2, Image as Image2, Paper } from "@mantine/core";
|
|
91
|
+
import { IconUpload } from "@tabler/icons-react";
|
|
92
|
+
import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
93
|
+
var DEFAULT_MAX_FILE_SIZE_BYTES = 5e5;
|
|
94
|
+
var isClient = () => typeof window !== "undefined";
|
|
95
|
+
function ImageInput({
|
|
96
|
+
value,
|
|
97
|
+
withPreview = true,
|
|
98
|
+
maxFileSizeBytes = DEFAULT_MAX_FILE_SIZE_BYTES,
|
|
99
|
+
...props
|
|
100
|
+
}) {
|
|
101
|
+
const [imageUrl, setImageUrl] = useState2(null);
|
|
102
|
+
const largeFile = isClient() && value && value instanceof File && value.size >= maxFileSizeBytes;
|
|
103
|
+
const isFileValue = isClient() && value instanceof File;
|
|
104
|
+
const isString = typeof value == "string";
|
|
105
|
+
useEffect2(() => {
|
|
106
|
+
if (isFileValue) {
|
|
107
|
+
setImageUrl(URL.createObjectURL(value));
|
|
108
|
+
} else if (isString) {
|
|
109
|
+
setImageUrl(value);
|
|
110
|
+
}
|
|
111
|
+
}, [value, isFileValue, isString]);
|
|
112
|
+
if (props.disabled && !isFileValue) {
|
|
113
|
+
return /* @__PURE__ */ jsx4(
|
|
114
|
+
Avatar,
|
|
115
|
+
{
|
|
116
|
+
size: "xl",
|
|
117
|
+
src: imageUrl,
|
|
118
|
+
...props.disabledPlaceholderProps
|
|
119
|
+
}
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
return /* @__PURE__ */ jsxs3(Group2, { children: [
|
|
123
|
+
withPreview && /* @__PURE__ */ jsx4(Paper, { radius: "md", p: "sm", withBorder: true, children: /* @__PURE__ */ jsx4(
|
|
124
|
+
Image2,
|
|
125
|
+
{
|
|
126
|
+
w: "5rem",
|
|
127
|
+
h: "5rem",
|
|
128
|
+
fit: "contain",
|
|
129
|
+
radius: "sm",
|
|
130
|
+
src: imageUrl,
|
|
131
|
+
...props.previewProps
|
|
132
|
+
}
|
|
133
|
+
) }),
|
|
134
|
+
/* @__PURE__ */ jsx4(
|
|
135
|
+
FileInput,
|
|
136
|
+
{
|
|
137
|
+
styles: { input: { fontSize: "var(--mantine-font-size-xs)" } },
|
|
138
|
+
leftSection: /* @__PURE__ */ jsx4(ActionIcon, { variant: "light", size: "xs", color: "gray", children: /* @__PURE__ */ jsx4(IconUpload, {}) }),
|
|
139
|
+
placeholder: "Upload",
|
|
140
|
+
error: largeFile ? `File size must be under ${maxFileSizeBytes / 1e3} KB` : void 0,
|
|
141
|
+
onChange: (file) => {
|
|
142
|
+
props.onChange?.(file);
|
|
143
|
+
if (file) {
|
|
144
|
+
setImageUrl(URL.createObjectURL(file));
|
|
145
|
+
}
|
|
146
|
+
},
|
|
147
|
+
...props
|
|
148
|
+
}
|
|
149
|
+
)
|
|
150
|
+
] });
|
|
151
|
+
}
|
|
152
|
+
var ImageInput_default = ImageInput;
|
|
153
|
+
|
|
154
|
+
// src/components/Logo/index.tsx
|
|
155
|
+
import { useEffect as useEffect3, useState as useState3 } from "react";
|
|
156
|
+
import { Avatar as Avatar2, ThemeIcon } from "@mantine/core";
|
|
157
|
+
|
|
158
|
+
// src/utils/colors.ts
|
|
159
|
+
import chroma from "chroma-js";
|
|
160
|
+
import { darken, lighten } from "@mantine/core";
|
|
161
|
+
function loadImage(imageUrl) {
|
|
162
|
+
return new Promise((resolve, reject) => {
|
|
163
|
+
const image = new Image();
|
|
164
|
+
image.crossOrigin = "anonymous";
|
|
165
|
+
image.referrerPolicy = "no-referrer";
|
|
166
|
+
image.onload = () => resolve(image);
|
|
167
|
+
image.onerror = () => reject(new Error("Could not load image for color extraction"));
|
|
168
|
+
image.src = imageUrl;
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
function quantizeChannel(value) {
|
|
172
|
+
return Math.round(value / 16) * 16;
|
|
173
|
+
}
|
|
174
|
+
function extractQuantizedPixels(imageData) {
|
|
175
|
+
const colors = [];
|
|
176
|
+
for (let index = 0; index < imageData.length; index += 4) {
|
|
177
|
+
const alpha = imageData[index + 3] ?? 0;
|
|
178
|
+
if (alpha < 16) continue;
|
|
179
|
+
const red = quantizeChannel(imageData[index] ?? 0);
|
|
180
|
+
const green = quantizeChannel(imageData[index + 1] ?? 0);
|
|
181
|
+
const blue = quantizeChannel(imageData[index + 2] ?? 0);
|
|
182
|
+
colors.push(chroma(red, green, blue).hex());
|
|
183
|
+
}
|
|
184
|
+
return colors;
|
|
185
|
+
}
|
|
186
|
+
function extractEdgeQuantizedPixels(imageData, width, height) {
|
|
187
|
+
const edgeColors = [];
|
|
188
|
+
const edgeThickness = Math.max(1, Math.floor(Math.min(width, height) * 0.1));
|
|
189
|
+
for (let y = 0; y < height; y += 1) {
|
|
190
|
+
for (let x = 0; x < width; x += 1) {
|
|
191
|
+
const isEdge = x < edgeThickness || x >= width - edgeThickness || y < edgeThickness || y >= height - edgeThickness;
|
|
192
|
+
if (!isEdge) continue;
|
|
193
|
+
const pixelIndex = (y * width + x) * 4;
|
|
194
|
+
const alpha = imageData[pixelIndex + 3] ?? 0;
|
|
195
|
+
if (alpha < 16) continue;
|
|
196
|
+
const red = quantizeChannel(imageData[pixelIndex] ?? 0);
|
|
197
|
+
const green = quantizeChannel(imageData[pixelIndex + 1] ?? 0);
|
|
198
|
+
const blue = quantizeChannel(imageData[pixelIndex + 2] ?? 0);
|
|
199
|
+
edgeColors.push(chroma(red, green, blue).hex());
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
return edgeColors;
|
|
203
|
+
}
|
|
204
|
+
function getMostFrequentColor(colors) {
|
|
205
|
+
if (colors.length === 0) return null;
|
|
206
|
+
const frequencies = /* @__PURE__ */ new Map();
|
|
207
|
+
for (const color of colors) {
|
|
208
|
+
frequencies.set(color, (frequencies.get(color) ?? 0) + 1);
|
|
209
|
+
}
|
|
210
|
+
let selectedColor = null;
|
|
211
|
+
let selectedCount = 0;
|
|
212
|
+
for (const [color, count] of frequencies.entries()) {
|
|
213
|
+
if (count > selectedCount) {
|
|
214
|
+
selectedColor = color;
|
|
215
|
+
selectedCount = count;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
return selectedColor;
|
|
219
|
+
}
|
|
220
|
+
var getDominantColorFromImageUrl = async (imageUrl, fallbackDominantColor = "#000000", fallbackBackgroundColor = "#ffffff") => {
|
|
221
|
+
try {
|
|
222
|
+
const image = await loadImage(imageUrl);
|
|
223
|
+
const canvas = document.createElement("canvas");
|
|
224
|
+
const context = canvas.getContext("2d", { willReadFrequently: true });
|
|
225
|
+
if (!context) {
|
|
226
|
+
return { dominant: fallbackDominantColor, background: fallbackBackgroundColor };
|
|
227
|
+
}
|
|
228
|
+
const maxSize = 96;
|
|
229
|
+
const ratio = Math.min(maxSize / image.naturalWidth, maxSize / image.naturalHeight, 1);
|
|
230
|
+
canvas.width = Math.max(1, Math.round(image.naturalWidth * ratio));
|
|
231
|
+
canvas.height = Math.max(1, Math.round(image.naturalHeight * ratio));
|
|
232
|
+
context.drawImage(image, 0, 0, canvas.width, canvas.height);
|
|
233
|
+
const imageData = context.getImageData(0, 0, canvas.width, canvas.height).data;
|
|
234
|
+
const allPixels = extractQuantizedPixels(imageData);
|
|
235
|
+
const edgePixels = extractEdgeQuantizedPixels(imageData, canvas.width, canvas.height);
|
|
236
|
+
const background = getMostFrequentColor(edgePixels) ?? getMostFrequentColor(allPixels);
|
|
237
|
+
const dominant = getMostFrequentColor(
|
|
238
|
+
background ? allPixels.filter((hex) => chroma.distance(hex, background, "rgb") > 28) : allPixels
|
|
239
|
+
) ?? getMostFrequentColor(allPixels);
|
|
240
|
+
return {
|
|
241
|
+
dominant: dominant ?? fallbackDominantColor,
|
|
242
|
+
background: background ?? fallbackBackgroundColor
|
|
243
|
+
};
|
|
244
|
+
} catch {
|
|
245
|
+
return { dominant: fallbackDominantColor, background: fallbackBackgroundColor };
|
|
246
|
+
}
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
// src/components/Logo/index.tsx
|
|
250
|
+
import { IconBuildingSkyscraper as IconFallback } from "@tabler/icons-react";
|
|
251
|
+
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
252
|
+
function Logo({ withColorPair = true, ...props }) {
|
|
253
|
+
const [logoColorPair, setLogoColorPair] = useState3({
|
|
254
|
+
dominant: "#000000",
|
|
255
|
+
background: "#ffffff"
|
|
256
|
+
});
|
|
257
|
+
useEffect3(() => {
|
|
258
|
+
let isMounted = true;
|
|
259
|
+
if (props.src && withColorPair) {
|
|
260
|
+
getDominantColorFromImageUrl(props.src).then(({ dominant, background }) => {
|
|
261
|
+
if (isMounted) {
|
|
262
|
+
setLogoColorPair({ dominant, background });
|
|
263
|
+
}
|
|
264
|
+
});
|
|
265
|
+
} else if (isMounted) {
|
|
266
|
+
setLogoColorPair({ dominant: "#000000", background: "#ffffff" });
|
|
267
|
+
}
|
|
268
|
+
return () => {
|
|
269
|
+
isMounted = false;
|
|
270
|
+
};
|
|
271
|
+
}, [props.src, withColorPair]);
|
|
272
|
+
return /* @__PURE__ */ jsx5(
|
|
273
|
+
Avatar2,
|
|
274
|
+
{
|
|
275
|
+
size: "5rem",
|
|
276
|
+
radius: "lg",
|
|
277
|
+
p: "0.125rem",
|
|
278
|
+
bg: withColorPair ? logoColorPair.background : void 0,
|
|
279
|
+
styles: {
|
|
280
|
+
image: {
|
|
281
|
+
objectFit: "contain",
|
|
282
|
+
objectPosition: "center"
|
|
283
|
+
}
|
|
284
|
+
},
|
|
285
|
+
imageProps: { referrerPolicy: "no-referrer" },
|
|
286
|
+
...props,
|
|
287
|
+
children: /* @__PURE__ */ jsx5(ThemeIcon, { variant: "transparent", size: "5rem", children: /* @__PURE__ */ jsx5(IconFallback, { size: 48 * 1.5, stroke: 1 }) })
|
|
288
|
+
}
|
|
289
|
+
);
|
|
290
|
+
}
|
|
291
|
+
var Logo_default = Logo;
|
|
292
|
+
|
|
293
|
+
// src/components/NativePDFViewer/index.tsx
|
|
294
|
+
import { useState as useState4 } from "react";
|
|
295
|
+
import { Box as Box2, Center, Loader } from "@mantine/core";
|
|
296
|
+
import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
297
|
+
function getBrowser() {
|
|
298
|
+
const { userAgent } = navigator;
|
|
299
|
+
const isSafari = /^((?!chrome|android).)*safari/i.test(userAgent);
|
|
300
|
+
const isEdge = /Edg\//.test(userAgent);
|
|
301
|
+
const isFirefox = /Firefox\//.test(userAgent);
|
|
302
|
+
const isChromium = /Chrome\/|CriOS\//.test(userAgent) && !isEdge;
|
|
303
|
+
if (isSafari) return "Safari";
|
|
304
|
+
if (isEdge) return "Edge";
|
|
305
|
+
if (isFirefox) return "Firefox";
|
|
306
|
+
if (isChromium) return "Chromium";
|
|
307
|
+
return "Unknown";
|
|
308
|
+
}
|
|
309
|
+
function NativePDFViewer({
|
|
310
|
+
mediaUrl,
|
|
311
|
+
title,
|
|
312
|
+
zoomLevel,
|
|
313
|
+
withToolbar = true,
|
|
314
|
+
fallback = "Cannot display PDF on this browser. Use a different browser or download the PDF."
|
|
315
|
+
}) {
|
|
316
|
+
const [loading, setLoading] = useState4(false);
|
|
317
|
+
const toolbarHeight = {
|
|
318
|
+
Safari: 0,
|
|
319
|
+
Edge: 40,
|
|
320
|
+
Firefox: 32,
|
|
321
|
+
Chromium: 58,
|
|
322
|
+
Unknown: 58
|
|
323
|
+
}[getBrowser()];
|
|
324
|
+
let optionsString = "";
|
|
325
|
+
if (zoomLevel) {
|
|
326
|
+
optionsString += `#zoom=${zoomLevel}%`;
|
|
327
|
+
}
|
|
328
|
+
if (!withToolbar) {
|
|
329
|
+
optionsString = "#toolbar=0";
|
|
330
|
+
}
|
|
331
|
+
const renderFallback = () => typeof fallback === "function" ? fallback() : fallback;
|
|
332
|
+
if (!mediaUrl) {
|
|
333
|
+
return null;
|
|
334
|
+
}
|
|
335
|
+
return /* @__PURE__ */ jsxs4(
|
|
336
|
+
Box2,
|
|
337
|
+
{
|
|
338
|
+
w: "100%",
|
|
339
|
+
h: toolbarHeight ? `calc(100% + ${toolbarHeight}px)` : "100%",
|
|
340
|
+
style: {
|
|
341
|
+
transform: toolbarHeight ? `translateY(-${toolbarHeight}px)` : void 0
|
|
342
|
+
},
|
|
343
|
+
children: [
|
|
344
|
+
loading ? /* @__PURE__ */ jsx6(Center, { h: "100%", w: "100%", children: /* @__PURE__ */ jsx6(Loader, { size: "xl" }) }) : null,
|
|
345
|
+
/* @__PURE__ */ jsx6(
|
|
346
|
+
"object",
|
|
347
|
+
{
|
|
348
|
+
data: `${mediaUrl}${optionsString}`,
|
|
349
|
+
type: "application/pdf",
|
|
350
|
+
width: "100%",
|
|
351
|
+
height: "100%",
|
|
352
|
+
onLoad: () => setLoading(false),
|
|
353
|
+
onError: () => setLoading(false),
|
|
354
|
+
children: /* @__PURE__ */ jsx6(Box2, { children: renderFallback() })
|
|
355
|
+
}
|
|
356
|
+
)
|
|
357
|
+
]
|
|
358
|
+
}
|
|
359
|
+
);
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
// src/components/NoData/index.tsx
|
|
363
|
+
import { Alert, Center as Center2 } from "@mantine/core";
|
|
364
|
+
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
365
|
+
function NoData({ title, children, alertProps, ...props }) {
|
|
366
|
+
return /* @__PURE__ */ jsx7(Center2, { h: "100%", ...props, children: /* @__PURE__ */ jsx7(Alert, { p: "3rem", title: title ?? "No data", ...alertProps, children: /* @__PURE__ */ jsx7(Center2, { children }) }) });
|
|
367
|
+
}
|
|
368
|
+
var NoData_default = NoData;
|
|
369
|
+
|
|
370
|
+
// src/components/PageContainer/index.tsx
|
|
371
|
+
import { Box as Box3, Container, Group as Group3, ScrollArea, Stack as Stack2, Title } from "@mantine/core";
|
|
372
|
+
import { jsx as jsx8, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
373
|
+
function PageContainer({
|
|
374
|
+
children,
|
|
375
|
+
title,
|
|
376
|
+
titleProps,
|
|
377
|
+
header,
|
|
378
|
+
headerProps,
|
|
379
|
+
rightSection = null,
|
|
380
|
+
contentProps,
|
|
381
|
+
outerContentProps,
|
|
382
|
+
fullPage = false,
|
|
383
|
+
withContentScroll = false,
|
|
384
|
+
...props
|
|
385
|
+
}) {
|
|
386
|
+
function getTitle() {
|
|
387
|
+
if (title) {
|
|
388
|
+
return /* @__PURE__ */ jsx8(Title, { order: 2, ...titleProps, children: title });
|
|
389
|
+
}
|
|
390
|
+
return null;
|
|
391
|
+
}
|
|
392
|
+
function getHeader() {
|
|
393
|
+
if (header) {
|
|
394
|
+
return header;
|
|
395
|
+
}
|
|
396
|
+
return /* @__PURE__ */ jsxs5(Group3, { justify: "space-between", w: "100%", ...headerProps, children: [
|
|
397
|
+
getTitle(),
|
|
398
|
+
rightSection
|
|
399
|
+
] });
|
|
400
|
+
}
|
|
401
|
+
function getContent() {
|
|
402
|
+
if (fullPage) {
|
|
403
|
+
return /* @__PURE__ */ jsx8(Box3, { ...contentProps, children });
|
|
404
|
+
}
|
|
405
|
+
return /* @__PURE__ */ jsxs5(Stack2, { gap: "xl", ...outerContentProps, children: [
|
|
406
|
+
getHeader(),
|
|
407
|
+
/* @__PURE__ */ jsx8(Stack2, { px: "xl", py: "lg", h: "100%", w: "100%", ...contentProps, children })
|
|
408
|
+
] });
|
|
409
|
+
}
|
|
410
|
+
if (withContentScroll) {
|
|
411
|
+
return /* @__PURE__ */ jsx8(ScrollArea, { h: "100vh", p: 0, ...props, children: /* @__PURE__ */ jsx8(Container, { fluid: true, children: getContent() }) });
|
|
412
|
+
}
|
|
413
|
+
return /* @__PURE__ */ jsx8(Container, { p: 0, w: "100%", fluid: true, children: getContent() });
|
|
414
|
+
}
|
|
415
|
+
var PageContainer_default = PageContainer;
|
|
416
|
+
|
|
417
|
+
// src/components/PhoneInput/index.tsx
|
|
418
|
+
import { useEffect as useEffect4, useState as useState5 } from "react";
|
|
419
|
+
import { getCountryData, getEmojiFlag } from "countries-list";
|
|
420
|
+
import parsePhoneNumber, {
|
|
421
|
+
getCountries,
|
|
422
|
+
getCountryCallingCode
|
|
423
|
+
} from "libphonenumber-js";
|
|
424
|
+
import { Group as Group4, Select, TextInput } from "@mantine/core";
|
|
425
|
+
import { Fragment as Fragment2, jsx as jsx9, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
426
|
+
var COUNTRY_CODES = getCountries();
|
|
427
|
+
function PhoneInput({ value, defaultValue, defaultCountryCode, ...props }) {
|
|
428
|
+
const valueNumber = value ?? "";
|
|
429
|
+
const valueNumberData = parsePhoneNumber(valueNumber);
|
|
430
|
+
let valueNumberCountryCode;
|
|
431
|
+
if (valueNumberData?.isValid()) {
|
|
432
|
+
valueNumberCountryCode = valueNumberData.country;
|
|
433
|
+
}
|
|
434
|
+
const [selectedCountryCode, setSelectedCountryCode] = useState5(
|
|
435
|
+
defaultCountryCode
|
|
436
|
+
);
|
|
437
|
+
const selectedCountryCodeCallingNumber = selectedCountryCode ? getCountryCallingCode(selectedCountryCode) : void 0;
|
|
438
|
+
useEffect4(() => {
|
|
439
|
+
if (selectedCountryCode && selectedCountryCode !== valueNumberCountryCode) {
|
|
440
|
+
const code = selectedCountryCode ?? defaultCountryCode ?? "";
|
|
441
|
+
const callingCode = getCountryCallingCode(code);
|
|
442
|
+
if (props.onChange) {
|
|
443
|
+
const numberUpdate = `+${callingCode}${valueNumber.replace(callingCode, "")}`;
|
|
444
|
+
const numberUpdateData = parsePhoneNumber(numberUpdate, selectedCountryCode);
|
|
445
|
+
if (numberUpdateData?.isValid()) {
|
|
446
|
+
props.onChange(`+${callingCode}${valueNumber.replace(callingCode, "")}`);
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
}, [selectedCountryCode]);
|
|
451
|
+
return /* @__PURE__ */ jsxs6(Group4, { wrap: "nowrap", children: [
|
|
452
|
+
/* @__PURE__ */ jsx9(
|
|
453
|
+
Select,
|
|
454
|
+
{
|
|
455
|
+
label: "Country code",
|
|
456
|
+
size: "sm",
|
|
457
|
+
classNames: { ...props.classNames },
|
|
458
|
+
defaultValue: defaultCountryCode,
|
|
459
|
+
value: valueNumberCountryCode,
|
|
460
|
+
onChange: (c) => {
|
|
461
|
+
if (c === null) {
|
|
462
|
+
setSelectedCountryCode(void 0);
|
|
463
|
+
} else {
|
|
464
|
+
setSelectedCountryCode(c);
|
|
465
|
+
}
|
|
466
|
+
},
|
|
467
|
+
data: COUNTRY_CODES.map((code) => {
|
|
468
|
+
const countryCallingCode = getCountryCallingCode(code);
|
|
469
|
+
const countryName = getCountryData(code).name;
|
|
470
|
+
return {
|
|
471
|
+
value: code,
|
|
472
|
+
label: `${countryName} ${getEmojiFlag(code)} +${countryCallingCode}`
|
|
473
|
+
};
|
|
474
|
+
}),
|
|
475
|
+
rightSection: props.disabled ? /* @__PURE__ */ jsx9(Fragment2, {}) : void 0,
|
|
476
|
+
disabled: props.disabled,
|
|
477
|
+
searchable: true
|
|
478
|
+
}
|
|
479
|
+
),
|
|
480
|
+
/* @__PURE__ */ jsx9(
|
|
481
|
+
TextInput,
|
|
482
|
+
{
|
|
483
|
+
...props,
|
|
484
|
+
defaultValue: valueNumberData?.nationalNumber,
|
|
485
|
+
onChange: (e) => {
|
|
486
|
+
if (props.onChange && selectedCountryCodeCallingNumber) {
|
|
487
|
+
const numberUpdate = `+${selectedCountryCodeCallingNumber}${e.currentTarget.value.replace(selectedCountryCodeCallingNumber, "")}`;
|
|
488
|
+
const numberUpdateData = parsePhoneNumber(numberUpdate, selectedCountryCode);
|
|
489
|
+
if (numberUpdateData?.isValid()) {
|
|
490
|
+
props.onChange(numberUpdateData.number);
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
)
|
|
496
|
+
] });
|
|
497
|
+
}
|
|
498
|
+
var PhoneInput_default = PhoneInput;
|
|
499
|
+
|
|
500
|
+
// src/components/TextEditor/index.tsx
|
|
501
|
+
import { useEffect as useEffect5 } from "react";
|
|
502
|
+
import Highlight from "@tiptap/extension-highlight";
|
|
503
|
+
import SubScript from "@tiptap/extension-subscript";
|
|
504
|
+
import Superscript from "@tiptap/extension-superscript";
|
|
505
|
+
import TextAlign from "@tiptap/extension-text-align";
|
|
506
|
+
import Underline from "@tiptap/extension-underline";
|
|
507
|
+
import { useEditor } from "@tiptap/react";
|
|
508
|
+
import StarterKit from "@tiptap/starter-kit";
|
|
509
|
+
import { Link, RichTextEditor } from "@mantine/tiptap";
|
|
510
|
+
import { jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
511
|
+
function TextEditor({
|
|
512
|
+
content,
|
|
513
|
+
value,
|
|
514
|
+
onChangeEditorHTML = () => {
|
|
515
|
+
},
|
|
516
|
+
onChange = () => {
|
|
517
|
+
},
|
|
518
|
+
...props
|
|
519
|
+
}) {
|
|
520
|
+
const editor = useEditor({
|
|
521
|
+
editable: true,
|
|
522
|
+
extensions: [
|
|
523
|
+
StarterKit,
|
|
524
|
+
Underline,
|
|
525
|
+
Link,
|
|
526
|
+
Superscript,
|
|
527
|
+
SubScript,
|
|
528
|
+
Highlight,
|
|
529
|
+
TextAlign.configure({ types: ["heading", "paragraph"] })
|
|
530
|
+
],
|
|
531
|
+
content
|
|
532
|
+
});
|
|
533
|
+
useEffect5(() => {
|
|
534
|
+
onChangeEditorHTML(editor?.getHTML());
|
|
535
|
+
onChange(editor?.getHTML());
|
|
536
|
+
}, [editor?.state, editor, onChangeEditorHTML, onChange]);
|
|
537
|
+
return /* @__PURE__ */ jsxs7(RichTextEditor, { editor, ...props, children: [
|
|
538
|
+
/* @__PURE__ */ jsxs7(RichTextEditor.Toolbar, { sticky: true, stickyOffset: 60, children: [
|
|
539
|
+
/* @__PURE__ */ jsxs7(RichTextEditor.ControlsGroup, { children: [
|
|
540
|
+
/* @__PURE__ */ jsx10(RichTextEditor.Bold, {}),
|
|
541
|
+
/* @__PURE__ */ jsx10(RichTextEditor.Italic, {}),
|
|
542
|
+
/* @__PURE__ */ jsx10(RichTextEditor.Underline, {}),
|
|
543
|
+
/* @__PURE__ */ jsx10(RichTextEditor.Strikethrough, {}),
|
|
544
|
+
/* @__PURE__ */ jsx10(RichTextEditor.ClearFormatting, {}),
|
|
545
|
+
/* @__PURE__ */ jsx10(RichTextEditor.Highlight, {}),
|
|
546
|
+
/* @__PURE__ */ jsx10(RichTextEditor.Code, {})
|
|
547
|
+
] }),
|
|
548
|
+
/* @__PURE__ */ jsxs7(RichTextEditor.ControlsGroup, { children: [
|
|
549
|
+
/* @__PURE__ */ jsx10(RichTextEditor.H1, {}),
|
|
550
|
+
/* @__PURE__ */ jsx10(RichTextEditor.H2, {}),
|
|
551
|
+
/* @__PURE__ */ jsx10(RichTextEditor.H3, {}),
|
|
552
|
+
/* @__PURE__ */ jsx10(RichTextEditor.H4, {})
|
|
553
|
+
] }),
|
|
554
|
+
/* @__PURE__ */ jsxs7(RichTextEditor.ControlsGroup, { children: [
|
|
555
|
+
/* @__PURE__ */ jsx10(RichTextEditor.Blockquote, {}),
|
|
556
|
+
/* @__PURE__ */ jsx10(RichTextEditor.Hr, {}),
|
|
557
|
+
/* @__PURE__ */ jsx10(RichTextEditor.BulletList, {}),
|
|
558
|
+
/* @__PURE__ */ jsx10(RichTextEditor.OrderedList, {}),
|
|
559
|
+
/* @__PURE__ */ jsx10(RichTextEditor.Subscript, {}),
|
|
560
|
+
/* @__PURE__ */ jsx10(RichTextEditor.Superscript, {})
|
|
561
|
+
] }),
|
|
562
|
+
/* @__PURE__ */ jsxs7(RichTextEditor.ControlsGroup, { children: [
|
|
563
|
+
/* @__PURE__ */ jsx10(RichTextEditor.Link, {}),
|
|
564
|
+
/* @__PURE__ */ jsx10(RichTextEditor.Unlink, {})
|
|
565
|
+
] }),
|
|
566
|
+
/* @__PURE__ */ jsxs7(RichTextEditor.ControlsGroup, { children: [
|
|
567
|
+
/* @__PURE__ */ jsx10(RichTextEditor.AlignLeft, {}),
|
|
568
|
+
/* @__PURE__ */ jsx10(RichTextEditor.AlignCenter, {}),
|
|
569
|
+
/* @__PURE__ */ jsx10(RichTextEditor.AlignJustify, {}),
|
|
570
|
+
/* @__PURE__ */ jsx10(RichTextEditor.AlignRight, {})
|
|
571
|
+
] })
|
|
572
|
+
] }),
|
|
573
|
+
/* @__PURE__ */ jsx10(RichTextEditor.Content, {})
|
|
574
|
+
] });
|
|
575
|
+
}
|
|
576
|
+
var TextEditor_default = TextEditor;
|
|
577
|
+
|
|
578
|
+
// src/components/ThemeToggle/index.tsx
|
|
579
|
+
import {
|
|
580
|
+
Switch,
|
|
581
|
+
ThemeIcon as ThemeIcon2,
|
|
582
|
+
Tooltip,
|
|
583
|
+
useComputedColorScheme,
|
|
584
|
+
useMantineColorScheme
|
|
585
|
+
} from "@mantine/core";
|
|
586
|
+
import { IconMoon as IconSwitchDark, IconSun as IconSwitchLight } from "@tabler/icons-react";
|
|
587
|
+
import { jsx as jsx11 } from "react/jsx-runtime";
|
|
588
|
+
function ThemeToggle({ ...props }) {
|
|
589
|
+
const { setColorScheme } = useMantineColorScheme();
|
|
590
|
+
const computedColorScheme = useComputedColorScheme("light", { getInitialValueInEffect: true });
|
|
591
|
+
return /* @__PURE__ */ jsx11(
|
|
592
|
+
Tooltip,
|
|
593
|
+
{
|
|
594
|
+
label: computedColorScheme === "light" ? "Switch to dark mode" : "Switch to light mode",
|
|
595
|
+
position: "bottom",
|
|
596
|
+
withinPortal: true,
|
|
597
|
+
children: /* @__PURE__ */ jsx11(ClientOnly, { children: /* @__PURE__ */ jsx11(
|
|
598
|
+
Switch,
|
|
599
|
+
{
|
|
600
|
+
styles: { track: { cursor: "pointer" } },
|
|
601
|
+
defaultChecked: computedColorScheme === "dark",
|
|
602
|
+
onChange: () => setColorScheme(computedColorScheme === "light" ? "dark" : "light"),
|
|
603
|
+
onLabel: /* @__PURE__ */ jsx11(ThemeIcon2, { size: props.size ?? "sm", variant: "transparent", children: /* @__PURE__ */ jsx11(IconSwitchDark, {}) }),
|
|
604
|
+
offLabel: /* @__PURE__ */ jsx11(ThemeIcon2, { size: props.size ?? "sm", color: "yellow", variant: "transparent", children: /* @__PURE__ */ jsx11(IconSwitchLight, {}) }),
|
|
605
|
+
color: "dark",
|
|
606
|
+
size: "md",
|
|
607
|
+
...props
|
|
608
|
+
}
|
|
609
|
+
) })
|
|
610
|
+
}
|
|
611
|
+
);
|
|
612
|
+
}
|
|
613
|
+
var ThemeToggle_default = ThemeToggle;
|
|
614
|
+
export {
|
|
615
|
+
ClientOnly,
|
|
616
|
+
ConfirmBar_default as ConfirmBar,
|
|
617
|
+
ContentLoader_default as ContentLoader,
|
|
618
|
+
ImageInput_default as ImageInput,
|
|
619
|
+
Logo_default as Logo,
|
|
620
|
+
NativePDFViewer,
|
|
621
|
+
NoData_default as NoData,
|
|
622
|
+
PageContainer_default as PageContainer,
|
|
623
|
+
PhoneInput_default as PhoneInput,
|
|
624
|
+
TextEditor_default as TextEditor,
|
|
625
|
+
ThemeToggle_default as ThemeToggle
|
|
626
|
+
};
|
|
627
|
+
//# sourceMappingURL=index.mjs.map
|