@guiexpert/table 1.1.96 → 1.1.98

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.
Files changed (41) hide show
  1. package/README.md +7 -0
  2. package/css/main.css +192 -27
  3. package/css/table-classes.css +33 -9
  4. package/css/table-color-vars.css +12 -0
  5. package/css/table-fill-batch.css +9 -2
  6. package/css/table-master-detail.css +115 -0
  7. package/css/table-tree.css +23 -16
  8. package/index.cjs +50 -50
  9. package/index.d.ts +12 -0
  10. package/index.js +3996 -2631
  11. package/lib/table/aria/aria-ids.d.ts +7 -0
  12. package/lib/table/aria/aria-texts.d.ts +2 -0
  13. package/lib/table/aria/aria-texts.if.d.ts +14 -0
  14. package/lib/table/crud/crud-object-edit.d.ts +2 -0
  15. package/lib/table/crud/crud-object-view.d.ts +2 -0
  16. package/lib/table/crud/crud-table-model-factory.d.ts +2 -0
  17. package/lib/table/data/common/event/ge-detail-event.d.ts +40 -0
  18. package/lib/table/data/options/auto-restore-options.d.ts +2 -0
  19. package/lib/table/data/options/auto-restore-options.if.d.ts +6 -0
  20. package/lib/table/data/options/table-options.d.ts +8 -0
  21. package/lib/table/data/options/table-options.if.d.ts +35 -0
  22. package/lib/table/ele-scope.d.ts +51 -0
  23. package/lib/table/event-adapter.d.ts +3 -0
  24. package/lib/table/event-listener.if.d.ts +7 -0
  25. package/lib/table/master-detail/detail-renderer.if.d.ts +99 -0
  26. package/lib/table/master-detail/master-detail-options.d.ts +30 -0
  27. package/lib/table/master-detail/master-detail-options.if.d.ts +60 -0
  28. package/lib/table/master-detail/master-detail-service.d.ts +223 -0
  29. package/lib/table/render-scope.d.ts +73 -0
  30. package/lib/table/row-layout/row-layout.d.ts +120 -0
  31. package/lib/table/rtl/rtl-util.d.ts +126 -0
  32. package/lib/table/rtl/table-direction.type.d.ts +23 -0
  33. package/lib/table/service/convenience-dom.service.d.ts +49 -1
  34. package/lib/table/service/excel-export-options.if.d.ts +17 -0
  35. package/lib/table/service/excel-service.d.ts +8 -2
  36. package/lib/table/service/excel-service.if.d.ts +3 -1
  37. package/lib/table/state/table-state.if.d.ts +4 -1
  38. package/lib/table/state/table-state.service.d.ts +4 -0
  39. package/lib/table/table-api.d.ts +123 -2
  40. package/lib/table/table-scope.d.ts +69 -0
  41. package/package.json +1 -1
package/README.md CHANGED
@@ -54,6 +54,13 @@ This is the UI-agnostic table component for your next web app. 😊
54
54
  dates, `Item 1` → `Item 2`; ⌥/Alt switches, Ctrl/⌘+D, Ctrl/⌘+R), batch edit collects changes (`ge-table-cell-pending`)
55
55
  until `tableApi.commitBatchEdit()` / `cancelBatchEdit()`, `ColumnDef.validate`, one `onModelChanged` per change with
56
56
  old and new values (`tableOptions.fillHandle`, `tableOptions.batchEdit`) – since 1.1.96
57
+ - Master/detail: expandable rows with a detail row over the full width (nested table, form, framework component),
58
+ created lazily and kept while scrolling, fixed or measured height, keyboard (Enter, Tab) and screen readers
59
+ (`aria-expanded`), `tableApi.setDetailExpanded()` / `expandAllDetails()`, stored with the table state
60
+ (`tableOptions.masterDetail`) – since 1.1.97. Variable row heights use prefix sums (O(log n) per scroll frame)
61
+ - Right-to-left (Arabic, Hebrew, Persian, Urdu): `tableOptions.direction: "rtl"` (or `"auto"` from the page) mirrors
62
+ the whole table – first column on the right, horizontal scrolling, fixed columns, tree indent, resize handles, fill
63
+ handle, row drag, master/detail, arrow keys; right-to-left Excel sheet – since 1.1.98
57
64
  - Custom Filtering
58
65
  - In-place Cell Editing
59
66
  - Userdefined Key and Mouse Events
package/css/main.css CHANGED
@@ -49,8 +49,8 @@
49
49
 
50
50
 
51
51
  .ge-table-label-div .ge-table-label {
52
- padding-left: 10px;
53
- padding-right: 10px;
52
+ padding-inline-start: 10px;
53
+ padding-inline-end: 10px;
54
54
  }
55
55
 
56
56
  /* Total rows of AreaModelAggregateFooter (1.1.94) – before the align classes, so a column's footer class wins */
@@ -74,21 +74,45 @@
74
74
  overflow: visible;
75
75
  }
76
76
 
77
+ /* "left" and "right" describe the left-to-right layout: start and end of the row – mirrored in right-to-left
78
+ (direction: "rtl", since 1.1.98). A column that must stay physically right needs its own class. */
77
79
  .ge-table-text-align-left {
78
- text-align: left;
80
+ text-align: start;
79
81
  }
80
82
 
81
83
  .ge-table-text-align-right {
84
+ text-align: end;
85
+ }
86
+
87
+ .ge-table-text-align-start {
88
+ text-align: start;
89
+ }
90
+
91
+ .ge-table-text-align-end {
92
+ text-align: end;
93
+ }
94
+
95
+ /* Latin text with punctuation in a right-to-left table ("Rossi S.p.A." would show as ".Rossi S.p.A"): every label gets
96
+ the direction of its own text (unicode-bidi: plaintext) and stays aligned to the start of the table (since 1.1.98). */
97
+ .ge-table-text-plaintext {
98
+ text-align: left;
99
+ }
100
+
101
+ .ge-table[dir="rtl"] .ge-table-text-plaintext:not(.ge-table[dir="rtl"] .ge-table[dir="ltr"] .ge-table-text-plaintext) {
82
102
  text-align: right;
83
103
  }
84
104
 
105
+ .ge-table-text-plaintext .ge-table-label {
106
+ unicode-bidi: plaintext;
107
+ }
108
+
85
109
  .ge-table-text-align-center {
86
110
  text-align: center;
87
111
  }
88
112
 
89
113
  /* Row checkbox */
90
114
  .ge-table-row-checkbox-div {
91
- padding-left: 14px;
115
+ padding-inline-start: 14px;
92
116
  }
93
117
  .ge-table-body-east {
94
118
  z-index: 999;
@@ -112,10 +136,10 @@
112
136
  overflow-y: auto;
113
137
  table th,
114
138
  table td {
115
- text-align: left;
139
+ text-align: start;
116
140
 
117
141
  &:nth-child(2) {
118
- padding-left: 12px;
142
+ padding-inline-start: 12px;
119
143
  }
120
144
  &.ge-table-crud-object-view-object-child {
121
145
  font-weight: bold;
@@ -152,7 +176,7 @@
152
176
  justify-items: stretch;
153
177
  label {
154
178
  align-self: end;
155
- text-align: right;
179
+ text-align: end;
156
180
  line-height: 2;
157
181
  }
158
182
  }
@@ -176,9 +200,9 @@
176
200
  }
177
201
 
178
202
 
179
- /* room for the sort icon (20px, absolute, right) – otherwise it covers right-aligned header labels */
203
+ /* room for the sort icon (20px, absolute, at the end) – otherwise it covers end-aligned header labels */
180
204
  .ge-table-col-div:has(> .ge-table-sorted-icon-div) .ge-table-label {
181
- padding-right: 22px;
205
+ padding-inline-end: 22px;
182
206
  }
183
207
 
184
208
 
@@ -487,6 +511,12 @@
487
511
  --ge-table-cell-invalid-bg: #fde2e1;
488
512
  --ge-table-cell-invalid-text: #8a1c14;
489
513
  --ge-table-cell-invalid-border: #d93025;
514
+
515
+ /* Master/detail (since 1.1.97): the detail row below an expanded master row */
516
+ --ge-table-detail-bg: #f4f6f9;
517
+ --ge-table-detail-border: #c9d1db;
518
+ --ge-table-detail-toggle-color: #5f6368;
519
+ --ge-table-detail-toggle-hover-bg: rgba(128, 128, 128, 0.15);
490
520
  }
491
521
 
492
522
 
@@ -608,16 +638,24 @@ html[data-theme="dark"] {
608
638
  --ge-table-cell-invalid-bg: #5c1d1a;
609
639
  --ge-table-cell-invalid-text: #fecaca;
610
640
  --ge-table-cell-invalid-border: #f28b82;
641
+
642
+ /* Master/detail (since 1.1.97) */
643
+ --ge-table-detail-bg: #1b1f24;
644
+ --ge-table-detail-border: #3c434d;
645
+ --ge-table-detail-toggle-color: #bdc1c6;
646
+ --ge-table-detail-toggle-hover-bg: rgba(255, 255, 255, 0.12);
611
647
  }
612
648
  /* Fill handle and batch edit (since 1.1.96) – colors in table-color-vars.css (--ge-table-fill-*, --ge-table-cell-*) */
613
649
 
614
- /* the square at the bottom right corner of the selected range; its center sits on the corner */
650
+ /* the square at the bottom end corner of the selected range (right-to-left: bottom left); its center sits on it */
615
651
  .ge-table-fill-handle {
616
652
  position: absolute;
617
653
  z-index: 9000; /* above the cells, below the overlay (10000) */
618
654
  width: 7px;
619
655
  height: 7px;
620
- margin: -4px 0 0 -4px;
656
+ margin: 0;
657
+ margin-block-start: -4px;
658
+ margin-inline-start: -4px;
621
659
  box-sizing: border-box;
622
660
  background: var(--ge-table-fill-handle-color);
623
661
  border: 1px solid var(--ge-table-fill-handle-border);
@@ -652,6 +690,11 @@ html[data-theme="dark"] {
652
690
  background-image: linear-gradient(225deg, var(--ge-table-cell-pending-marker) 6px, transparent 6px);
653
691
  }
654
692
 
693
+ /* right-to-left: the corner mark at the top end (left) */
694
+ .ge-table[dir="rtl"] .ge-table-col-div.ge-table-cell-pending:not(.ge-table[dir="rtl"] .ge-table[dir="ltr"] .ge-table-col-div.ge-table-cell-pending) {
695
+ background-image: linear-gradient(135deg, var(--ge-table-cell-pending-marker) 6px, transparent 6px);
696
+ }
697
+
655
698
  /* the color only while the cell is not selected – a selected cell keeps the selection color (and the corner mark) */
656
699
  .ge-table-col-div.ge-table-cell-pending:not([class*="-selected-range"]) {
657
700
  background-color: var(--ge-table-cell-pending-bg);
@@ -667,6 +710,121 @@ html[data-theme="dark"] {
667
710
  .ge-table-col-div.ge-table-cell-invalid {
668
711
  box-shadow: inset 0 0 0 2px var(--ge-table-cell-invalid-border);
669
712
  }
713
+ /* Master/detail (since 1.1.97) – colors in table-color-vars.css (--ge-table-detail-*) */
714
+
715
+ /* the layer over the visible body (full width, fixed columns included, without the scroll bars); positioned by the
716
+ table. Only the detail rows take pointer events – the body cells between them stay clickable. */
717
+ .ge-table-detail-layer {
718
+ position: absolute;
719
+ z-index: 1000; /* above .ge-table-body-east (999), below the fill preview (8999), focus frame (9999), overlay (10000) */
720
+ overflow: hidden;
721
+ pointer-events: none;
722
+ }
723
+
724
+ .ge-table-detail-row {
725
+ position: absolute;
726
+ inset-inline: 0;
727
+ box-sizing: border-box;
728
+ pointer-events: auto;
729
+ background: var(--ge-table-detail-bg);
730
+ border-top: 1px solid var(--ge-table-detail-border);
731
+ border-bottom: 1px solid var(--ge-table-detail-border);
732
+ }
733
+
734
+ /* scrolled out of view: hidden, not destroyed – the content keeps its state (inputs, scroll positions) */
735
+ .ge-table-detail-row.ge-table-detail-row-parked {
736
+ visibility: hidden;
737
+ content-visibility: hidden;
738
+ }
739
+
740
+ .ge-table-detail-cell {
741
+ box-sizing: border-box;
742
+ width: 100%;
743
+ height: 100%;
744
+ padding-block: 8px;
745
+ padding-inline: 32px 12px;
746
+ overflow: auto;
747
+ }
748
+
749
+ /* detailHeight "auto": the row is as high as its content (measured) */
750
+ .ge-table-detail-row-auto .ge-table-detail-cell {
751
+ height: auto;
752
+ overflow: visible;
753
+ }
754
+
755
+ /* a nested table (context.createTable) */
756
+ .ge-table-detail-table {
757
+ width: 100%;
758
+ position: relative;
759
+ }
760
+
761
+ /* the cell with the expand icon: room for the icon at the start */
762
+ .ge-table-detail-toggle-cell {
763
+ box-sizing: border-box;
764
+ padding-inline-start: 22px;
765
+ }
766
+
767
+ /* behind a row drag handle */
768
+ .ge-table-row-drag-cell.ge-table-detail-toggle-cell {
769
+ padding-inline-start: 36px;
770
+ }
771
+
772
+ .ge-table-detail-toggle {
773
+ position: absolute;
774
+ inset-inline-start: 3px;
775
+ top: 50%;
776
+ width: 16px;
777
+ height: 16px;
778
+ margin-top: -8px;
779
+ border-radius: 3px;
780
+ cursor: pointer;
781
+ }
782
+
783
+ .ge-table-row-drag-cell .ge-table-detail-toggle {
784
+ inset-inline-start: 17px;
785
+ }
786
+
787
+ .ge-table-detail-toggle:hover {
788
+ background-color: var(--ge-table-detail-toggle-hover-bg);
789
+ }
790
+
791
+ /* a chevron drawn with CSS: ▸ collapsed, ▾ expanded */
792
+ .ge-table-detail-toggle::before {
793
+ content: "";
794
+ position: absolute;
795
+ inset-inline-start: 5px;
796
+ top: 4px;
797
+ width: 0;
798
+ height: 0;
799
+ border-style: solid;
800
+ border-width: 4px 0 4px 6px;
801
+ border-color: transparent transparent transparent var(--ge-table-detail-toggle-color);
802
+ transition: transform 0.12s ease-out;
803
+ }
804
+
805
+ .ge-table-detail-toggle.ge-table-detail-toggle-expanded::before {
806
+ transform: rotate(90deg);
807
+ }
808
+
809
+ /* right-to-left (since 1.1.98): the triangle points to the left, expanded down */
810
+ .ge-table[dir="rtl"] .ge-table-detail-toggle:not(.ge-table[dir="rtl"] .ge-table[dir="ltr"] .ge-table-detail-toggle)::before {
811
+ border-width: 4px 6px 4px 0;
812
+ border-color: transparent var(--ge-table-detail-toggle-color) transparent transparent;
813
+ }
814
+
815
+ .ge-table[dir="rtl"] .ge-table-detail-toggle.ge-table-detail-toggle-expanded:not(.ge-table[dir="rtl"] .ge-table[dir="ltr"] .ge-table-detail-toggle.ge-table-detail-toggle-expanded)::before {
816
+ transform: rotate(-90deg);
817
+ }
818
+
819
+ /* right-to-left (since 1.1.98): the triangle points to the left, expanded down */
820
+ .ge-table[dir="rtl"] .ge-table-detail-toggle:not(.ge-table[dir="rtl"] .ge-table[dir="ltr"] .ge-table-detail-toggle)::before {
821
+ border-width: 4px 6px 4px 0;
822
+ border-color: transparent var(--ge-table-detail-toggle-color) transparent transparent;
823
+ }
824
+
825
+ .ge-table[dir="rtl"] .ge-table-detail-toggle.ge-table-detail-toggle-expanded:not(.ge-table[dir="rtl"] .ge-table[dir="ltr"] .ge-table-detail-toggle.ge-table-detail-toggle-expanded)::before {
826
+ transform: rotate(-90deg);
827
+ }
670
828
  /* Pivot tables (PivotFactory / AreaModelPivot, since 1.1.94) */
671
829
 
672
830
  /* every value cell: numbers on the end side, same digit widths */
@@ -818,23 +976,23 @@ html[data-theme="dark"] {
818
976
  /* Tree table */
819
977
 
820
978
  .ge-table-col-div.ge-table-col-div-0.ge-table-tree-cell {
821
- text-align: left;
979
+ text-align: start;
822
980
  }
823
981
 
824
982
  .ge-table-tree-cell .ge-table-label-div {
825
- padding-left: 0;
826
- padding-right: 10px;
983
+ padding-inline-start: 0;
984
+ padding-inline-end: 10px;
827
985
  display: inline;
828
986
  }
829
987
 
830
988
 
831
989
  .ge-table-col-tree {
832
- text-align: left;
990
+ text-align: start;
833
991
  }
834
992
 
835
993
  /* Row numbers (RowNumberColumnDef) in a tree: no tree look – right aligned like in a flat table (since 1.1.93) */
836
994
  .ge-table-col-div.ge-table-row-number.ge-table-tree-cell {
837
- text-align: right;
995
+ text-align: end;
838
996
  }
839
997
  .ge-table-row-number.ge-table-tree-cell .ge-table-label-div {
840
998
  display: block;
@@ -842,47 +1000,47 @@ html[data-theme="dark"] {
842
1000
  }
843
1001
 
844
1002
  .ge-padding-property-checkbox {
845
- padding-left: 0;
1003
+ padding-inline-start: 0;
846
1004
  }
847
1005
 
848
1006
  .ge-table-col-tree.ge-table-tree-deep-0 {
849
- padding-left: 16px;
1007
+ padding-inline-start: 16px;
850
1008
  }
851
1009
 
852
1010
  .ge-table-col-tree.ge-table-tree-deep-1 {
853
- padding-left: 36px;
1011
+ padding-inline-start: 36px;
854
1012
  }
855
1013
 
856
1014
  .ge-table-col-tree.ge-table-tree-deep-2 {
857
- padding-left: 56px;
1015
+ padding-inline-start: 56px;
858
1016
  }
859
1017
 
860
1018
  .ge-table-col-tree.ge-table-tree-deep-3 {
861
- padding-left: 76px;
1019
+ padding-inline-start: 76px;
862
1020
  }
863
1021
 
864
1022
  .ge-table-col-tree.ge-table-tree-deep-4 {
865
- padding-left: 96px;
1023
+ padding-inline-start: 96px;
866
1024
  }
867
1025
 
868
1026
  .ge-table-col-tree.ge-table-tree-deep-5 {
869
- padding-left: 116px;
1027
+ padding-inline-start: 116px;
870
1028
  }
871
1029
 
872
1030
  .ge-table-col-tree.ge-table-tree-deep-6 {
873
- padding-left: 136px;
1031
+ padding-inline-start: 136px;
874
1032
  }
875
1033
 
876
1034
  .ge-table-col-tree.ge-table-tree-deep-7 {
877
- padding-left: 156px;
1035
+ padding-inline-start: 156px;
878
1036
  }
879
1037
 
880
1038
  .ge-table-col-tree.ge-table-tree-deep-8 {
881
- padding-left: 176px;
1039
+ padding-inline-start: 176px;
882
1040
  }
883
1041
 
884
1042
  .ge-table-col-tree.ge-table-tree-deep-9 {
885
- padding-left: 196px;
1043
+ padding-inline-start: 196px;
886
1044
  }
887
1045
 
888
1046
  .ge-table-col-div.ge-table-col-tree.ge-table-tree-cell {
@@ -893,3 +1051,10 @@ html[data-theme="dark"] {
893
1051
  display: grid;
894
1052
  grid-template-columns: 16px 20px 1fr;
895
1053
  }
1054
+
1055
+ /* Right-to-left (direction: "rtl", since 1.1.98): the arrow ">" is mirrored by the browser ("<"), so the expanded
1056
+ arrow of the default icon turns the other way (its transform is an inline style: !important). */
1057
+ .ge-table[dir="rtl"] .gt-table-tree-arrow-expanded:not(.ge-table[dir="rtl"] .ge-table[dir="ltr"] .gt-table-tree-arrow-expanded) {
1058
+ transform: rotate(-90deg) translate(-66%, -66%) !important;
1059
+ transform-origin: 100% 0 !important;
1060
+ }
@@ -42,8 +42,8 @@
42
42
 
43
43
 
44
44
  .ge-table-label-div .ge-table-label {
45
- padding-left: 10px;
46
- padding-right: 10px;
45
+ padding-inline-start: 10px;
46
+ padding-inline-end: 10px;
47
47
  }
48
48
 
49
49
  /* Total rows of AreaModelAggregateFooter (1.1.94) – before the align classes, so a column's footer class wins */
@@ -67,21 +67,45 @@
67
67
  overflow: visible;
68
68
  }
69
69
 
70
+ /* "left" and "right" describe the left-to-right layout: start and end of the row – mirrored in right-to-left
71
+ (direction: "rtl", since 1.1.98). A column that must stay physically right needs its own class. */
70
72
  .ge-table-text-align-left {
71
- text-align: left;
73
+ text-align: start;
72
74
  }
73
75
 
74
76
  .ge-table-text-align-right {
77
+ text-align: end;
78
+ }
79
+
80
+ .ge-table-text-align-start {
81
+ text-align: start;
82
+ }
83
+
84
+ .ge-table-text-align-end {
85
+ text-align: end;
86
+ }
87
+
88
+ /* Latin text with punctuation in a right-to-left table ("Rossi S.p.A." would show as ".Rossi S.p.A"): every label gets
89
+ the direction of its own text (unicode-bidi: plaintext) and stays aligned to the start of the table (since 1.1.98). */
90
+ .ge-table-text-plaintext {
91
+ text-align: left;
92
+ }
93
+
94
+ .ge-table[dir="rtl"] .ge-table-text-plaintext:not(.ge-table[dir="rtl"] .ge-table[dir="ltr"] .ge-table-text-plaintext) {
75
95
  text-align: right;
76
96
  }
77
97
 
98
+ .ge-table-text-plaintext .ge-table-label {
99
+ unicode-bidi: plaintext;
100
+ }
101
+
78
102
  .ge-table-text-align-center {
79
103
  text-align: center;
80
104
  }
81
105
 
82
106
  /* Row checkbox */
83
107
  .ge-table-row-checkbox-div {
84
- padding-left: 14px;
108
+ padding-inline-start: 14px;
85
109
  }
86
110
  .ge-table-body-east {
87
111
  z-index: 999;
@@ -105,10 +129,10 @@
105
129
  overflow-y: auto;
106
130
  table th,
107
131
  table td {
108
- text-align: left;
132
+ text-align: start;
109
133
 
110
134
  &:nth-child(2) {
111
- padding-left: 12px;
135
+ padding-inline-start: 12px;
112
136
  }
113
137
  &.ge-table-crud-object-view-object-child {
114
138
  font-weight: bold;
@@ -145,7 +169,7 @@
145
169
  justify-items: stretch;
146
170
  label {
147
171
  align-self: end;
148
- text-align: right;
172
+ text-align: end;
149
173
  line-height: 2;
150
174
  }
151
175
  }
@@ -169,9 +193,9 @@
169
193
  }
170
194
 
171
195
 
172
- /* room for the sort icon (20px, absolute, right) – otherwise it covers right-aligned header labels */
196
+ /* room for the sort icon (20px, absolute, at the end) – otherwise it covers end-aligned header labels */
173
197
  .ge-table-col-div:has(> .ge-table-sorted-icon-div) .ge-table-label {
174
- padding-right: 22px;
198
+ padding-inline-end: 22px;
175
199
  }
176
200
 
177
201
 
@@ -130,6 +130,12 @@ html, html[data-theme="light"] {
130
130
  --ge-table-cell-invalid-bg: #fde2e1;
131
131
  --ge-table-cell-invalid-text: #8a1c14;
132
132
  --ge-table-cell-invalid-border: #d93025;
133
+
134
+ /* Master/detail (since 1.1.97): the detail row below an expanded master row */
135
+ --ge-table-detail-bg: #f4f6f9;
136
+ --ge-table-detail-border: #c9d1db;
137
+ --ge-table-detail-toggle-color: #5f6368;
138
+ --ge-table-detail-toggle-hover-bg: rgba(128, 128, 128, 0.15);
133
139
  }
134
140
 
135
141
 
@@ -251,4 +257,10 @@ html[data-theme="dark"] {
251
257
  --ge-table-cell-invalid-bg: #5c1d1a;
252
258
  --ge-table-cell-invalid-text: #fecaca;
253
259
  --ge-table-cell-invalid-border: #f28b82;
260
+
261
+ /* Master/detail (since 1.1.97) */
262
+ --ge-table-detail-bg: #1b1f24;
263
+ --ge-table-detail-border: #3c434d;
264
+ --ge-table-detail-toggle-color: #bdc1c6;
265
+ --ge-table-detail-toggle-hover-bg: rgba(255, 255, 255, 0.12);
254
266
  }
@@ -1,12 +1,14 @@
1
1
  /* Fill handle and batch edit (since 1.1.96) – colors in table-color-vars.css (--ge-table-fill-*, --ge-table-cell-*) */
2
2
 
3
- /* the square at the bottom right corner of the selected range; its center sits on the corner */
3
+ /* the square at the bottom end corner of the selected range (right-to-left: bottom left); its center sits on it */
4
4
  .ge-table-fill-handle {
5
5
  position: absolute;
6
6
  z-index: 9000; /* above the cells, below the overlay (10000) */
7
7
  width: 7px;
8
8
  height: 7px;
9
- margin: -4px 0 0 -4px;
9
+ margin: 0;
10
+ margin-block-start: -4px;
11
+ margin-inline-start: -4px;
10
12
  box-sizing: border-box;
11
13
  background: var(--ge-table-fill-handle-color);
12
14
  border: 1px solid var(--ge-table-fill-handle-border);
@@ -41,6 +43,11 @@
41
43
  background-image: linear-gradient(225deg, var(--ge-table-cell-pending-marker) 6px, transparent 6px);
42
44
  }
43
45
 
46
+ /* right-to-left: the corner mark at the top end (left) */
47
+ .ge-table[dir="rtl"] .ge-table-col-div.ge-table-cell-pending:not(.ge-table[dir="rtl"] .ge-table[dir="ltr"] .ge-table-col-div.ge-table-cell-pending) {
48
+ background-image: linear-gradient(135deg, var(--ge-table-cell-pending-marker) 6px, transparent 6px);
49
+ }
50
+
44
51
  /* the color only while the cell is not selected – a selected cell keeps the selection color (and the corner mark) */
45
52
  .ge-table-col-div.ge-table-cell-pending:not([class*="-selected-range"]) {
46
53
  background-color: var(--ge-table-cell-pending-bg);
@@ -0,0 +1,115 @@
1
+ /* Master/detail (since 1.1.97) – colors in table-color-vars.css (--ge-table-detail-*) */
2
+
3
+ /* the layer over the visible body (full width, fixed columns included, without the scroll bars); positioned by the
4
+ table. Only the detail rows take pointer events – the body cells between them stay clickable. */
5
+ .ge-table-detail-layer {
6
+ position: absolute;
7
+ z-index: 1000; /* above .ge-table-body-east (999), below the fill preview (8999), focus frame (9999), overlay (10000) */
8
+ overflow: hidden;
9
+ pointer-events: none;
10
+ }
11
+
12
+ .ge-table-detail-row {
13
+ position: absolute;
14
+ inset-inline: 0;
15
+ box-sizing: border-box;
16
+ pointer-events: auto;
17
+ background: var(--ge-table-detail-bg);
18
+ border-top: 1px solid var(--ge-table-detail-border);
19
+ border-bottom: 1px solid var(--ge-table-detail-border);
20
+ }
21
+
22
+ /* scrolled out of view: hidden, not destroyed – the content keeps its state (inputs, scroll positions) */
23
+ .ge-table-detail-row.ge-table-detail-row-parked {
24
+ visibility: hidden;
25
+ content-visibility: hidden;
26
+ }
27
+
28
+ .ge-table-detail-cell {
29
+ box-sizing: border-box;
30
+ width: 100%;
31
+ height: 100%;
32
+ padding-block: 8px;
33
+ padding-inline: 32px 12px;
34
+ overflow: auto;
35
+ }
36
+
37
+ /* detailHeight "auto": the row is as high as its content (measured) */
38
+ .ge-table-detail-row-auto .ge-table-detail-cell {
39
+ height: auto;
40
+ overflow: visible;
41
+ }
42
+
43
+ /* a nested table (context.createTable) */
44
+ .ge-table-detail-table {
45
+ width: 100%;
46
+ position: relative;
47
+ }
48
+
49
+ /* the cell with the expand icon: room for the icon at the start */
50
+ .ge-table-detail-toggle-cell {
51
+ box-sizing: border-box;
52
+ padding-inline-start: 22px;
53
+ }
54
+
55
+ /* behind a row drag handle */
56
+ .ge-table-row-drag-cell.ge-table-detail-toggle-cell {
57
+ padding-inline-start: 36px;
58
+ }
59
+
60
+ .ge-table-detail-toggle {
61
+ position: absolute;
62
+ inset-inline-start: 3px;
63
+ top: 50%;
64
+ width: 16px;
65
+ height: 16px;
66
+ margin-top: -8px;
67
+ border-radius: 3px;
68
+ cursor: pointer;
69
+ }
70
+
71
+ .ge-table-row-drag-cell .ge-table-detail-toggle {
72
+ inset-inline-start: 17px;
73
+ }
74
+
75
+ .ge-table-detail-toggle:hover {
76
+ background-color: var(--ge-table-detail-toggle-hover-bg);
77
+ }
78
+
79
+ /* a chevron drawn with CSS: ▸ collapsed, ▾ expanded */
80
+ .ge-table-detail-toggle::before {
81
+ content: "";
82
+ position: absolute;
83
+ inset-inline-start: 5px;
84
+ top: 4px;
85
+ width: 0;
86
+ height: 0;
87
+ border-style: solid;
88
+ border-width: 4px 0 4px 6px;
89
+ border-color: transparent transparent transparent var(--ge-table-detail-toggle-color);
90
+ transition: transform 0.12s ease-out;
91
+ }
92
+
93
+ .ge-table-detail-toggle.ge-table-detail-toggle-expanded::before {
94
+ transform: rotate(90deg);
95
+ }
96
+
97
+ /* right-to-left (since 1.1.98): the triangle points to the left, expanded down */
98
+ .ge-table[dir="rtl"] .ge-table-detail-toggle:not(.ge-table[dir="rtl"] .ge-table[dir="ltr"] .ge-table-detail-toggle)::before {
99
+ border-width: 4px 6px 4px 0;
100
+ border-color: transparent var(--ge-table-detail-toggle-color) transparent transparent;
101
+ }
102
+
103
+ .ge-table[dir="rtl"] .ge-table-detail-toggle.ge-table-detail-toggle-expanded:not(.ge-table[dir="rtl"] .ge-table[dir="ltr"] .ge-table-detail-toggle.ge-table-detail-toggle-expanded)::before {
104
+ transform: rotate(-90deg);
105
+ }
106
+
107
+ /* right-to-left (since 1.1.98): the triangle points to the left, expanded down */
108
+ .ge-table[dir="rtl"] .ge-table-detail-toggle:not(.ge-table[dir="rtl"] .ge-table[dir="ltr"] .ge-table-detail-toggle)::before {
109
+ border-width: 4px 6px 4px 0;
110
+ border-color: transparent var(--ge-table-detail-toggle-color) transparent transparent;
111
+ }
112
+
113
+ .ge-table[dir="rtl"] .ge-table-detail-toggle.ge-table-detail-toggle-expanded:not(.ge-table[dir="rtl"] .ge-table[dir="ltr"] .ge-table-detail-toggle.ge-table-detail-toggle-expanded)::before {
114
+ transform: rotate(-90deg);
115
+ }