@kispace-io/core 0.7.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.
Files changed (272) hide show
  1. package/dist/api/base-classes.d.ts +7 -0
  2. package/dist/api/base-classes.d.ts.map +1 -0
  3. package/dist/api/constants.d.ts +2 -0
  4. package/dist/api/constants.d.ts.map +1 -0
  5. package/dist/api/index.d.ts +6 -0
  6. package/dist/api/index.d.ts.map +1 -0
  7. package/dist/api/index.js +80 -0
  8. package/dist/api/index.js.map +1 -0
  9. package/dist/api/services.d.ts +27 -0
  10. package/dist/api/services.d.ts.map +1 -0
  11. package/dist/api/types.d.ts +11 -0
  12. package/dist/api/types.d.ts.map +1 -0
  13. package/dist/commands/files.d.ts +2 -0
  14. package/dist/commands/files.d.ts.map +1 -0
  15. package/dist/commands/global.d.ts +1 -0
  16. package/dist/commands/global.d.ts.map +1 -0
  17. package/dist/commands/index.d.ts +1 -0
  18. package/dist/commands/index.d.ts.map +1 -0
  19. package/dist/commands/version-info.d.ts +2 -0
  20. package/dist/commands/version-info.d.ts.map +1 -0
  21. package/dist/components/index.d.ts +1 -0
  22. package/dist/components/index.d.ts.map +1 -0
  23. package/dist/components/k-app-selector.d.ts +17 -0
  24. package/dist/components/k-app-selector.d.ts.map +1 -0
  25. package/dist/components/k-app-switcher.d.ts +13 -0
  26. package/dist/components/k-app-switcher.d.ts.map +1 -0
  27. package/dist/components/k-command.d.ts +31 -0
  28. package/dist/components/k-command.d.ts.map +1 -0
  29. package/dist/components/k-extensions.d.ts +32 -0
  30. package/dist/components/k-extensions.d.ts.map +1 -0
  31. package/dist/components/k-fastviews.d.ts +34 -0
  32. package/dist/components/k-fastviews.d.ts.map +1 -0
  33. package/dist/components/k-filebrowser.d.ts +40 -0
  34. package/dist/components/k-filebrowser.d.ts.map +1 -0
  35. package/dist/components/k-language-selector.d.ts +12 -0
  36. package/dist/components/k-language-selector.d.ts.map +1 -0
  37. package/dist/components/k-log-terminal.d.ts +36 -0
  38. package/dist/components/k-log-terminal.d.ts.map +1 -0
  39. package/dist/components/k-part-name.d.ts +12 -0
  40. package/dist/components/k-part-name.d.ts.map +1 -0
  41. package/dist/components/k-tasks.d.ts +13 -0
  42. package/dist/components/k-tasks.d.ts.map +1 -0
  43. package/dist/components/k-workspace-name.d.ts +14 -0
  44. package/dist/components/k-workspace-name.d.ts.map +1 -0
  45. package/dist/contributions/default-ui-contributions.d.ts +2 -0
  46. package/dist/contributions/default-ui-contributions.d.ts.map +1 -0
  47. package/dist/contributions/index.d.ts +1 -0
  48. package/dist/contributions/index.d.ts.map +1 -0
  49. package/dist/contributions/marketplace-catalog-contributions.d.ts +2 -0
  50. package/dist/contributions/marketplace-catalog-contributions.d.ts.map +1 -0
  51. package/dist/core/app-host-config.d.ts +7 -0
  52. package/dist/core/app-host-config.d.ts.map +1 -0
  53. package/dist/core/apploader.d.ts +214 -0
  54. package/dist/core/apploader.d.ts.map +1 -0
  55. package/dist/core/appstate.d.ts +12 -0
  56. package/dist/core/appstate.d.ts.map +1 -0
  57. package/dist/core/commandregistry.d.ts +79 -0
  58. package/dist/core/commandregistry.d.ts.map +1 -0
  59. package/dist/core/config.d.ts +15 -0
  60. package/dist/core/config.d.ts.map +1 -0
  61. package/dist/core/constants.d.ts +21 -0
  62. package/dist/core/constants.d.ts.map +1 -0
  63. package/dist/core/contributionregistry.d.ts +49 -0
  64. package/dist/core/contributionregistry.d.ts.map +1 -0
  65. package/dist/core/di.d.ts +18 -0
  66. package/dist/core/di.d.ts.map +1 -0
  67. package/dist/core/dialogservice.d.ts +33 -0
  68. package/dist/core/dialogservice.d.ts.map +1 -0
  69. package/dist/core/editorregistry.d.ts +73 -0
  70. package/dist/core/editorregistry.d.ts.map +1 -0
  71. package/dist/core/esmsh-service.d.ts +40 -0
  72. package/dist/core/esmsh-service.d.ts.map +1 -0
  73. package/dist/core/events.d.ts +7 -0
  74. package/dist/core/events.d.ts.map +1 -0
  75. package/dist/core/events.js +63 -0
  76. package/dist/core/events.js.map +1 -0
  77. package/dist/core/extensionregistry.d.ts +98 -0
  78. package/dist/core/extensionregistry.d.ts.map +1 -0
  79. package/dist/core/filesys.d.ts +139 -0
  80. package/dist/core/filesys.d.ts.map +1 -0
  81. package/dist/core/i18n.d.ts +50 -0
  82. package/dist/core/i18n.d.ts.map +1 -0
  83. package/dist/core/index.d.ts +1 -0
  84. package/dist/core/index.d.ts.map +1 -0
  85. package/dist/core/k-utils.d.ts +2 -0
  86. package/dist/core/k-utils.d.ts.map +1 -0
  87. package/dist/core/keybindings.d.ts +67 -0
  88. package/dist/core/keybindings.d.ts.map +1 -0
  89. package/dist/core/logger.d.ts +44 -0
  90. package/dist/core/logger.d.ts.map +1 -0
  91. package/dist/core/marketplaceregistry.d.ts +25 -0
  92. package/dist/core/marketplaceregistry.d.ts.map +1 -0
  93. package/dist/core/packageinfoservice.d.ts +16 -0
  94. package/dist/core/packageinfoservice.d.ts.map +1 -0
  95. package/dist/core/persistenceservice.d.ts +6 -0
  96. package/dist/core/persistenceservice.d.ts.map +1 -0
  97. package/dist/core/settingsservice.d.ts +19 -0
  98. package/dist/core/settingsservice.d.ts.map +1 -0
  99. package/dist/core/signals.d.ts +3 -0
  100. package/dist/core/signals.d.ts.map +1 -0
  101. package/dist/core/taskservice.d.ts +20 -0
  102. package/dist/core/taskservice.d.ts.map +1 -0
  103. package/dist/core/toast.d.ts +4 -0
  104. package/dist/core/toast.d.ts.map +1 -0
  105. package/dist/core/tree-utils.d.ts +16 -0
  106. package/dist/core/tree-utils.d.ts.map +1 -0
  107. package/dist/dialogs/confirm-dialog.d.ts +14 -0
  108. package/dist/dialogs/confirm-dialog.d.ts.map +1 -0
  109. package/dist/dialogs/index.d.ts +5 -0
  110. package/dist/dialogs/index.d.ts.map +1 -0
  111. package/dist/dialogs/info-dialog.d.ts +13 -0
  112. package/dist/dialogs/info-dialog.d.ts.map +1 -0
  113. package/dist/dialogs/navigable-info-dialog.d.ts +33 -0
  114. package/dist/dialogs/navigable-info-dialog.d.ts.map +1 -0
  115. package/dist/dialogs/prompt-dialog.d.ts +21 -0
  116. package/dist/dialogs/prompt-dialog.d.ts.map +1 -0
  117. package/dist/externals/lit.d.ts +20 -0
  118. package/dist/externals/lit.d.ts.map +1 -0
  119. package/dist/externals/lit.js +15 -0
  120. package/dist/externals/lit.js.map +1 -0
  121. package/dist/externals/third-party.d.ts +7 -0
  122. package/dist/externals/third-party.d.ts.map +1 -0
  123. package/dist/externals/third-party.js +2 -0
  124. package/dist/externals/third-party.js.map +1 -0
  125. package/dist/externals/webawesome.d.ts +1 -0
  126. package/dist/externals/webawesome.d.ts.map +1 -0
  127. package/dist/externals/webawesome.js +52 -0
  128. package/dist/externals/webawesome.js.map +1 -0
  129. package/dist/i18n/extensions.json.d.ts +42 -0
  130. package/dist/i18n/fastviews.json.d.ts +13 -0
  131. package/dist/i18n/filebrowser.json.d.ts +35 -0
  132. package/dist/i18n/index.d.ts +2 -0
  133. package/dist/i18n/index.d.ts.map +1 -0
  134. package/dist/i18n/logterminal.json.d.ts +45 -0
  135. package/dist/i18n/partname.json.d.ts +15 -0
  136. package/dist/i18n/tasks.json.d.ts +15 -0
  137. package/dist/i18n/workspace.json.d.ts +15 -0
  138. package/dist/index.d.ts +2 -0
  139. package/dist/index.d.ts.map +1 -0
  140. package/dist/index.js +80 -0
  141. package/dist/index.js.map +1 -0
  142. package/dist/k-icon-BZC7dQV0.js +492 -0
  143. package/dist/k-icon-BZC7dQV0.js.map +1 -0
  144. package/dist/k-nocontent-Bh_yToGh.js +48 -0
  145. package/dist/k-nocontent-Bh_yToGh.js.map +1 -0
  146. package/dist/k-resizable-grid-Ch3iWZaL.js +3157 -0
  147. package/dist/k-resizable-grid-Ch3iWZaL.js.map +1 -0
  148. package/dist/k-standard-layout-CQ1VZoxa.js +5011 -0
  149. package/dist/k-standard-layout-CQ1VZoxa.js.map +1 -0
  150. package/dist/layouts/k-standard-layout.d.ts +16 -0
  151. package/dist/layouts/k-standard-layout.d.ts.map +1 -0
  152. package/dist/parts/index.d.ts +1 -0
  153. package/dist/parts/index.d.ts.map +1 -0
  154. package/dist/parts/index.js +53 -0
  155. package/dist/parts/index.js.map +1 -0
  156. package/dist/parts/k-app.d.ts +11 -0
  157. package/dist/parts/k-app.d.ts.map +1 -0
  158. package/dist/parts/k-container.d.ts +4 -0
  159. package/dist/parts/k-container.d.ts.map +1 -0
  160. package/dist/parts/k-contextmenu.d.ts +38 -0
  161. package/dist/parts/k-contextmenu.d.ts.map +1 -0
  162. package/dist/parts/k-dialog-content.d.ts +9 -0
  163. package/dist/parts/k-dialog-content.d.ts.map +1 -0
  164. package/dist/parts/k-element.d.ts +36 -0
  165. package/dist/parts/k-element.d.ts.map +1 -0
  166. package/dist/parts/k-part.d.ts +96 -0
  167. package/dist/parts/k-part.d.ts.map +1 -0
  168. package/dist/parts/k-resizable-grid.d.ts +31 -0
  169. package/dist/parts/k-resizable-grid.d.ts.map +1 -0
  170. package/dist/parts/k-tabs.d.ts +74 -0
  171. package/dist/parts/k-tabs.d.ts.map +1 -0
  172. package/dist/parts/k-toolbar.d.ts +21 -0
  173. package/dist/parts/k-toolbar.d.ts.map +1 -0
  174. package/dist/widgets/index.d.ts +1 -0
  175. package/dist/widgets/index.d.ts.map +1 -0
  176. package/dist/widgets/index.js +3 -0
  177. package/dist/widgets/index.js.map +1 -0
  178. package/dist/widgets/k-icon.d.ts +10 -0
  179. package/dist/widgets/k-icon.d.ts.map +1 -0
  180. package/dist/widgets/k-nocontent.d.ts +13 -0
  181. package/dist/widgets/k-nocontent.d.ts.map +1 -0
  182. package/dist/widgets/k-widget.d.ts +25 -0
  183. package/dist/widgets/k-widget.d.ts.map +1 -0
  184. package/package.json +81 -0
  185. package/src/api/base-classes.ts +10 -0
  186. package/src/api/constants.ts +3 -0
  187. package/src/api/index.ts +31 -0
  188. package/src/api/services.ts +52 -0
  189. package/src/api/types.ts +46 -0
  190. package/src/commands/files.ts +829 -0
  191. package/src/commands/global.ts +225 -0
  192. package/src/commands/index.ts +4 -0
  193. package/src/commands/version-info.ts +214 -0
  194. package/src/components/index.ts +10 -0
  195. package/src/components/k-app-selector.ts +233 -0
  196. package/src/components/k-app-switcher.ts +126 -0
  197. package/src/components/k-command.ts +236 -0
  198. package/src/components/k-extensions.ts +615 -0
  199. package/src/components/k-fastviews.ts +314 -0
  200. package/src/components/k-filebrowser.ts +442 -0
  201. package/src/components/k-language-selector.ts +166 -0
  202. package/src/components/k-log-terminal.ts +337 -0
  203. package/src/components/k-part-name.ts +54 -0
  204. package/src/components/k-tasks.ts +267 -0
  205. package/src/components/k-workspace-name.ts +56 -0
  206. package/src/contributions/default-ui-contributions.ts +51 -0
  207. package/src/contributions/index.ts +3 -0
  208. package/src/contributions/marketplace-catalog-contributions.ts +6 -0
  209. package/src/core/app-host-config.ts +23 -0
  210. package/src/core/apploader.ts +630 -0
  211. package/src/core/appstate.ts +15 -0
  212. package/src/core/commandregistry.ts +210 -0
  213. package/src/core/config.ts +29 -0
  214. package/src/core/constants.ts +27 -0
  215. package/src/core/contributionregistry.ts +77 -0
  216. package/src/core/di.ts +54 -0
  217. package/src/core/dialogservice.ts +266 -0
  218. package/src/core/editorregistry.ts +303 -0
  219. package/src/core/esmsh-service.ts +404 -0
  220. package/src/core/events.ts +68 -0
  221. package/src/core/extensionregistry.ts +399 -0
  222. package/src/core/filesys.ts +618 -0
  223. package/src/core/i18n.ts +221 -0
  224. package/src/core/index.ts +51 -0
  225. package/src/core/k-utils.ts +11 -0
  226. package/src/core/keybindings.ts +274 -0
  227. package/src/core/logger.ts +187 -0
  228. package/src/core/marketplaceregistry.ts +197 -0
  229. package/src/core/packageinfoservice.ts +56 -0
  230. package/src/core/persistenceservice.ts +15 -0
  231. package/src/core/settingsservice.ts +70 -0
  232. package/src/core/signals.ts +18 -0
  233. package/src/core/taskservice.ts +72 -0
  234. package/src/core/toast.ts +11 -0
  235. package/src/core/tree-utils.ts +24 -0
  236. package/src/dialogs/confirm-dialog.ts +72 -0
  237. package/src/dialogs/index.ts +4 -0
  238. package/src/dialogs/info-dialog.ts +67 -0
  239. package/src/dialogs/navigable-info-dialog.ts +256 -0
  240. package/src/dialogs/prompt-dialog.ts +123 -0
  241. package/src/externals/lit.ts +26 -0
  242. package/src/externals/third-party.ts +9 -0
  243. package/src/externals/webawesome.ts +54 -0
  244. package/src/i18n/extensions.json +39 -0
  245. package/src/i18n/fastviews.json +10 -0
  246. package/src/i18n/filebrowser.json +33 -0
  247. package/src/i18n/index.ts +25 -0
  248. package/src/i18n/logterminal.json +42 -0
  249. package/src/i18n/partname.json +12 -0
  250. package/src/i18n/tasks.json +12 -0
  251. package/src/i18n/workspace.json +12 -0
  252. package/src/icons/icons.txt +3 -0
  253. package/src/icons/js.svg +6 -0
  254. package/src/icons/jupyter.svg +18 -0
  255. package/src/icons/python.svg +15 -0
  256. package/src/index.ts +3 -0
  257. package/src/layouts/k-standard-layout.ts +174 -0
  258. package/src/parts/index.ts +6 -0
  259. package/src/parts/k-app.ts +29 -0
  260. package/src/parts/k-container.ts +4 -0
  261. package/src/parts/k-contextmenu.ts +245 -0
  262. package/src/parts/k-dialog-content.ts +31 -0
  263. package/src/parts/k-element.ts +100 -0
  264. package/src/parts/k-part.ts +158 -0
  265. package/src/parts/k-resizable-grid.ts +366 -0
  266. package/src/parts/k-tabs.ts +574 -0
  267. package/src/parts/k-toolbar.ts +158 -0
  268. package/src/vite-env.d.ts +2 -0
  269. package/src/widgets/index.ts +2 -0
  270. package/src/widgets/k-icon.ts +39 -0
  271. package/src/widgets/k-nocontent.ts +40 -0
  272. package/src/widgets/k-widget.ts +90 -0
@@ -0,0 +1,366 @@
1
+ /**
2
+ * KResizableGrid - A simple resizable grid layout component
3
+ *
4
+ * Uses CSS Grid with explicit column/row templates and manual resize handles.
5
+ * Much simpler and more predictable than flex-based layouts.
6
+ *
7
+ * Features:
8
+ * - Horizontal or vertical orientation
9
+ * - Custom size distribution via 'sizes' attribute
10
+ * - Interactive resize handles between children
11
+ * - Min size constraints (5% of container)
12
+ *
13
+ * Example usage:
14
+ * <k-resizable-grid orientation="horizontal" sizes="20%, 60%, 20%">
15
+ * <div>Left</div>
16
+ * <div>Center</div>
17
+ * <div>Right</div>
18
+ * </k-resizable-grid>
19
+ */
20
+ import {customElement, property, state} from "lit/decorators.js";
21
+ import {html, nothing} from "lit";
22
+ import {KElement} from "./k-element";
23
+
24
+ @customElement('k-resizable-grid')
25
+ export class KResizableGrid extends KElement {
26
+ @property()
27
+ orientation: 'horizontal' | 'vertical' = 'horizontal';
28
+
29
+ @property()
30
+ sizes?: string; // e.g., "20%, 60%, 20%"
31
+
32
+ @state()
33
+ private gridSizes: string[] = [];
34
+
35
+ @state()
36
+ private gridChildren: HTMLElement[] = [];
37
+
38
+ private resizing: {
39
+ handleIndex: number;
40
+ startPos: number;
41
+ startSizes: number[];
42
+ currentSizes?: number[];
43
+ } | null = null;
44
+
45
+ private resizeOverlay: HTMLDivElement | null = null;
46
+ private childrenLoaded = false;
47
+ private childStylesApplied = false;
48
+ private mutationObserver?: MutationObserver;
49
+ private settingsLoaded = false;
50
+
51
+ createRenderRoot() {
52
+ // intentionally disabling shadow DOM for the resizable grid
53
+ return this;
54
+ }
55
+
56
+ // ============= Lifecycle Methods =============
57
+
58
+ protected doBeforeUI() {
59
+ // Only set up observer if children not yet loaded
60
+ if (!this.childrenLoaded) {
61
+ // Use MutationObserver to detect when children are added
62
+ this.mutationObserver = new MutationObserver(() => {
63
+ if (!this.childrenLoaded) {
64
+ this.loadChildren();
65
+ }
66
+ });
67
+
68
+ this.mutationObserver.observe(this, { childList: true, subtree: false });
69
+
70
+ // Also try to load immediately
71
+ this.loadChildren();
72
+ }
73
+ }
74
+
75
+ private async loadChildren() {
76
+ const potentialChildren = Array.from(this.children).filter(
77
+ child => child.tagName !== 'STYLE' &&
78
+ child.tagName !== 'SCRIPT' &&
79
+ !child.classList.contains('resize-handle')
80
+ ) as HTMLElement[];
81
+
82
+ if (potentialChildren.length === 0) {
83
+ return;
84
+ }
85
+
86
+ // Mark as loaded and disconnect observer
87
+ this.childrenLoaded = true;
88
+ if (this.mutationObserver) {
89
+ this.mutationObserver.disconnect();
90
+ this.mutationObserver = undefined;
91
+ }
92
+
93
+ // Store children references
94
+ this.gridChildren = potentialChildren;
95
+
96
+ // Load persisted sizes once if available
97
+ if (!this.settingsLoaded) {
98
+ this.settingsLoaded = true;
99
+ const persisted = await this.getDialogSetting();
100
+ if (persisted && Array.isArray(persisted.sizes) && persisted.sizes.length === this.gridChildren.length) {
101
+ this.gridSizes = persisted.sizes;
102
+ this.requestUpdate();
103
+ return;
104
+ }
105
+ }
106
+
107
+ // Use sizes attribute or equal distribution (only if not restored from settings)
108
+ if (this.sizes) {
109
+ this.gridSizes = this.sizes.split(',').map(s => s.trim());
110
+ } else {
111
+ const equalSize = `${100 / this.gridChildren.length}%`;
112
+ this.gridSizes = this.gridChildren.map(() => equalSize);
113
+ }
114
+
115
+ this.requestUpdate();
116
+ }
117
+
118
+ private async saveSizes() {
119
+ if (this.gridSizes.length === 0) {
120
+ return;
121
+ }
122
+
123
+ await this.setDialogSetting({
124
+ sizes: this.gridSizes,
125
+ orientation: this.orientation
126
+ });
127
+ }
128
+
129
+ updated(changedProperties: Map<string, any>) {
130
+ super.updated(changedProperties);
131
+
132
+ // Only apply child styles once when children are first loaded
133
+ // This prevents interfering with nested resizable grids during resize operations
134
+ if (changedProperties.has('gridChildren') && !this.childStylesApplied && this.gridChildren.length > 0) {
135
+ this.childStylesApplied = true;
136
+
137
+ /**
138
+ * Direct style manipulation is intentionally used here.
139
+ *
140
+ * Reasoning:
141
+ * - Grid positioning (gridColumn/gridRow) must be computed dynamically based on
142
+ * the number of children and orientation at runtime
143
+ * - Shadow DOM is disabled (see createRenderRoot), so we cannot use ::slotted()
144
+ * or scoped CSS selectors to style children
145
+ * - CSS classes alone cannot express the dynamic grid positioning logic
146
+ * (e.g., child at index 0 → column 1, index 1 → column 3, etc.)
147
+ * - This is a layout container whose primary job is to programmatically position
148
+ * its children within a CSS grid system
149
+ */
150
+ this.gridChildren.forEach((child, index) => {
151
+ child.style.overflow = 'hidden';
152
+ child.style.height = '100%';
153
+ child.style.width = '100%';
154
+ child.style.gridColumn = this.orientation === 'horizontal' ? `${index * 2 + 1}` : '1';
155
+ child.style.gridRow = this.orientation === 'vertical' ? `${index * 2 + 1}` : '1';
156
+ child.style.display = 'flex';
157
+ child.style.flexDirection = 'column';
158
+ });
159
+ }
160
+ }
161
+
162
+ // ============= Resize Handling Methods =============
163
+
164
+ private startResize(e: MouseEvent, handleIndex: number) {
165
+ e.preventDefault();
166
+
167
+ if (handleIndex >= this.gridChildren.length - 1) return;
168
+
169
+ const startPos = this.orientation === 'horizontal' ? e.clientX : e.clientY;
170
+
171
+ // Convert all sizes to pixels at the start of resize
172
+ const containerSize = this.orientation === 'horizontal'
173
+ ? this.offsetWidth
174
+ : this.offsetHeight;
175
+
176
+ const startSizes = this.gridSizes.map(size => {
177
+ if (size.endsWith('%')) {
178
+ return (parseFloat(size) / 100) * containerSize;
179
+ } else if (size.endsWith('px')) {
180
+ return parseFloat(size);
181
+ } else {
182
+ return parseFloat(size);
183
+ }
184
+ });
185
+
186
+ this.resizing = {
187
+ handleIndex,
188
+ startPos,
189
+ startSizes
190
+ };
191
+
192
+ // Create overlay to prevent iframes from capturing mouse events
193
+ this.resizeOverlay = document.createElement('div');
194
+ this.resizeOverlay.style.position = 'fixed';
195
+ this.resizeOverlay.style.top = '0';
196
+ this.resizeOverlay.style.left = '0';
197
+ this.resizeOverlay.style.width = '100%';
198
+ this.resizeOverlay.style.height = '100%';
199
+ this.resizeOverlay.style.zIndex = '9999';
200
+ this.resizeOverlay.style.cursor = this.orientation === 'horizontal' ? 'col-resize' : 'row-resize';
201
+ document.body.appendChild(this.resizeOverlay);
202
+
203
+ document.addEventListener('mousemove', this.handleResize);
204
+ document.addEventListener('mouseup', this.stopResize);
205
+
206
+ document.body.style.cursor = this.orientation === 'horizontal' ? 'col-resize' : 'row-resize';
207
+ document.body.style.userSelect = 'none';
208
+ }
209
+
210
+ private handleResize = (e: MouseEvent) => {
211
+ if (!this.resizing) return;
212
+
213
+ const currentPos = this.orientation === 'horizontal' ? e.clientX : e.clientY;
214
+ const delta = currentPos - this.resizing.startPos;
215
+
216
+ const newSizes = [...this.resizing.startSizes];
217
+ newSizes[this.resizing.handleIndex] += delta;
218
+ newSizes[this.resizing.handleIndex + 1] -= delta;
219
+
220
+ // Apply min constraints (5% of container)
221
+ const containerSize = this.orientation === 'horizontal'
222
+ ? this.offsetWidth
223
+ : this.offsetHeight;
224
+ const minSize = containerSize * 0.05;
225
+
226
+ if (newSizes[this.resizing.handleIndex] >= minSize &&
227
+ newSizes[this.resizing.handleIndex + 1] >= minSize) {
228
+ this.resizing.currentSizes = newSizes;
229
+
230
+ // Update visual preview directly without triggering requestUpdate()
231
+ const gridTemplate = newSizes.map((size, index) => {
232
+ const percent = (size / containerSize) * 100;
233
+ const sizeStr = `${percent.toFixed(2)}%`;
234
+ if (index === newSizes.length - 1) {
235
+ return sizeStr;
236
+ }
237
+ return `${sizeStr} 4px`;
238
+ }).join(' ');
239
+
240
+ if (this.orientation === 'horizontal') {
241
+ this.style.gridTemplateColumns = gridTemplate;
242
+ } else {
243
+ this.style.gridTemplateRows = gridTemplate;
244
+ }
245
+ }
246
+ }
247
+
248
+ private stopResize = async () => {
249
+ if (this.resizing?.currentSizes) {
250
+ const containerSize = this.orientation === 'horizontal'
251
+ ? this.offsetWidth
252
+ : this.offsetHeight;
253
+
254
+ this.gridSizes = this.resizing.currentSizes.map(size => {
255
+ const percent = (size / containerSize) * 100;
256
+ return `${percent.toFixed(2)}%`;
257
+ });
258
+
259
+ await this.saveSizes();
260
+ this.requestUpdate();
261
+ }
262
+
263
+ // Remove overlay
264
+ if (this.resizeOverlay) {
265
+ document.body.removeChild(this.resizeOverlay);
266
+ this.resizeOverlay = null;
267
+ }
268
+
269
+ this.resizing = null;
270
+ document.removeEventListener('mousemove', this.handleResize);
271
+ document.removeEventListener('mouseup', this.stopResize);
272
+ document.body.style.cursor = '';
273
+ document.body.style.userSelect = '';
274
+ }
275
+
276
+ // ============= Render Methods =============
277
+
278
+ render() {
279
+ if (this.gridChildren.length === 0 || this.gridSizes.length === 0) {
280
+ // Show children with default styling while grid is initializing
281
+ return nothing;
282
+ }
283
+
284
+ // Build grid template with resize handles
285
+ // For 3 children: "size1 4px size2 4px size3"
286
+ const gridTemplate = this.gridSizes.flatMap((size, index) => {
287
+ if (index === this.gridSizes.length - 1) {
288
+ return [size];
289
+ }
290
+ return [size, '4px'];
291
+ }).join(' ');
292
+
293
+ // Apply grid layout to the custom element itself
294
+ this.style.display = 'grid';
295
+ if (this.orientation === 'horizontal') {
296
+ this.style.gridTemplateColumns = gridTemplate;
297
+ this.style.gridTemplateRows = '100%';
298
+ } else {
299
+ this.style.gridTemplateColumns = '100%';
300
+ this.style.gridTemplateRows = gridTemplate;
301
+ }
302
+ this.style.overflow = 'hidden';
303
+
304
+ // Render resize handles
305
+ // Child styling is applied in updated() when gridChildren/gridSizes change
306
+ return html`
307
+ <style>
308
+ .resize-handle {
309
+ position: relative;
310
+ z-index: 10;
311
+ background-color: var(--wa-color-neutral-border-quiet);
312
+ transition: background-color var(--wa-transition-fast);
313
+ }
314
+
315
+ .resize-handle:hover {
316
+ background-color: var(--wa-color-brand-fill-normal);
317
+ }
318
+ </style>
319
+
320
+ ${this.gridChildren.map((_, index) => {
321
+ if (index < this.gridChildren.length - 1) {
322
+ const gridCol = this.orientation === 'horizontal' ? `${index * 2 + 2}` : '1';
323
+ const gridRow = this.orientation === 'vertical' ? `${index * 2 + 2}` : '1';
324
+ return html`
325
+ <div
326
+ class="resize-handle"
327
+ style="
328
+ cursor: ${this.orientation === 'horizontal' ? 'col-resize' : 'row-resize'};
329
+ grid-column: ${gridCol};
330
+ grid-row: ${gridRow};
331
+ "
332
+ @mousedown=${(e: MouseEvent) => this.startResize(e, index)}
333
+ ></div>
334
+ `;
335
+ }
336
+ return nothing;
337
+ })}
338
+ `;
339
+ }
340
+
341
+ // ============= Cleanup Methods =============
342
+
343
+ disconnectedCallback() {
344
+ super.disconnectedCallback();
345
+ if (this.resizing) {
346
+ this.stopResize();
347
+ }
348
+ if (this.mutationObserver) {
349
+ this.mutationObserver.disconnect();
350
+ this.mutationObserver = undefined;
351
+ }
352
+ }
353
+
354
+ connectedCallback() {
355
+ super.connectedCallback();
356
+ this.style.height = '100%';
357
+ this.style.width = '100%';
358
+ }
359
+ }
360
+
361
+ declare global {
362
+ interface HTMLElementTagNameMap {
363
+ 'k-resizable-grid': KResizableGrid
364
+ }
365
+ }
366
+