@nuraly/lumenjs 0.1.3 → 0.2.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 (306) hide show
  1. package/README.md +62 -282
  2. package/dist/auth/config.d.ts +23 -0
  3. package/dist/auth/config.js +115 -0
  4. package/dist/auth/guard.d.ts +12 -0
  5. package/dist/auth/guard.js +28 -0
  6. package/dist/auth/index.d.ts +3 -0
  7. package/dist/auth/index.js +1 -0
  8. package/dist/auth/middleware.d.ts +23 -0
  9. package/dist/auth/middleware.js +89 -0
  10. package/dist/auth/native-auth.d.ts +82 -0
  11. package/dist/auth/native-auth.js +340 -0
  12. package/dist/auth/oidc-client.d.ts +17 -0
  13. package/dist/auth/oidc-client.js +123 -0
  14. package/dist/auth/providers/google.d.ts +23 -0
  15. package/dist/auth/providers/google.js +25 -0
  16. package/dist/auth/providers/index.d.ts +2 -0
  17. package/dist/auth/providers/index.js +1 -0
  18. package/dist/auth/routes/login.d.ts +8 -0
  19. package/dist/auth/routes/login.js +121 -0
  20. package/dist/auth/routes/logout.d.ts +4 -0
  21. package/dist/auth/routes/logout.js +79 -0
  22. package/dist/auth/routes/oidc-callback.d.ts +3 -0
  23. package/dist/auth/routes/oidc-callback.js +70 -0
  24. package/dist/auth/routes/password.d.ts +5 -0
  25. package/dist/auth/routes/password.js +149 -0
  26. package/dist/auth/routes/signup.d.ts +3 -0
  27. package/dist/auth/routes/signup.js +81 -0
  28. package/dist/auth/routes/token.d.ts +4 -0
  29. package/dist/auth/routes/token.js +70 -0
  30. package/dist/auth/routes/totp.d.ts +22 -0
  31. package/dist/auth/routes/totp.js +232 -0
  32. package/dist/auth/routes/utils.d.ts +7 -0
  33. package/dist/auth/routes/utils.js +35 -0
  34. package/dist/auth/routes/verify.d.ts +3 -0
  35. package/dist/auth/routes/verify.js +26 -0
  36. package/dist/auth/routes.d.ts +8 -0
  37. package/dist/auth/routes.js +124 -0
  38. package/dist/auth/session.d.ts +8 -0
  39. package/dist/auth/session.js +54 -0
  40. package/dist/auth/token.d.ts +33 -0
  41. package/dist/auth/token.js +90 -0
  42. package/dist/auth/types.d.ts +156 -0
  43. package/dist/auth/types.js +2 -0
  44. package/dist/build/build-client.d.ts +15 -0
  45. package/dist/build/build-client.js +45 -0
  46. package/dist/build/build-prerender.d.ts +11 -0
  47. package/dist/build/build-prerender.js +159 -0
  48. package/dist/build/build-server.d.ts +18 -0
  49. package/dist/build/build-server.js +107 -0
  50. package/dist/build/build.js +60 -123
  51. package/dist/build/scan.d.ts +18 -0
  52. package/dist/build/scan.js +77 -6
  53. package/dist/build/serve-api.js +8 -2
  54. package/dist/build/serve-loaders.d.ts +4 -4
  55. package/dist/build/serve-loaders.js +26 -18
  56. package/dist/build/serve-ssr.js +38 -11
  57. package/dist/build/serve-static.js +3 -3
  58. package/dist/build/serve.js +341 -18
  59. package/dist/cli.js +37 -6
  60. package/dist/communication/encryption.d.ts +35 -0
  61. package/dist/communication/encryption.js +90 -0
  62. package/dist/communication/handlers/context.d.ts +27 -0
  63. package/dist/communication/handlers/context.js +1 -0
  64. package/dist/communication/handlers/conversation.d.ts +24 -0
  65. package/dist/communication/handlers/conversation.js +113 -0
  66. package/dist/communication/handlers/file-upload.d.ts +17 -0
  67. package/dist/communication/handlers/file-upload.js +62 -0
  68. package/dist/communication/handlers/messaging.d.ts +30 -0
  69. package/dist/communication/handlers/messaging.js +237 -0
  70. package/dist/communication/handlers/presence.d.ts +15 -0
  71. package/dist/communication/handlers/presence.js +76 -0
  72. package/dist/communication/handlers.d.ts +5 -0
  73. package/dist/communication/handlers.js +5 -0
  74. package/dist/communication/index.d.ts +9 -0
  75. package/dist/communication/index.js +7 -0
  76. package/dist/communication/link-preview.d.ts +18 -0
  77. package/dist/communication/link-preview.js +115 -0
  78. package/dist/communication/schema.d.ts +10 -0
  79. package/dist/communication/schema.js +101 -0
  80. package/dist/communication/server.d.ts +86 -0
  81. package/dist/communication/server.js +212 -0
  82. package/dist/communication/signaling.d.ts +43 -0
  83. package/dist/communication/signaling.js +271 -0
  84. package/dist/communication/store.d.ts +71 -0
  85. package/dist/communication/store.js +289 -0
  86. package/dist/communication/types.d.ts +454 -0
  87. package/dist/communication/types.js +1 -0
  88. package/dist/create.d.ts +1 -0
  89. package/dist/create.js +55 -0
  90. package/dist/db/auto-migrate.d.ts +3 -0
  91. package/dist/db/auto-migrate.js +100 -0
  92. package/dist/db/client.d.ts +3 -0
  93. package/dist/db/client.js +18 -0
  94. package/dist/db/index.d.ts +17 -13
  95. package/dist/db/index.js +205 -26
  96. package/dist/db/seed.d.ts +12 -0
  97. package/dist/db/seed.js +88 -0
  98. package/dist/db/table.d.ts +10 -0
  99. package/dist/db/table.js +12 -0
  100. package/dist/dev-server/config.d.ts +11 -0
  101. package/dist/dev-server/config.js +40 -20
  102. package/dist/dev-server/index-html.d.ts +4 -0
  103. package/dist/dev-server/index-html.js +21 -6
  104. package/dist/dev-server/nuralyui-aliases.d.ts +0 -4
  105. package/dist/dev-server/nuralyui-aliases.js +115 -94
  106. package/dist/dev-server/plugins/vite-plugin-api-routes.js +29 -5
  107. package/dist/dev-server/plugins/vite-plugin-auth.d.ts +6 -0
  108. package/dist/dev-server/plugins/vite-plugin-auth.js +223 -0
  109. package/dist/dev-server/plugins/vite-plugin-auto-define.d.ts +16 -0
  110. package/dist/dev-server/plugins/vite-plugin-auto-define.js +111 -0
  111. package/dist/dev-server/plugins/vite-plugin-communication.d.ts +6 -0
  112. package/dist/dev-server/plugins/vite-plugin-communication.js +205 -0
  113. package/dist/dev-server/plugins/vite-plugin-editor-api.d.ts +6 -0
  114. package/dist/dev-server/plugins/vite-plugin-editor-api.js +318 -0
  115. package/dist/dev-server/plugins/vite-plugin-i18n.js +69 -2
  116. package/dist/dev-server/plugins/vite-plugin-lit-dedup.d.ts +6 -0
  117. package/dist/dev-server/plugins/vite-plugin-lit-dedup.js +78 -34
  118. package/dist/dev-server/plugins/vite-plugin-lit-hmr.js +44 -2
  119. package/dist/dev-server/plugins/vite-plugin-llms.d.ts +2 -0
  120. package/dist/dev-server/plugins/vite-plugin-llms.js +92 -0
  121. package/dist/dev-server/plugins/vite-plugin-loaders.js +146 -13
  122. package/dist/dev-server/plugins/vite-plugin-routes.js +16 -5
  123. package/dist/dev-server/plugins/vite-plugin-socketio.d.ts +2 -0
  124. package/dist/dev-server/plugins/vite-plugin-socketio.js +51 -0
  125. package/dist/dev-server/plugins/vite-plugin-source-annotator.d.ts +2 -0
  126. package/dist/dev-server/plugins/vite-plugin-source-annotator.js +26 -3
  127. package/dist/dev-server/plugins/vite-plugin-storage.d.ts +10 -0
  128. package/dist/dev-server/plugins/vite-plugin-storage.js +126 -0
  129. package/dist/dev-server/plugins/vite-plugin-virtual-modules.js +140 -3
  130. package/dist/dev-server/server.js +242 -70
  131. package/dist/dev-server/ssr-render.d.ts +2 -1
  132. package/dist/dev-server/ssr-render.js +117 -50
  133. package/dist/editor/ai/backend.d.ts +20 -0
  134. package/dist/editor/ai/backend.js +113 -0
  135. package/dist/editor/ai/claude-code-client.d.ts +20 -0
  136. package/dist/editor/ai/claude-code-client.js +145 -0
  137. package/dist/editor/ai/deepseek-client.d.ts +7 -0
  138. package/dist/editor/ai/deepseek-client.js +113 -0
  139. package/dist/editor/ai/opencode-client.d.ts +14 -0
  140. package/dist/editor/ai/opencode-client.js +99 -0
  141. package/dist/editor/ai/snapshot-store.d.ts +22 -0
  142. package/dist/editor/ai/snapshot-store.js +35 -0
  143. package/dist/editor/ai/types.d.ts +30 -0
  144. package/dist/editor/ai/types.js +136 -0
  145. package/dist/editor/ai-chat-panel.d.ts +13 -0
  146. package/dist/editor/ai-chat-panel.js +613 -0
  147. package/dist/editor/ai-markdown.d.ts +10 -0
  148. package/dist/editor/ai-markdown.js +70 -0
  149. package/dist/editor/ai-project-panel.d.ts +11 -0
  150. package/dist/editor/ai-project-panel.js +332 -0
  151. package/dist/editor/ast-modification.d.ts +11 -0
  152. package/dist/editor/ast-modification.js +1 -0
  153. package/dist/editor/ast-service.d.ts +30 -0
  154. package/dist/editor/ast-service.js +180 -0
  155. package/dist/editor/css-rules.d.ts +54 -0
  156. package/dist/editor/css-rules.js +423 -0
  157. package/dist/editor/editor-api-client.d.ts +51 -0
  158. package/dist/editor/editor-api-client.js +162 -0
  159. package/dist/editor/editor-bridge.d.ts +1 -0
  160. package/dist/editor/editor-bridge.js +18 -8
  161. package/dist/editor/editor-toolbar.d.ts +14 -0
  162. package/dist/editor/editor-toolbar.js +115 -0
  163. package/dist/editor/file-editor.d.ts +9 -0
  164. package/dist/editor/file-editor.js +236 -0
  165. package/dist/editor/file-service.d.ts +16 -0
  166. package/dist/editor/file-service.js +52 -0
  167. package/dist/editor/i18n-key-gen.d.ts +1 -0
  168. package/dist/editor/i18n-key-gen.js +7 -0
  169. package/dist/editor/inline-text-edit.d.ts +5 -0
  170. package/dist/editor/inline-text-edit.js +173 -92
  171. package/dist/editor/overlay-events.d.ts +5 -0
  172. package/dist/editor/overlay-events.js +364 -0
  173. package/dist/editor/overlay-hmr.d.ts +2 -0
  174. package/dist/editor/overlay-hmr.js +76 -0
  175. package/dist/editor/overlay-selection.d.ts +29 -0
  176. package/dist/editor/overlay-selection.js +148 -0
  177. package/dist/editor/overlay-utils.d.ts +12 -0
  178. package/dist/editor/overlay-utils.js +59 -0
  179. package/dist/editor/properties-panel-persist.d.ts +14 -0
  180. package/dist/editor/properties-panel-persist.js +70 -0
  181. package/dist/editor/properties-panel-rows.d.ts +10 -0
  182. package/dist/editor/properties-panel-rows.js +349 -0
  183. package/dist/editor/properties-panel-styles.d.ts +4 -0
  184. package/dist/editor/properties-panel-styles.js +174 -0
  185. package/dist/editor/properties-panel.d.ts +4 -0
  186. package/dist/editor/properties-panel.js +148 -0
  187. package/dist/editor/property-registry.d.ts +16 -0
  188. package/dist/editor/property-registry.js +303 -0
  189. package/dist/editor/standalone-file-panel.d.ts +0 -0
  190. package/dist/editor/standalone-file-panel.js +1 -0
  191. package/dist/editor/standalone-overlay-dom.d.ts +0 -0
  192. package/dist/editor/standalone-overlay-dom.js +1 -0
  193. package/dist/editor/standalone-overlay-styles.d.ts +0 -0
  194. package/dist/editor/standalone-overlay-styles.js +1 -0
  195. package/dist/editor/standalone-overlay.d.ts +1 -0
  196. package/dist/editor/standalone-overlay.js +76 -0
  197. package/dist/editor/syntax-highlighter.d.ts +4 -0
  198. package/dist/editor/syntax-highlighter.js +81 -0
  199. package/dist/editor/text-toolbar.d.ts +11 -0
  200. package/dist/editor/text-toolbar.js +327 -0
  201. package/dist/editor/toolbar-styles.d.ts +4 -0
  202. package/dist/editor/toolbar-styles.js +198 -0
  203. package/dist/email/index.d.ts +32 -0
  204. package/dist/email/index.js +154 -0
  205. package/dist/email/providers/resend.d.ts +2 -0
  206. package/dist/email/providers/resend.js +24 -0
  207. package/dist/email/providers/sendgrid.d.ts +2 -0
  208. package/dist/email/providers/sendgrid.js +31 -0
  209. package/dist/email/providers/smtp.d.ts +13 -0
  210. package/dist/email/providers/smtp.js +125 -0
  211. package/dist/email/template-engine.d.ts +18 -0
  212. package/dist/email/template-engine.js +116 -0
  213. package/dist/email/templates/base.d.ts +9 -0
  214. package/dist/email/templates/base.js +65 -0
  215. package/dist/email/templates/password-reset.d.ts +5 -0
  216. package/dist/email/templates/password-reset.js +15 -0
  217. package/dist/email/templates/verify-email.d.ts +5 -0
  218. package/dist/email/templates/verify-email.js +15 -0
  219. package/dist/email/templates/welcome.d.ts +5 -0
  220. package/dist/email/templates/welcome.js +13 -0
  221. package/dist/email/types.d.ts +49 -0
  222. package/dist/email/types.js +1 -0
  223. package/dist/llms/generate.d.ts +46 -0
  224. package/dist/llms/generate.js +185 -0
  225. package/dist/permissions/guard.d.ts +28 -0
  226. package/dist/permissions/guard.js +30 -0
  227. package/dist/permissions/index.d.ts +6 -0
  228. package/dist/permissions/index.js +3 -0
  229. package/dist/permissions/service.d.ts +80 -0
  230. package/dist/permissions/service.js +210 -0
  231. package/dist/permissions/tables.d.ts +5 -0
  232. package/dist/permissions/tables.js +68 -0
  233. package/dist/permissions/types.d.ts +33 -0
  234. package/dist/permissions/types.js +1 -0
  235. package/dist/runtime/app-shell.d.ts +1 -1
  236. package/dist/runtime/app-shell.js +164 -0
  237. package/dist/runtime/auth.d.ts +10 -0
  238. package/dist/runtime/auth.js +30 -0
  239. package/dist/runtime/communication.d.ts +137 -0
  240. package/dist/runtime/communication.js +228 -0
  241. package/dist/runtime/error-boundary.d.ts +23 -0
  242. package/dist/runtime/error-boundary.js +120 -0
  243. package/dist/runtime/i18n.d.ts +6 -1
  244. package/dist/runtime/i18n.js +42 -21
  245. package/dist/runtime/island.d.ts +16 -0
  246. package/dist/runtime/island.js +80 -0
  247. package/dist/runtime/router-data.d.ts +3 -0
  248. package/dist/runtime/router-data.js +102 -17
  249. package/dist/runtime/router-hydration.js +34 -2
  250. package/dist/runtime/router.d.ts +19 -2
  251. package/dist/runtime/router.js +237 -43
  252. package/dist/runtime/socket-client.d.ts +2 -0
  253. package/dist/runtime/socket-client.js +30 -0
  254. package/dist/runtime/webrtc.d.ts +91 -0
  255. package/dist/runtime/webrtc.js +428 -0
  256. package/dist/shared/dom-shims.js +4 -2
  257. package/dist/shared/graceful-shutdown.d.ts +8 -0
  258. package/dist/shared/graceful-shutdown.js +36 -0
  259. package/dist/shared/health.d.ts +8 -0
  260. package/dist/shared/health.js +25 -0
  261. package/dist/shared/llms-txt.d.ts +31 -0
  262. package/dist/shared/llms-txt.js +85 -0
  263. package/dist/shared/logger.d.ts +32 -0
  264. package/dist/shared/logger.js +93 -0
  265. package/dist/shared/meta.d.ts +27 -0
  266. package/dist/shared/meta.js +71 -0
  267. package/dist/shared/middleware-runner.d.ts +9 -0
  268. package/dist/shared/middleware-runner.js +29 -0
  269. package/dist/shared/rate-limit.d.ts +18 -0
  270. package/dist/shared/rate-limit.js +71 -0
  271. package/dist/shared/request-id.d.ts +5 -0
  272. package/dist/shared/request-id.js +18 -0
  273. package/dist/shared/route-matching.js +16 -1
  274. package/dist/shared/security-headers.d.ts +18 -0
  275. package/dist/shared/security-headers.js +38 -0
  276. package/dist/shared/socket-io-setup.d.ts +11 -0
  277. package/dist/shared/socket-io-setup.js +51 -0
  278. package/dist/shared/types.d.ts +15 -0
  279. package/dist/shared/utils.d.ts +33 -7
  280. package/dist/shared/utils.js +164 -27
  281. package/dist/storage/adapters/local.d.ts +44 -0
  282. package/dist/storage/adapters/local.js +85 -0
  283. package/dist/storage/adapters/s3.d.ts +32 -0
  284. package/dist/storage/adapters/s3.js +119 -0
  285. package/dist/storage/adapters/types.d.ts +53 -0
  286. package/dist/storage/adapters/types.js +1 -0
  287. package/dist/storage/index.d.ts +76 -0
  288. package/dist/storage/index.js +83 -0
  289. package/package.json +45 -7
  290. package/templates/blog/api/posts.ts +4 -18
  291. package/templates/blog/data/migrations/001_init.sql +6 -5
  292. package/templates/blog/lumenjs.config.ts +3 -0
  293. package/templates/blog/package.json +14 -0
  294. package/templates/blog/pages/_layout.ts +25 -0
  295. package/templates/blog/pages/index.ts +48 -22
  296. package/templates/blog/pages/posts/[slug].ts +45 -20
  297. package/templates/blog/pages/tag/[tag].ts +44 -0
  298. package/templates/dashboard/api/stats.ts +8 -5
  299. package/templates/dashboard/lumenjs.config.ts +3 -0
  300. package/templates/dashboard/package.json +14 -0
  301. package/templates/dashboard/pages/_layout.ts +25 -0
  302. package/templates/dashboard/pages/index.ts +54 -23
  303. package/templates/dashboard/pages/settings/index.ts +29 -0
  304. package/templates/default/lumenjs.config.ts +3 -0
  305. package/templates/default/package.json +14 -0
  306. package/templates/default/pages/index.ts +24 -0
@@ -0,0 +1,349 @@
1
+ import { CSS_ENUMS, COMMON_CSS_PROPS, isColorValue, normalizeToHex, notifyLayoutChange, } from './css-rules.js';
2
+ import { persistAttribute, persistAttributeDebounced, persistStyle, persistStyleDebounced, } from './properties-panel-persist.js';
3
+ export function createGroup(label) {
4
+ const group = document.createElement('div');
5
+ group.className = 'nk-pp-group';
6
+ group.innerHTML = `<div class="nk-pp-group-header">${label}</div>`;
7
+ return group;
8
+ }
9
+ export function parseInlineStyles(element) {
10
+ const result = [];
11
+ const style = element.style;
12
+ for (let i = 0; i < style.length; i++) {
13
+ const prop = style[i];
14
+ if (prop === 'outline' || prop === 'outline-offset')
15
+ continue;
16
+ const val = style.getPropertyValue(prop);
17
+ if (val)
18
+ result.push([prop, val]);
19
+ }
20
+ return result;
21
+ }
22
+ export function createPropertyRow(prop, element) {
23
+ const row = document.createElement('div');
24
+ row.className = 'nk-pp-row';
25
+ const label = document.createElement('div');
26
+ label.className = 'nk-pp-label';
27
+ label.textContent = prop.name;
28
+ label.title = prop.name;
29
+ row.appendChild(label);
30
+ const control = document.createElement('div');
31
+ control.className = 'nk-pp-control';
32
+ if (prop.type === 'Boolean') {
33
+ const toggle = document.createElement('button');
34
+ toggle.className = 'nk-pp-toggle' + (prop.value ? ' on' : '');
35
+ toggle.addEventListener('click', () => {
36
+ const newVal = !toggle.classList.contains('on');
37
+ toggle.classList.toggle('on', newVal);
38
+ element[prop.name] = newVal;
39
+ if (newVal) {
40
+ element.setAttribute(prop.attrName, '');
41
+ }
42
+ else {
43
+ element.removeAttribute(prop.attrName);
44
+ }
45
+ persistAttribute(element, prop.attrName, newVal ? '' : undefined);
46
+ });
47
+ control.appendChild(toggle);
48
+ }
49
+ else if (prop.type === 'Array' || prop.type === 'Object') {
50
+ const ro = document.createElement('div');
51
+ ro.className = 'nk-pp-readonly';
52
+ try {
53
+ ro.textContent = JSON.stringify(prop.value);
54
+ }
55
+ catch {
56
+ ro.textContent = String(prop.value);
57
+ }
58
+ control.appendChild(ro);
59
+ }
60
+ else if (prop.enumValues && prop.enumValues.length > 0) {
61
+ const select = document.createElement('select');
62
+ const emptyOpt = document.createElement('option');
63
+ emptyOpt.value = '';
64
+ emptyOpt.textContent = '—';
65
+ select.appendChild(emptyOpt);
66
+ for (const val of prop.enumValues) {
67
+ const opt = document.createElement('option');
68
+ opt.value = val;
69
+ opt.textContent = val;
70
+ select.appendChild(opt);
71
+ }
72
+ select.value = prop.value != null ? String(prop.value) : '';
73
+ select.addEventListener('change', () => {
74
+ const v = select.value;
75
+ element[prop.name] = v;
76
+ if (v) {
77
+ element.setAttribute(prop.attrName, v);
78
+ }
79
+ else {
80
+ element.removeAttribute(prop.attrName);
81
+ }
82
+ persistAttribute(element, prop.attrName, v || undefined);
83
+ });
84
+ control.appendChild(select);
85
+ }
86
+ else if (isColorValue(prop.name, String(prop.value ?? ''))) {
87
+ const wrap = document.createElement('div');
88
+ wrap.className = 'nk-pp-color-wrap';
89
+ const colorInput = document.createElement('input');
90
+ colorInput.type = 'color';
91
+ colorInput.value = normalizeToHex(String(prop.value ?? '#000000'));
92
+ const textInput = document.createElement('input');
93
+ textInput.type = 'text';
94
+ textInput.value = String(prop.value ?? '');
95
+ const sync = (val) => {
96
+ element[prop.name] = val;
97
+ element.setAttribute(prop.attrName, val);
98
+ persistAttributeDebounced(element, prop.attrName, val, prop.name);
99
+ };
100
+ colorInput.addEventListener('input', () => {
101
+ textInput.value = colorInput.value;
102
+ sync(colorInput.value);
103
+ });
104
+ textInput.addEventListener('input', () => {
105
+ sync(textInput.value);
106
+ });
107
+ wrap.appendChild(colorInput);
108
+ wrap.appendChild(textInput);
109
+ control.appendChild(wrap);
110
+ }
111
+ else if (prop.type === 'Number') {
112
+ const input = document.createElement('input');
113
+ input.type = 'number';
114
+ input.value = prop.value != null ? String(prop.value) : '';
115
+ input.addEventListener('input', () => {
116
+ const v = input.value;
117
+ element[prop.name] = v ? Number(v) : undefined;
118
+ if (v) {
119
+ element.setAttribute(prop.attrName, v);
120
+ }
121
+ else {
122
+ element.removeAttribute(prop.attrName);
123
+ }
124
+ persistAttributeDebounced(element, prop.attrName, v || undefined, prop.name);
125
+ });
126
+ control.appendChild(input);
127
+ }
128
+ else {
129
+ const input = document.createElement('input');
130
+ input.type = 'text';
131
+ input.value = prop.value != null ? String(prop.value) : '';
132
+ input.addEventListener('input', () => {
133
+ const v = input.value;
134
+ element[prop.name] = v;
135
+ if (v) {
136
+ element.setAttribute(prop.attrName, v);
137
+ }
138
+ else {
139
+ element.removeAttribute(prop.attrName);
140
+ }
141
+ persistAttributeDebounced(element, prop.attrName, v || undefined, prop.name);
142
+ });
143
+ control.appendChild(input);
144
+ }
145
+ row.appendChild(control);
146
+ return row;
147
+ }
148
+ export function createStyleRow(cssProp, cssVal, element, group) {
149
+ const row = document.createElement('div');
150
+ row.className = 'nk-pp-row';
151
+ const label = document.createElement('div');
152
+ label.className = 'nk-pp-label';
153
+ label.textContent = cssProp;
154
+ label.title = cssProp;
155
+ row.appendChild(label);
156
+ const control = document.createElement('div');
157
+ control.className = 'nk-pp-control';
158
+ const enumVals = CSS_ENUMS[cssProp];
159
+ if (isColorValue(cssProp, cssVal)) {
160
+ const wrap = document.createElement('div');
161
+ wrap.className = 'nk-pp-color-wrap';
162
+ const colorInput = document.createElement('input');
163
+ colorInput.type = 'color';
164
+ colorInput.value = normalizeToHex(cssVal);
165
+ const textInput = document.createElement('input');
166
+ textInput.type = 'text';
167
+ textInput.value = cssVal;
168
+ const sync = (val) => {
169
+ element.style.setProperty(cssProp, val);
170
+ notifyLayoutChange();
171
+ persistStyleDebounced(element);
172
+ };
173
+ colorInput.addEventListener('input', () => {
174
+ textInput.value = colorInput.value;
175
+ sync(colorInput.value);
176
+ });
177
+ textInput.addEventListener('input', () => {
178
+ sync(textInput.value);
179
+ });
180
+ wrap.appendChild(colorInput);
181
+ wrap.appendChild(textInput);
182
+ control.appendChild(wrap);
183
+ }
184
+ else if (enumVals) {
185
+ const select = document.createElement('select');
186
+ const emptyOpt = document.createElement('option');
187
+ emptyOpt.value = '';
188
+ emptyOpt.textContent = '—';
189
+ select.appendChild(emptyOpt);
190
+ for (const v of enumVals) {
191
+ const opt = document.createElement('option');
192
+ opt.value = v;
193
+ opt.textContent = v;
194
+ select.appendChild(opt);
195
+ }
196
+ select.value = cssVal;
197
+ select.addEventListener('change', () => {
198
+ element.style.setProperty(cssProp, select.value);
199
+ notifyLayoutChange();
200
+ persistStyleDebounced(element);
201
+ });
202
+ control.appendChild(select);
203
+ }
204
+ else {
205
+ const input = document.createElement('input');
206
+ input.type = 'text';
207
+ input.value = cssVal;
208
+ input.addEventListener('input', () => {
209
+ element.style.setProperty(cssProp, input.value);
210
+ notifyLayoutChange();
211
+ persistStyleDebounced(element);
212
+ });
213
+ control.appendChild(input);
214
+ }
215
+ row.appendChild(control);
216
+ // Remove button
217
+ const removeBtn = document.createElement('button');
218
+ removeBtn.className = 'nk-pp-remove';
219
+ removeBtn.innerHTML = '&times;';
220
+ removeBtn.title = 'Remove style';
221
+ removeBtn.addEventListener('click', () => {
222
+ element.style.removeProperty(cssProp);
223
+ row.remove();
224
+ notifyLayoutChange();
225
+ persistStyle(element);
226
+ });
227
+ row.appendChild(removeBtn);
228
+ return row;
229
+ }
230
+ export function createAddAttributeRow(element, group) {
231
+ const wrapper = document.createElement('div');
232
+ wrapper.className = 'nk-pp-add-row';
233
+ const addBtn = document.createElement('button');
234
+ addBtn.className = 'nk-pp-add-btn';
235
+ addBtn.textContent = '+ Add Attribute';
236
+ wrapper.appendChild(addBtn);
237
+ addBtn.addEventListener('click', () => {
238
+ addBtn.style.display = 'none';
239
+ const form = document.createElement('div');
240
+ form.className = 'nk-pp-add-form';
241
+ const nameInput = document.createElement('input');
242
+ nameInput.placeholder = 'name';
243
+ const valInput = document.createElement('input');
244
+ valInput.placeholder = 'value';
245
+ const confirmBtn = document.createElement('button');
246
+ confirmBtn.textContent = '\u2713';
247
+ form.appendChild(nameInput);
248
+ form.appendChild(valInput);
249
+ form.appendChild(confirmBtn);
250
+ wrapper.appendChild(form);
251
+ nameInput.focus();
252
+ const commit = () => {
253
+ const name = nameInput.value.trim();
254
+ const val = valInput.value;
255
+ if (!name) {
256
+ addBtn.style.display = '';
257
+ form.remove();
258
+ return;
259
+ }
260
+ if (element.hasAttribute(name)) {
261
+ nameInput.style.borderColor = '#f87171';
262
+ return;
263
+ }
264
+ element.setAttribute(name, val);
265
+ persistAttribute(element, name, val);
266
+ const prop = { name, attrName: name, type: 'String', value: val };
267
+ group.insertBefore(createPropertyRow(prop, element), wrapper);
268
+ addBtn.style.display = '';
269
+ form.remove();
270
+ };
271
+ confirmBtn.addEventListener('click', commit);
272
+ nameInput.addEventListener('keydown', (e) => { if (e.key === 'Enter')
273
+ commit(); if (e.key === 'Escape') {
274
+ addBtn.style.display = '';
275
+ form.remove();
276
+ } });
277
+ valInput.addEventListener('keydown', (e) => { if (e.key === 'Enter')
278
+ commit(); if (e.key === 'Escape') {
279
+ addBtn.style.display = '';
280
+ form.remove();
281
+ } });
282
+ });
283
+ return wrapper;
284
+ }
285
+ export function createAddStyleRow(element, group) {
286
+ const wrapper = document.createElement('div');
287
+ wrapper.className = 'nk-pp-add-row';
288
+ const addBtn = document.createElement('button');
289
+ addBtn.className = 'nk-pp-add-btn';
290
+ addBtn.textContent = '+ Add Style';
291
+ wrapper.appendChild(addBtn);
292
+ addBtn.addEventListener('click', () => {
293
+ addBtn.style.display = 'none';
294
+ const form = document.createElement('div');
295
+ form.className = 'nk-pp-add-form';
296
+ const nameInput = document.createElement('input');
297
+ nameInput.placeholder = 'property';
298
+ nameInput.setAttribute('list', 'nk-pp-css-list');
299
+ const valInput = document.createElement('input');
300
+ valInput.placeholder = 'value';
301
+ const confirmBtn = document.createElement('button');
302
+ confirmBtn.textContent = '\u2713';
303
+ form.appendChild(nameInput);
304
+ form.appendChild(valInput);
305
+ form.appendChild(confirmBtn);
306
+ wrapper.appendChild(form);
307
+ // Datalist for autocomplete
308
+ if (!document.getElementById('nk-pp-css-list')) {
309
+ const dl = document.createElement('datalist');
310
+ dl.id = 'nk-pp-css-list';
311
+ for (const p of COMMON_CSS_PROPS) {
312
+ const opt = document.createElement('option');
313
+ opt.value = p;
314
+ dl.appendChild(opt);
315
+ }
316
+ document.body.appendChild(dl);
317
+ }
318
+ nameInput.focus();
319
+ const commit = () => {
320
+ const prop = nameInput.value.trim();
321
+ const val = valInput.value.trim();
322
+ if (!prop || !val) {
323
+ addBtn.style.display = '';
324
+ form.remove();
325
+ return;
326
+ }
327
+ element.style.setProperty(prop, val);
328
+ notifyLayoutChange();
329
+ persistStyle(element);
330
+ group.insertBefore(createStyleRow(prop, val, element, group), wrapper);
331
+ addBtn.style.display = '';
332
+ form.remove();
333
+ };
334
+ confirmBtn.addEventListener('click', commit);
335
+ nameInput.addEventListener('keydown', (e) => { if (e.key === 'Enter') {
336
+ valInput.focus();
337
+ e.preventDefault();
338
+ } if (e.key === 'Escape') {
339
+ addBtn.style.display = '';
340
+ form.remove();
341
+ } });
342
+ valInput.addEventListener('keydown', (e) => { if (e.key === 'Enter')
343
+ commit(); if (e.key === 'Escape') {
344
+ addBtn.style.display = '';
345
+ form.remove();
346
+ } });
347
+ });
348
+ return wrapper;
349
+ }
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Properties Panel — CSS styles, extracted from properties-panel.ts.
3
+ */
4
+ export declare function injectPropertiesPanelStyles(): void;
@@ -0,0 +1,174 @@
1
+ /**
2
+ * Properties Panel — CSS styles, extracted from properties-panel.ts.
3
+ */
4
+ export function injectPropertiesPanelStyles() {
5
+ const style = document.createElement('style');
6
+ style.textContent = `
7
+ #nk-props-panel {
8
+ position: fixed; top: 44px; right: 0; width: 300px;
9
+ height: calc(100vh - 44px); background: #1e1b2e;
10
+ border-left: 1px solid #334155;
11
+ z-index: 99999; display: none; flex-direction: column;
12
+ font-family: system-ui, -apple-system, sans-serif; font-size: 12px;
13
+ box-shadow: -4px 0 16px rgba(0,0,0,0.3); color: #e2e8f0;
14
+ }
15
+ #nk-props-panel.open { display: flex; }
16
+ .nk-pp-header {
17
+ display: flex; align-items: center; justify-content: space-between;
18
+ padding: 10px 12px; border-bottom: 1px solid #334155; flex-shrink: 0;
19
+ }
20
+ .nk-pp-tag {
21
+ font-family: 'SF Mono', ui-monospace, monospace; font-size: 13px;
22
+ color: #67e8f9; font-weight: 600;
23
+ }
24
+ .nk-pp-close {
25
+ background: none; border: none; color: #94a3b8; cursor: pointer;
26
+ padding: 4px; display: flex; align-items: center;
27
+ -webkit-tap-highlight-color: transparent;
28
+ }
29
+ .nk-pp-close:hover { color: #e2e8f0; }
30
+ .nk-pp-content {
31
+ flex: 1; overflow-y: auto; padding: 0;
32
+ -webkit-overflow-scrolling: touch;
33
+ }
34
+ .nk-pp-group {
35
+ border-bottom: 1px solid #334155;
36
+ }
37
+ .nk-pp-group-header {
38
+ padding: 8px 12px; font-size: 10px; font-weight: 700;
39
+ text-transform: uppercase; letter-spacing: 0.08em; color: #64748b;
40
+ background: #161325;
41
+ }
42
+ .nk-pp-row {
43
+ display: flex; align-items: center; gap: 8px; padding: 6px 12px;
44
+ border-bottom: 1px solid #1a1730;
45
+ }
46
+ .nk-pp-row:last-child { border-bottom: none; }
47
+ .nk-pp-label {
48
+ width: 90px; flex-shrink: 0; font-size: 11px; color: #94a3b8;
49
+ font-family: 'SF Mono', ui-monospace, monospace;
50
+ overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
51
+ }
52
+ .nk-pp-control { flex: 1; min-width: 0; }
53
+ .nk-pp-control input[type="text"],
54
+ .nk-pp-control input[type="number"] {
55
+ width: 100%; background: #0f0d1a; color: #e2e8f0;
56
+ border: 1px solid #334155; border-radius: 4px; padding: 4px 8px;
57
+ font-size: 11px; font-family: 'SF Mono', ui-monospace, monospace;
58
+ outline: none; box-sizing: border-box;
59
+ }
60
+ .nk-pp-control input:focus { border-color: #7c3aed; }
61
+ .nk-pp-control select {
62
+ width: 100%; background: #0f0d1a; color: #e2e8f0;
63
+ border: 1px solid #334155; border-radius: 4px; padding: 4px 6px;
64
+ font-size: 11px; font-family: inherit; cursor: pointer; outline: none;
65
+ }
66
+ .nk-pp-control select:hover { border-color: #475569; }
67
+ .nk-pp-control select:focus { border-color: #7c3aed; }
68
+ .nk-pp-toggle {
69
+ position: relative; width: 32px; height: 18px; background: #334155;
70
+ border-radius: 9px; cursor: pointer; transition: background 0.2s;
71
+ border: none; padding: 0;
72
+ }
73
+ .nk-pp-toggle.on { background: #7c3aed; }
74
+ .nk-pp-toggle::after {
75
+ content: ''; position: absolute; top: 2px; left: 2px;
76
+ width: 14px; height: 14px; background: #e2e8f0; border-radius: 50%;
77
+ transition: transform 0.2s;
78
+ }
79
+ .nk-pp-toggle.on::after { transform: translateX(14px); }
80
+ .nk-pp-readonly {
81
+ font-size: 10px; color: #64748b; font-family: 'SF Mono', ui-monospace, monospace;
82
+ max-height: 60px; overflow: auto; word-break: break-all;
83
+ }
84
+ .nk-pp-add-row {
85
+ padding: 6px 12px;
86
+ }
87
+ .nk-pp-add-btn {
88
+ background: none; border: 1px dashed #334155; border-radius: 4px;
89
+ color: #64748b; cursor: pointer; font-size: 11px; padding: 4px 10px;
90
+ width: 100%; text-align: center; font-family: inherit;
91
+ -webkit-tap-highlight-color: transparent;
92
+ }
93
+ .nk-pp-add-btn:hover { border-color: #7c3aed; color: #c084fc; }
94
+ .nk-pp-add-form {
95
+ display: flex; gap: 4px; align-items: center; padding: 6px 12px;
96
+ }
97
+ .nk-pp-add-form input {
98
+ flex: 1; background: #0f0d1a; color: #e2e8f0; border: 1px solid #334155;
99
+ border-radius: 4px; padding: 4px 6px; font-size: 11px;
100
+ font-family: 'SF Mono', ui-monospace, monospace; outline: none;
101
+ min-width: 0;
102
+ }
103
+ .nk-pp-add-form input:focus { border-color: #7c3aed; }
104
+ .nk-pp-add-form button {
105
+ background: #7c3aed; color: white; border: none; border-radius: 4px;
106
+ padding: 4px 8px; cursor: pointer; font-size: 11px; flex-shrink: 0;
107
+ }
108
+ .nk-pp-add-form button:hover { background: #6d28d9; }
109
+ .nk-pp-remove {
110
+ background: none; border: none; color: #475569; cursor: pointer;
111
+ padding: 2px; font-size: 14px; line-height: 1; flex-shrink: 0;
112
+ -webkit-tap-highlight-color: transparent;
113
+ }
114
+ .nk-pp-remove:hover { color: #f87171; }
115
+ .nk-pp-color-wrap {
116
+ display: flex; align-items: center; gap: 4px; width: 100%;
117
+ }
118
+ .nk-pp-rule-header {
119
+ padding: 6px 12px; font-size: 11px; color: #c084fc;
120
+ font-family: 'SF Mono', ui-monospace, monospace; background: #1a1730;
121
+ border-bottom: 1px solid #1a1730; cursor: pointer; display: flex;
122
+ align-items: center; justify-content: space-between;
123
+ }
124
+ .nk-pp-rule-header:hover { background: #201d33; }
125
+ .nk-pp-rule-header .nk-pp-toggle-arrow {
126
+ font-size: 10px; color: #64748b; transition: transform 0.15s;
127
+ }
128
+ .nk-pp-rule-header .nk-pp-toggle-arrow.open { transform: rotate(90deg); }
129
+ .nk-pp-rule-body { display: none; }
130
+ .nk-pp-rule-body.open { display: block; }
131
+ .nk-pp-color-wrap input[type="color"] {
132
+ width: 28px; height: 24px; border: 1px solid #334155; border-radius: 4px;
133
+ background: #0f0d1a; cursor: pointer; padding: 0; flex-shrink: 0;
134
+ }
135
+ .nk-pp-color-wrap input[type="text"] { flex: 1; }
136
+ .nk-pp-ai-row {
137
+ display: none; padding: 8px 12px; border-bottom: 1px solid #334155;
138
+ }
139
+ .nk-pp-ai-btn {
140
+ width: 100%; padding: 8px 12px; background: #7c3aed; color: #fff;
141
+ border: none; border-radius: 6px; font-size: 12px; font-weight: 600;
142
+ font-family: inherit; cursor: pointer; display: flex; align-items: center;
143
+ justify-content: center; gap: 6px;
144
+ -webkit-tap-highlight-color: transparent; touch-action: manipulation;
145
+ }
146
+ .nk-pp-ai-btn:hover { background: #6d28d9; }
147
+ .nk-pp-ai-btn:active { background: #5b21b6; }
148
+
149
+ /* Floating properties icon (mobile only) */
150
+ #nk-pp-fab {
151
+ display: none; position: fixed; bottom: 24px; right: 16px;
152
+ width: 48px; height: 48px; border-radius: 50%;
153
+ background: #7c3aed; color: #fff; border: none;
154
+ box-shadow: 0 4px 16px rgba(124,58,237,0.5);
155
+ z-index: 99999; cursor: pointer; align-items: center; justify-content: center;
156
+ font-size: 20px; -webkit-tap-highlight-color: transparent; touch-action: manipulation;
157
+ }
158
+ #nk-pp-fab.visible { display: flex; }
159
+ #nk-pp-fab:active { background: #5b21b6; transform: scale(0.92); }
160
+
161
+ /* Mobile responsive */
162
+ @media (max-width: 640px) {
163
+ #nk-props-panel {
164
+ width: 100%; left: 0; right: 0; top: 0;
165
+ height: 100vh; max-height: 100vh;
166
+ border-left: none; border-bottom: none;
167
+ touch-action: manipulation;
168
+ z-index: 199999;
169
+ }
170
+ .nk-pp-ai-row { display: block; }
171
+ }
172
+ `;
173
+ document.head.appendChild(style);
174
+ }
@@ -0,0 +1,4 @@
1
+ export declare function createPropertiesPanel(): HTMLDivElement;
2
+ export declare function showPropertiesForElement(element: HTMLElement): void;
3
+ export declare function hidePropertiesPanel(): void;
4
+ export declare function isPropertiesPanelOpen(): boolean;
@@ -0,0 +1,148 @@
1
+ /**
2
+ * Properties Panel — right-side panel for editing element properties and styles.
3
+ */
4
+ import { discoverProperties } from './property-registry.js';
5
+ import { loadCssRulesForElement } from './css-rules.js';
6
+ import { injectPropertiesPanelStyles } from './properties-panel-styles.js';
7
+ import { state as persistState, resetDebounceTimers } from './properties-panel-persist.js';
8
+ import { createGroup, parseInlineStyles, createPropertyRow, createStyleRow, createAddAttributeRow, createAddStyleRow, } from './properties-panel-rows.js';
9
+ let panel;
10
+ let currentElement = null;
11
+ export function createPropertiesPanel() {
12
+ panel = document.createElement('div');
13
+ panel.id = 'nk-props-panel';
14
+ panel.innerHTML = `
15
+ <div class="nk-pp-header">
16
+ <span class="nk-pp-tag"></span>
17
+ <button class="nk-pp-close">
18
+ <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
19
+ </button>
20
+ </div>
21
+ <div class="nk-pp-ai-row">
22
+ <button class="nk-pp-ai-btn" id="nk-pp-ai-btn">
23
+ <span>✦</span> Ask AI about this element
24
+ </button>
25
+ </div>
26
+ <div class="nk-pp-content"></div>
27
+ `;
28
+ injectPropertiesPanelStyles();
29
+ // Close button
30
+ panel.querySelector('.nk-pp-close').addEventListener('click', (e) => {
31
+ e.stopPropagation();
32
+ hidePropertiesPanel();
33
+ });
34
+ // AI button — prefills toolbar AI input with element context
35
+ panel.querySelector('#nk-pp-ai-btn').addEventListener('click', (e) => {
36
+ e.stopPropagation();
37
+ if (!currentElement)
38
+ return;
39
+ const tag = currentElement.tagName.toLowerCase();
40
+ const aiInput = document.querySelector('.nk-tb-page-ai-input');
41
+ if (aiInput) {
42
+ hidePropertiesPanel();
43
+ aiInput.value = `Change the <${tag}> element: `;
44
+ aiInput.focus();
45
+ const sendBtn = document.querySelector('.nk-tb-page-ai-send');
46
+ if (sendBtn)
47
+ sendBtn.disabled = false;
48
+ }
49
+ });
50
+ // Prevent clicks from propagating to element selection
51
+ panel.addEventListener('click', (e) => e.stopPropagation());
52
+ panel.addEventListener('mousedown', (e) => e.stopPropagation());
53
+ panel.addEventListener('touchend', (e) => e.stopPropagation());
54
+ document.body.appendChild(panel);
55
+ // Floating action button for mobile
56
+ const fab = document.createElement('button');
57
+ fab.id = 'nk-pp-fab';
58
+ fab.innerHTML = '<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 20h9"/><path d="M16.5 3.5a2.121 2.121 0 113 3L7 19l-4 1 1-4L16.5 3.5z"/></svg>';
59
+ fab.title = 'Edit properties';
60
+ fab.addEventListener('click', (e) => {
61
+ e.stopPropagation();
62
+ if (!currentElement)
63
+ return;
64
+ fab.classList.remove('visible');
65
+ openPanelFull(currentElement);
66
+ });
67
+ fab.addEventListener('touchend', (e) => e.stopPropagation());
68
+ document.body.appendChild(fab);
69
+ return panel;
70
+ }
71
+ function isMobile() { return window.innerWidth <= 640; }
72
+ function toggleToolbarForPanel(show) {
73
+ const toolbar = document.getElementById('nk-editor-toolbar');
74
+ if (toolbar && isMobile())
75
+ toolbar.style.display = show ? '' : 'none';
76
+ }
77
+ function openPanelFull(element) {
78
+ const tag = element.tagName.toLowerCase();
79
+ panel.querySelector('.nk-pp-tag').textContent = `<${tag}>`;
80
+ toggleToolbarForPanel(false);
81
+ // Hide AI chat on mobile when fullscreen panel opens
82
+ const aiChat = document.getElementById('nk-ai-chat');
83
+ if (aiChat)
84
+ aiChat.classList.remove('open');
85
+ buildPanelContent(element);
86
+ panel.classList.add('open');
87
+ }
88
+ export function showPropertiesForElement(element) {
89
+ currentElement = element;
90
+ resetDebounceTimers();
91
+ if (isMobile()) {
92
+ // On mobile: close any existing open panel, restore toolbar, show FAB
93
+ if (panel.classList.contains('open')) {
94
+ panel.classList.remove('open');
95
+ toggleToolbarForPanel(true);
96
+ }
97
+ const fab = document.getElementById('nk-pp-fab');
98
+ if (fab)
99
+ fab.classList.add('visible');
100
+ return;
101
+ }
102
+ const tag = element.tagName.toLowerCase();
103
+ panel.querySelector('.nk-pp-tag').textContent = `<${tag}>`;
104
+ buildPanelContent(element);
105
+ panel.classList.add('open');
106
+ }
107
+ function buildPanelContent(element) {
108
+ resetDebounceTimers();
109
+ const content = panel.querySelector('.nk-pp-content');
110
+ content.innerHTML = '';
111
+ // Attributes group
112
+ const props = discoverProperties(element);
113
+ const attrGroup = createGroup('Attributes');
114
+ for (const prop of props) {
115
+ attrGroup.appendChild(createPropertyRow(prop, element));
116
+ }
117
+ attrGroup.appendChild(createAddAttributeRow(element, attrGroup));
118
+ content.appendChild(attrGroup);
119
+ // Inline Styles group
120
+ const styleGroup = createGroup('Inline Styles');
121
+ const inlineStyles = parseInlineStyles(element);
122
+ for (const [cssProp, cssVal] of inlineStyles) {
123
+ styleGroup.appendChild(createStyleRow(cssProp, cssVal, element, styleGroup));
124
+ }
125
+ styleGroup.appendChild(createAddStyleRow(element, styleGroup));
126
+ content.appendChild(styleGroup);
127
+ // CSS Rules group
128
+ const cssGroup = createGroup('CSS Rules');
129
+ const cssLoading = document.createElement('div');
130
+ cssLoading.className = 'nk-pp-row';
131
+ cssLoading.innerHTML = '<span class="nk-pp-label" style="width:auto;color:#4a4662">Loading...</span>';
132
+ cssGroup.appendChild(cssLoading);
133
+ content.appendChild(cssGroup);
134
+ const currentElementRef = { get current() { return currentElement; } };
135
+ loadCssRulesForElement(element, cssGroup, currentElementRef, persistState.debounceTimers);
136
+ }
137
+ export function hidePropertiesPanel() {
138
+ panel.classList.remove('open');
139
+ toggleToolbarForPanel(true);
140
+ const fab = document.getElementById('nk-pp-fab');
141
+ if (fab)
142
+ fab.classList.remove('visible');
143
+ currentElement = null;
144
+ resetDebounceTimers();
145
+ }
146
+ export function isPropertiesPanelOpen() {
147
+ return panel.classList.contains('open');
148
+ }