@trafica/editor 1.0.23 → 1.0.24
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 +518 -644
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +518 -644
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { forwardRef, useRef, useEffect, useCallback, useMemo, useImperativeHandle, useState, useLayoutEffect, useSyncExternalStore } from 'react';
|
|
2
|
-
import { createPortal } from 'react-dom';
|
|
3
2
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
3
|
+
import { createPortal } from 'react-dom';
|
|
4
4
|
|
|
5
5
|
// src/editor/core/DocumentModel.ts
|
|
6
6
|
function isTextNode(node) {
|
|
@@ -3319,15 +3319,13 @@ var OPTIONS = [
|
|
|
3319
3319
|
function AlignmentDropdown({ engine, activeAlignment }) {
|
|
3320
3320
|
var _a;
|
|
3321
3321
|
const [open, setOpen] = useState(false);
|
|
3322
|
-
const
|
|
3323
|
-
const buttonRef = useRef(null);
|
|
3324
|
-
const popupRef = useRef(null);
|
|
3322
|
+
const containerRef = useRef(null);
|
|
3325
3323
|
useEffect(() => {
|
|
3326
3324
|
if (!open) return;
|
|
3327
3325
|
const handler = (e) => {
|
|
3328
|
-
|
|
3329
|
-
|
|
3330
|
-
|
|
3326
|
+
if (containerRef.current && !containerRef.current.contains(e.target)) {
|
|
3327
|
+
setOpen(false);
|
|
3328
|
+
}
|
|
3331
3329
|
};
|
|
3332
3330
|
document.addEventListener("mousedown", handler);
|
|
3333
3331
|
return () => document.removeEventListener("mousedown", handler);
|
|
@@ -3341,31 +3339,22 @@ function AlignmentDropdown({ engine, activeAlignment }) {
|
|
|
3341
3339
|
return () => document.removeEventListener("keydown", handler);
|
|
3342
3340
|
}, [open]);
|
|
3343
3341
|
const activeOption = (_a = OPTIONS.find((o) => o.value === activeAlignment)) != null ? _a : OPTIONS[0];
|
|
3344
|
-
return /* @__PURE__ */ jsxs(
|
|
3342
|
+
return /* @__PURE__ */ jsxs("div", { ref: containerRef, className: "relative", children: [
|
|
3345
3343
|
/* @__PURE__ */ jsxs(
|
|
3346
3344
|
"button",
|
|
3347
3345
|
{
|
|
3348
|
-
ref: buttonRef,
|
|
3349
3346
|
type: "button",
|
|
3350
3347
|
title: `Text alignment (${activeOption.label})`,
|
|
3351
3348
|
"aria-haspopup": "listbox",
|
|
3352
3349
|
"aria-expanded": open,
|
|
3353
3350
|
onMouseDown: (e) => {
|
|
3354
3351
|
e.preventDefault();
|
|
3355
|
-
|
|
3356
|
-
setOpen(false);
|
|
3357
|
-
return;
|
|
3358
|
-
}
|
|
3359
|
-
if (buttonRef.current) {
|
|
3360
|
-
const rect = buttonRef.current.getBoundingClientRect();
|
|
3361
|
-
setPopupPos({ top: rect.bottom + 4, left: rect.left });
|
|
3362
|
-
}
|
|
3363
|
-
setOpen(true);
|
|
3352
|
+
setOpen((prev) => !prev);
|
|
3364
3353
|
},
|
|
3365
3354
|
className: [
|
|
3366
3355
|
"flex items-center gap-0.5 px-1.5 h-8 rounded text-sm font-medium transition-colors",
|
|
3367
3356
|
"focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500",
|
|
3368
|
-
open ? "bg-gray-100
|
|
3357
|
+
open ? "bg-gray-100 text-gray-900 " : "text-gray-700 hover:bg-gray-100 "
|
|
3369
3358
|
].join(" "),
|
|
3370
3359
|
children: [
|
|
3371
3360
|
activeOption.icon,
|
|
@@ -3373,45 +3362,40 @@ function AlignmentDropdown({ engine, activeAlignment }) {
|
|
|
3373
3362
|
]
|
|
3374
3363
|
}
|
|
3375
3364
|
),
|
|
3376
|
-
open &&
|
|
3377
|
-
|
|
3378
|
-
|
|
3379
|
-
|
|
3380
|
-
|
|
3381
|
-
|
|
3382
|
-
|
|
3383
|
-
|
|
3384
|
-
|
|
3385
|
-
|
|
3386
|
-
|
|
3387
|
-
|
|
3388
|
-
"
|
|
3389
|
-
|
|
3390
|
-
|
|
3391
|
-
|
|
3392
|
-
|
|
3393
|
-
|
|
3394
|
-
|
|
3395
|
-
e.preventDefault();
|
|
3396
|
-
setAlignment(option.value)(engine);
|
|
3397
|
-
setOpen(false);
|
|
3398
|
-
},
|
|
3399
|
-
className: [
|
|
3400
|
-
"w-full flex items-center gap-3 px-3 py-1.5 text-sm transition-colors",
|
|
3401
|
-
isActive ? "bg-blue-50 dark:bg-blue-900/30 text-blue-700 dark:text-blue-300 font-medium" : "text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700"
|
|
3402
|
-
].join(" "),
|
|
3403
|
-
children: [
|
|
3404
|
-
/* @__PURE__ */ jsx("span", { className: "flex-shrink-0", children: option.icon }),
|
|
3405
|
-
/* @__PURE__ */ jsx("span", { className: "flex-1 text-left", children: option.label }),
|
|
3406
|
-
isActive && /* @__PURE__ */ jsx(CheckIcon, {})
|
|
3407
|
-
]
|
|
3365
|
+
open && /* @__PURE__ */ jsx(
|
|
3366
|
+
"div",
|
|
3367
|
+
{
|
|
3368
|
+
role: "listbox",
|
|
3369
|
+
"aria-label": "Text alignment",
|
|
3370
|
+
className: "absolute top-full left-0 mt-1 z-50 bg-white border border-gray-200 rounded-lg shadow-lg py-1 min-w-[168px]",
|
|
3371
|
+
children: OPTIONS.map((option) => {
|
|
3372
|
+
const isActive = activeAlignment === option.value;
|
|
3373
|
+
return /* @__PURE__ */ jsxs(
|
|
3374
|
+
"button",
|
|
3375
|
+
{
|
|
3376
|
+
type: "button",
|
|
3377
|
+
role: "option",
|
|
3378
|
+
"aria-selected": isActive,
|
|
3379
|
+
title: `${option.label} (${option.shortcut})`,
|
|
3380
|
+
onMouseDown: (e) => {
|
|
3381
|
+
e.preventDefault();
|
|
3382
|
+
setAlignment(option.value)(engine);
|
|
3383
|
+
setOpen(false);
|
|
3408
3384
|
},
|
|
3409
|
-
|
|
3410
|
-
|
|
3411
|
-
|
|
3412
|
-
|
|
3413
|
-
|
|
3414
|
-
|
|
3385
|
+
className: [
|
|
3386
|
+
"w-full flex items-center gap-3 px-3 py-1.5 text-sm transition-colors",
|
|
3387
|
+
isActive ? "bg-blue-50 text-blue-700 font-medium" : "text-gray-700 hover:bg-gray-100 "
|
|
3388
|
+
].join(" "),
|
|
3389
|
+
children: [
|
|
3390
|
+
/* @__PURE__ */ jsx("span", { className: "flex-shrink-0", children: option.icon }),
|
|
3391
|
+
/* @__PURE__ */ jsx("span", { className: "flex-1 text-left", children: option.label }),
|
|
3392
|
+
isActive && /* @__PURE__ */ jsx(CheckIcon, {})
|
|
3393
|
+
]
|
|
3394
|
+
},
|
|
3395
|
+
option.value
|
|
3396
|
+
);
|
|
3397
|
+
})
|
|
3398
|
+
}
|
|
3415
3399
|
)
|
|
3416
3400
|
] });
|
|
3417
3401
|
}
|
|
@@ -3456,15 +3440,11 @@ function CheckIcon() {
|
|
|
3456
3440
|
var SIZES = ["8", "10", "12", "14", "16", "18", "24", "32", "48"];
|
|
3457
3441
|
function FontSizeDropdown({ engine, activeFontSize }) {
|
|
3458
3442
|
const [open, setOpen] = useState(false);
|
|
3459
|
-
const
|
|
3460
|
-
const buttonRef = useRef(null);
|
|
3461
|
-
const popupRef = useRef(null);
|
|
3443
|
+
const containerRef = useRef(null);
|
|
3462
3444
|
useEffect(() => {
|
|
3463
3445
|
if (!open) return;
|
|
3464
3446
|
const handler = (e) => {
|
|
3465
|
-
|
|
3466
|
-
const target = e.target;
|
|
3467
|
-
if (!((_a = popupRef.current) == null ? void 0 : _a.contains(target)) && !((_b = buttonRef.current) == null ? void 0 : _b.contains(target))) {
|
|
3447
|
+
if (containerRef.current && !containerRef.current.contains(e.target)) {
|
|
3468
3448
|
setOpen(false);
|
|
3469
3449
|
}
|
|
3470
3450
|
};
|
|
@@ -3479,36 +3459,24 @@ function FontSizeDropdown({ engine, activeFontSize }) {
|
|
|
3479
3459
|
document.addEventListener("keydown", handler);
|
|
3480
3460
|
return () => document.removeEventListener("keydown", handler);
|
|
3481
3461
|
}, [open]);
|
|
3482
|
-
function openDropdown() {
|
|
3483
|
-
if (buttonRef.current) {
|
|
3484
|
-
const rect = buttonRef.current.getBoundingClientRect();
|
|
3485
|
-
setPopupPos({ top: rect.bottom + 4, left: rect.left });
|
|
3486
|
-
}
|
|
3487
|
-
setOpen(true);
|
|
3488
|
-
}
|
|
3489
3462
|
const activeNum = activeFontSize ? activeFontSize.replace("px", "") : null;
|
|
3490
3463
|
const label = activeNum != null ? activeNum : "Size";
|
|
3491
|
-
return /* @__PURE__ */ jsxs(
|
|
3464
|
+
return /* @__PURE__ */ jsxs("div", { ref: containerRef, className: "relative", children: [
|
|
3492
3465
|
/* @__PURE__ */ jsxs(
|
|
3493
3466
|
"button",
|
|
3494
3467
|
{
|
|
3495
|
-
ref: buttonRef,
|
|
3496
3468
|
type: "button",
|
|
3497
3469
|
title: "Font size",
|
|
3498
3470
|
"aria-haspopup": "listbox",
|
|
3499
3471
|
"aria-expanded": open,
|
|
3500
3472
|
onMouseDown: (e) => {
|
|
3501
3473
|
e.preventDefault();
|
|
3502
|
-
|
|
3503
|
-
setOpen(false);
|
|
3504
|
-
} else {
|
|
3505
|
-
openDropdown();
|
|
3506
|
-
}
|
|
3474
|
+
setOpen((prev) => !prev);
|
|
3507
3475
|
},
|
|
3508
3476
|
className: [
|
|
3509
3477
|
"flex items-center gap-0.5 px-1.5 h-8 rounded text-sm font-medium transition-colors min-w-[52px]",
|
|
3510
3478
|
"focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500",
|
|
3511
|
-
open ? "bg-gray-100
|
|
3479
|
+
open ? "bg-gray-100 text-gray-900 " : "text-gray-700 hover:bg-gray-100 "
|
|
3512
3480
|
].join(" "),
|
|
3513
3481
|
children: [
|
|
3514
3482
|
/* @__PURE__ */ jsx("span", { className: "flex-1 text-left", children: label }),
|
|
@@ -3516,66 +3484,61 @@ function FontSizeDropdown({ engine, activeFontSize }) {
|
|
|
3516
3484
|
]
|
|
3517
3485
|
}
|
|
3518
3486
|
),
|
|
3519
|
-
open &&
|
|
3520
|
-
|
|
3521
|
-
|
|
3522
|
-
|
|
3523
|
-
|
|
3524
|
-
|
|
3525
|
-
|
|
3526
|
-
|
|
3527
|
-
|
|
3528
|
-
|
|
3529
|
-
|
|
3487
|
+
open && /* @__PURE__ */ jsxs(
|
|
3488
|
+
"div",
|
|
3489
|
+
{
|
|
3490
|
+
role: "listbox",
|
|
3491
|
+
"aria-label": "Font size",
|
|
3492
|
+
className: "absolute top-full left-0 mt-1 z-50 bg-white border border-gray-200 rounded-lg shadow-lg py-1 min-w-[88px] max-h-64 overflow-y-auto",
|
|
3493
|
+
children: [
|
|
3494
|
+
/* @__PURE__ */ jsxs(
|
|
3495
|
+
"button",
|
|
3496
|
+
{
|
|
3497
|
+
type: "button",
|
|
3498
|
+
role: "option",
|
|
3499
|
+
"aria-selected": activeFontSize === null,
|
|
3500
|
+
onMouseDown: (e) => {
|
|
3501
|
+
e.preventDefault();
|
|
3502
|
+
setFontSize(null)(engine);
|
|
3503
|
+
setOpen(false);
|
|
3504
|
+
},
|
|
3505
|
+
className: [
|
|
3506
|
+
"w-full flex items-center justify-between px-3 py-1.5 text-sm transition-colors",
|
|
3507
|
+
activeFontSize === null ? "bg-blue-50 text-blue-700 font-medium" : "text-gray-700 hover:bg-gray-100 "
|
|
3508
|
+
].join(" "),
|
|
3509
|
+
children: [
|
|
3510
|
+
/* @__PURE__ */ jsx("span", { children: "Default" }),
|
|
3511
|
+
activeFontSize === null && /* @__PURE__ */ jsx(CheckIcon2, {})
|
|
3512
|
+
]
|
|
3513
|
+
}
|
|
3514
|
+
),
|
|
3515
|
+
SIZES.map((size) => {
|
|
3516
|
+
const isActive = activeNum === size;
|
|
3517
|
+
return /* @__PURE__ */ jsxs(
|
|
3530
3518
|
"button",
|
|
3531
3519
|
{
|
|
3532
3520
|
type: "button",
|
|
3533
3521
|
role: "option",
|
|
3534
|
-
"aria-selected":
|
|
3522
|
+
"aria-selected": isActive,
|
|
3535
3523
|
onMouseDown: (e) => {
|
|
3536
3524
|
e.preventDefault();
|
|
3537
|
-
setFontSize(
|
|
3525
|
+
setFontSize(`${size}px`)(engine);
|
|
3538
3526
|
setOpen(false);
|
|
3539
3527
|
},
|
|
3540
3528
|
className: [
|
|
3541
|
-
"w-full flex items-center justify-between px-3 py-1.5
|
|
3542
|
-
|
|
3529
|
+
"w-full flex items-center justify-between px-3 py-1.5 transition-colors",
|
|
3530
|
+
isActive ? "bg-blue-50 text-blue-700 font-medium" : "text-gray-700 hover:bg-gray-100 "
|
|
3543
3531
|
].join(" "),
|
|
3544
3532
|
children: [
|
|
3545
|
-
/* @__PURE__ */ jsx("span", { children:
|
|
3546
|
-
|
|
3533
|
+
/* @__PURE__ */ jsx("span", { style: { fontSize: `${size}px`, lineHeight: 1.3 }, children: size }),
|
|
3534
|
+
isActive && /* @__PURE__ */ jsx(CheckIcon2, {})
|
|
3547
3535
|
]
|
|
3548
|
-
}
|
|
3549
|
-
|
|
3550
|
-
|
|
3551
|
-
|
|
3552
|
-
|
|
3553
|
-
|
|
3554
|
-
{
|
|
3555
|
-
type: "button",
|
|
3556
|
-
role: "option",
|
|
3557
|
-
"aria-selected": isActive,
|
|
3558
|
-
onMouseDown: (e) => {
|
|
3559
|
-
e.preventDefault();
|
|
3560
|
-
setFontSize(`${size}px`)(engine);
|
|
3561
|
-
setOpen(false);
|
|
3562
|
-
},
|
|
3563
|
-
className: [
|
|
3564
|
-
"w-full flex items-center justify-between px-3 py-1.5 transition-colors",
|
|
3565
|
-
isActive ? "bg-blue-50 dark:bg-blue-900/30 text-blue-700 dark:text-blue-300 font-medium" : "text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700"
|
|
3566
|
-
].join(" "),
|
|
3567
|
-
children: [
|
|
3568
|
-
/* @__PURE__ */ jsx("span", { style: { fontSize: `${size}px`, lineHeight: 1.3 }, children: size }),
|
|
3569
|
-
isActive && /* @__PURE__ */ jsx(CheckIcon2, {})
|
|
3570
|
-
]
|
|
3571
|
-
},
|
|
3572
|
-
size
|
|
3573
|
-
);
|
|
3574
|
-
})
|
|
3575
|
-
]
|
|
3576
|
-
}
|
|
3577
|
-
),
|
|
3578
|
-
document.body
|
|
3536
|
+
},
|
|
3537
|
+
size
|
|
3538
|
+
);
|
|
3539
|
+
})
|
|
3540
|
+
]
|
|
3541
|
+
}
|
|
3579
3542
|
)
|
|
3580
3543
|
] });
|
|
3581
3544
|
}
|
|
@@ -3601,16 +3564,12 @@ function FontFamilyDropdown({ engine, activeFontFamily }) {
|
|
|
3601
3564
|
const [open, setOpen] = useState(false);
|
|
3602
3565
|
const [showCustomInput, setShowCustomInput] = useState(false);
|
|
3603
3566
|
const [customValue, setCustomValue] = useState("");
|
|
3604
|
-
const
|
|
3605
|
-
const buttonRef = useRef(null);
|
|
3606
|
-
const popupRef = useRef(null);
|
|
3567
|
+
const containerRef = useRef(null);
|
|
3607
3568
|
const customInputRef = useRef(null);
|
|
3608
3569
|
useEffect(() => {
|
|
3609
3570
|
if (!open) return;
|
|
3610
3571
|
const handler = (e) => {
|
|
3611
|
-
|
|
3612
|
-
const target = e.target;
|
|
3613
|
-
if (!((_a2 = popupRef.current) == null ? void 0 : _a2.contains(target)) && !((_b = buttonRef.current) == null ? void 0 : _b.contains(target))) {
|
|
3572
|
+
if (containerRef.current && !containerRef.current.contains(e.target)) {
|
|
3614
3573
|
closeDropdown();
|
|
3615
3574
|
}
|
|
3616
3575
|
};
|
|
@@ -3629,17 +3588,6 @@ function FontFamilyDropdown({ engine, activeFontFamily }) {
|
|
|
3629
3588
|
var _a2;
|
|
3630
3589
|
if (showCustomInput) (_a2 = customInputRef.current) == null ? void 0 : _a2.focus();
|
|
3631
3590
|
}, [showCustomInput]);
|
|
3632
|
-
function openDropdown() {
|
|
3633
|
-
if (buttonRef.current) {
|
|
3634
|
-
const rect = buttonRef.current.getBoundingClientRect();
|
|
3635
|
-
const popupWidth = 200;
|
|
3636
|
-
const left = Math.min(rect.left, window.innerWidth - popupWidth - 8);
|
|
3637
|
-
setPopupPos({ top: rect.bottom + 4, left: Math.max(8, left) });
|
|
3638
|
-
}
|
|
3639
|
-
setShowCustomInput(false);
|
|
3640
|
-
setCustomValue("");
|
|
3641
|
-
setOpen(true);
|
|
3642
|
-
}
|
|
3643
3591
|
function closeDropdown() {
|
|
3644
3592
|
setOpen(false);
|
|
3645
3593
|
setShowCustomInput(false);
|
|
@@ -3651,11 +3599,10 @@ function FontFamilyDropdown({ engine, activeFontFamily }) {
|
|
|
3651
3599
|
}
|
|
3652
3600
|
const activeOption = activeFontFamily ? (_a = FONTS.find((f) => f.value === activeFontFamily)) != null ? _a : null : null;
|
|
3653
3601
|
const triggerLabel = activeOption ? activeOption.label : activeFontFamily ? activeFontFamily.split(",")[0].replace(/['"]/g, "").trim().slice(0, 10) : "Font";
|
|
3654
|
-
return /* @__PURE__ */ jsxs(
|
|
3602
|
+
return /* @__PURE__ */ jsxs("div", { ref: containerRef, className: "relative", children: [
|
|
3655
3603
|
/* @__PURE__ */ jsxs(
|
|
3656
3604
|
"button",
|
|
3657
3605
|
{
|
|
3658
|
-
ref: buttonRef,
|
|
3659
3606
|
type: "button",
|
|
3660
3607
|
title: "Font family",
|
|
3661
3608
|
"aria-haspopup": "listbox",
|
|
@@ -3664,14 +3611,16 @@ function FontFamilyDropdown({ engine, activeFontFamily }) {
|
|
|
3664
3611
|
e.preventDefault();
|
|
3665
3612
|
if (open) {
|
|
3666
3613
|
closeDropdown();
|
|
3667
|
-
|
|
3668
|
-
openDropdown();
|
|
3614
|
+
return;
|
|
3669
3615
|
}
|
|
3616
|
+
setShowCustomInput(false);
|
|
3617
|
+
setCustomValue("");
|
|
3618
|
+
setOpen(true);
|
|
3670
3619
|
},
|
|
3671
3620
|
className: [
|
|
3672
3621
|
"flex items-center gap-0.5 px-1.5 h-8 rounded text-sm font-medium transition-colors min-w-[60px] max-w-[120px]",
|
|
3673
3622
|
"focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500",
|
|
3674
|
-
open ? "bg-gray-100
|
|
3623
|
+
open ? "bg-gray-100 text-gray-900 " : "text-gray-700 hover:bg-gray-100 "
|
|
3675
3624
|
].join(" "),
|
|
3676
3625
|
children: [
|
|
3677
3626
|
/* @__PURE__ */ jsx(FontIcon, {}),
|
|
@@ -3680,65 +3629,60 @@ function FontFamilyDropdown({ engine, activeFontFamily }) {
|
|
|
3680
3629
|
]
|
|
3681
3630
|
}
|
|
3682
3631
|
),
|
|
3683
|
-
open &&
|
|
3684
|
-
|
|
3685
|
-
|
|
3686
|
-
|
|
3687
|
-
|
|
3688
|
-
|
|
3689
|
-
|
|
3690
|
-
|
|
3691
|
-
|
|
3692
|
-
|
|
3693
|
-
|
|
3632
|
+
open && /* @__PURE__ */ jsxs(
|
|
3633
|
+
"div",
|
|
3634
|
+
{
|
|
3635
|
+
role: "listbox",
|
|
3636
|
+
"aria-label": "Font family",
|
|
3637
|
+
className: "absolute top-full left-0 mt-1 z-50 bg-white border border-gray-200 rounded-lg shadow-lg py-1 min-w-[200px]",
|
|
3638
|
+
children: [
|
|
3639
|
+
/* @__PURE__ */ jsxs(
|
|
3640
|
+
"button",
|
|
3641
|
+
{
|
|
3642
|
+
type: "button",
|
|
3643
|
+
role: "option",
|
|
3644
|
+
"aria-selected": activeFontFamily === null,
|
|
3645
|
+
onMouseDown: (e) => {
|
|
3646
|
+
e.preventDefault();
|
|
3647
|
+
applyFont(null);
|
|
3648
|
+
},
|
|
3649
|
+
className: [
|
|
3650
|
+
"w-full flex items-center justify-between px-3 py-1.5 text-sm transition-colors",
|
|
3651
|
+
activeFontFamily === null ? "bg-blue-50 text-blue-700 font-medium" : "text-gray-700 hover:bg-gray-100 "
|
|
3652
|
+
].join(" "),
|
|
3653
|
+
children: [
|
|
3654
|
+
/* @__PURE__ */ jsx("span", { children: "Default" }),
|
|
3655
|
+
activeFontFamily === null && /* @__PURE__ */ jsx(CheckIcon3, {})
|
|
3656
|
+
]
|
|
3657
|
+
}
|
|
3658
|
+
),
|
|
3659
|
+
/* @__PURE__ */ jsx("div", { className: "my-1 border-t border-gray-100 " }),
|
|
3660
|
+
FONTS.map((font) => {
|
|
3661
|
+
const isActive = activeFontFamily === font.value;
|
|
3662
|
+
return /* @__PURE__ */ jsxs(
|
|
3694
3663
|
"button",
|
|
3695
3664
|
{
|
|
3696
3665
|
type: "button",
|
|
3697
3666
|
role: "option",
|
|
3698
|
-
"aria-selected":
|
|
3667
|
+
"aria-selected": isActive,
|
|
3699
3668
|
onMouseDown: (e) => {
|
|
3700
3669
|
e.preventDefault();
|
|
3701
|
-
applyFont(
|
|
3670
|
+
applyFont(font.value);
|
|
3702
3671
|
},
|
|
3703
3672
|
className: [
|
|
3704
3673
|
"w-full flex items-center justify-between px-3 py-1.5 text-sm transition-colors",
|
|
3705
|
-
|
|
3674
|
+
isActive ? "bg-blue-50 text-blue-700 font-medium" : "text-gray-700 hover:bg-gray-100 "
|
|
3706
3675
|
].join(" "),
|
|
3707
3676
|
children: [
|
|
3708
|
-
/* @__PURE__ */ jsx("span", { children:
|
|
3709
|
-
|
|
3677
|
+
/* @__PURE__ */ jsx("span", { style: { fontFamily: font.value }, children: font.label }),
|
|
3678
|
+
isActive && /* @__PURE__ */ jsx(CheckIcon3, {})
|
|
3710
3679
|
]
|
|
3711
|
-
}
|
|
3712
|
-
|
|
3713
|
-
|
|
3714
|
-
|
|
3715
|
-
|
|
3716
|
-
|
|
3717
|
-
"button",
|
|
3718
|
-
{
|
|
3719
|
-
type: "button",
|
|
3720
|
-
role: "option",
|
|
3721
|
-
"aria-selected": isActive,
|
|
3722
|
-
onMouseDown: (e) => {
|
|
3723
|
-
e.preventDefault();
|
|
3724
|
-
applyFont(font.value);
|
|
3725
|
-
},
|
|
3726
|
-
className: [
|
|
3727
|
-
"w-full flex items-center justify-between px-3 py-1.5 text-sm transition-colors",
|
|
3728
|
-
isActive ? "bg-blue-50 dark:bg-blue-900/30 text-blue-700 dark:text-blue-300 font-medium" : "text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700"
|
|
3729
|
-
].join(" "),
|
|
3730
|
-
children: [
|
|
3731
|
-
/* @__PURE__ */ jsx("span", { style: { fontFamily: font.value }, children: font.label }),
|
|
3732
|
-
isActive && /* @__PURE__ */ jsx(CheckIcon3, {})
|
|
3733
|
-
]
|
|
3734
|
-
},
|
|
3735
|
-
font.value
|
|
3736
|
-
);
|
|
3737
|
-
})
|
|
3738
|
-
]
|
|
3739
|
-
}
|
|
3740
|
-
),
|
|
3741
|
-
document.body
|
|
3680
|
+
},
|
|
3681
|
+
font.value
|
|
3682
|
+
);
|
|
3683
|
+
})
|
|
3684
|
+
]
|
|
3685
|
+
}
|
|
3742
3686
|
)
|
|
3743
3687
|
] });
|
|
3744
3688
|
}
|
|
@@ -3784,15 +3728,11 @@ function BackgroundColorDropdown({
|
|
|
3784
3728
|
const [lastColor, setLastColor] = useState(PRESET_COLORS[6].value);
|
|
3785
3729
|
const [hexInput, setHexInput] = useState("");
|
|
3786
3730
|
const [hexError, setHexError] = useState(false);
|
|
3787
|
-
const
|
|
3788
|
-
const chevronRef = useRef(null);
|
|
3789
|
-
const popupRef = useRef(null);
|
|
3731
|
+
const containerRef = useRef(null);
|
|
3790
3732
|
useEffect(() => {
|
|
3791
3733
|
if (!open) return;
|
|
3792
3734
|
const handler = (e) => {
|
|
3793
|
-
|
|
3794
|
-
const target = e.target;
|
|
3795
|
-
if (!((_a = popupRef.current) == null ? void 0 : _a.contains(target)) && !((_b = chevronRef.current) == null ? void 0 : _b.contains(target)))
|
|
3735
|
+
if (containerRef.current && !containerRef.current.contains(e.target))
|
|
3796
3736
|
setOpen(false);
|
|
3797
3737
|
};
|
|
3798
3738
|
document.addEventListener("mousedown", handler);
|
|
@@ -3835,7 +3775,7 @@ function BackgroundColorDropdown({
|
|
|
3835
3775
|
(c) => !PRESET_COLORS.some((p) => normalizeHex(p.value) === normalizeHex(c))
|
|
3836
3776
|
);
|
|
3837
3777
|
const normActive = activeColor ? normalizeHex(activeColor) : null;
|
|
3838
|
-
return /* @__PURE__ */ jsxs("div", { className: "flex items-center", children: [
|
|
3778
|
+
return /* @__PURE__ */ jsxs("div", { ref: containerRef, className: "relative flex items-center", children: [
|
|
3839
3779
|
/* @__PURE__ */ jsxs(
|
|
3840
3780
|
"button",
|
|
3841
3781
|
{
|
|
@@ -3845,7 +3785,7 @@ function BackgroundColorDropdown({
|
|
|
3845
3785
|
e.preventDefault();
|
|
3846
3786
|
handleQuickApply();
|
|
3847
3787
|
},
|
|
3848
|
-
className: "flex flex-col items-center justify-center gap-0.5 w-8 h-8 rounded-l\n text-gray-700
|
|
3788
|
+
className: "flex flex-col items-center justify-center gap-0.5 w-8 h-8 rounded-l\r\n text-gray-700 \r\n hover:bg-gray-100 \r\n focus:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-blue-500\r\n transition-colors",
|
|
3849
3789
|
children: [
|
|
3850
3790
|
/* @__PURE__ */ jsx(BgColorIcon, {}),
|
|
3851
3791
|
/* @__PURE__ */ jsx(ColorBar, { color: normActive != null ? normActive : lastColor })
|
|
@@ -3855,145 +3795,135 @@ function BackgroundColorDropdown({
|
|
|
3855
3795
|
/* @__PURE__ */ jsx(
|
|
3856
3796
|
"button",
|
|
3857
3797
|
{
|
|
3858
|
-
ref: chevronRef,
|
|
3859
3798
|
type: "button",
|
|
3860
3799
|
title: "More background colors",
|
|
3861
3800
|
"aria-haspopup": "listbox",
|
|
3862
3801
|
"aria-expanded": open,
|
|
3863
3802
|
onMouseDown: (e) => {
|
|
3864
3803
|
e.preventDefault();
|
|
3865
|
-
|
|
3866
|
-
|
|
3867
|
-
|
|
3868
|
-
|
|
3869
|
-
|
|
3870
|
-
|
|
3871
|
-
|
|
3872
|
-
}
|
|
3873
|
-
setHexInput("");
|
|
3874
|
-
setHexError(false);
|
|
3875
|
-
setOpen(true);
|
|
3804
|
+
setOpen((p) => {
|
|
3805
|
+
if (!p) {
|
|
3806
|
+
setHexInput("");
|
|
3807
|
+
setHexError(false);
|
|
3808
|
+
}
|
|
3809
|
+
return !p;
|
|
3810
|
+
});
|
|
3876
3811
|
},
|
|
3877
3812
|
className: [
|
|
3878
|
-
"flex items-center justify-center w-4 h-8 rounded-r border-l border-gray-200
|
|
3813
|
+
"flex items-center justify-center w-4 h-8 rounded-r border-l border-gray-200 ",
|
|
3879
3814
|
"focus:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-blue-500",
|
|
3880
3815
|
"transition-colors",
|
|
3881
|
-
open ? "bg-gray-100
|
|
3816
|
+
open ? "bg-gray-100 text-gray-700 " : "text-gray-400 hover:bg-gray-100 "
|
|
3882
3817
|
].join(" "),
|
|
3883
3818
|
children: /* @__PURE__ */ jsx(ChevronDownIcon4, {})
|
|
3884
3819
|
}
|
|
3885
3820
|
),
|
|
3886
|
-
open &&
|
|
3887
|
-
|
|
3888
|
-
|
|
3889
|
-
|
|
3890
|
-
|
|
3891
|
-
|
|
3892
|
-
|
|
3893
|
-
|
|
3894
|
-
|
|
3895
|
-
|
|
3821
|
+
open && /* @__PURE__ */ jsxs(
|
|
3822
|
+
"div",
|
|
3823
|
+
{
|
|
3824
|
+
role: "dialog",
|
|
3825
|
+
"aria-label": "Background color",
|
|
3826
|
+
className: "absolute top-full left-0 mt-1 z-50\r\n bg-white \r\n border border-gray-200 \r\n rounded-lg shadow-xl\r\n p-3 w-[208px]",
|
|
3827
|
+
children: [
|
|
3828
|
+
/* @__PURE__ */ jsxs(
|
|
3829
|
+
"button",
|
|
3830
|
+
{
|
|
3831
|
+
type: "button",
|
|
3832
|
+
onMouseDown: (e) => {
|
|
3833
|
+
e.preventDefault();
|
|
3834
|
+
applyColor(null);
|
|
3835
|
+
},
|
|
3836
|
+
className: "flex items-center gap-2 w-full px-2 py-1.5 mb-2.5 text-xs font-medium\r\n text-gray-600 \r\n rounded hover:bg-gray-100 \r\n transition-colors",
|
|
3837
|
+
children: [
|
|
3838
|
+
/* @__PURE__ */ jsx(RemoveColorIcon, {}),
|
|
3839
|
+
"Remove background"
|
|
3840
|
+
]
|
|
3841
|
+
}
|
|
3842
|
+
),
|
|
3843
|
+
/* @__PURE__ */ jsx("div", { className: "h-px bg-gray-100 mb-2.5" }),
|
|
3844
|
+
extraDocColors.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3845
|
+
/* @__PURE__ */ jsx("p", { className: "text-[10px] font-semibold uppercase tracking-widest text-gray-400 mb-1.5 px-0.5", children: "Document colors" }),
|
|
3846
|
+
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-5 gap-1 mb-2.5", children: extraDocColors.slice(0, 10).map((c) => /* @__PURE__ */ jsx(
|
|
3847
|
+
Swatch,
|
|
3848
|
+
{
|
|
3849
|
+
color: { label: c, value: c },
|
|
3850
|
+
isActive: normActive === normalizeHex(c),
|
|
3851
|
+
onSelect: applyColor
|
|
3852
|
+
},
|
|
3853
|
+
c
|
|
3854
|
+
)) }),
|
|
3855
|
+
/* @__PURE__ */ jsx("div", { className: "h-px bg-gray-100 mb-2.5" })
|
|
3856
|
+
] }),
|
|
3857
|
+
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-5 gap-1 mb-3", children: PRESET_COLORS.map((c) => /* @__PURE__ */ jsx(
|
|
3858
|
+
Swatch,
|
|
3859
|
+
{
|
|
3860
|
+
color: c,
|
|
3861
|
+
isActive: normActive === normalizeHex(c.value),
|
|
3862
|
+
onSelect: applyColor
|
|
3863
|
+
},
|
|
3864
|
+
c.value
|
|
3865
|
+
)) }),
|
|
3866
|
+
/* @__PURE__ */ jsx("div", { className: "h-px bg-gray-100 mb-2.5" }),
|
|
3867
|
+
/* @__PURE__ */ jsx("p", { className: "text-[10px] font-semibold uppercase tracking-widest text-gray-400 mb-1.5 px-0.5", children: "Custom color" }),
|
|
3868
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
3869
|
+
/* @__PURE__ */ jsx(
|
|
3870
|
+
"div",
|
|
3871
|
+
{
|
|
3872
|
+
className: "shrink-0 w-7 h-7 rounded border border-gray-300 ",
|
|
3873
|
+
style: { backgroundColor: hexInputToPreview(hexInput) }
|
|
3874
|
+
}
|
|
3875
|
+
),
|
|
3896
3876
|
/* @__PURE__ */ jsxs(
|
|
3877
|
+
"div",
|
|
3878
|
+
{
|
|
3879
|
+
className: "flex flex-1 items-center border rounded overflow-hidden\r\n border-gray-300 \r\n focus-within:ring-2 focus-within:ring-blue-500",
|
|
3880
|
+
children: [
|
|
3881
|
+
/* @__PURE__ */ jsx("span", { className: "pl-2 text-xs text-gray-400 select-none", children: "#" }),
|
|
3882
|
+
/* @__PURE__ */ jsx(
|
|
3883
|
+
"input",
|
|
3884
|
+
{
|
|
3885
|
+
type: "text",
|
|
3886
|
+
maxLength: 6,
|
|
3887
|
+
value: hexInput,
|
|
3888
|
+
onChange: (e) => {
|
|
3889
|
+
setHexInput(e.target.value.replace(/[^0-9a-fA-F]/g, ""));
|
|
3890
|
+
setHexError(false);
|
|
3891
|
+
},
|
|
3892
|
+
onKeyDown: (e) => {
|
|
3893
|
+
if (e.key === "Enter") {
|
|
3894
|
+
e.preventDefault();
|
|
3895
|
+
commitHexInput();
|
|
3896
|
+
}
|
|
3897
|
+
if (e.key === "Escape") setOpen(false);
|
|
3898
|
+
},
|
|
3899
|
+
placeholder: "e.g. ffff00",
|
|
3900
|
+
className: [
|
|
3901
|
+
"flex-1 px-1 py-1.5 text-xs bg-transparent outline-none font-mono",
|
|
3902
|
+
"text-gray-900 ",
|
|
3903
|
+
hexError ? "text-red-500" : ""
|
|
3904
|
+
].join(" "),
|
|
3905
|
+
"aria-label": "Hex colour value"
|
|
3906
|
+
}
|
|
3907
|
+
)
|
|
3908
|
+
]
|
|
3909
|
+
}
|
|
3910
|
+
),
|
|
3911
|
+
/* @__PURE__ */ jsx(
|
|
3897
3912
|
"button",
|
|
3898
3913
|
{
|
|
3899
3914
|
type: "button",
|
|
3900
3915
|
onMouseDown: (e) => {
|
|
3901
3916
|
e.preventDefault();
|
|
3902
|
-
|
|
3917
|
+
commitHexInput();
|
|
3903
3918
|
},
|
|
3904
|
-
className: "
|
|
3905
|
-
children:
|
|
3906
|
-
/* @__PURE__ */ jsx(RemoveColorIcon, {}),
|
|
3907
|
-
"Remove background"
|
|
3908
|
-
]
|
|
3919
|
+
className: "shrink-0 px-2 py-1.5 text-xs bg-blue-600 text-white rounded\r\n hover:bg-blue-700 transition-colors",
|
|
3920
|
+
children: "\u2713"
|
|
3909
3921
|
}
|
|
3910
|
-
)
|
|
3911
|
-
|
|
3912
|
-
|
|
3913
|
-
|
|
3914
|
-
|
|
3915
|
-
Swatch,
|
|
3916
|
-
{
|
|
3917
|
-
color: { label: c, value: c },
|
|
3918
|
-
isActive: normActive === normalizeHex(c),
|
|
3919
|
-
onSelect: applyColor
|
|
3920
|
-
},
|
|
3921
|
-
c
|
|
3922
|
-
)) }),
|
|
3923
|
-
/* @__PURE__ */ jsx("div", { className: "h-px bg-gray-100 dark:bg-gray-700 mb-2.5" })
|
|
3924
|
-
] }),
|
|
3925
|
-
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-5 gap-1 mb-3", children: PRESET_COLORS.map((c) => /* @__PURE__ */ jsx(
|
|
3926
|
-
Swatch,
|
|
3927
|
-
{
|
|
3928
|
-
color: c,
|
|
3929
|
-
isActive: normActive === normalizeHex(c.value),
|
|
3930
|
-
onSelect: applyColor
|
|
3931
|
-
},
|
|
3932
|
-
c.value
|
|
3933
|
-
)) }),
|
|
3934
|
-
/* @__PURE__ */ jsx("div", { className: "h-px bg-gray-100 dark:bg-gray-700 mb-2.5" }),
|
|
3935
|
-
/* @__PURE__ */ jsx("p", { className: "text-[10px] font-semibold uppercase tracking-widest text-gray-400 dark:text-gray-500 mb-1.5 px-0.5", children: "Custom color" }),
|
|
3936
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
3937
|
-
/* @__PURE__ */ jsx(
|
|
3938
|
-
"div",
|
|
3939
|
-
{
|
|
3940
|
-
className: "shrink-0 w-7 h-7 rounded border border-gray-300 dark:border-gray-600",
|
|
3941
|
-
style: { backgroundColor: hexInputToPreview(hexInput) }
|
|
3942
|
-
}
|
|
3943
|
-
),
|
|
3944
|
-
/* @__PURE__ */ jsxs(
|
|
3945
|
-
"div",
|
|
3946
|
-
{
|
|
3947
|
-
className: "flex flex-1 items-center border rounded overflow-hidden\n border-gray-300 dark:border-gray-600\n focus-within:ring-2 focus-within:ring-blue-500",
|
|
3948
|
-
children: [
|
|
3949
|
-
/* @__PURE__ */ jsx("span", { className: "pl-2 text-xs text-gray-400 select-none", children: "#" }),
|
|
3950
|
-
/* @__PURE__ */ jsx(
|
|
3951
|
-
"input",
|
|
3952
|
-
{
|
|
3953
|
-
type: "text",
|
|
3954
|
-
maxLength: 6,
|
|
3955
|
-
value: hexInput,
|
|
3956
|
-
onChange: (e) => {
|
|
3957
|
-
setHexInput(e.target.value.replace(/[^0-9a-fA-F]/g, ""));
|
|
3958
|
-
setHexError(false);
|
|
3959
|
-
},
|
|
3960
|
-
onKeyDown: (e) => {
|
|
3961
|
-
if (e.key === "Enter") {
|
|
3962
|
-
e.preventDefault();
|
|
3963
|
-
commitHexInput();
|
|
3964
|
-
}
|
|
3965
|
-
if (e.key === "Escape") setOpen(false);
|
|
3966
|
-
},
|
|
3967
|
-
placeholder: "e.g. ffff00",
|
|
3968
|
-
className: [
|
|
3969
|
-
"flex-1 px-1 py-1.5 text-xs bg-transparent outline-none font-mono",
|
|
3970
|
-
"text-gray-900 dark:text-gray-100",
|
|
3971
|
-
hexError ? "text-red-500" : ""
|
|
3972
|
-
].join(" "),
|
|
3973
|
-
"aria-label": "Hex colour value"
|
|
3974
|
-
}
|
|
3975
|
-
)
|
|
3976
|
-
]
|
|
3977
|
-
}
|
|
3978
|
-
),
|
|
3979
|
-
/* @__PURE__ */ jsx(
|
|
3980
|
-
"button",
|
|
3981
|
-
{
|
|
3982
|
-
type: "button",
|
|
3983
|
-
onMouseDown: (e) => {
|
|
3984
|
-
e.preventDefault();
|
|
3985
|
-
commitHexInput();
|
|
3986
|
-
},
|
|
3987
|
-
className: "shrink-0 px-2 py-1.5 text-xs bg-blue-600 text-white rounded\n hover:bg-blue-700 transition-colors",
|
|
3988
|
-
children: "\u2713"
|
|
3989
|
-
}
|
|
3990
|
-
)
|
|
3991
|
-
] }),
|
|
3992
|
-
hexError && /* @__PURE__ */ jsx("p", { className: "text-[10px] text-red-500 mt-1 px-0.5", children: "Invalid hex colour" })
|
|
3993
|
-
]
|
|
3994
|
-
}
|
|
3995
|
-
),
|
|
3996
|
-
document.body
|
|
3922
|
+
)
|
|
3923
|
+
] }),
|
|
3924
|
+
hexError && /* @__PURE__ */ jsx("p", { className: "text-[10px] text-red-500 mt-1 px-0.5", children: "Invalid hex colour" })
|
|
3925
|
+
]
|
|
3926
|
+
}
|
|
3997
3927
|
)
|
|
3998
3928
|
] });
|
|
3999
3929
|
}
|
|
@@ -4018,7 +3948,7 @@ function Swatch({
|
|
|
4018
3948
|
"hover:scale-110 focus:outline-none",
|
|
4019
3949
|
"focus-visible:ring-2 focus-visible:ring-offset-1 focus-visible:ring-blue-500",
|
|
4020
3950
|
isActive ? "ring-2 ring-offset-1 ring-blue-500 scale-105" : "",
|
|
4021
|
-
color.hasBorder ? "border border-gray-300
|
|
3951
|
+
color.hasBorder ? "border border-gray-300 " : ""
|
|
4022
3952
|
].join(" "),
|
|
4023
3953
|
style: { backgroundColor: color.value },
|
|
4024
3954
|
children: isActive && /* @__PURE__ */ jsx(CheckIcon4, { light: isLight(color.value) })
|
|
@@ -4141,15 +4071,11 @@ function TextColorDropdown({
|
|
|
4141
4071
|
const [lastColor, setLastColor] = useState(PRESET_COLORS2[0].value);
|
|
4142
4072
|
const [hexInput, setHexInput] = useState("");
|
|
4143
4073
|
const [hexError, setHexError] = useState(false);
|
|
4144
|
-
const
|
|
4145
|
-
const chevronRef = useRef(null);
|
|
4146
|
-
const popupRef = useRef(null);
|
|
4074
|
+
const containerRef = useRef(null);
|
|
4147
4075
|
useEffect(() => {
|
|
4148
4076
|
if (!open) return;
|
|
4149
4077
|
const handler = (e) => {
|
|
4150
|
-
|
|
4151
|
-
const target = e.target;
|
|
4152
|
-
if (!((_a = popupRef.current) == null ? void 0 : _a.contains(target)) && !((_b = chevronRef.current) == null ? void 0 : _b.contains(target)))
|
|
4078
|
+
if (containerRef.current && !containerRef.current.contains(e.target))
|
|
4153
4079
|
setOpen(false);
|
|
4154
4080
|
};
|
|
4155
4081
|
document.addEventListener("mousedown", handler);
|
|
@@ -4189,7 +4115,7 @@ function TextColorDropdown({
|
|
|
4189
4115
|
(c) => !PRESET_COLORS2.some((p) => normalizeHex2(p.value) === normalizeHex2(c))
|
|
4190
4116
|
);
|
|
4191
4117
|
const normActive = activeColor ? normalizeHex2(activeColor) : null;
|
|
4192
|
-
return /* @__PURE__ */ jsxs("div", { className: "flex items-center", children: [
|
|
4118
|
+
return /* @__PURE__ */ jsxs("div", { ref: containerRef, className: "relative flex items-center", children: [
|
|
4193
4119
|
/* @__PURE__ */ jsxs(
|
|
4194
4120
|
"button",
|
|
4195
4121
|
{
|
|
@@ -4199,7 +4125,7 @@ function TextColorDropdown({
|
|
|
4199
4125
|
e.preventDefault();
|
|
4200
4126
|
handleQuickApply();
|
|
4201
4127
|
},
|
|
4202
|
-
className: "flex flex-col items-center justify-center gap-0.5 w-8 h-8 rounded-l\n text-gray-700
|
|
4128
|
+
className: "flex flex-col items-center justify-center gap-0.5 w-8 h-8 rounded-l\r\n text-gray-700 \r\n hover:bg-gray-100 \r\n focus:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-blue-500\r\n transition-colors",
|
|
4203
4129
|
children: [
|
|
4204
4130
|
/* @__PURE__ */ jsx(TextColorIcon, {}),
|
|
4205
4131
|
/* @__PURE__ */ jsx(
|
|
@@ -4215,139 +4141,129 @@ function TextColorDropdown({
|
|
|
4215
4141
|
/* @__PURE__ */ jsx(
|
|
4216
4142
|
"button",
|
|
4217
4143
|
{
|
|
4218
|
-
ref: chevronRef,
|
|
4219
4144
|
type: "button",
|
|
4220
4145
|
title: "More text colors",
|
|
4221
4146
|
"aria-haspopup": "listbox",
|
|
4222
4147
|
"aria-expanded": open,
|
|
4223
4148
|
onMouseDown: (e) => {
|
|
4224
4149
|
e.preventDefault();
|
|
4225
|
-
|
|
4226
|
-
|
|
4227
|
-
|
|
4228
|
-
|
|
4229
|
-
|
|
4230
|
-
|
|
4231
|
-
|
|
4232
|
-
}
|
|
4233
|
-
setHexInput("");
|
|
4234
|
-
setHexError(false);
|
|
4235
|
-
setOpen(true);
|
|
4150
|
+
setOpen((p) => {
|
|
4151
|
+
if (!p) {
|
|
4152
|
+
setHexInput("");
|
|
4153
|
+
setHexError(false);
|
|
4154
|
+
}
|
|
4155
|
+
return !p;
|
|
4156
|
+
});
|
|
4236
4157
|
},
|
|
4237
4158
|
className: [
|
|
4238
|
-
"flex items-center justify-center w-4 h-8 rounded-r border-l border-gray-200
|
|
4159
|
+
"flex items-center justify-center w-4 h-8 rounded-r border-l border-gray-200 ",
|
|
4239
4160
|
"focus:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-blue-500",
|
|
4240
4161
|
"transition-colors",
|
|
4241
|
-
open ? "bg-gray-100
|
|
4162
|
+
open ? "bg-gray-100 text-gray-700 " : "text-gray-400 hover:bg-gray-100 "
|
|
4242
4163
|
].join(" "),
|
|
4243
4164
|
children: /* @__PURE__ */ jsx(ChevronDownIcon5, {})
|
|
4244
4165
|
}
|
|
4245
4166
|
),
|
|
4246
|
-
open &&
|
|
4247
|
-
|
|
4248
|
-
|
|
4249
|
-
|
|
4250
|
-
|
|
4251
|
-
|
|
4252
|
-
|
|
4253
|
-
|
|
4254
|
-
|
|
4255
|
-
|
|
4256
|
-
|
|
4257
|
-
|
|
4258
|
-
|
|
4259
|
-
|
|
4260
|
-
|
|
4261
|
-
|
|
4262
|
-
|
|
4263
|
-
},
|
|
4264
|
-
|
|
4265
|
-
|
|
4266
|
-
|
|
4267
|
-
|
|
4268
|
-
|
|
4269
|
-
|
|
4270
|
-
),
|
|
4271
|
-
/* @__PURE__ */ jsx("div", { className: "
|
|
4272
|
-
extraDocColors.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4273
|
-
/* @__PURE__ */ jsx("p", { className: "text-[10px] font-semibold uppercase tracking-widest text-gray-400 dark:text-gray-500 mb-1.5 px-0.5", children: "Document colors" }),
|
|
4274
|
-
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-5 gap-1 mb-2.5", children: extraDocColors.slice(0, 10).map((c) => /* @__PURE__ */ jsx(
|
|
4275
|
-
Swatch2,
|
|
4276
|
-
{
|
|
4277
|
-
color: { label: c, value: c },
|
|
4278
|
-
isActive: normActive === normalizeHex2(c),
|
|
4279
|
-
onSelect: applyColor
|
|
4280
|
-
},
|
|
4281
|
-
c
|
|
4282
|
-
)) }),
|
|
4283
|
-
/* @__PURE__ */ jsx("div", { className: "h-px bg-gray-100 dark:bg-gray-700 mb-2.5" })
|
|
4284
|
-
] }),
|
|
4285
|
-
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-5 gap-1 mb-3", children: PRESET_COLORS2.map((c) => /* @__PURE__ */ jsx(
|
|
4167
|
+
open && /* @__PURE__ */ jsxs(
|
|
4168
|
+
"div",
|
|
4169
|
+
{
|
|
4170
|
+
role: "dialog",
|
|
4171
|
+
"aria-label": "Text color",
|
|
4172
|
+
className: "absolute top-full left-0 mt-1 z-50\r\n bg-white \r\n border border-gray-200 \r\n rounded-lg shadow-xl\r\n p-3 w-[208px]",
|
|
4173
|
+
children: [
|
|
4174
|
+
/* @__PURE__ */ jsxs(
|
|
4175
|
+
"button",
|
|
4176
|
+
{
|
|
4177
|
+
type: "button",
|
|
4178
|
+
onMouseDown: (e) => {
|
|
4179
|
+
e.preventDefault();
|
|
4180
|
+
applyColor(null);
|
|
4181
|
+
},
|
|
4182
|
+
className: "flex items-center gap-2 w-full px-2 py-1.5 mb-2.5 text-xs font-medium\r\n text-gray-600 \r\n rounded hover:bg-gray-100 \r\n transition-colors",
|
|
4183
|
+
children: [
|
|
4184
|
+
/* @__PURE__ */ jsx(RemoveColorIcon2, {}),
|
|
4185
|
+
"Remove color"
|
|
4186
|
+
]
|
|
4187
|
+
}
|
|
4188
|
+
),
|
|
4189
|
+
/* @__PURE__ */ jsx("div", { className: "h-px bg-gray-100 mb-2.5" }),
|
|
4190
|
+
extraDocColors.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4191
|
+
/* @__PURE__ */ jsx("p", { className: "text-[10px] font-semibold uppercase tracking-widest text-gray-400 mb-1.5 px-0.5", children: "Document colors" }),
|
|
4192
|
+
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-5 gap-1 mb-2.5", children: extraDocColors.slice(0, 10).map((c) => /* @__PURE__ */ jsx(
|
|
4286
4193
|
Swatch2,
|
|
4287
4194
|
{
|
|
4288
|
-
color: c,
|
|
4289
|
-
isActive: normActive === normalizeHex2(c
|
|
4195
|
+
color: { label: c, value: c },
|
|
4196
|
+
isActive: normActive === normalizeHex2(c),
|
|
4290
4197
|
onSelect: applyColor
|
|
4291
4198
|
},
|
|
4292
|
-
c
|
|
4199
|
+
c
|
|
4293
4200
|
)) }),
|
|
4294
|
-
/* @__PURE__ */ jsx("div", { className: "h-px bg-gray-100
|
|
4295
|
-
|
|
4296
|
-
|
|
4297
|
-
|
|
4298
|
-
|
|
4299
|
-
|
|
4300
|
-
|
|
4301
|
-
|
|
4302
|
-
|
|
4303
|
-
|
|
4304
|
-
|
|
4305
|
-
|
|
4306
|
-
|
|
4307
|
-
|
|
4308
|
-
|
|
4309
|
-
|
|
4310
|
-
|
|
4311
|
-
|
|
4312
|
-
|
|
4313
|
-
|
|
4314
|
-
|
|
4315
|
-
|
|
4316
|
-
|
|
4317
|
-
if (e.key === "Enter") {
|
|
4318
|
-
e.preventDefault();
|
|
4319
|
-
commitHexInput();
|
|
4320
|
-
}
|
|
4321
|
-
if (e.key === "Escape") setOpen(false);
|
|
4322
|
-
},
|
|
4323
|
-
placeholder: "e.g. 000000",
|
|
4324
|
-
className: [
|
|
4325
|
-
"flex-1 px-1 py-1.5 text-xs bg-transparent outline-none font-mono",
|
|
4326
|
-
"text-gray-900 dark:text-gray-100",
|
|
4327
|
-
hexError ? "text-red-500" : ""
|
|
4328
|
-
].join(" "),
|
|
4329
|
-
"aria-label": "Hex colour value"
|
|
4330
|
-
}
|
|
4331
|
-
)
|
|
4332
|
-
] }),
|
|
4201
|
+
/* @__PURE__ */ jsx("div", { className: "h-px bg-gray-100 mb-2.5" })
|
|
4202
|
+
] }),
|
|
4203
|
+
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-5 gap-1 mb-3", children: PRESET_COLORS2.map((c) => /* @__PURE__ */ jsx(
|
|
4204
|
+
Swatch2,
|
|
4205
|
+
{
|
|
4206
|
+
color: c,
|
|
4207
|
+
isActive: normActive === normalizeHex2(c.value),
|
|
4208
|
+
onSelect: applyColor
|
|
4209
|
+
},
|
|
4210
|
+
c.value
|
|
4211
|
+
)) }),
|
|
4212
|
+
/* @__PURE__ */ jsx("div", { className: "h-px bg-gray-100 mb-2.5" }),
|
|
4213
|
+
/* @__PURE__ */ jsx("p", { className: "text-[10px] font-semibold uppercase tracking-widest text-gray-400 mb-1.5 px-0.5", children: "Custom color" }),
|
|
4214
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
4215
|
+
/* @__PURE__ */ jsx(
|
|
4216
|
+
"div",
|
|
4217
|
+
{
|
|
4218
|
+
className: "shrink-0 w-7 h-7 rounded border border-gray-300 ",
|
|
4219
|
+
style: { backgroundColor: hexInputToPreview2(hexInput) }
|
|
4220
|
+
}
|
|
4221
|
+
),
|
|
4222
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-1 items-center border rounded overflow-hidden\r\n border-gray-300 \r\n focus-within:ring-2 focus-within:ring-blue-500", children: [
|
|
4223
|
+
/* @__PURE__ */ jsx("span", { className: "pl-2 text-xs text-gray-400 select-none", children: "#" }),
|
|
4333
4224
|
/* @__PURE__ */ jsx(
|
|
4334
|
-
"
|
|
4225
|
+
"input",
|
|
4335
4226
|
{
|
|
4336
|
-
type: "
|
|
4337
|
-
|
|
4338
|
-
|
|
4339
|
-
|
|
4227
|
+
type: "text",
|
|
4228
|
+
maxLength: 6,
|
|
4229
|
+
value: hexInput,
|
|
4230
|
+
onChange: (e) => {
|
|
4231
|
+
setHexInput(e.target.value.replace(/[^0-9a-fA-F]/g, ""));
|
|
4232
|
+
setHexError(false);
|
|
4340
4233
|
},
|
|
4341
|
-
|
|
4342
|
-
|
|
4234
|
+
onKeyDown: (e) => {
|
|
4235
|
+
if (e.key === "Enter") {
|
|
4236
|
+
e.preventDefault();
|
|
4237
|
+
commitHexInput();
|
|
4238
|
+
}
|
|
4239
|
+
if (e.key === "Escape") setOpen(false);
|
|
4240
|
+
},
|
|
4241
|
+
placeholder: "e.g. 000000",
|
|
4242
|
+
className: [
|
|
4243
|
+
"flex-1 px-1 py-1.5 text-xs bg-transparent outline-none font-mono",
|
|
4244
|
+
"text-gray-900 ",
|
|
4245
|
+
hexError ? "text-red-500" : ""
|
|
4246
|
+
].join(" "),
|
|
4247
|
+
"aria-label": "Hex colour value"
|
|
4343
4248
|
}
|
|
4344
4249
|
)
|
|
4345
4250
|
] }),
|
|
4346
|
-
|
|
4347
|
-
|
|
4348
|
-
|
|
4349
|
-
|
|
4350
|
-
|
|
4251
|
+
/* @__PURE__ */ jsx(
|
|
4252
|
+
"button",
|
|
4253
|
+
{
|
|
4254
|
+
type: "button",
|
|
4255
|
+
onMouseDown: (e) => {
|
|
4256
|
+
e.preventDefault();
|
|
4257
|
+
commitHexInput();
|
|
4258
|
+
},
|
|
4259
|
+
className: "shrink-0 px-2 py-1.5 text-xs bg-blue-600 text-white rounded\r\n hover:bg-blue-700 transition-colors",
|
|
4260
|
+
children: "\u2713"
|
|
4261
|
+
}
|
|
4262
|
+
)
|
|
4263
|
+
] }),
|
|
4264
|
+
hexError && /* @__PURE__ */ jsx("p", { className: "text-[10px] text-red-500 mt-1 px-0.5", children: "Invalid hex colour" })
|
|
4265
|
+
]
|
|
4266
|
+
}
|
|
4351
4267
|
)
|
|
4352
4268
|
] });
|
|
4353
4269
|
}
|
|
@@ -4372,7 +4288,7 @@ function Swatch2({
|
|
|
4372
4288
|
"hover:scale-110 focus:outline-none",
|
|
4373
4289
|
"focus-visible:ring-2 focus-visible:ring-offset-1 focus-visible:ring-blue-500",
|
|
4374
4290
|
isActive ? "ring-2 ring-offset-1 ring-blue-500 scale-105" : "",
|
|
4375
|
-
color.hasBorder ? "border border-gray-300
|
|
4291
|
+
color.hasBorder ? "border border-gray-300 " : ""
|
|
4376
4292
|
].join(" "),
|
|
4377
4293
|
style: { backgroundColor: color.value },
|
|
4378
4294
|
children: isActive && /* @__PURE__ */ jsx(CheckIcon5, { light: isLight2(color.value) })
|
|
@@ -5904,9 +5820,7 @@ function CodeBlockButton({ engine }) {
|
|
|
5904
5820
|
const activeBlock = getActiveBlockType(state.doc, state.selection);
|
|
5905
5821
|
const isActive = activeBlock === "code_block";
|
|
5906
5822
|
const [open, setOpen] = useState(false);
|
|
5907
|
-
const
|
|
5908
|
-
const chevronRef = useRef(null);
|
|
5909
|
-
const popupRef = useRef(null);
|
|
5823
|
+
const containerRef = useRef(null);
|
|
5910
5824
|
const currentLang = (() => {
|
|
5911
5825
|
var _a2;
|
|
5912
5826
|
if (!isActive || !state.selection) return "plaintext";
|
|
@@ -5919,9 +5833,9 @@ function CodeBlockButton({ engine }) {
|
|
|
5919
5833
|
useEffect(() => {
|
|
5920
5834
|
if (!open) return;
|
|
5921
5835
|
const handler = (e) => {
|
|
5922
|
-
|
|
5923
|
-
|
|
5924
|
-
|
|
5836
|
+
if (containerRef.current && !containerRef.current.contains(e.target)) {
|
|
5837
|
+
closeDropdown();
|
|
5838
|
+
}
|
|
5925
5839
|
};
|
|
5926
5840
|
document.addEventListener("mousedown", handler);
|
|
5927
5841
|
return () => document.removeEventListener("mousedown", handler);
|
|
@@ -5948,7 +5862,7 @@ function CodeBlockButton({ engine }) {
|
|
|
5948
5862
|
setOpen(false);
|
|
5949
5863
|
};
|
|
5950
5864
|
const activeLang = LANGUAGES.find((l) => l.value === currentLang);
|
|
5951
|
-
return /* @__PURE__ */ jsxs("div", { className: "flex items-center", children: [
|
|
5865
|
+
return /* @__PURE__ */ jsxs("div", { ref: containerRef, className: "relative flex items-center", children: [
|
|
5952
5866
|
/* @__PURE__ */ jsx(
|
|
5953
5867
|
"button",
|
|
5954
5868
|
{
|
|
@@ -5960,7 +5874,7 @@ function CodeBlockButton({ engine }) {
|
|
|
5960
5874
|
},
|
|
5961
5875
|
className: [
|
|
5962
5876
|
"flex items-center justify-center w-8 h-8 rounded-l text-sm transition-colors",
|
|
5963
|
-
isActive ? "bg-blue-100
|
|
5877
|
+
isActive ? "bg-blue-100 text-blue-700 " : "text-gray-700 hover:bg-gray-100 "
|
|
5964
5878
|
].join(" "),
|
|
5965
5879
|
children: /* @__PURE__ */ jsx(CodeBlockIcon, {})
|
|
5966
5880
|
}
|
|
@@ -5968,69 +5882,55 @@ function CodeBlockButton({ engine }) {
|
|
|
5968
5882
|
/* @__PURE__ */ jsx(
|
|
5969
5883
|
"button",
|
|
5970
5884
|
{
|
|
5971
|
-
ref: chevronRef,
|
|
5972
5885
|
type: "button",
|
|
5973
5886
|
title: isActive ? `Language: ${(_a = activeLang == null ? void 0 : activeLang.label) != null ? _a : "Plain text"}` : "Select language",
|
|
5974
5887
|
"aria-haspopup": "listbox",
|
|
5975
5888
|
"aria-expanded": open,
|
|
5976
5889
|
onMouseDown: (e) => {
|
|
5977
5890
|
e.preventDefault();
|
|
5978
|
-
|
|
5979
|
-
closeDropdown();
|
|
5980
|
-
return;
|
|
5981
|
-
}
|
|
5982
|
-
if (chevronRef.current) {
|
|
5983
|
-
const rect = chevronRef.current.getBoundingClientRect();
|
|
5984
|
-
setPopupPos({ top: rect.bottom + 4, left: rect.left - 160 });
|
|
5985
|
-
}
|
|
5986
|
-
setOpen(true);
|
|
5891
|
+
setOpen((p) => !p);
|
|
5987
5892
|
},
|
|
5988
5893
|
className: [
|
|
5989
|
-
"flex items-center justify-center w-4 h-8 rounded-r border-l border-gray-200
|
|
5990
|
-
open ? "bg-gray-100
|
|
5894
|
+
"flex items-center justify-center w-4 h-8 rounded-r border-l border-gray-200 transition-colors",
|
|
5895
|
+
open ? "bg-gray-100 text-gray-700 " : "text-gray-400 hover:bg-gray-100 "
|
|
5991
5896
|
].join(" "),
|
|
5992
5897
|
children: /* @__PURE__ */ jsx(ChevronIcon, {})
|
|
5993
5898
|
}
|
|
5994
5899
|
),
|
|
5995
|
-
open &&
|
|
5996
|
-
|
|
5997
|
-
|
|
5998
|
-
|
|
5999
|
-
|
|
6000
|
-
|
|
6001
|
-
|
|
6002
|
-
|
|
6003
|
-
|
|
6004
|
-
|
|
6005
|
-
/* @__PURE__ */
|
|
6006
|
-
|
|
6007
|
-
|
|
6008
|
-
|
|
6009
|
-
"
|
|
6010
|
-
|
|
6011
|
-
|
|
6012
|
-
|
|
6013
|
-
|
|
6014
|
-
onMouseDown: (e) => {
|
|
6015
|
-
e.preventDefault();
|
|
6016
|
-
handleSelectLanguage(lang.value);
|
|
6017
|
-
},
|
|
6018
|
-
className: [
|
|
6019
|
-
"w-full text-left px-3 py-1.5 text-sm flex items-center gap-2 transition-colors",
|
|
6020
|
-
isSelected ? "bg-blue-50 dark:bg-blue-900/30 text-blue-700 dark:text-blue-300 font-medium" : "text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700"
|
|
6021
|
-
].join(" "),
|
|
6022
|
-
children: [
|
|
6023
|
-
isSelected && /* @__PURE__ */ jsx("svg", { className: "w-3 h-3 shrink-0", viewBox: "0 0 12 12", fill: "currentColor", children: /* @__PURE__ */ jsx("polyline", { points: "1 6 4.5 9.5 11 2.5", fill: "none", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round" }) }),
|
|
6024
|
-
/* @__PURE__ */ jsx("span", { className: isSelected ? "" : "ml-5", children: lang.label })
|
|
6025
|
-
]
|
|
5900
|
+
open && /* @__PURE__ */ jsxs(
|
|
5901
|
+
"div",
|
|
5902
|
+
{
|
|
5903
|
+
role: "listbox",
|
|
5904
|
+
"aria-label": "Code block language",
|
|
5905
|
+
className: "absolute top-full left-0 mt-1 z-50 bg-white border border-gray-200 rounded-lg shadow-xl py-1 w-44 max-h-72 overflow-y-auto",
|
|
5906
|
+
children: [
|
|
5907
|
+
/* @__PURE__ */ jsx("p", { className: "px-3 py-1.5 text-[10px] font-semibold uppercase tracking-widest text-gray-400 ", children: "Language" }),
|
|
5908
|
+
LANGUAGES.map((lang) => {
|
|
5909
|
+
const isSelected = isActive && currentLang === lang.value;
|
|
5910
|
+
return /* @__PURE__ */ jsxs(
|
|
5911
|
+
"button",
|
|
5912
|
+
{
|
|
5913
|
+
type: "button",
|
|
5914
|
+
role: "option",
|
|
5915
|
+
"aria-selected": isSelected,
|
|
5916
|
+
onMouseDown: (e) => {
|
|
5917
|
+
e.preventDefault();
|
|
5918
|
+
handleSelectLanguage(lang.value);
|
|
6026
5919
|
},
|
|
6027
|
-
|
|
6028
|
-
|
|
6029
|
-
|
|
6030
|
-
|
|
6031
|
-
|
|
6032
|
-
|
|
6033
|
-
|
|
5920
|
+
className: [
|
|
5921
|
+
"w-full text-left px-3 py-1.5 text-sm flex items-center gap-2 transition-colors",
|
|
5922
|
+
isSelected ? "bg-blue-50 text-blue-700 font-medium" : "text-gray-700 hover:bg-gray-100 "
|
|
5923
|
+
].join(" "),
|
|
5924
|
+
children: [
|
|
5925
|
+
isSelected && /* @__PURE__ */ jsx("svg", { className: "w-3 h-3 shrink-0", viewBox: "0 0 12 12", fill: "currentColor", children: /* @__PURE__ */ jsx("polyline", { points: "1 6 4.5 9.5 11 2.5", fill: "none", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round" }) }),
|
|
5926
|
+
/* @__PURE__ */ jsx("span", { className: isSelected ? "" : "ml-5", children: lang.label })
|
|
5927
|
+
]
|
|
5928
|
+
},
|
|
5929
|
+
lang.value
|
|
5930
|
+
);
|
|
5931
|
+
})
|
|
5932
|
+
]
|
|
5933
|
+
}
|
|
6034
5934
|
)
|
|
6035
5935
|
] });
|
|
6036
5936
|
}
|
|
@@ -6360,16 +6260,12 @@ function HeadingDropdown({
|
|
|
6360
6260
|
}) {
|
|
6361
6261
|
var _a;
|
|
6362
6262
|
const [open, setOpen] = useState(false);
|
|
6363
|
-
const
|
|
6364
|
-
const buttonRef = useRef(null);
|
|
6365
|
-
const popupRef = useRef(null);
|
|
6263
|
+
const containerRef = useRef(null);
|
|
6366
6264
|
const run = (command) => command(engine);
|
|
6367
6265
|
useEffect(() => {
|
|
6368
6266
|
if (!open) return;
|
|
6369
6267
|
const handler = (e) => {
|
|
6370
|
-
|
|
6371
|
-
const target = e.target;
|
|
6372
|
-
if (!((_a2 = popupRef.current) == null ? void 0 : _a2.contains(target)) && !((_b = buttonRef.current) == null ? void 0 : _b.contains(target)))
|
|
6268
|
+
if (containerRef.current && !containerRef.current.contains(e.target))
|
|
6373
6269
|
setOpen(false);
|
|
6374
6270
|
};
|
|
6375
6271
|
document.addEventListener("mousedown", handler);
|
|
@@ -6387,23 +6283,14 @@ function HeadingDropdown({
|
|
|
6387
6283
|
code_block: "Code"
|
|
6388
6284
|
};
|
|
6389
6285
|
const label = (_a = BLOCK_LABELS[activeBlock]) != null ? _a : "Paragraph";
|
|
6390
|
-
return /* @__PURE__ */ jsxs(
|
|
6286
|
+
return /* @__PURE__ */ jsxs("div", { ref: containerRef, className: "relative", children: [
|
|
6391
6287
|
/* @__PURE__ */ jsxs(
|
|
6392
6288
|
"button",
|
|
6393
6289
|
{
|
|
6394
|
-
ref: buttonRef,
|
|
6395
6290
|
type: "button",
|
|
6396
6291
|
onMouseDown: (e) => {
|
|
6397
6292
|
e.preventDefault();
|
|
6398
|
-
|
|
6399
|
-
setOpen(false);
|
|
6400
|
-
return;
|
|
6401
|
-
}
|
|
6402
|
-
if (buttonRef.current) {
|
|
6403
|
-
const rect = buttonRef.current.getBoundingClientRect();
|
|
6404
|
-
setPopupPos({ top: rect.bottom + 2, left: rect.left });
|
|
6405
|
-
}
|
|
6406
|
-
setOpen(true);
|
|
6293
|
+
setOpen((v) => !v);
|
|
6407
6294
|
},
|
|
6408
6295
|
className: "flex items-center gap-1 px-2 h-8 rounded text-sm font-medium text-gray-700 hover:bg-gray-100 cursor-pointer",
|
|
6409
6296
|
children: [
|
|
@@ -6412,7 +6299,7 @@ function HeadingDropdown({
|
|
|
6412
6299
|
]
|
|
6413
6300
|
}
|
|
6414
6301
|
),
|
|
6415
|
-
open &&
|
|
6302
|
+
open && /* @__PURE__ */ jsx("div", { className: "absolute top-full left-0 mt-0.5 w-40 bg-white border border-gray-200 rounded shadow-lg z-50", children: [
|
|
6416
6303
|
{
|
|
6417
6304
|
label: "Paragraph",
|
|
6418
6305
|
cmd: setParagraph,
|
|
@@ -6464,7 +6351,7 @@ function HeadingDropdown({
|
|
|
6464
6351
|
children: label2
|
|
6465
6352
|
},
|
|
6466
6353
|
label2
|
|
6467
|
-
)) })
|
|
6354
|
+
)) })
|
|
6468
6355
|
] });
|
|
6469
6356
|
}
|
|
6470
6357
|
function LinkButton({
|
|
@@ -6479,16 +6366,10 @@ function LinkButton({
|
|
|
6479
6366
|
const [editMode, setEditMode] = useState(false);
|
|
6480
6367
|
const [url, setUrl] = useState("");
|
|
6481
6368
|
const [displayText, setDisplayText] = useState("");
|
|
6482
|
-
const [popupPos, setPopupPos] = useState({ top: 0, left: 0 });
|
|
6483
6369
|
const containerRef = useRef(null);
|
|
6484
|
-
const popupRef = useRef(null);
|
|
6485
6370
|
const urlInputRef = useRef(null);
|
|
6486
6371
|
const textInputRef = useRef(null);
|
|
6487
6372
|
const openPopup = () => {
|
|
6488
|
-
if (containerRef.current) {
|
|
6489
|
-
const rect = containerRef.current.getBoundingClientRect();
|
|
6490
|
-
setPopupPos({ top: rect.bottom + 4, left: rect.left });
|
|
6491
|
-
}
|
|
6492
6373
|
if (isActive) {
|
|
6493
6374
|
setUrl(activeHref != null ? activeHref : "");
|
|
6494
6375
|
setDisplayText("");
|
|
@@ -6520,9 +6401,7 @@ function LinkButton({
|
|
|
6520
6401
|
useEffect(() => {
|
|
6521
6402
|
if (!open) return;
|
|
6522
6403
|
const handler = (e) => {
|
|
6523
|
-
|
|
6524
|
-
const target = e.target;
|
|
6525
|
-
if (!((_a = popupRef.current) == null ? void 0 : _a.contains(target)) && !((_b = containerRef.current) == null ? void 0 : _b.contains(target))) {
|
|
6404
|
+
if (containerRef.current && !containerRef.current.contains(e.target)) {
|
|
6526
6405
|
closePopup();
|
|
6527
6406
|
}
|
|
6528
6407
|
};
|
|
@@ -6562,7 +6441,7 @@ function LinkButton({
|
|
|
6562
6441
|
setEditMode(true);
|
|
6563
6442
|
};
|
|
6564
6443
|
const showTextInput = !hasTextSelected && !isActive;
|
|
6565
|
-
return /* @__PURE__ */ jsxs("div", { ref: containerRef, children: [
|
|
6444
|
+
return /* @__PURE__ */ jsxs("div", { ref: containerRef, className: "relative", children: [
|
|
6566
6445
|
/* @__PURE__ */ jsx(
|
|
6567
6446
|
ToolbarButton,
|
|
6568
6447
|
{
|
|
@@ -6573,43 +6452,115 @@ function LinkButton({
|
|
|
6573
6452
|
icon: /* @__PURE__ */ jsx(LinkIcon, {})
|
|
6574
6453
|
}
|
|
6575
6454
|
),
|
|
6576
|
-
open &&
|
|
6577
|
-
|
|
6578
|
-
|
|
6579
|
-
|
|
6580
|
-
|
|
6581
|
-
|
|
6582
|
-
|
|
6583
|
-
|
|
6584
|
-
className: "
|
|
6585
|
-
|
|
6586
|
-
|
|
6587
|
-
|
|
6455
|
+
open && /* @__PURE__ */ jsx(
|
|
6456
|
+
"div",
|
|
6457
|
+
{
|
|
6458
|
+
role: "dialog",
|
|
6459
|
+
"aria-label": "Link editor",
|
|
6460
|
+
className: "absolute top-full left-0 mt-1 z-50 bg-white border border-gray-200 rounded-lg shadow-xl p-3 w-80",
|
|
6461
|
+
children: isActive && !editMode ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
6462
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs font-medium text-gray-400 mb-2 uppercase tracking-wide", children: "Link" }),
|
|
6463
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 min-w-0", children: [
|
|
6464
|
+
/* @__PURE__ */ jsx(
|
|
6465
|
+
"a",
|
|
6466
|
+
{
|
|
6467
|
+
href: activeHref != null ? activeHref : "#",
|
|
6468
|
+
target: "_blank",
|
|
6469
|
+
rel: "noopener noreferrer",
|
|
6470
|
+
className: "flex-1 text-sm text-blue-600 hover:underline truncate",
|
|
6471
|
+
title: activeHref != null ? activeHref : "",
|
|
6472
|
+
children: activeHref
|
|
6473
|
+
}
|
|
6474
|
+
),
|
|
6475
|
+
/* @__PURE__ */ jsx(
|
|
6476
|
+
"button",
|
|
6477
|
+
{
|
|
6478
|
+
type: "button",
|
|
6479
|
+
onMouseDown: (e) => {
|
|
6480
|
+
e.preventDefault();
|
|
6481
|
+
handleStartEdit();
|
|
6482
|
+
},
|
|
6483
|
+
className: "shrink-0 text-xs text-gray-500 hover:text-gray-700 px-2 py-1 rounded hover:bg-gray-100 ",
|
|
6484
|
+
"aria-label": "Edit link",
|
|
6485
|
+
children: "Edit"
|
|
6486
|
+
}
|
|
6487
|
+
),
|
|
6488
|
+
/* @__PURE__ */ jsx(
|
|
6489
|
+
"button",
|
|
6490
|
+
{
|
|
6491
|
+
type: "button",
|
|
6492
|
+
onMouseDown: (e) => {
|
|
6493
|
+
e.preventDefault();
|
|
6494
|
+
handleRemove();
|
|
6495
|
+
},
|
|
6496
|
+
className: "shrink-0 text-xs text-red-500 hover:text-red-700 px-2 py-1 rounded hover:bg-red-50 ",
|
|
6497
|
+
"aria-label": "Remove link",
|
|
6498
|
+
children: "Remove"
|
|
6499
|
+
}
|
|
6500
|
+
)
|
|
6501
|
+
] })
|
|
6502
|
+
] }) : (
|
|
6503
|
+
/* ── Edit / Insert mode ── */
|
|
6504
|
+
/* @__PURE__ */ jsxs(Fragment, { children: [
|
|
6505
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs font-medium text-gray-400 mb-3 uppercase tracking-wide", children: isActive ? "Edit link" : "Insert link" }),
|
|
6506
|
+
showTextInput && /* @__PURE__ */ jsxs("div", { className: "mb-2", children: [
|
|
6507
|
+
/* @__PURE__ */ jsx("label", { className: "block text-xs text-gray-600 mb-1", children: "Display text" }),
|
|
6588
6508
|
/* @__PURE__ */ jsx(
|
|
6589
|
-
"
|
|
6509
|
+
"input",
|
|
6590
6510
|
{
|
|
6591
|
-
|
|
6592
|
-
|
|
6593
|
-
|
|
6594
|
-
|
|
6595
|
-
|
|
6596
|
-
|
|
6511
|
+
ref: textInputRef,
|
|
6512
|
+
type: "text",
|
|
6513
|
+
value: displayText,
|
|
6514
|
+
onChange: (e) => setDisplayText(e.target.value),
|
|
6515
|
+
onKeyDown: (e) => {
|
|
6516
|
+
var _a;
|
|
6517
|
+
if (e.key === "Enter") {
|
|
6518
|
+
e.preventDefault();
|
|
6519
|
+
(_a = urlInputRef.current) == null ? void 0 : _a.focus();
|
|
6520
|
+
}
|
|
6521
|
+
if (e.key === "Escape") closePopup();
|
|
6522
|
+
},
|
|
6523
|
+
placeholder: "Link text",
|
|
6524
|
+
className: "w-full border border-gray-300 rounded px-2 py-1.5 text-sm bg-white text-gray-900 focus:outline-none focus:ring-2 focus:ring-blue-500"
|
|
6597
6525
|
}
|
|
6598
|
-
)
|
|
6526
|
+
)
|
|
6527
|
+
] }),
|
|
6528
|
+
/* @__PURE__ */ jsxs("div", { className: "mb-3", children: [
|
|
6529
|
+
/* @__PURE__ */ jsx("label", { className: "block text-xs text-gray-600 mb-1", children: "URL" }),
|
|
6530
|
+
/* @__PURE__ */ jsx(
|
|
6531
|
+
"input",
|
|
6532
|
+
{
|
|
6533
|
+
ref: urlInputRef,
|
|
6534
|
+
type: "url",
|
|
6535
|
+
value: url,
|
|
6536
|
+
onChange: (e) => setUrl(e.target.value),
|
|
6537
|
+
onKeyDown: (e) => {
|
|
6538
|
+
if (e.key === "Enter") {
|
|
6539
|
+
e.preventDefault();
|
|
6540
|
+
handleApply();
|
|
6541
|
+
}
|
|
6542
|
+
if (e.key === "Escape") closePopup();
|
|
6543
|
+
},
|
|
6544
|
+
placeholder: "https://example.com",
|
|
6545
|
+
className: "w-full border border-gray-300 rounded px-2 py-1.5 text-sm bg-white text-gray-900 focus:outline-none focus:ring-2 focus:ring-blue-500"
|
|
6546
|
+
}
|
|
6547
|
+
)
|
|
6548
|
+
] }),
|
|
6549
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
6599
6550
|
/* @__PURE__ */ jsx(
|
|
6600
6551
|
"button",
|
|
6601
6552
|
{
|
|
6602
6553
|
type: "button",
|
|
6603
6554
|
onMouseDown: (e) => {
|
|
6604
6555
|
e.preventDefault();
|
|
6605
|
-
|
|
6556
|
+
handleApply();
|
|
6606
6557
|
},
|
|
6607
|
-
|
|
6608
|
-
"
|
|
6609
|
-
children: "
|
|
6558
|
+
disabled: !url.trim() || showTextInput && !displayText.trim() && !hasTextSelected && !isActive,
|
|
6559
|
+
className: "flex-1 px-3 py-1.5 bg-blue-600 text-white text-sm rounded hover:bg-blue-700 disabled:opacity-40 disabled:cursor-not-allowed",
|
|
6560
|
+
children: isActive ? "Update" : "Insert"
|
|
6610
6561
|
}
|
|
6611
6562
|
),
|
|
6612
|
-
/* @__PURE__ */ jsx(
|
|
6563
|
+
isActive && /* @__PURE__ */ jsx(
|
|
6613
6564
|
"button",
|
|
6614
6565
|
{
|
|
6615
6566
|
type: "button",
|
|
@@ -6617,104 +6568,27 @@ function LinkButton({
|
|
|
6617
6568
|
e.preventDefault();
|
|
6618
6569
|
handleRemove();
|
|
6619
6570
|
},
|
|
6620
|
-
className: "
|
|
6621
|
-
"aria-label": "Remove link",
|
|
6571
|
+
className: "px-3 py-1.5 text-sm text-red-600 border border-red-200 rounded hover:bg-red-50 ",
|
|
6622
6572
|
children: "Remove"
|
|
6623
6573
|
}
|
|
6574
|
+
),
|
|
6575
|
+
/* @__PURE__ */ jsx(
|
|
6576
|
+
"button",
|
|
6577
|
+
{
|
|
6578
|
+
type: "button",
|
|
6579
|
+
onMouseDown: (e) => {
|
|
6580
|
+
e.preventDefault();
|
|
6581
|
+
closePopup();
|
|
6582
|
+
},
|
|
6583
|
+
className: "px-3 py-1.5 text-sm text-gray-500 hover:text-gray-700 ",
|
|
6584
|
+
"aria-label": "Cancel",
|
|
6585
|
+
children: "\u2715"
|
|
6586
|
+
}
|
|
6624
6587
|
)
|
|
6625
6588
|
] })
|
|
6626
|
-
] })
|
|
6627
|
-
|
|
6628
|
-
|
|
6629
|
-
/* @__PURE__ */ jsx("p", { className: "text-xs font-medium text-gray-400 mb-3 uppercase tracking-wide", children: isActive ? "Edit link" : "Insert link" }),
|
|
6630
|
-
showTextInput && /* @__PURE__ */ jsxs("div", { className: "mb-2", children: [
|
|
6631
|
-
/* @__PURE__ */ jsx("label", { className: "block text-xs text-gray-600 mb-1", children: "Display text" }),
|
|
6632
|
-
/* @__PURE__ */ jsx(
|
|
6633
|
-
"input",
|
|
6634
|
-
{
|
|
6635
|
-
ref: textInputRef,
|
|
6636
|
-
type: "text",
|
|
6637
|
-
value: displayText,
|
|
6638
|
-
onChange: (e) => setDisplayText(e.target.value),
|
|
6639
|
-
onKeyDown: (e) => {
|
|
6640
|
-
var _a;
|
|
6641
|
-
if (e.key === "Enter") {
|
|
6642
|
-
e.preventDefault();
|
|
6643
|
-
(_a = urlInputRef.current) == null ? void 0 : _a.focus();
|
|
6644
|
-
}
|
|
6645
|
-
if (e.key === "Escape") closePopup();
|
|
6646
|
-
},
|
|
6647
|
-
placeholder: "Link text",
|
|
6648
|
-
className: "w-full border border-gray-300 rounded px-2 py-1.5 text-sm bg-white text-gray-900 focus:outline-none focus:ring-2 focus:ring-blue-500"
|
|
6649
|
-
}
|
|
6650
|
-
)
|
|
6651
|
-
] }),
|
|
6652
|
-
/* @__PURE__ */ jsxs("div", { className: "mb-3", children: [
|
|
6653
|
-
/* @__PURE__ */ jsx("label", { className: "block text-xs text-gray-600 mb-1", children: "URL" }),
|
|
6654
|
-
/* @__PURE__ */ jsx(
|
|
6655
|
-
"input",
|
|
6656
|
-
{
|
|
6657
|
-
ref: urlInputRef,
|
|
6658
|
-
type: "url",
|
|
6659
|
-
value: url,
|
|
6660
|
-
onChange: (e) => setUrl(e.target.value),
|
|
6661
|
-
onKeyDown: (e) => {
|
|
6662
|
-
if (e.key === "Enter") {
|
|
6663
|
-
e.preventDefault();
|
|
6664
|
-
handleApply();
|
|
6665
|
-
}
|
|
6666
|
-
if (e.key === "Escape") closePopup();
|
|
6667
|
-
},
|
|
6668
|
-
placeholder: "https://example.com",
|
|
6669
|
-
className: "w-full border border-gray-300 rounded px-2 py-1.5 text-sm bg-white text-gray-900 focus:outline-none focus:ring-2 focus:ring-blue-500"
|
|
6670
|
-
}
|
|
6671
|
-
)
|
|
6672
|
-
] }),
|
|
6673
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
6674
|
-
/* @__PURE__ */ jsx(
|
|
6675
|
-
"button",
|
|
6676
|
-
{
|
|
6677
|
-
type: "button",
|
|
6678
|
-
onMouseDown: (e) => {
|
|
6679
|
-
e.preventDefault();
|
|
6680
|
-
handleApply();
|
|
6681
|
-
},
|
|
6682
|
-
disabled: !url.trim() || showTextInput && !displayText.trim() && !hasTextSelected && !isActive,
|
|
6683
|
-
className: "flex-1 px-3 py-1.5 bg-blue-600 text-white text-sm rounded hover:bg-blue-700 disabled:opacity-40 disabled:cursor-not-allowed",
|
|
6684
|
-
children: isActive ? "Update" : "Insert"
|
|
6685
|
-
}
|
|
6686
|
-
),
|
|
6687
|
-
isActive && /* @__PURE__ */ jsx(
|
|
6688
|
-
"button",
|
|
6689
|
-
{
|
|
6690
|
-
type: "button",
|
|
6691
|
-
onMouseDown: (e) => {
|
|
6692
|
-
e.preventDefault();
|
|
6693
|
-
handleRemove();
|
|
6694
|
-
},
|
|
6695
|
-
className: "px-3 py-1.5 text-sm text-red-600 border border-red-200 rounded hover:bg-red-50 ",
|
|
6696
|
-
children: "Remove"
|
|
6697
|
-
}
|
|
6698
|
-
),
|
|
6699
|
-
/* @__PURE__ */ jsx(
|
|
6700
|
-
"button",
|
|
6701
|
-
{
|
|
6702
|
-
type: "button",
|
|
6703
|
-
onMouseDown: (e) => {
|
|
6704
|
-
e.preventDefault();
|
|
6705
|
-
closePopup();
|
|
6706
|
-
},
|
|
6707
|
-
className: "px-3 py-1.5 text-sm text-gray-500 hover:text-gray-700 ",
|
|
6708
|
-
"aria-label": "Cancel",
|
|
6709
|
-
children: "\u2715"
|
|
6710
|
-
}
|
|
6711
|
-
)
|
|
6712
|
-
] })
|
|
6713
|
-
] })
|
|
6714
|
-
)
|
|
6715
|
-
}
|
|
6716
|
-
),
|
|
6717
|
-
document.body
|
|
6589
|
+
] })
|
|
6590
|
+
)
|
|
6591
|
+
}
|
|
6718
6592
|
)
|
|
6719
6593
|
] });
|
|
6720
6594
|
}
|