@casualoffice/sheets 0.12.0 → 0.14.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/chrome.cjs +1568 -283
- package/dist/chrome.cjs.map +1 -1
- package/dist/chrome.d.cts +35 -2
- package/dist/chrome.d.ts +35 -2
- package/dist/chrome.js +1566 -291
- package/dist/chrome.js.map +1 -1
- package/dist/embed/embed-runtime.js +131 -131
- package/dist/embed.cjs +3 -3
- package/dist/embed.cjs.map +1 -1
- package/dist/embed.js +3 -3
- package/dist/embed.js.map +1 -1
- package/dist/index.cjs +3 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/chrome/MenuBar.tsx +1246 -104
- package/src/chrome/Toolbar.tsx +546 -216
- package/src/embed/EmbedTransport.ts +3 -3
- package/src/embed-runtime/index.tsx +71 -21
package/dist/chrome.js
CHANGED
|
@@ -526,7 +526,7 @@ function AutoSumPicker({ api }) {
|
|
|
526
526
|
}
|
|
527
527
|
|
|
528
528
|
// src/chrome/Toolbar.tsx
|
|
529
|
-
import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
529
|
+
import { Fragment, jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
530
530
|
var NO_STYLE = {
|
|
531
531
|
bold: false,
|
|
532
532
|
italic: false,
|
|
@@ -536,7 +536,8 @@ var NO_STYLE = {
|
|
|
536
536
|
vt: 0,
|
|
537
537
|
tb: 0,
|
|
538
538
|
ff: "",
|
|
539
|
-
fs: 0
|
|
539
|
+
fs: 0,
|
|
540
|
+
nf: ""
|
|
540
541
|
};
|
|
541
542
|
function readActiveStyle(api) {
|
|
542
543
|
const sel = api.getSelection();
|
|
@@ -553,138 +554,236 @@ function readActiveStyle(api) {
|
|
|
553
554
|
vt: typeof s?.vt === "number" ? s.vt : 0,
|
|
554
555
|
tb: typeof s?.tb === "number" ? s.tb : 0,
|
|
555
556
|
ff: typeof s?.ff === "string" ? s.ff : "",
|
|
556
|
-
fs: typeof s?.fs === "number" ? s.fs : 0
|
|
557
|
+
fs: typeof s?.fs === "number" ? s.fs : 0,
|
|
558
|
+
nf: typeof s?.n?.pattern === "string" ? s.n.pattern : ""
|
|
557
559
|
};
|
|
558
560
|
}
|
|
559
|
-
var FONT_FAMILIES = [
|
|
560
|
-
|
|
561
|
+
var FONT_FAMILIES = [
|
|
562
|
+
"Calibri",
|
|
563
|
+
"Arial",
|
|
564
|
+
"Helvetica",
|
|
565
|
+
"Inter",
|
|
566
|
+
"Times New Roman",
|
|
567
|
+
"Georgia",
|
|
568
|
+
"Verdana",
|
|
569
|
+
"Courier New",
|
|
570
|
+
"JetBrains Mono"
|
|
571
|
+
];
|
|
572
|
+
var FONT_SIZES = [8, 9, 10, 11, 12, 14, 16, 18, 20, 24, 28, 32, 36, 48, 72];
|
|
573
|
+
var NUMBER_FORMAT_PATTERNS = {
|
|
574
|
+
general: "",
|
|
575
|
+
integer: "#,##0",
|
|
576
|
+
number: "#,##0.00",
|
|
577
|
+
currency: '"$"#,##0.00',
|
|
578
|
+
accounting: '_("$"* #,##0.00_);_("$"* (#,##0.00);_("$"* "-"??_);_(@_)',
|
|
579
|
+
percent: "0.00%",
|
|
580
|
+
date: "yyyy-mm-dd",
|
|
581
|
+
time: "hh:mm:ss",
|
|
582
|
+
scientific: "0.00E+00",
|
|
583
|
+
text: "@"
|
|
584
|
+
};
|
|
585
|
+
var NUMBER_FORMAT_OPTIONS = [
|
|
586
|
+
{ value: "general", label: "General" },
|
|
587
|
+
{ value: "integer", label: "Number (no decimals)" },
|
|
588
|
+
{ value: "number", label: "Number (2 decimals)" },
|
|
589
|
+
{ value: "currency", label: "Currency" },
|
|
590
|
+
{ value: "accounting", label: "Accounting" },
|
|
591
|
+
{ value: "percent", label: "Percent" },
|
|
592
|
+
{ value: "date", label: "Date (yyyy-mm-dd)" },
|
|
593
|
+
{ value: "time", label: "Time (hh:mm:ss)" },
|
|
594
|
+
{ value: "scientific", label: "Scientific" },
|
|
595
|
+
{ value: "text", label: "Text" }
|
|
596
|
+
];
|
|
597
|
+
function detectFormatKey(pattern) {
|
|
598
|
+
for (const k of Object.keys(NUMBER_FORMAT_PATTERNS)) {
|
|
599
|
+
if (NUMBER_FORMAT_PATTERNS[k] === pattern) return k;
|
|
600
|
+
}
|
|
601
|
+
return "general";
|
|
602
|
+
}
|
|
561
603
|
var GROUPS = [
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
icon: "
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
604
|
+
{
|
|
605
|
+
feature: "history",
|
|
606
|
+
actions: [
|
|
607
|
+
{ id: "undo", label: "Undo (Ctrl+Z)", command: "univer.command.undo", icon: "undo" },
|
|
608
|
+
{ id: "redo", label: "Redo (Ctrl+Y)", command: "univer.command.redo", icon: "redo" }
|
|
609
|
+
]
|
|
610
|
+
},
|
|
611
|
+
{
|
|
612
|
+
feature: "clipboard",
|
|
613
|
+
actions: [
|
|
614
|
+
{
|
|
615
|
+
id: "paste",
|
|
616
|
+
label: "Paste (Ctrl+V)",
|
|
617
|
+
command: "univer.command.paste",
|
|
618
|
+
icon: "content_paste"
|
|
619
|
+
},
|
|
620
|
+
{ id: "cut", label: "Cut (Ctrl+X)", command: "univer.command.cut", icon: "content_cut" },
|
|
621
|
+
{ id: "copy", label: "Copy (Ctrl+C)", command: "univer.command.copy", icon: "content_copy" },
|
|
622
|
+
{
|
|
623
|
+
id: "paste-values",
|
|
624
|
+
label: "Paste values only",
|
|
625
|
+
command: "univer.command.paste",
|
|
626
|
+
icon: "content_paste_go",
|
|
627
|
+
params: { value: "special-paste-value" }
|
|
628
|
+
}
|
|
629
|
+
]
|
|
630
|
+
},
|
|
631
|
+
{
|
|
632
|
+
feature: "format-painter",
|
|
633
|
+
actions: [
|
|
634
|
+
{
|
|
635
|
+
id: "format-painter",
|
|
636
|
+
label: "Format Painter",
|
|
637
|
+
command: "sheet.command.set-once-format-painter",
|
|
638
|
+
icon: "format_paint"
|
|
639
|
+
}
|
|
640
|
+
]
|
|
641
|
+
},
|
|
642
|
+
{
|
|
643
|
+
feature: "font-style",
|
|
644
|
+
actions: [
|
|
645
|
+
{
|
|
646
|
+
id: "bold",
|
|
647
|
+
label: "Bold (Ctrl+B)",
|
|
648
|
+
command: "sheet.command.set-range-bold",
|
|
649
|
+
icon: "format_bold"
|
|
650
|
+
},
|
|
651
|
+
{
|
|
652
|
+
id: "italic",
|
|
653
|
+
label: "Italic (Ctrl+I)",
|
|
654
|
+
command: "sheet.command.set-range-italic",
|
|
655
|
+
icon: "format_italic"
|
|
656
|
+
},
|
|
657
|
+
{
|
|
658
|
+
id: "underline",
|
|
659
|
+
label: "Underline (Ctrl+U)",
|
|
660
|
+
command: "sheet.command.set-range-underline",
|
|
661
|
+
icon: "format_underlined"
|
|
662
|
+
},
|
|
663
|
+
{
|
|
664
|
+
id: "strikethrough",
|
|
665
|
+
label: "Strikethrough",
|
|
666
|
+
command: "sheet.command.set-range-stroke",
|
|
667
|
+
icon: "format_strikethrough"
|
|
668
|
+
}
|
|
669
|
+
]
|
|
670
|
+
},
|
|
671
|
+
{
|
|
672
|
+
feature: "alignment",
|
|
673
|
+
actions: [
|
|
674
|
+
{
|
|
675
|
+
id: "align-left",
|
|
676
|
+
label: "Align left",
|
|
677
|
+
command: "sheet.command.set-horizontal-text-align",
|
|
678
|
+
icon: "format_align_left",
|
|
679
|
+
params: { value: 1 }
|
|
680
|
+
},
|
|
681
|
+
{
|
|
682
|
+
id: "align-center",
|
|
683
|
+
label: "Align center",
|
|
684
|
+
command: "sheet.command.set-horizontal-text-align",
|
|
685
|
+
icon: "format_align_center",
|
|
686
|
+
params: { value: 2 }
|
|
687
|
+
},
|
|
688
|
+
{
|
|
689
|
+
id: "align-right",
|
|
690
|
+
label: "Align right",
|
|
691
|
+
command: "sheet.command.set-horizontal-text-align",
|
|
692
|
+
icon: "format_align_right",
|
|
693
|
+
params: { value: 3 }
|
|
694
|
+
},
|
|
695
|
+
{
|
|
696
|
+
id: "wrap-text",
|
|
697
|
+
label: "Wrap text",
|
|
698
|
+
command: "sheet.command.set-text-wrap",
|
|
699
|
+
icon: "wrap_text",
|
|
700
|
+
params: { value: 3 }
|
|
701
|
+
}
|
|
702
|
+
]
|
|
703
|
+
},
|
|
704
|
+
{
|
|
705
|
+
feature: "alignment",
|
|
706
|
+
actions: [
|
|
707
|
+
{
|
|
708
|
+
id: "align-top",
|
|
709
|
+
label: "Align top",
|
|
710
|
+
command: "sheet.command.set-vertical-text-align",
|
|
711
|
+
icon: "vertical_align_top",
|
|
712
|
+
params: { value: 1 }
|
|
713
|
+
},
|
|
714
|
+
{
|
|
715
|
+
id: "align-middle",
|
|
716
|
+
label: "Align middle",
|
|
717
|
+
command: "sheet.command.set-vertical-text-align",
|
|
718
|
+
icon: "vertical_align_center",
|
|
719
|
+
params: { value: 2 }
|
|
720
|
+
},
|
|
721
|
+
{
|
|
722
|
+
id: "align-bottom",
|
|
723
|
+
label: "Align bottom",
|
|
724
|
+
command: "sheet.command.set-vertical-text-align",
|
|
725
|
+
icon: "vertical_align_bottom",
|
|
726
|
+
params: { value: 3 }
|
|
727
|
+
}
|
|
728
|
+
]
|
|
729
|
+
},
|
|
730
|
+
{
|
|
731
|
+
feature: "merge",
|
|
732
|
+
actions: [
|
|
733
|
+
{
|
|
734
|
+
id: "merge",
|
|
735
|
+
label: "Merge cells",
|
|
736
|
+
command: "sheet.command.add-worksheet-merge-all",
|
|
737
|
+
icon: "cell_merge"
|
|
738
|
+
},
|
|
739
|
+
{
|
|
740
|
+
id: "unmerge",
|
|
741
|
+
label: "Unmerge cells",
|
|
742
|
+
command: "sheet.command.remove-worksheet-merge",
|
|
743
|
+
icon: "splitscreen_vertical_add"
|
|
744
|
+
}
|
|
745
|
+
]
|
|
746
|
+
},
|
|
747
|
+
{
|
|
748
|
+
feature: "number",
|
|
749
|
+
actions: [
|
|
750
|
+
{
|
|
751
|
+
id: "currency",
|
|
752
|
+
label: "Currency format",
|
|
753
|
+
command: "sheet.command.numfmt.set.currency",
|
|
754
|
+
icon: "attach_money"
|
|
755
|
+
},
|
|
756
|
+
{
|
|
757
|
+
id: "percent",
|
|
758
|
+
label: "Percent format",
|
|
759
|
+
command: "sheet.command.numfmt.set.percent",
|
|
760
|
+
icon: "percent"
|
|
761
|
+
},
|
|
762
|
+
{
|
|
763
|
+
id: "decimal-increase",
|
|
764
|
+
label: "Increase decimals",
|
|
765
|
+
command: "sheet.command.numfmt.add.decimal.command",
|
|
766
|
+
icon: "decimal_increase"
|
|
767
|
+
},
|
|
768
|
+
{
|
|
769
|
+
id: "decimal-decrease",
|
|
770
|
+
label: "Decrease decimals",
|
|
771
|
+
command: "sheet.command.numfmt.subtract.decimal.command",
|
|
772
|
+
icon: "decimal_decrease"
|
|
773
|
+
}
|
|
774
|
+
]
|
|
775
|
+
},
|
|
776
|
+
{
|
|
777
|
+
feature: "clear-format",
|
|
778
|
+
actions: [
|
|
779
|
+
{
|
|
780
|
+
id: "clear-format",
|
|
781
|
+
label: "Clear formatting",
|
|
782
|
+
command: "sheet.command.clear-selection-format",
|
|
783
|
+
icon: "format_clear"
|
|
784
|
+
}
|
|
785
|
+
]
|
|
786
|
+
}
|
|
688
787
|
];
|
|
689
788
|
var BAR_STYLE = {
|
|
690
789
|
display: "flex",
|
|
@@ -694,7 +793,8 @@ var BAR_STYLE = {
|
|
|
694
793
|
borderBottom: "1px solid var(--cs-chrome-border, #e6e9ee)",
|
|
695
794
|
background: "var(--cs-chrome-bg, #eef1f5)",
|
|
696
795
|
flex: "0 0 auto",
|
|
697
|
-
userSelect: "none"
|
|
796
|
+
userSelect: "none",
|
|
797
|
+
flexWrap: "wrap"
|
|
698
798
|
};
|
|
699
799
|
var BTN_STYLE4 = {
|
|
700
800
|
width: 30,
|
|
@@ -727,6 +827,9 @@ var SELECT_STYLE = {
|
|
|
727
827
|
padding: "0 4px",
|
|
728
828
|
cursor: "pointer"
|
|
729
829
|
};
|
|
830
|
+
function enabled(features, key) {
|
|
831
|
+
return features?.[key] !== false;
|
|
832
|
+
}
|
|
730
833
|
function isActive(id, s) {
|
|
731
834
|
switch (id) {
|
|
732
835
|
case "bold":
|
|
@@ -755,7 +858,7 @@ function isActive(id, s) {
|
|
|
755
858
|
return false;
|
|
756
859
|
}
|
|
757
860
|
}
|
|
758
|
-
function Toolbar({ api }) {
|
|
861
|
+
function Toolbar({ api, features, onDialogRequest }) {
|
|
759
862
|
const [active, setActive] = useState4(NO_STYLE);
|
|
760
863
|
useEffect4(() => {
|
|
761
864
|
ensureChromeFonts();
|
|
@@ -770,75 +873,194 @@ function Toolbar({ api }) {
|
|
|
770
873
|
return () => sub?.dispose();
|
|
771
874
|
}, [api]);
|
|
772
875
|
const dispatch = (command, params) => void api?.executeCommand(command, params);
|
|
773
|
-
const
|
|
876
|
+
const applyFontSize = (size) => {
|
|
877
|
+
if (!Number.isFinite(size) || size <= 0) return;
|
|
878
|
+
dispatch("sheet.command.set-range-fontsize", { value: size });
|
|
879
|
+
};
|
|
880
|
+
const adjustFontSize = (delta) => {
|
|
881
|
+
const current = active.fs && active.fs > 0 ? active.fs : 11;
|
|
882
|
+
const next = Math.max(6, Math.min(72, current + delta));
|
|
883
|
+
if (next === current) return;
|
|
884
|
+
applyFontSize(next);
|
|
885
|
+
};
|
|
886
|
+
const applyNumberFormat = (pattern) => {
|
|
887
|
+
const sheet = api?.univer.getActiveWorkbook()?.getActiveSheet();
|
|
888
|
+
const range = sheet?.getActiveRange?.();
|
|
889
|
+
range?.setNumberFormat?.(pattern);
|
|
890
|
+
};
|
|
891
|
+
const familyValue = active.ff || "Calibri";
|
|
774
892
|
const familyOptions = active.ff && !FONT_FAMILIES.includes(active.ff) ? [active.ff, ...FONT_FAMILIES] : FONT_FAMILIES;
|
|
775
893
|
const sizeValue = active.fs || 11;
|
|
776
894
|
const sizeOptions = active.fs && !FONT_SIZES.includes(active.fs) ? [active.fs, ...FONT_SIZES] : FONT_SIZES;
|
|
895
|
+
const numberFormatValue = detectFormatKey(active.nf);
|
|
896
|
+
const renderActionButton = (a) => {
|
|
897
|
+
const on = isActive(a.id, active);
|
|
898
|
+
const baseBg = on ? "var(--cs-chrome-active, #e6f3f7)" : "transparent";
|
|
899
|
+
return /* @__PURE__ */ jsx5(
|
|
900
|
+
"button",
|
|
901
|
+
{
|
|
902
|
+
type: "button",
|
|
903
|
+
title: a.label,
|
|
904
|
+
"aria-label": a.label,
|
|
905
|
+
"aria-pressed": on,
|
|
906
|
+
"data-action": a.id,
|
|
907
|
+
"data-testid": `cs-${a.id}`,
|
|
908
|
+
"data-active": on ? "true" : void 0,
|
|
909
|
+
disabled: !api,
|
|
910
|
+
style: {
|
|
911
|
+
...BTN_STYLE4,
|
|
912
|
+
background: baseBg,
|
|
913
|
+
color: on ? "var(--cs-chrome-active-fg, #0e7490)" : BTN_STYLE4.color
|
|
914
|
+
},
|
|
915
|
+
onMouseDown: (e) => {
|
|
916
|
+
e.preventDefault();
|
|
917
|
+
dispatch(a.command, a.params);
|
|
918
|
+
},
|
|
919
|
+
onMouseEnter: (e) => {
|
|
920
|
+
if (!on) e.currentTarget.style.background = "var(--cs-chrome-hover, rgba(0,0,0,0.06))";
|
|
921
|
+
},
|
|
922
|
+
onMouseLeave: (e) => {
|
|
923
|
+
e.currentTarget.style.background = baseBg;
|
|
924
|
+
},
|
|
925
|
+
children: /* @__PURE__ */ jsx5(Icon, { name: a.icon, size: 20 })
|
|
926
|
+
},
|
|
927
|
+
a.id
|
|
928
|
+
);
|
|
929
|
+
};
|
|
930
|
+
const renderIconButton = (id, label, icon, onPress, testid) => /* @__PURE__ */ jsx5(
|
|
931
|
+
"button",
|
|
932
|
+
{
|
|
933
|
+
type: "button",
|
|
934
|
+
title: label,
|
|
935
|
+
"aria-label": label,
|
|
936
|
+
"data-action": id,
|
|
937
|
+
"data-testid": testid,
|
|
938
|
+
disabled: !api,
|
|
939
|
+
style: BTN_STYLE4,
|
|
940
|
+
onMouseDown: (e) => {
|
|
941
|
+
e.preventDefault();
|
|
942
|
+
onPress();
|
|
943
|
+
},
|
|
944
|
+
onMouseEnter: (e) => {
|
|
945
|
+
e.currentTarget.style.background = "var(--cs-chrome-hover, rgba(0,0,0,0.06))";
|
|
946
|
+
},
|
|
947
|
+
onMouseLeave: (e) => {
|
|
948
|
+
e.currentTarget.style.background = "transparent";
|
|
949
|
+
},
|
|
950
|
+
children: /* @__PURE__ */ jsx5(Icon, { name: icon, size: 20 })
|
|
951
|
+
},
|
|
952
|
+
id
|
|
953
|
+
);
|
|
954
|
+
let firstGroupRendered = false;
|
|
955
|
+
const groupNodes = GROUPS.map((group, gi) => {
|
|
956
|
+
if (!enabled(features, group.feature)) return null;
|
|
957
|
+
const visible = group.actions.filter((a) => enabled(features, a.feature ?? group.feature));
|
|
958
|
+
if (visible.length === 0) return null;
|
|
959
|
+
const showDivider = firstGroupRendered;
|
|
960
|
+
firstGroupRendered = true;
|
|
961
|
+
return /* @__PURE__ */ jsxs4("span", { style: { display: "inline-flex", alignItems: "center" }, children: [
|
|
962
|
+
showDivider && /* @__PURE__ */ jsx5("span", { style: DIVIDER_STYLE, "aria-hidden": true }),
|
|
963
|
+
visible.map(renderActionButton)
|
|
964
|
+
] }, gi);
|
|
965
|
+
});
|
|
966
|
+
const showFont = enabled(features, "font");
|
|
967
|
+
const showColor = enabled(features, "color");
|
|
968
|
+
const showBorders = enabled(features, "borders");
|
|
969
|
+
const showAutoSum = enabled(features, "autosum");
|
|
970
|
+
const showNumberDropdown = enabled(features, "number");
|
|
971
|
+
const showFormatCells = enabled(features, "format-cells") && !!onDialogRequest;
|
|
972
|
+
const showInsertChart = enabled(features, "insert-chart") && !!onDialogRequest;
|
|
973
|
+
const showPivotTable = enabled(features, "pivot-table") && !!onDialogRequest;
|
|
974
|
+
const showDialogGroup = showFormatCells || showInsertChart || showPivotTable;
|
|
777
975
|
return /* @__PURE__ */ jsxs4("div", { style: BAR_STYLE, "data-testid": "casual-sheets-toolbar", role: "toolbar", "aria-label": "Editor", children: [
|
|
778
|
-
/* @__PURE__ */
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
"
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
/* @__PURE__ */
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
976
|
+
showFont && /* @__PURE__ */ jsxs4(Fragment, { children: [
|
|
977
|
+
/* @__PURE__ */ jsx5(
|
|
978
|
+
"select",
|
|
979
|
+
{
|
|
980
|
+
"aria-label": "Font family",
|
|
981
|
+
"data-testid": "cs-font-family",
|
|
982
|
+
style: { ...SELECT_STYLE, width: 130 },
|
|
983
|
+
value: familyValue,
|
|
984
|
+
disabled: !api,
|
|
985
|
+
onChange: (e) => dispatch("sheet.command.set-range-font-family", { value: e.target.value }),
|
|
986
|
+
children: familyOptions.map((f) => /* @__PURE__ */ jsx5("option", { value: f, children: f }, f))
|
|
987
|
+
}
|
|
988
|
+
),
|
|
989
|
+
/* @__PURE__ */ jsx5(
|
|
990
|
+
"select",
|
|
991
|
+
{
|
|
992
|
+
"aria-label": "Font size",
|
|
993
|
+
"data-testid": "cs-font-size",
|
|
994
|
+
style: { ...SELECT_STYLE, width: 56, marginLeft: 4 },
|
|
995
|
+
value: sizeValue,
|
|
996
|
+
disabled: !api,
|
|
997
|
+
onChange: (e) => applyFontSize(Number(e.target.value)),
|
|
998
|
+
children: sizeOptions.map((s) => /* @__PURE__ */ jsx5("option", { value: s, children: s }, s))
|
|
999
|
+
}
|
|
1000
|
+
),
|
|
1001
|
+
renderIconButton(
|
|
1002
|
+
"font-size-up",
|
|
1003
|
+
"Increase font size",
|
|
1004
|
+
"text_increase",
|
|
1005
|
+
() => adjustFontSize(1),
|
|
1006
|
+
"cs-font-size-up"
|
|
1007
|
+
),
|
|
1008
|
+
renderIconButton(
|
|
1009
|
+
"font-size-down",
|
|
1010
|
+
"Decrease font size",
|
|
1011
|
+
"text_decrease",
|
|
1012
|
+
() => adjustFontSize(-1),
|
|
1013
|
+
"cs-font-size-down"
|
|
1014
|
+
),
|
|
1015
|
+
/* @__PURE__ */ jsx5("span", { style: DIVIDER_STYLE, "aria-hidden": true })
|
|
1016
|
+
] }),
|
|
1017
|
+
groupNodes,
|
|
1018
|
+
(showColor || showBorders) && /* @__PURE__ */ jsx5("span", { style: DIVIDER_STYLE, "aria-hidden": true }),
|
|
1019
|
+
showColor && /* @__PURE__ */ jsx5(ColorPicker, { api }),
|
|
1020
|
+
showBorders && /* @__PURE__ */ jsx5(BordersPicker, { api }),
|
|
1021
|
+
showNumberDropdown && /* @__PURE__ */ jsxs4(Fragment, { children: [
|
|
1022
|
+
/* @__PURE__ */ jsx5("span", { style: DIVIDER_STYLE, "aria-hidden": true }),
|
|
1023
|
+
/* @__PURE__ */ jsx5(
|
|
1024
|
+
"select",
|
|
1025
|
+
{
|
|
1026
|
+
"aria-label": "Number format",
|
|
1027
|
+
"data-testid": "cs-number-format",
|
|
1028
|
+
style: { ...SELECT_STYLE, width: 124 },
|
|
1029
|
+
value: numberFormatValue,
|
|
1030
|
+
disabled: !api,
|
|
1031
|
+
onChange: (e) => applyNumberFormat(NUMBER_FORMAT_PATTERNS[e.target.value]),
|
|
1032
|
+
children: NUMBER_FORMAT_OPTIONS.map((o) => /* @__PURE__ */ jsx5("option", { value: o.value, children: o.label }, o.value))
|
|
1033
|
+
}
|
|
1034
|
+
)
|
|
1035
|
+
] }),
|
|
1036
|
+
showAutoSum && /* @__PURE__ */ jsxs4(Fragment, { children: [
|
|
1037
|
+
/* @__PURE__ */ jsx5("span", { style: DIVIDER_STYLE, "aria-hidden": true }),
|
|
1038
|
+
/* @__PURE__ */ jsx5(AutoSumPicker, { api })
|
|
1039
|
+
] }),
|
|
1040
|
+
showDialogGroup && /* @__PURE__ */ jsxs4(Fragment, { children: [
|
|
1041
|
+
/* @__PURE__ */ jsx5("span", { style: DIVIDER_STYLE, "aria-hidden": true }),
|
|
1042
|
+
showFormatCells && renderIconButton(
|
|
1043
|
+
"format-cells",
|
|
1044
|
+
"Format Cells\u2026",
|
|
1045
|
+
"format_shapes",
|
|
1046
|
+
() => onDialogRequest?.("format-cells"),
|
|
1047
|
+
"cs-format-cells"
|
|
1048
|
+
),
|
|
1049
|
+
showInsertChart && renderIconButton(
|
|
1050
|
+
"insert-chart",
|
|
1051
|
+
"Insert chart",
|
|
1052
|
+
"bar_chart",
|
|
1053
|
+
() => onDialogRequest?.("insert-chart"),
|
|
1054
|
+
"cs-insert-chart"
|
|
1055
|
+
),
|
|
1056
|
+
showPivotTable && renderIconButton(
|
|
1057
|
+
"pivot-table",
|
|
1058
|
+
"Insert PivotTable",
|
|
1059
|
+
"pivot_table_chart",
|
|
1060
|
+
() => onDialogRequest?.("pivot-table"),
|
|
1061
|
+
"cs-pivot-table"
|
|
1062
|
+
)
|
|
1063
|
+
] })
|
|
842
1064
|
] });
|
|
843
1065
|
}
|
|
844
1066
|
|
|
@@ -1431,7 +1653,7 @@ function FormulaBar({ api }) {
|
|
|
1431
1653
|
// src/chrome/StatusBar.tsx
|
|
1432
1654
|
import { useEffect as useEffect7, useState as useState7 } from "react";
|
|
1433
1655
|
import { ICommandService as ICommandService4 } from "@univerjs/core";
|
|
1434
|
-
import { Fragment, jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1656
|
+
import { Fragment as Fragment2, jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1435
1657
|
function readStats(api) {
|
|
1436
1658
|
const sel = api.getSelection();
|
|
1437
1659
|
const sheet = api.univer.getActiveWorkbook()?.getActiveSheet();
|
|
@@ -1543,7 +1765,7 @@ function StatusBar({ api }) {
|
|
|
1543
1765
|
const zoomBy = (delta) => setZoomRatio(Math.round((zoom + delta) * 100) / 100);
|
|
1544
1766
|
const resetZoom = () => setZoomRatio(1);
|
|
1545
1767
|
return /* @__PURE__ */ jsxs7("div", { style: BAR_STYLE3, "data-testid": "casual-sheets-status-bar", children: [
|
|
1546
|
-
stats && /* @__PURE__ */ jsxs7(
|
|
1768
|
+
stats && /* @__PURE__ */ jsxs7(Fragment2, { children: [
|
|
1547
1769
|
stats.numCount > 0 && /* @__PURE__ */ jsxs7("span", { "data-stat": "average", children: [
|
|
1548
1770
|
"Average: ",
|
|
1549
1771
|
fmt(stats.avg)
|
|
@@ -1552,7 +1774,7 @@ function StatusBar({ api }) {
|
|
|
1552
1774
|
"Count: ",
|
|
1553
1775
|
stats.count
|
|
1554
1776
|
] }),
|
|
1555
|
-
stats.numCount > 0 && /* @__PURE__ */ jsxs7(
|
|
1777
|
+
stats.numCount > 0 && /* @__PURE__ */ jsxs7(Fragment2, { children: [
|
|
1556
1778
|
/* @__PURE__ */ jsxs7("span", { "data-stat": "num-count", children: [
|
|
1557
1779
|
"Numerical Count: ",
|
|
1558
1780
|
stats.numCount
|
|
@@ -1629,17 +1851,639 @@ function StatusBar({ api }) {
|
|
|
1629
1851
|
|
|
1630
1852
|
// src/chrome/MenuBar.tsx
|
|
1631
1853
|
import { useEffect as useEffect8, useRef as useRef6, useState as useState8 } from "react";
|
|
1854
|
+
import { BorderStyleTypes, BorderType } from "@univerjs/core";
|
|
1855
|
+
|
|
1856
|
+
// src/univer/lazy-plugins.ts
|
|
1857
|
+
var LOADERS = {
|
|
1858
|
+
cf: async () => {
|
|
1859
|
+
const [base, ui] = await Promise.all([
|
|
1860
|
+
import("@univerjs/sheets-conditional-formatting"),
|
|
1861
|
+
import("@univerjs/sheets-conditional-formatting-ui")
|
|
1862
|
+
]);
|
|
1863
|
+
return [
|
|
1864
|
+
[base.UniverSheetsConditionalFormattingPlugin],
|
|
1865
|
+
[ui.UniverSheetsConditionalFormattingUIPlugin]
|
|
1866
|
+
];
|
|
1867
|
+
},
|
|
1868
|
+
dv: async () => {
|
|
1869
|
+
const [base, ui] = await Promise.all([
|
|
1870
|
+
import("@univerjs/sheets-data-validation"),
|
|
1871
|
+
import("@univerjs/sheets-data-validation-ui")
|
|
1872
|
+
]);
|
|
1873
|
+
return [
|
|
1874
|
+
[base.UniverSheetsDataValidationPlugin],
|
|
1875
|
+
[ui.UniverSheetsDataValidationUIPlugin]
|
|
1876
|
+
];
|
|
1877
|
+
},
|
|
1878
|
+
hyperlink: async () => {
|
|
1879
|
+
const [base, ui] = await Promise.all([
|
|
1880
|
+
import("@univerjs/sheets-hyper-link"),
|
|
1881
|
+
import("@univerjs/sheets-hyper-link-ui")
|
|
1882
|
+
]);
|
|
1883
|
+
return [
|
|
1884
|
+
[base.UniverSheetsHyperLinkPlugin],
|
|
1885
|
+
[ui.UniverSheetsHyperLinkUIPlugin]
|
|
1886
|
+
];
|
|
1887
|
+
},
|
|
1888
|
+
note: async () => {
|
|
1889
|
+
const [base, ui] = await Promise.all([
|
|
1890
|
+
import("@univerjs/sheets-note"),
|
|
1891
|
+
import("@univerjs/sheets-note-ui")
|
|
1892
|
+
]);
|
|
1893
|
+
return [[base.UniverSheetsNotePlugin], [ui.UniverSheetsNoteUIPlugin]];
|
|
1894
|
+
},
|
|
1895
|
+
table: async () => {
|
|
1896
|
+
const [base, ui] = await Promise.all([
|
|
1897
|
+
import("@univerjs/sheets-table"),
|
|
1898
|
+
import("@univerjs/sheets-table-ui")
|
|
1899
|
+
]);
|
|
1900
|
+
return [[base.UniverSheetsTablePlugin], [ui.UniverSheetsTableUIPlugin]];
|
|
1901
|
+
},
|
|
1902
|
+
threadComment: async () => {
|
|
1903
|
+
const [tc, tcUi, sheetsTc, sheetsTcUi] = await Promise.all([
|
|
1904
|
+
import("@univerjs/thread-comment"),
|
|
1905
|
+
import("@univerjs/thread-comment-ui"),
|
|
1906
|
+
import("@univerjs/sheets-thread-comment"),
|
|
1907
|
+
import("@univerjs/sheets-thread-comment-ui")
|
|
1908
|
+
]);
|
|
1909
|
+
return [
|
|
1910
|
+
[tc.UniverThreadCommentPlugin],
|
|
1911
|
+
[tcUi.UniverThreadCommentUIPlugin],
|
|
1912
|
+
[sheetsTc.UniverSheetsThreadCommentPlugin],
|
|
1913
|
+
[sheetsTcUi.UniverSheetsThreadCommentUIPlugin]
|
|
1914
|
+
];
|
|
1915
|
+
},
|
|
1916
|
+
drawing: async () => {
|
|
1917
|
+
const [d, dUi, sd, sdUi] = await Promise.all([
|
|
1918
|
+
import("@univerjs/drawing"),
|
|
1919
|
+
import("@univerjs/drawing-ui"),
|
|
1920
|
+
import("@univerjs/sheets-drawing"),
|
|
1921
|
+
import("@univerjs/sheets-drawing-ui"),
|
|
1922
|
+
// Side-effect imports: install FWorksheet.insertImage / getImages /
|
|
1923
|
+
// updateImages on the facade prototype. Without these, code that
|
|
1924
|
+
// reaches in via the FUniver facade (e2e specs, future shell glue)
|
|
1925
|
+
// sees an undefined method even though the plugin is registered.
|
|
1926
|
+
import("@univerjs/sheets-drawing/facade"),
|
|
1927
|
+
import("@univerjs/sheets-drawing-ui/facade")
|
|
1928
|
+
]);
|
|
1929
|
+
return [
|
|
1930
|
+
[d.UniverDrawingPlugin],
|
|
1931
|
+
[dUi.UniverDrawingUIPlugin],
|
|
1932
|
+
[sd.UniverSheetsDrawingPlugin],
|
|
1933
|
+
[sdUi.UniverSheetsDrawingUIPlugin]
|
|
1934
|
+
];
|
|
1935
|
+
},
|
|
1936
|
+
sort: async () => {
|
|
1937
|
+
const [base, ui] = await Promise.all([
|
|
1938
|
+
import("@univerjs/sheets-sort"),
|
|
1939
|
+
import("@univerjs/sheets-sort-ui")
|
|
1940
|
+
]);
|
|
1941
|
+
return [[base.UniverSheetsSortPlugin], [ui.UniverSheetsSortUIPlugin]];
|
|
1942
|
+
},
|
|
1943
|
+
filter: async () => {
|
|
1944
|
+
const [base, ui] = await Promise.all([
|
|
1945
|
+
import("@univerjs/sheets-filter"),
|
|
1946
|
+
import("@univerjs/sheets-filter-ui")
|
|
1947
|
+
]);
|
|
1948
|
+
return [[base.UniverSheetsFilterPlugin], [ui.UniverSheetsFilterUIPlugin]];
|
|
1949
|
+
},
|
|
1950
|
+
findReplace: async () => {
|
|
1951
|
+
const [base, sheets] = await Promise.all([
|
|
1952
|
+
import("@univerjs/find-replace"),
|
|
1953
|
+
import("@univerjs/sheets-find-replace")
|
|
1954
|
+
]);
|
|
1955
|
+
return [[base.UniverFindReplacePlugin], [sheets.UniverSheetsFindReplacePlugin]];
|
|
1956
|
+
}
|
|
1957
|
+
};
|
|
1958
|
+
var loaded = /* @__PURE__ */ new Set();
|
|
1959
|
+
var inflight = /* @__PURE__ */ new Map();
|
|
1960
|
+
var currentUniver = null;
|
|
1961
|
+
function ensurePlugin(univer, group) {
|
|
1962
|
+
if (loaded.has(group)) return Promise.resolve();
|
|
1963
|
+
const existing = inflight.get(group);
|
|
1964
|
+
if (existing) return existing;
|
|
1965
|
+
const loader = LOADERS[group];
|
|
1966
|
+
if (!loader) return Promise.resolve();
|
|
1967
|
+
const p = loader().then((plugins) => {
|
|
1968
|
+
for (const [PluginCtor, config] of plugins) {
|
|
1969
|
+
univer.registerPlugin(PluginCtor, config);
|
|
1970
|
+
}
|
|
1971
|
+
loaded.add(group);
|
|
1972
|
+
inflight.delete(group);
|
|
1973
|
+
});
|
|
1974
|
+
inflight.set(group, p);
|
|
1975
|
+
return p;
|
|
1976
|
+
}
|
|
1977
|
+
function ensurePluginByName(group) {
|
|
1978
|
+
if (loaded.has(group)) return Promise.resolve();
|
|
1979
|
+
if (!currentUniver) return Promise.resolve();
|
|
1980
|
+
return ensurePlugin(currentUniver, group);
|
|
1981
|
+
}
|
|
1982
|
+
|
|
1983
|
+
// src/chrome/MenuBar.tsx
|
|
1632
1984
|
import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1985
|
+
function fmtShortcut(shortcut) {
|
|
1986
|
+
const isMac = typeof navigator !== "undefined" && /Mac|iPhone|iPad/i.test(navigator.platform || "");
|
|
1987
|
+
if (!isMac) return shortcut;
|
|
1988
|
+
return shortcut.split("+").map((part) => {
|
|
1989
|
+
switch (part) {
|
|
1990
|
+
case "Ctrl":
|
|
1991
|
+
return "\u2318";
|
|
1992
|
+
case "Alt":
|
|
1993
|
+
return "\u2325";
|
|
1994
|
+
case "Shift":
|
|
1995
|
+
return "\u21E7";
|
|
1996
|
+
default:
|
|
1997
|
+
return part;
|
|
1998
|
+
}
|
|
1999
|
+
}).join("");
|
|
2000
|
+
}
|
|
2001
|
+
function fu(api) {
|
|
2002
|
+
return api.univer;
|
|
2003
|
+
}
|
|
2004
|
+
function activeRange(api) {
|
|
2005
|
+
return fu(api).getActiveWorkbook()?.getActiveSheet()?.getActiveRange() ?? null;
|
|
2006
|
+
}
|
|
2007
|
+
function activeSheet(api) {
|
|
2008
|
+
return fu(api).getActiveWorkbook()?.getActiveSheet() ?? null;
|
|
2009
|
+
}
|
|
2010
|
+
function selectionA1(api) {
|
|
2011
|
+
const range = activeRange(api);
|
|
2012
|
+
if (!range) return null;
|
|
2013
|
+
try {
|
|
2014
|
+
return range.getA1Notation();
|
|
2015
|
+
} catch {
|
|
2016
|
+
return null;
|
|
2017
|
+
}
|
|
2018
|
+
}
|
|
2019
|
+
var undo = (api) => void api.executeCommand("univer.command.undo");
|
|
2020
|
+
var redo = (api) => void api.executeCommand("univer.command.redo");
|
|
2021
|
+
var cut = (api) => void api.executeCommand("univer.command.cut");
|
|
2022
|
+
var copy = (api) => void api.executeCommand("univer.command.copy");
|
|
2023
|
+
var paste = (api) => void api.executeCommand("univer.command.paste");
|
|
2024
|
+
var pasteFormattingOnly = (api) => void api.executeCommand("sheet.command.paste-format");
|
|
2025
|
+
var insertRowAbove = (api) => {
|
|
2026
|
+
const range = activeRange(api);
|
|
2027
|
+
const sheet = activeSheet(api);
|
|
2028
|
+
if (!range || !sheet) return;
|
|
2029
|
+
sheet.insertRowBefore(range.getRow());
|
|
2030
|
+
};
|
|
2031
|
+
var insertRowBelow = (api) => {
|
|
2032
|
+
const range = activeRange(api);
|
|
2033
|
+
const sheet = activeSheet(api);
|
|
2034
|
+
if (!range || !sheet) return;
|
|
2035
|
+
sheet.insertRowAfter(range.getRow() + range.getHeight() - 1);
|
|
2036
|
+
};
|
|
2037
|
+
var insertColumnLeft = (api) => {
|
|
2038
|
+
const range = activeRange(api);
|
|
2039
|
+
const sheet = activeSheet(api);
|
|
2040
|
+
if (!range || !sheet) return;
|
|
2041
|
+
sheet.insertColumnBefore(range.getColumn());
|
|
2042
|
+
};
|
|
2043
|
+
var insertColumnRight = (api) => {
|
|
2044
|
+
const range = activeRange(api);
|
|
2045
|
+
const sheet = activeSheet(api);
|
|
2046
|
+
if (!range || !sheet) return;
|
|
2047
|
+
sheet.insertColumnAfter(range.getColumn() + range.getWidth() - 1);
|
|
2048
|
+
};
|
|
2049
|
+
var deleteSelectedRow = (api) => {
|
|
2050
|
+
const range = activeRange(api);
|
|
2051
|
+
const sheet = activeSheet(api);
|
|
2052
|
+
if (!range || !sheet) return;
|
|
2053
|
+
sheet.deleteRows(range.getRow(), range.getHeight());
|
|
2054
|
+
};
|
|
2055
|
+
var deleteSelectedColumn = (api) => {
|
|
2056
|
+
const range = activeRange(api);
|
|
2057
|
+
const sheet = activeSheet(api);
|
|
2058
|
+
if (!range || !sheet) return;
|
|
2059
|
+
sheet.deleteColumns(range.getColumn(), range.getWidth());
|
|
2060
|
+
};
|
|
2061
|
+
var insertNewSheet = (api) => {
|
|
2062
|
+
fu(api).getActiveWorkbook()?.insertSheet();
|
|
2063
|
+
};
|
|
2064
|
+
var insertImage = (api) => void api.executeCommand("sheet.command.insert-float-image");
|
|
2065
|
+
var insertHyperlink = (api) => void api.executeCommand("sheet.operation.insert-hyper-link");
|
|
2066
|
+
var insertComment = (api) => void api.executeCommand("sheet.operation.show-comment-modal");
|
|
2067
|
+
var insertTodayDate = (api) => {
|
|
2068
|
+
const range = activeRange(api);
|
|
2069
|
+
if (!range) return;
|
|
2070
|
+
const today = /* @__PURE__ */ new Date();
|
|
2071
|
+
const pad = (n) => n.toString().padStart(2, "0");
|
|
2072
|
+
const v = `${today.getFullYear()}-${pad(today.getMonth() + 1)}-${pad(today.getDate())}`;
|
|
2073
|
+
range.setValue({ v });
|
|
2074
|
+
};
|
|
2075
|
+
var insertCurrentTime = (api) => {
|
|
2076
|
+
const range = activeRange(api);
|
|
2077
|
+
if (!range) return;
|
|
2078
|
+
const now = /* @__PURE__ */ new Date();
|
|
2079
|
+
const pad = (n) => n.toString().padStart(2, "0");
|
|
2080
|
+
const v = `${pad(now.getHours())}:${pad(now.getMinutes())}:${pad(now.getSeconds())}`;
|
|
2081
|
+
range.setValue({ v });
|
|
2082
|
+
};
|
|
2083
|
+
var insertTable = (api) => {
|
|
2084
|
+
void (async () => {
|
|
2085
|
+
const range = activeRange(api);
|
|
2086
|
+
const sheet = activeSheet(api);
|
|
2087
|
+
const wb = fu(api).getActiveWorkbook();
|
|
2088
|
+
if (!range || !sheet || !wb) return;
|
|
2089
|
+
await ensurePluginByName("table");
|
|
2090
|
+
await api.executeCommand("sheet.command.add-table", {
|
|
2091
|
+
unitId: wb.getId(),
|
|
2092
|
+
subUnitId: sheet.getSheetId(),
|
|
2093
|
+
range: {
|
|
2094
|
+
startRow: range.getRow(),
|
|
2095
|
+
startColumn: range.getColumn(),
|
|
2096
|
+
endRow: range.getRow() + range.getHeight() - 1,
|
|
2097
|
+
endColumn: range.getColumn() + range.getWidth() - 1
|
|
2098
|
+
}
|
|
2099
|
+
});
|
|
2100
|
+
})();
|
|
2101
|
+
};
|
|
2102
|
+
var autoFitColumns = (api) => {
|
|
2103
|
+
const range = activeRange(api);
|
|
2104
|
+
const sheet = activeSheet(api);
|
|
2105
|
+
if (!range || !sheet) return;
|
|
2106
|
+
const withAutoWidth = sheet;
|
|
2107
|
+
withAutoWidth.setColumnAutoWidth?.(range.getColumn(), range.getWidth());
|
|
2108
|
+
};
|
|
2109
|
+
var AUTO_FIT_ROW_CAP = 500;
|
|
2110
|
+
var autoFitRows = (api) => {
|
|
2111
|
+
const range = activeRange(api);
|
|
2112
|
+
const sheet = activeSheet(api);
|
|
2113
|
+
if (!range || !sheet) return;
|
|
2114
|
+
const start = range.getRow();
|
|
2115
|
+
const count = Math.min(range.getHeight(), AUTO_FIT_ROW_CAP);
|
|
2116
|
+
for (let r = 0; r < count; r++) sheet.autoFitRow(start + r);
|
|
2117
|
+
};
|
|
2118
|
+
var NUMBER_FORMAT_PATTERNS2 = {
|
|
2119
|
+
general: "",
|
|
2120
|
+
number: "#,##0.00",
|
|
2121
|
+
integer: "#,##0",
|
|
2122
|
+
currency: '"$"#,##0.00',
|
|
2123
|
+
accounting: '_("$"* #,##0.00_);_("$"* (#,##0.00);_("$"* "-"??_);_(@_)',
|
|
2124
|
+
percent: "0.00%",
|
|
2125
|
+
date: "yyyy-mm-dd",
|
|
2126
|
+
time: "hh:mm:ss",
|
|
2127
|
+
scientific: "0.00E+00",
|
|
2128
|
+
text: "@"
|
|
2129
|
+
};
|
|
2130
|
+
var NUM_FORMAT_ORDER = [
|
|
2131
|
+
"general",
|
|
2132
|
+
"number",
|
|
2133
|
+
"integer",
|
|
2134
|
+
"currency",
|
|
2135
|
+
"accounting",
|
|
2136
|
+
"percent",
|
|
2137
|
+
"date",
|
|
2138
|
+
"time",
|
|
2139
|
+
"scientific",
|
|
2140
|
+
"text"
|
|
2141
|
+
];
|
|
2142
|
+
var NUM_FORMAT_SHORTCUT = {
|
|
2143
|
+
number: "Ctrl+Shift+1",
|
|
2144
|
+
time: "Ctrl+Shift+2",
|
|
2145
|
+
date: "Ctrl+Shift+3",
|
|
2146
|
+
currency: "Ctrl+Shift+4",
|
|
2147
|
+
percent: "Ctrl+Shift+5",
|
|
2148
|
+
scientific: "Ctrl+Shift+6"
|
|
2149
|
+
};
|
|
2150
|
+
function setNumberFormatByKey(api, key) {
|
|
2151
|
+
const range = activeRange(api);
|
|
2152
|
+
range?.setNumberFormat?.(NUMBER_FORMAT_PATTERNS2[key]);
|
|
2153
|
+
}
|
|
2154
|
+
var increaseDecimal = (api) => void api.executeCommand("sheet.command.numfmt.add.decimal.command");
|
|
2155
|
+
var decreaseDecimal = (api) => void api.executeCommand("sheet.command.numfmt.subtract.decimal.command");
|
|
2156
|
+
var clearFormat = (api) => void api.executeCommand("sheet.command.clear-selection-format");
|
|
2157
|
+
function applyBorders(api, choice) {
|
|
2158
|
+
const range = activeRange(api);
|
|
2159
|
+
if (!range) return;
|
|
2160
|
+
const type = choice === "all" ? BorderType.ALL : choice === "outside" ? BorderType.OUTSIDE : BorderType.NONE;
|
|
2161
|
+
const style = choice === "none" ? BorderStyleTypes.NONE : BorderStyleTypes.THIN;
|
|
2162
|
+
range.setBorder(type, style, "#000000");
|
|
2163
|
+
}
|
|
2164
|
+
function rowSpan(api) {
|
|
2165
|
+
const wb = fu(api).getActiveWorkbook();
|
|
2166
|
+
const sheet = activeSheet(api);
|
|
2167
|
+
const range = activeRange(api);
|
|
2168
|
+
if (!wb || !sheet || !range) return null;
|
|
2169
|
+
const startRow = range.getRow();
|
|
2170
|
+
const endRow = startRow + range.getHeight() - 1;
|
|
2171
|
+
const maxCol = sheet.getMaxColumns?.() ?? 1;
|
|
2172
|
+
return { wb, sheet, startRow, endRow, maxCol };
|
|
2173
|
+
}
|
|
2174
|
+
function colSpan(api) {
|
|
2175
|
+
const wb = fu(api).getActiveWorkbook();
|
|
2176
|
+
const sheet = activeSheet(api);
|
|
2177
|
+
const range = activeRange(api);
|
|
2178
|
+
if (!wb || !sheet || !range) return null;
|
|
2179
|
+
const startColumn = range.getColumn();
|
|
2180
|
+
const endColumn = startColumn + range.getWidth() - 1;
|
|
2181
|
+
const maxRow = sheet.getMaxRows?.() ?? 1;
|
|
2182
|
+
return { wb, sheet, startColumn, endColumn, maxRow };
|
|
2183
|
+
}
|
|
2184
|
+
var hideSelectedRows = (api) => {
|
|
2185
|
+
const s = rowSpan(api);
|
|
2186
|
+
if (!s) return;
|
|
2187
|
+
void api.executeCommand("sheet.command.set-rows-hidden", {
|
|
2188
|
+
unitId: s.wb.getId(),
|
|
2189
|
+
subUnitId: s.sheet.getSheetId(),
|
|
2190
|
+
ranges: [
|
|
2191
|
+
{
|
|
2192
|
+
startRow: s.startRow,
|
|
2193
|
+
endRow: s.endRow,
|
|
2194
|
+
startColumn: 0,
|
|
2195
|
+
endColumn: Math.max(0, s.maxCol - 1),
|
|
2196
|
+
rangeType: 1
|
|
2197
|
+
}
|
|
2198
|
+
]
|
|
2199
|
+
});
|
|
2200
|
+
};
|
|
2201
|
+
var unhideSelectedRows = (api) => {
|
|
2202
|
+
const s = rowSpan(api);
|
|
2203
|
+
if (!s) return;
|
|
2204
|
+
void api.executeCommand("sheet.command.set-specific-rows-visible", {
|
|
2205
|
+
unitId: s.wb.getId(),
|
|
2206
|
+
subUnitId: s.sheet.getSheetId(),
|
|
2207
|
+
ranges: [
|
|
2208
|
+
{
|
|
2209
|
+
startRow: s.startRow,
|
|
2210
|
+
endRow: s.endRow,
|
|
2211
|
+
startColumn: 0,
|
|
2212
|
+
endColumn: Math.max(0, s.maxCol - 1),
|
|
2213
|
+
rangeType: 1
|
|
2214
|
+
}
|
|
2215
|
+
]
|
|
2216
|
+
});
|
|
2217
|
+
};
|
|
2218
|
+
var hideSelectedColumns = (api) => {
|
|
2219
|
+
const s = colSpan(api);
|
|
2220
|
+
if (!s) return;
|
|
2221
|
+
void api.executeCommand("sheet.command.set-col-hidden", {
|
|
2222
|
+
unitId: s.wb.getId(),
|
|
2223
|
+
subUnitId: s.sheet.getSheetId(),
|
|
2224
|
+
ranges: [
|
|
2225
|
+
{
|
|
2226
|
+
startRow: 0,
|
|
2227
|
+
endRow: Math.max(0, s.maxRow - 1),
|
|
2228
|
+
startColumn: s.startColumn,
|
|
2229
|
+
endColumn: s.endColumn,
|
|
2230
|
+
rangeType: 2
|
|
2231
|
+
}
|
|
2232
|
+
]
|
|
2233
|
+
});
|
|
2234
|
+
};
|
|
2235
|
+
var unhideSelectedColumns = (api) => {
|
|
2236
|
+
const s = colSpan(api);
|
|
2237
|
+
if (!s) return;
|
|
2238
|
+
void api.executeCommand("sheet.command.set-col-visible-on-cols", {
|
|
2239
|
+
unitId: s.wb.getId(),
|
|
2240
|
+
subUnitId: s.sheet.getSheetId(),
|
|
2241
|
+
ranges: [
|
|
2242
|
+
{
|
|
2243
|
+
startRow: 0,
|
|
2244
|
+
endRow: Math.max(0, s.maxRow - 1),
|
|
2245
|
+
startColumn: s.startColumn,
|
|
2246
|
+
endColumn: s.endColumn,
|
|
2247
|
+
rangeType: 2
|
|
2248
|
+
}
|
|
2249
|
+
]
|
|
2250
|
+
});
|
|
2251
|
+
};
|
|
2252
|
+
var freezeFirstRow = (api) => {
|
|
2253
|
+
activeSheet(api)?.setFrozenRows(1);
|
|
2254
|
+
};
|
|
2255
|
+
var freezeFirstColumn = (api) => {
|
|
2256
|
+
activeSheet(api)?.setFrozenColumns(1);
|
|
2257
|
+
};
|
|
2258
|
+
var freezeAtSelection = (api) => void api.executeCommand("sheet.command.set-selection-frozen");
|
|
2259
|
+
var unfreezePanes = (api) => void api.executeCommand("sheet.command.cancel-frozen");
|
|
2260
|
+
var toggleGridlines = (api) => {
|
|
2261
|
+
const wb = fu(api).getActiveWorkbook();
|
|
2262
|
+
const sheet = activeSheet(api);
|
|
2263
|
+
if (!wb || !sheet) return;
|
|
2264
|
+
void api.executeCommand("sheet.command.toggle-gridlines", {
|
|
2265
|
+
unitId: wb.getId(),
|
|
2266
|
+
subUnitId: sheet.getSheetId(),
|
|
2267
|
+
showGridlines: 0
|
|
2268
|
+
});
|
|
2269
|
+
};
|
|
2270
|
+
var toggleCommentPanel = (api) => void api.executeCommand("sheet.operation.toggle-comment-panel");
|
|
2271
|
+
var jumpToFirstCell = (api) => {
|
|
2272
|
+
activeSheet(api)?.getRange(0, 0).activate();
|
|
2273
|
+
};
|
|
2274
|
+
var switchToPreviousSheet = (api) => switchSheetByDelta(api, -1);
|
|
2275
|
+
var switchToNextSheet = (api) => switchSheetByDelta(api, 1);
|
|
2276
|
+
function switchSheetByDelta(api, delta) {
|
|
2277
|
+
const wb = fu(api).getActiveWorkbook();
|
|
2278
|
+
const active = wb?.getActiveSheet();
|
|
2279
|
+
if (!wb || !active) return;
|
|
2280
|
+
const sheets = wb.getSheets();
|
|
2281
|
+
const activeId = active.getSheetId();
|
|
2282
|
+
const idx = sheets.findIndex((s) => s.getSheetId() === activeId);
|
|
2283
|
+
if (idx < 0) return;
|
|
2284
|
+
const nextIdx = idx + delta;
|
|
2285
|
+
if (nextIdx < 0 || nextIdx >= sheets.length) return;
|
|
2286
|
+
wb.setActiveSheet(sheets[nextIdx]);
|
|
2287
|
+
}
|
|
2288
|
+
var showFormulas = (api) => void api.executeCommand("sheet.command.set-show-formula", {});
|
|
2289
|
+
var sortAsc = (api) => sortRange(api, true);
|
|
2290
|
+
var sortDesc = (api) => sortRange(api, false);
|
|
2291
|
+
function sortRange(api, ascending) {
|
|
2292
|
+
const range = activeRange(api);
|
|
2293
|
+
if (!range) return;
|
|
2294
|
+
const withSort = range;
|
|
2295
|
+
withSort.sort?.({ column: range.getColumn(), ascending });
|
|
2296
|
+
}
|
|
2297
|
+
var toggleFilter = (api) => {
|
|
2298
|
+
void (async () => {
|
|
2299
|
+
await ensurePluginByName("filter");
|
|
2300
|
+
const wb = fu(api).getActiveWorkbook();
|
|
2301
|
+
const sheet = activeSheet(api);
|
|
2302
|
+
const range = activeRange(api);
|
|
2303
|
+
if (!wb || !sheet || !range) return;
|
|
2304
|
+
const sheetWithFilter = sheet;
|
|
2305
|
+
if (sheetWithFilter.getFilter?.()) {
|
|
2306
|
+
await api.executeCommand("sheet.command.remove-sheet-filter", {
|
|
2307
|
+
unitId: wb.getId(),
|
|
2308
|
+
subUnitId: sheet.getSheetId()
|
|
2309
|
+
});
|
|
2310
|
+
return;
|
|
2311
|
+
}
|
|
2312
|
+
await api.executeCommand("sheet.command.set-filter-range", {
|
|
2313
|
+
unitId: wb.getId(),
|
|
2314
|
+
subUnitId: sheet.getSheetId(),
|
|
2315
|
+
range: {
|
|
2316
|
+
startRow: range.getRow(),
|
|
2317
|
+
startColumn: range.getColumn(),
|
|
2318
|
+
endRow: range.getRow() + range.getHeight() - 1,
|
|
2319
|
+
endColumn: range.getColumn() + range.getWidth() - 1
|
|
2320
|
+
}
|
|
2321
|
+
});
|
|
2322
|
+
})();
|
|
2323
|
+
};
|
|
2324
|
+
var splitTextToColumns = (api) => void api.executeCommand("sheet.command.split-text-to-columns");
|
|
2325
|
+
var forceRecalculate = (api) => void api.executeCommand("formula.mutation.set-formula-calculation-start", {
|
|
2326
|
+
forceCalculation: true
|
|
2327
|
+
});
|
|
1633
2328
|
var MENUS = [
|
|
2329
|
+
{
|
|
2330
|
+
id: "file",
|
|
2331
|
+
label: "File",
|
|
2332
|
+
feature: "file",
|
|
2333
|
+
items: [
|
|
2334
|
+
{ kind: "item", id: "properties", label: "Properties\u2026", icon: "info", dialog: "properties" },
|
|
2335
|
+
{
|
|
2336
|
+
kind: "item",
|
|
2337
|
+
id: "about",
|
|
2338
|
+
label: "About casual sheets",
|
|
2339
|
+
icon: "help_outline",
|
|
2340
|
+
dialog: "about"
|
|
2341
|
+
}
|
|
2342
|
+
]
|
|
2343
|
+
},
|
|
1634
2344
|
{
|
|
1635
2345
|
id: "edit",
|
|
1636
2346
|
label: "Edit",
|
|
1637
2347
|
items: [
|
|
1638
|
-
{ id: "undo", label: "Undo",
|
|
1639
|
-
{ id: "redo", label: "Redo",
|
|
1640
|
-
{
|
|
1641
|
-
{ id: "
|
|
1642
|
-
{
|
|
2348
|
+
{ kind: "item", id: "undo", label: "Undo", icon: "undo", shortcut: "Ctrl+Z", run: undo },
|
|
2349
|
+
{ kind: "item", id: "redo", label: "Redo", icon: "redo", shortcut: "Ctrl+Y", run: redo },
|
|
2350
|
+
{ kind: "separator", id: "sep-clip" },
|
|
2351
|
+
{ kind: "item", id: "cut", label: "Cut", icon: "content_cut", shortcut: "Ctrl+X", run: cut },
|
|
2352
|
+
{
|
|
2353
|
+
kind: "item",
|
|
2354
|
+
id: "copy",
|
|
2355
|
+
label: "Copy",
|
|
2356
|
+
icon: "content_copy",
|
|
2357
|
+
shortcut: "Ctrl+C",
|
|
2358
|
+
run: copy
|
|
2359
|
+
},
|
|
2360
|
+
{
|
|
2361
|
+
kind: "item",
|
|
2362
|
+
id: "paste",
|
|
2363
|
+
label: "Paste",
|
|
2364
|
+
icon: "content_paste",
|
|
2365
|
+
shortcut: "Ctrl+V",
|
|
2366
|
+
run: paste
|
|
2367
|
+
},
|
|
2368
|
+
{
|
|
2369
|
+
kind: "item",
|
|
2370
|
+
id: "paste-format",
|
|
2371
|
+
label: "Paste formatting only",
|
|
2372
|
+
icon: "content_paste",
|
|
2373
|
+
shortcut: "Ctrl+Shift+V",
|
|
2374
|
+
run: pasteFormattingOnly
|
|
2375
|
+
},
|
|
2376
|
+
{
|
|
2377
|
+
kind: "item",
|
|
2378
|
+
id: "paste-special",
|
|
2379
|
+
label: "Paste Special\u2026",
|
|
2380
|
+
icon: "content_paste_go",
|
|
2381
|
+
shortcut: "Ctrl+Alt+V",
|
|
2382
|
+
dialog: "paste-special"
|
|
2383
|
+
},
|
|
2384
|
+
{ kind: "separator", id: "sep-find" },
|
|
2385
|
+
{
|
|
2386
|
+
kind: "item",
|
|
2387
|
+
id: "find-replace",
|
|
2388
|
+
label: "Find & Replace\u2026",
|
|
2389
|
+
icon: "search",
|
|
2390
|
+
shortcut: "Ctrl+F",
|
|
2391
|
+
dialog: "find-replace"
|
|
2392
|
+
},
|
|
2393
|
+
{ kind: "separator", id: "sep-cells" },
|
|
2394
|
+
{
|
|
2395
|
+
kind: "item",
|
|
2396
|
+
id: "edit-insert-cells",
|
|
2397
|
+
label: "Insert cells\u2026",
|
|
2398
|
+
icon: "add_box",
|
|
2399
|
+
shortcut: "Ctrl++",
|
|
2400
|
+
dialog: "insert-cells"
|
|
2401
|
+
},
|
|
2402
|
+
{
|
|
2403
|
+
kind: "item",
|
|
2404
|
+
id: "edit-delete-cells",
|
|
2405
|
+
label: "Delete cells\u2026",
|
|
2406
|
+
icon: "indeterminate_check_box",
|
|
2407
|
+
shortcut: "Ctrl+-",
|
|
2408
|
+
dialog: "delete-cells"
|
|
2409
|
+
}
|
|
2410
|
+
]
|
|
2411
|
+
},
|
|
2412
|
+
{
|
|
2413
|
+
id: "view",
|
|
2414
|
+
label: "View",
|
|
2415
|
+
items: [
|
|
2416
|
+
{
|
|
2417
|
+
kind: "item",
|
|
2418
|
+
id: "show-formulas",
|
|
2419
|
+
label: "Show formulas",
|
|
2420
|
+
icon: "description",
|
|
2421
|
+
shortcut: "Ctrl+`",
|
|
2422
|
+
run: showFormulas
|
|
2423
|
+
},
|
|
2424
|
+
{
|
|
2425
|
+
kind: "item",
|
|
2426
|
+
id: "toggle-gridlines",
|
|
2427
|
+
label: "Toggle gridlines",
|
|
2428
|
+
icon: "grid_on",
|
|
2429
|
+
run: toggleGridlines
|
|
2430
|
+
},
|
|
2431
|
+
{ kind: "separator", id: "sep-freeze" },
|
|
2432
|
+
{
|
|
2433
|
+
kind: "item",
|
|
2434
|
+
id: "freeze-row",
|
|
2435
|
+
label: "Freeze top row",
|
|
2436
|
+
icon: "border_horizontal",
|
|
2437
|
+
run: freezeFirstRow
|
|
2438
|
+
},
|
|
2439
|
+
{
|
|
2440
|
+
kind: "item",
|
|
2441
|
+
id: "freeze-col",
|
|
2442
|
+
label: "Freeze first column",
|
|
2443
|
+
icon: "border_vertical",
|
|
2444
|
+
run: freezeFirstColumn
|
|
2445
|
+
},
|
|
2446
|
+
{
|
|
2447
|
+
kind: "item",
|
|
2448
|
+
id: "freeze-selection",
|
|
2449
|
+
label: "Freeze panes (at selection)",
|
|
2450
|
+
icon: "grid_4x4",
|
|
2451
|
+
run: freezeAtSelection
|
|
2452
|
+
},
|
|
2453
|
+
{ kind: "item", id: "unfreeze", label: "Unfreeze", icon: "grid_off", run: unfreezePanes },
|
|
2454
|
+
{ kind: "separator", id: "sep-nav" },
|
|
2455
|
+
{
|
|
2456
|
+
kind: "item",
|
|
2457
|
+
id: "jump-home",
|
|
2458
|
+
label: "Jump to A1",
|
|
2459
|
+
icon: "home",
|
|
2460
|
+
shortcut: "Ctrl+Home",
|
|
2461
|
+
run: jumpToFirstCell
|
|
2462
|
+
},
|
|
2463
|
+
{
|
|
2464
|
+
kind: "item",
|
|
2465
|
+
id: "prev-sheet",
|
|
2466
|
+
label: "Previous sheet",
|
|
2467
|
+
icon: "navigate_before",
|
|
2468
|
+
shortcut: "Ctrl+PageUp",
|
|
2469
|
+
run: switchToPreviousSheet
|
|
2470
|
+
},
|
|
2471
|
+
{
|
|
2472
|
+
kind: "item",
|
|
2473
|
+
id: "next-sheet",
|
|
2474
|
+
label: "Next sheet",
|
|
2475
|
+
icon: "navigate_next",
|
|
2476
|
+
shortcut: "Ctrl+PageDown",
|
|
2477
|
+
run: switchToNextSheet
|
|
2478
|
+
},
|
|
2479
|
+
{ kind: "separator", id: "sep-panels" },
|
|
2480
|
+
{
|
|
2481
|
+
kind: "item",
|
|
2482
|
+
id: "comments-panel",
|
|
2483
|
+
label: "Comments panel",
|
|
2484
|
+
icon: "forum",
|
|
2485
|
+
run: toggleCommentPanel
|
|
2486
|
+
}
|
|
1643
2487
|
]
|
|
1644
2488
|
},
|
|
1645
2489
|
{
|
|
@@ -1647,28 +2491,140 @@ var MENUS = [
|
|
|
1647
2491
|
label: "Insert",
|
|
1648
2492
|
items: [
|
|
1649
2493
|
{
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
icon: "
|
|
2494
|
+
kind: "item",
|
|
2495
|
+
id: "new-sheet",
|
|
2496
|
+
label: "New sheet",
|
|
2497
|
+
icon: "add_box",
|
|
2498
|
+
shortcut: "Shift+F11",
|
|
2499
|
+
run: insertNewSheet
|
|
1654
2500
|
},
|
|
1655
2501
|
{
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
icon: "
|
|
2502
|
+
kind: "item",
|
|
2503
|
+
id: "insert-table",
|
|
2504
|
+
label: "Table",
|
|
2505
|
+
icon: "table_rows",
|
|
2506
|
+
shortcut: "Ctrl+L",
|
|
2507
|
+
run: insertTable,
|
|
2508
|
+
feature: "tables"
|
|
1660
2509
|
},
|
|
1661
2510
|
{
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
icon: "
|
|
2511
|
+
kind: "item",
|
|
2512
|
+
id: "insert-chart",
|
|
2513
|
+
label: "Chart\u2026",
|
|
2514
|
+
icon: "bar_chart",
|
|
2515
|
+
dialog: "insert-chart",
|
|
2516
|
+
feature: "charts"
|
|
1666
2517
|
},
|
|
1667
2518
|
{
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
icon: "
|
|
2519
|
+
kind: "item",
|
|
2520
|
+
id: "insert-sparkline",
|
|
2521
|
+
label: "Sparkline\u2026",
|
|
2522
|
+
icon: "show_chart",
|
|
2523
|
+
dialog: "insert-sparkline",
|
|
2524
|
+
feature: "sparklines"
|
|
2525
|
+
},
|
|
2526
|
+
{
|
|
2527
|
+
kind: "item",
|
|
2528
|
+
id: "insert-pivot",
|
|
2529
|
+
label: "PivotTable\u2026",
|
|
2530
|
+
icon: "pivot_table_chart",
|
|
2531
|
+
dialog: "insert-pivot",
|
|
2532
|
+
feature: "pivots"
|
|
2533
|
+
},
|
|
2534
|
+
{ kind: "separator", id: "sep-objects" },
|
|
2535
|
+
{ kind: "item", id: "insert-image", label: "Image\u2026", icon: "image", run: insertImage },
|
|
2536
|
+
{
|
|
2537
|
+
kind: "item",
|
|
2538
|
+
id: "insert-function",
|
|
2539
|
+
label: "Function\u2026",
|
|
2540
|
+
icon: "functions",
|
|
2541
|
+
shortcut: "Shift+F3",
|
|
2542
|
+
dialog: "insert-function"
|
|
2543
|
+
},
|
|
2544
|
+
{
|
|
2545
|
+
kind: "item",
|
|
2546
|
+
id: "insert-link",
|
|
2547
|
+
label: "Hyperlink\u2026",
|
|
2548
|
+
icon: "link",
|
|
2549
|
+
shortcut: "Ctrl+K",
|
|
2550
|
+
run: insertHyperlink
|
|
2551
|
+
},
|
|
2552
|
+
{
|
|
2553
|
+
kind: "item",
|
|
2554
|
+
id: "insert-comment",
|
|
2555
|
+
label: "Comment",
|
|
2556
|
+
icon: "comment",
|
|
2557
|
+
shortcut: "Shift+F2",
|
|
2558
|
+
run: insertComment
|
|
2559
|
+
},
|
|
2560
|
+
{ kind: "separator", id: "sep-rowcol" },
|
|
2561
|
+
{
|
|
2562
|
+
kind: "submenu",
|
|
2563
|
+
id: "insert-rowcol",
|
|
2564
|
+
label: "Rows & columns",
|
|
2565
|
+
icon: "grid_on",
|
|
2566
|
+
items: [
|
|
2567
|
+
{
|
|
2568
|
+
kind: "item",
|
|
2569
|
+
id: "insert-row-above",
|
|
2570
|
+
label: "Row above",
|
|
2571
|
+
icon: "vertical_align_top",
|
|
2572
|
+
run: insertRowAbove
|
|
2573
|
+
},
|
|
2574
|
+
{
|
|
2575
|
+
kind: "item",
|
|
2576
|
+
id: "insert-row-below",
|
|
2577
|
+
label: "Row below",
|
|
2578
|
+
icon: "vertical_align_bottom",
|
|
2579
|
+
run: insertRowBelow
|
|
2580
|
+
},
|
|
2581
|
+
{
|
|
2582
|
+
kind: "item",
|
|
2583
|
+
id: "insert-col-left",
|
|
2584
|
+
label: "Column left",
|
|
2585
|
+
icon: "keyboard_tab_rtl",
|
|
2586
|
+
run: insertColumnLeft
|
|
2587
|
+
},
|
|
2588
|
+
{
|
|
2589
|
+
kind: "item",
|
|
2590
|
+
id: "insert-col-right",
|
|
2591
|
+
label: "Column right",
|
|
2592
|
+
icon: "keyboard_tab",
|
|
2593
|
+
run: insertColumnRight
|
|
2594
|
+
}
|
|
2595
|
+
]
|
|
2596
|
+
},
|
|
2597
|
+
{ kind: "separator", id: "sep-autofit" },
|
|
2598
|
+
{
|
|
2599
|
+
kind: "item",
|
|
2600
|
+
id: "autofit-col",
|
|
2601
|
+
label: "Auto-fit column width",
|
|
2602
|
+
icon: "settings_ethernet",
|
|
2603
|
+
run: autoFitColumns
|
|
2604
|
+
},
|
|
2605
|
+
{
|
|
2606
|
+
kind: "item",
|
|
2607
|
+
id: "autofit-row",
|
|
2608
|
+
label: "Auto-fit row height",
|
|
2609
|
+
icon: "height",
|
|
2610
|
+
run: autoFitRows
|
|
2611
|
+
},
|
|
2612
|
+
{ kind: "separator", id: "sep-date" },
|
|
2613
|
+
{
|
|
2614
|
+
kind: "item",
|
|
2615
|
+
id: "insert-today",
|
|
2616
|
+
label: "Today's date",
|
|
2617
|
+
icon: "today",
|
|
2618
|
+
shortcut: "Ctrl+;",
|
|
2619
|
+
run: insertTodayDate
|
|
2620
|
+
},
|
|
2621
|
+
{
|
|
2622
|
+
kind: "item",
|
|
2623
|
+
id: "insert-time",
|
|
2624
|
+
label: "Current time",
|
|
2625
|
+
icon: "schedule",
|
|
2626
|
+
shortcut: "Ctrl+Shift+:",
|
|
2627
|
+
run: insertCurrentTime
|
|
1672
2628
|
}
|
|
1673
2629
|
]
|
|
1674
2630
|
},
|
|
@@ -1676,30 +2632,177 @@ var MENUS = [
|
|
|
1676
2632
|
id: "format",
|
|
1677
2633
|
label: "Format",
|
|
1678
2634
|
items: [
|
|
1679
|
-
{ id: "bold", label: "Bold", command: "sheet.command.set-range-bold", icon: "format_bold" },
|
|
1680
2635
|
{
|
|
2636
|
+
kind: "item",
|
|
2637
|
+
id: "format-cells",
|
|
2638
|
+
label: "Format cells\u2026",
|
|
2639
|
+
icon: "format_shapes",
|
|
2640
|
+
shortcut: "Ctrl+1",
|
|
2641
|
+
dialog: "format-cells"
|
|
2642
|
+
},
|
|
2643
|
+
{ kind: "separator", id: "sep-format-cells" },
|
|
2644
|
+
{
|
|
2645
|
+
kind: "item",
|
|
2646
|
+
id: "bold",
|
|
2647
|
+
label: "Bold",
|
|
2648
|
+
icon: "format_bold",
|
|
2649
|
+
shortcut: "Ctrl+B",
|
|
2650
|
+
run: (api) => void api.executeCommand("sheet.command.set-range-bold")
|
|
2651
|
+
},
|
|
2652
|
+
{
|
|
2653
|
+
kind: "item",
|
|
1681
2654
|
id: "italic",
|
|
1682
2655
|
label: "Italic",
|
|
1683
|
-
|
|
1684
|
-
|
|
2656
|
+
icon: "format_italic",
|
|
2657
|
+
shortcut: "Ctrl+I",
|
|
2658
|
+
run: (api) => void api.executeCommand("sheet.command.set-range-italic")
|
|
1685
2659
|
},
|
|
1686
2660
|
{
|
|
2661
|
+
kind: "item",
|
|
1687
2662
|
id: "underline",
|
|
1688
2663
|
label: "Underline",
|
|
1689
|
-
|
|
1690
|
-
|
|
2664
|
+
icon: "format_underlined",
|
|
2665
|
+
shortcut: "Ctrl+U",
|
|
2666
|
+
run: (api) => void api.executeCommand("sheet.command.set-range-underline")
|
|
1691
2667
|
},
|
|
1692
2668
|
{
|
|
2669
|
+
kind: "item",
|
|
1693
2670
|
id: "wrap-text",
|
|
1694
2671
|
label: "Wrap text",
|
|
1695
|
-
|
|
1696
|
-
|
|
2672
|
+
icon: "wrap_text",
|
|
2673
|
+
run: (api) => void api.executeCommand("sheet.command.set-text-wrap", { value: 3 })
|
|
2674
|
+
},
|
|
2675
|
+
{ kind: "separator", id: "sep-numfmt" },
|
|
2676
|
+
{
|
|
2677
|
+
kind: "submenu",
|
|
2678
|
+
id: "num-format",
|
|
2679
|
+
label: "Number format",
|
|
2680
|
+
icon: "looks_one",
|
|
2681
|
+
items: NUM_FORMAT_ORDER.map((k) => ({
|
|
2682
|
+
kind: "item",
|
|
2683
|
+
id: `num-${k}`,
|
|
2684
|
+
label: k[0].toUpperCase() + k.slice(1),
|
|
2685
|
+
icon: "looks_one",
|
|
2686
|
+
shortcut: NUM_FORMAT_SHORTCUT[k],
|
|
2687
|
+
run: (api) => setNumberFormatByKey(api, k)
|
|
2688
|
+
}))
|
|
1697
2689
|
},
|
|
1698
2690
|
{
|
|
2691
|
+
kind: "item",
|
|
2692
|
+
id: "decimal-up",
|
|
2693
|
+
label: "Increase decimals",
|
|
2694
|
+
icon: "decimal_increase",
|
|
2695
|
+
run: increaseDecimal
|
|
2696
|
+
},
|
|
2697
|
+
{
|
|
2698
|
+
kind: "item",
|
|
2699
|
+
id: "decimal-down",
|
|
2700
|
+
label: "Decrease decimals",
|
|
2701
|
+
icon: "decimal_decrease",
|
|
2702
|
+
run: decreaseDecimal
|
|
2703
|
+
},
|
|
2704
|
+
{ kind: "separator", id: "sep-borders" },
|
|
2705
|
+
{
|
|
2706
|
+
kind: "submenu",
|
|
2707
|
+
id: "borders",
|
|
2708
|
+
label: "Borders",
|
|
2709
|
+
icon: "border_all",
|
|
2710
|
+
items: [
|
|
2711
|
+
{
|
|
2712
|
+
kind: "item",
|
|
2713
|
+
id: "border-all",
|
|
2714
|
+
label: "All borders",
|
|
2715
|
+
icon: "border_all",
|
|
2716
|
+
run: (api) => applyBorders(api, "all")
|
|
2717
|
+
},
|
|
2718
|
+
{
|
|
2719
|
+
kind: "item",
|
|
2720
|
+
id: "border-outside",
|
|
2721
|
+
label: "Outside borders",
|
|
2722
|
+
icon: "border_outer",
|
|
2723
|
+
run: (api) => applyBorders(api, "outside")
|
|
2724
|
+
},
|
|
2725
|
+
{
|
|
2726
|
+
kind: "item",
|
|
2727
|
+
id: "border-none",
|
|
2728
|
+
label: "No border",
|
|
2729
|
+
icon: "border_clear",
|
|
2730
|
+
run: (api) => applyBorders(api, "none")
|
|
2731
|
+
}
|
|
2732
|
+
]
|
|
2733
|
+
},
|
|
2734
|
+
{ kind: "separator", id: "sep-cond" },
|
|
2735
|
+
{
|
|
2736
|
+
kind: "item",
|
|
2737
|
+
id: "conditional-formatting",
|
|
2738
|
+
label: "Conditional formatting\u2026",
|
|
2739
|
+
icon: "palette",
|
|
2740
|
+
dialog: "conditional-formatting",
|
|
2741
|
+
feature: "conditionalFormatting"
|
|
2742
|
+
},
|
|
2743
|
+
{ kind: "separator", id: "sep-visibility" },
|
|
2744
|
+
{
|
|
2745
|
+
kind: "submenu",
|
|
2746
|
+
id: "visibility",
|
|
2747
|
+
label: "Visibility",
|
|
2748
|
+
icon: "visibility",
|
|
2749
|
+
items: [
|
|
2750
|
+
{
|
|
2751
|
+
kind: "item",
|
|
2752
|
+
id: "hide-row",
|
|
2753
|
+
label: "Hide row",
|
|
2754
|
+
icon: "visibility_off",
|
|
2755
|
+
shortcut: "Ctrl+9",
|
|
2756
|
+
run: hideSelectedRows
|
|
2757
|
+
},
|
|
2758
|
+
{
|
|
2759
|
+
kind: "item",
|
|
2760
|
+
id: "unhide-row",
|
|
2761
|
+
label: "Unhide row",
|
|
2762
|
+
icon: "visibility",
|
|
2763
|
+
shortcut: "Ctrl+Shift+9",
|
|
2764
|
+
run: unhideSelectedRows
|
|
2765
|
+
},
|
|
2766
|
+
{
|
|
2767
|
+
kind: "item",
|
|
2768
|
+
id: "hide-col",
|
|
2769
|
+
label: "Hide column",
|
|
2770
|
+
icon: "visibility_off",
|
|
2771
|
+
shortcut: "Ctrl+0",
|
|
2772
|
+
run: hideSelectedColumns
|
|
2773
|
+
},
|
|
2774
|
+
{
|
|
2775
|
+
kind: "item",
|
|
2776
|
+
id: "unhide-col",
|
|
2777
|
+
label: "Unhide column",
|
|
2778
|
+
icon: "visibility",
|
|
2779
|
+
shortcut: "Ctrl+Shift+0",
|
|
2780
|
+
run: unhideSelectedColumns
|
|
2781
|
+
}
|
|
2782
|
+
]
|
|
2783
|
+
},
|
|
2784
|
+
{ kind: "separator", id: "sep-clear" },
|
|
2785
|
+
{
|
|
2786
|
+
kind: "item",
|
|
1699
2787
|
id: "clear-format",
|
|
1700
2788
|
label: "Clear formatting",
|
|
1701
|
-
|
|
1702
|
-
|
|
2789
|
+
icon: "format_clear",
|
|
2790
|
+
run: clearFormat
|
|
2791
|
+
},
|
|
2792
|
+
{ kind: "separator", id: "sep-delete" },
|
|
2793
|
+
{
|
|
2794
|
+
kind: "item",
|
|
2795
|
+
id: "delete-row",
|
|
2796
|
+
label: "Delete row",
|
|
2797
|
+
icon: "delete_sweep",
|
|
2798
|
+
run: deleteSelectedRow
|
|
2799
|
+
},
|
|
2800
|
+
{
|
|
2801
|
+
kind: "item",
|
|
2802
|
+
id: "delete-col",
|
|
2803
|
+
label: "Delete column",
|
|
2804
|
+
icon: "folder_delete",
|
|
2805
|
+
run: deleteSelectedColumn
|
|
1703
2806
|
}
|
|
1704
2807
|
]
|
|
1705
2808
|
},
|
|
@@ -1708,46 +2811,97 @@ var MENUS = [
|
|
|
1708
2811
|
label: "Data",
|
|
1709
2812
|
items: [
|
|
1710
2813
|
{
|
|
2814
|
+
kind: "item",
|
|
1711
2815
|
id: "sort-asc",
|
|
1712
2816
|
label: "Sort ascending",
|
|
1713
|
-
|
|
1714
|
-
|
|
2817
|
+
icon: "arrow_upward",
|
|
2818
|
+
run: sortAsc
|
|
1715
2819
|
},
|
|
1716
2820
|
{
|
|
2821
|
+
kind: "item",
|
|
1717
2822
|
id: "sort-desc",
|
|
1718
2823
|
label: "Sort descending",
|
|
1719
|
-
|
|
1720
|
-
|
|
2824
|
+
icon: "arrow_downward",
|
|
2825
|
+
run: sortDesc
|
|
2826
|
+
},
|
|
2827
|
+
{
|
|
2828
|
+
kind: "item",
|
|
2829
|
+
id: "sort-custom",
|
|
2830
|
+
label: "Sort range\u2026",
|
|
2831
|
+
icon: "sort",
|
|
2832
|
+
dialog: "custom-sort"
|
|
1721
2833
|
},
|
|
1722
2834
|
{
|
|
2835
|
+
kind: "item",
|
|
1723
2836
|
id: "toggle-filter",
|
|
1724
2837
|
label: "Toggle filter",
|
|
1725
|
-
|
|
1726
|
-
|
|
2838
|
+
icon: "filter_alt",
|
|
2839
|
+
shortcut: "Ctrl+Shift+L",
|
|
2840
|
+
run: toggleFilter,
|
|
2841
|
+
feature: "filter"
|
|
2842
|
+
},
|
|
2843
|
+
{ kind: "separator", id: "sep-tools" },
|
|
2844
|
+
{
|
|
2845
|
+
kind: "item",
|
|
2846
|
+
id: "data-validation",
|
|
2847
|
+
label: "Data validation\u2026",
|
|
2848
|
+
icon: "rule",
|
|
2849
|
+
dialog: "data-validation",
|
|
2850
|
+
feature: "dataValidation"
|
|
2851
|
+
},
|
|
2852
|
+
{
|
|
2853
|
+
kind: "item",
|
|
2854
|
+
id: "name-manager",
|
|
2855
|
+
label: "Name Manager\u2026",
|
|
2856
|
+
icon: "bookmark_add",
|
|
2857
|
+
shortcut: "Ctrl+F3",
|
|
2858
|
+
dialog: "name-manager"
|
|
2859
|
+
},
|
|
2860
|
+
{
|
|
2861
|
+
kind: "item",
|
|
2862
|
+
id: "goal-seek",
|
|
2863
|
+
label: "Goal Seek\u2026",
|
|
2864
|
+
icon: "analytics",
|
|
2865
|
+
dialog: "goal-seek"
|
|
2866
|
+
},
|
|
2867
|
+
{ kind: "separator", id: "sep-clean" },
|
|
2868
|
+
{
|
|
2869
|
+
kind: "item",
|
|
2870
|
+
id: "text-to-columns",
|
|
2871
|
+
label: "Text to Columns",
|
|
2872
|
+
icon: "splitscreen",
|
|
2873
|
+
run: splitTextToColumns
|
|
2874
|
+
},
|
|
2875
|
+
{
|
|
2876
|
+
kind: "item",
|
|
2877
|
+
id: "recalculate",
|
|
2878
|
+
label: "Recalculate",
|
|
2879
|
+
icon: "autorenew",
|
|
2880
|
+
shortcut: "F9",
|
|
2881
|
+
run: forceRecalculate
|
|
1727
2882
|
}
|
|
1728
2883
|
]
|
|
1729
2884
|
},
|
|
1730
2885
|
{
|
|
1731
|
-
id: "
|
|
1732
|
-
label: "
|
|
2886
|
+
id: "help",
|
|
2887
|
+
label: "Help",
|
|
1733
2888
|
items: [
|
|
1734
2889
|
{
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
icon: "
|
|
2890
|
+
kind: "item",
|
|
2891
|
+
id: "keyboard-shortcuts",
|
|
2892
|
+
label: "Keyboard shortcuts",
|
|
2893
|
+
icon: "info",
|
|
2894
|
+
shortcut: "Ctrl+/",
|
|
2895
|
+
dialog: "keyboard-shortcuts"
|
|
1739
2896
|
},
|
|
2897
|
+
{ kind: "separator", id: "sep-help" },
|
|
2898
|
+
{ kind: "item", id: "about", label: "About casual sheets", icon: "info", dialog: "about" },
|
|
1740
2899
|
{
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
icon: "
|
|
1745
|
-
|
|
1746
|
-
{
|
|
1747
|
-
id: "toggle-gridlines",
|
|
1748
|
-
label: "Toggle gridlines",
|
|
1749
|
-
command: "sheet.command.toggle-gridlines",
|
|
1750
|
-
icon: "grid_on"
|
|
2900
|
+
kind: "item",
|
|
2901
|
+
id: "github",
|
|
2902
|
+
label: "View on GitHub",
|
|
2903
|
+
icon: "open_in_new",
|
|
2904
|
+
run: () => window.open("https://github.com/CasualOffice/sheets", "_blank")
|
|
1751
2905
|
}
|
|
1752
2906
|
]
|
|
1753
2907
|
}
|
|
@@ -1781,7 +2935,7 @@ var MENU_BTN_STYLE = {
|
|
|
1781
2935
|
var DROPDOWN_STYLE = {
|
|
1782
2936
|
position: "absolute",
|
|
1783
2937
|
top: "100%",
|
|
1784
|
-
minWidth:
|
|
2938
|
+
minWidth: 220,
|
|
1785
2939
|
marginTop: 2,
|
|
1786
2940
|
padding: 4,
|
|
1787
2941
|
display: "flex",
|
|
@@ -1808,8 +2962,63 @@ var ITEM_STYLE3 = {
|
|
|
1808
2962
|
fontSize: 13,
|
|
1809
2963
|
textAlign: "left"
|
|
1810
2964
|
};
|
|
1811
|
-
|
|
2965
|
+
var SEPARATOR_STYLE = {
|
|
2966
|
+
height: 1,
|
|
2967
|
+
margin: "4px 6px",
|
|
2968
|
+
background: "var(--cs-chrome-border, #e6e9ee)"
|
|
2969
|
+
};
|
|
2970
|
+
var SHORTCUT_STYLE = {
|
|
2971
|
+
marginLeft: "auto",
|
|
2972
|
+
paddingLeft: 16,
|
|
2973
|
+
fontSize: 11,
|
|
2974
|
+
color: "var(--cs-chrome-muted, #6b7280)"
|
|
2975
|
+
};
|
|
2976
|
+
var SUBMENU_PANEL_STYLE = {
|
|
2977
|
+
position: "absolute",
|
|
2978
|
+
top: -4,
|
|
2979
|
+
left: "100%",
|
|
2980
|
+
minWidth: 200,
|
|
2981
|
+
marginLeft: 2,
|
|
2982
|
+
padding: 4,
|
|
2983
|
+
display: "flex",
|
|
2984
|
+
flexDirection: "column",
|
|
2985
|
+
border: "1px solid var(--cs-chrome-border, #e6e9ee)",
|
|
2986
|
+
borderRadius: 8,
|
|
2987
|
+
background: "var(--cs-chrome-input-bg, #fff)",
|
|
2988
|
+
boxShadow: "0 6px 20px rgba(0,0,0,0.16)",
|
|
2989
|
+
zIndex: 1001
|
|
2990
|
+
};
|
|
2991
|
+
function featureOn(feature, features) {
|
|
2992
|
+
if (!feature) return true;
|
|
2993
|
+
return features[feature] !== false;
|
|
2994
|
+
}
|
|
2995
|
+
function keepItem(item, features, hasDialogHost) {
|
|
2996
|
+
if (!featureOn(item.feature, features)) return null;
|
|
2997
|
+
if (item.kind === "separator") return item;
|
|
2998
|
+
if (item.kind === "submenu") {
|
|
2999
|
+
const items = filterItems(item.items, features, hasDialogHost);
|
|
3000
|
+
if (items.length === 0) return null;
|
|
3001
|
+
return { ...item, items };
|
|
3002
|
+
}
|
|
3003
|
+
if (item.dialog && !hasDialogHost) return null;
|
|
3004
|
+
return item;
|
|
3005
|
+
}
|
|
3006
|
+
function filterItems(items, features, hasDialogHost) {
|
|
3007
|
+
const kept = items.map((i) => keepItem(i, features, hasDialogHost)).filter((i) => i !== null);
|
|
3008
|
+
const out = [];
|
|
3009
|
+
for (const item of kept) {
|
|
3010
|
+
if (item.kind === "separator") {
|
|
3011
|
+
if (out.length === 0) continue;
|
|
3012
|
+
if (out[out.length - 1].kind === "separator") continue;
|
|
3013
|
+
}
|
|
3014
|
+
out.push(item);
|
|
3015
|
+
}
|
|
3016
|
+
while (out.length > 0 && out[out.length - 1].kind === "separator") out.pop();
|
|
3017
|
+
return out;
|
|
3018
|
+
}
|
|
3019
|
+
function MenuBar({ api, features = {}, onDialogRequest }) {
|
|
1812
3020
|
const [open, setOpen] = useState8(null);
|
|
3021
|
+
const [openSubmenu, setOpenSubmenu] = useState8(null);
|
|
1813
3022
|
const rootRef = useRef6(null);
|
|
1814
3023
|
useEffect8(() => {
|
|
1815
3024
|
ensureChromeFonts();
|
|
@@ -1817,10 +3026,16 @@ function MenuBar({ api }) {
|
|
|
1817
3026
|
useEffect8(() => {
|
|
1818
3027
|
if (open === null) return;
|
|
1819
3028
|
const onKey = (e) => {
|
|
1820
|
-
if (e.key === "Escape")
|
|
3029
|
+
if (e.key === "Escape") {
|
|
3030
|
+
setOpen(null);
|
|
3031
|
+
setOpenSubmenu(null);
|
|
3032
|
+
}
|
|
1821
3033
|
};
|
|
1822
3034
|
const onDown = (e) => {
|
|
1823
|
-
if (!rootRef.current?.contains(e.target))
|
|
3035
|
+
if (!rootRef.current?.contains(e.target)) {
|
|
3036
|
+
setOpen(null);
|
|
3037
|
+
setOpenSubmenu(null);
|
|
3038
|
+
}
|
|
1824
3039
|
};
|
|
1825
3040
|
document.addEventListener("keydown", onKey);
|
|
1826
3041
|
document.addEventListener("pointerdown", onDown, true);
|
|
@@ -1829,10 +3044,90 @@ function MenuBar({ api }) {
|
|
|
1829
3044
|
document.removeEventListener("pointerdown", onDown, true);
|
|
1830
3045
|
};
|
|
1831
3046
|
}, [open]);
|
|
1832
|
-
const
|
|
3047
|
+
const close = () => {
|
|
1833
3048
|
setOpen(null);
|
|
1834
|
-
|
|
3049
|
+
setOpenSubmenu(null);
|
|
3050
|
+
};
|
|
3051
|
+
const runItem = (item) => {
|
|
3052
|
+
close();
|
|
3053
|
+
if (!api) return;
|
|
3054
|
+
if (item.dialog) {
|
|
3055
|
+
const seeded = item.dialog === "insert-chart" || item.dialog === "insert-pivot" || item.dialog === "insert-sparkline" || item.dialog === "insert-cells" || item.dialog === "delete-cells";
|
|
3056
|
+
onDialogRequest?.(item.dialog, seeded ? selectionA1(api) : void 0);
|
|
3057
|
+
return;
|
|
3058
|
+
}
|
|
3059
|
+
item.run?.(api);
|
|
1835
3060
|
};
|
|
3061
|
+
const hasDialogHost = !!onDialogRequest;
|
|
3062
|
+
const visibleMenus = MENUS.map((menu) => ({
|
|
3063
|
+
...menu,
|
|
3064
|
+
items: filterItems(menu.items, features, hasDialogHost)
|
|
3065
|
+
})).filter((menu) => featureOn(menu.feature, features) && menu.items.length > 0);
|
|
3066
|
+
const renderItems = (items) => items.map((item) => {
|
|
3067
|
+
if (item.kind === "separator") {
|
|
3068
|
+
return /* @__PURE__ */ jsx9("div", { style: SEPARATOR_STYLE, role: "separator", "aria-hidden": true }, item.id);
|
|
3069
|
+
}
|
|
3070
|
+
if (item.kind === "submenu") {
|
|
3071
|
+
const isSubOpen = openSubmenu === item.id;
|
|
3072
|
+
return /* @__PURE__ */ jsxs8(
|
|
3073
|
+
"div",
|
|
3074
|
+
{
|
|
3075
|
+
style: { position: "relative" },
|
|
3076
|
+
onMouseEnter: () => setOpenSubmenu(item.id),
|
|
3077
|
+
onMouseLeave: () => setOpenSubmenu((cur) => cur === item.id ? null : cur),
|
|
3078
|
+
children: [
|
|
3079
|
+
/* @__PURE__ */ jsxs8(
|
|
3080
|
+
"button",
|
|
3081
|
+
{
|
|
3082
|
+
type: "button",
|
|
3083
|
+
role: "menuitem",
|
|
3084
|
+
"data-testid": `cs-menuitem-${item.id}`,
|
|
3085
|
+
"aria-haspopup": "menu",
|
|
3086
|
+
"aria-expanded": isSubOpen,
|
|
3087
|
+
disabled: !api,
|
|
3088
|
+
style: { ...ITEM_STYLE3, opacity: api ? 1 : 0.5 },
|
|
3089
|
+
onMouseDown: (e) => e.preventDefault(),
|
|
3090
|
+
children: [
|
|
3091
|
+
item.icon ? /* @__PURE__ */ jsx9(Icon, { name: item.icon, size: 18 }) : /* @__PURE__ */ jsx9("span", { style: { width: 18 }, "aria-hidden": true }),
|
|
3092
|
+
/* @__PURE__ */ jsx9("span", { children: item.label }),
|
|
3093
|
+
/* @__PURE__ */ jsx9(Icon, { name: "chevron_right", size: 18, style: { marginLeft: "auto" } })
|
|
3094
|
+
]
|
|
3095
|
+
}
|
|
3096
|
+
),
|
|
3097
|
+
isSubOpen && /* @__PURE__ */ jsx9("div", { style: SUBMENU_PANEL_STYLE, role: "menu", "aria-label": item.label, children: renderItems(item.items) })
|
|
3098
|
+
]
|
|
3099
|
+
},
|
|
3100
|
+
item.id
|
|
3101
|
+
);
|
|
3102
|
+
}
|
|
3103
|
+
return /* @__PURE__ */ jsxs8(
|
|
3104
|
+
"button",
|
|
3105
|
+
{
|
|
3106
|
+
type: "button",
|
|
3107
|
+
role: "menuitem",
|
|
3108
|
+
"data-testid": `cs-menuitem-${item.id}`,
|
|
3109
|
+
disabled: !api,
|
|
3110
|
+
style: { ...ITEM_STYLE3, opacity: api ? 1 : 0.5 },
|
|
3111
|
+
onMouseDown: (e) => {
|
|
3112
|
+
e.preventDefault();
|
|
3113
|
+
runItem(item);
|
|
3114
|
+
},
|
|
3115
|
+
onMouseEnter: (e) => {
|
|
3116
|
+
setOpenSubmenu(null);
|
|
3117
|
+
e.currentTarget.style.background = "var(--cs-chrome-hover, rgba(0,0,0,0.06))";
|
|
3118
|
+
},
|
|
3119
|
+
onMouseLeave: (e) => {
|
|
3120
|
+
e.currentTarget.style.background = "transparent";
|
|
3121
|
+
},
|
|
3122
|
+
children: [
|
|
3123
|
+
item.icon ? /* @__PURE__ */ jsx9(Icon, { name: item.icon, size: 18 }) : /* @__PURE__ */ jsx9("span", { style: { width: 18 }, "aria-hidden": true }),
|
|
3124
|
+
/* @__PURE__ */ jsx9("span", { children: item.label }),
|
|
3125
|
+
item.shortcut && /* @__PURE__ */ jsx9("span", { style: SHORTCUT_STYLE, children: fmtShortcut(item.shortcut) })
|
|
3126
|
+
]
|
|
3127
|
+
},
|
|
3128
|
+
item.id
|
|
3129
|
+
);
|
|
3130
|
+
});
|
|
1836
3131
|
return /* @__PURE__ */ jsx9(
|
|
1837
3132
|
"div",
|
|
1838
3133
|
{
|
|
@@ -1841,7 +3136,7 @@ function MenuBar({ api }) {
|
|
|
1841
3136
|
"data-testid": "cs-menubar",
|
|
1842
3137
|
role: "menubar",
|
|
1843
3138
|
"aria-label": "Menu bar",
|
|
1844
|
-
children:
|
|
3139
|
+
children: visibleMenus.map((menu) => {
|
|
1845
3140
|
const isOpen = open === menu.id;
|
|
1846
3141
|
return /* @__PURE__ */ jsxs8("div", { style: { position: "relative" }, children: [
|
|
1847
3142
|
/* @__PURE__ */ jsx9(
|
|
@@ -1849,6 +3144,7 @@ function MenuBar({ api }) {
|
|
|
1849
3144
|
{
|
|
1850
3145
|
type: "button",
|
|
1851
3146
|
"data-menu": menu.id,
|
|
3147
|
+
"data-testid": `cs-menu-${menu.id}`,
|
|
1852
3148
|
"aria-haspopup": "menu",
|
|
1853
3149
|
"aria-expanded": isOpen,
|
|
1854
3150
|
style: {
|
|
@@ -1858,11 +3154,14 @@ function MenuBar({ api }) {
|
|
|
1858
3154
|
},
|
|
1859
3155
|
onMouseDown: (e) => {
|
|
1860
3156
|
e.preventDefault();
|
|
3157
|
+
setOpenSubmenu(null);
|
|
1861
3158
|
setOpen((cur) => cur === menu.id ? null : menu.id);
|
|
1862
3159
|
},
|
|
1863
3160
|
onMouseEnter: (e) => {
|
|
1864
|
-
if (open !== null && open !== menu.id)
|
|
1865
|
-
|
|
3161
|
+
if (open !== null && open !== menu.id) {
|
|
3162
|
+
setOpen(menu.id);
|
|
3163
|
+
setOpenSubmenu(null);
|
|
3164
|
+
} else if (!isOpen)
|
|
1866
3165
|
e.currentTarget.style.background = "var(--cs-chrome-hover, rgba(0,0,0,0.06))";
|
|
1867
3166
|
},
|
|
1868
3167
|
onMouseLeave: (e) => {
|
|
@@ -1871,31 +3170,7 @@ function MenuBar({ api }) {
|
|
|
1871
3170
|
children: menu.label
|
|
1872
3171
|
}
|
|
1873
3172
|
),
|
|
1874
|
-
isOpen && /* @__PURE__ */ jsx9("div", { style: DROPDOWN_STYLE, role: "menu", "aria-label": menu.label, children: menu.items
|
|
1875
|
-
"button",
|
|
1876
|
-
{
|
|
1877
|
-
type: "button",
|
|
1878
|
-
role: "menuitem",
|
|
1879
|
-
"data-testid": `cs-menuitem-${item.id}`,
|
|
1880
|
-
disabled: !api,
|
|
1881
|
-
style: { ...ITEM_STYLE3, opacity: api ? 1 : 0.5 },
|
|
1882
|
-
onMouseDown: (e) => {
|
|
1883
|
-
e.preventDefault();
|
|
1884
|
-
run(item);
|
|
1885
|
-
},
|
|
1886
|
-
onMouseEnter: (e) => {
|
|
1887
|
-
e.currentTarget.style.background = "var(--cs-chrome-hover, rgba(0,0,0,0.06))";
|
|
1888
|
-
},
|
|
1889
|
-
onMouseLeave: (e) => {
|
|
1890
|
-
e.currentTarget.style.background = "transparent";
|
|
1891
|
-
},
|
|
1892
|
-
children: [
|
|
1893
|
-
item.icon ? /* @__PURE__ */ jsx9(Icon, { name: item.icon, size: 18 }) : /* @__PURE__ */ jsx9("span", { style: { width: 18 }, "aria-hidden": true }),
|
|
1894
|
-
/* @__PURE__ */ jsx9("span", { children: item.label })
|
|
1895
|
-
]
|
|
1896
|
-
},
|
|
1897
|
-
item.id
|
|
1898
|
-
)) })
|
|
3173
|
+
isOpen && /* @__PURE__ */ jsx9("div", { style: DROPDOWN_STYLE, role: "menu", "aria-label": menu.label, children: renderItems(menu.items) })
|
|
1899
3174
|
] }, menu.id);
|
|
1900
3175
|
})
|
|
1901
3176
|
}
|
|
@@ -2520,9 +3795,9 @@ function replaceInString(text, query, replacement, matchCase) {
|
|
|
2520
3795
|
}
|
|
2521
3796
|
|
|
2522
3797
|
// src/chrome/ChromeTop.tsx
|
|
2523
|
-
import { Fragment as
|
|
3798
|
+
import { Fragment as Fragment3, jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
2524
3799
|
function ChromeTop({ api }) {
|
|
2525
|
-
return /* @__PURE__ */ jsxs11(
|
|
3800
|
+
return /* @__PURE__ */ jsxs11(Fragment3, { children: [
|
|
2526
3801
|
/* @__PURE__ */ jsx12(MenuBar, { api }),
|
|
2527
3802
|
/* @__PURE__ */ jsx12(Toolbar, { api }),
|
|
2528
3803
|
/* @__PURE__ */ jsx12(FormulaBar, { api })
|
|
@@ -2530,9 +3805,9 @@ function ChromeTop({ api }) {
|
|
|
2530
3805
|
}
|
|
2531
3806
|
|
|
2532
3807
|
// src/chrome/ChromeBottom.tsx
|
|
2533
|
-
import { Fragment as
|
|
3808
|
+
import { Fragment as Fragment4, jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
2534
3809
|
function ChromeBottom({ api }) {
|
|
2535
|
-
return /* @__PURE__ */ jsxs12(
|
|
3810
|
+
return /* @__PURE__ */ jsxs12(Fragment4, { children: [
|
|
2536
3811
|
/* @__PURE__ */ jsx13(SheetTabs, { api }),
|
|
2537
3812
|
/* @__PURE__ */ jsx13(StatusBar, { api }),
|
|
2538
3813
|
/* @__PURE__ */ jsx13(FindReplace, { api })
|