@x-plat/design-system 0.11.0 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/AutoResizeTextArea/index.cjs +2 -2
- package/dist/components/AutoResizeTextArea/index.js +2 -2
- package/dist/components/ChatInput/index.cjs +2 -2
- package/dist/components/ChatInput/index.js +2 -2
- package/dist/components/CheckBox/index.cjs +2 -2
- package/dist/components/CheckBox/index.js +2 -2
- package/dist/components/DatePicker/index.cjs +109 -75
- package/dist/components/DatePicker/index.d.cts +19 -0
- package/dist/components/DatePicker/index.d.ts +19 -0
- package/dist/components/DatePicker/index.js +109 -75
- package/dist/components/Dropdown/index.cjs +22 -9
- package/dist/components/Dropdown/index.css +3 -0
- package/dist/components/Dropdown/index.js +22 -9
- package/dist/components/Editor/index.cjs +602 -30
- package/dist/components/Editor/index.css +103 -0
- package/dist/components/Editor/index.d.cts +1 -1
- package/dist/components/Editor/index.d.ts +1 -1
- package/dist/components/Editor/index.js +602 -30
- package/dist/components/FieldMessage/index.cjs +2 -2
- package/dist/components/FieldMessage/index.d.cts +8 -0
- package/dist/components/FieldMessage/index.d.ts +8 -0
- package/dist/components/FieldMessage/index.js +2 -2
- package/dist/components/FileUpload/index.cjs +10 -6
- package/dist/components/FileUpload/index.d.cts +15 -2
- package/dist/components/FileUpload/index.d.ts +15 -2
- package/dist/components/FileUpload/index.js +10 -6
- package/dist/components/ImageSelector/index.cjs +7 -6
- package/dist/components/ImageSelector/index.d.cts +15 -2
- package/dist/components/ImageSelector/index.d.ts +15 -2
- package/dist/components/ImageSelector/index.js +7 -6
- package/dist/components/Input/index.cjs +2 -2
- package/dist/components/Input/index.d.cts +4 -0
- package/dist/components/Input/index.d.ts +4 -0
- package/dist/components/Input/index.js +2 -2
- package/dist/components/PopOver/index.cjs +21 -7
- package/dist/components/PopOver/index.css +3 -0
- package/dist/components/PopOver/index.js +21 -7
- package/dist/components/Radio/index.cjs +2 -2
- package/dist/components/Radio/index.js +2 -2
- package/dist/components/Select/index.cjs +23 -10
- package/dist/components/Select/index.css +3 -0
- package/dist/components/Select/index.d.cts +1 -2
- package/dist/components/Select/index.d.ts +1 -2
- package/dist/components/Select/index.js +23 -10
- package/dist/components/Switch/index.cjs +2 -2
- package/dist/components/Switch/index.js +2 -2
- package/dist/components/TextArea/index.cjs +2 -2
- package/dist/components/TextArea/index.js +2 -2
- package/dist/components/TimePicker/index.cjs +23 -10
- package/dist/components/TimePicker/index.css +3 -0
- package/dist/components/TimePicker/index.js +23 -10
- package/dist/components/index.cjs +751 -124
- package/dist/components/index.css +113 -0
- package/dist/components/index.js +751 -124
- package/dist/index.cjs +751 -124
- package/dist/index.css +113 -0
- package/dist/index.js +751 -124
- package/guidelines/Guidelines.md +12 -0
- package/guidelines/MIGRATION.md +270 -0
- package/guidelines/components/datepicker.md +26 -0
- package/guidelines/components/editor.md +58 -3
- package/guidelines/components/file-media.md +21 -4
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -5622,11 +5622,11 @@ var FieldMessage = (props) => {
|
|
|
5622
5622
|
FieldMessage.displayName = "FieldMessage";
|
|
5623
5623
|
var FieldMessage_default = FieldMessage;
|
|
5624
5624
|
var Field = (props) => {
|
|
5625
|
-
const { label, required = false, htmlFor, validations, children } = props;
|
|
5625
|
+
const { label, required = false, htmlFor, labelId, validations, children } = props;
|
|
5626
5626
|
const hasMessages = !!validations && validations.length > 0;
|
|
5627
5627
|
if (!label && !hasMessages) return /* @__PURE__ */ jsx297(Fragment, { children });
|
|
5628
5628
|
return /* @__PURE__ */ jsxs191("div", { className: "lib-xplat-field", children: [
|
|
5629
|
-
label && /* @__PURE__ */ jsxs191("label", { className: "lib-xplat-field-label", htmlFor, children: [
|
|
5629
|
+
label && /* @__PURE__ */ jsxs191("label", { className: "lib-xplat-field-label", id: labelId, htmlFor, children: [
|
|
5630
5630
|
label,
|
|
5631
5631
|
required && /* @__PURE__ */ jsx297("span", { className: "required", "aria-hidden": "true", children: "*" })
|
|
5632
5632
|
] }),
|
|
@@ -7406,8 +7406,12 @@ var SingleDatePicker = (props) => {
|
|
|
7406
7406
|
highlightDates = [],
|
|
7407
7407
|
locale = "ko",
|
|
7408
7408
|
rangeStart,
|
|
7409
|
-
rangeEnd
|
|
7409
|
+
rangeEnd,
|
|
7410
|
+
label,
|
|
7411
|
+
required,
|
|
7412
|
+
validations
|
|
7410
7413
|
} = props;
|
|
7414
|
+
const labelId = React12.useId();
|
|
7411
7415
|
const initialYear = value?.getFullYear();
|
|
7412
7416
|
const initialMonth = value?.getMonth();
|
|
7413
7417
|
const { year, month, days, goToPrevMonth, goToNextMonth, setYear, setMonth } = useCalendar(
|
|
@@ -7470,10 +7474,12 @@ var SingleDatePicker = (props) => {
|
|
|
7470
7474
|
const monthLabels = MONTH_LABELS[locale];
|
|
7471
7475
|
const titleText = pickerMode === "days" ? locale === "ko" ? `${year}\uB144 ${monthLabels[month]}` : `${monthLabels[month]} ${year}` : pickerMode === "months" ? `${year}` : `${yearRangeStart} - ${yearRangeStart + 11}`;
|
|
7472
7476
|
const hasRange = rangeStart != null && rangeEnd != null;
|
|
7473
|
-
|
|
7477
|
+
const calendar = /* @__PURE__ */ jsxs200(
|
|
7474
7478
|
"div",
|
|
7475
7479
|
{
|
|
7476
7480
|
className: clsx_default("lib-xplat-datepicker", "single"),
|
|
7481
|
+
role: "group",
|
|
7482
|
+
"aria-labelledby": label ? labelId : void 0,
|
|
7477
7483
|
children: [
|
|
7478
7484
|
/* @__PURE__ */ jsxs200("div", { className: "datepicker-header", children: [
|
|
7479
7485
|
/* @__PURE__ */ jsx314("button", { className: "datepicker-nav", onClick: handlePrev, type: "button", children: /* @__PURE__ */ jsx314(ChevronLeftIcon_default, {}) }),
|
|
@@ -7494,18 +7500,18 @@ var SingleDatePicker = (props) => {
|
|
|
7494
7500
|
y
|
|
7495
7501
|
);
|
|
7496
7502
|
}) }),
|
|
7497
|
-
pickerMode === "months" && /* @__PURE__ */ jsx314("div", { className: "datepicker-picker-grid", children: monthLabels.map((
|
|
7503
|
+
pickerMode === "months" && /* @__PURE__ */ jsx314("div", { className: "datepicker-picker-grid", children: monthLabels.map((label2, i) => /* @__PURE__ */ jsx314(
|
|
7498
7504
|
"button",
|
|
7499
7505
|
{
|
|
7500
7506
|
type: "button",
|
|
7501
7507
|
className: clsx_default("datepicker-picker-cell", i === month && "active"),
|
|
7502
7508
|
onClick: () => handleMonthSelect(i),
|
|
7503
|
-
children:
|
|
7509
|
+
children: label2
|
|
7504
7510
|
},
|
|
7505
7511
|
i
|
|
7506
7512
|
)) }),
|
|
7507
7513
|
pickerMode === "days" && /* @__PURE__ */ jsxs200(Fragment4, { children: [
|
|
7508
|
-
/* @__PURE__ */ jsx314("div", { className: "datepicker-weekdays", children: weekdays.map((
|
|
7514
|
+
/* @__PURE__ */ jsx314("div", { className: "datepicker-weekdays", children: weekdays.map((label2, i) => /* @__PURE__ */ jsx314(
|
|
7509
7515
|
"div",
|
|
7510
7516
|
{
|
|
7511
7517
|
className: clsx_default(
|
|
@@ -7513,9 +7519,9 @@ var SingleDatePicker = (props) => {
|
|
|
7513
7519
|
i === 0 && "sunday",
|
|
7514
7520
|
i === 6 && "saturday"
|
|
7515
7521
|
),
|
|
7516
|
-
children:
|
|
7522
|
+
children: label2
|
|
7517
7523
|
},
|
|
7518
|
-
|
|
7524
|
+
label2
|
|
7519
7525
|
)) }),
|
|
7520
7526
|
/* @__PURE__ */ jsx314("div", { className: "datepicker-grid", children: days.map((day, idx) => {
|
|
7521
7527
|
const t = day.date.getTime();
|
|
@@ -7547,6 +7553,7 @@ var SingleDatePicker = (props) => {
|
|
|
7547
7553
|
]
|
|
7548
7554
|
}
|
|
7549
7555
|
);
|
|
7556
|
+
return /* @__PURE__ */ jsx314(Field, { label, required, labelId, validations, children: calendar });
|
|
7550
7557
|
};
|
|
7551
7558
|
SingleDatePicker.displayName = "SingleDatePicker";
|
|
7552
7559
|
var SingleDatePicker_default = SingleDatePicker;
|
|
@@ -7561,7 +7568,18 @@ var formatDate = (date) => {
|
|
|
7561
7568
|
return `${y}/${m}/${d}`;
|
|
7562
7569
|
};
|
|
7563
7570
|
var InputDatePicker = (props) => {
|
|
7564
|
-
const {
|
|
7571
|
+
const {
|
|
7572
|
+
value,
|
|
7573
|
+
onChange,
|
|
7574
|
+
minDate,
|
|
7575
|
+
maxDate,
|
|
7576
|
+
disabled,
|
|
7577
|
+
locale = "ko",
|
|
7578
|
+
placeholder,
|
|
7579
|
+
label,
|
|
7580
|
+
required,
|
|
7581
|
+
validations
|
|
7582
|
+
} = props;
|
|
7565
7583
|
const [isOpen, setIsOpen] = React13.useState(false);
|
|
7566
7584
|
const [tempDate, setTempDate] = React13.useState(value ?? /* @__PURE__ */ new Date());
|
|
7567
7585
|
const handleOpen = () => {
|
|
@@ -7587,6 +7605,9 @@ var InputDatePicker = (props) => {
|
|
|
7587
7605
|
placeholder,
|
|
7588
7606
|
suffix: /* @__PURE__ */ jsx315(CalenderIcon_default, {}),
|
|
7589
7607
|
disabled,
|
|
7608
|
+
label,
|
|
7609
|
+
required,
|
|
7610
|
+
validations,
|
|
7590
7611
|
readOnly: true
|
|
7591
7612
|
}
|
|
7592
7613
|
) }),
|
|
@@ -7718,8 +7739,12 @@ var RangePicker = (props) => {
|
|
|
7718
7739
|
onChange,
|
|
7719
7740
|
minDate,
|
|
7720
7741
|
maxDate,
|
|
7721
|
-
locale = "ko"
|
|
7742
|
+
locale = "ko",
|
|
7743
|
+
label,
|
|
7744
|
+
required,
|
|
7745
|
+
validations
|
|
7722
7746
|
} = props;
|
|
7747
|
+
const labelId = React16.useId();
|
|
7723
7748
|
const [activeTab, setActiveTab] = React16.useState("start");
|
|
7724
7749
|
const handleStartChange = (date) => {
|
|
7725
7750
|
if (!date) return;
|
|
@@ -7733,70 +7758,79 @@ var RangePicker = (props) => {
|
|
|
7733
7758
|
};
|
|
7734
7759
|
const startMaxDate = maxDate && endDate < maxDate ? endDate : endDate;
|
|
7735
7760
|
const endMinDate = minDate && startDate > minDate ? startDate : startDate;
|
|
7736
|
-
|
|
7737
|
-
|
|
7738
|
-
|
|
7739
|
-
|
|
7740
|
-
|
|
7741
|
-
|
|
7742
|
-
|
|
7743
|
-
|
|
7744
|
-
|
|
7745
|
-
|
|
7746
|
-
|
|
7747
|
-
|
|
7748
|
-
|
|
7749
|
-
|
|
7750
|
-
|
|
7751
|
-
|
|
7752
|
-
|
|
7753
|
-
|
|
7754
|
-
|
|
7755
|
-
|
|
7756
|
-
|
|
7757
|
-
|
|
7758
|
-
|
|
7759
|
-
|
|
7760
|
-
|
|
7761
|
-
|
|
7762
|
-
|
|
7763
|
-
|
|
7764
|
-
|
|
7765
|
-
|
|
7766
|
-
|
|
7767
|
-
|
|
7768
|
-
|
|
7769
|
-
|
|
7770
|
-
|
|
7771
|
-
|
|
7772
|
-
|
|
7773
|
-
|
|
7774
|
-
|
|
7775
|
-
|
|
7776
|
-
|
|
7777
|
-
|
|
7778
|
-
|
|
7779
|
-
|
|
7780
|
-
|
|
7781
|
-
|
|
7782
|
-
|
|
7783
|
-
|
|
7784
|
-
|
|
7785
|
-
|
|
7786
|
-
|
|
7787
|
-
|
|
7788
|
-
|
|
7789
|
-
|
|
7790
|
-
|
|
7791
|
-
|
|
7792
|
-
|
|
7793
|
-
|
|
7794
|
-
|
|
7795
|
-
|
|
7796
|
-
|
|
7797
|
-
|
|
7798
|
-
|
|
7799
|
-
|
|
7761
|
+
const calendar = /* @__PURE__ */ jsxs203(
|
|
7762
|
+
"div",
|
|
7763
|
+
{
|
|
7764
|
+
className: clsx_default("lib-xplat-datepicker", "range"),
|
|
7765
|
+
role: "group",
|
|
7766
|
+
"aria-labelledby": label ? labelId : void 0,
|
|
7767
|
+
children: [
|
|
7768
|
+
/* @__PURE__ */ jsx318("div", { className: "datepicker-range-tabs", children: /* @__PURE__ */ jsx318(
|
|
7769
|
+
Tab_default,
|
|
7770
|
+
{
|
|
7771
|
+
activeIndex: activeTab === "start" ? 0 : 1,
|
|
7772
|
+
tabs: [
|
|
7773
|
+
{ value: "start", title: locale === "ko" ? "\uC2DC\uC791\uC77C" : "Start" },
|
|
7774
|
+
{ value: "end", title: locale === "ko" ? "\uC885\uB8CC\uC77C" : "End" }
|
|
7775
|
+
],
|
|
7776
|
+
onChange: (tab) => setActiveTab(tab.value),
|
|
7777
|
+
type: "toggle",
|
|
7778
|
+
size: "sm"
|
|
7779
|
+
}
|
|
7780
|
+
) }),
|
|
7781
|
+
/* @__PURE__ */ jsxs203("div", { className: "datepicker-range-panels", children: [
|
|
7782
|
+
/* @__PURE__ */ jsx318(
|
|
7783
|
+
SingleDatePicker_default,
|
|
7784
|
+
{
|
|
7785
|
+
value: startDate,
|
|
7786
|
+
onChange: handleStartChange,
|
|
7787
|
+
minDate,
|
|
7788
|
+
maxDate: startMaxDate,
|
|
7789
|
+
rangeStart: startDate,
|
|
7790
|
+
rangeEnd: endDate,
|
|
7791
|
+
locale
|
|
7792
|
+
}
|
|
7793
|
+
),
|
|
7794
|
+
/* @__PURE__ */ jsx318(
|
|
7795
|
+
SingleDatePicker_default,
|
|
7796
|
+
{
|
|
7797
|
+
value: endDate,
|
|
7798
|
+
onChange: handleEndChange,
|
|
7799
|
+
minDate: endMinDate,
|
|
7800
|
+
maxDate,
|
|
7801
|
+
rangeStart: startDate,
|
|
7802
|
+
rangeEnd: endDate,
|
|
7803
|
+
locale
|
|
7804
|
+
}
|
|
7805
|
+
)
|
|
7806
|
+
] }),
|
|
7807
|
+
/* @__PURE__ */ jsx318("div", { className: "datepicker-range-mobile", children: activeTab === "start" ? /* @__PURE__ */ jsx318(
|
|
7808
|
+
SingleDatePicker_default,
|
|
7809
|
+
{
|
|
7810
|
+
value: startDate,
|
|
7811
|
+
onChange: handleStartChange,
|
|
7812
|
+
minDate,
|
|
7813
|
+
maxDate: startMaxDate,
|
|
7814
|
+
rangeStart: startDate,
|
|
7815
|
+
rangeEnd: endDate,
|
|
7816
|
+
locale
|
|
7817
|
+
}
|
|
7818
|
+
) : /* @__PURE__ */ jsx318(
|
|
7819
|
+
SingleDatePicker_default,
|
|
7820
|
+
{
|
|
7821
|
+
value: endDate,
|
|
7822
|
+
onChange: handleEndChange,
|
|
7823
|
+
minDate: endMinDate,
|
|
7824
|
+
maxDate,
|
|
7825
|
+
rangeStart: startDate,
|
|
7826
|
+
rangeEnd: endDate,
|
|
7827
|
+
locale
|
|
7828
|
+
}
|
|
7829
|
+
) })
|
|
7830
|
+
]
|
|
7831
|
+
}
|
|
7832
|
+
);
|
|
7833
|
+
return /* @__PURE__ */ jsx318(Field, { label, required, labelId, validations, children: calendar });
|
|
7800
7834
|
};
|
|
7801
7835
|
RangePicker.displayName = "RangePicker";
|
|
7802
7836
|
var RangePicker_default = RangePicker;
|
|
@@ -7945,8 +7979,10 @@ import React19 from "react";
|
|
|
7945
7979
|
var useAutoPosition = (triggerRef, popRef, enabled = true) => {
|
|
7946
7980
|
const [position, setPosition] = React19.useState({
|
|
7947
7981
|
position: {},
|
|
7948
|
-
direction: "bottom"
|
|
7982
|
+
direction: "bottom",
|
|
7983
|
+
repositioning: false
|
|
7949
7984
|
});
|
|
7985
|
+
const placedRef = React19.useRef(false);
|
|
7950
7986
|
const calculatePosition = React19.useCallback(() => {
|
|
7951
7987
|
if (!triggerRef.current || !popRef.current) return;
|
|
7952
7988
|
const triggerRect = triggerRef.current.getBoundingClientRect();
|
|
@@ -7971,11 +8007,16 @@ var useAutoPosition = (triggerRef, popRef, enabled = true) => {
|
|
|
7971
8007
|
if (left < 8) left = 8;
|
|
7972
8008
|
setPosition({
|
|
7973
8009
|
position: { top, left },
|
|
7974
|
-
direction
|
|
8010
|
+
direction,
|
|
8011
|
+
repositioning: placedRef.current
|
|
7975
8012
|
});
|
|
8013
|
+
placedRef.current = true;
|
|
7976
8014
|
}, [triggerRef, popRef]);
|
|
7977
8015
|
React19.useLayoutEffect(() => {
|
|
7978
|
-
if (!enabled)
|
|
8016
|
+
if (!enabled) {
|
|
8017
|
+
placedRef.current = false;
|
|
8018
|
+
return;
|
|
8019
|
+
}
|
|
7979
8020
|
calculatePosition();
|
|
7980
8021
|
const raf = requestAnimationFrame(calculatePosition);
|
|
7981
8022
|
return () => cancelAnimationFrame(raf);
|
|
@@ -7990,11 +8031,17 @@ var useAutoPosition = (triggerRef, popRef, enabled = true) => {
|
|
|
7990
8031
|
}, [calculatePosition, enabled, popRef]);
|
|
7991
8032
|
React19.useEffect(() => {
|
|
7992
8033
|
if (!enabled) return;
|
|
7993
|
-
|
|
7994
|
-
|
|
8034
|
+
let raf = 0;
|
|
8035
|
+
const onScrollOrResize = () => {
|
|
8036
|
+
cancelAnimationFrame(raf);
|
|
8037
|
+
raf = requestAnimationFrame(calculatePosition);
|
|
8038
|
+
};
|
|
8039
|
+
window.addEventListener("resize", onScrollOrResize, { passive: true });
|
|
8040
|
+
window.addEventListener("scroll", onScrollOrResize, { passive: true, capture: true });
|
|
7995
8041
|
return () => {
|
|
7996
|
-
|
|
7997
|
-
window.removeEventListener("
|
|
8042
|
+
cancelAnimationFrame(raf);
|
|
8043
|
+
window.removeEventListener("resize", onScrollOrResize);
|
|
8044
|
+
window.removeEventListener("scroll", onScrollOrResize, true);
|
|
7998
8045
|
};
|
|
7999
8046
|
}, [calculatePosition, enabled]);
|
|
8000
8047
|
return position;
|
|
@@ -8035,7 +8082,7 @@ var Dropdown = (props) => {
|
|
|
8035
8082
|
const [visible, setVisible] = React21.useState(false);
|
|
8036
8083
|
const triggerRef = React21.useRef(null);
|
|
8037
8084
|
const menuRef = React21.useRef(null);
|
|
8038
|
-
const { position, direction } = useAutoPosition_default(triggerRef, menuRef, mounted);
|
|
8085
|
+
const { position, direction, repositioning } = useAutoPosition_default(triggerRef, menuRef, mounted);
|
|
8039
8086
|
useClickOutside_default([triggerRef, menuRef], () => setIsOpen(false), isOpen);
|
|
8040
8087
|
useEscapeKey(isOpen, () => {
|
|
8041
8088
|
setIsOpen(false);
|
|
@@ -8070,7 +8117,7 @@ var Dropdown = (props) => {
|
|
|
8070
8117
|
"div",
|
|
8071
8118
|
{
|
|
8072
8119
|
ref: menuRef,
|
|
8073
|
-
className: clsx_default("lib-xplat-dropdown-menu", direction, { visible }),
|
|
8120
|
+
className: clsx_default("lib-xplat-dropdown-menu", direction, { visible }, repositioning && "repositioning"),
|
|
8074
8121
|
style: { top: position.top, left: position.left },
|
|
8075
8122
|
role: "menu",
|
|
8076
8123
|
children: items.map((item) => /* @__PURE__ */ jsx322(
|
|
@@ -8096,6 +8143,111 @@ var Dropdown_default = Dropdown;
|
|
|
8096
8143
|
|
|
8097
8144
|
// src/components/Editor/Editor.tsx
|
|
8098
8145
|
import React22 from "react";
|
|
8146
|
+
|
|
8147
|
+
// src/components/Editor/highlight.ts
|
|
8148
|
+
var CODE_LANGUAGES = [
|
|
8149
|
+
{ value: "plain", label: "\uC5C6\uC74C" },
|
|
8150
|
+
{ value: "javascript", label: "JavaScript" },
|
|
8151
|
+
{ value: "typescript", label: "TypeScript" },
|
|
8152
|
+
{ value: "json", label: "JSON" },
|
|
8153
|
+
{ value: "html", label: "HTML" },
|
|
8154
|
+
{ value: "css", label: "CSS" },
|
|
8155
|
+
{ value: "python", label: "Python" },
|
|
8156
|
+
{ value: "sql", label: "SQL" },
|
|
8157
|
+
{ value: "bash", label: "Bash" }
|
|
8158
|
+
];
|
|
8159
|
+
var KEYWORDS = {
|
|
8160
|
+
plain: [],
|
|
8161
|
+
javascript: "const let var function return if else for while class new this import export from default async await try catch throw typeof instanceof null undefined true false break continue switch case do delete in of yield".split(" "),
|
|
8162
|
+
typescript: "const let var function return if else for while class new this import export from default async await try catch throw typeof instanceof null undefined true false break continue switch case do delete in of yield interface type enum implements extends public private protected readonly as satisfies keyof infer never unknown any".split(" "),
|
|
8163
|
+
json: ["true", "false", "null"],
|
|
8164
|
+
html: [],
|
|
8165
|
+
css: [],
|
|
8166
|
+
python: "def class return if elif else for while import from as try except finally raise with lambda None True False and or not in is pass break continue global nonlocal yield async await".split(" "),
|
|
8167
|
+
sql: "SELECT FROM WHERE INSERT INTO VALUES UPDATE SET DELETE CREATE TABLE ALTER DROP JOIN LEFT RIGHT INNER OUTER ON GROUP BY ORDER HAVING LIMIT OFFSET AS AND OR NOT NULL DISTINCT UNION INDEX PRIMARY KEY FOREIGN REFERENCES DEFAULT".split(" "),
|
|
8168
|
+
bash: "if then else fi for while do done case esac function return export local echo cd ls rm cp mv mkdir sudo source set unset exit".split(" ")
|
|
8169
|
+
};
|
|
8170
|
+
var LINE_COMMENT = {
|
|
8171
|
+
javascript: "//",
|
|
8172
|
+
typescript: "//",
|
|
8173
|
+
css: "",
|
|
8174
|
+
python: "#",
|
|
8175
|
+
sql: "--",
|
|
8176
|
+
bash: "#"
|
|
8177
|
+
};
|
|
8178
|
+
var escape = (s) => s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
8179
|
+
var wrap = (cls, text) => `<span class="tok-${cls}">${escape(text)}</span>`;
|
|
8180
|
+
var highlight = (code, lang) => {
|
|
8181
|
+
if (lang === "plain" || !code) return escape(code);
|
|
8182
|
+
const keywords = new Set(KEYWORDS[lang]);
|
|
8183
|
+
const lineComment = LINE_COMMENT[lang];
|
|
8184
|
+
const caseInsensitive = lang === "sql";
|
|
8185
|
+
let out = "";
|
|
8186
|
+
let i = 0;
|
|
8187
|
+
while (i < code.length) {
|
|
8188
|
+
const rest = code.slice(i);
|
|
8189
|
+
if ((lang === "javascript" || lang === "typescript" || lang === "css") && rest.startsWith("/*")) {
|
|
8190
|
+
const end = code.indexOf("*/", i + 2);
|
|
8191
|
+
const stop = end === -1 ? code.length : end + 2;
|
|
8192
|
+
out += wrap("comment", code.slice(i, stop));
|
|
8193
|
+
i = stop;
|
|
8194
|
+
continue;
|
|
8195
|
+
}
|
|
8196
|
+
if (lineComment && rest.startsWith(lineComment)) {
|
|
8197
|
+
const nl = code.indexOf("\n", i);
|
|
8198
|
+
const stop = nl === -1 ? code.length : nl;
|
|
8199
|
+
out += wrap("comment", code.slice(i, stop));
|
|
8200
|
+
i = stop;
|
|
8201
|
+
continue;
|
|
8202
|
+
}
|
|
8203
|
+
const q = rest[0];
|
|
8204
|
+
if (q === '"' || q === "'" || q === "`") {
|
|
8205
|
+
let j = 1;
|
|
8206
|
+
while (j < rest.length) {
|
|
8207
|
+
if (rest[j] === "\\") {
|
|
8208
|
+
j += 2;
|
|
8209
|
+
continue;
|
|
8210
|
+
}
|
|
8211
|
+
if (rest[j] === q) {
|
|
8212
|
+
j += 1;
|
|
8213
|
+
break;
|
|
8214
|
+
}
|
|
8215
|
+
if (rest[j] === "\n" && q !== "`") break;
|
|
8216
|
+
j += 1;
|
|
8217
|
+
}
|
|
8218
|
+
out += wrap("string", rest.slice(0, j));
|
|
8219
|
+
i += j;
|
|
8220
|
+
continue;
|
|
8221
|
+
}
|
|
8222
|
+
const num = /^\d+(\.\d+)?/.exec(rest);
|
|
8223
|
+
if (num && !/[\w$]/.test(code[i - 1] ?? "")) {
|
|
8224
|
+
out += wrap("number", num[0]);
|
|
8225
|
+
i += num[0].length;
|
|
8226
|
+
continue;
|
|
8227
|
+
}
|
|
8228
|
+
const word = /^[A-Za-z_$][\w$]*/.exec(rest);
|
|
8229
|
+
if (word) {
|
|
8230
|
+
const w = word[0];
|
|
8231
|
+
const hit = caseInsensitive ? keywords.has(w.toUpperCase()) : keywords.has(w);
|
|
8232
|
+
out += hit ? wrap("keyword", w) : escape(w);
|
|
8233
|
+
i += w.length;
|
|
8234
|
+
continue;
|
|
8235
|
+
}
|
|
8236
|
+
if (lang === "html" && rest.startsWith("<")) {
|
|
8237
|
+
const tag = /^<\/?[A-Za-z][\w-]*/.exec(rest);
|
|
8238
|
+
if (tag) {
|
|
8239
|
+
out += wrap("keyword", tag[0]);
|
|
8240
|
+
i += tag[0].length;
|
|
8241
|
+
continue;
|
|
8242
|
+
}
|
|
8243
|
+
}
|
|
8244
|
+
out += escape(code[i]);
|
|
8245
|
+
i += 1;
|
|
8246
|
+
}
|
|
8247
|
+
return out;
|
|
8248
|
+
};
|
|
8249
|
+
|
|
8250
|
+
// src/components/Editor/Editor.tsx
|
|
8099
8251
|
import { jsx as jsx323, jsxs as jsxs207 } from "react/jsx-runtime";
|
|
8100
8252
|
var DEFAULT_TOOLBAR = [
|
|
8101
8253
|
"bold",
|
|
@@ -8103,14 +8255,27 @@ var DEFAULT_TOOLBAR = [
|
|
|
8103
8255
|
"underline",
|
|
8104
8256
|
"strikethrough",
|
|
8105
8257
|
"code",
|
|
8106
|
-
"heading",
|
|
8258
|
+
"heading-1",
|
|
8259
|
+
"heading-2",
|
|
8260
|
+
"heading-3",
|
|
8107
8261
|
"list",
|
|
8108
8262
|
"ordered-list",
|
|
8109
8263
|
"blockquote",
|
|
8110
8264
|
"code-block",
|
|
8111
8265
|
"link",
|
|
8112
8266
|
"image",
|
|
8113
|
-
"divider"
|
|
8267
|
+
"divider",
|
|
8268
|
+
"checklist",
|
|
8269
|
+
"table",
|
|
8270
|
+
"align-left",
|
|
8271
|
+
"align-center",
|
|
8272
|
+
"align-right",
|
|
8273
|
+
"highlight",
|
|
8274
|
+
"superscript",
|
|
8275
|
+
"subscript",
|
|
8276
|
+
"clear-format",
|
|
8277
|
+
"undo",
|
|
8278
|
+
"redo"
|
|
8114
8279
|
];
|
|
8115
8280
|
var ALLOWED_TAGS = /* @__PURE__ */ new Set([
|
|
8116
8281
|
"p",
|
|
@@ -8139,11 +8304,41 @@ var ALLOWED_TAGS = /* @__PURE__ */ new Set([
|
|
|
8139
8304
|
"img",
|
|
8140
8305
|
"hr",
|
|
8141
8306
|
"span",
|
|
8142
|
-
"div"
|
|
8307
|
+
"div",
|
|
8308
|
+
"sub",
|
|
8309
|
+
"sup",
|
|
8310
|
+
"mark",
|
|
8311
|
+
"table",
|
|
8312
|
+
"thead",
|
|
8313
|
+
"tbody",
|
|
8314
|
+
"tr",
|
|
8315
|
+
"th",
|
|
8316
|
+
"td"
|
|
8143
8317
|
]);
|
|
8144
8318
|
var ALLOWED_ATTRS = {
|
|
8145
8319
|
a: ["href", "target", "rel"],
|
|
8146
|
-
img: ["src", "alt"]
|
|
8320
|
+
img: ["src", "alt", "width"],
|
|
8321
|
+
// 정렬·체크리스트는 클래스로만 표현한다. style 을 열면 붙여넣기로 아무 CSS 나 들어온다
|
|
8322
|
+
p: ["class"],
|
|
8323
|
+
h1: ["class"],
|
|
8324
|
+
h2: ["class"],
|
|
8325
|
+
h3: ["class"],
|
|
8326
|
+
h4: ["class"],
|
|
8327
|
+
h5: ["class"],
|
|
8328
|
+
h6: ["class"],
|
|
8329
|
+
ul: ["class"],
|
|
8330
|
+
ol: ["class"],
|
|
8331
|
+
li: ["class", "data-checked"],
|
|
8332
|
+
blockquote: ["class"],
|
|
8333
|
+
div: ["class"],
|
|
8334
|
+
span: ["class"],
|
|
8335
|
+
pre: ["class"],
|
|
8336
|
+
code: ["class"],
|
|
8337
|
+
mark: ["class"],
|
|
8338
|
+
table: ["class"],
|
|
8339
|
+
td: ["class"],
|
|
8340
|
+
th: ["class"],
|
|
8341
|
+
tr: ["class"]
|
|
8147
8342
|
};
|
|
8148
8343
|
var DROP_WITH_CONTENT = /* @__PURE__ */ new Set([
|
|
8149
8344
|
"script",
|
|
@@ -8196,7 +8391,9 @@ var escapeHtml = (text) => {
|
|
|
8196
8391
|
};
|
|
8197
8392
|
var SLASH_ITEMS = [
|
|
8198
8393
|
{ key: "paragraph", label: "\uB2E8\uB77D", hint: "\uAE30\uBCF8 \uD14D\uC2A4\uD2B8" },
|
|
8199
|
-
{ key: "heading", label: "\uC81C\uBAA9 1", hint: "\uD070 \uC81C\uBAA9" },
|
|
8394
|
+
{ key: "heading-1", label: "\uC81C\uBAA9 1", hint: "\uAC00\uC7A5 \uD070 \uC81C\uBAA9" },
|
|
8395
|
+
{ key: "heading-2", label: "\uC81C\uBAA9 2", hint: "" },
|
|
8396
|
+
{ key: "heading-3", label: "\uC81C\uBAA9 3", hint: "" },
|
|
8200
8397
|
{ key: "list", label: "\uAE00\uBA38\uB9AC \uAE30\uD638 \uBAA9\uB85D", hint: "\u2022 \uD56D\uBAA9" },
|
|
8201
8398
|
{ key: "ordered-list", label: "\uBC88\uD638 \uB9E4\uAE30\uAE30 \uBAA9\uB85D", hint: "1. \uD56D\uBAA9" },
|
|
8202
8399
|
{ key: "blockquote", label: "\uC778\uC6A9", hint: "" },
|
|
@@ -8239,6 +8436,8 @@ var Editor = (props) => {
|
|
|
8239
8436
|
el.innerHTML = sanitizeHtml(value || "");
|
|
8240
8437
|
if (!el.firstChild) el.innerHTML = "<p><br></p>";
|
|
8241
8438
|
lastEmittedRef.current = null;
|
|
8439
|
+
historyRef.current = [{ html: el.innerHTML, caret: 0 }];
|
|
8440
|
+
historyIdxRef.current = 0;
|
|
8242
8441
|
updateEmpty();
|
|
8243
8442
|
}, [value]);
|
|
8244
8443
|
const updateEmpty = () => {
|
|
@@ -8283,6 +8482,17 @@ var Editor = (props) => {
|
|
|
8283
8482
|
if (document.queryCommandState("insertOrderedList")) next.add("ordered-list");
|
|
8284
8483
|
const block = String(document.queryCommandValue("formatBlock") || "").toLowerCase();
|
|
8285
8484
|
if (block) next.add(`block:${block}`);
|
|
8485
|
+
if (document.queryCommandState("superscript")) next.add("superscript");
|
|
8486
|
+
if (document.queryCommandState("subscript")) next.add("subscript");
|
|
8487
|
+
} catch {
|
|
8488
|
+
}
|
|
8489
|
+
try {
|
|
8490
|
+
const blockEl = currentBlock();
|
|
8491
|
+
if (blockEl?.classList.contains("align-center")) next.add("align:center");
|
|
8492
|
+
else if (blockEl?.classList.contains("align-right")) next.add("align:right");
|
|
8493
|
+
else if (blockEl) next.add("align:left");
|
|
8494
|
+
if (blockEl?.closest("mark")) next.add("highlight");
|
|
8495
|
+
if (blockEl?.closest("ul.checklist")) next.add("checklist");
|
|
8286
8496
|
} catch {
|
|
8287
8497
|
}
|
|
8288
8498
|
setActiveFormats(next);
|
|
@@ -8296,6 +8506,122 @@ var Editor = (props) => {
|
|
|
8296
8506
|
const setBlock = (tag) => {
|
|
8297
8507
|
exec("formatBlock", tag);
|
|
8298
8508
|
};
|
|
8509
|
+
const toggleBlock = (tag) => {
|
|
8510
|
+
const current = String(document.queryCommandValue("formatBlock") || "").toLowerCase();
|
|
8511
|
+
setBlock(current === tag ? "p" : tag);
|
|
8512
|
+
};
|
|
8513
|
+
const historyRef = React22.useRef([]);
|
|
8514
|
+
const historyIdxRef = React22.useRef(-1);
|
|
8515
|
+
const lastPushAtRef = React22.useRef(0);
|
|
8516
|
+
const isRestoringRef = React22.useRef(false);
|
|
8517
|
+
const caretOffset = (rootEl) => {
|
|
8518
|
+
const el = rootEl ?? editorRef.current;
|
|
8519
|
+
const sel = window.getSelection();
|
|
8520
|
+
if (!el || !sel || sel.rangeCount === 0 || !el.contains(sel.anchorNode)) return 0;
|
|
8521
|
+
const range = sel.getRangeAt(0).cloneRange();
|
|
8522
|
+
range.selectNodeContents(el);
|
|
8523
|
+
range.setEnd(sel.getRangeAt(0).endContainer, sel.getRangeAt(0).endOffset);
|
|
8524
|
+
return range.toString().length;
|
|
8525
|
+
};
|
|
8526
|
+
const setCaretOffset = (offset, rootEl) => {
|
|
8527
|
+
const el = rootEl ?? editorRef.current;
|
|
8528
|
+
if (!el) return;
|
|
8529
|
+
const walker = document.createTreeWalker(el, NodeFilter.SHOW_TEXT);
|
|
8530
|
+
let remaining = offset;
|
|
8531
|
+
let node = null;
|
|
8532
|
+
while (node = walker.nextNode()) {
|
|
8533
|
+
const len = node.textContent?.length ?? 0;
|
|
8534
|
+
if (remaining <= len) {
|
|
8535
|
+
const range = document.createRange();
|
|
8536
|
+
range.setStart(node, remaining);
|
|
8537
|
+
range.collapse(true);
|
|
8538
|
+
const sel = window.getSelection();
|
|
8539
|
+
sel?.removeAllRanges();
|
|
8540
|
+
sel?.addRange(range);
|
|
8541
|
+
return;
|
|
8542
|
+
}
|
|
8543
|
+
remaining -= len;
|
|
8544
|
+
}
|
|
8545
|
+
placeCaretAtEnd(el);
|
|
8546
|
+
};
|
|
8547
|
+
const pushHistory = (force = false) => {
|
|
8548
|
+
const el = editorRef.current;
|
|
8549
|
+
if (!el || isRestoringRef.current) return;
|
|
8550
|
+
const html = el.innerHTML;
|
|
8551
|
+
const hist = historyRef.current;
|
|
8552
|
+
const cur = hist[historyIdxRef.current];
|
|
8553
|
+
if (cur && cur.html === html) return;
|
|
8554
|
+
const now = Date.now();
|
|
8555
|
+
const coalesce = !force && cur && now - lastPushAtRef.current < 500;
|
|
8556
|
+
lastPushAtRef.current = now;
|
|
8557
|
+
if (coalesce) {
|
|
8558
|
+
hist[historyIdxRef.current] = { html, caret: caretOffset() };
|
|
8559
|
+
return;
|
|
8560
|
+
}
|
|
8561
|
+
hist.length = historyIdxRef.current + 1;
|
|
8562
|
+
hist.push({ html, caret: caretOffset() });
|
|
8563
|
+
if (hist.length > 200) hist.shift();
|
|
8564
|
+
historyIdxRef.current = hist.length - 1;
|
|
8565
|
+
};
|
|
8566
|
+
const applySnapshot = (snap) => {
|
|
8567
|
+
const el = editorRef.current;
|
|
8568
|
+
if (!el) return;
|
|
8569
|
+
isRestoringRef.current = true;
|
|
8570
|
+
el.innerHTML = snap.html;
|
|
8571
|
+
setCaretOffset(snap.caret);
|
|
8572
|
+
isRestoringRef.current = false;
|
|
8573
|
+
lastEmittedRef.current = el.innerHTML;
|
|
8574
|
+
onChange?.(el.innerHTML);
|
|
8575
|
+
updateEmpty();
|
|
8576
|
+
updateActiveFormats();
|
|
8577
|
+
};
|
|
8578
|
+
const undo = () => {
|
|
8579
|
+
pushHistory(true);
|
|
8580
|
+
if (historyIdxRef.current <= 0) return;
|
|
8581
|
+
historyIdxRef.current -= 1;
|
|
8582
|
+
applySnapshot(historyRef.current[historyIdxRef.current]);
|
|
8583
|
+
};
|
|
8584
|
+
const redo = () => {
|
|
8585
|
+
if (historyIdxRef.current >= historyRef.current.length - 1) return;
|
|
8586
|
+
historyIdxRef.current += 1;
|
|
8587
|
+
applySnapshot(historyRef.current[historyIdxRef.current]);
|
|
8588
|
+
};
|
|
8589
|
+
const langOf = (pre) => {
|
|
8590
|
+
const cls = Array.from(pre.classList).find((c) => c.startsWith("lang-"));
|
|
8591
|
+
return cls?.slice(5) ?? "plain";
|
|
8592
|
+
};
|
|
8593
|
+
const [codeLang, setCodeLang] = React22.useState("plain");
|
|
8594
|
+
const highlightRafRef = React22.useRef(0);
|
|
8595
|
+
const rehighlight = (pre) => {
|
|
8596
|
+
if (composingRef.current) return;
|
|
8597
|
+
const code = pre.querySelector("code");
|
|
8598
|
+
if (!code) return;
|
|
8599
|
+
const lang = langOf(pre);
|
|
8600
|
+
const text = code.textContent || "";
|
|
8601
|
+
const next = highlight(text, lang);
|
|
8602
|
+
if (code.innerHTML === next) return;
|
|
8603
|
+
const caret = caretOffset(code);
|
|
8604
|
+
isRestoringRef.current = true;
|
|
8605
|
+
code.innerHTML = next;
|
|
8606
|
+
setCaretOffset(caret, code);
|
|
8607
|
+
isRestoringRef.current = false;
|
|
8608
|
+
};
|
|
8609
|
+
const scheduleHighlight = () => {
|
|
8610
|
+
const pre = closestPre();
|
|
8611
|
+
if (!pre) return;
|
|
8612
|
+
cancelAnimationFrame(highlightRafRef.current);
|
|
8613
|
+
highlightRafRef.current = requestAnimationFrame(() => rehighlight(pre));
|
|
8614
|
+
};
|
|
8615
|
+
const changeCodeLang = (lang) => {
|
|
8616
|
+
const pre = closestPre();
|
|
8617
|
+
if (!pre) return;
|
|
8618
|
+
pushHistory(true);
|
|
8619
|
+
Array.from(pre.classList).filter((c) => c.startsWith("lang-")).forEach((c) => pre.classList.remove(c));
|
|
8620
|
+
if (lang !== "plain") pre.classList.add(`lang-${lang}`);
|
|
8621
|
+
setCodeLang(lang);
|
|
8622
|
+
rehighlight(pre);
|
|
8623
|
+
handleInput();
|
|
8624
|
+
};
|
|
8299
8625
|
const closestPre = () => {
|
|
8300
8626
|
const sel = window.getSelection();
|
|
8301
8627
|
const node = sel?.anchorNode;
|
|
@@ -8304,6 +8630,7 @@ var Editor = (props) => {
|
|
|
8304
8630
|
return el?.closest("pre") ?? null;
|
|
8305
8631
|
};
|
|
8306
8632
|
const insertCodeBlock = () => {
|
|
8633
|
+
pushHistory(true);
|
|
8307
8634
|
const el = editorRef.current;
|
|
8308
8635
|
const sel = window.getSelection();
|
|
8309
8636
|
if (!el || !sel || sel.rangeCount === 0) return;
|
|
@@ -8386,7 +8713,167 @@ var Editor = (props) => {
|
|
|
8386
8713
|
sel.addRange(r2);
|
|
8387
8714
|
editorRef.current?.focus();
|
|
8388
8715
|
};
|
|
8716
|
+
const clearFormat = () => {
|
|
8717
|
+
exec("removeFormat");
|
|
8718
|
+
exec("unlink");
|
|
8719
|
+
setBlock("p");
|
|
8720
|
+
};
|
|
8721
|
+
const indentList = (outdent) => {
|
|
8722
|
+
exec(outdent ? "outdent" : "indent");
|
|
8723
|
+
};
|
|
8724
|
+
const inListItem = () => {
|
|
8725
|
+
const sel = window.getSelection();
|
|
8726
|
+
const node = sel?.anchorNode;
|
|
8727
|
+
if (!node || !editorRef.current?.contains(node)) return false;
|
|
8728
|
+
const el = node.nodeType === Node.ELEMENT_NODE ? node : node.parentElement;
|
|
8729
|
+
return !!el?.closest("li");
|
|
8730
|
+
};
|
|
8731
|
+
const currentBlock = () => {
|
|
8732
|
+
const sel = window.getSelection();
|
|
8733
|
+
const node = sel?.anchorNode;
|
|
8734
|
+
const root = editorRef.current;
|
|
8735
|
+
if (!node || !root?.contains(node)) return null;
|
|
8736
|
+
let el = node.nodeType === Node.ELEMENT_NODE ? node : node.parentElement;
|
|
8737
|
+
while (el && el !== root && !/^(P|H[1-6]|LI|BLOCKQUOTE|PRE|DIV|TD|TH)$/.test(el.tagName)) {
|
|
8738
|
+
el = el.parentElement;
|
|
8739
|
+
}
|
|
8740
|
+
return el && el !== root ? el : null;
|
|
8741
|
+
};
|
|
8742
|
+
const setAlign = (align) => {
|
|
8743
|
+
const block = currentBlock();
|
|
8744
|
+
if (!block) return;
|
|
8745
|
+
pushHistory(true);
|
|
8746
|
+
block.classList.remove("align-left", "align-center", "align-right");
|
|
8747
|
+
if (align !== "left") block.classList.add(`align-${align}`);
|
|
8748
|
+
handleInput();
|
|
8749
|
+
};
|
|
8750
|
+
const toggleChecklist = () => {
|
|
8751
|
+
pushHistory(true);
|
|
8752
|
+
const block = currentBlock();
|
|
8753
|
+
const list = block?.closest("ul");
|
|
8754
|
+
if (list?.classList.contains("checklist")) {
|
|
8755
|
+
list.classList.remove("checklist");
|
|
8756
|
+
list.querySelectorAll("li").forEach((li) => li.removeAttribute("data-checked"));
|
|
8757
|
+
handleInput();
|
|
8758
|
+
return;
|
|
8759
|
+
}
|
|
8760
|
+
if (list) {
|
|
8761
|
+
list.classList.add("checklist");
|
|
8762
|
+
list.querySelectorAll("li").forEach((li) => li.setAttribute("data-checked", "false"));
|
|
8763
|
+
handleInput();
|
|
8764
|
+
return;
|
|
8765
|
+
}
|
|
8766
|
+
exec("insertUnorderedList");
|
|
8767
|
+
const made = currentBlock()?.closest("ul");
|
|
8768
|
+
if (made) {
|
|
8769
|
+
made.classList.add("checklist");
|
|
8770
|
+
made.querySelectorAll("li").forEach((li) => li.setAttribute("data-checked", "false"));
|
|
8771
|
+
}
|
|
8772
|
+
handleInput();
|
|
8773
|
+
};
|
|
8774
|
+
const handleEditorClick = (e) => {
|
|
8775
|
+
if (readOnly) return;
|
|
8776
|
+
const target = e.target;
|
|
8777
|
+
const li = target.closest?.("li");
|
|
8778
|
+
if (!li || !li.closest("ul.checklist")) return;
|
|
8779
|
+
const rect = li.getBoundingClientRect();
|
|
8780
|
+
if (e.clientX - rect.left > 20) return;
|
|
8781
|
+
e.preventDefault();
|
|
8782
|
+
pushHistory(true);
|
|
8783
|
+
li.setAttribute("data-checked", li.getAttribute("data-checked") === "true" ? "false" : "true");
|
|
8784
|
+
handleInput();
|
|
8785
|
+
};
|
|
8786
|
+
const toggleHighlight = () => {
|
|
8787
|
+
const sel = window.getSelection();
|
|
8788
|
+
if (!sel || sel.rangeCount === 0 || sel.isCollapsed) return;
|
|
8789
|
+
pushHistory(true);
|
|
8790
|
+
const range = sel.getRangeAt(0);
|
|
8791
|
+
const node = sel.anchorNode;
|
|
8792
|
+
const el = node?.nodeType === Node.ELEMENT_NODE ? node : node?.parentElement;
|
|
8793
|
+
const existing = el?.closest("mark");
|
|
8794
|
+
if (existing) {
|
|
8795
|
+
const parent = existing.parentNode;
|
|
8796
|
+
while (existing.firstChild) parent?.insertBefore(existing.firstChild, existing);
|
|
8797
|
+
parent?.removeChild(existing);
|
|
8798
|
+
handleInput();
|
|
8799
|
+
return;
|
|
8800
|
+
}
|
|
8801
|
+
const mark = document.createElement("mark");
|
|
8802
|
+
try {
|
|
8803
|
+
range.surroundContents(mark);
|
|
8804
|
+
} catch {
|
|
8805
|
+
const frag = range.extractContents();
|
|
8806
|
+
mark.appendChild(frag);
|
|
8807
|
+
range.insertNode(mark);
|
|
8808
|
+
}
|
|
8809
|
+
handleInput();
|
|
8810
|
+
};
|
|
8811
|
+
const insertTable = (cols = 3, rows = 2) => {
|
|
8812
|
+
const sel = window.getSelection();
|
|
8813
|
+
if (!sel || sel.rangeCount === 0) return;
|
|
8814
|
+
pushHistory(true);
|
|
8815
|
+
const table = document.createElement("table");
|
|
8816
|
+
const thead = document.createElement("thead");
|
|
8817
|
+
const headRow = document.createElement("tr");
|
|
8818
|
+
for (let c = 0; c < cols; c++) {
|
|
8819
|
+
const th = document.createElement("th");
|
|
8820
|
+
th.innerHTML = "<br>";
|
|
8821
|
+
headRow.appendChild(th);
|
|
8822
|
+
}
|
|
8823
|
+
thead.appendChild(headRow);
|
|
8824
|
+
table.appendChild(thead);
|
|
8825
|
+
const tbody = document.createElement("tbody");
|
|
8826
|
+
for (let r2 = 0; r2 < rows; r2++) {
|
|
8827
|
+
const tr = document.createElement("tr");
|
|
8828
|
+
for (let c = 0; c < cols; c++) {
|
|
8829
|
+
const td = document.createElement("td");
|
|
8830
|
+
td.innerHTML = "<br>";
|
|
8831
|
+
tr.appendChild(td);
|
|
8832
|
+
}
|
|
8833
|
+
tbody.appendChild(tr);
|
|
8834
|
+
}
|
|
8835
|
+
table.appendChild(tbody);
|
|
8836
|
+
const range = sel.getRangeAt(0);
|
|
8837
|
+
range.deleteContents();
|
|
8838
|
+
range.insertNode(table);
|
|
8839
|
+
ensureParagraphAfter(table);
|
|
8840
|
+
const first = table.querySelector("th");
|
|
8841
|
+
if (first) placeCaretAtEnd(first);
|
|
8842
|
+
handleInput();
|
|
8843
|
+
};
|
|
8844
|
+
const moveTableCell = (backwards) => {
|
|
8845
|
+
const block = currentBlock();
|
|
8846
|
+
const cell = block?.closest("td, th");
|
|
8847
|
+
if (!cell) return false;
|
|
8848
|
+
const table = cell.closest("table");
|
|
8849
|
+
if (!table) return false;
|
|
8850
|
+
const cells = Array.from(table.querySelectorAll("td, th"));
|
|
8851
|
+
const i = cells.indexOf(cell);
|
|
8852
|
+
const next = cells[i + (backwards ? -1 : 1)];
|
|
8853
|
+
if (next) {
|
|
8854
|
+
placeCaretAtEnd(next);
|
|
8855
|
+
return true;
|
|
8856
|
+
}
|
|
8857
|
+
if (!backwards) {
|
|
8858
|
+
pushHistory(true);
|
|
8859
|
+
const lastRow = table.querySelector("tbody")?.lastElementChild;
|
|
8860
|
+
if (lastRow) {
|
|
8861
|
+
const tr = document.createElement("tr");
|
|
8862
|
+
for (let c = 0; c < lastRow.children.length; c++) {
|
|
8863
|
+
const td = document.createElement("td");
|
|
8864
|
+
td.innerHTML = "<br>";
|
|
8865
|
+
tr.appendChild(td);
|
|
8866
|
+
}
|
|
8867
|
+
lastRow.after(tr);
|
|
8868
|
+
placeCaretAtEnd(tr.firstElementChild);
|
|
8869
|
+
handleInput();
|
|
8870
|
+
return true;
|
|
8871
|
+
}
|
|
8872
|
+
}
|
|
8873
|
+
return false;
|
|
8874
|
+
};
|
|
8389
8875
|
const insertDivider = () => {
|
|
8876
|
+
pushHistory(true);
|
|
8390
8877
|
exec("insertHorizontalRule");
|
|
8391
8878
|
const el = editorRef.current;
|
|
8392
8879
|
if (el && el.lastElementChild?.tagName === "HR") {
|
|
@@ -8479,8 +8966,14 @@ var Editor = (props) => {
|
|
|
8479
8966
|
case "paragraph":
|
|
8480
8967
|
setBlock("p");
|
|
8481
8968
|
break;
|
|
8482
|
-
case "heading":
|
|
8483
|
-
|
|
8969
|
+
case "heading-1":
|
|
8970
|
+
toggleBlock("h1");
|
|
8971
|
+
break;
|
|
8972
|
+
case "heading-2":
|
|
8973
|
+
toggleBlock("h2");
|
|
8974
|
+
break;
|
|
8975
|
+
case "heading-3":
|
|
8976
|
+
toggleBlock("h3");
|
|
8484
8977
|
break;
|
|
8485
8978
|
case "list":
|
|
8486
8979
|
exec("insertUnorderedList");
|
|
@@ -8573,6 +9066,8 @@ var Editor = (props) => {
|
|
|
8573
9066
|
if (!el) return;
|
|
8574
9067
|
const html = el.innerHTML;
|
|
8575
9068
|
lastEmittedRef.current = html;
|
|
9069
|
+
pushHistory();
|
|
9070
|
+
scheduleHighlight();
|
|
8576
9071
|
onChange?.(html);
|
|
8577
9072
|
updateEmpty();
|
|
8578
9073
|
updateActiveFormats();
|
|
@@ -8626,6 +9121,15 @@ var Editor = (props) => {
|
|
|
8626
9121
|
return;
|
|
8627
9122
|
}
|
|
8628
9123
|
}
|
|
9124
|
+
if (e.key === "Tab" && moveTableCell(e.shiftKey)) {
|
|
9125
|
+
e.preventDefault();
|
|
9126
|
+
return;
|
|
9127
|
+
}
|
|
9128
|
+
if (e.key === "Tab" && inListItem()) {
|
|
9129
|
+
e.preventDefault();
|
|
9130
|
+
indentList(e.shiftKey);
|
|
9131
|
+
return;
|
|
9132
|
+
}
|
|
8629
9133
|
if (slashOpen) {
|
|
8630
9134
|
if (e.key === "ArrowDown") {
|
|
8631
9135
|
e.preventDefault();
|
|
@@ -8649,6 +9153,21 @@ var Editor = (props) => {
|
|
|
8649
9153
|
return;
|
|
8650
9154
|
}
|
|
8651
9155
|
}
|
|
9156
|
+
if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === "z") {
|
|
9157
|
+
e.preventDefault();
|
|
9158
|
+
if (e.shiftKey) redo();
|
|
9159
|
+
else undo();
|
|
9160
|
+
return;
|
|
9161
|
+
}
|
|
9162
|
+
if ((e.metaKey || e.ctrlKey) && e.shiftKey && e.key.toLowerCase() === "v") {
|
|
9163
|
+
plainPasteRef.current = true;
|
|
9164
|
+
return;
|
|
9165
|
+
}
|
|
9166
|
+
if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === "y") {
|
|
9167
|
+
e.preventDefault();
|
|
9168
|
+
redo();
|
|
9169
|
+
return;
|
|
9170
|
+
}
|
|
8652
9171
|
if ((e.metaKey || e.ctrlKey) && !e.shiftKey && !e.altKey) {
|
|
8653
9172
|
const k = e.key.toLowerCase();
|
|
8654
9173
|
if (k === "b") {
|
|
@@ -8682,10 +9201,16 @@ var Editor = (props) => {
|
|
|
8682
9201
|
}
|
|
8683
9202
|
}
|
|
8684
9203
|
};
|
|
9204
|
+
const plainPasteRef = React22.useRef(false);
|
|
8685
9205
|
const handlePaste = (e) => {
|
|
8686
9206
|
if (readOnly) return;
|
|
8687
9207
|
e.preventDefault();
|
|
8688
9208
|
const text = e.clipboardData.getData("text/plain");
|
|
9209
|
+
if (plainPasteRef.current) {
|
|
9210
|
+
plainPasteRef.current = false;
|
|
9211
|
+
insertTextAtCaret(text);
|
|
9212
|
+
return;
|
|
9213
|
+
}
|
|
8689
9214
|
if (closestPre()) {
|
|
8690
9215
|
insertTextAtCaret(text);
|
|
8691
9216
|
return;
|
|
@@ -8712,9 +9237,11 @@ var Editor = (props) => {
|
|
|
8712
9237
|
};
|
|
8713
9238
|
const handleSelectionUpdate = () => {
|
|
8714
9239
|
updateActiveFormats();
|
|
9240
|
+
const pre = closestPre();
|
|
9241
|
+
setCodeLang(pre ? langOf(pre) : "plain");
|
|
8715
9242
|
};
|
|
8716
9243
|
const onToolbarAction = (item) => {
|
|
8717
|
-
if (closestPre() &&
|
|
9244
|
+
if (closestPre() && !["code-block", "undo", "redo"].includes(item)) return;
|
|
8718
9245
|
switch (item) {
|
|
8719
9246
|
case "bold":
|
|
8720
9247
|
exec("bold");
|
|
@@ -8743,8 +9270,14 @@ var Editor = (props) => {
|
|
|
8743
9270
|
handleInput();
|
|
8744
9271
|
break;
|
|
8745
9272
|
}
|
|
8746
|
-
case "heading":
|
|
8747
|
-
|
|
9273
|
+
case "heading-1":
|
|
9274
|
+
toggleBlock("h1");
|
|
9275
|
+
break;
|
|
9276
|
+
case "heading-2":
|
|
9277
|
+
toggleBlock("h2");
|
|
9278
|
+
break;
|
|
9279
|
+
case "heading-3":
|
|
9280
|
+
toggleBlock("h3");
|
|
8748
9281
|
break;
|
|
8749
9282
|
case "list":
|
|
8750
9283
|
exec("insertUnorderedList");
|
|
@@ -8767,6 +9300,39 @@ var Editor = (props) => {
|
|
|
8767
9300
|
case "divider":
|
|
8768
9301
|
insertDivider();
|
|
8769
9302
|
break;
|
|
9303
|
+
case "checklist":
|
|
9304
|
+
toggleChecklist();
|
|
9305
|
+
break;
|
|
9306
|
+
case "align-left":
|
|
9307
|
+
setAlign("left");
|
|
9308
|
+
break;
|
|
9309
|
+
case "align-center":
|
|
9310
|
+
setAlign("center");
|
|
9311
|
+
break;
|
|
9312
|
+
case "align-right":
|
|
9313
|
+
setAlign("right");
|
|
9314
|
+
break;
|
|
9315
|
+
case "highlight":
|
|
9316
|
+
toggleHighlight();
|
|
9317
|
+
break;
|
|
9318
|
+
case "superscript":
|
|
9319
|
+
exec("superscript");
|
|
9320
|
+
break;
|
|
9321
|
+
case "subscript":
|
|
9322
|
+
exec("subscript");
|
|
9323
|
+
break;
|
|
9324
|
+
case "table":
|
|
9325
|
+
insertTable();
|
|
9326
|
+
break;
|
|
9327
|
+
case "clear-format":
|
|
9328
|
+
clearFormat();
|
|
9329
|
+
break;
|
|
9330
|
+
case "undo":
|
|
9331
|
+
undo();
|
|
9332
|
+
break;
|
|
9333
|
+
case "redo":
|
|
9334
|
+
redo();
|
|
9335
|
+
break;
|
|
8770
9336
|
}
|
|
8771
9337
|
};
|
|
8772
9338
|
return /* @__PURE__ */ jsxs207("div", { className: clsx_default("lib-xplat-editor", isFocused && "focused", readOnly && "readonly"), children: [
|
|
@@ -8775,7 +9341,10 @@ var Editor = (props) => {
|
|
|
8775
9341
|
{
|
|
8776
9342
|
items: toolbar,
|
|
8777
9343
|
active: activeFormats,
|
|
8778
|
-
onAction: onToolbarAction
|
|
9344
|
+
onAction: onToolbarAction,
|
|
9345
|
+
codeLang,
|
|
9346
|
+
inCodeBlock: activeFormats.has("block:pre"),
|
|
9347
|
+
onCodeLangChange: changeCodeLang
|
|
8779
9348
|
}
|
|
8780
9349
|
),
|
|
8781
9350
|
/* @__PURE__ */ jsxs207("div", { className: "lib-xplat-editor__content", style: { minHeight }, children: [
|
|
@@ -8793,6 +9362,7 @@ var Editor = (props) => {
|
|
|
8793
9362
|
className: "lib-xplat-editor__editable",
|
|
8794
9363
|
onInput: handleInput,
|
|
8795
9364
|
onKeyDown: handleKeyDown,
|
|
9365
|
+
onClick: handleEditorClick,
|
|
8796
9366
|
onKeyUp: handleSelectionUpdate,
|
|
8797
9367
|
onMouseUp: handleSelectionUpdate,
|
|
8798
9368
|
onPaste: handlePaste,
|
|
@@ -8834,14 +9404,27 @@ var TOOLBAR_LABEL = {
|
|
|
8834
9404
|
underline: "U",
|
|
8835
9405
|
strikethrough: "S",
|
|
8836
9406
|
code: "<>",
|
|
8837
|
-
heading: "
|
|
9407
|
+
"heading-1": "H1",
|
|
9408
|
+
"heading-2": "H2",
|
|
9409
|
+
"heading-3": "H3",
|
|
8838
9410
|
list: "\u2022",
|
|
8839
9411
|
"ordered-list": "1.",
|
|
8840
9412
|
blockquote: "\u275D",
|
|
8841
9413
|
"code-block": "[ ]",
|
|
8842
9414
|
link: "\u{1F517}",
|
|
8843
9415
|
image: "\u{1F5BC}",
|
|
8844
|
-
divider: "\u2014"
|
|
9416
|
+
divider: "\u2014",
|
|
9417
|
+
checklist: "\u2611",
|
|
9418
|
+
"align-left": "\u21E4",
|
|
9419
|
+
"align-center": "\u2194",
|
|
9420
|
+
"align-right": "\u21E5",
|
|
9421
|
+
highlight: "\u{1F58D}",
|
|
9422
|
+
superscript: "x\xB2",
|
|
9423
|
+
subscript: "x\u2082",
|
|
9424
|
+
table: "\u25A6",
|
|
9425
|
+
"clear-format": "\u232B",
|
|
9426
|
+
undo: "\u21B6",
|
|
9427
|
+
redo: "\u21B7"
|
|
8845
9428
|
};
|
|
8846
9429
|
var TOOLBAR_TITLE = {
|
|
8847
9430
|
bold: "\uAD75\uAC8C (\u2318B)",
|
|
@@ -8849,36 +9432,74 @@ var TOOLBAR_TITLE = {
|
|
|
8849
9432
|
underline: "\uBC11\uC904 (\u2318U)",
|
|
8850
9433
|
strikethrough: "\uCDE8\uC18C\uC120",
|
|
8851
9434
|
code: "\uC778\uB77C\uC778 \uCF54\uB4DC",
|
|
8852
|
-
heading: "\uC81C\uBAA9",
|
|
9435
|
+
"heading-1": "\uC81C\uBAA9 1",
|
|
9436
|
+
"heading-2": "\uC81C\uBAA9 2",
|
|
9437
|
+
"heading-3": "\uC81C\uBAA9 3",
|
|
8853
9438
|
list: "\uAE00\uBA38\uB9AC \uAE30\uD638 \uBAA9\uB85D",
|
|
8854
9439
|
"ordered-list": "\uBC88\uD638 \uB9E4\uAE30\uAE30 \uBAA9\uB85D",
|
|
8855
9440
|
blockquote: "\uC778\uC6A9",
|
|
8856
9441
|
"code-block": "\uCF54\uB4DC \uBE14\uB85D",
|
|
8857
9442
|
link: "\uB9C1\uD06C (\u2318K)",
|
|
8858
9443
|
image: "\uC774\uBBF8\uC9C0",
|
|
8859
|
-
divider: "\uAD6C\uBD84\uC120"
|
|
9444
|
+
divider: "\uAD6C\uBD84\uC120",
|
|
9445
|
+
checklist: "\uCCB4\uD06C\uB9AC\uC2A4\uD2B8",
|
|
9446
|
+
"align-left": "\uC67C\uCABD \uC815\uB82C",
|
|
9447
|
+
"align-center": "\uAC00\uC6B4\uB370 \uC815\uB82C",
|
|
9448
|
+
"align-right": "\uC624\uB978\uCABD \uC815\uB82C",
|
|
9449
|
+
highlight: "\uD615\uAD11\uD39C",
|
|
9450
|
+
superscript: "\uC704 \uCCA8\uC790",
|
|
9451
|
+
subscript: "\uC544\uB798 \uCCA8\uC790",
|
|
9452
|
+
table: "\uD45C \uC0BD\uC785",
|
|
9453
|
+
"clear-format": "\uC11C\uC2DD \uC9C0\uC6B0\uAE30",
|
|
9454
|
+
undo: "\uB418\uB3CC\uB9AC\uAE30 (\u2318Z)",
|
|
9455
|
+
redo: "\uB2E4\uC2DC\uD558\uAE30 (\u2318\u21E7Z)"
|
|
8860
9456
|
};
|
|
8861
9457
|
var isActive = (item, active) => {
|
|
8862
|
-
if (item === "heading") return active.has("block:h1")
|
|
9458
|
+
if (item === "heading-1") return active.has("block:h1");
|
|
9459
|
+
if (item === "heading-2") return active.has("block:h2");
|
|
9460
|
+
if (item === "heading-3") return active.has("block:h3");
|
|
8863
9461
|
if (item === "blockquote") return active.has("block:blockquote");
|
|
8864
9462
|
if (item === "code-block") return active.has("block:pre");
|
|
9463
|
+
if (item === "align-left") return active.has("align:left");
|
|
9464
|
+
if (item === "align-center") return active.has("align:center");
|
|
9465
|
+
if (item === "align-right") return active.has("align:right");
|
|
8865
9466
|
return active.has(item);
|
|
8866
9467
|
};
|
|
8867
|
-
var EditorToolbar = ({
|
|
8868
|
-
|
|
8869
|
-
|
|
8870
|
-
|
|
8871
|
-
|
|
8872
|
-
|
|
8873
|
-
|
|
8874
|
-
|
|
8875
|
-
|
|
8876
|
-
|
|
9468
|
+
var EditorToolbar = ({
|
|
9469
|
+
items,
|
|
9470
|
+
active,
|
|
9471
|
+
onAction,
|
|
9472
|
+
codeLang,
|
|
9473
|
+
inCodeBlock,
|
|
9474
|
+
onCodeLangChange
|
|
9475
|
+
}) => {
|
|
9476
|
+
return /* @__PURE__ */ jsxs207("div", { className: "lib-xplat-editor__toolbar", children: [
|
|
9477
|
+
items.map((item) => /* @__PURE__ */ jsx323(
|
|
9478
|
+
"button",
|
|
9479
|
+
{
|
|
9480
|
+
type: "button",
|
|
9481
|
+
className: clsx_default("lib-xplat-editor__toolbar-btn", isActive(item, active) && "active"),
|
|
9482
|
+
title: TOOLBAR_TITLE[item],
|
|
9483
|
+
onMouseDown: (e) => {
|
|
9484
|
+
e.preventDefault();
|
|
9485
|
+
onAction(item);
|
|
9486
|
+
},
|
|
9487
|
+
children: TOOLBAR_LABEL[item]
|
|
8877
9488
|
},
|
|
8878
|
-
|
|
8879
|
-
|
|
8880
|
-
|
|
8881
|
-
|
|
9489
|
+
item
|
|
9490
|
+
)),
|
|
9491
|
+
inCodeBlock && /* @__PURE__ */ jsx323(
|
|
9492
|
+
"select",
|
|
9493
|
+
{
|
|
9494
|
+
className: "lib-xplat-editor__lang",
|
|
9495
|
+
value: codeLang,
|
|
9496
|
+
"aria-label": "\uCF54\uB4DC \uC5B8\uC5B4",
|
|
9497
|
+
onMouseDown: (e) => e.stopPropagation(),
|
|
9498
|
+
onChange: (e) => onCodeLangChange(e.target.value),
|
|
9499
|
+
children: CODE_LANGUAGES.map((l) => /* @__PURE__ */ jsx323("option", { value: l.value, children: l.label }, l.value))
|
|
9500
|
+
}
|
|
9501
|
+
)
|
|
9502
|
+
] });
|
|
8882
9503
|
};
|
|
8883
9504
|
var SlashMenu = ({ position, items, activeIndex, onSelect, onClose }) => {
|
|
8884
9505
|
React22.useEffect(() => {
|
|
@@ -8982,10 +9603,13 @@ var FileUpload = (props) => {
|
|
|
8982
9603
|
multiple = false,
|
|
8983
9604
|
maxSize,
|
|
8984
9605
|
onChange,
|
|
8985
|
-
|
|
9606
|
+
placeholder = "\uD30C\uC77C\uC744 \uB4DC\uB798\uADF8\uD558\uAC70\uB098 \uD074\uB9AD\uD558\uC5EC \uC5C5\uB85C\uB4DC",
|
|
8986
9607
|
description,
|
|
8987
|
-
validations
|
|
9608
|
+
validations,
|
|
9609
|
+
label,
|
|
9610
|
+
required
|
|
8988
9611
|
} = props;
|
|
9612
|
+
const fieldId = React23.useId();
|
|
8989
9613
|
const [isDragOver, setIsDragOver] = React23.useState(false);
|
|
8990
9614
|
const inputRef = React23.useRef(null);
|
|
8991
9615
|
const handleFiles = (fileList) => {
|
|
@@ -9030,6 +9654,7 @@ var FileUpload = (props) => {
|
|
|
9030
9654
|
"input",
|
|
9031
9655
|
{
|
|
9032
9656
|
ref: inputRef,
|
|
9657
|
+
id: fieldId,
|
|
9033
9658
|
type: "file",
|
|
9034
9659
|
accept,
|
|
9035
9660
|
multiple,
|
|
@@ -9038,12 +9663,12 @@ var FileUpload = (props) => {
|
|
|
9038
9663
|
}
|
|
9039
9664
|
),
|
|
9040
9665
|
/* @__PURE__ */ jsx325("div", { className: "upload-icon", children: /* @__PURE__ */ jsx325(UploadIcon_default, {}) }),
|
|
9041
|
-
/* @__PURE__ */ jsx325("p", { className: "upload-label", children:
|
|
9666
|
+
/* @__PURE__ */ jsx325("p", { className: "upload-label", children: placeholder }),
|
|
9042
9667
|
description && /* @__PURE__ */ jsx325("p", { className: "upload-description", children: description })
|
|
9043
9668
|
]
|
|
9044
9669
|
}
|
|
9045
9670
|
);
|
|
9046
|
-
return /* @__PURE__ */ jsx325(Field, { validations, children: control });
|
|
9671
|
+
return /* @__PURE__ */ jsx325(Field, { label, required, htmlFor: fieldId, validations, children: control });
|
|
9047
9672
|
};
|
|
9048
9673
|
FileUpload.displayName = "FileUpload";
|
|
9049
9674
|
var FileUpload_default = FileUpload;
|
|
@@ -9186,7 +9811,8 @@ var HtmlTypeWriter_default = HtmlTypeWriter;
|
|
|
9186
9811
|
import React26 from "react";
|
|
9187
9812
|
import { jsx as jsx327, jsxs as jsxs210 } from "react/jsx-runtime";
|
|
9188
9813
|
var ImageSelector = (props) => {
|
|
9189
|
-
const { value,
|
|
9814
|
+
const { value, placeholder, onChange, validations, label, required } = props;
|
|
9815
|
+
const fieldId = React26.useId();
|
|
9190
9816
|
const [previewUrl, setPreviewUrl] = React26.useState();
|
|
9191
9817
|
React26.useEffect(() => {
|
|
9192
9818
|
if (!value) {
|
|
@@ -9216,7 +9842,7 @@ var ImageSelector = (props) => {
|
|
|
9216
9842
|
{
|
|
9217
9843
|
type: "file",
|
|
9218
9844
|
accept: "image/*",
|
|
9219
|
-
id:
|
|
9845
|
+
id: fieldId,
|
|
9220
9846
|
onChange: handleFileChange,
|
|
9221
9847
|
ref: inputRef,
|
|
9222
9848
|
"aria-invalid": hasError(validations) || void 0
|
|
@@ -9228,10 +9854,10 @@ var ImageSelector = (props) => {
|
|
|
9228
9854
|
] }),
|
|
9229
9855
|
/* @__PURE__ */ jsx327("div", { className: "content", children: previewUrl ? /* @__PURE__ */ jsx327("img", { src: previewUrl, alt: "preview" }) : /* @__PURE__ */ jsxs210("div", { className: "skeleton", onClick: handleOpenFileDialog, children: [
|
|
9230
9856
|
/* @__PURE__ */ jsx327("div", { className: "icon-wrapper", children: /* @__PURE__ */ jsx327(ImageIcon_default, {}) }),
|
|
9231
|
-
/* @__PURE__ */ jsx327("div", { className: "label", children:
|
|
9857
|
+
/* @__PURE__ */ jsx327("div", { className: "label", children: placeholder || "\uC774\uBBF8\uC9C0 \uCD94\uAC00\uD558\uAE30" })
|
|
9232
9858
|
] }) })
|
|
9233
9859
|
] });
|
|
9234
|
-
return /* @__PURE__ */ jsx327(Field, { validations, children: control });
|
|
9860
|
+
return /* @__PURE__ */ jsx327(Field, { label, required, htmlFor: fieldId, validations, children: control });
|
|
9235
9861
|
};
|
|
9236
9862
|
ImageSelector.displayName = "ImageSelector";
|
|
9237
9863
|
var ImageSelector_default = ImageSelector;
|
|
@@ -9423,6 +10049,7 @@ var PopOver = (props) => {
|
|
|
9423
10049
|
className: clsx_default(
|
|
9424
10050
|
"lib-xplat-pop-over-content",
|
|
9425
10051
|
position.direction,
|
|
10052
|
+
position.repositioning && "repositioning",
|
|
9426
10053
|
eventTrigger && "visible"
|
|
9427
10054
|
),
|
|
9428
10055
|
ref: popRef,
|
|
@@ -9769,7 +10396,7 @@ var SelectRoot = (props) => {
|
|
|
9769
10396
|
mounted && /* @__PURE__ */ jsx337(Portal_default, { children: /* @__PURE__ */ jsxs216(
|
|
9770
10397
|
"div",
|
|
9771
10398
|
{
|
|
9772
|
-
className: clsx_default("lib-xplat-select-content", size, position.direction, stateClass),
|
|
10399
|
+
className: clsx_default("lib-xplat-select-content", size, position.direction, stateClass, position.repositioning && "repositioning"),
|
|
9773
10400
|
ref: contentRef,
|
|
9774
10401
|
style: { ...position.position, width: triggerRef.current?.offsetWidth },
|
|
9775
10402
|
role: "listbox",
|
|
@@ -10662,7 +11289,7 @@ var TimePicker = (props) => {
|
|
|
10662
11289
|
"div",
|
|
10663
11290
|
{
|
|
10664
11291
|
ref: contentRef,
|
|
10665
|
-
className: clsx_default("lib-xplat-time-picker-content", size, visible ? "enter" : "exit"),
|
|
11292
|
+
className: clsx_default("lib-xplat-time-picker-content", size, visible ? "enter" : "exit", position.repositioning && "repositioning"),
|
|
10666
11293
|
style: { ...position.position, width: triggerRef.current?.offsetWidth },
|
|
10667
11294
|
role: "listbox",
|
|
10668
11295
|
children: options.map((t) => /* @__PURE__ */ jsx351(
|