@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.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