@aquera/nile-elements 2.0.15 → 2.0.17

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 (376) hide show
  1. package/README.md +6 -0
  2. package/demo/nxtgen-classes.css +5 -5
  3. package/demo/nxtgen-dark.css +16 -16
  4. package/demo/nxtgen-properties.css +2 -2
  5. package/demo/nxtgen-utilities.css +5 -5
  6. package/demo/nxtgen.css +5 -5
  7. package/demo/utilities.css +2 -2
  8. package/demo/variables.css +2 -2
  9. package/dist/{index-f6944844.cjs.js → index-0c0c869d.cjs.js} +2 -2
  10. package/dist/{index-f6944844.cjs.js.map → index-0c0c869d.cjs.js.map} +1 -1
  11. package/dist/{index-403841c7.cjs.js → index-129ef6fb.cjs.js} +3 -3
  12. package/dist/{index-403841c7.cjs.js.map → index-129ef6fb.cjs.js.map} +1 -1
  13. package/dist/{index-1faa963c.esm.js → index-36f2a6b5.esm.js} +1 -1
  14. package/dist/index-4df50481.esm.js +1 -0
  15. package/dist/index-5d34cff1.esm.js +1 -0
  16. package/dist/index-7ae95edd.cjs.js +2 -0
  17. package/dist/{index-3ca67627.cjs.js.map → index-7ae95edd.cjs.js.map} +1 -1
  18. package/dist/index-7ca72b78.esm.js +1 -0
  19. package/dist/index-bbe23ad8.cjs.js +2 -0
  20. package/dist/index-bbe23ad8.cjs.js.map +1 -0
  21. package/dist/index-ccc6a799.cjs.js +5 -0
  22. package/dist/index-ccc6a799.cjs.js.map +1 -0
  23. package/dist/index.cjs.js +1 -1
  24. package/dist/index.esm.js +1 -1
  25. package/dist/index.js +124 -72
  26. package/dist/nile-auto-complete/index.cjs.js +1 -1
  27. package/dist/nile-auto-complete/nile-auto-complete.cjs.js +1 -1
  28. package/dist/nile-auto-complete/portal-manager.cjs.js +1 -1
  29. package/dist/nile-auto-complete/portal-utils.cjs.js +1 -1
  30. package/dist/nile-code-editor/extensionSetup.cjs.js +2 -2
  31. package/dist/nile-code-editor/index.cjs.js +1 -1
  32. package/dist/nile-code-editor/nile-code-editor.cjs.js +1 -1
  33. package/dist/nile-code-editor/theme.cjs.js +1 -1
  34. package/dist/nile-color-picker/index.cjs.js +1 -1
  35. package/dist/nile-color-picker/nile-color-picker.cjs.js +1 -1
  36. package/dist/nile-combobox/index.cjs.js +1 -1
  37. package/dist/nile-combobox/nile-combobox.cjs.js +1 -1
  38. package/dist/nile-combobox/portal-manager.cjs.js +1 -1
  39. package/dist/nile-context-menu/index.cjs.js +1 -1
  40. package/dist/nile-context-menu/nile-context-menu.cjs.js +1 -1
  41. package/dist/nile-context-submenu/index.cjs.js +1 -1
  42. package/dist/nile-context-submenu/nile-context-submenu.cjs.js +1 -1
  43. package/dist/nile-detail/index.cjs.js +1 -1
  44. package/dist/nile-detail/nile-detail.cjs.js +1 -1
  45. package/dist/nile-dropdown/index.cjs.js +1 -1
  46. package/dist/nile-dropdown/nile-dropdown.cjs.js +1 -1
  47. package/dist/nile-dropdown/portal-manager.cjs.js +1 -1
  48. package/dist/nile-file-upload/index.cjs.js +1 -1
  49. package/dist/nile-file-upload/nile-file-upload.cjs.js +1 -1
  50. package/dist/nile-file-upload/nile-file-upload.template.cjs.js +1 -1
  51. package/dist/nile-floating-panel/index.cjs.js +1 -1
  52. package/dist/nile-floating-panel/nile-floating-panel.cjs.js +1 -1
  53. package/dist/nile-lite-tooltip/index.cjs.js +1 -1
  54. package/dist/nile-lite-tooltip/nile-lite-tooltip.cjs.js +1 -1
  55. package/dist/nile-lite-tooltip/nile-lite-tooltip.css.cjs.js +1 -1
  56. package/dist/nile-lite-tooltip/nile-lite-tooltip.css.cjs.js.map +1 -1
  57. package/dist/nile-lite-tooltip/nile-lite-tooltip.css.esm.js +1 -1
  58. package/dist/nile-markdown-editor/index.cjs.js +1 -1
  59. package/dist/nile-markdown-editor/nile-markdown-editor.cjs.js +1 -1
  60. package/dist/nile-popover/index.cjs.js +1 -1
  61. package/dist/nile-popover/nile-popover.cjs.js +1 -1
  62. package/dist/nile-popover/portal-manager.cjs.js +1 -1
  63. package/dist/nile-popup/index.cjs.js +1 -1
  64. package/dist/nile-popup/nile-popup.cjs.js +1 -1
  65. package/dist/nile-segmented-progress-bar/index.cjs.js +1 -1
  66. package/dist/nile-segmented-progress-bar/nile-segmented-progress-bar.cjs.js +1 -1
  67. package/dist/nile-select/index.cjs.js +1 -1
  68. package/dist/nile-select/nile-select.cjs.js +1 -1
  69. package/dist/nile-select/portal-manager.cjs.js +1 -1
  70. package/dist/nile-side-bar-action/index.cjs.js +1 -1
  71. package/dist/nile-side-bar-action/nile-side-bar-action.cjs.js +1 -1
  72. package/dist/nile-side-bar-action/portal-manager.cjs.js +1 -1
  73. package/dist/nile-tooltip/index.cjs.js +1 -1
  74. package/dist/nile-tooltip/nile-tooltip.cjs.js +1 -1
  75. package/dist/nile-tooltip/nile-tooltip.css.cjs.js +1 -1
  76. package/dist/nile-tooltip/nile-tooltip.css.cjs.js.map +1 -1
  77. package/dist/nile-tooltip/nile-tooltip.css.esm.js +1 -1
  78. package/dist/nile-virtual-select/index.cjs.js +1 -1
  79. package/dist/nile-virtual-select/nile-virtual-select.cjs.js +1 -1
  80. package/dist/nile-virtual-select/portal-manager.cjs.js +1 -1
  81. package/dist/nile-virtual-select/renderer.cjs.js +1 -1
  82. package/dist/nile-wysiwyg-editor/engine/commands.cjs.js +1 -1
  83. package/dist/nile-wysiwyg-editor/engine/commands.cjs.js.map +1 -1
  84. package/dist/nile-wysiwyg-editor/engine/commands.esm.js +1 -1
  85. package/dist/nile-wysiwyg-editor/engine/create-state.cjs.js +1 -1
  86. package/dist/nile-wysiwyg-editor/engine/create-state.cjs.js.map +1 -1
  87. package/dist/nile-wysiwyg-editor/engine/create-state.esm.js +1 -1
  88. package/dist/nile-wysiwyg-editor/engine/email-css.cjs.js +2 -0
  89. package/dist/nile-wysiwyg-editor/engine/email-css.cjs.js.map +1 -0
  90. package/dist/nile-wysiwyg-editor/engine/email-css.esm.js +1 -0
  91. package/dist/nile-wysiwyg-editor/engine/email-render.cjs.js +2 -0
  92. package/dist/nile-wysiwyg-editor/engine/email-render.cjs.js.map +1 -0
  93. package/dist/nile-wysiwyg-editor/engine/email-render.esm.js +1 -0
  94. package/dist/nile-wysiwyg-editor/engine/html-detect.cjs.js +2 -0
  95. package/dist/nile-wysiwyg-editor/engine/html-detect.cjs.js.map +1 -0
  96. package/dist/nile-wysiwyg-editor/engine/html-detect.esm.js +1 -0
  97. package/dist/nile-wysiwyg-editor/engine/index.cjs.js +1 -1
  98. package/dist/nile-wysiwyg-editor/engine/index.esm.js +1 -1
  99. package/dist/nile-wysiwyg-editor/engine/inputrules.cjs.js +1 -1
  100. package/dist/nile-wysiwyg-editor/engine/inputrules.cjs.js.map +1 -1
  101. package/dist/nile-wysiwyg-editor/engine/inputrules.esm.js +1 -1
  102. package/dist/nile-wysiwyg-editor/engine/keymap.cjs.js +1 -1
  103. package/dist/nile-wysiwyg-editor/engine/keymap.cjs.js.map +1 -1
  104. package/dist/nile-wysiwyg-editor/engine/keymap.esm.js +1 -1
  105. package/dist/nile-wysiwyg-editor/engine/plugins/code-highlight.cjs.js +1 -1
  106. package/dist/nile-wysiwyg-editor/engine/plugins/code-highlight.cjs.js.map +1 -1
  107. package/dist/nile-wysiwyg-editor/engine/plugins/code-highlight.esm.js +1 -1
  108. package/dist/nile-wysiwyg-editor/engine/plugins/embed-view.cjs.js +1 -1
  109. package/dist/nile-wysiwyg-editor/engine/plugins/embed-view.cjs.js.map +1 -1
  110. package/dist/nile-wysiwyg-editor/engine/plugins/embed-view.esm.js +1 -1
  111. package/dist/nile-wysiwyg-editor/engine/plugins/embeds.cjs.js +1 -1
  112. package/dist/nile-wysiwyg-editor/engine/plugins/embeds.cjs.js.map +1 -1
  113. package/dist/nile-wysiwyg-editor/engine/plugins/embeds.esm.js +1 -1
  114. package/dist/nile-wysiwyg-editor/engine/plugins/find-replace.cjs.js +1 -1
  115. package/dist/nile-wysiwyg-editor/engine/plugins/find-replace.cjs.js.map +1 -1
  116. package/dist/nile-wysiwyg-editor/engine/plugins/find-replace.esm.js +1 -1
  117. package/dist/nile-wysiwyg-editor/engine/plugins/format-painter.cjs.js +1 -1
  118. package/dist/nile-wysiwyg-editor/engine/plugins/format-painter.cjs.js.map +1 -1
  119. package/dist/nile-wysiwyg-editor/engine/plugins/format-painter.esm.js +1 -1
  120. package/dist/nile-wysiwyg-editor/engine/plugins/image-view.cjs.js +1 -1
  121. package/dist/nile-wysiwyg-editor/engine/plugins/image-view.cjs.js.map +1 -1
  122. package/dist/nile-wysiwyg-editor/engine/plugins/image-view.esm.js +1 -1
  123. package/dist/nile-wysiwyg-editor/engine/plugins/image.cjs.js +1 -1
  124. package/dist/nile-wysiwyg-editor/engine/plugins/image.cjs.js.map +1 -1
  125. package/dist/nile-wysiwyg-editor/engine/plugins/image.esm.js +1 -1
  126. package/dist/nile-wysiwyg-editor/engine/plugins/link.cjs.js +1 -1
  127. package/dist/nile-wysiwyg-editor/engine/plugins/link.cjs.js.map +1 -1
  128. package/dist/nile-wysiwyg-editor/engine/plugins/link.esm.js +1 -1
  129. package/dist/nile-wysiwyg-editor/engine/plugins/max-length.cjs.js +1 -1
  130. package/dist/nile-wysiwyg-editor/engine/plugins/max-length.cjs.js.map +1 -1
  131. package/dist/nile-wysiwyg-editor/engine/plugins/max-length.esm.js +1 -1
  132. package/dist/nile-wysiwyg-editor/engine/plugins/paste.cjs.js +1 -1
  133. package/dist/nile-wysiwyg-editor/engine/plugins/paste.cjs.js.map +1 -1
  134. package/dist/nile-wysiwyg-editor/engine/plugins/paste.esm.js +1 -1
  135. package/dist/nile-wysiwyg-editor/engine/plugins/placeholder.cjs.js +1 -1
  136. package/dist/nile-wysiwyg-editor/engine/plugins/placeholder.cjs.js.map +1 -1
  137. package/dist/nile-wysiwyg-editor/engine/plugins/placeholder.esm.js +1 -1
  138. package/dist/nile-wysiwyg-editor/engine/plugins/single-line.cjs.js +1 -1
  139. package/dist/nile-wysiwyg-editor/engine/plugins/single-line.cjs.js.map +1 -1
  140. package/dist/nile-wysiwyg-editor/engine/plugins/single-line.esm.js +1 -1
  141. package/dist/nile-wysiwyg-editor/engine/plugins/suggestions.cjs.js +1 -1
  142. package/dist/nile-wysiwyg-editor/engine/plugins/suggestions.cjs.js.map +1 -1
  143. package/dist/nile-wysiwyg-editor/engine/plugins/suggestions.esm.js +1 -1
  144. package/dist/nile-wysiwyg-editor/engine/plugins/tables.cjs.js +1 -1
  145. package/dist/nile-wysiwyg-editor/engine/plugins/tables.cjs.js.map +1 -1
  146. package/dist/nile-wysiwyg-editor/engine/plugins/tables.esm.js +1 -1
  147. package/dist/nile-wysiwyg-editor/engine/sanitize.cjs.js +2 -1
  148. package/dist/nile-wysiwyg-editor/engine/sanitize.cjs.js.map +1 -1
  149. package/dist/nile-wysiwyg-editor/engine/sanitize.esm.js +1 -1
  150. package/dist/nile-wysiwyg-editor/engine/schema.cjs.js +1 -1
  151. package/dist/nile-wysiwyg-editor/engine/schema.cjs.js.map +1 -1
  152. package/dist/nile-wysiwyg-editor/engine/schema.esm.js +1 -1
  153. package/dist/nile-wysiwyg-editor/engine/selection-state.cjs.js +1 -1
  154. package/dist/nile-wysiwyg-editor/engine/selection-state.cjs.js.map +1 -1
  155. package/dist/nile-wysiwyg-editor/engine/selection-state.esm.js +1 -1
  156. package/dist/nile-wysiwyg-editor/engine/serializer.cjs.js +1 -1
  157. package/dist/nile-wysiwyg-editor/engine/serializer.cjs.js.map +1 -1
  158. package/dist/nile-wysiwyg-editor/engine/serializer.esm.js +1 -1
  159. package/dist/nile-wysiwyg-editor/index.cjs.js +1 -1
  160. package/dist/nile-wysiwyg-editor/index.esm.js +1 -1
  161. package/dist/nile-wysiwyg-editor/nile-wysiwyg-editor.cjs.js +1 -1
  162. package/dist/nile-wysiwyg-editor/nile-wysiwyg-editor.cjs.js.map +1 -1
  163. package/dist/nile-wysiwyg-editor/nile-wysiwyg-editor.css.cjs.js +1 -1
  164. package/dist/nile-wysiwyg-editor/nile-wysiwyg-editor.css.cjs.js.map +1 -1
  165. package/dist/nile-wysiwyg-editor/nile-wysiwyg-editor.css.esm.js +45 -4
  166. package/dist/nile-wysiwyg-editor/nile-wysiwyg-editor.esm.js +2 -2
  167. package/dist/nile-wysiwyg-editor/nile-wysiwyg-toolbar/index.cjs.js +1 -1
  168. package/dist/nile-wysiwyg-editor/nile-wysiwyg-toolbar/nile-wysiwyg-toolbar.cjs.js +1 -1
  169. package/dist/nile-wysiwyg-editor/ui/bookmark-panel.cjs.js +1 -1
  170. package/dist/nile-wysiwyg-editor/ui/bookmark-panel.cjs.js.map +1 -1
  171. package/dist/nile-wysiwyg-editor/ui/bookmark-panel.esm.js +2 -2
  172. package/dist/nile-wysiwyg-editor/ui/bubble-menu.cjs.js +1 -1
  173. package/dist/nile-wysiwyg-editor/ui/bubble-menu.cjs.js.map +1 -1
  174. package/dist/nile-wysiwyg-editor/ui/bubble-menu.esm.js +5 -5
  175. package/dist/nile-wysiwyg-editor/ui/code-block-menu.cjs.js +1 -1
  176. package/dist/nile-wysiwyg-editor/ui/code-block-menu.cjs.js.map +1 -1
  177. package/dist/nile-wysiwyg-editor/ui/code-block-menu.esm.js +1 -1
  178. package/dist/nile-wysiwyg-editor/ui/embed-menu.cjs.js +1 -1
  179. package/dist/nile-wysiwyg-editor/ui/embed-menu.cjs.js.map +1 -1
  180. package/dist/nile-wysiwyg-editor/ui/embed-menu.esm.js +1 -1
  181. package/dist/nile-wysiwyg-editor/ui/embed-panel.cjs.js +1 -1
  182. package/dist/nile-wysiwyg-editor/ui/embed-panel.cjs.js.map +1 -1
  183. package/dist/nile-wysiwyg-editor/ui/embed-panel.esm.js +2 -2
  184. package/dist/nile-wysiwyg-editor/ui/emoji-picker.cjs.js +1 -1
  185. package/dist/nile-wysiwyg-editor/ui/emoji-picker.cjs.js.map +1 -1
  186. package/dist/nile-wysiwyg-editor/ui/emoji-picker.esm.js +1 -1
  187. package/dist/nile-wysiwyg-editor/ui/find-replace.cjs.js +1 -1
  188. package/dist/nile-wysiwyg-editor/ui/find-replace.cjs.js.map +1 -1
  189. package/dist/nile-wysiwyg-editor/ui/find-replace.esm.js +3 -3
  190. package/dist/nile-wysiwyg-editor/ui/image-menu.cjs.js +1 -1
  191. package/dist/nile-wysiwyg-editor/ui/image-menu.cjs.js.map +1 -1
  192. package/dist/nile-wysiwyg-editor/ui/image-menu.esm.js +3 -3
  193. package/dist/nile-wysiwyg-editor/ui/image-panel.cjs.js +1 -1
  194. package/dist/nile-wysiwyg-editor/ui/image-panel.cjs.js.map +1 -1
  195. package/dist/nile-wysiwyg-editor/ui/image-panel.esm.js +1 -1
  196. package/dist/nile-wysiwyg-editor/ui/insert-menu.cjs.js +1 -1
  197. package/dist/nile-wysiwyg-editor/ui/insert-menu.cjs.js.map +1 -1
  198. package/dist/nile-wysiwyg-editor/ui/insert-menu.esm.js +1 -1
  199. package/dist/nile-wysiwyg-editor/ui/link-editor.cjs.js +1 -1
  200. package/dist/nile-wysiwyg-editor/ui/link-editor.cjs.js.map +1 -1
  201. package/dist/nile-wysiwyg-editor/ui/link-editor.esm.js +9 -9
  202. package/dist/nile-wysiwyg-editor/ui/markdown-panel.cjs.js +1 -1
  203. package/dist/nile-wysiwyg-editor/ui/markdown-panel.cjs.js.map +1 -1
  204. package/dist/nile-wysiwyg-editor/ui/markdown-panel.esm.js +1 -1
  205. package/dist/nile-wysiwyg-editor/ui/math-panel.cjs.js +1 -1
  206. package/dist/nile-wysiwyg-editor/ui/math-panel.cjs.js.map +1 -1
  207. package/dist/nile-wysiwyg-editor/ui/math-panel.esm.js +1 -1
  208. package/dist/nile-wysiwyg-editor/ui/shortcut-help.cjs.js +1 -1
  209. package/dist/nile-wysiwyg-editor/ui/shortcut-help.cjs.js.map +1 -1
  210. package/dist/nile-wysiwyg-editor/ui/shortcut-help.esm.js +1 -1
  211. package/dist/nile-wysiwyg-editor/ui/source-view.cjs.js +1 -1
  212. package/dist/nile-wysiwyg-editor/ui/source-view.cjs.js.map +1 -1
  213. package/dist/nile-wysiwyg-editor/ui/source-view.esm.js +4 -4
  214. package/dist/nile-wysiwyg-editor/ui/special-chars.cjs.js +1 -1
  215. package/dist/nile-wysiwyg-editor/ui/special-chars.cjs.js.map +1 -1
  216. package/dist/nile-wysiwyg-editor/ui/special-chars.esm.js +1 -1
  217. package/dist/nile-wysiwyg-editor/ui/suggest-list.cjs.js +1 -1
  218. package/dist/nile-wysiwyg-editor/ui/suggest-list.cjs.js.map +1 -1
  219. package/dist/nile-wysiwyg-editor/ui/suggest-list.esm.js +23 -12
  220. package/dist/nile-wysiwyg-editor/ui/table-grid-picker.cjs.js +1 -1
  221. package/dist/nile-wysiwyg-editor/ui/table-grid-picker.cjs.js.map +1 -1
  222. package/dist/nile-wysiwyg-editor/ui/table-grid-picker.esm.js +7 -7
  223. package/dist/nile-wysiwyg-editor/ui/table-menu.cjs.js +1 -1
  224. package/dist/nile-wysiwyg-editor/ui/table-menu.cjs.js.map +1 -1
  225. package/dist/nile-wysiwyg-editor/ui/table-menu.esm.js +1 -1
  226. package/dist/src/nile-lite-tooltip/nile-lite-tooltip.css.js +1 -1
  227. package/dist/src/nile-lite-tooltip/nile-lite-tooltip.css.js.map +1 -1
  228. package/dist/src/nile-tooltip/nile-tooltip.css.js +1 -1
  229. package/dist/src/nile-tooltip/nile-tooltip.css.js.map +1 -1
  230. package/dist/src/nile-wysiwyg-editor/engine/create-state.d.ts +5 -0
  231. package/dist/src/nile-wysiwyg-editor/engine/create-state.js +2 -0
  232. package/dist/src/nile-wysiwyg-editor/engine/create-state.js.map +1 -1
  233. package/dist/src/nile-wysiwyg-editor/engine/email-css.d.ts +14 -0
  234. package/dist/src/nile-wysiwyg-editor/engine/email-css.js +140 -0
  235. package/dist/src/nile-wysiwyg-editor/engine/email-css.js.map +1 -0
  236. package/dist/src/nile-wysiwyg-editor/engine/email-fidelity.test.d.ts +1 -0
  237. package/dist/src/nile-wysiwyg-editor/engine/email-fidelity.test.js +1045 -0
  238. package/dist/src/nile-wysiwyg-editor/engine/email-fidelity.test.js.map +1 -0
  239. package/dist/src/nile-wysiwyg-editor/engine/email-render.d.ts +11 -0
  240. package/dist/src/nile-wysiwyg-editor/engine/email-render.js +93 -0
  241. package/dist/src/nile-wysiwyg-editor/engine/email-render.js.map +1 -0
  242. package/dist/src/nile-wysiwyg-editor/engine/html-detect.d.ts +2 -0
  243. package/dist/src/nile-wysiwyg-editor/engine/html-detect.js +24 -0
  244. package/dist/src/nile-wysiwyg-editor/engine/html-detect.js.map +1 -0
  245. package/dist/src/nile-wysiwyg-editor/engine/index.d.ts +4 -1
  246. package/dist/src/nile-wysiwyg-editor/engine/index.js +3 -1
  247. package/dist/src/nile-wysiwyg-editor/engine/index.js.map +1 -1
  248. package/dist/src/nile-wysiwyg-editor/engine/inputrules.d.ts +0 -5
  249. package/dist/src/nile-wysiwyg-editor/engine/inputrules.js +19 -0
  250. package/dist/src/nile-wysiwyg-editor/engine/inputrules.js.map +1 -1
  251. package/dist/src/nile-wysiwyg-editor/engine/plugins/image-view.js +3 -2
  252. package/dist/src/nile-wysiwyg-editor/engine/plugins/image-view.js.map +1 -1
  253. package/dist/src/nile-wysiwyg-editor/engine/plugins/link.d.ts +4 -0
  254. package/dist/src/nile-wysiwyg-editor/engine/plugins/link.js +56 -1
  255. package/dist/src/nile-wysiwyg-editor/engine/plugins/link.js.map +1 -1
  256. package/dist/src/nile-wysiwyg-editor/engine/plugins/paste.d.ts +5 -0
  257. package/dist/src/nile-wysiwyg-editor/engine/plugins/paste.js +27 -6
  258. package/dist/src/nile-wysiwyg-editor/engine/plugins/paste.js.map +1 -1
  259. package/dist/src/nile-wysiwyg-editor/engine/plugins/tables.js +30 -7
  260. package/dist/src/nile-wysiwyg-editor/engine/plugins/tables.js.map +1 -1
  261. package/dist/src/nile-wysiwyg-editor/engine/pm.test.js +46 -0
  262. package/dist/src/nile-wysiwyg-editor/engine/pm.test.js.map +1 -1
  263. package/dist/src/nile-wysiwyg-editor/engine/sanitize.d.ts +9 -1
  264. package/dist/src/nile-wysiwyg-editor/engine/sanitize.js +730 -7
  265. package/dist/src/nile-wysiwyg-editor/engine/sanitize.js.map +1 -1
  266. package/dist/src/nile-wysiwyg-editor/engine/schema.d.ts +3 -0
  267. package/dist/src/nile-wysiwyg-editor/engine/schema.js +215 -34
  268. package/dist/src/nile-wysiwyg-editor/engine/schema.js.map +1 -1
  269. package/dist/src/nile-wysiwyg-editor/engine/selection-state.js +3 -1
  270. package/dist/src/nile-wysiwyg-editor/engine/selection-state.js.map +1 -1
  271. package/dist/src/nile-wysiwyg-editor/engine/serializer.d.ts +12 -4
  272. package/dist/src/nile-wysiwyg-editor/engine/serializer.js +18 -8
  273. package/dist/src/nile-wysiwyg-editor/engine/serializer.js.map +1 -1
  274. package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-editor-email-fidelity.test.d.ts +1 -0
  275. package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-editor-email-fidelity.test.js +287 -0
  276. package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-editor-email-fidelity.test.js.map +1 -0
  277. package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-editor.css.js +45 -4
  278. package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-editor.css.js.map +1 -1
  279. package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-editor.d.ts +23 -0
  280. package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-editor.js +113 -15
  281. package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-editor.js.map +1 -1
  282. package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-editor.test.js +213 -0
  283. package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-editor.test.js.map +1 -1
  284. package/dist/src/nile-wysiwyg-editor/ui/bookmark-panel.js +2 -2
  285. package/dist/src/nile-wysiwyg-editor/ui/bookmark-panel.js.map +1 -1
  286. package/dist/src/nile-wysiwyg-editor/ui/bubble-menu.js +1 -1
  287. package/dist/src/nile-wysiwyg-editor/ui/bubble-menu.js.map +1 -1
  288. package/dist/src/nile-wysiwyg-editor/ui/embed-menu.js +1 -1
  289. package/dist/src/nile-wysiwyg-editor/ui/embed-menu.js.map +1 -1
  290. package/dist/src/nile-wysiwyg-editor/ui/embed-panel.js +1 -1
  291. package/dist/src/nile-wysiwyg-editor/ui/embed-panel.js.map +1 -1
  292. package/dist/src/nile-wysiwyg-editor/ui/emoji-picker.js +1 -1
  293. package/dist/src/nile-wysiwyg-editor/ui/emoji-picker.js.map +1 -1
  294. package/dist/src/nile-wysiwyg-editor/ui/find-replace.js +1 -1
  295. package/dist/src/nile-wysiwyg-editor/ui/find-replace.js.map +1 -1
  296. package/dist/src/nile-wysiwyg-editor/ui/image-menu.js +1 -1
  297. package/dist/src/nile-wysiwyg-editor/ui/image-menu.js.map +1 -1
  298. package/dist/src/nile-wysiwyg-editor/ui/image-panel.js +1 -1
  299. package/dist/src/nile-wysiwyg-editor/ui/image-panel.js.map +1 -1
  300. package/dist/src/nile-wysiwyg-editor/ui/insert-menu.js +1 -1
  301. package/dist/src/nile-wysiwyg-editor/ui/insert-menu.js.map +1 -1
  302. package/dist/src/nile-wysiwyg-editor/ui/link-editor.js +2 -2
  303. package/dist/src/nile-wysiwyg-editor/ui/link-editor.js.map +1 -1
  304. package/dist/src/nile-wysiwyg-editor/ui/markdown-panel.js +1 -1
  305. package/dist/src/nile-wysiwyg-editor/ui/markdown-panel.js.map +1 -1
  306. package/dist/src/nile-wysiwyg-editor/ui/math-panel.js +1 -1
  307. package/dist/src/nile-wysiwyg-editor/ui/math-panel.js.map +1 -1
  308. package/dist/src/nile-wysiwyg-editor/ui/shortcut-help.js +1 -1
  309. package/dist/src/nile-wysiwyg-editor/ui/shortcut-help.js.map +1 -1
  310. package/dist/src/nile-wysiwyg-editor/ui/source-view.js +2 -2
  311. package/dist/src/nile-wysiwyg-editor/ui/source-view.js.map +1 -1
  312. package/dist/src/nile-wysiwyg-editor/ui/special-chars.js +1 -1
  313. package/dist/src/nile-wysiwyg-editor/ui/special-chars.js.map +1 -1
  314. package/dist/src/nile-wysiwyg-editor/ui/suggest-list.js +14 -3
  315. package/dist/src/nile-wysiwyg-editor/ui/suggest-list.js.map +1 -1
  316. package/dist/src/nile-wysiwyg-editor/ui/table-grid-picker.js +2 -2
  317. package/dist/src/nile-wysiwyg-editor/ui/table-grid-picker.js.map +1 -1
  318. package/dist/src/nile-wysiwyg-editor/ui/table-menu.js +1 -1
  319. package/dist/src/nile-wysiwyg-editor/ui/table-menu.js.map +1 -1
  320. package/dist/src/version.js +1 -1
  321. package/dist/src/version.js.map +1 -1
  322. package/dist/tsconfig.tsbuildinfo +1 -1
  323. package/dist/version.cjs.js +1 -1
  324. package/dist/version.cjs.js.map +1 -1
  325. package/dist/version.esm.js +1 -1
  326. package/package.json +1 -1
  327. package/src/nile-lite-tooltip/nile-lite-tooltip.css.ts +1 -1
  328. package/src/nile-tooltip/nile-tooltip.css.ts +1 -1
  329. package/src/nile-wysiwyg-editor/engine/create-state.ts +7 -0
  330. package/src/nile-wysiwyg-editor/engine/email-css.ts +136 -0
  331. package/src/nile-wysiwyg-editor/engine/email-fidelity.test.ts +1347 -0
  332. package/src/nile-wysiwyg-editor/engine/email-render.ts +99 -0
  333. package/src/nile-wysiwyg-editor/engine/html-detect.ts +26 -0
  334. package/src/nile-wysiwyg-editor/engine/index.ts +10 -1
  335. package/src/nile-wysiwyg-editor/engine/inputrules.ts +18 -1
  336. package/src/nile-wysiwyg-editor/engine/plugins/image-view.ts +3 -2
  337. package/src/nile-wysiwyg-editor/engine/plugins/link.ts +58 -2
  338. package/src/nile-wysiwyg-editor/engine/plugins/paste.ts +31 -8
  339. package/src/nile-wysiwyg-editor/engine/plugins/tables.ts +29 -7
  340. package/src/nile-wysiwyg-editor/engine/pm.test.ts +73 -0
  341. package/src/nile-wysiwyg-editor/engine/sanitize.ts +729 -7
  342. package/src/nile-wysiwyg-editor/engine/schema.ts +206 -33
  343. package/src/nile-wysiwyg-editor/engine/selection-state.ts +3 -1
  344. package/src/nile-wysiwyg-editor/engine/serializer.ts +30 -8
  345. package/src/nile-wysiwyg-editor/nile-wysiwyg-editor-email-fidelity.test.ts +357 -0
  346. package/src/nile-wysiwyg-editor/nile-wysiwyg-editor.css.ts +45 -4
  347. package/src/nile-wysiwyg-editor/nile-wysiwyg-editor.test.ts +258 -0
  348. package/src/nile-wysiwyg-editor/nile-wysiwyg-editor.ts +119 -12
  349. package/src/nile-wysiwyg-editor/ui/bookmark-panel.ts +2 -2
  350. package/src/nile-wysiwyg-editor/ui/bubble-menu.ts +1 -1
  351. package/src/nile-wysiwyg-editor/ui/embed-menu.ts +1 -1
  352. package/src/nile-wysiwyg-editor/ui/embed-panel.ts +1 -1
  353. package/src/nile-wysiwyg-editor/ui/emoji-picker.ts +1 -1
  354. package/src/nile-wysiwyg-editor/ui/find-replace.ts +1 -1
  355. package/src/nile-wysiwyg-editor/ui/image-menu.ts +1 -1
  356. package/src/nile-wysiwyg-editor/ui/image-panel.ts +1 -1
  357. package/src/nile-wysiwyg-editor/ui/insert-menu.ts +1 -1
  358. package/src/nile-wysiwyg-editor/ui/link-editor.ts +2 -2
  359. package/src/nile-wysiwyg-editor/ui/markdown-panel.ts +1 -1
  360. package/src/nile-wysiwyg-editor/ui/math-panel.ts +1 -1
  361. package/src/nile-wysiwyg-editor/ui/shortcut-help.ts +1 -1
  362. package/src/nile-wysiwyg-editor/ui/source-view.ts +2 -2
  363. package/src/nile-wysiwyg-editor/ui/special-chars.ts +1 -1
  364. package/src/nile-wysiwyg-editor/ui/suggest-list.ts +14 -3
  365. package/src/nile-wysiwyg-editor/ui/table-grid-picker.ts +2 -2
  366. package/src/nile-wysiwyg-editor/ui/table-menu.ts +1 -1
  367. package/vscode-html-custom-data.json +15 -1
  368. package/web-test-runner.config.mjs +4 -0
  369. package/dist/index-3ca67627.cjs.js +0 -2
  370. package/dist/index-6f3fa4ab.esm.js +0 -1
  371. package/dist/index-7b1c9857.esm.js +0 -1
  372. package/dist/index-89c520e9.cjs.js +0 -5
  373. package/dist/index-89c520e9.cjs.js.map +0 -1
  374. package/dist/index-ba47645d.esm.js +0 -1
  375. package/dist/index-c3210a9c.cjs.js +0 -2
  376. package/dist/index-c3210a9c.cjs.js.map +0 -1
@@ -35,7 +35,7 @@ let NileWysiwygBookmarkPanel = class NileWysiwygBookmarkPanel extends NileElemen
35
35
  gap: 8px;
36
36
  min-width: 280px;
37
37
  padding: 12px;
38
- background: var(--nile-wysiwyg-popover-bg, var(--ng-colors-bg-primary));
38
+ background: var(--nile-wysiwyg-popover-bg, var(--nile-colors-white-base, var(--ng-colors-bg-primary)));
39
39
  border: 1px solid var(--nile-colors-neutral-400, var(--ng-colors-border-primary));
40
40
  border-radius: var(--nile-wysiwyg-radius, 8px);
41
41
  box-shadow: var(--nile-wysiwyg-popover-shadow, 0 4px 12px rgba(16, 24, 40, 0.12));
@@ -89,7 +89,7 @@ let NileWysiwygBookmarkPanel = class NileWysiwygBookmarkPanel extends NileElemen
89
89
 
90
90
  button.primary {
91
91
  background: var(--nile-colors-primary-600, var(--ng-componentcolors-utility-blue-600));
92
- color: var(--ng-colors-text-white);
92
+ color: var(--nile-colors-white-base, var(--ng-colors-text-white));
93
93
  }
94
94
  `,
95
95
  ];
@@ -1 +1 @@
1
- {"version":3,"file":"bookmark-panel.js","sourceRoot":"","sources":["../../../../src/nile-wysiwyg-editor/ui/bookmark-panel.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAE,GAAG,EAAkC,MAAM,KAAK,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC1E,OAAO,WAAW,MAAM,6BAA6B,CAAC;AAEtD;;;GAGG;AAEI,IAAM,wBAAwB,GAA9B,MAAM,wBAAyB,SAAQ,WAAW;IAAlD;;QACuC,SAAI,GAAG,KAAK,CAAC;QAExC,UAAK,GAAG,EAAE,CAAC;IAwI9B,CAAC;IApIQ,MAAM,KAAK,MAAM;QACtB,OAAO;YACL,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA6EF;SACF,CAAC;IACJ,CAAC;IAEM,UAAU;QACf,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;QAChB,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,EAAE;YAC5B,IAAI,IAAI,CAAC,SAAS;gBAAE,IAAI,CAAC,SAAS,CAAC,KAAK,GAAG,EAAE,CAAC;YAC9C,IAAI,CAAC,SAAS,EAAE,KAAK,EAAE,CAAC;QAC1B,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,YAAY,CAAC,KAAY;QAC/B,KAAK,CAAC,cAAc,EAAE,CAAC;QACvB,uEAAuE;QACvE,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QACrE,IAAI,CAAC,EAAE,EAAE,CAAC;YACR,IAAI,CAAC,KAAK,GAAG,wBAAwB,CAAC;YACtC,OAAO;QACT,CAAC;QACD,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;QAChB,IAAI,CAAC,IAAI,CAAC,wBAAwB,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;IAC9C,CAAC;IAEM,MAAM;QACX,OAAO,IAAI,CAAA;;;;kBAIG,IAAI,CAAC,YAAY;mBAChB,CAAC,CAAgB,EAAE,EAAE;YAC9B,IAAI,CAAC,CAAC,GAAG,KAAK,QAAQ,EAAE,CAAC;gBACvB,CAAC,CAAC,eAAe,EAAE,CAAC;gBACpB,IAAI,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;YACvC,CAAC;QACH,CAAC;;;;;;UAMC,IAAI,CAAC,KAAK;YACV,CAAC,CAAC,IAAI,CAAA,sBAAsB,IAAI,CAAC,KAAK,QAAQ;YAC9C,CAAC,CAAC,IAAI,CAAA,wEAAwE;;yCAE/C,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,yBAAyB,CAAC;;;;;;KAM9E,CAAC;IACJ,CAAC;CACF,CAAA;AA1I6C;IAA3C,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;sDAAc;AAExC;IAAhB,KAAK,EAAE;uDAAoB;AAEI;IAA/B,KAAK,CAAC,uBAAuB,CAAC;2DAA8B;AALlD,wBAAwB;IADpC,aAAa,CAAC,6BAA6B,CAAC;GAChC,wBAAwB,CA2IpC","sourcesContent":["import { html, css, TemplateResult, CSSResultArray } from 'lit';\nimport { customElement, property, query, state } from 'lit/decorators.js';\nimport NileElement from '../../internal/nile-element';\n\n/**\n * Floating bookmark-insert panel: name an in-text anchor. Emits\n * `wysiwyg-bookmark-apply` detail: { id } and `wysiwyg-bookmark-cancel`.\n */\n@customElement('nile-wysiwyg-bookmark-panel')\nexport class NileWysiwygBookmarkPanel extends NileElement {\n @property({ type: Boolean, reflect: true }) open = false;\n\n @state() private error = '';\n\n @query('.bookmark-panel__name') nameInput?: HTMLInputElement;\n\n public static get styles(): CSSResultArray {\n return [\n css`\n :host {\n font-family: var(\n --nile-font-family-sans-serif,\n var(--ng-font-family-body, system-ui, -apple-system, sans-serif)\n );\n position: absolute;\n z-index: 20;\n display: none;\n }\n\n :host([open]) {\n display: block;\n }\n\n .bookmark-panel {\n display: flex;\n flex-direction: column;\n gap: 8px;\n min-width: 280px;\n padding: 12px;\n background: var(--nile-wysiwyg-popover-bg, var(--ng-colors-bg-primary));\n border: 1px solid var(--nile-colors-neutral-400, var(--ng-colors-border-primary));\n border-radius: var(--nile-wysiwyg-radius, 8px);\n box-shadow: var(--nile-wysiwyg-popover-shadow, 0 4px 12px rgba(16, 24, 40, 0.12));\n font-size: 13px;\n }\n\n label {\n display: flex;\n flex-direction: column;\n gap: 4px;\n color: var(--nile-colors-neutral-700, var(--ng-colors-text-secondary-700));\n }\n\n input {\n font: inherit;\n padding: 6px 8px;\n border: 1px solid var(--nile-colors-neutral-400, var(--ng-colors-border-primary));\n border-radius: 6px;\n outline: none;\n }\n\n input:focus {\n border-color: var(--nile-colors-primary-600, var(--ng-componentcolors-utility-blue-600));\n }\n\n .hint {\n font-size: 12px;\n color: var(--nile-colors-neutral-500, var(--ng-colors-text-quaternary-500));\n }\n\n .error {\n font-size: 12px;\n color: var(--nile-colors-error-600, var(--ng-componentcolors-utility-error-600));\n }\n\n .actions {\n display: flex;\n gap: 8px;\n justify-content: flex-end;\n }\n\n button {\n font: inherit;\n padding: 6px 12px;\n border-radius: 6px;\n border: 1px solid transparent;\n cursor: pointer;\n background: transparent;\n color: var(--nile-colors-neutral-700, var(--ng-colors-text-secondary-700));\n }\n\n button.primary {\n background: var(--nile-colors-primary-600, var(--ng-componentcolors-utility-blue-600));\n color: var(--ng-colors-text-white);\n }\n `,\n ];\n }\n\n public focusInput(): void {\n this.error = '';\n this.updateComplete.then(() => {\n if (this.nameInput) this.nameInput.value = '';\n this.nameInput?.focus();\n });\n }\n\n private handleSubmit(event: Event): void {\n event.preventDefault();\n // Anchor ids can't contain whitespace; collapse runs to a single dash.\n const id = (this.nameInput?.value ?? '').trim().replace(/\\s+/g, '-');\n if (!id) {\n this.error = 'Enter a bookmark name.';\n return;\n }\n this.error = '';\n this.emit('wysiwyg-bookmark-apply', { id });\n }\n\n public render(): TemplateResult {\n return html`\n <form\n class=\"bookmark-panel\"\n part=\"bookmark-panel\"\n @submit=${this.handleSubmit}\n @keydown=${(e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n e.stopPropagation();\n this.emit('wysiwyg-bookmark-cancel');\n }\n }}\n >\n <label>\n Bookmark name\n <input class=\"bookmark-panel__name\" type=\"text\" placeholder=\"section-intro\" />\n </label>\n ${this.error\n ? html`<div class=\"error\">${this.error}</div>`\n : html`<div class=\"hint\">An invisible anchor you can link to with #name</div>`}\n <div class=\"actions\">\n <button type=\"button\" @click=${() => this.emit('wysiwyg-bookmark-cancel')}>\n Cancel\n </button>\n <button type=\"submit\" class=\"primary\">Insert</button>\n </div>\n </form>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'nile-wysiwyg-bookmark-panel': NileWysiwygBookmarkPanel;\n }\n}\n"]}
1
+ {"version":3,"file":"bookmark-panel.js","sourceRoot":"","sources":["../../../../src/nile-wysiwyg-editor/ui/bookmark-panel.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAE,GAAG,EAAkC,MAAM,KAAK,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC1E,OAAO,WAAW,MAAM,6BAA6B,CAAC;AAEtD;;;GAGG;AAEI,IAAM,wBAAwB,GAA9B,MAAM,wBAAyB,SAAQ,WAAW;IAAlD;;QACuC,SAAI,GAAG,KAAK,CAAC;QAExC,UAAK,GAAG,EAAE,CAAC;IAwI9B,CAAC;IApIQ,MAAM,KAAK,MAAM;QACtB,OAAO;YACL,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA6EF;SACF,CAAC;IACJ,CAAC;IAEM,UAAU;QACf,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;QAChB,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,EAAE;YAC5B,IAAI,IAAI,CAAC,SAAS;gBAAE,IAAI,CAAC,SAAS,CAAC,KAAK,GAAG,EAAE,CAAC;YAC9C,IAAI,CAAC,SAAS,EAAE,KAAK,EAAE,CAAC;QAC1B,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,YAAY,CAAC,KAAY;QAC/B,KAAK,CAAC,cAAc,EAAE,CAAC;QACvB,uEAAuE;QACvE,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QACrE,IAAI,CAAC,EAAE,EAAE,CAAC;YACR,IAAI,CAAC,KAAK,GAAG,wBAAwB,CAAC;YACtC,OAAO;QACT,CAAC;QACD,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;QAChB,IAAI,CAAC,IAAI,CAAC,wBAAwB,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;IAC9C,CAAC;IAEM,MAAM;QACX,OAAO,IAAI,CAAA;;;;kBAIG,IAAI,CAAC,YAAY;mBAChB,CAAC,CAAgB,EAAE,EAAE;YAC9B,IAAI,CAAC,CAAC,GAAG,KAAK,QAAQ,EAAE,CAAC;gBACvB,CAAC,CAAC,eAAe,EAAE,CAAC;gBACpB,IAAI,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;YACvC,CAAC;QACH,CAAC;;;;;;UAMC,IAAI,CAAC,KAAK;YACV,CAAC,CAAC,IAAI,CAAA,sBAAsB,IAAI,CAAC,KAAK,QAAQ;YAC9C,CAAC,CAAC,IAAI,CAAA,wEAAwE;;yCAE/C,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,yBAAyB,CAAC;;;;;;KAM9E,CAAC;IACJ,CAAC;CACF,CAAA;AA1I6C;IAA3C,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;sDAAc;AAExC;IAAhB,KAAK,EAAE;uDAAoB;AAEI;IAA/B,KAAK,CAAC,uBAAuB,CAAC;2DAA8B;AALlD,wBAAwB;IADpC,aAAa,CAAC,6BAA6B,CAAC;GAChC,wBAAwB,CA2IpC","sourcesContent":["import { html, css, TemplateResult, CSSResultArray } from 'lit';\nimport { customElement, property, query, state } from 'lit/decorators.js';\nimport NileElement from '../../internal/nile-element';\n\n/**\n * Floating bookmark-insert panel: name an in-text anchor. Emits\n * `wysiwyg-bookmark-apply` detail: { id } and `wysiwyg-bookmark-cancel`.\n */\n@customElement('nile-wysiwyg-bookmark-panel')\nexport class NileWysiwygBookmarkPanel extends NileElement {\n @property({ type: Boolean, reflect: true }) open = false;\n\n @state() private error = '';\n\n @query('.bookmark-panel__name') nameInput?: HTMLInputElement;\n\n public static get styles(): CSSResultArray {\n return [\n css`\n :host {\n font-family: var(\n --nile-font-family-sans-serif,\n var(--ng-font-family-body, system-ui, -apple-system, sans-serif)\n );\n position: absolute;\n z-index: 20;\n display: none;\n }\n\n :host([open]) {\n display: block;\n }\n\n .bookmark-panel {\n display: flex;\n flex-direction: column;\n gap: 8px;\n min-width: 280px;\n padding: 12px;\n background: var(--nile-wysiwyg-popover-bg, var(--nile-colors-white-base, var(--ng-colors-bg-primary)));\n border: 1px solid var(--nile-colors-neutral-400, var(--ng-colors-border-primary));\n border-radius: var(--nile-wysiwyg-radius, 8px);\n box-shadow: var(--nile-wysiwyg-popover-shadow, 0 4px 12px rgba(16, 24, 40, 0.12));\n font-size: 13px;\n }\n\n label {\n display: flex;\n flex-direction: column;\n gap: 4px;\n color: var(--nile-colors-neutral-700, var(--ng-colors-text-secondary-700));\n }\n\n input {\n font: inherit;\n padding: 6px 8px;\n border: 1px solid var(--nile-colors-neutral-400, var(--ng-colors-border-primary));\n border-radius: 6px;\n outline: none;\n }\n\n input:focus {\n border-color: var(--nile-colors-primary-600, var(--ng-componentcolors-utility-blue-600));\n }\n\n .hint {\n font-size: 12px;\n color: var(--nile-colors-neutral-500, var(--ng-colors-text-quaternary-500));\n }\n\n .error {\n font-size: 12px;\n color: var(--nile-colors-error-600, var(--ng-componentcolors-utility-error-600));\n }\n\n .actions {\n display: flex;\n gap: 8px;\n justify-content: flex-end;\n }\n\n button {\n font: inherit;\n padding: 6px 12px;\n border-radius: 6px;\n border: 1px solid transparent;\n cursor: pointer;\n background: transparent;\n color: var(--nile-colors-neutral-700, var(--ng-colors-text-secondary-700));\n }\n\n button.primary {\n background: var(--nile-colors-primary-600, var(--ng-componentcolors-utility-blue-600));\n color: var(--nile-colors-white-base, var(--ng-colors-text-white));\n }\n `,\n ];\n }\n\n public focusInput(): void {\n this.error = '';\n this.updateComplete.then(() => {\n if (this.nameInput) this.nameInput.value = '';\n this.nameInput?.focus();\n });\n }\n\n private handleSubmit(event: Event): void {\n event.preventDefault();\n // Anchor ids can't contain whitespace; collapse runs to a single dash.\n const id = (this.nameInput?.value ?? '').trim().replace(/\\s+/g, '-');\n if (!id) {\n this.error = 'Enter a bookmark name.';\n return;\n }\n this.error = '';\n this.emit('wysiwyg-bookmark-apply', { id });\n }\n\n public render(): TemplateResult {\n return html`\n <form\n class=\"bookmark-panel\"\n part=\"bookmark-panel\"\n @submit=${this.handleSubmit}\n @keydown=${(e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n e.stopPropagation();\n this.emit('wysiwyg-bookmark-cancel');\n }\n }}\n >\n <label>\n Bookmark name\n <input class=\"bookmark-panel__name\" type=\"text\" placeholder=\"section-intro\" />\n </label>\n ${this.error\n ? html`<div class=\"error\">${this.error}</div>`\n : html`<div class=\"hint\">An invisible anchor you can link to with #name</div>`}\n <div class=\"actions\">\n <button type=\"button\" @click=${() => this.emit('wysiwyg-bookmark-cancel')}>\n Cancel\n </button>\n <button type=\"submit\" class=\"primary\">Insert</button>\n </div>\n </form>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'nile-wysiwyg-bookmark-panel': NileWysiwygBookmarkPanel;\n }\n}\n"]}
@@ -109,7 +109,7 @@ let NileWysiwygBubbleMenu = class NileWysiwygBubbleMenu extends NileElement {
109
109
  display: flex;
110
110
  gap: 2px;
111
111
  padding: 4px;
112
- background: var(--nile-wysiwyg-popover-bg, var(--ng-colors-bg-primary));
112
+ background: var(--nile-wysiwyg-popover-bg, var(--nile-colors-white-base, var(--ng-colors-bg-primary)));
113
113
  border: 1px solid
114
114
  var(--nile-wysiwyg-border-color, var(--nile-colors-neutral-400, var(--ng-colors-border-primary)));
115
115
  border-radius: var(--nile-wysiwyg-radius, 8px);
@@ -1 +1 @@
1
- {"version":3,"file":"bubble-menu.js","sourceRoot":"","sources":["../../../../src/nile-wysiwyg-editor/ui/bubble-menu.ts"],"names":[],"mappings":"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","sourcesContent":["import { html, css, TemplateResult, CSSResultArray, nothing } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport NileElement from '../../internal/nile-element';\nimport { renderGlyph } from '../../internal/glyph';\nimport type { ToolbarState } from '../engine/selection-state';\nimport type { WysiwygCommandDetail } from '../types';\nimport type { AuthoredToolbarItem } from '../nile-wysiwyg-toolbar/nile-wysiwyg-toolbar';\nimport '../../nile-lite-tooltip/nile-lite-tooltip';\n\n/** A control the bubble menu knows how to render, keyed by its authored name. */\ninterface BubbleDef {\n /** The command dispatched on click. */\n command: WysiwygCommandDetail['name'];\n label: string;\n /** nile-glyph icon name (ng-* names are stroke-drawn). */\n icon: string;\n /** Static attrs sent with the command (e.g. alignment direction). */\n attrs?: WysiwygCommandDetail['attrs'];\n active?: (state: ToolbarState) => boolean;\n}\n\n/**\n * Registry of controls addressable by `<nile-wysiwyg-bubble-item name=\"…\">`.\n * Icons/labels mirror the main toolbar so both surfaces look identical.\n */\nconst BUBBLE_ITEMS: Record<string, BubbleDef> = {\n bold: { command: 'bold', label: 'Bold', icon: 'format_bold', active: s => s.bold },\n italic: { command: 'italic', label: 'Italic', icon: 'format_italic', active: s => s.italic },\n underline: {\n command: 'underline',\n label: 'Underline',\n icon: 'format_underline',\n active: s => s.underline,\n },\n strike: {\n command: 'strike',\n label: 'Strikethrough',\n icon: 'ng-strikethrough',\n active: s => s.strike,\n },\n code: { command: 'code', label: 'Inline code', icon: 'ng-code', active: s => s.code },\n subscript: {\n command: 'subscript',\n label: 'Subscript',\n icon: 'ng-subscript',\n active: s => s.subscript,\n },\n superscript: {\n command: 'superscript',\n label: 'Superscript',\n icon: 'ng-superscript',\n active: s => s.superscript,\n },\n link: { command: 'openLink', label: 'Link', icon: 'link_2', active: s => s.linkActive },\n bulletList: {\n command: 'bulletList',\n label: 'Bulleted list',\n icon: 'format_list_bulleted',\n active: s => s.inBulletList,\n },\n orderedList: {\n command: 'orderedList',\n label: 'Numbered list',\n icon: 'format_list_numbered',\n active: s => s.inOrderedList,\n },\n alignLeft: {\n command: 'align',\n label: 'Align left',\n icon: 'format_align_left',\n attrs: { align: 'left' },\n active: s => s.align === 'left',\n },\n alignCenter: {\n command: 'align',\n label: 'Align center',\n icon: 'format_align_middle',\n attrs: { align: 'center' },\n active: s => s.align === 'center',\n },\n alignRight: {\n command: 'align',\n label: 'Align right',\n icon: 'format_align_right',\n attrs: { align: 'right' },\n active: s => s.align === 'right',\n },\n clearFormatting: {\n command: 'clearFormatting',\n label: 'Clear formatting',\n icon: 'format_clear',\n },\n};\n\n/** Built-in default when no `<nile-wysiwyg-bubble-item>` children are authored. */\nconst DEFAULT_BUBBLE = ['bold', 'italic', 'underline', 'strike', 'link'];\n\n/**\n * Balloon toolbar shown over non-empty selections. The host owns positioning\n * (absolute left/top) and visibility; commands bubble up as\n * `wysiwyg-command` events, same contract as the main toolbar.\n */\n@customElement('nile-wysiwyg-bubble-menu')\nexport class NileWysiwygBubbleMenu extends NileElement {\n @property({ type: Boolean, reflect: true }) open = false;\n\n @property({ attribute: false }) toolbarState?: ToolbarState;\n\n /**\n * Structured item list authored in light DOM (from\n * `<nile-wysiwyg-bubble-item>` children). `'|'` is a separator. Falls back to\n * {@link DEFAULT_BUBBLE} when empty.\n */\n @property({ attribute: false }) items?: AuthoredToolbarItem[];\n\n public static get styles(): CSSResultArray {\n return [\n css`\n :host {\n font-family: var(\n --nile-font-family-sans-serif,\n var(--ng-font-family-body, system-ui, -apple-system, sans-serif)\n );\n position: absolute;\n z-index: 15;\n display: none;\n }\n\n :host([open]) {\n display: block;\n }\n\n .bubble {\n display: flex;\n gap: 2px;\n padding: 4px;\n background: var(--nile-wysiwyg-popover-bg, var(--ng-colors-bg-primary));\n border: 1px solid\n var(--nile-wysiwyg-border-color, var(--nile-colors-neutral-400, var(--ng-colors-border-primary)));\n border-radius: var(--nile-wysiwyg-radius, 8px);\n box-shadow: var(\n --nile-wysiwyg-popover-shadow,\n 0 4px 12px rgba(16, 24, 40, 0.12)\n );\n }\n\n button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 26px;\n height: 26px;\n border: none;\n border-radius: 5px;\n background: transparent;\n cursor: pointer;\n font-size: 13px;\n font-weight: 600;\n color: var(--nile-colors-neutral-700, var(--ng-colors-text-secondary-700));\n }\n\n button:hover {\n background: var(--nile-colors-neutral-100, var(--ng-colors-bg-secondary));\n }\n\n button[data-active] {\n background: var(--nile-colors-primary-50, var(--ng-componentcolors-utility-blue-50));\n color: var(--nile-colors-primary-700, var(--ng-componentcolors-utility-blue-700));\n }\n\n .divider {\n align-self: stretch;\n width: 1px;\n margin: 3px 2px;\n background: var(--nile-colors-neutral-300, var(--ng-colors-border-secondary));\n }\n `,\n ];\n }\n\n /**\n * True when this instance is an author's declarative `<nile-wysiwyg-bubble-menu>`\n * container in an editor's light DOM (holding `<nile-wysiwyg-bubble-item>`\n * children). It renders nothing — the editor reads the items and renders the\n * real bubble menu in its own shadow DOM. The editor's internal instance\n * lives in a shadow root, so `closest` never matches it.\n */\n private get isAuthoringContainer(): boolean {\n return !!this.closest('nile-wysiwyg-editor');\n }\n\n public render(): TemplateResult {\n if (this.isAuthoringContainer) return html``;\n\n const state = this.toolbarState;\n const entries: AuthoredToolbarItem[] =\n this.items && this.items.length\n ? this.items\n : DEFAULT_BUBBLE.map(name => ({ name }));\n return html`\n <div class=\"bubble\" part=\"bubble-menu\" @mousedown=${(e: Event) => e.preventDefault()}>\n ${entries.map(entry => this.renderEntry(entry, state))}\n </div>\n `;\n }\n\n private renderEntry(\n entry: AuthoredToolbarItem,\n state?: ToolbarState\n ): TemplateResult | typeof nothing {\n if (entry.name === '|') {\n return html`<span class=\"divider\" part=\"bubble-divider\"></span>`;\n }\n const base = BUBBLE_ITEMS[entry.name];\n const label = entry.label || base?.label || entry.name;\n const icon = entry.icon || base?.icon;\n // Unknown command with no icon to draw → nothing to render.\n if (!icon) return nothing;\n const command = base?.command ?? (entry.name as WysiwygCommandDetail['name']);\n const attrs = base?.attrs;\n const isActive = base?.active && state ? base.active(state) : false;\n return html`\n <nile-lite-tooltip content=${label} placement=\"top\">\n <button\n type=\"button\"\n aria-label=${label}\n ?data-active=${isActive}\n @click=${() =>\n this.emit('wysiwyg-command', attrs ? { name: command, attrs } : { name: command })}\n >\n ${renderGlyph(icon, 16)}\n </button>\n </nile-lite-tooltip>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'nile-wysiwyg-bubble-menu': NileWysiwygBubbleMenu;\n }\n}\n"]}
1
+ {"version":3,"file":"bubble-menu.js","sourceRoot":"","sources":["../../../../src/nile-wysiwyg-editor/ui/bubble-menu.ts"],"names":[],"mappings":"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","sourcesContent":["import { html, css, TemplateResult, CSSResultArray, nothing } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport NileElement from '../../internal/nile-element';\nimport { renderGlyph } from '../../internal/glyph';\nimport type { ToolbarState } from '../engine/selection-state';\nimport type { WysiwygCommandDetail } from '../types';\nimport type { AuthoredToolbarItem } from '../nile-wysiwyg-toolbar/nile-wysiwyg-toolbar';\nimport '../../nile-lite-tooltip/nile-lite-tooltip';\n\n/** A control the bubble menu knows how to render, keyed by its authored name. */\ninterface BubbleDef {\n /** The command dispatched on click. */\n command: WysiwygCommandDetail['name'];\n label: string;\n /** nile-glyph icon name (ng-* names are stroke-drawn). */\n icon: string;\n /** Static attrs sent with the command (e.g. alignment direction). */\n attrs?: WysiwygCommandDetail['attrs'];\n active?: (state: ToolbarState) => boolean;\n}\n\n/**\n * Registry of controls addressable by `<nile-wysiwyg-bubble-item name=\"…\">`.\n * Icons/labels mirror the main toolbar so both surfaces look identical.\n */\nconst BUBBLE_ITEMS: Record<string, BubbleDef> = {\n bold: { command: 'bold', label: 'Bold', icon: 'format_bold', active: s => s.bold },\n italic: { command: 'italic', label: 'Italic', icon: 'format_italic', active: s => s.italic },\n underline: {\n command: 'underline',\n label: 'Underline',\n icon: 'format_underline',\n active: s => s.underline,\n },\n strike: {\n command: 'strike',\n label: 'Strikethrough',\n icon: 'ng-strikethrough',\n active: s => s.strike,\n },\n code: { command: 'code', label: 'Inline code', icon: 'ng-code', active: s => s.code },\n subscript: {\n command: 'subscript',\n label: 'Subscript',\n icon: 'ng-subscript',\n active: s => s.subscript,\n },\n superscript: {\n command: 'superscript',\n label: 'Superscript',\n icon: 'ng-superscript',\n active: s => s.superscript,\n },\n link: { command: 'openLink', label: 'Link', icon: 'link_2', active: s => s.linkActive },\n bulletList: {\n command: 'bulletList',\n label: 'Bulleted list',\n icon: 'format_list_bulleted',\n active: s => s.inBulletList,\n },\n orderedList: {\n command: 'orderedList',\n label: 'Numbered list',\n icon: 'format_list_numbered',\n active: s => s.inOrderedList,\n },\n alignLeft: {\n command: 'align',\n label: 'Align left',\n icon: 'format_align_left',\n attrs: { align: 'left' },\n active: s => s.align === 'left',\n },\n alignCenter: {\n command: 'align',\n label: 'Align center',\n icon: 'format_align_middle',\n attrs: { align: 'center' },\n active: s => s.align === 'center',\n },\n alignRight: {\n command: 'align',\n label: 'Align right',\n icon: 'format_align_right',\n attrs: { align: 'right' },\n active: s => s.align === 'right',\n },\n clearFormatting: {\n command: 'clearFormatting',\n label: 'Clear formatting',\n icon: 'format_clear',\n },\n};\n\n/** Built-in default when no `<nile-wysiwyg-bubble-item>` children are authored. */\nconst DEFAULT_BUBBLE = ['bold', 'italic', 'underline', 'strike', 'link'];\n\n/**\n * Balloon toolbar shown over non-empty selections. The host owns positioning\n * (absolute left/top) and visibility; commands bubble up as\n * `wysiwyg-command` events, same contract as the main toolbar.\n */\n@customElement('nile-wysiwyg-bubble-menu')\nexport class NileWysiwygBubbleMenu extends NileElement {\n @property({ type: Boolean, reflect: true }) open = false;\n\n @property({ attribute: false }) toolbarState?: ToolbarState;\n\n /**\n * Structured item list authored in light DOM (from\n * `<nile-wysiwyg-bubble-item>` children). `'|'` is a separator. Falls back to\n * {@link DEFAULT_BUBBLE} when empty.\n */\n @property({ attribute: false }) items?: AuthoredToolbarItem[];\n\n public static get styles(): CSSResultArray {\n return [\n css`\n :host {\n font-family: var(\n --nile-font-family-sans-serif,\n var(--ng-font-family-body, system-ui, -apple-system, sans-serif)\n );\n position: absolute;\n z-index: 15;\n display: none;\n }\n\n :host([open]) {\n display: block;\n }\n\n .bubble {\n display: flex;\n gap: 2px;\n padding: 4px;\n background: var(--nile-wysiwyg-popover-bg, var(--nile-colors-white-base, var(--ng-colors-bg-primary)));\n border: 1px solid\n var(--nile-wysiwyg-border-color, var(--nile-colors-neutral-400, var(--ng-colors-border-primary)));\n border-radius: var(--nile-wysiwyg-radius, 8px);\n box-shadow: var(\n --nile-wysiwyg-popover-shadow,\n 0 4px 12px rgba(16, 24, 40, 0.12)\n );\n }\n\n button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 26px;\n height: 26px;\n border: none;\n border-radius: 5px;\n background: transparent;\n cursor: pointer;\n font-size: 13px;\n font-weight: 600;\n color: var(--nile-colors-neutral-700, var(--ng-colors-text-secondary-700));\n }\n\n button:hover {\n background: var(--nile-colors-neutral-100, var(--ng-colors-bg-secondary));\n }\n\n button[data-active] {\n background: var(--nile-colors-primary-50, var(--ng-componentcolors-utility-blue-50));\n color: var(--nile-colors-primary-700, var(--ng-componentcolors-utility-blue-700));\n }\n\n .divider {\n align-self: stretch;\n width: 1px;\n margin: 3px 2px;\n background: var(--nile-colors-neutral-300, var(--ng-colors-border-secondary));\n }\n `,\n ];\n }\n\n /**\n * True when this instance is an author's declarative `<nile-wysiwyg-bubble-menu>`\n * container in an editor's light DOM (holding `<nile-wysiwyg-bubble-item>`\n * children). It renders nothing — the editor reads the items and renders the\n * real bubble menu in its own shadow DOM. The editor's internal instance\n * lives in a shadow root, so `closest` never matches it.\n */\n private get isAuthoringContainer(): boolean {\n return !!this.closest('nile-wysiwyg-editor');\n }\n\n public render(): TemplateResult {\n if (this.isAuthoringContainer) return html``;\n\n const state = this.toolbarState;\n const entries: AuthoredToolbarItem[] =\n this.items && this.items.length\n ? this.items\n : DEFAULT_BUBBLE.map(name => ({ name }));\n return html`\n <div class=\"bubble\" part=\"bubble-menu\" @mousedown=${(e: Event) => e.preventDefault()}>\n ${entries.map(entry => this.renderEntry(entry, state))}\n </div>\n `;\n }\n\n private renderEntry(\n entry: AuthoredToolbarItem,\n state?: ToolbarState\n ): TemplateResult | typeof nothing {\n if (entry.name === '|') {\n return html`<span class=\"divider\" part=\"bubble-divider\"></span>`;\n }\n const base = BUBBLE_ITEMS[entry.name];\n const label = entry.label || base?.label || entry.name;\n const icon = entry.icon || base?.icon;\n // Unknown command with no icon to draw → nothing to render.\n if (!icon) return nothing;\n const command = base?.command ?? (entry.name as WysiwygCommandDetail['name']);\n const attrs = base?.attrs;\n const isActive = base?.active && state ? base.active(state) : false;\n return html`\n <nile-lite-tooltip content=${label} placement=\"top\">\n <button\n type=\"button\"\n aria-label=${label}\n ?data-active=${isActive}\n @click=${() =>\n this.emit('wysiwyg-command', attrs ? { name: command, attrs } : { name: command })}\n >\n ${renderGlyph(icon, 16)}\n </button>\n </nile-lite-tooltip>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'nile-wysiwyg-bubble-menu': NileWysiwygBubbleMenu;\n }\n}\n"]}
@@ -58,7 +58,7 @@ let NileWysiwygEmbedMenu = class NileWysiwygEmbedMenu extends NileElement {
58
58
  display: flex;
59
59
  gap: 2px;
60
60
  padding: 4px;
61
- background: var(--nile-wysiwyg-popover-bg, var(--ng-colors-bg-primary));
61
+ background: var(--nile-wysiwyg-popover-bg, var(--nile-colors-white-base, var(--ng-colors-bg-primary)));
62
62
  border: 1px solid var(--nile-colors-neutral-400, var(--ng-colors-border-primary));
63
63
  border-radius: 8px;
64
64
  box-shadow: var(--nile-wysiwyg-popover-shadow, 0 4px 12px rgba(16, 24, 40, 0.12));
@@ -1 +1 @@
1
- {"version":3,"file":"embed-menu.js","sourceRoot":"","sources":["../../../../src/nile-wysiwyg-editor/ui/embed-menu.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAE,GAAG,EAAkC,MAAM,KAAK,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,WAAW,MAAM,6BAA6B,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAYnD,MAAM,GAAG,GAAc;IACrB;QACE,KAAK,EAAE,YAAY;QACnB,IAAI,EAAE,mBAAmB;QACzB,OAAO,EAAE,eAAe;QACxB,KAAK,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE;QACxB,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,MAAM,IAAI,CAAC,CAAC,UAAU,KAAK,IAAI;KAC9D;IACD;QACE,KAAK,EAAE,cAAc;QACrB,IAAI,EAAE,qBAAqB;QAC3B,OAAO,EAAE,eAAe;QACxB,KAAK,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE;QAC1B,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,QAAQ;KACvC;IACD;QACE,KAAK,EAAE,aAAa;QACpB,IAAI,EAAE,oBAAoB;QAC1B,OAAO,EAAE,eAAe;QACxB,KAAK,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE;QACzB,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,OAAO;KACtC;IACD,EAAE,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,aAAa,EAAE;CACvE,CAAC;AAEF;;;;GAIG;AAEI,IAAM,oBAAoB,GAA1B,MAAM,oBAAqB,SAAQ,WAAW;IAA9C;;QACuC,SAAI,GAAG,KAAK,CAAC;IA+E3D,CAAC;IA3EQ,MAAM,KAAK,MAAM;QACtB,OAAO;YACL,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAiDF;SACF,CAAC;IACJ,CAAC;IAEM,MAAM;QACX,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC;QAChC,OAAO,IAAI,CAAA;uDACwC,CAAC,CAAQ,EAAE,EAAE,CAAC,CAAC,CAAC,cAAc,EAAE;UAC7E,GAAG,CAAC,GAAG,CACP,EAAE,CAAC,EAAE,CAAC,IAAI,CAAA;;;sBAGE,EAAE,CAAC,KAAK;2BACH,EAAE,CAAC,KAAK;6BACN,KAAK,IAAI,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK;uBACnD,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,EAAE,IAAI,EAAE,EAAE,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC;;gBAEhF,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI;;WAEjD,CACF;;KAEJ,CAAC;IACJ,CAAC;CACF,CAAA;AA/E6C;IAA3C,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;kDAAc;AAEzB;IAA/B,QAAQ,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;0DAA6B;AAHjD,oBAAoB;IADhC,aAAa,CAAC,yBAAyB,CAAC;GAC5B,oBAAoB,CAgFhC","sourcesContent":["import { html, css, TemplateResult, CSSResultArray } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport NileElement from '../../internal/nile-element';\nimport { renderGlyph } from '../../internal/glyph';\nimport type { ToolbarState } from '../engine/selection-state';\n\ninterface EmbedOp {\n label: string;\n icon?: string;\n text?: string;\n command: string;\n attrs?: Record<string, unknown>;\n active?: (s: ToolbarState) => boolean;\n}\n\nconst OPS: EmbedOp[] = [\n {\n label: 'Align left',\n icon: 'format_align_left',\n command: 'setEmbedAlign',\n attrs: { align: 'left' },\n active: s => s.embedAlign === 'left' || s.embedAlign === null,\n },\n {\n label: 'Align center',\n icon: 'format_align_middle',\n command: 'setEmbedAlign',\n attrs: { align: 'center' },\n active: s => s.embedAlign === 'center',\n },\n {\n label: 'Align right',\n icon: 'format_align_right',\n command: 'setEmbedAlign',\n attrs: { align: 'right' },\n active: s => s.embedAlign === 'right',\n },\n { label: 'Delete video', icon: 'ng-trash-01', command: 'deleteEmbed' },\n];\n\n/**\n * Compact floating bar shown while a video embed is selected — mirrors the\n * image menu (align left/center/right, delete). The host positions it;\n * operations bubble up as `wysiwyg-command` events.\n */\n@customElement('nile-wysiwyg-embed-menu')\nexport class NileWysiwygEmbedMenu extends NileElement {\n @property({ type: Boolean, reflect: true }) open = false;\n\n @property({ attribute: false }) toolbarState?: ToolbarState;\n\n public static get styles(): CSSResultArray {\n return [\n css`\n :host {\n font-family: var(\n --nile-font-family-sans-serif,\n var(--ng-font-family-body, system-ui, -apple-system, sans-serif)\n );\n position: absolute;\n z-index: 15;\n display: none;\n }\n\n :host([open]) {\n display: block;\n }\n\n .menu {\n display: flex;\n gap: 2px;\n padding: 4px;\n background: var(--nile-wysiwyg-popover-bg, var(--ng-colors-bg-primary));\n border: 1px solid var(--nile-colors-neutral-400, var(--ng-colors-border-primary));\n border-radius: 8px;\n box-shadow: var(--nile-wysiwyg-popover-shadow, 0 4px 12px rgba(16, 24, 40, 0.12));\n }\n\n button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 26px;\n height: 26px;\n padding: 0 4px;\n border: none;\n border-radius: 5px;\n background: transparent;\n cursor: pointer;\n font-size: 12px;\n font-weight: 600;\n color: var(--nile-colors-neutral-700, var(--ng-colors-text-secondary-700));\n }\n\n button:hover {\n background: var(--nile-colors-neutral-100, var(--ng-colors-bg-secondary));\n }\n\n button[data-active] {\n background: var(--nile-colors-primary-50, var(--ng-componentcolors-utility-blue-50));\n color: var(--nile-colors-primary-700, var(--ng-componentcolors-utility-blue-700));\n }\n `,\n ];\n }\n\n public render(): TemplateResult {\n const state = this.toolbarState;\n return html`\n <div class=\"menu\" part=\"embed-menu\" @mousedown=${(e: Event) => e.preventDefault()}>\n ${OPS.map(\n op => html`\n <button\n type=\"button\"\n title=${op.label}\n aria-label=${op.label}\n ?data-active=${state && op.active ? op.active(state) : false}\n @click=${() => this.emit('wysiwyg-command', { name: op.command, attrs: op.attrs })}\n >\n ${op.icon ? renderGlyph(op.icon, 16) : op.text}\n </button>\n `\n )}\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'nile-wysiwyg-embed-menu': NileWysiwygEmbedMenu;\n }\n}\n"]}
1
+ {"version":3,"file":"embed-menu.js","sourceRoot":"","sources":["../../../../src/nile-wysiwyg-editor/ui/embed-menu.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAE,GAAG,EAAkC,MAAM,KAAK,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,WAAW,MAAM,6BAA6B,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAYnD,MAAM,GAAG,GAAc;IACrB;QACE,KAAK,EAAE,YAAY;QACnB,IAAI,EAAE,mBAAmB;QACzB,OAAO,EAAE,eAAe;QACxB,KAAK,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE;QACxB,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,MAAM,IAAI,CAAC,CAAC,UAAU,KAAK,IAAI;KAC9D;IACD;QACE,KAAK,EAAE,cAAc;QACrB,IAAI,EAAE,qBAAqB;QAC3B,OAAO,EAAE,eAAe;QACxB,KAAK,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE;QAC1B,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,QAAQ;KACvC;IACD;QACE,KAAK,EAAE,aAAa;QACpB,IAAI,EAAE,oBAAoB;QAC1B,OAAO,EAAE,eAAe;QACxB,KAAK,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE;QACzB,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,OAAO;KACtC;IACD,EAAE,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,aAAa,EAAE;CACvE,CAAC;AAEF;;;;GAIG;AAEI,IAAM,oBAAoB,GAA1B,MAAM,oBAAqB,SAAQ,WAAW;IAA9C;;QACuC,SAAI,GAAG,KAAK,CAAC;IA+E3D,CAAC;IA3EQ,MAAM,KAAK,MAAM;QACtB,OAAO;YACL,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAiDF;SACF,CAAC;IACJ,CAAC;IAEM,MAAM;QACX,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC;QAChC,OAAO,IAAI,CAAA;uDACwC,CAAC,CAAQ,EAAE,EAAE,CAAC,CAAC,CAAC,cAAc,EAAE;UAC7E,GAAG,CAAC,GAAG,CACP,EAAE,CAAC,EAAE,CAAC,IAAI,CAAA;;;sBAGE,EAAE,CAAC,KAAK;2BACH,EAAE,CAAC,KAAK;6BACN,KAAK,IAAI,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK;uBACnD,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,EAAE,IAAI,EAAE,EAAE,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC;;gBAEhF,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI;;WAEjD,CACF;;KAEJ,CAAC;IACJ,CAAC;CACF,CAAA;AA/E6C;IAA3C,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;kDAAc;AAEzB;IAA/B,QAAQ,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;0DAA6B;AAHjD,oBAAoB;IADhC,aAAa,CAAC,yBAAyB,CAAC;GAC5B,oBAAoB,CAgFhC","sourcesContent":["import { html, css, TemplateResult, CSSResultArray } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport NileElement from '../../internal/nile-element';\nimport { renderGlyph } from '../../internal/glyph';\nimport type { ToolbarState } from '../engine/selection-state';\n\ninterface EmbedOp {\n label: string;\n icon?: string;\n text?: string;\n command: string;\n attrs?: Record<string, unknown>;\n active?: (s: ToolbarState) => boolean;\n}\n\nconst OPS: EmbedOp[] = [\n {\n label: 'Align left',\n icon: 'format_align_left',\n command: 'setEmbedAlign',\n attrs: { align: 'left' },\n active: s => s.embedAlign === 'left' || s.embedAlign === null,\n },\n {\n label: 'Align center',\n icon: 'format_align_middle',\n command: 'setEmbedAlign',\n attrs: { align: 'center' },\n active: s => s.embedAlign === 'center',\n },\n {\n label: 'Align right',\n icon: 'format_align_right',\n command: 'setEmbedAlign',\n attrs: { align: 'right' },\n active: s => s.embedAlign === 'right',\n },\n { label: 'Delete video', icon: 'ng-trash-01', command: 'deleteEmbed' },\n];\n\n/**\n * Compact floating bar shown while a video embed is selected — mirrors the\n * image menu (align left/center/right, delete). The host positions it;\n * operations bubble up as `wysiwyg-command` events.\n */\n@customElement('nile-wysiwyg-embed-menu')\nexport class NileWysiwygEmbedMenu extends NileElement {\n @property({ type: Boolean, reflect: true }) open = false;\n\n @property({ attribute: false }) toolbarState?: ToolbarState;\n\n public static get styles(): CSSResultArray {\n return [\n css`\n :host {\n font-family: var(\n --nile-font-family-sans-serif,\n var(--ng-font-family-body, system-ui, -apple-system, sans-serif)\n );\n position: absolute;\n z-index: 15;\n display: none;\n }\n\n :host([open]) {\n display: block;\n }\n\n .menu {\n display: flex;\n gap: 2px;\n padding: 4px;\n background: var(--nile-wysiwyg-popover-bg, var(--nile-colors-white-base, var(--ng-colors-bg-primary)));\n border: 1px solid var(--nile-colors-neutral-400, var(--ng-colors-border-primary));\n border-radius: 8px;\n box-shadow: var(--nile-wysiwyg-popover-shadow, 0 4px 12px rgba(16, 24, 40, 0.12));\n }\n\n button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 26px;\n height: 26px;\n padding: 0 4px;\n border: none;\n border-radius: 5px;\n background: transparent;\n cursor: pointer;\n font-size: 12px;\n font-weight: 600;\n color: var(--nile-colors-neutral-700, var(--ng-colors-text-secondary-700));\n }\n\n button:hover {\n background: var(--nile-colors-neutral-100, var(--ng-colors-bg-secondary));\n }\n\n button[data-active] {\n background: var(--nile-colors-primary-50, var(--ng-componentcolors-utility-blue-50));\n color: var(--nile-colors-primary-700, var(--ng-componentcolors-utility-blue-700));\n }\n `,\n ];\n }\n\n public render(): TemplateResult {\n const state = this.toolbarState;\n return html`\n <div class=\"menu\" part=\"embed-menu\" @mousedown=${(e: Event) => e.preventDefault()}>\n ${OPS.map(\n op => html`\n <button\n type=\"button\"\n title=${op.label}\n aria-label=${op.label}\n ?data-active=${state && op.active ? op.active(state) : false}\n @click=${() => this.emit('wysiwyg-command', { name: op.command, attrs: op.attrs })}\n >\n ${op.icon ? renderGlyph(op.icon, 16) : op.text}\n </button>\n `\n )}\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'nile-wysiwyg-embed-menu': NileWysiwygEmbedMenu;\n }\n}\n"]}
@@ -42,7 +42,7 @@ let NileWysiwygEmbedPanel = class NileWysiwygEmbedPanel extends NileElement {
42
42
  min-width: 340px;
43
43
  max-width: 420px;
44
44
  padding: 12px;
45
- background: var(--nile-wysiwyg-popover-bg, var(--ng-colors-bg-primary));
45
+ background: var(--nile-wysiwyg-popover-bg, var(--nile-colors-white-base, var(--ng-colors-bg-primary)));
46
46
  border: 1px solid var(--nile-colors-neutral-400, var(--ng-colors-border-primary));
47
47
  border-radius: 8px;
48
48
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
@@ -1 +1 @@
1
- {"version":3,"file":"embed-panel.js","sourceRoot":"","sources":["../../../../src/nile-wysiwyg-editor/ui/embed-panel.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAE,GAAG,EAAkC,MAAM,KAAK,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AACnE,OAAO,WAAW,MAAM,6BAA6B,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,wBAAwB,CAAC;AAChC,OAAO,yBAAyB,CAAC;AAEjC;;;;;GAKG;AAEI,IAAM,qBAAqB,GAA3B,MAAM,qBAAsB,SAAQ,WAAW;IAA/C;;QACuC,SAAI,GAAG,KAAK,CAAC;QAExC,aAAQ,GAAG,EAAE,CAAC;QACd,UAAK,GAAG,EAAE,CAAC;IAuH9B,CAAC;IArHQ,MAAM,KAAK,MAAM;QACtB,OAAO;YACL,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAkDF;SACF,CAAC;IACJ,CAAC;IAEM,UAAU;QACf,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,EAAE;YAC5B,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,YAAY,CAAuB,CAAC;YACjF,KAAK,EAAE,KAAK,EAAE,CAAC;QACjB,CAAC,CAAC,CAAC;IACL,CAAC;IAED,wBAAwB;IACjB,KAAK;QACV,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAC;QACnB,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;IAClB,CAAC;IAEO,KAAK,CAAC,KAAkB;QAC9B,IAAI,CAAC,QAAQ,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,IAAI,EAAE,CAAW,CAAC;QACtD,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;IAClB,CAAC;IAEO,YAAY;QAClB,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;QAChD,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,IAAI,CAAC,KAAK,GAAG,6BAA6B,CAAC;YAC3C,OAAO;QACT,CAAC;QACD,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;QAChB,IAAI,CAAC,IAAI,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;IAC3C,CAAC;IAEO,aAAa,CAAC,KAAoB;QACxC,IAAI,KAAK,CAAC,GAAG,KAAK,QAAQ,EAAE,CAAC;YAC3B,KAAK,CAAC,eAAe,EAAE,CAAC;YACxB,IAAI,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;QACpC,CAAC;aAAM,IAAI,KAAK,CAAC,GAAG,KAAK,OAAO,EAAE,CAAC;YACjC,KAAK,CAAC,cAAc,EAAE,CAAC;YACvB,KAAK,CAAC,eAAe,EAAE,CAAC;YACxB,IAAI,CAAC,YAAY,EAAE,CAAC;QACtB,CAAC;IACH,CAAC;IAEM,MAAM;QACX,OAAO,IAAI,CAAA;6DAC8C,IAAI,CAAC,aAAa;;;;mBAI5D,IAAI,CAAC,QAAQ;wBACR,IAAI,CAAC,KAAK;;;UAGxB,IAAI,CAAC,KAAK;YACV,CAAC,CAAC,IAAI,CAAA,oCAAoC,IAAI,CAAC,KAAK,SAAS;YAC7D,CAAC,CAAC,IAAI,CAAA,8CAA8C;;;kDAGZ,GAAG,EAAE,CAAC,IAAI,CAAC,YAAY,EAAE;;;;;KAKtE,CAAC;IACJ,CAAC;CACF,CAAA;AA1H6C;IAA3C,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;mDAAc;AAExC;IAAhB,KAAK,EAAE;uDAAuB;AACd;IAAhB,KAAK,EAAE;oDAAoB;AAJjB,qBAAqB;IADjC,aAAa,CAAC,0BAA0B,CAAC;GAC7B,qBAAqB,CA2HjC","sourcesContent":["import { html, css, TemplateResult, CSSResultArray } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport NileElement from '../../internal/nile-element';\nimport { toEmbedUrl } from '../engine/plugins/embeds';\nimport '../../nile-input/index';\nimport '../../nile-button/index';\n\n/**\n * Floating embed-insert panel: paste any https:// link (YouTube/Vimeo/Loom\n * are auto-formatted; anything else embeds as a sandboxed iframe). Styled to\n * match the image panel (nile-input + nile-button). Emits\n * `wysiwyg-embed-apply` detail: { src, provider } and `wysiwyg-embed-cancel`.\n */\n@customElement('nile-wysiwyg-embed-panel')\nexport class NileWysiwygEmbedPanel extends NileElement {\n @property({ type: Boolean, reflect: true }) open = false;\n\n @state() private urlValue = '';\n @state() private error = '';\n\n public static get styles(): CSSResultArray {\n return [\n css`\n :host {\n font-family: var(\n --nile-font-family-sans-serif,\n var(--ng-font-family-body, system-ui, -apple-system, sans-serif)\n );\n position: absolute;\n z-index: 20;\n display: none;\n }\n\n :host([open]) {\n display: block;\n }\n\n .embed-panel {\n display: flex;\n flex-direction: column;\n gap: 12px;\n min-width: 340px;\n max-width: 420px;\n padding: 12px;\n background: var(--nile-wysiwyg-popover-bg, var(--ng-colors-bg-primary));\n border: 1px solid var(--nile-colors-neutral-400, var(--ng-colors-border-primary));\n border-radius: 8px;\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);\n font-size: 13px;\n }\n\n nile-input {\n width: 100%;\n }\n\n .hint {\n font-size: 12px;\n color: var(--nile-colors-neutral-500, var(--ng-colors-text-quaternary-500));\n }\n\n .error {\n font-size: 12px;\n color: var(--nile-colors-danger-600, var(--ng-componentcolors-utility-error-600));\n }\n\n .actions {\n display: flex;\n justify-content: flex-end;\n align-items: center;\n gap: 8px;\n width: 100%;\n }\n `,\n ];\n }\n\n public focusInput(): void {\n this.updateComplete.then(() => {\n const input = this.shadowRoot?.querySelector('nile-input') as HTMLElement | null;\n input?.focus();\n });\n }\n\n /** Clears the field. */\n public reset(): void {\n this.urlValue = '';\n this.error = '';\n }\n\n private onUrl(event: CustomEvent): void {\n this.urlValue = (event.detail?.value ?? '') as string;\n this.error = '';\n }\n\n private handleSubmit(): void {\n const target = toEmbedUrl(this.urlValue.trim());\n if (!target) {\n this.error = 'Enter a valid https:// URL.';\n return;\n }\n this.error = '';\n this.emit('wysiwyg-embed-apply', target);\n }\n\n private handleKeydown(event: KeyboardEvent): void {\n if (event.key === 'Escape') {\n event.stopPropagation();\n this.emit('wysiwyg-embed-cancel');\n } else if (event.key === 'Enter') {\n event.preventDefault();\n event.stopPropagation();\n this.handleSubmit();\n }\n }\n\n public render(): TemplateResult {\n return html`\n <div class=\"embed-panel\" part=\"embed-panel\" @keydown=${this.handleKeydown}>\n <nile-input\n label=\"Video URL\"\n placeholder=\"https://www.youtube.com/watch?v=…\"\n .value=${this.urlValue}\n @nile-input=${this.onUrl}\n ></nile-input>\n\n ${this.error\n ? html`<span class=\"error\" part=\"error\">${this.error}</span>`\n : html`<span class=\"hint\">Add any link to it</span>`}\n\n <div class=\"actions\">\n <nile-button variant=\"primary\" @click=${() => this.handleSubmit()}\n >Embed</nile-button\n >\n </div>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'nile-wysiwyg-embed-panel': NileWysiwygEmbedPanel;\n }\n}\n"]}
1
+ {"version":3,"file":"embed-panel.js","sourceRoot":"","sources":["../../../../src/nile-wysiwyg-editor/ui/embed-panel.ts"],"names":[],"mappings":"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","sourcesContent":["import { html, css, TemplateResult, CSSResultArray } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport NileElement from '../../internal/nile-element';\nimport { toEmbedUrl } from '../engine/plugins/embeds';\nimport '../../nile-input/index';\nimport '../../nile-button/index';\n\n/**\n * Floating embed-insert panel: paste any https:// link (YouTube/Vimeo/Loom\n * are auto-formatted; anything else embeds as a sandboxed iframe). Styled to\n * match the image panel (nile-input + nile-button). Emits\n * `wysiwyg-embed-apply` detail: { src, provider } and `wysiwyg-embed-cancel`.\n */\n@customElement('nile-wysiwyg-embed-panel')\nexport class NileWysiwygEmbedPanel extends NileElement {\n @property({ type: Boolean, reflect: true }) open = false;\n\n @state() private urlValue = '';\n @state() private error = '';\n\n public static get styles(): CSSResultArray {\n return [\n css`\n :host {\n font-family: var(\n --nile-font-family-sans-serif,\n var(--ng-font-family-body, system-ui, -apple-system, sans-serif)\n );\n position: absolute;\n z-index: 20;\n display: none;\n }\n\n :host([open]) {\n display: block;\n }\n\n .embed-panel {\n display: flex;\n flex-direction: column;\n gap: 12px;\n min-width: 340px;\n max-width: 420px;\n padding: 12px;\n background: var(--nile-wysiwyg-popover-bg, var(--nile-colors-white-base, var(--ng-colors-bg-primary)));\n border: 1px solid var(--nile-colors-neutral-400, var(--ng-colors-border-primary));\n border-radius: 8px;\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);\n font-size: 13px;\n }\n\n nile-input {\n width: 100%;\n }\n\n .hint {\n font-size: 12px;\n color: var(--nile-colors-neutral-500, var(--ng-colors-text-quaternary-500));\n }\n\n .error {\n font-size: 12px;\n color: var(--nile-colors-danger-600, var(--ng-componentcolors-utility-error-600));\n }\n\n .actions {\n display: flex;\n justify-content: flex-end;\n align-items: center;\n gap: 8px;\n width: 100%;\n }\n `,\n ];\n }\n\n public focusInput(): void {\n this.updateComplete.then(() => {\n const input = this.shadowRoot?.querySelector('nile-input') as HTMLElement | null;\n input?.focus();\n });\n }\n\n /** Clears the field. */\n public reset(): void {\n this.urlValue = '';\n this.error = '';\n }\n\n private onUrl(event: CustomEvent): void {\n this.urlValue = (event.detail?.value ?? '') as string;\n this.error = '';\n }\n\n private handleSubmit(): void {\n const target = toEmbedUrl(this.urlValue.trim());\n if (!target) {\n this.error = 'Enter a valid https:// URL.';\n return;\n }\n this.error = '';\n this.emit('wysiwyg-embed-apply', target);\n }\n\n private handleKeydown(event: KeyboardEvent): void {\n if (event.key === 'Escape') {\n event.stopPropagation();\n this.emit('wysiwyg-embed-cancel');\n } else if (event.key === 'Enter') {\n event.preventDefault();\n event.stopPropagation();\n this.handleSubmit();\n }\n }\n\n public render(): TemplateResult {\n return html`\n <div class=\"embed-panel\" part=\"embed-panel\" @keydown=${this.handleKeydown}>\n <nile-input\n label=\"Video URL\"\n placeholder=\"https://www.youtube.com/watch?v=…\"\n .value=${this.urlValue}\n @nile-input=${this.onUrl}\n ></nile-input>\n\n ${this.error\n ? html`<span class=\"error\" part=\"error\">${this.error}</span>`\n : html`<span class=\"hint\">Add any link to it</span>`}\n\n <div class=\"actions\">\n <nile-button variant=\"primary\" @click=${() => this.handleSubmit()}\n >Embed</nile-button\n >\n </div>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'nile-wysiwyg-embed-panel': NileWysiwygEmbedPanel;\n }\n}\n"]}
@@ -34,7 +34,7 @@ let NileWysiwygEmojiPicker = class NileWysiwygEmojiPicker extends NileElement {
34
34
  .panel {
35
35
  width: 316px;
36
36
  padding: 8px;
37
- background: var(--nile-wysiwyg-popover-bg, var(--ng-colors-bg-primary));
37
+ background: var(--nile-wysiwyg-popover-bg, var(--nile-colors-white-base, var(--ng-colors-bg-primary)));
38
38
  border: 1px solid var(--nile-colors-neutral-400, var(--ng-colors-border-primary));
39
39
  border-radius: 8px;
40
40
  box-shadow: var(--nile-wysiwyg-popover-shadow, 0 4px 12px rgba(16, 24, 40, 0.12));
@@ -1 +1 @@
1
- {"version":3,"file":"emoji-picker.js","sourceRoot":"","sources":["../../../../src/nile-wysiwyg-editor/ui/emoji-picker.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAE,GAAG,EAAkC,MAAM,KAAK,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC1E,OAAO,WAAW,MAAM,6BAA6B,CAAC;AACtD,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAEjC;;;;GAIG;AAEI,IAAM,sBAAsB,GAA5B,MAAM,sBAAuB,SAAQ,WAAW;IAAhD;;QACuC,SAAI,GAAG,KAAK,CAAC;QAExC,WAAM,GAAG,EAAE,CAAC;IAmI/B,CAAC;IA/HQ,MAAM,KAAK,MAAM;QACtB,OAAO;YACL,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAuEF;SACF,CAAC;IACJ,CAAC;IAEM,UAAU;QACf,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC;QACjB,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,EAAE;YAC5B,IAAI,IAAI,CAAC,WAAW;gBAAE,IAAI,CAAC,WAAW,CAAC,KAAK,GAAG,EAAE,CAAC;YAClD,IAAI,CAAC,WAAW,EAAE,KAAK,EAAE,CAAC;QAC5B,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,aAAa,CAAC,KAAoB;QACxC,IAAI,KAAK,CAAC,GAAG,KAAK,QAAQ,EAAE,CAAC;YAC3B,KAAK,CAAC,eAAe,EAAE,CAAC;YACxB,IAAI,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;QACpC,CAAC;IACH,CAAC;IAEM,MAAM;QACX,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAC/C,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;QACxE,OAAO,IAAI,CAAA;wDACyC,IAAI,CAAC,aAAa;;;;;;mBAMvD,CAAC,CAAQ,EAAE,EAAE;YACpB,IAAI,CAAC,MAAM,GAAI,CAAC,CAAC,MAA2B,CAAC,KAAK,CAAC;QACrD,CAAC;;;YAGC,KAAK,CAAC,GAAG,CACT,CAAC,CAAC,EAAE,CAAC,IAAI,CAAA;;;;wBAIG,CAAC,CAAC,IAAI;6BACD,CAAC,EAAS,EAAE,EAAE,CAAC,EAAE,CAAC,cAAc,EAAE;yBACtC,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,sBAAsB,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;;kBAEhE,CAAC,CAAC,IAAI;;aAEX,CACF;YACC,KAAK,CAAC,MAAM,KAAK,CAAC;YAClB,CAAC,CAAC,IAAI,CAAA,qEAAqE;YAC3E,CAAC,CAAC,EAAE;;;KAGX,CAAC;IACJ,CAAC;CACF,CAAA;AArI6C;IAA3C,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;oDAAc;AAExC;IAAhB,KAAK,EAAE;sDAAqB;AAEG;IAA/B,KAAK,CAAC,uBAAuB,CAAC;2DAAgC;AALpD,sBAAsB;IADlC,aAAa,CAAC,2BAA2B,CAAC;GAC9B,sBAAsB,CAsIlC","sourcesContent":["import { html, css, TemplateResult, CSSResultArray } from 'lit';\nimport { customElement, property, query, state } from 'lit/decorators.js';\nimport NileElement from '../../internal/nile-element';\nimport { EMOJI } from '../emoji';\n\n/**\n * Emoji picker panel (the 😊 toolbar item). Shares the emoji set with the\n * \":\" autocomplete; the search box filters by name. Emits\n * `wysiwyg-emoji-select` detail: { char } and `wysiwyg-emoji-cancel`.\n */\n@customElement('nile-wysiwyg-emoji-picker')\nexport class NileWysiwygEmojiPicker extends NileElement {\n @property({ type: Boolean, reflect: true }) open = false;\n\n @state() private filter = '';\n\n @query('.emoji-picker__search') searchInput?: HTMLInputElement;\n\n public static get styles(): CSSResultArray {\n return [\n css`\n :host {\n font-family: var(\n --nile-font-family-sans-serif,\n var(--ng-font-family-body, system-ui, -apple-system, sans-serif)\n );\n position: absolute;\n z-index: 20;\n display: none;\n }\n\n :host([open]) {\n display: block;\n }\n\n .panel {\n width: 316px;\n padding: 8px;\n background: var(--nile-wysiwyg-popover-bg, var(--ng-colors-bg-primary));\n border: 1px solid var(--nile-colors-neutral-400, var(--ng-colors-border-primary));\n border-radius: 8px;\n box-shadow: var(--nile-wysiwyg-popover-shadow, 0 4px 12px rgba(16, 24, 40, 0.12));\n }\n\n input {\n font: inherit;\n font-size: 13px;\n width: 100%;\n box-sizing: border-box;\n margin-bottom: 6px;\n padding: 5px 8px;\n border: 1px solid var(--nile-colors-neutral-400, var(--ng-colors-border-primary));\n border-radius: 6px;\n outline: none;\n }\n\n input:focus {\n border-color: var(--nile-colors-primary-600, var(--ng-componentcolors-utility-blue-600));\n }\n\n .grid {\n display: grid;\n grid-template-columns: repeat(9, 1fr);\n gap: 2px;\n max-height: 200px;\n overflow-y: auto;\n overscroll-behavior: contain;\n }\n\n .emoji {\n font: inherit;\n font-size: 18px;\n height: 30px;\n padding: 0;\n border: none;\n border-radius: 5px;\n background: transparent;\n cursor: pointer;\n line-height: 1;\n }\n\n .emoji:hover {\n background: var(--nile-colors-neutral-100, var(--ng-colors-bg-secondary));\n }\n\n .empty {\n padding: 12px 4px;\n font-size: 12px;\n color: var(--nile-colors-neutral-500, var(--ng-colors-text-quaternary-500));\n text-align: center;\n }\n `,\n ];\n }\n\n public focusInput(): void {\n this.filter = '';\n this.updateComplete.then(() => {\n if (this.searchInput) this.searchInput.value = '';\n this.searchInput?.focus();\n });\n }\n\n private handleKeydown(event: KeyboardEvent): void {\n if (event.key === 'Escape') {\n event.stopPropagation();\n this.emit('wysiwyg-emoji-cancel');\n }\n }\n\n public render(): TemplateResult {\n const query = this.filter.trim().toLowerCase();\n const shown = query ? EMOJI.filter(e => e.name.includes(query)) : EMOJI;\n return html`\n <div class=\"panel\" part=\"emoji-picker\" @keydown=${this.handleKeydown}>\n <input\n class=\"emoji-picker__search\"\n type=\"text\"\n placeholder=\"Search emoji…\"\n aria-label=\"Search emoji\"\n @input=${(e: Event) => {\n this.filter = (e.target as HTMLInputElement).value;\n }}\n />\n <div class=\"grid\" role=\"listbox\" aria-label=\"Emoji\">\n ${shown.map(\n e => html`\n <button\n type=\"button\"\n class=\"emoji\"\n title=${e.name}\n @mousedown=${(ev: Event) => ev.preventDefault()}\n @click=${() => this.emit('wysiwyg-emoji-select', { char: e.char })}\n >\n ${e.char}\n </button>\n `\n )}\n ${shown.length === 0\n ? html`<div class=\"empty\" style=\"grid-column: 1 / -1\">No emoji found</div>`\n : ''}\n </div>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'nile-wysiwyg-emoji-picker': NileWysiwygEmojiPicker;\n }\n}\n"]}
1
+ {"version":3,"file":"emoji-picker.js","sourceRoot":"","sources":["../../../../src/nile-wysiwyg-editor/ui/emoji-picker.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAE,GAAG,EAAkC,MAAM,KAAK,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC1E,OAAO,WAAW,MAAM,6BAA6B,CAAC;AACtD,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAEjC;;;;GAIG;AAEI,IAAM,sBAAsB,GAA5B,MAAM,sBAAuB,SAAQ,WAAW;IAAhD;;QACuC,SAAI,GAAG,KAAK,CAAC;QAExC,WAAM,GAAG,EAAE,CAAC;IAmI/B,CAAC;IA/HQ,MAAM,KAAK,MAAM;QACtB,OAAO;YACL,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAuEF;SACF,CAAC;IACJ,CAAC;IAEM,UAAU;QACf,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC;QACjB,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,EAAE;YAC5B,IAAI,IAAI,CAAC,WAAW;gBAAE,IAAI,CAAC,WAAW,CAAC,KAAK,GAAG,EAAE,CAAC;YAClD,IAAI,CAAC,WAAW,EAAE,KAAK,EAAE,CAAC;QAC5B,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,aAAa,CAAC,KAAoB;QACxC,IAAI,KAAK,CAAC,GAAG,KAAK,QAAQ,EAAE,CAAC;YAC3B,KAAK,CAAC,eAAe,EAAE,CAAC;YACxB,IAAI,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;QACpC,CAAC;IACH,CAAC;IAEM,MAAM;QACX,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAC/C,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;QACxE,OAAO,IAAI,CAAA;wDACyC,IAAI,CAAC,aAAa;;;;;;mBAMvD,CAAC,CAAQ,EAAE,EAAE;YACpB,IAAI,CAAC,MAAM,GAAI,CAAC,CAAC,MAA2B,CAAC,KAAK,CAAC;QACrD,CAAC;;;YAGC,KAAK,CAAC,GAAG,CACT,CAAC,CAAC,EAAE,CAAC,IAAI,CAAA;;;;wBAIG,CAAC,CAAC,IAAI;6BACD,CAAC,EAAS,EAAE,EAAE,CAAC,EAAE,CAAC,cAAc,EAAE;yBACtC,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,sBAAsB,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;;kBAEhE,CAAC,CAAC,IAAI;;aAEX,CACF;YACC,KAAK,CAAC,MAAM,KAAK,CAAC;YAClB,CAAC,CAAC,IAAI,CAAA,qEAAqE;YAC3E,CAAC,CAAC,EAAE;;;KAGX,CAAC;IACJ,CAAC;CACF,CAAA;AArI6C;IAA3C,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;oDAAc;AAExC;IAAhB,KAAK,EAAE;sDAAqB;AAEG;IAA/B,KAAK,CAAC,uBAAuB,CAAC;2DAAgC;AALpD,sBAAsB;IADlC,aAAa,CAAC,2BAA2B,CAAC;GAC9B,sBAAsB,CAsIlC","sourcesContent":["import { html, css, TemplateResult, CSSResultArray } from 'lit';\nimport { customElement, property, query, state } from 'lit/decorators.js';\nimport NileElement from '../../internal/nile-element';\nimport { EMOJI } from '../emoji';\n\n/**\n * Emoji picker panel (the 😊 toolbar item). Shares the emoji set with the\n * \":\" autocomplete; the search box filters by name. Emits\n * `wysiwyg-emoji-select` detail: { char } and `wysiwyg-emoji-cancel`.\n */\n@customElement('nile-wysiwyg-emoji-picker')\nexport class NileWysiwygEmojiPicker extends NileElement {\n @property({ type: Boolean, reflect: true }) open = false;\n\n @state() private filter = '';\n\n @query('.emoji-picker__search') searchInput?: HTMLInputElement;\n\n public static get styles(): CSSResultArray {\n return [\n css`\n :host {\n font-family: var(\n --nile-font-family-sans-serif,\n var(--ng-font-family-body, system-ui, -apple-system, sans-serif)\n );\n position: absolute;\n z-index: 20;\n display: none;\n }\n\n :host([open]) {\n display: block;\n }\n\n .panel {\n width: 316px;\n padding: 8px;\n background: var(--nile-wysiwyg-popover-bg, var(--nile-colors-white-base, var(--ng-colors-bg-primary)));\n border: 1px solid var(--nile-colors-neutral-400, var(--ng-colors-border-primary));\n border-radius: 8px;\n box-shadow: var(--nile-wysiwyg-popover-shadow, 0 4px 12px rgba(16, 24, 40, 0.12));\n }\n\n input {\n font: inherit;\n font-size: 13px;\n width: 100%;\n box-sizing: border-box;\n margin-bottom: 6px;\n padding: 5px 8px;\n border: 1px solid var(--nile-colors-neutral-400, var(--ng-colors-border-primary));\n border-radius: 6px;\n outline: none;\n }\n\n input:focus {\n border-color: var(--nile-colors-primary-600, var(--ng-componentcolors-utility-blue-600));\n }\n\n .grid {\n display: grid;\n grid-template-columns: repeat(9, 1fr);\n gap: 2px;\n max-height: 200px;\n overflow-y: auto;\n overscroll-behavior: contain;\n }\n\n .emoji {\n font: inherit;\n font-size: 18px;\n height: 30px;\n padding: 0;\n border: none;\n border-radius: 5px;\n background: transparent;\n cursor: pointer;\n line-height: 1;\n }\n\n .emoji:hover {\n background: var(--nile-colors-neutral-100, var(--ng-colors-bg-secondary));\n }\n\n .empty {\n padding: 12px 4px;\n font-size: 12px;\n color: var(--nile-colors-neutral-500, var(--ng-colors-text-quaternary-500));\n text-align: center;\n }\n `,\n ];\n }\n\n public focusInput(): void {\n this.filter = '';\n this.updateComplete.then(() => {\n if (this.searchInput) this.searchInput.value = '';\n this.searchInput?.focus();\n });\n }\n\n private handleKeydown(event: KeyboardEvent): void {\n if (event.key === 'Escape') {\n event.stopPropagation();\n this.emit('wysiwyg-emoji-cancel');\n }\n }\n\n public render(): TemplateResult {\n const query = this.filter.trim().toLowerCase();\n const shown = query ? EMOJI.filter(e => e.name.includes(query)) : EMOJI;\n return html`\n <div class=\"panel\" part=\"emoji-picker\" @keydown=${this.handleKeydown}>\n <input\n class=\"emoji-picker__search\"\n type=\"text\"\n placeholder=\"Search emoji…\"\n aria-label=\"Search emoji\"\n @input=${(e: Event) => {\n this.filter = (e.target as HTMLInputElement).value;\n }}\n />\n <div class=\"grid\" role=\"listbox\" aria-label=\"Emoji\">\n ${shown.map(\n e => html`\n <button\n type=\"button\"\n class=\"emoji\"\n title=${e.name}\n @mousedown=${(ev: Event) => ev.preventDefault()}\n @click=${() => this.emit('wysiwyg-emoji-select', { char: e.char })}\n >\n ${e.char}\n </button>\n `\n )}\n ${shown.length === 0\n ? html`<div class=\"empty\" style=\"grid-column: 1 / -1\">No emoji found</div>`\n : ''}\n </div>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'nile-wysiwyg-emoji-picker': NileWysiwygEmojiPicker;\n }\n}\n"]}
@@ -42,7 +42,7 @@ let NileWysiwygFindBar = class NileWysiwygFindBar extends NileElement {
42
42
  align-items: center;
43
43
  gap: 6px;
44
44
  padding: 8px;
45
- background: var(--nile-wysiwyg-popover-bg, var(--ng-colors-bg-primary));
45
+ background: var(--nile-wysiwyg-popover-bg, var(--nile-colors-white-base, var(--ng-colors-bg-primary)));
46
46
  border: 1px solid var(--nile-colors-neutral-400, var(--ng-colors-border-primary));
47
47
  border-radius: 8px;
48
48
  box-shadow: var(--nile-wysiwyg-popover-shadow, 0 4px 12px rgba(16, 24, 40, 0.12));
@@ -1 +1 @@
1
- {"version":3,"file":"find-replace.js","sourceRoot":"","sources":["../../../../src/nile-wysiwyg-editor/ui/find-replace.ts"],"names":[],"mappings":"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","sourcesContent":["import { html, css, TemplateResult, CSSResultArray } from 'lit';\nimport { customElement, property, query } from 'lit/decorators.js';\nimport NileElement from '../../internal/nile-element';\n\n/**\n * Find & replace bar pinned to the top-right of the editor. Emits:\n * - `wysiwyg-find` detail: { query }\n * - `wysiwyg-find-step` detail: { direction: 'next' | 'prev' }\n * - `wysiwyg-replace` detail: { value }\n * - `wysiwyg-replace-all` detail: { value }\n * - `wysiwyg-find-close`\n */\n@customElement('nile-wysiwyg-find-bar')\nexport class NileWysiwygFindBar extends NileElement {\n @property({ type: Boolean, reflect: true }) open = false;\n\n @property({ type: Number }) matchCount = 0;\n\n @property({ type: Number }) activeIndex = 0;\n\n @query('.find-bar__query') queryInput?: HTMLInputElement;\n\n @query('.find-bar__replace') replaceInput?: HTMLInputElement;\n\n public static get styles(): CSSResultArray {\n return [\n css`\n :host {\n font-family: var(\n --nile-font-family-sans-serif,\n var(--ng-font-family-body, system-ui, -apple-system, sans-serif)\n );\n position: absolute;\n top: 8px;\n right: 8px;\n z-index: 25;\n display: none;\n }\n\n :host([open]) {\n display: block;\n }\n\n .find-bar {\n display: grid;\n grid-template-columns: auto auto auto auto;\n align-items: center;\n gap: 6px;\n padding: 8px;\n background: var(--nile-wysiwyg-popover-bg, var(--ng-colors-bg-primary));\n border: 1px solid var(--nile-colors-neutral-400, var(--ng-colors-border-primary));\n border-radius: 8px;\n box-shadow: var(--nile-wysiwyg-popover-shadow, 0 4px 12px rgba(16, 24, 40, 0.12));\n font-size: 13px;\n }\n\n input {\n font: inherit;\n font-size: 13px;\n width: 160px;\n padding: 4px 8px;\n border: 1px solid var(--nile-colors-neutral-400, var(--ng-colors-border-primary));\n border-radius: 6px;\n outline: none;\n }\n\n input:focus {\n border-color: var(--nile-colors-primary-600, var(--ng-componentcolors-utility-blue-600));\n }\n\n .count {\n min-width: 42px;\n text-align: center;\n color: var(--nile-colors-neutral-500, var(--ng-colors-text-quaternary-500));\n font-variant-numeric: tabular-nums;\n }\n\n button {\n font: inherit;\n font-size: 12px;\n padding: 4px 8px;\n border: none;\n border-radius: 5px;\n background: transparent;\n cursor: pointer;\n color: var(--nile-colors-neutral-700, var(--ng-colors-text-secondary-700));\n }\n\n button:hover {\n background: var(--nile-colors-neutral-100, var(--ng-colors-bg-secondary));\n }\n `,\n ];\n }\n\n public focusInput(): void {\n this.updateComplete.then(() => {\n this.queryInput?.focus();\n this.queryInput?.select();\n });\n }\n\n private handleKeydown(event: KeyboardEvent): void {\n if (event.key === 'Escape') {\n event.stopPropagation();\n this.emit('wysiwyg-find-close');\n } else if (event.key === 'Enter' && event.target === this.queryInput) {\n event.preventDefault();\n this.emit('wysiwyg-find-step', { direction: event.shiftKey ? 'prev' : 'next' });\n }\n }\n\n public render(): TemplateResult {\n const count = this.matchCount\n ? `${Math.min(this.activeIndex + 1, this.matchCount)}/${this.matchCount}`\n : '0/0';\n return html`\n <div class=\"find-bar\" part=\"find-bar\" @keydown=${this.handleKeydown}>\n <input\n class=\"find-bar__query\"\n type=\"text\"\n placeholder=\"Find\"\n aria-label=\"Find\"\n @input=${(e: Event) =>\n this.emit('wysiwyg-find', { query: (e.target as HTMLInputElement).value })}\n />\n <span class=\"count\">${count}</span>\n <button\n type=\"button\"\n title=\"Previous match\"\n @click=${() => this.emit('wysiwyg-find-step', { direction: 'prev' })}\n >\n ↑\n </button>\n <button\n type=\"button\"\n title=\"Next match\"\n @click=${() => this.emit('wysiwyg-find-step', { direction: 'next' })}\n >\n ↓\n </button>\n <input\n class=\"find-bar__replace\"\n type=\"text\"\n placeholder=\"Replace with\"\n aria-label=\"Replace with\"\n />\n <button\n type=\"button\"\n @click=${() =>\n this.emit('wysiwyg-replace', { value: this.replaceInput?.value ?? '' })}\n >\n Replace\n </button>\n <button\n type=\"button\"\n @click=${() =>\n this.emit('wysiwyg-replace-all', { value: this.replaceInput?.value ?? '' })}\n >\n All\n </button>\n <button type=\"button\" title=\"Close (Esc)\" @click=${() => this.emit('wysiwyg-find-close')}>\n ✕\n </button>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'nile-wysiwyg-find-bar': NileWysiwygFindBar;\n }\n}\n"]}
1
+ {"version":3,"file":"find-replace.js","sourceRoot":"","sources":["../../../../src/nile-wysiwyg-editor/ui/find-replace.ts"],"names":[],"mappings":"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","sourcesContent":["import { html, css, TemplateResult, CSSResultArray } from 'lit';\nimport { customElement, property, query } from 'lit/decorators.js';\nimport NileElement from '../../internal/nile-element';\n\n/**\n * Find & replace bar pinned to the top-right of the editor. Emits:\n * - `wysiwyg-find` detail: { query }\n * - `wysiwyg-find-step` detail: { direction: 'next' | 'prev' }\n * - `wysiwyg-replace` detail: { value }\n * - `wysiwyg-replace-all` detail: { value }\n * - `wysiwyg-find-close`\n */\n@customElement('nile-wysiwyg-find-bar')\nexport class NileWysiwygFindBar extends NileElement {\n @property({ type: Boolean, reflect: true }) open = false;\n\n @property({ type: Number }) matchCount = 0;\n\n @property({ type: Number }) activeIndex = 0;\n\n @query('.find-bar__query') queryInput?: HTMLInputElement;\n\n @query('.find-bar__replace') replaceInput?: HTMLInputElement;\n\n public static get styles(): CSSResultArray {\n return [\n css`\n :host {\n font-family: var(\n --nile-font-family-sans-serif,\n var(--ng-font-family-body, system-ui, -apple-system, sans-serif)\n );\n position: absolute;\n top: 8px;\n right: 8px;\n z-index: 25;\n display: none;\n }\n\n :host([open]) {\n display: block;\n }\n\n .find-bar {\n display: grid;\n grid-template-columns: auto auto auto auto;\n align-items: center;\n gap: 6px;\n padding: 8px;\n background: var(--nile-wysiwyg-popover-bg, var(--nile-colors-white-base, var(--ng-colors-bg-primary)));\n border: 1px solid var(--nile-colors-neutral-400, var(--ng-colors-border-primary));\n border-radius: 8px;\n box-shadow: var(--nile-wysiwyg-popover-shadow, 0 4px 12px rgba(16, 24, 40, 0.12));\n font-size: 13px;\n }\n\n input {\n font: inherit;\n font-size: 13px;\n width: 160px;\n padding: 4px 8px;\n border: 1px solid var(--nile-colors-neutral-400, var(--ng-colors-border-primary));\n border-radius: 6px;\n outline: none;\n }\n\n input:focus {\n border-color: var(--nile-colors-primary-600, var(--ng-componentcolors-utility-blue-600));\n }\n\n .count {\n min-width: 42px;\n text-align: center;\n color: var(--nile-colors-neutral-500, var(--ng-colors-text-quaternary-500));\n font-variant-numeric: tabular-nums;\n }\n\n button {\n font: inherit;\n font-size: 12px;\n padding: 4px 8px;\n border: none;\n border-radius: 5px;\n background: transparent;\n cursor: pointer;\n color: var(--nile-colors-neutral-700, var(--ng-colors-text-secondary-700));\n }\n\n button:hover {\n background: var(--nile-colors-neutral-100, var(--ng-colors-bg-secondary));\n }\n `,\n ];\n }\n\n public focusInput(): void {\n this.updateComplete.then(() => {\n this.queryInput?.focus();\n this.queryInput?.select();\n });\n }\n\n private handleKeydown(event: KeyboardEvent): void {\n if (event.key === 'Escape') {\n event.stopPropagation();\n this.emit('wysiwyg-find-close');\n } else if (event.key === 'Enter' && event.target === this.queryInput) {\n event.preventDefault();\n this.emit('wysiwyg-find-step', { direction: event.shiftKey ? 'prev' : 'next' });\n }\n }\n\n public render(): TemplateResult {\n const count = this.matchCount\n ? `${Math.min(this.activeIndex + 1, this.matchCount)}/${this.matchCount}`\n : '0/0';\n return html`\n <div class=\"find-bar\" part=\"find-bar\" @keydown=${this.handleKeydown}>\n <input\n class=\"find-bar__query\"\n type=\"text\"\n placeholder=\"Find\"\n aria-label=\"Find\"\n @input=${(e: Event) =>\n this.emit('wysiwyg-find', { query: (e.target as HTMLInputElement).value })}\n />\n <span class=\"count\">${count}</span>\n <button\n type=\"button\"\n title=\"Previous match\"\n @click=${() => this.emit('wysiwyg-find-step', { direction: 'prev' })}\n >\n ↑\n </button>\n <button\n type=\"button\"\n title=\"Next match\"\n @click=${() => this.emit('wysiwyg-find-step', { direction: 'next' })}\n >\n ↓\n </button>\n <input\n class=\"find-bar__replace\"\n type=\"text\"\n placeholder=\"Replace with\"\n aria-label=\"Replace with\"\n />\n <button\n type=\"button\"\n @click=${() =>\n this.emit('wysiwyg-replace', { value: this.replaceInput?.value ?? '' })}\n >\n Replace\n </button>\n <button\n type=\"button\"\n @click=${() =>\n this.emit('wysiwyg-replace-all', { value: this.replaceInput?.value ?? '' })}\n >\n All\n </button>\n <button type=\"button\" title=\"Close (Esc)\" @click=${() => this.emit('wysiwyg-find-close')}>\n ✕\n </button>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'nile-wysiwyg-find-bar': NileWysiwygFindBar;\n }\n}\n"]}
@@ -64,7 +64,7 @@ let NileWysiwygImageMenu = class NileWysiwygImageMenu extends NileElement {
64
64
  display: flex;
65
65
  gap: 2px;
66
66
  padding: 4px;
67
- background: var(--nile-wysiwyg-popover-bg, var(--ng-colors-bg-primary));
67
+ background: var(--nile-wysiwyg-popover-bg, var(--nile-colors-white-base, var(--ng-colors-bg-primary)));
68
68
  border: 1px solid var(--nile-colors-neutral-400, var(--ng-colors-border-primary));
69
69
  border-radius: 8px;
70
70
  box-shadow: var(--nile-wysiwyg-popover-shadow, 0 4px 12px rgba(16, 24, 40, 0.12));
@@ -1 +1 @@
1
- {"version":3,"file":"image-menu.js","sourceRoot":"","sources":["../../../../src/nile-wysiwyg-editor/ui/image-menu.ts"],"names":[],"mappings":"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","sourcesContent":["import { html, css, TemplateResult, CSSResultArray } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport NileElement from '../../internal/nile-element';\nimport { renderGlyph } from '../../internal/glyph';\nimport type { ToolbarState } from '../engine/selection-state';\n\ninterface ImageOp {\n label: string;\n /** Design-system icon name; `text` is the fallback when no glyph fits. */\n icon?: string;\n text?: string;\n command: string;\n attrs?: Record<string, unknown>;\n active?: (s: ToolbarState) => boolean;\n}\n\nconst OPS: ImageOp[] = [\n {\n label: 'Align left',\n icon: 'format_align_left',\n command: 'setImageAlign',\n attrs: { align: 'left' },\n active: s => s.imageAlign === 'left',\n },\n {\n label: 'Align center',\n icon: 'format_align_middle',\n command: 'setImageAlign',\n attrs: { align: 'center' },\n active: s => s.imageAlign === 'center',\n },\n {\n label: 'Align right',\n icon: 'format_align_right',\n command: 'setImageAlign',\n attrs: { align: 'right' },\n active: s => s.imageAlign === 'right',\n },\n {\n label: 'Toggle caption',\n icon: 'ng-captions',\n command: 'toggleImageCaption',\n active: s => s.imageIsFigure,\n },\n { label: 'Original size', text: '1:1', command: 'setImageWidth', attrs: { width: null } },\n { label: 'Delete image', icon: 'ng-trash-01', command: 'deleteImage' },\n];\n\n/**\n * Compact floating bar shown while an image or figure is selected. The host\n * positions it; operations bubble up as `wysiwyg-command` events.\n */\n@customElement('nile-wysiwyg-image-menu')\nexport class NileWysiwygImageMenu extends NileElement {\n @property({ type: Boolean, reflect: true }) open = false;\n\n @property({ attribute: false }) toolbarState?: ToolbarState;\n\n public static get styles(): CSSResultArray {\n return [\n css`\n :host {\n font-family: var(\n --nile-font-family-sans-serif,\n var(--ng-font-family-body, system-ui, -apple-system, sans-serif)\n );\n position: absolute;\n z-index: 15;\n display: none;\n }\n\n :host([open]) {\n display: block;\n }\n\n .menu {\n display: flex;\n gap: 2px;\n padding: 4px;\n background: var(--nile-wysiwyg-popover-bg, var(--ng-colors-bg-primary));\n border: 1px solid var(--nile-colors-neutral-400, var(--ng-colors-border-primary));\n border-radius: 8px;\n box-shadow: var(--nile-wysiwyg-popover-shadow, 0 4px 12px rgba(16, 24, 40, 0.12));\n }\n\n button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 26px;\n height: 26px;\n padding: 0 4px;\n border: none;\n border-radius: 5px;\n background: transparent;\n cursor: pointer;\n font-size: 12px;\n font-weight: 600;\n color: var(--nile-colors-neutral-700, var(--ng-colors-text-secondary-700));\n }\n\n button:hover {\n background: var(--nile-colors-neutral-100, var(--ng-colors-bg-secondary));\n }\n\n button[data-active] {\n background: var(--nile-colors-primary-50, var(--ng-componentcolors-utility-blue-50));\n color: var(--nile-colors-primary-700, var(--ng-componentcolors-utility-blue-700));\n }\n `,\n ];\n }\n\n public render(): TemplateResult {\n const state = this.toolbarState;\n return html`\n <div class=\"menu\" part=\"image-menu\" @mousedown=${(e: Event) => e.preventDefault()}>\n ${OPS.map(\n op => html`\n <button\n type=\"button\"\n title=${op.label}\n aria-label=${op.label}\n ?data-active=${state && op.active ? op.active(state) : false}\n @click=${() => this.emit('wysiwyg-command', { name: op.command, attrs: op.attrs })}\n >\n ${op.icon ? renderGlyph(op.icon, 16) : op.text}\n </button>\n `\n )}\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'nile-wysiwyg-image-menu': NileWysiwygImageMenu;\n }\n}\n"]}
1
+ {"version":3,"file":"image-menu.js","sourceRoot":"","sources":["../../../../src/nile-wysiwyg-editor/ui/image-menu.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAE,GAAG,EAAkC,MAAM,KAAK,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,WAAW,MAAM,6BAA6B,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAanD,MAAM,GAAG,GAAc;IACrB;QACE,KAAK,EAAE,YAAY;QACnB,IAAI,EAAE,mBAAmB;QACzB,OAAO,EAAE,eAAe;QACxB,KAAK,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE;QACxB,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,MAAM;KACrC;IACD;QACE,KAAK,EAAE,cAAc;QACrB,IAAI,EAAE,qBAAqB;QAC3B,OAAO,EAAE,eAAe;QACxB,KAAK,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE;QAC1B,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,QAAQ;KACvC;IACD;QACE,KAAK,EAAE,aAAa;QACpB,IAAI,EAAE,oBAAoB;QAC1B,OAAO,EAAE,eAAe;QACxB,KAAK,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE;QACzB,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,OAAO;KACtC;IACD;QACE,KAAK,EAAE,gBAAgB;QACvB,IAAI,EAAE,aAAa;QACnB,OAAO,EAAE,oBAAoB;QAC7B,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,aAAa;KAC7B;IACD,EAAE,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;IACzF,EAAE,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,aAAa,EAAE;CACvE,CAAC;AAEF;;;GAGG;AAEI,IAAM,oBAAoB,GAA1B,MAAM,oBAAqB,SAAQ,WAAW;IAA9C;;QACuC,SAAI,GAAG,KAAK,CAAC;IA+E3D,CAAC;IA3EQ,MAAM,KAAK,MAAM;QACtB,OAAO;YACL,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAiDF;SACF,CAAC;IACJ,CAAC;IAEM,MAAM;QACX,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC;QAChC,OAAO,IAAI,CAAA;uDACwC,CAAC,CAAQ,EAAE,EAAE,CAAC,CAAC,CAAC,cAAc,EAAE;UAC7E,GAAG,CAAC,GAAG,CACP,EAAE,CAAC,EAAE,CAAC,IAAI,CAAA;;;sBAGE,EAAE,CAAC,KAAK;2BACH,EAAE,CAAC,KAAK;6BACN,KAAK,IAAI,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK;uBACnD,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,EAAE,IAAI,EAAE,EAAE,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC;;gBAEhF,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI;;WAEjD,CACF;;KAEJ,CAAC;IACJ,CAAC;CACF,CAAA;AA/E6C;IAA3C,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;kDAAc;AAEzB;IAA/B,QAAQ,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;0DAA6B;AAHjD,oBAAoB;IADhC,aAAa,CAAC,yBAAyB,CAAC;GAC5B,oBAAoB,CAgFhC","sourcesContent":["import { html, css, TemplateResult, CSSResultArray } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport NileElement from '../../internal/nile-element';\nimport { renderGlyph } from '../../internal/glyph';\nimport type { ToolbarState } from '../engine/selection-state';\n\ninterface ImageOp {\n label: string;\n /** Design-system icon name; `text` is the fallback when no glyph fits. */\n icon?: string;\n text?: string;\n command: string;\n attrs?: Record<string, unknown>;\n active?: (s: ToolbarState) => boolean;\n}\n\nconst OPS: ImageOp[] = [\n {\n label: 'Align left',\n icon: 'format_align_left',\n command: 'setImageAlign',\n attrs: { align: 'left' },\n active: s => s.imageAlign === 'left',\n },\n {\n label: 'Align center',\n icon: 'format_align_middle',\n command: 'setImageAlign',\n attrs: { align: 'center' },\n active: s => s.imageAlign === 'center',\n },\n {\n label: 'Align right',\n icon: 'format_align_right',\n command: 'setImageAlign',\n attrs: { align: 'right' },\n active: s => s.imageAlign === 'right',\n },\n {\n label: 'Toggle caption',\n icon: 'ng-captions',\n command: 'toggleImageCaption',\n active: s => s.imageIsFigure,\n },\n { label: 'Original size', text: '1:1', command: 'setImageWidth', attrs: { width: null } },\n { label: 'Delete image', icon: 'ng-trash-01', command: 'deleteImage' },\n];\n\n/**\n * Compact floating bar shown while an image or figure is selected. The host\n * positions it; operations bubble up as `wysiwyg-command` events.\n */\n@customElement('nile-wysiwyg-image-menu')\nexport class NileWysiwygImageMenu extends NileElement {\n @property({ type: Boolean, reflect: true }) open = false;\n\n @property({ attribute: false }) toolbarState?: ToolbarState;\n\n public static get styles(): CSSResultArray {\n return [\n css`\n :host {\n font-family: var(\n --nile-font-family-sans-serif,\n var(--ng-font-family-body, system-ui, -apple-system, sans-serif)\n );\n position: absolute;\n z-index: 15;\n display: none;\n }\n\n :host([open]) {\n display: block;\n }\n\n .menu {\n display: flex;\n gap: 2px;\n padding: 4px;\n background: var(--nile-wysiwyg-popover-bg, var(--nile-colors-white-base, var(--ng-colors-bg-primary)));\n border: 1px solid var(--nile-colors-neutral-400, var(--ng-colors-border-primary));\n border-radius: 8px;\n box-shadow: var(--nile-wysiwyg-popover-shadow, 0 4px 12px rgba(16, 24, 40, 0.12));\n }\n\n button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 26px;\n height: 26px;\n padding: 0 4px;\n border: none;\n border-radius: 5px;\n background: transparent;\n cursor: pointer;\n font-size: 12px;\n font-weight: 600;\n color: var(--nile-colors-neutral-700, var(--ng-colors-text-secondary-700));\n }\n\n button:hover {\n background: var(--nile-colors-neutral-100, var(--ng-colors-bg-secondary));\n }\n\n button[data-active] {\n background: var(--nile-colors-primary-50, var(--ng-componentcolors-utility-blue-50));\n color: var(--nile-colors-primary-700, var(--ng-componentcolors-utility-blue-700));\n }\n `,\n ];\n }\n\n public render(): TemplateResult {\n const state = this.toolbarState;\n return html`\n <div class=\"menu\" part=\"image-menu\" @mousedown=${(e: Event) => e.preventDefault()}>\n ${OPS.map(\n op => html`\n <button\n type=\"button\"\n title=${op.label}\n aria-label=${op.label}\n ?data-active=${state && op.active ? op.active(state) : false}\n @click=${() => this.emit('wysiwyg-command', { name: op.command, attrs: op.attrs })}\n >\n ${op.icon ? renderGlyph(op.icon, 16) : op.text}\n </button>\n `\n )}\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'nile-wysiwyg-image-menu': NileWysiwygImageMenu;\n }\n}\n"]}
@@ -59,7 +59,7 @@ let NileWysiwygImagePanel = class NileWysiwygImagePanel extends NileElement {
59
59
  min-width: 340px;
60
60
  max-width: 420px;
61
61
  padding: 12px;
62
- background: var(--nile-wysiwyg-popover-bg, var(--ng-colors-bg-primary));
62
+ background: var(--nile-wysiwyg-popover-bg, var(--nile-colors-white-base, var(--ng-colors-bg-primary)));
63
63
  border: 1px solid var(--nile-colors-neutral-400, var(--ng-colors-border-primary));
64
64
  border-radius: 8px;
65
65
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
@@ -1 +1 @@
1
- {"version":3,"file":"image-panel.js","sourceRoot":"","sources":["../../../../src/nile-wysiwyg-editor/ui/image-panel.ts"],"names":[],"mappings":"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","sourcesContent":["import { html, css, TemplateResult, CSSResultArray } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport NileElement from '../../internal/nile-element';\nimport '../../nile-input/index';\nimport '../../nile-button/index';\n\n/**\n * Floating image insert/edit panel, matching nile-rich-text-editor's image\n * dialog: URL + alt + caption (nile-input) and an Insert action. When\n * `upload-from-computer` is set it also offers an \"or / Upload from computer\"\n * button (with max-size validation), matching the RTE's `uploadfromcomputer`\n * flag. An edit mode pre-fills the fields and adds Remove.\n *\n * The host positions it and listens for:\n * - `wysiwyg-image-apply` detail: { src, alt, caption } (insert / edit)\n * - `wysiwyg-image-file` detail: { file, alt, caption } (upload)\n * - `wysiwyg-image-remove` (delete active image)\n * - `wysiwyg-image-cancel` (Escape)\n */\n@customElement('nile-wysiwyg-image-panel')\nexport class NileWysiwygImagePanel extends NileElement {\n @property({ type: Boolean, reflect: true }) open = false;\n\n /** True when editing an already-inserted image (shows Remove, \"Save\"). */\n @property({ type: Boolean }) editing = false;\n\n /** Shows the \"Upload from computer\" button below the URL field. */\n @property({ type: Boolean, attribute: 'upload-from-computer' })\n uploadFromComputer = false;\n\n /** Maximum allowed upload size in bytes (default 2 MB). */\n @property({ type: Number, attribute: 'max-file-size' }) maxFileSize = 2 * 1024 * 1024;\n\n @state() private srcValue = '';\n @state() private altValue = '';\n @state() private captionValue = '';\n @state() private uploadedFileName = '';\n @state() private errorMessage = '';\n\n /** File staged by \"Upload from computer\", applied on Insert. */\n private stagedFile: File | null = null;\n\n public static get styles(): CSSResultArray {\n return [\n css`\n :host {\n font-family: var(\n --nile-font-family-sans-serif,\n var(--ng-font-family-body, system-ui, -apple-system, sans-serif)\n );\n position: absolute;\n z-index: 20;\n display: none;\n }\n\n :host([open]) {\n display: block;\n }\n\n .image-panel {\n display: flex;\n flex-direction: column;\n gap: 12px;\n min-width: 340px;\n max-width: 420px;\n padding: 12px;\n background: var(--nile-wysiwyg-popover-bg, var(--ng-colors-bg-primary));\n border: 1px solid var(--nile-colors-neutral-400, var(--ng-colors-border-primary));\n border-radius: 8px;\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);\n font-size: 13px;\n }\n\n nile-input {\n width: 100%;\n }\n\n .divider {\n display: flex;\n align-items: center;\n gap: 8px;\n color: var(--nile-colors-neutral-500, var(--ng-colors-text-quaternary-500));\n font-size: 12px;\n }\n\n .divider::before,\n .divider::after {\n content: '';\n flex: 1;\n height: 1px;\n background: var(--nile-colors-neutral-300, var(--ng-colors-border-secondary));\n }\n\n .upload-row {\n display: flex;\n flex-direction: column;\n align-items: stretch;\n gap: 6px;\n }\n\n .upload-btn {\n width: 100%;\n }\n\n /* Center the icon + label within the full-width upload button. */\n .upload-btn::part(base) {\n width: 100%;\n justify-content: center;\n }\n\n .upload-filename {\n color: var(--nile-colors-neutral-600, var(--ng-colors-text-tertiary-600));\n font-size: 12px;\n text-align: center;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .hidden-file {\n display: none;\n }\n\n .error {\n color: var(--nile-colors-danger-600, var(--ng-componentcolors-utility-error-600));\n font-size: 12px;\n }\n\n .actions {\n display: flex;\n justify-content: flex-end;\n align-items: center;\n gap: 8px;\n width: 100%;\n }\n\n .actions .spacer {\n flex: 1;\n }\n `,\n ];\n }\n\n public focusInput(): void {\n this.updateComplete.then(() => {\n const input = this.shadowRoot?.querySelector('nile-input') as HTMLElement | null;\n input?.focus();\n });\n }\n\n /** Clears every field and returns to insert (non-editing) mode. */\n public reset(): void {\n this.editing = false;\n this.srcValue = '';\n this.altValue = '';\n this.captionValue = '';\n this.uploadedFileName = '';\n this.errorMessage = '';\n this.stagedFile = null;\n }\n\n /** Pre-fills the panel for editing an existing image. */\n public prefill(data: { src?: string; alt?: string; caption?: string }): void {\n this.editing = true;\n this.srcValue = data.src ?? '';\n this.altValue = data.alt ?? '';\n this.captionValue = data.caption ?? '';\n this.uploadedFileName = '';\n this.errorMessage = '';\n this.stagedFile = null;\n }\n\n private onSrc(event: CustomEvent): void {\n this.srcValue = (event.detail?.value ?? '') as string;\n if (this.srcValue && this.stagedFile) {\n this.stagedFile = null;\n this.uploadedFileName = '';\n }\n this.errorMessage = '';\n }\n\n private onAlt(event: CustomEvent): void {\n this.altValue = (event.detail?.value ?? '') as string;\n }\n\n private onCaption(event: CustomEvent): void {\n this.captionValue = (event.detail?.value ?? '') as string;\n }\n\n private triggerFilePicker(): void {\n const input = this.shadowRoot?.querySelector('.hidden-file') as HTMLInputElement | null;\n input?.click();\n }\n\n private onFileChange(event: Event): void {\n const input = event.target as HTMLInputElement;\n const file = input.files?.[0];\n if (!file) return;\n if (!file.type.startsWith('image/')) {\n this.errorMessage = 'Please choose an image file.';\n input.value = '';\n return;\n }\n if (file.size > this.maxFileSize) {\n const mb = Math.round((this.maxFileSize / (1024 * 1024)) * 10) / 10;\n this.errorMessage = `Image must be under ${mb} MB.`;\n input.value = '';\n return;\n }\n this.stagedFile = file;\n this.uploadedFileName = file.name;\n this.srcValue = '';\n this.errorMessage = '';\n input.value = '';\n }\n\n private handleSubmit(): void {\n const alt = this.altValue.trim();\n const caption = this.captionValue.trim();\n if (this.stagedFile) {\n this.emit('wysiwyg-image-file', { file: this.stagedFile, alt, caption });\n return;\n }\n const src = this.srcValue.trim();\n if (!src) {\n this.errorMessage = this.uploadFromComputer\n ? 'Add an image URL or upload a file.'\n : 'Add an image URL.';\n return;\n }\n this.emit('wysiwyg-image-apply', { src, alt, caption });\n }\n\n private handleKeydown(event: KeyboardEvent): void {\n if (event.key === 'Escape') {\n event.stopPropagation();\n this.emit('wysiwyg-image-cancel');\n } else if (event.key === 'Enter') {\n event.preventDefault();\n event.stopPropagation();\n this.handleSubmit();\n }\n }\n\n public render(): TemplateResult {\n return html`\n <div class=\"image-panel\" part=\"image-panel\" @keydown=${this.handleKeydown}>\n <nile-input\n label=\"Image URL\"\n placeholder=\"Paste image link here\"\n .value=${this.srcValue}\n @nile-input=${this.onSrc}\n ></nile-input>\n\n ${this.uploadFromComputer\n ? html`\n <div class=\"divider\">or</div>\n <div class=\"upload-row\">\n <nile-button\n class=\"upload-btn\"\n variant=\"secondary\"\n @click=${this.triggerFilePicker}\n >\n <svg\n slot=\"prefix\"\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\" />\n <polyline points=\"17 8 12 3 7 8\" />\n <line x1=\"12\" y1=\"3\" x2=\"12\" y2=\"15\" />\n </svg>\n Upload from computer\n </nile-button>\n ${this.uploadedFileName\n ? html`<span class=\"upload-filename\" title=${this.uploadedFileName}\n >${this.uploadedFileName}</span\n >`\n : null}\n </div>\n <input\n class=\"hidden-file\"\n type=\"file\"\n accept=\"image/*\"\n @change=${this.onFileChange}\n />\n `\n : null}\n\n ${this.errorMessage\n ? html`<span class=\"error\" part=\"error\">${this.errorMessage}</span>`\n : null}\n\n <nile-input\n label=\"Alt text\"\n placeholder=\"Describe the image\"\n .value=${this.altValue}\n @nile-input=${this.onAlt}\n ></nile-input>\n\n <nile-input\n label=\"Caption\"\n placeholder=\"Add a caption (optional)\"\n .value=${this.captionValue}\n @nile-input=${this.onCaption}\n ></nile-input>\n\n <div class=\"actions\">\n ${this.editing\n ? html`<nile-button\n variant=\"destructive\"\n @click=${() => this.emit('wysiwyg-image-remove')}\n >Remove</nile-button\n >\n <span class=\"spacer\"></span>`\n : null}\n <nile-button variant=\"primary\" @click=${() => this.handleSubmit()}\n >${this.editing ? 'Save' : 'Insert'}</nile-button\n >\n </div>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'nile-wysiwyg-image-panel': NileWysiwygImagePanel;\n }\n}\n"]}
1
+ {"version":3,"file":"image-panel.js","sourceRoot":"","sources":["../../../../src/nile-wysiwyg-editor/ui/image-panel.ts"],"names":[],"mappings":"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","sourcesContent":["import { html, css, TemplateResult, CSSResultArray } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport NileElement from '../../internal/nile-element';\nimport '../../nile-input/index';\nimport '../../nile-button/index';\n\n/**\n * Floating image insert/edit panel, matching nile-rich-text-editor's image\n * dialog: URL + alt + caption (nile-input) and an Insert action. When\n * `upload-from-computer` is set it also offers an \"or / Upload from computer\"\n * button (with max-size validation), matching the RTE's `uploadfromcomputer`\n * flag. An edit mode pre-fills the fields and adds Remove.\n *\n * The host positions it and listens for:\n * - `wysiwyg-image-apply` detail: { src, alt, caption } (insert / edit)\n * - `wysiwyg-image-file` detail: { file, alt, caption } (upload)\n * - `wysiwyg-image-remove` (delete active image)\n * - `wysiwyg-image-cancel` (Escape)\n */\n@customElement('nile-wysiwyg-image-panel')\nexport class NileWysiwygImagePanel extends NileElement {\n @property({ type: Boolean, reflect: true }) open = false;\n\n /** True when editing an already-inserted image (shows Remove, \"Save\"). */\n @property({ type: Boolean }) editing = false;\n\n /** Shows the \"Upload from computer\" button below the URL field. */\n @property({ type: Boolean, attribute: 'upload-from-computer' })\n uploadFromComputer = false;\n\n /** Maximum allowed upload size in bytes (default 2 MB). */\n @property({ type: Number, attribute: 'max-file-size' }) maxFileSize = 2 * 1024 * 1024;\n\n @state() private srcValue = '';\n @state() private altValue = '';\n @state() private captionValue = '';\n @state() private uploadedFileName = '';\n @state() private errorMessage = '';\n\n /** File staged by \"Upload from computer\", applied on Insert. */\n private stagedFile: File | null = null;\n\n public static get styles(): CSSResultArray {\n return [\n css`\n :host {\n font-family: var(\n --nile-font-family-sans-serif,\n var(--ng-font-family-body, system-ui, -apple-system, sans-serif)\n );\n position: absolute;\n z-index: 20;\n display: none;\n }\n\n :host([open]) {\n display: block;\n }\n\n .image-panel {\n display: flex;\n flex-direction: column;\n gap: 12px;\n min-width: 340px;\n max-width: 420px;\n padding: 12px;\n background: var(--nile-wysiwyg-popover-bg, var(--nile-colors-white-base, var(--ng-colors-bg-primary)));\n border: 1px solid var(--nile-colors-neutral-400, var(--ng-colors-border-primary));\n border-radius: 8px;\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);\n font-size: 13px;\n }\n\n nile-input {\n width: 100%;\n }\n\n .divider {\n display: flex;\n align-items: center;\n gap: 8px;\n color: var(--nile-colors-neutral-500, var(--ng-colors-text-quaternary-500));\n font-size: 12px;\n }\n\n .divider::before,\n .divider::after {\n content: '';\n flex: 1;\n height: 1px;\n background: var(--nile-colors-neutral-300, var(--ng-colors-border-secondary));\n }\n\n .upload-row {\n display: flex;\n flex-direction: column;\n align-items: stretch;\n gap: 6px;\n }\n\n .upload-btn {\n width: 100%;\n }\n\n /* Center the icon + label within the full-width upload button. */\n .upload-btn::part(base) {\n width: 100%;\n justify-content: center;\n }\n\n .upload-filename {\n color: var(--nile-colors-neutral-600, var(--ng-colors-text-tertiary-600));\n font-size: 12px;\n text-align: center;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .hidden-file {\n display: none;\n }\n\n .error {\n color: var(--nile-colors-danger-600, var(--ng-componentcolors-utility-error-600));\n font-size: 12px;\n }\n\n .actions {\n display: flex;\n justify-content: flex-end;\n align-items: center;\n gap: 8px;\n width: 100%;\n }\n\n .actions .spacer {\n flex: 1;\n }\n `,\n ];\n }\n\n public focusInput(): void {\n this.updateComplete.then(() => {\n const input = this.shadowRoot?.querySelector('nile-input') as HTMLElement | null;\n input?.focus();\n });\n }\n\n /** Clears every field and returns to insert (non-editing) mode. */\n public reset(): void {\n this.editing = false;\n this.srcValue = '';\n this.altValue = '';\n this.captionValue = '';\n this.uploadedFileName = '';\n this.errorMessage = '';\n this.stagedFile = null;\n }\n\n /** Pre-fills the panel for editing an existing image. */\n public prefill(data: { src?: string; alt?: string; caption?: string }): void {\n this.editing = true;\n this.srcValue = data.src ?? '';\n this.altValue = data.alt ?? '';\n this.captionValue = data.caption ?? '';\n this.uploadedFileName = '';\n this.errorMessage = '';\n this.stagedFile = null;\n }\n\n private onSrc(event: CustomEvent): void {\n this.srcValue = (event.detail?.value ?? '') as string;\n if (this.srcValue && this.stagedFile) {\n this.stagedFile = null;\n this.uploadedFileName = '';\n }\n this.errorMessage = '';\n }\n\n private onAlt(event: CustomEvent): void {\n this.altValue = (event.detail?.value ?? '') as string;\n }\n\n private onCaption(event: CustomEvent): void {\n this.captionValue = (event.detail?.value ?? '') as string;\n }\n\n private triggerFilePicker(): void {\n const input = this.shadowRoot?.querySelector('.hidden-file') as HTMLInputElement | null;\n input?.click();\n }\n\n private onFileChange(event: Event): void {\n const input = event.target as HTMLInputElement;\n const file = input.files?.[0];\n if (!file) return;\n if (!file.type.startsWith('image/')) {\n this.errorMessage = 'Please choose an image file.';\n input.value = '';\n return;\n }\n if (file.size > this.maxFileSize) {\n const mb = Math.round((this.maxFileSize / (1024 * 1024)) * 10) / 10;\n this.errorMessage = `Image must be under ${mb} MB.`;\n input.value = '';\n return;\n }\n this.stagedFile = file;\n this.uploadedFileName = file.name;\n this.srcValue = '';\n this.errorMessage = '';\n input.value = '';\n }\n\n private handleSubmit(): void {\n const alt = this.altValue.trim();\n const caption = this.captionValue.trim();\n if (this.stagedFile) {\n this.emit('wysiwyg-image-file', { file: this.stagedFile, alt, caption });\n return;\n }\n const src = this.srcValue.trim();\n if (!src) {\n this.errorMessage = this.uploadFromComputer\n ? 'Add an image URL or upload a file.'\n : 'Add an image URL.';\n return;\n }\n this.emit('wysiwyg-image-apply', { src, alt, caption });\n }\n\n private handleKeydown(event: KeyboardEvent): void {\n if (event.key === 'Escape') {\n event.stopPropagation();\n this.emit('wysiwyg-image-cancel');\n } else if (event.key === 'Enter') {\n event.preventDefault();\n event.stopPropagation();\n this.handleSubmit();\n }\n }\n\n public render(): TemplateResult {\n return html`\n <div class=\"image-panel\" part=\"image-panel\" @keydown=${this.handleKeydown}>\n <nile-input\n label=\"Image URL\"\n placeholder=\"Paste image link here\"\n .value=${this.srcValue}\n @nile-input=${this.onSrc}\n ></nile-input>\n\n ${this.uploadFromComputer\n ? html`\n <div class=\"divider\">or</div>\n <div class=\"upload-row\">\n <nile-button\n class=\"upload-btn\"\n variant=\"secondary\"\n @click=${this.triggerFilePicker}\n >\n <svg\n slot=\"prefix\"\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\" />\n <polyline points=\"17 8 12 3 7 8\" />\n <line x1=\"12\" y1=\"3\" x2=\"12\" y2=\"15\" />\n </svg>\n Upload from computer\n </nile-button>\n ${this.uploadedFileName\n ? html`<span class=\"upload-filename\" title=${this.uploadedFileName}\n >${this.uploadedFileName}</span\n >`\n : null}\n </div>\n <input\n class=\"hidden-file\"\n type=\"file\"\n accept=\"image/*\"\n @change=${this.onFileChange}\n />\n `\n : null}\n\n ${this.errorMessage\n ? html`<span class=\"error\" part=\"error\">${this.errorMessage}</span>`\n : null}\n\n <nile-input\n label=\"Alt text\"\n placeholder=\"Describe the image\"\n .value=${this.altValue}\n @nile-input=${this.onAlt}\n ></nile-input>\n\n <nile-input\n label=\"Caption\"\n placeholder=\"Add a caption (optional)\"\n .value=${this.captionValue}\n @nile-input=${this.onCaption}\n ></nile-input>\n\n <div class=\"actions\">\n ${this.editing\n ? html`<nile-button\n variant=\"destructive\"\n @click=${() => this.emit('wysiwyg-image-remove')}\n >Remove</nile-button\n >\n <span class=\"spacer\"></span>`\n : null}\n <nile-button variant=\"primary\" @click=${() => this.handleSubmit()}\n >${this.editing ? 'Save' : 'Insert'}</nile-button\n >\n </div>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'nile-wysiwyg-image-panel': NileWysiwygImagePanel;\n }\n}\n"]}
@@ -38,7 +38,7 @@ let NileWysiwygInsertMenu = class NileWysiwygInsertMenu extends NileElement {
38
38
  overflow-y: auto;
39
39
  overscroll-behavior: contain;
40
40
  padding: 6px;
41
- background: var(--nile-wysiwyg-popover-bg, var(--ng-colors-bg-primary));
41
+ background: var(--nile-wysiwyg-popover-bg, var(--nile-colors-white-base, var(--ng-colors-bg-primary)));
42
42
  border: 1px solid var(--nile-colors-neutral-400, var(--ng-colors-border-primary));
43
43
  border-radius: 8px;
44
44
  box-shadow: var(--nile-wysiwyg-popover-shadow, 0 4px 12px rgba(16, 24, 40, 0.12));
@@ -1 +1 @@
1
- {"version":3,"file":"insert-menu.js","sourceRoot":"","sources":["../../../../src/nile-wysiwyg-editor/ui/insert-menu.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAE,GAAG,EAAkC,OAAO,EAAE,MAAM,KAAK,CAAC;AACzE,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,WAAW,MAAM,6BAA6B,CAAC;AAOtD;;;;GAIG;AAEI,IAAM,qBAAqB,GAA3B,MAAM,qBAAsB,SAAQ,WAAW;IAA/C;;QACuC,SAAI,GAAG,KAAK,CAAC;QAE7B,YAAO,GAAG,EAAE,CAAC;QAEY,cAAS,GAAG,qBAAqB,CAAC;QAEvD,UAAK,GAAqB,EAAE,CAAC;IAiH/D,CAAC;IA/GQ,MAAM,KAAK,MAAM;QACtB,OAAO;YACL,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAoEF;SACF,CAAC;IACJ,CAAC;IAEO,aAAa,CAAC,KAAoB;QACxC,IAAI,KAAK,CAAC,GAAG,KAAK,QAAQ,EAAE,CAAC;YAC3B,KAAK,CAAC,eAAe,EAAE,CAAC;YACxB,IAAI,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;QACrC,CAAC;IACH,CAAC;IAEM,MAAM;QACX,OAAO,IAAI,CAAA;;;;;mBAKI,IAAI,CAAC,aAAa;qBAChB,CAAC,CAAQ,EAAE,EAAE,CAAC,CAAC,CAAC,cAAc,EAAE;;UAE3C,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAA,wBAAwB,IAAI,CAAC,OAAO,QAAQ,CAAC,CAAC,CAAC,OAAO;UACzE,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC;YACvB,CAAC,CAAC,IAAI,CAAA,sBAAsB,IAAI,CAAC,SAAS,QAAQ;YAClD,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CACZ,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAA;;;;;2BAKR,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,uBAAuB,EAAE,EAAE,KAAK,EAAE,CAAC;;uCAEvC,IAAI,CAAC,KAAK;oBAC7B,IAAI,CAAC,WAAW;gBAChB,CAAC,CAAC,IAAI,CAAA,qBAAqB,IAAI,CAAC,WAAW,QAAQ;gBACnD,CAAC,CAAC,OAAO;;eAEd,CACF;;KAER,CAAC;IACJ,CAAC;CACF,CAAA;AAvH6C;IAA3C,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;mDAAc;AAE7B;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;sDAAc;AAEY;IAApD,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC;wDAAmC;AAEvD;IAA/B,QAAQ,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;oDAA8B;AAPlD,qBAAqB;IADjC,aAAa,CAAC,0BAA0B,CAAC;GAC7B,qBAAqB,CAwHjC","sourcesContent":["import { html, css, TemplateResult, CSSResultArray, nothing } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport NileElement from '../../internal/nile-element';\n\nexport interface InsertMenuItem {\n label: string;\n description?: string;\n}\n\n/**\n * Generic list popover for \"pick one and insert\" toolbar actions — used by the\n * template and merge-field pickers. Emits `wysiwyg-insert-select` { index } and\n * `wysiwyg-insert-cancel`. Never takes focus, so the editor selection survives.\n */\n@customElement('nile-wysiwyg-insert-menu')\nexport class NileWysiwygInsertMenu extends NileElement {\n @property({ type: Boolean, reflect: true }) open = false;\n\n @property({ type: String }) heading = '';\n\n @property({ type: String, attribute: 'empty-text' }) emptyText = 'Nothing configured.';\n\n @property({ attribute: false }) items: InsertMenuItem[] = [];\n\n public static get styles(): CSSResultArray {\n return [\n css`\n :host {\n font-family: var(\n --nile-font-family-sans-serif,\n var(--ng-font-family-body, system-ui, -apple-system, sans-serif)\n );\n position: absolute;\n z-index: 20;\n display: none;\n }\n\n :host([open]) {\n display: block;\n }\n\n .panel {\n width: 260px;\n max-height: 300px;\n overflow-y: auto;\n overscroll-behavior: contain;\n padding: 6px;\n background: var(--nile-wysiwyg-popover-bg, var(--ng-colors-bg-primary));\n border: 1px solid var(--nile-colors-neutral-400, var(--ng-colors-border-primary));\n border-radius: 8px;\n box-shadow: var(--nile-wysiwyg-popover-shadow, 0 4px 12px rgba(16, 24, 40, 0.12));\n }\n\n .heading {\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n color: var(--nile-colors-neutral-600, var(--ng-colors-text-tertiary-600));\n padding: 4px 8px;\n }\n\n .item {\n display: block;\n width: 100%;\n text-align: left;\n font: inherit;\n padding: 6px 8px;\n border: none;\n border-radius: 6px;\n background: transparent;\n cursor: pointer;\n color: var(--nile-colors-dark-900, var(--ng-colors-text-primary-900));\n }\n\n .item:hover {\n background: var(--nile-colors-neutral-100, var(--ng-colors-bg-secondary));\n }\n\n .item .label {\n font-size: 13px;\n }\n\n .item .desc {\n font-size: 11px;\n color: var(--nile-colors-neutral-600, var(--ng-colors-text-tertiary-600));\n margin-top: 1px;\n }\n\n .empty {\n font-size: 12px;\n color: var(--nile-colors-neutral-600, var(--ng-colors-text-tertiary-600));\n padding: 8px;\n }\n `,\n ];\n }\n\n private handleKeydown(event: KeyboardEvent): void {\n if (event.key === 'Escape') {\n event.stopPropagation();\n this.emit('wysiwyg-insert-cancel');\n }\n }\n\n public render(): TemplateResult {\n return html`\n <div\n class=\"panel\"\n part=\"insert-menu\"\n role=\"menu\"\n @keydown=${this.handleKeydown}\n @mousedown=${(e: Event) => e.preventDefault()}\n >\n ${this.heading ? html`<div class=\"heading\">${this.heading}</div>` : nothing}\n ${this.items.length === 0\n ? html`<div class=\"empty\">${this.emptyText}</div>`\n : this.items.map(\n (item, index) => html`\n <button\n type=\"button\"\n class=\"item\"\n role=\"menuitem\"\n @click=${() => this.emit('wysiwyg-insert-select', { index })}\n >\n <div class=\"label\">${item.label}</div>\n ${item.description\n ? html`<div class=\"desc\">${item.description}</div>`\n : nothing}\n </button>\n `\n )}\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'nile-wysiwyg-insert-menu': NileWysiwygInsertMenu;\n }\n}\n"]}
1
+ {"version":3,"file":"insert-menu.js","sourceRoot":"","sources":["../../../../src/nile-wysiwyg-editor/ui/insert-menu.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAE,GAAG,EAAkC,OAAO,EAAE,MAAM,KAAK,CAAC;AACzE,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,WAAW,MAAM,6BAA6B,CAAC;AAOtD;;;;GAIG;AAEI,IAAM,qBAAqB,GAA3B,MAAM,qBAAsB,SAAQ,WAAW;IAA/C;;QACuC,SAAI,GAAG,KAAK,CAAC;QAE7B,YAAO,GAAG,EAAE,CAAC;QAEY,cAAS,GAAG,qBAAqB,CAAC;QAEvD,UAAK,GAAqB,EAAE,CAAC;IAiH/D,CAAC;IA/GQ,MAAM,KAAK,MAAM;QACtB,OAAO;YACL,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAoEF;SACF,CAAC;IACJ,CAAC;IAEO,aAAa,CAAC,KAAoB;QACxC,IAAI,KAAK,CAAC,GAAG,KAAK,QAAQ,EAAE,CAAC;YAC3B,KAAK,CAAC,eAAe,EAAE,CAAC;YACxB,IAAI,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;QACrC,CAAC;IACH,CAAC;IAEM,MAAM;QACX,OAAO,IAAI,CAAA;;;;;mBAKI,IAAI,CAAC,aAAa;qBAChB,CAAC,CAAQ,EAAE,EAAE,CAAC,CAAC,CAAC,cAAc,EAAE;;UAE3C,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAA,wBAAwB,IAAI,CAAC,OAAO,QAAQ,CAAC,CAAC,CAAC,OAAO;UACzE,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC;YACvB,CAAC,CAAC,IAAI,CAAA,sBAAsB,IAAI,CAAC,SAAS,QAAQ;YAClD,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CACZ,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAA;;;;;2BAKR,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,uBAAuB,EAAE,EAAE,KAAK,EAAE,CAAC;;uCAEvC,IAAI,CAAC,KAAK;oBAC7B,IAAI,CAAC,WAAW;gBAChB,CAAC,CAAC,IAAI,CAAA,qBAAqB,IAAI,CAAC,WAAW,QAAQ;gBACnD,CAAC,CAAC,OAAO;;eAEd,CACF;;KAER,CAAC;IACJ,CAAC;CACF,CAAA;AAvH6C;IAA3C,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;mDAAc;AAE7B;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;sDAAc;AAEY;IAApD,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC;wDAAmC;AAEvD;IAA/B,QAAQ,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;oDAA8B;AAPlD,qBAAqB;IADjC,aAAa,CAAC,0BAA0B,CAAC;GAC7B,qBAAqB,CAwHjC","sourcesContent":["import { html, css, TemplateResult, CSSResultArray, nothing } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport NileElement from '../../internal/nile-element';\n\nexport interface InsertMenuItem {\n label: string;\n description?: string;\n}\n\n/**\n * Generic list popover for \"pick one and insert\" toolbar actions — used by the\n * template and merge-field pickers. Emits `wysiwyg-insert-select` { index } and\n * `wysiwyg-insert-cancel`. Never takes focus, so the editor selection survives.\n */\n@customElement('nile-wysiwyg-insert-menu')\nexport class NileWysiwygInsertMenu extends NileElement {\n @property({ type: Boolean, reflect: true }) open = false;\n\n @property({ type: String }) heading = '';\n\n @property({ type: String, attribute: 'empty-text' }) emptyText = 'Nothing configured.';\n\n @property({ attribute: false }) items: InsertMenuItem[] = [];\n\n public static get styles(): CSSResultArray {\n return [\n css`\n :host {\n font-family: var(\n --nile-font-family-sans-serif,\n var(--ng-font-family-body, system-ui, -apple-system, sans-serif)\n );\n position: absolute;\n z-index: 20;\n display: none;\n }\n\n :host([open]) {\n display: block;\n }\n\n .panel {\n width: 260px;\n max-height: 300px;\n overflow-y: auto;\n overscroll-behavior: contain;\n padding: 6px;\n background: var(--nile-wysiwyg-popover-bg, var(--nile-colors-white-base, var(--ng-colors-bg-primary)));\n border: 1px solid var(--nile-colors-neutral-400, var(--ng-colors-border-primary));\n border-radius: 8px;\n box-shadow: var(--nile-wysiwyg-popover-shadow, 0 4px 12px rgba(16, 24, 40, 0.12));\n }\n\n .heading {\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n color: var(--nile-colors-neutral-600, var(--ng-colors-text-tertiary-600));\n padding: 4px 8px;\n }\n\n .item {\n display: block;\n width: 100%;\n text-align: left;\n font: inherit;\n padding: 6px 8px;\n border: none;\n border-radius: 6px;\n background: transparent;\n cursor: pointer;\n color: var(--nile-colors-dark-900, var(--ng-colors-text-primary-900));\n }\n\n .item:hover {\n background: var(--nile-colors-neutral-100, var(--ng-colors-bg-secondary));\n }\n\n .item .label {\n font-size: 13px;\n }\n\n .item .desc {\n font-size: 11px;\n color: var(--nile-colors-neutral-600, var(--ng-colors-text-tertiary-600));\n margin-top: 1px;\n }\n\n .empty {\n font-size: 12px;\n color: var(--nile-colors-neutral-600, var(--ng-colors-text-tertiary-600));\n padding: 8px;\n }\n `,\n ];\n }\n\n private handleKeydown(event: KeyboardEvent): void {\n if (event.key === 'Escape') {\n event.stopPropagation();\n this.emit('wysiwyg-insert-cancel');\n }\n }\n\n public render(): TemplateResult {\n return html`\n <div\n class=\"panel\"\n part=\"insert-menu\"\n role=\"menu\"\n @keydown=${this.handleKeydown}\n @mousedown=${(e: Event) => e.preventDefault()}\n >\n ${this.heading ? html`<div class=\"heading\">${this.heading}</div>` : nothing}\n ${this.items.length === 0\n ? html`<div class=\"empty\">${this.emptyText}</div>`\n : this.items.map(\n (item, index) => html`\n <button\n type=\"button\"\n class=\"item\"\n role=\"menuitem\"\n @click=${() => this.emit('wysiwyg-insert-select', { index })}\n >\n <div class=\"label\">${item.label}</div>\n ${item.description\n ? html`<div class=\"desc\">${item.description}</div>`\n : nothing}\n </button>\n `\n )}\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'nile-wysiwyg-insert-menu': NileWysiwygInsertMenu;\n }\n}\n"]}
@@ -43,7 +43,7 @@ let NileWysiwygLinkEditor = class NileWysiwygLinkEditor extends NileElement {
43
43
  gap: 8px;
44
44
  min-width: 280px;
45
45
  padding: 12px;
46
- background: var(--nile-wysiwyg-popover-bg, var(--ng-colors-bg-primary));
46
+ background: var(--nile-wysiwyg-popover-bg, var(--nile-colors-white-base, var(--ng-colors-bg-primary)));
47
47
  border: 1px solid
48
48
  var(--nile-wysiwyg-border-color, var(--nile-colors-neutral-400, var(--ng-colors-border-primary)));
49
49
  border-radius: var(--nile-wysiwyg-radius, 8px);
@@ -91,7 +91,7 @@ let NileWysiwygLinkEditor = class NileWysiwygLinkEditor extends NileElement {
91
91
 
92
92
  button.primary {
93
93
  background: var(--nile-colors-primary-600, var(--ng-componentcolors-utility-blue-600));
94
- color: var(--ng-colors-text-white);
94
+ color: var(--nile-colors-white-base, var(--ng-colors-text-white));
95
95
  }
96
96
 
97
97
  button.danger {
@@ -1 +1 @@
1
- {"version":3,"file":"link-editor.js","sourceRoot":"","sources":["../../../../src/nile-wysiwyg-editor/ui/link-editor.ts"],"names":[],"mappings":"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","sourcesContent":["import { html, css, TemplateResult, CSSResultArray, nothing } from 'lit';\nimport { customElement, property, query } from 'lit/decorators.js';\nimport NileElement from '../../internal/nile-element';\n\n/**\n * Floating link create/edit panel. The host positions it absolutely inside\n * the editor chrome and listens for:\n * - `wysiwyg-link-apply` detail: { href, text }\n * - `wysiwyg-link-remove`\n * - `wysiwyg-link-cancel`\n */\n@customElement('nile-wysiwyg-link-editor')\nexport class NileWysiwygLinkEditor extends NileElement {\n @property({ type: Boolean, reflect: true }) open = false;\n\n @property({ type: String }) href = '';\n\n @property({ type: String }) text = '';\n\n /** Show the text field (only when creating a link from a cursor). */\n @property({ type: Boolean }) allowText = false;\n\n /** Show the remove button (when editing an existing link). */\n @property({ type: Boolean }) canRemove = false;\n\n @query('.link-editor__href') hrefInput?: HTMLInputElement;\n\n public static get styles(): CSSResultArray {\n return [\n css`\n :host {\n font-family: var(\n --nile-font-family-sans-serif,\n var(--ng-font-family-body, system-ui, -apple-system, sans-serif)\n );\n position: absolute;\n z-index: 20;\n display: none;\n }\n\n :host([open]) {\n display: block;\n }\n\n .link-editor {\n display: flex;\n flex-direction: column;\n gap: 8px;\n min-width: 280px;\n padding: 12px;\n background: var(--nile-wysiwyg-popover-bg, var(--ng-colors-bg-primary));\n border: 1px solid\n var(--nile-wysiwyg-border-color, var(--nile-colors-neutral-400, var(--ng-colors-border-primary)));\n border-radius: var(--nile-wysiwyg-radius, 8px);\n box-shadow: var(\n --nile-wysiwyg-popover-shadow,\n 0 4px 12px rgba(16, 24, 40, 0.12)\n );\n font-size: 13px;\n }\n\n label {\n display: flex;\n flex-direction: column;\n gap: 4px;\n color: var(--nile-colors-neutral-700, var(--ng-colors-text-secondary-700));\n }\n\n input {\n font: inherit;\n padding: 6px 8px;\n border: 1px solid var(--nile-colors-neutral-400, var(--ng-colors-border-primary));\n border-radius: 6px;\n outline: none;\n }\n\n input:focus {\n border-color: var(--nile-colors-primary-600, var(--ng-componentcolors-utility-blue-600));\n }\n\n .link-editor__actions {\n display: flex;\n gap: 8px;\n justify-content: flex-end;\n }\n\n button {\n font: inherit;\n padding: 6px 12px;\n border-radius: 6px;\n border: 1px solid transparent;\n cursor: pointer;\n background: transparent;\n color: var(--nile-colors-neutral-700, var(--ng-colors-text-secondary-700));\n }\n\n button.primary {\n background: var(--nile-colors-primary-600, var(--ng-componentcolors-utility-blue-600));\n color: var(--ng-colors-text-white);\n }\n\n button.danger {\n color: var(--nile-colors-error-600, var(--ng-componentcolors-utility-error-600));\n }\n `,\n ];\n }\n\n /** Focuses the URL field; called by the host after opening. */\n public focusInput(): void {\n this.updateComplete.then(() => this.hrefInput?.focus());\n }\n\n private handleSubmit(event: Event): void {\n event.preventDefault();\n const href = this.hrefInput?.value.trim() ?? '';\n if (!href) return;\n const textInput = this.shadowRoot?.querySelector<HTMLInputElement>('.link-editor__text');\n this.emit('wysiwyg-link-apply', { href, text: textInput?.value.trim() ?? '' });\n }\n\n private handleKeydown(event: KeyboardEvent): void {\n if (event.key === 'Escape') {\n event.stopPropagation();\n this.emit('wysiwyg-link-cancel');\n }\n }\n\n public render(): TemplateResult {\n return html`\n <form\n class=\"link-editor\"\n part=\"link-editor\"\n @submit=${this.handleSubmit}\n @keydown=${this.handleKeydown}\n >\n <label>\n URL\n <input\n class=\"link-editor__href\"\n type=\"url\"\n placeholder=\"https://\"\n .value=${this.href}\n />\n </label>\n ${this.allowText\n ? html`\n <label>\n Text\n <input class=\"link-editor__text\" type=\"text\" .value=${this.text} />\n </label>\n `\n : nothing}\n <div class=\"link-editor__actions\">\n ${this.canRemove\n ? html`\n <button\n type=\"button\"\n class=\"danger\"\n @click=${() => this.emit('wysiwyg-link-remove')}\n >\n Remove\n </button>\n `\n : nothing}\n <button type=\"button\" @click=${() => this.emit('wysiwyg-link-cancel')}>\n Cancel\n </button>\n <button type=\"submit\" class=\"primary\">Apply</button>\n </div>\n </form>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'nile-wysiwyg-link-editor': NileWysiwygLinkEditor;\n }\n}\n"]}
1
+ {"version":3,"file":"link-editor.js","sourceRoot":"","sources":["../../../../src/nile-wysiwyg-editor/ui/link-editor.ts"],"names":[],"mappings":"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","sourcesContent":["import { html, css, TemplateResult, CSSResultArray, nothing } from 'lit';\nimport { customElement, property, query } from 'lit/decorators.js';\nimport NileElement from '../../internal/nile-element';\n\n/**\n * Floating link create/edit panel. The host positions it absolutely inside\n * the editor chrome and listens for:\n * - `wysiwyg-link-apply` detail: { href, text }\n * - `wysiwyg-link-remove`\n * - `wysiwyg-link-cancel`\n */\n@customElement('nile-wysiwyg-link-editor')\nexport class NileWysiwygLinkEditor extends NileElement {\n @property({ type: Boolean, reflect: true }) open = false;\n\n @property({ type: String }) href = '';\n\n @property({ type: String }) text = '';\n\n /** Show the text field (only when creating a link from a cursor). */\n @property({ type: Boolean }) allowText = false;\n\n /** Show the remove button (when editing an existing link). */\n @property({ type: Boolean }) canRemove = false;\n\n @query('.link-editor__href') hrefInput?: HTMLInputElement;\n\n public static get styles(): CSSResultArray {\n return [\n css`\n :host {\n font-family: var(\n --nile-font-family-sans-serif,\n var(--ng-font-family-body, system-ui, -apple-system, sans-serif)\n );\n position: absolute;\n z-index: 20;\n display: none;\n }\n\n :host([open]) {\n display: block;\n }\n\n .link-editor {\n display: flex;\n flex-direction: column;\n gap: 8px;\n min-width: 280px;\n padding: 12px;\n background: var(--nile-wysiwyg-popover-bg, var(--nile-colors-white-base, var(--ng-colors-bg-primary)));\n border: 1px solid\n var(--nile-wysiwyg-border-color, var(--nile-colors-neutral-400, var(--ng-colors-border-primary)));\n border-radius: var(--nile-wysiwyg-radius, 8px);\n box-shadow: var(\n --nile-wysiwyg-popover-shadow,\n 0 4px 12px rgba(16, 24, 40, 0.12)\n );\n font-size: 13px;\n }\n\n label {\n display: flex;\n flex-direction: column;\n gap: 4px;\n color: var(--nile-colors-neutral-700, var(--ng-colors-text-secondary-700));\n }\n\n input {\n font: inherit;\n padding: 6px 8px;\n border: 1px solid var(--nile-colors-neutral-400, var(--ng-colors-border-primary));\n border-radius: 6px;\n outline: none;\n }\n\n input:focus {\n border-color: var(--nile-colors-primary-600, var(--ng-componentcolors-utility-blue-600));\n }\n\n .link-editor__actions {\n display: flex;\n gap: 8px;\n justify-content: flex-end;\n }\n\n button {\n font: inherit;\n padding: 6px 12px;\n border-radius: 6px;\n border: 1px solid transparent;\n cursor: pointer;\n background: transparent;\n color: var(--nile-colors-neutral-700, var(--ng-colors-text-secondary-700));\n }\n\n button.primary {\n background: var(--nile-colors-primary-600, var(--ng-componentcolors-utility-blue-600));\n color: var(--nile-colors-white-base, var(--ng-colors-text-white));\n }\n\n button.danger {\n color: var(--nile-colors-error-600, var(--ng-componentcolors-utility-error-600));\n }\n `,\n ];\n }\n\n /** Focuses the URL field; called by the host after opening. */\n public focusInput(): void {\n this.updateComplete.then(() => this.hrefInput?.focus());\n }\n\n private handleSubmit(event: Event): void {\n event.preventDefault();\n const href = this.hrefInput?.value.trim() ?? '';\n if (!href) return;\n const textInput = this.shadowRoot?.querySelector<HTMLInputElement>('.link-editor__text');\n this.emit('wysiwyg-link-apply', { href, text: textInput?.value.trim() ?? '' });\n }\n\n private handleKeydown(event: KeyboardEvent): void {\n if (event.key === 'Escape') {\n event.stopPropagation();\n this.emit('wysiwyg-link-cancel');\n }\n }\n\n public render(): TemplateResult {\n return html`\n <form\n class=\"link-editor\"\n part=\"link-editor\"\n @submit=${this.handleSubmit}\n @keydown=${this.handleKeydown}\n >\n <label>\n URL\n <input\n class=\"link-editor__href\"\n type=\"url\"\n placeholder=\"https://\"\n .value=${this.href}\n />\n </label>\n ${this.allowText\n ? html`\n <label>\n Text\n <input class=\"link-editor__text\" type=\"text\" .value=${this.text} />\n </label>\n `\n : nothing}\n <div class=\"link-editor__actions\">\n ${this.canRemove\n ? html`\n <button\n type=\"button\"\n class=\"danger\"\n @click=${() => this.emit('wysiwyg-link-remove')}\n >\n Remove\n </button>\n `\n : nothing}\n <button type=\"button\" @click=${() => this.emit('wysiwyg-link-cancel')}>\n Cancel\n </button>\n <button type=\"submit\" class=\"primary\">Apply</button>\n </div>\n </form>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'nile-wysiwyg-link-editor': NileWysiwygLinkEditor;\n }\n}\n"]}
@@ -38,7 +38,7 @@ let NileWysiwygMarkdownPanel = class NileWysiwygMarkdownPanel extends NileElemen
38
38
  width: 460px;
39
39
  max-width: 90vw;
40
40
  padding: 14px;
41
- background: var(--nile-wysiwyg-popover-bg, var(--ng-colors-bg-primary));
41
+ background: var(--nile-wysiwyg-popover-bg, var(--nile-colors-white-base, var(--ng-colors-bg-primary)));
42
42
  border: 1px solid var(--nile-colors-neutral-400, var(--ng-colors-border-primary));
43
43
  border-radius: 8px;
44
44
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);