@schukai/monster 4.41.0 → 4.42.1

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.
@@ -187,6 +187,12 @@ class DataTable extends CustomElement {
187
187
  * @property {boolean} features.doubleClickCopyToClipboard Double click copy to clipboard feature
188
188
  * @property {boolean} features.copyAll Copy all feature
189
189
  * @property {boolean} features.help Help feature
190
+ * @property {boolean} features.resizeable Columns are resizable
191
+ * @property {Object} copy Copy configuration
192
+ * @property {string} copy.delimiter Delimiter character
193
+ * @property {string} copy.quoteOpen Quote open character
194
+ * @property {string} copy.quoteClose Quote close character
195
+ * @property {string} copy.rowBreak Row break character
190
196
  * @property {Object} templateMapping Template mapping
191
197
  * @property {string} templateMapping.row-key Row key
192
198
  * @property {string} templateMapping.filter-id Filter id
@@ -203,7 +209,7 @@ class DataTable extends CustomElement {
203
209
 
204
210
  datasource: {
205
211
  selector: null,
206
- orderDelimiter: ",", // look at initOptionsFromArguments()
212
+ orderDelimiter: ",", // see initOptionsFromArguments()
207
213
  },
208
214
 
209
215
  mapping: {
@@ -232,6 +238,7 @@ class DataTable extends CustomElement {
232
238
  doubleClickCopyToClipboard: true,
233
239
  copyAll: true,
234
240
  help: true,
241
+ resizable: true,
235
242
  },
236
243
 
237
244
  copy: {
@@ -431,7 +438,9 @@ class DataTable extends CustomElement {
431
438
  const selectAll = this[gridHeadersElementSymbol].querySelector(
432
439
  `[data-monster-role="select-all"]`,
433
440
  );
434
- selectAll.checked = false;
441
+ if (selectAll instanceof HTMLInputElement) {
442
+ selectAll.checked = false;
443
+ }
435
444
 
436
445
  getSlottedElements
437
446
  .call(this, "[data-monster-role=row-action-button]", "bar")
@@ -750,27 +759,107 @@ function updateConfigColumnBar() {
750
759
  function initEventHandler() {
751
760
  const self = this;
752
761
 
762
+ // --- Column resizing state ---
763
+ let isResizing = false;
764
+ let resizingColumnIndex = -1;
765
+ let startX = 0;
766
+ let startWidth = 0;
767
+
768
+ // --- Pointer-based resize handlers (robust for mouse/touch/stylus) ---
769
+ const onPointerDown = (event) => {
770
+ // Important: Call helper with (attrName, value) – not with CSS selector
771
+ const resizeHandle = findTargetElementFromEvent(
772
+ event,
773
+ "data-monster-role",
774
+ "resize-handle",
775
+ );
776
+ if (!resizeHandle) return;
777
+
778
+ event.preventDefault();
779
+ isResizing = true;
780
+
781
+ const headerCell = resizeHandle.closest("[data-monster-index]");
782
+ resizingColumnIndex = parseInt(
783
+ headerCell.getAttribute("data-monster-index"),
784
+ 10,
785
+ );
786
+ startX = event.clientX;
787
+ startWidth = headerCell.offsetWidth;
788
+
789
+ // Capture to prevent losing events during fast dragging
790
+ event.target.setPointerCapture?.(event.pointerId);
791
+
792
+ getWindow().addEventListener("pointermove", onPointerMove);
793
+ getWindow().addEventListener("pointerup", onPointerUp);
794
+
795
+ // Global cursor styling during resizing
796
+ self.shadowRoot.host.classList.add("is-resizing");
797
+ };
798
+
799
+ const onPointerMove = (event) => {
800
+ if (!isResizing) return;
801
+
802
+ const deltaX = event.clientX - startX;
803
+ let newWidth = startWidth + deltaX;
804
+
805
+ const headers = self.getOption("headers");
806
+ const resizingHeader = headers[resizingColumnIndex];
807
+
808
+ const minWidth = 50;
809
+
810
+ const visibleHeaders = headers.filter(
811
+ (h) => h.getInternal("mode") !== ATTRIBUTE_DATATABLE_MODE_HIDDEN,
812
+ );
813
+ const numOtherVisibleColumns =
814
+ visibleHeaders.length > 1 ? visibleHeaders.length - 1 : 0;
815
+
816
+ const reservedSpaceForOthers = numOtherVisibleColumns * 50;
817
+ const tableContainerWidth = self[gridElementSymbol].clientWidth;
818
+ const maxWidth = tableContainerWidth - reservedSpaceForOthers;
819
+
820
+ newWidth = Math.max(minWidth, Math.min(newWidth, maxWidth));
821
+
822
+ resizingHeader.setInternal("grid", `${newWidth}px`);
823
+
824
+ updateGrid.call(self);
825
+ };
826
+
827
+ const onPointerUp = () => {
828
+ if (!isResizing) return;
829
+
830
+ isResizing = false;
831
+ getWindow().removeEventListener("pointermove", onPointerMove);
832
+ getWindow().removeEventListener("pointerup", onPointerUp);
833
+
834
+ self.shadowRoot.host.classList.remove("is-resizing");
835
+ };
836
+
837
+ // Use pointer events instead of mouse: more resilient
838
+ this[gridHeadersElementSymbol].addEventListener("pointerdown", onPointerDown);
839
+
840
+ // --- Copy configuration ---
753
841
  const quoteOpenChar = this.getOption("copy.quoteOpen");
754
842
  const quoteCloseChar = this.getOption("copy.quoteClose");
755
843
  const delimiterChar = this.getOption("copy.delimiter");
756
844
  const rowBreak = this.getOption("copy.rowBreak");
757
845
 
758
- self[columnBarElementSymbol].attachObserver(
759
- new Observer((e) => {
760
- updateHeaderFromColumnBar.call(self);
761
- updateGrid.call(self);
762
- updateConfigColumnBar.call(self);
763
- }),
764
- );
846
+ // --- Column-Bar -> Header visibility & persistence ---
847
+ if (self[columnBarElementSymbol]) {
848
+ self[columnBarElementSymbol].attachObserver(
849
+ new Observer(() => {
850
+ updateHeaderFromColumnBar.call(self);
851
+ updateGrid.call(self);
852
+ updateConfigColumnBar.call(self);
853
+ }),
854
+ );
855
+ }
765
856
 
857
+ // --- Sorting (click on header link) ---
766
858
  self[gridHeadersElementSymbol].addEventListener("click", function (event) {
767
- let element = null;
768
859
  const datasource = self[datasourceLinkedElementSymbol];
769
- if (!datasource) {
770
- return;
771
- }
860
+ if (!datasource) return;
772
861
 
773
- element = findTargetElementFromEvent(event, ATTRIBUTE_DATATABLE_SORTABLE);
862
+ const element = findTargetElementFromEvent(event, "data-monster-sortable");
774
863
  if (element instanceof HTMLElement) {
775
864
  const index = element.parentNode?.getAttribute(ATTRIBUTE_DATATABLE_INDEX);
776
865
  const headers = self.getOption("headers");
@@ -780,7 +869,6 @@ function initEventHandler() {
780
869
  headers[index].changeDirection();
781
870
 
782
871
  queueMicrotask(function () {
783
- /** hotfix, normally this should be done via the updater, no idea why this is not possible. */
784
872
  element.setAttribute(
785
873
  ATTRIBUTE_DATATABLE_SORTABLE,
786
874
  `${headers[index].field} ${headers[index].direction}`,
@@ -791,57 +879,57 @@ function initEventHandler() {
791
879
  }
792
880
  });
793
881
 
882
+ // --- Double-Click Copy (column or entire row with Shift) ---
794
883
  const eventHandlerDoubleClickCopyToClipboard = (event) => {
795
- const element = findTargetElementFromEvent(event, "data-monster-head");
796
- if (element) {
797
- let text = "";
798
-
799
- if (event.shiftKey) {
800
- const index = element.getAttribute("data-monster-insert-reference");
801
- if (index) {
802
- const cols = self.getGridElements(
803
- `[data-monster-insert-reference="${index}"]`,
804
- );
805
-
806
- const colTexts = [];
807
- for (let i = 0; i < cols.length; i++) {
808
- const col = cols[i];
809
-
810
- if (
811
- col.querySelector("monster-button-bar") ||
812
- col.querySelector("monster-button")
813
- ) {
814
- continue;
815
- }
884
+ const headCell = findTargetElementFromEvent(event, "data-monster-head");
885
+ if (!headCell) return;
816
886
 
817
- if (col.textContent) {
818
- colTexts.push(
819
- quoteOpenChar + col.textContent.trim() + quoteCloseChar,
820
- );
821
- }
887
+ let text = "";
888
+
889
+ if (event.shiftKey) {
890
+ const index = headCell.getAttribute("data-monster-insert-reference");
891
+ if (index) {
892
+ const cols = self.getGridElements(
893
+ `[data-monster-insert-reference="${index}"]`,
894
+ );
895
+
896
+ const colTexts = [];
897
+ for (let i = 0; i < cols.length; i++) {
898
+ const col = cols[i];
899
+
900
+ if (
901
+ col.querySelector("monster-button-bar") ||
902
+ col.querySelector("monster-button")
903
+ ) {
904
+ continue;
822
905
  }
823
906
 
824
- text = colTexts.join(delimiterChar);
825
- }
826
- } else {
827
- if (
828
- element.querySelector("monster-button-bar") ||
829
- element.querySelector("monster-button")
830
- ) {
831
- return;
907
+ if (col.textContent) {
908
+ colTexts.push(
909
+ quoteOpenChar + col.textContent.trim() + quoteCloseChar,
910
+ );
911
+ }
832
912
  }
833
913
 
834
- text = element.textContent.trim();
914
+ text = colTexts.join(delimiterChar);
835
915
  }
836
-
837
- if (getWindow().navigator.clipboard && text) {
838
- getWindow()
839
- .navigator.clipboard.writeText(text)
840
- .then(
841
- () => {},
842
- (err) => {},
843
- );
916
+ } else {
917
+ if (
918
+ headCell.querySelector("monster-button-bar") ||
919
+ headCell.querySelector("monster-button")
920
+ ) {
921
+ return;
844
922
  }
923
+ text = headCell.textContent.trim();
924
+ }
925
+
926
+ if (getWindow().navigator.clipboard && text) {
927
+ getWindow()
928
+ .navigator.clipboard.writeText(text)
929
+ .then(
930
+ () => {},
931
+ () => {},
932
+ );
845
933
  }
846
934
  };
847
935
 
@@ -852,13 +940,13 @@ function initEventHandler() {
852
940
  );
853
941
  }
854
942
 
943
+ // --- Copy All ---
855
944
  if (self.getOption("features.copyAll") && this[copyAllElementSymbol]) {
856
945
  this[copyAllElementSymbol].addEventListener("click", (event) => {
857
946
  event.preventDefault();
858
947
 
859
948
  const table = [];
860
949
  let currentRow = [];
861
- let currentIndex = null;
862
950
 
863
951
  const cols = self.getGridElements(`[data-monster-insert-reference]`);
864
952
  const rowIndexes = new Map();
@@ -867,13 +955,13 @@ function initEventHandler() {
867
955
  rowIndexes.set(index, true);
868
956
  });
869
957
 
870
- rowIndexes.forEach((value, key) => {
871
- const cols = self.getGridElements(
958
+ rowIndexes.forEach((_, key) => {
959
+ const rowCols = self.getGridElements(
872
960
  `[data-monster-insert-reference="${key}"]`,
873
961
  );
874
962
 
875
- for (let i = 0; i < cols.length; i++) {
876
- const col = cols[i];
963
+ for (let i = 0; i < rowCols.length; i++) {
964
+ const col = rowCols[i];
877
965
 
878
966
  if (
879
967
  col.querySelector("monster-button-bar") ||
@@ -902,114 +990,93 @@ function initEventHandler() {
902
990
  .navigator.clipboard.writeText(text)
903
991
  .then(
904
992
  () => {},
905
- (err) => {},
993
+ () => {},
906
994
  );
907
995
  }
908
996
  }
909
997
  });
910
998
  }
911
999
 
1000
+ // --- Row Selection (single) ---
912
1001
  const selectRowCallback = (event) => {
913
- const element = findTargetElementFromEvent(
1002
+ const checkbox = findTargetElementFromEvent(
914
1003
  event,
915
1004
  "data-monster-role",
916
1005
  "select-row",
917
1006
  );
918
1007
 
919
- if (!(element instanceof HTMLInputElement)) {
920
- return;
921
- }
922
-
923
- const parentNode = element.parentNode;
924
- if (!(parentNode instanceof HTMLDivElement)) {
925
- return;
926
- }
1008
+ if (!(checkbox instanceof HTMLInputElement)) return;
927
1009
 
928
- const key = element.parentNode.getAttribute(
929
- "data-monster-insert-reference",
930
- );
1010
+ const parentNode = checkbox.parentNode;
1011
+ if (!(parentNode instanceof HTMLDivElement)) return;
931
1012
 
1013
+ const key = parentNode.getAttribute("data-monster-insert-reference");
932
1014
  const row = self.getGridElements(
933
1015
  `[data-monster-insert-reference="${key}"]`,
934
1016
  );
935
-
936
1017
  const index = key.split("-").pop();
937
1018
 
938
- if (element.checked) {
939
- row.forEach((col) => {
940
- col.classList.add("selected");
941
- });
942
-
943
- fireCustomEvent(self, "monster-datatable-row-selected", {
944
- index: index,
945
- });
1019
+ if (checkbox.checked) {
1020
+ row.forEach((col) => col.classList.add("selected"));
1021
+ fireCustomEvent(self, "monster-datatable-row-selected", { index });
946
1022
  } else {
947
- row.forEach((col) => {
948
- col.classList.remove("selected");
949
- });
950
-
951
- fireCustomEvent(self, "monster-datatable-row-deselected", {
952
- index: index,
953
- });
1023
+ row.forEach((col) => col.classList.remove("selected"));
1024
+ fireCustomEvent(self, "monster-datatable-row-deselected", { index });
954
1025
  }
955
1026
 
956
1027
  fireCustomEvent(this, "monster-datatable-selection-changed", {});
957
1028
 
958
1029
  const rows = self.getGridElements(`[data-monster-role="select-row"]`);
959
- const allSelected = Array.from(rows).every((row) => row.checked);
1030
+ const allSelected = Array.from(rows).every((r) => r.checked);
960
1031
 
961
1032
  const selectAll = this[gridHeadersElementSymbol].querySelector(
962
1033
  `[data-monster-role="select-all"]`,
963
1034
  );
964
1035
 
1036
+ // Row-Action-Buttons visible/invisible depending on selection
965
1037
  getSlottedElements
966
1038
  .call(this, "[data-monster-role=row-action-button]", "bar")
967
1039
  .forEach((i, e) => {
968
1040
  const selected = self.getSelectedRows();
969
1041
  const mode = selected.length === 0 ? "hidden" : "visible";
970
- if (e instanceof HTMLElement) {
971
- e.style.visibility = mode;
972
- }
1042
+ if (e instanceof HTMLElement) e.style.visibility = mode;
973
1043
  });
974
1044
 
975
- if (selectAll) {
976
- selectAll.checked = allSelected;
977
- }
1045
+ if (selectAll) selectAll.checked = allSelected;
978
1046
  };
979
1047
 
980
1048
  this[gridElementSymbol].addEventListener("click", selectRowCallback);
981
1049
  this[gridElementSymbol].addEventListener("touch", selectRowCallback);
982
1050
 
1051
+ // --- Row Selection (all) ---
983
1052
  const selectAllCallback = (event) => {
984
- const element = findTargetElementFromEvent(
1053
+ const toggle = findTargetElementFromEvent(
985
1054
  event,
986
1055
  "data-monster-role",
987
1056
  "select-all",
988
1057
  );
989
- if (element) {
990
- const mode = element.checked;
1058
+ if (!toggle) return;
991
1059
 
992
- const rows = this.getGridElements(`[data-monster-role="select-row"]`);
993
- rows.forEach((row) => {
994
- row.checked = mode;
995
- });
1060
+ const mode = toggle.checked;
1061
+ const rows = this.getGridElements(`[data-monster-role="select-row"]`);
1062
+ rows.forEach((row) => {
1063
+ row.checked = mode;
1064
+ });
996
1065
 
997
- if (mode) {
998
- fireCustomEvent(this, "monster-datatable-all-rows-selected", {});
999
- } else {
1000
- fireCustomEvent(this, "monster-datatable-all-rows-deselected", {});
1001
- }
1066
+ if (mode) {
1067
+ fireCustomEvent(this, "monster-datatable-all-rows-selected", {});
1068
+ } else {
1069
+ fireCustomEvent(this, "monster-datatable-all-rows-deselected", {});
1070
+ }
1002
1071
 
1003
- getSlottedElements
1004
- .call(this, "[data-monster-role=row-action-button]", "bar")
1005
- .forEach((i, e) => {
1006
- if (e instanceof HTMLElement) {
1007
- e.style.visibility = mode ? "visible" : "hidden";
1008
- }
1009
- });
1072
+ getSlottedElements
1073
+ .call(this, "[data-monster-role=row-action-button]", "bar")
1074
+ .forEach((i, e) => {
1075
+ if (e instanceof HTMLElement)
1076
+ e.style.visibility = mode ? "visible" : "hidden";
1077
+ });
1010
1078
 
1011
- fireCustomEvent(this, "monster-datatable-selection-changed", {});
1012
- }
1079
+ fireCustomEvent(this, "monster-datatable-selection-changed", {});
1013
1080
  };
1014
1081
 
1015
1082
  this[gridHeadersElementSymbol].addEventListener("click", selectAllCallback);
@@ -1156,6 +1223,7 @@ function initGridAndStructs(hostConfig, headerOrderMap) {
1156
1223
  orderTemplate = row.getAttribute("data-monster-order-template");
1157
1224
  }
1158
1225
 
1226
+ const isResizable = this.getOption("features.resizable");
1159
1227
  const header = new Header();
1160
1228
  header.setInternals({
1161
1229
  field: field,
@@ -1168,14 +1236,26 @@ function initGridAndStructs(hostConfig, headerOrderMap) {
1168
1236
  direction: direction,
1169
1237
  features: features,
1170
1238
  orderTemplate: orderTemplate,
1239
+ resizable: isResizable,
1171
1240
  });
1172
1241
 
1173
1242
  headers.push(header);
1174
1243
  }
1175
1244
 
1176
1245
  this.setOption("headers", headers);
1177
- queueMicrotask(() => {
1246
+ requestAnimationFrame(() => {
1178
1247
  storeOrderStatement.call(this, this.getOption("features.autoInit"));
1248
+
1249
+ const headerElements = this[gridHeadersElementSymbol].querySelectorAll(
1250
+ "[data-monster-index]",
1251
+ );
1252
+ headerElements.forEach((cell) => {
1253
+ const index = parseInt(cell.getAttribute("data-monster-index"), 10);
1254
+ if (headers[index]) {
1255
+ console.log("store initial width for header", index, cell.offsetWidth);
1256
+ headers[index].setInternal("initialWidth", cell.offsetWidth);
1257
+ }
1258
+ });
1179
1259
  });
1180
1260
  }
1181
1261
 
@@ -50,7 +50,6 @@
50
50
  align-items: center;
51
51
  gap: 2rem;
52
52
  }
53
-
54
53
  }
55
54
 
56
55
  :host {
@@ -58,6 +57,12 @@
58
57
  margin: 0;
59
58
  }
60
59
 
60
+
61
+ :host(.is-resizing) {
62
+ cursor: col-resize;
63
+ user-select: none;
64
+ }
65
+
61
66
  ::slotted(.monster-button-group) {
62
67
  margin: 0 !important;
63
68
  flex-grow: 2;
@@ -81,7 +86,6 @@
81
86
  line-height: 1.2;
82
87
  border-bottom: 1px dashed var(--monster-theme-control-border-color);
83
88
  box-sizing: border-box;
84
-
85
89
  min-width: 0;
86
90
  overflow: auto;
87
91
 
@@ -129,13 +133,11 @@
129
133
  }
130
134
 
131
135
  @for $i from 0 to 500 {
132
- &:has([data-monster-insert-reference$=row-$(i)]:hover) [data-monster-insert-reference$=row-$(i)
133
-
134
- ] {
135
- color: var(--monster-theme-control-hover-color);
136
- background-color: var(--monster-theme-control-hover-bg-color);
137
- box-sizing: border-box;
138
- }
136
+ &:has([data-monster-insert-reference$=row-$(i)]:hover) [data-monster-insert-reference$=row-$(i)] {
137
+ color: var(--monster-theme-control-hover-color);
138
+ background-color: var(--monster-theme-control-hover-bg-color);
139
+ box-sizing: border-box;
140
+ }
139
141
  }
140
142
 
141
143
  & .monster-form {
@@ -143,7 +145,6 @@
143
145
  flex-direction: column;
144
146
  gap: 0.5rem;
145
147
  }
146
-
147
148
  }
148
149
 
149
150
 
@@ -162,7 +163,6 @@
162
163
  display: none;
163
164
  }
164
165
  }
165
-
166
166
  }
167
167
 
168
168
  [data-monster-role=datatable-headers] {
@@ -172,13 +172,19 @@
172
172
  @mixin text;
173
173
  font-weight: bold;
174
174
  padding: 0.3rem 0.2rem;
175
+ position: relative;
175
176
  display: flex;
176
177
  align-items: center;
177
- justify-content: flex-start;
178
- text-overflow: ellipsis;
179
- white-space: nowrap;
180
- overflow: hidden;
181
- max-width: 100%;
178
+ justify-content: flex-start;
179
+ overflow: visible;
180
+ padding-right: 28px;
181
+
182
+ & a[data-monster-sortable] {
183
+ flex-grow: 1;
184
+ overflow: hidden;
185
+ text-overflow: ellipsis;
186
+ white-space: nowrap;
187
+ }
182
188
 
183
189
  & a[data-monster-sortable]:after {
184
190
  content: "";
@@ -212,8 +218,38 @@
212
218
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M8 1a.5.5 0 0 1 .5.5v11.793l3.146-3.147a.5.5 0 0 1 .708.708l-4 4a.5.5 0 0 1-.708 0l-4-4a.5.5 0 0 1 .708-.708L7.5 13.293V1.5A.5.5 0 0 1 8 1z'/%3E%3C/svg%3E");
213
219
  mask-size: cover;
214
220
  }
221
+
222
+ & .resize-handle {
223
+ position: absolute;
224
+ right: 0;
225
+ top: 0;
226
+ bottom: 0;
227
+ width: 20px;
228
+ cursor: col-resize;
229
+ display: flex;
230
+ align-items: center;
231
+ justify-content: center;
232
+ z-index: 10;
233
+ opacity: 1;
234
+ transition: opacity 0.15s ease-in-out, transform 0.05s ease-in-out;
235
+ pointer-events: auto;
215
236
  }
216
237
 
238
+ & .resize-handle svg {
239
+ width: 14px;
240
+ height: 20px;
241
+ pointer-events: none;
242
+ transform: scale(1.4);
243
+ }
244
+
245
+ &:hover .resize-handle {
246
+ opacity: 1;
247
+ }
248
+
249
+ & .resize-handle:active {
250
+ transform: scale(1.05);
251
+ }
252
+ }
217
253
 
218
254
  & .flex-start {
219
255
  justify-content: flex-start;
@@ -226,7 +262,6 @@
226
262
  & .flex-center {
227
263
  justify-content: center;
228
264
  }
229
-
230
265
  }
231
266
 
232
267
  a[data-monster-role="copy-all"] {
@@ -271,7 +306,6 @@ monster-state[data-monster-role=empty-without-action]::part(action) {
271
306
 
272
307
  [data-monster-role="control"].small {
273
308
 
274
-
275
309
  & [data-monster-role="datatable-headers"] {
276
310
  display: none;
277
311
  }
@@ -292,12 +326,9 @@ monster-state[data-monster-role=empty-without-action]::part(action) {
292
326
  }
293
327
 
294
328
  @for $i from 0 to 500 {
295
- &:has([data-monster-insert-reference=row-$(i)]:hover) [data-monster-insert-reference=row-$(i)
296
-
297
- ] {
298
- /*background-color: var(--monster-bg-color-selection-2);*/
299
- box-sizing: border-box;
300
- }
329
+ &:has([data-monster-insert-reference=row-$(i)]:hover) [data-monster-insert-reference=row-$(i)] {
330
+ box-sizing: border-box;
331
+ }
301
332
  }
302
333
  }
303
334
 
@@ -305,10 +336,8 @@ monster-state[data-monster-role=empty-without-action]::part(action) {
305
336
  display: flex;
306
337
  flex-direction: column !important;
307
338
  }
308
-
309
339
  }
310
340
 
311
-
312
341
  [data-monster-role=control].small {
313
342
 
314
343
  ::slotted(.monster-button-group) {
@@ -331,16 +360,5 @@ monster-state[data-monster-role=empty-without-action]::part(action) {
331
360
  &.center {
332
361
  justify-content: flex-start;
333
362
  }
334
-
335
363
  }
336
-
337
- }
338
-
339
-
340
-
341
-
342
-
343
-
344
-
345
-
346
-
364
+ }