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