snice 4.13.0 → 4.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (253) hide show
  1. package/dist/cdn/accordion/snice-accordion.js +1 -1
  2. package/dist/cdn/accordion/snice-accordion.min.js +1 -1
  3. package/dist/cdn/alert/snice-alert.js +1 -1
  4. package/dist/cdn/alert/snice-alert.min.js +1 -1
  5. package/dist/cdn/app-tiles/snice-app-tiles.js +1 -1
  6. package/dist/cdn/app-tiles/snice-app-tiles.min.js +1 -1
  7. package/dist/cdn/audio-recorder/snice-audio-recorder.js +1 -1
  8. package/dist/cdn/audio-recorder/snice-audio-recorder.min.js +1 -1
  9. package/dist/cdn/avatar/snice-avatar.js +1 -1
  10. package/dist/cdn/avatar/snice-avatar.min.js +1 -1
  11. package/dist/cdn/badge/snice-badge.js +1 -1
  12. package/dist/cdn/badge/snice-badge.min.js +1 -1
  13. package/dist/cdn/banner/snice-banner.js +1 -1
  14. package/dist/cdn/banner/snice-banner.min.js +1 -1
  15. package/dist/cdn/book/snice-book.js +1 -1
  16. package/dist/cdn/book/snice-book.min.js +1 -1
  17. package/dist/cdn/breadcrumbs/snice-breadcrumbs.js +1 -1
  18. package/dist/cdn/breadcrumbs/snice-breadcrumbs.min.js +1 -1
  19. package/dist/cdn/button/snice-button.js +1 -1
  20. package/dist/cdn/button/snice-button.min.js +1 -1
  21. package/dist/cdn/calendar/snice-calendar.js +1 -1
  22. package/dist/cdn/calendar/snice-calendar.min.js +1 -1
  23. package/dist/cdn/camera/snice-camera.js +1 -1
  24. package/dist/cdn/camera/snice-camera.min.js +1 -1
  25. package/dist/cdn/camera-annotate/snice-camera-annotate.js +1 -1
  26. package/dist/cdn/camera-annotate/snice-camera-annotate.min.js +1 -1
  27. package/dist/cdn/candlestick/snice-candlestick.js +1 -1
  28. package/dist/cdn/candlestick/snice-candlestick.min.js +1 -1
  29. package/dist/cdn/card/snice-card.js +1 -1
  30. package/dist/cdn/card/snice-card.min.js +1 -1
  31. package/dist/cdn/carousel/snice-carousel.js +1 -1
  32. package/dist/cdn/carousel/snice-carousel.min.js +1 -1
  33. package/dist/cdn/chart/snice-chart.js +1 -1
  34. package/dist/cdn/chart/snice-chart.min.js +1 -1
  35. package/dist/cdn/chat/snice-chat.js +1 -1
  36. package/dist/cdn/chat/snice-chat.min.js +1 -1
  37. package/dist/cdn/checkbox/snice-checkbox.js +1 -1
  38. package/dist/cdn/checkbox/snice-checkbox.min.js +1 -1
  39. package/dist/cdn/chip/snice-chip.js +1 -1
  40. package/dist/cdn/chip/snice-chip.min.js +1 -1
  41. package/dist/cdn/code-block/snice-code-block.js +2 -2
  42. package/dist/cdn/code-block/snice-code-block.js.map +1 -1
  43. package/dist/cdn/code-block/snice-code-block.min.js +2 -2
  44. package/dist/cdn/code-block/snice-code-block.min.js.map +1 -1
  45. package/dist/cdn/color-display/snice-color-display.js +1 -1
  46. package/dist/cdn/color-display/snice-color-display.min.js +1 -1
  47. package/dist/cdn/color-picker/snice-color-picker.js +1 -1
  48. package/dist/cdn/color-picker/snice-color-picker.min.js +1 -1
  49. package/dist/cdn/command-palette/snice-command-palette.js +1 -1
  50. package/dist/cdn/command-palette/snice-command-palette.min.js +1 -1
  51. package/dist/cdn/comments/snice-comments.js +1 -1
  52. package/dist/cdn/comments/snice-comments.min.js +1 -1
  53. package/dist/cdn/countdown/snice-countdown.js +1 -1
  54. package/dist/cdn/countdown/snice-countdown.min.js +1 -1
  55. package/dist/cdn/cropper/snice-cropper.js +1 -1
  56. package/dist/cdn/cropper/snice-cropper.min.js +1 -1
  57. package/dist/cdn/date-picker/snice-date-picker.js +1 -1
  58. package/dist/cdn/date-picker/snice-date-picker.min.js +1 -1
  59. package/dist/cdn/diff/snice-diff.js +1 -1
  60. package/dist/cdn/diff/snice-diff.min.js +1 -1
  61. package/dist/cdn/divider/snice-divider.js +1 -1
  62. package/dist/cdn/divider/snice-divider.min.js +1 -1
  63. package/dist/cdn/doc/snice-doc.js +1 -1
  64. package/dist/cdn/doc/snice-doc.min.js +1 -1
  65. package/dist/cdn/draw/snice-draw.js +1 -1
  66. package/dist/cdn/draw/snice-draw.min.js +1 -1
  67. package/dist/cdn/drawer/snice-drawer.js +1 -1
  68. package/dist/cdn/drawer/snice-drawer.min.js +1 -1
  69. package/dist/cdn/empty-state/snice-empty-state.js +1 -1
  70. package/dist/cdn/empty-state/snice-empty-state.min.js +1 -1
  71. package/dist/cdn/file-gallery/snice-file-gallery.js +1 -1
  72. package/dist/cdn/file-gallery/snice-file-gallery.min.js +1 -1
  73. package/dist/cdn/file-upload/snice-file-upload.js +1 -1
  74. package/dist/cdn/file-upload/snice-file-upload.min.js +1 -1
  75. package/dist/cdn/flip-card/snice-flip-card.js +1 -1
  76. package/dist/cdn/flip-card/snice-flip-card.min.js +1 -1
  77. package/dist/cdn/flow/snice-flow.js +1 -1
  78. package/dist/cdn/flow/snice-flow.min.js +1 -1
  79. package/dist/cdn/funnel/snice-funnel.js +1 -1
  80. package/dist/cdn/funnel/snice-funnel.min.js +1 -1
  81. package/dist/cdn/gantt/snice-gantt.js +1 -1
  82. package/dist/cdn/gantt/snice-gantt.min.js +1 -1
  83. package/dist/cdn/gauge/snice-gauge.js +1 -1
  84. package/dist/cdn/gauge/snice-gauge.min.js +1 -1
  85. package/dist/cdn/heatmap/snice-heatmap.js +1 -1
  86. package/dist/cdn/heatmap/snice-heatmap.min.js +1 -1
  87. package/dist/cdn/image/snice-image.js +1 -1
  88. package/dist/cdn/image/snice-image.min.js +1 -1
  89. package/dist/cdn/input/snice-input.js +1 -1
  90. package/dist/cdn/input/snice-input.min.js +1 -1
  91. package/dist/cdn/kanban/snice-kanban.js +1 -1
  92. package/dist/cdn/kanban/snice-kanban.min.js +1 -1
  93. package/dist/cdn/kpi/snice-kpi.js +1 -1
  94. package/dist/cdn/kpi/snice-kpi.min.js +1 -1
  95. package/dist/cdn/layout/snice-layout.js +1 -1
  96. package/dist/cdn/layout/snice-layout.min.js +1 -1
  97. package/dist/cdn/link/snice-link.js +1 -1
  98. package/dist/cdn/link/snice-link.min.js +1 -1
  99. package/dist/cdn/link-preview/snice-link-preview.js +1 -1
  100. package/dist/cdn/link-preview/snice-link-preview.min.js +1 -1
  101. package/dist/cdn/list/snice-list.js +1 -1
  102. package/dist/cdn/list/snice-list.min.js +1 -1
  103. package/dist/cdn/location/snice-location.js +1 -1
  104. package/dist/cdn/location/snice-location.min.js +1 -1
  105. package/dist/cdn/login/snice-login.js +1 -1
  106. package/dist/cdn/login/snice-login.min.js +1 -1
  107. package/dist/cdn/map/snice-map.js +1 -1
  108. package/dist/cdn/map/snice-map.min.js +1 -1
  109. package/dist/cdn/markdown/snice-markdown.js +1 -1
  110. package/dist/cdn/markdown/snice-markdown.min.js +1 -1
  111. package/dist/cdn/masonry/snice-masonry.js +1 -1
  112. package/dist/cdn/masonry/snice-masonry.min.js +1 -1
  113. package/dist/cdn/menu/snice-menu.js +1 -1
  114. package/dist/cdn/menu/snice-menu.min.js +1 -1
  115. package/dist/cdn/modal/snice-modal.js +1 -1
  116. package/dist/cdn/modal/snice-modal.min.js +1 -1
  117. package/dist/cdn/music-player/snice-music-player.js +1 -1
  118. package/dist/cdn/music-player/snice-music-player.min.js +1 -1
  119. package/dist/cdn/nav/snice-nav.js +1 -1
  120. package/dist/cdn/nav/snice-nav.min.js +1 -1
  121. package/dist/cdn/network-graph/snice-network-graph.js +1 -1
  122. package/dist/cdn/network-graph/snice-network-graph.min.js +1 -1
  123. package/dist/cdn/notification-center/snice-notification-center.js +1 -1
  124. package/dist/cdn/notification-center/snice-notification-center.min.js +1 -1
  125. package/dist/cdn/org-chart/snice-org-chart.js +1 -1
  126. package/dist/cdn/org-chart/snice-org-chart.min.js +1 -1
  127. package/dist/cdn/pagination/snice-pagination.js +1 -1
  128. package/dist/cdn/pagination/snice-pagination.min.js +1 -1
  129. package/dist/cdn/paint/snice-paint.js +1 -1
  130. package/dist/cdn/paint/snice-paint.min.js +1 -1
  131. package/dist/cdn/pdf-viewer/snice-pdf-viewer.js +1 -1
  132. package/dist/cdn/pdf-viewer/snice-pdf-viewer.min.js +1 -1
  133. package/dist/cdn/podcast-player/snice-podcast-player.js +1 -1
  134. package/dist/cdn/podcast-player/snice-podcast-player.min.js +1 -1
  135. package/dist/cdn/pricing-table/snice-pricing-table.js +1 -1
  136. package/dist/cdn/pricing-table/snice-pricing-table.min.js +1 -1
  137. package/dist/cdn/progress/snice-progress.js +1 -1
  138. package/dist/cdn/progress/snice-progress.min.js +1 -1
  139. package/dist/cdn/qr-code/README.md +2 -2
  140. package/dist/cdn/qr-code/snice-qr-code.js +149 -20
  141. package/dist/cdn/qr-code/snice-qr-code.js.map +1 -1
  142. package/dist/cdn/qr-code/snice-qr-code.min.js +3 -3
  143. package/dist/cdn/qr-code/snice-qr-code.min.js.map +1 -1
  144. package/dist/cdn/qr-reader/snice-qr-reader.js +1 -1
  145. package/dist/cdn/qr-reader/snice-qr-reader.min.js +1 -1
  146. package/dist/cdn/radio/snice-radio.js +1 -1
  147. package/dist/cdn/radio/snice-radio.min.js +1 -1
  148. package/dist/cdn/rating/snice-rating.js +1 -1
  149. package/dist/cdn/rating/snice-rating.min.js +1 -1
  150. package/dist/cdn/recipe/snice-recipe.js +1 -1
  151. package/dist/cdn/recipe/snice-recipe.min.js +1 -1
  152. package/dist/cdn/runtime/snice-runtime.esm.js +4 -4
  153. package/dist/cdn/runtime/snice-runtime.esm.js.map +1 -1
  154. package/dist/cdn/runtime/snice-runtime.esm.min.js +3 -3
  155. package/dist/cdn/runtime/snice-runtime.esm.min.js.map +1 -1
  156. package/dist/cdn/runtime/snice-runtime.js +4 -4
  157. package/dist/cdn/runtime/snice-runtime.js.map +1 -1
  158. package/dist/cdn/runtime/snice-runtime.min.js +3 -3
  159. package/dist/cdn/runtime/snice-runtime.min.js.map +1 -1
  160. package/dist/cdn/sankey/snice-sankey.js +1 -1
  161. package/dist/cdn/sankey/snice-sankey.min.js +1 -1
  162. package/dist/cdn/select/snice-select.js +1 -1
  163. package/dist/cdn/select/snice-select.min.js +1 -1
  164. package/dist/cdn/skeleton/snice-skeleton.js +1 -1
  165. package/dist/cdn/skeleton/snice-skeleton.min.js +1 -1
  166. package/dist/cdn/slider/snice-slider.js +2 -2
  167. package/dist/cdn/slider/snice-slider.js.map +1 -1
  168. package/dist/cdn/slider/snice-slider.min.js +5 -5
  169. package/dist/cdn/slider/snice-slider.min.js.map +1 -1
  170. package/dist/cdn/sortable/snice-sortable.js +1 -1
  171. package/dist/cdn/sortable/snice-sortable.min.js +1 -1
  172. package/dist/cdn/sparkline/snice-sparkline.js +1 -1
  173. package/dist/cdn/sparkline/snice-sparkline.min.js +1 -1
  174. package/dist/cdn/spinner/snice-spinner.js +1 -1
  175. package/dist/cdn/spinner/snice-spinner.min.js +1 -1
  176. package/dist/cdn/split-pane/snice-split-pane.js +1 -1
  177. package/dist/cdn/split-pane/snice-split-pane.min.js +1 -1
  178. package/dist/cdn/spotlight/snice-spotlight.js +1 -1
  179. package/dist/cdn/spotlight/snice-spotlight.min.js +1 -1
  180. package/dist/cdn/spreadsheet/snice-spreadsheet.js +1 -1
  181. package/dist/cdn/spreadsheet/snice-spreadsheet.min.js +1 -1
  182. package/dist/cdn/stepper/snice-stepper.js +1 -1
  183. package/dist/cdn/stepper/snice-stepper.min.js +1 -1
  184. package/dist/cdn/switch/snice-switch.js +1 -1
  185. package/dist/cdn/switch/snice-switch.min.js +1 -1
  186. package/dist/cdn/table/snice-table.js +1 -1
  187. package/dist/cdn/table/snice-table.min.js +1 -1
  188. package/dist/cdn/tabs/snice-tabs.js +1 -1
  189. package/dist/cdn/tabs/snice-tabs.min.js +1 -1
  190. package/dist/cdn/tag-input/snice-tag-input.js +1 -1
  191. package/dist/cdn/tag-input/snice-tag-input.min.js +1 -1
  192. package/dist/cdn/terminal/snice-terminal.js +1 -1
  193. package/dist/cdn/terminal/snice-terminal.min.js +1 -1
  194. package/dist/cdn/testimonial/snice-testimonial.js +1 -1
  195. package/dist/cdn/testimonial/snice-testimonial.min.js +1 -1
  196. package/dist/cdn/textarea/snice-textarea.js +1 -1
  197. package/dist/cdn/textarea/snice-textarea.min.js +1 -1
  198. package/dist/cdn/time-range-picker/snice-time-range-picker.js +1 -1
  199. package/dist/cdn/time-range-picker/snice-time-range-picker.min.js +1 -1
  200. package/dist/cdn/timeline/snice-timeline.js +1 -1
  201. package/dist/cdn/timeline/snice-timeline.min.js +1 -1
  202. package/dist/cdn/timer/snice-timer.js +1 -1
  203. package/dist/cdn/timer/snice-timer.min.js +1 -1
  204. package/dist/cdn/toast/snice-toast.js +1 -1
  205. package/dist/cdn/toast/snice-toast.min.js +1 -1
  206. package/dist/cdn/tooltip/snice-tooltip.js +1 -1
  207. package/dist/cdn/tooltip/snice-tooltip.min.js +1 -1
  208. package/dist/cdn/tree/snice-tree.js +1 -1
  209. package/dist/cdn/tree/snice-tree.min.js +1 -1
  210. package/dist/cdn/treemap/snice-treemap.js +1 -1
  211. package/dist/cdn/treemap/snice-treemap.min.js +1 -1
  212. package/dist/cdn/video-player/snice-video-player.js +1 -1
  213. package/dist/cdn/video-player/snice-video-player.min.js +1 -1
  214. package/dist/cdn/virtual-scroller/snice-virtual-scroller.js +1 -1
  215. package/dist/cdn/virtual-scroller/snice-virtual-scroller.min.js +1 -1
  216. package/dist/cdn/waterfall/snice-waterfall.js +1 -1
  217. package/dist/cdn/waterfall/snice-waterfall.min.js +1 -1
  218. package/dist/cdn/weather/snice-weather.js +1 -1
  219. package/dist/cdn/weather/snice-weather.min.js +1 -1
  220. package/dist/components/code-block/snice-code-block.js +1 -1
  221. package/dist/components/code-block/snice-code-block.js.map +1 -1
  222. package/dist/components/qr-code/qrcode.d.ts +1 -0
  223. package/dist/components/qr-code/qrcode.js +16 -8
  224. package/dist/components/qr-code/qrcode.js.map +1 -1
  225. package/dist/components/qr-code/snice-qr-code.d.ts +5 -2
  226. package/dist/components/qr-code/snice-qr-code.js +132 -11
  227. package/dist/components/qr-code/snice-qr-code.js.map +1 -1
  228. package/dist/components/qr-code/snice-qr-code.types.d.ts +3 -2
  229. package/dist/components/slider/snice-slider.js +1 -1
  230. package/dist/components/slider/snice-slider.js.map +1 -1
  231. package/dist/index.cjs +2 -2
  232. package/dist/index.esm.js +2 -2
  233. package/dist/index.iife.js +2 -2
  234. package/dist/symbols.cjs +1 -1
  235. package/dist/symbols.esm.js +1 -1
  236. package/dist/transitions.cjs +1 -1
  237. package/dist/transitions.esm.js +1 -1
  238. package/dist/types/request-options.d.ts +1 -1
  239. package/docs/ai/api.md +1 -1
  240. package/docs/ai/components/code-block.md +1 -1
  241. package/docs/ai/decorators.md +2 -2
  242. package/docs/ai/patterns.md +17 -6
  243. package/docs/code-block.md +1 -3
  244. package/docs/controllers.md +98 -391
  245. package/docs/elements.md +131 -117
  246. package/docs/events.md +74 -83
  247. package/docs/fetcher.md +64 -76
  248. package/docs/observe.md +13 -33
  249. package/docs/placards.md +6 -16
  250. package/docs/request-response.md +171 -693
  251. package/docs/routing.md +67 -136
  252. package/package.json +1 -1
  253. package/docs/migration-v2-to-v3.md +0 -569
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * snice v4.12.0
2
+ * snice v4.13.0
3
3
  * Imperative TypeScript framework for building vanilla web components with decorators, differential rendering, routing, and controllers. No virtual DOM, no build complexity.
4
4
  * (c) 2024
5
5
  * Released under the MIT License.
@@ -800,9 +800,11 @@ var SniceQrCode = (function (exports, snice) {
800
800
  draw(qrCode) {
801
801
  const opts = this.options;
802
802
  const nCount = qrCode.getModuleCount();
803
+ const margin = opts.margin || 0;
804
+ const totalSize = nCount + margin * 2;
803
805
  this.clear();
804
806
  const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
805
- svg.setAttribute('viewBox', `0 0 ${nCount} ${nCount}`);
807
+ svg.setAttribute('viewBox', `0 0 ${totalSize} ${totalSize}`);
806
808
  svg.setAttribute('width', '100%');
807
809
  svg.setAttribute('height', '100%');
808
810
  svg.setAttribute('fill', opts.colorLight);
@@ -823,8 +825,8 @@ var SniceQrCode = (function (exports, snice) {
823
825
  for (let col = 0; col < nCount; col++) {
824
826
  if (qrCode.isDark(row, col)) {
825
827
  const use = this.createSVGElement('use', {
826
- x: String(col),
827
- y: String(row)
828
+ x: String(margin + col),
829
+ y: String(margin + row)
828
830
  });
829
831
  use.setAttributeNS('http://www.w3.org/1999/xlink', 'href', '#template');
830
832
  svg.appendChild(use);
@@ -870,17 +872,22 @@ var SniceQrCode = (function (exports, snice) {
870
872
  return;
871
873
  const opts = this.options;
872
874
  const ctx = this.context;
875
+ const margin = opts.margin || 0;
873
876
  const nCount = qrCode.getModuleCount();
874
- const nWidth = opts.width / nCount;
875
- const nHeight = opts.height / nCount;
877
+ const drawSize = Math.min(opts.width, opts.height) - margin * 2;
878
+ const nWidth = drawSize / nCount;
879
+ const nHeight = drawSize / nCount;
876
880
  const nRoundedWidth = Math.round(nWidth);
877
881
  const nRoundedHeight = Math.round(nHeight);
878
882
  this.clear();
883
+ // Fill background including quiet zone
884
+ ctx.fillStyle = opts.colorLight;
885
+ ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
879
886
  for (let row = 0; row < nCount; row++) {
880
887
  for (let col = 0; col < nCount; col++) {
881
888
  const bIsDark = qrCode.isDark(row, col);
882
- const nLeft = col * nWidth;
883
- const nTop = row * nHeight;
889
+ const nLeft = margin + col * nWidth;
890
+ const nTop = margin + row * nHeight;
884
891
  const color = bIsDark ? opts.colorDark : opts.colorLight;
885
892
  ctx.fillStyle = color;
886
893
  if (opts.dotStyle === 'dots') {
@@ -944,7 +951,8 @@ var SniceQrCode = (function (exports, snice) {
944
951
  colorLight: '#ffffff',
945
952
  correctLevel: 'H',
946
953
  useSVG: false,
947
- dotStyle: 'square'
954
+ dotStyle: 'square',
955
+ margin: 4
948
956
  };
949
957
  let opts = vOption;
950
958
  if (typeof opts === 'string') {
@@ -1153,7 +1161,8 @@ var SniceQrCode = (function (exports, snice) {
1153
1161
  colorLight: this.bgColor,
1154
1162
  correctLevel: correctLevel,
1155
1163
  useSVG: this.renderMode === 'svg',
1156
- dotStyle: this.dotStyle
1164
+ dotStyle: this.dotStyle,
1165
+ margin: this.margin
1157
1166
  });
1158
1167
  // Apply overlays after QR code is rendered
1159
1168
  requestAnimationFrame(() => {
@@ -1161,7 +1170,11 @@ var SniceQrCode = (function (exports, snice) {
1161
1170
  });
1162
1171
  }
1163
1172
  applyOverlays() {
1164
- // Find the canvas element created by the library
1173
+ const svg = this.container?.querySelector('svg');
1174
+ if (svg) {
1175
+ this.applySvgOverlays(svg);
1176
+ return;
1177
+ }
1165
1178
  const canvas = this.container?.querySelector('canvas');
1166
1179
  if (!canvas)
1167
1180
  return;
@@ -1170,11 +1183,24 @@ var SniceQrCode = (function (exports, snice) {
1170
1183
  ctx = canvas.getContext('2d');
1171
1184
  }
1172
1185
  catch (e) {
1173
- // Canvas not supported in test environment
1174
1186
  return;
1175
1187
  }
1176
1188
  if (!ctx)
1177
1189
  return;
1190
+ // Apply quiet zone margin by re-drawing canvas content inset
1191
+ const m = this.margin;
1192
+ if (m > 0) {
1193
+ const s = this.size;
1194
+ const inner = s - m * 2;
1195
+ const imgData = ctx.getImageData(0, 0, s, s);
1196
+ const off = document.createElement('canvas');
1197
+ off.width = s;
1198
+ off.height = s;
1199
+ off.getContext('2d').putImageData(imgData, 0, 0);
1200
+ ctx.fillStyle = this.bgColor;
1201
+ ctx.fillRect(0, 0, s, s);
1202
+ ctx.drawImage(off, 0, 0, s, s, m, m, inner, inner);
1203
+ }
1178
1204
  // Center image overlay
1179
1205
  if (this.includeImage && this.imageUrl) {
1180
1206
  const img = new Image();
@@ -1183,9 +1209,7 @@ var SniceQrCode = (function (exports, snice) {
1183
1209
  const imgSize = this.imageSize;
1184
1210
  const imgX = (this.size - imgSize) / 2;
1185
1211
  const imgY = (this.size - imgSize) / 2;
1186
- // Draw image directly without background
1187
1212
  ctx.drawImage(img, imgX, imgY, imgSize, imgSize);
1188
- // Apply center text after image if both are present
1189
1213
  if (this.centerText) {
1190
1214
  this.drawCenterText(ctx);
1191
1215
  }
@@ -1193,39 +1217,144 @@ var SniceQrCode = (function (exports, snice) {
1193
1217
  img.src = this.imageUrl;
1194
1218
  }
1195
1219
  else if (this.centerText) {
1196
- // Center text overlay only
1197
1220
  this.drawCenterText(ctx);
1198
1221
  }
1199
1222
  }
1223
+ applySvgOverlays(svg) {
1224
+ // Get viewBox dimensions to position overlays in SVG coordinate space
1225
+ const vb = svg.getAttribute('viewBox')?.split(' ').map(Number) || [];
1226
+ const vbSize = vb[2] || 100;
1227
+ const center = vbSize / 2;
1228
+ // Scale factor: SVG viewBox units per pixel
1229
+ const scale = vbSize / this.size;
1230
+ // Center image overlay
1231
+ if (this.includeImage && this.imageUrl) {
1232
+ const imgSize = this.imageSize * scale;
1233
+ const imgX = center - imgSize / 2;
1234
+ const imgY = center - imgSize / 2;
1235
+ // Convert image to data URL for embedding in SVG
1236
+ const img = new Image();
1237
+ img.crossOrigin = 'anonymous';
1238
+ img.onload = () => {
1239
+ // Draw to temp canvas to get data URL
1240
+ const off = document.createElement('canvas');
1241
+ off.width = img.naturalWidth;
1242
+ off.height = img.naturalHeight;
1243
+ off.getContext('2d').drawImage(img, 0, 0);
1244
+ const dataUrl = off.toDataURL('image/png');
1245
+ const svgImg = document.createElementNS('http://www.w3.org/2000/svg', 'image');
1246
+ svgImg.setAttribute('x', String(imgX));
1247
+ svgImg.setAttribute('y', String(imgY));
1248
+ svgImg.setAttribute('width', String(imgSize));
1249
+ svgImg.setAttribute('height', String(imgSize));
1250
+ svgImg.setAttributeNS('http://www.w3.org/1999/xlink', 'href', dataUrl);
1251
+ svg.appendChild(svgImg);
1252
+ if (this.centerText) {
1253
+ this.drawSvgCenterText(svg, center, scale);
1254
+ }
1255
+ };
1256
+ img.src = this.imageUrl;
1257
+ }
1258
+ else if (this.centerText) {
1259
+ this.drawSvgCenterText(svg, center, scale);
1260
+ }
1261
+ }
1262
+ drawSvgCenterText(svg, center, scale) {
1263
+ const fontSize = this.centerTextSize * scale;
1264
+ const strokeWidth = 6 * scale;
1265
+ // Outline text
1266
+ const outline = document.createElementNS('http://www.w3.org/2000/svg', 'text');
1267
+ outline.setAttribute('x', String(center));
1268
+ outline.setAttribute('y', String(center));
1269
+ outline.setAttribute('text-anchor', 'middle');
1270
+ outline.setAttribute('dominant-baseline', 'central');
1271
+ outline.setAttribute('font-size', String(fontSize));
1272
+ outline.setAttribute('font-weight', 'bold');
1273
+ outline.setAttribute('font-family', 'sans-serif');
1274
+ outline.setAttribute('stroke', this.textOutlineColor);
1275
+ outline.setAttribute('stroke-width', String(strokeWidth));
1276
+ outline.setAttribute('stroke-linejoin', 'round');
1277
+ outline.setAttribute('fill', this.textOutlineColor);
1278
+ outline.textContent = this.centerText;
1279
+ svg.appendChild(outline);
1280
+ // Fill text
1281
+ const fill = document.createElementNS('http://www.w3.org/2000/svg', 'text');
1282
+ fill.setAttribute('x', String(center));
1283
+ fill.setAttribute('y', String(center));
1284
+ fill.setAttribute('text-anchor', 'middle');
1285
+ fill.setAttribute('dominant-baseline', 'central');
1286
+ fill.setAttribute('font-size', String(fontSize));
1287
+ fill.setAttribute('font-weight', 'bold');
1288
+ fill.setAttribute('font-family', 'sans-serif');
1289
+ fill.setAttribute('fill', this.textFillColor);
1290
+ fill.textContent = this.centerText;
1291
+ svg.appendChild(fill);
1292
+ }
1200
1293
  drawCenterText(ctx) {
1201
1294
  ctx.font = `bold ${this.centerTextSize}px sans-serif`;
1202
1295
  ctx.textAlign = 'center';
1203
1296
  ctx.textBaseline = 'middle';
1204
1297
  const x = this.size / 2;
1205
1298
  const y = this.size / 2;
1206
- // Draw text outline (stroke)
1207
1299
  ctx.strokeStyle = this.textOutlineColor;
1208
1300
  ctx.lineWidth = 6;
1209
1301
  ctx.lineJoin = 'round';
1210
1302
  ctx.miterLimit = 2;
1211
1303
  ctx.strokeText(this.centerText, x, y);
1212
- // Draw text fill
1213
1304
  ctx.fillStyle = this.textFillColor;
1214
1305
  ctx.fillText(this.centerText, x, y);
1215
1306
  }
1307
+ toSVGString() {
1308
+ const svg = this.container?.querySelector('svg');
1309
+ if (!svg)
1310
+ return '';
1311
+ return new XMLSerializer().serializeToString(svg);
1312
+ }
1216
1313
  async toDataURL(type = 'image/png', quality = 0.92) {
1314
+ // SVG export
1315
+ if (type === 'image/svg+xml') {
1316
+ const svgStr = this.toSVGString();
1317
+ if (!svgStr)
1318
+ return '';
1319
+ return 'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(svgStr);
1320
+ }
1321
+ // Canvas export (rasterize SVG if in SVG mode)
1217
1322
  const canvas = this.container?.querySelector('canvas');
1218
- if (!canvas)
1323
+ if (canvas)
1324
+ return canvas.toDataURL(type, quality);
1325
+ // SVG mode but raster export requested — rasterize to canvas
1326
+ const svg = this.container?.querySelector('svg');
1327
+ if (!svg)
1219
1328
  return '';
1220
- return canvas.toDataURL(type, quality);
1329
+ const svgStr = new XMLSerializer().serializeToString(svg);
1330
+ const blob = new Blob([svgStr], { type: 'image/svg+xml;charset=utf-8' });
1331
+ const url = URL.createObjectURL(blob);
1332
+ const img = new Image();
1333
+ return new Promise((resolve) => {
1334
+ img.onload = () => {
1335
+ const off = document.createElement('canvas');
1336
+ off.width = this.size;
1337
+ off.height = this.size;
1338
+ off.getContext('2d').drawImage(img, 0, 0, this.size, this.size);
1339
+ URL.revokeObjectURL(url);
1340
+ resolve(off.toDataURL(type, quality));
1341
+ };
1342
+ img.onerror = () => { URL.revokeObjectURL(url); resolve(''); };
1343
+ img.src = url;
1344
+ });
1221
1345
  }
1222
1346
  async toBlob(type = 'image/png', quality = 0.92) {
1347
+ if (type === 'image/svg+xml') {
1348
+ const svgStr = this.toSVGString();
1349
+ return new Blob([svgStr], { type: 'image/svg+xml;charset=utf-8' });
1350
+ }
1223
1351
  const dataURL = await this.toDataURL(type, quality);
1224
1352
  const response = await fetch(dataURL);
1225
1353
  return response.blob();
1226
1354
  }
1227
1355
  async download(filename = 'qr-code.png') {
1228
- const dataURL = await this.toDataURL();
1356
+ const isSvg = filename.endsWith('.svg');
1357
+ const dataURL = await this.toDataURL(isSvg ? 'image/svg+xml' : 'image/png');
1229
1358
  const a = document.createElement('a');
1230
1359
  a.href = dataURL;
1231
1360
  a.download = filename;