@emiketic/lib-mantine 1.0.0

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