@nice2dev/ui-graphics 1.1.10 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. package/CHANGELOG.md +173 -0
  2. package/README.md +60 -63
  3. package/dist/cjs/animation/AnimationEditor.js +0 -3
  4. package/dist/cjs/animation/Audience.js +3 -1
  5. package/dist/cjs/animation/BodyRenderer.js +1 -4
  6. package/dist/cjs/animation/rig/RigPlayer.js +1 -1
  7. package/dist/cjs/animation/rig/presets.js +67 -55
  8. package/dist/cjs/animation/shapes/heads.js +0 -3
  9. package/dist/cjs/animation/shapes/headwear.js +4 -1
  10. package/dist/cjs/core/NiceBrushEngine.js +6 -6
  11. package/dist/cjs/core/editorAsk.js +48 -0
  12. package/dist/cjs/core/i18n.js +7 -3
  13. package/dist/cjs/core/plugins.js +1 -1
  14. package/dist/cjs/core/rtl.js +1 -1
  15. package/dist/cjs/core/theme.js +1 -1
  16. package/dist/cjs/font/NiceFontEditor.js +16 -14
  17. package/dist/cjs/game/GameAsset2dEditor.js +28 -19
  18. package/dist/cjs/index.js +0 -11
  19. package/dist/cjs/nice2dev-ui-graphics.css +1 -1
  20. package/dist/cjs/photo/FilterThumb.js +3 -3
  21. package/dist/cjs/photo/NiceAITools.js +7 -5
  22. package/dist/cjs/photo/PhotoEditor.js +3 -1
  23. package/dist/cjs/photo/PhotoEditorCanvas.js +8 -6
  24. package/dist/cjs/photo/PhotoEditorLeftPanel.js +19 -19
  25. package/dist/cjs/photo/PhotoEditorToolbar.js +5 -5
  26. package/dist/cjs/photo/photoFilters.js +1 -0
  27. package/dist/cjs/pixel/PixelEditor.js +6 -6
  28. package/dist/cjs/pixel/PixelEditor.module.css.js +1 -1
  29. package/dist/cjs/pixel/PixelEditorCanvas.js +10 -6
  30. package/dist/cjs/pixel/PixelEditorMenuBar.js +3 -3
  31. package/dist/cjs/pixel/PixelEditorRightPanel.js +28 -24
  32. package/dist/cjs/pixel/PixelEditorStatusBar.js +8 -4
  33. package/dist/cjs/pixel/PixelEditorTimeline.js +11 -2
  34. package/dist/cjs/pixel/PixelEditorToolbar.js +10 -6
  35. package/dist/cjs/pixel/SpriteGeneratorPanel.js +12 -8
  36. package/dist/cjs/pixel/animalGeneratorPresets.js +31 -31
  37. package/dist/cjs/pixel/buildingGeneratorPresets.js +24 -24
  38. package/dist/cjs/pixel/characterGeneratorPresets.js +25 -25
  39. package/dist/cjs/pixel/usePixelEditor.js +13 -10
  40. package/dist/cjs/texture/Nice3DTexturePainter.js +12 -10
  41. package/dist/cjs/ui/NiceUIDesigner.js +18 -14
  42. package/dist/cjs/vector/NiceSvgToCode.js +6 -4
  43. package/dist/cjs/vector/VectorEditor.js +3 -5
  44. package/dist/cjs/vector/VectorEditorShapeRenderer.js +3 -1
  45. package/dist/cjs/vector/useVectorEditor.js +38 -29
  46. package/dist/cjs/vector/vectorEditorImport.js +1 -0
  47. package/dist/cjs/vector/vectorIconImport.js +1 -0
  48. package/dist/esm/animation/AnimationEditor.js +1 -3
  49. package/dist/esm/animation/Audience.js +3 -1
  50. package/dist/esm/animation/BodyRenderer.js +3 -5
  51. package/dist/esm/animation/rig/RigPlayer.js +1 -1
  52. package/dist/esm/animation/rig/presets.js +68 -56
  53. package/dist/esm/animation/shapes/heads.js +1 -3
  54. package/dist/esm/animation/shapes/headwear.js +4 -1
  55. package/dist/esm/animation/spineExport.js +1 -1
  56. package/dist/esm/core/NiceBrushEngine.js +6 -6
  57. package/dist/esm/core/editorAsk.js +45 -0
  58. package/dist/esm/core/i18n.js +8 -4
  59. package/dist/esm/core/plugins.js +1 -1
  60. package/dist/esm/core/rtl.js +1 -1
  61. package/dist/esm/core/theme.js +1 -1
  62. package/dist/esm/font/NiceFontEditor.js +16 -14
  63. package/dist/esm/game/GameAsset2dEditor.js +29 -19
  64. package/dist/esm/index.js +10 -10
  65. package/dist/esm/nice2dev-ui-graphics.css +1 -1
  66. package/dist/esm/photo/FilterThumb.js +3 -3
  67. package/dist/esm/photo/NiceAITools.js +7 -5
  68. package/dist/esm/photo/PhotoEditor.js +3 -1
  69. package/dist/esm/photo/PhotoEditorCanvas.js +8 -6
  70. package/dist/esm/photo/PhotoEditorLeftPanel.js +19 -19
  71. package/dist/esm/photo/PhotoEditorToolbar.js +5 -5
  72. package/dist/esm/photo/photoFilters.js +1 -0
  73. package/dist/esm/pixel/PixelEditor.js +7 -6
  74. package/dist/esm/pixel/PixelEditor.module.css.js +1 -1
  75. package/dist/esm/pixel/PixelEditorCanvas.js +10 -6
  76. package/dist/esm/pixel/PixelEditorMenuBar.js +3 -3
  77. package/dist/esm/pixel/PixelEditorRightPanel.js +28 -24
  78. package/dist/esm/pixel/PixelEditorStatusBar.js +8 -4
  79. package/dist/esm/pixel/PixelEditorTimeline.js +11 -2
  80. package/dist/esm/pixel/PixelEditorToolbar.js +10 -6
  81. package/dist/esm/pixel/SpriteGeneratorPanel.js +12 -8
  82. package/dist/esm/pixel/animalGeneratorPresets.js +32 -32
  83. package/dist/esm/pixel/buildingGeneratorPresets.js +25 -25
  84. package/dist/esm/pixel/characterGeneratorPresets.js +26 -26
  85. package/dist/esm/pixel/usePixelEditor.js +13 -10
  86. package/dist/esm/texture/Nice3DTexturePainter.js +12 -10
  87. package/dist/esm/ui/NiceUIDesigner.js +18 -14
  88. package/dist/esm/vector/NiceSvgToCode.js +6 -4
  89. package/dist/esm/vector/VectorEditor.js +4 -5
  90. package/dist/esm/vector/VectorEditorShapeRenderer.js +3 -1
  91. package/dist/esm/vector/useVectorEditor.js +38 -29
  92. package/dist/esm/vector/vectorEditorImport.js +1 -0
  93. package/dist/esm/vector/vectorIconImport.js +1 -0
  94. package/dist/types/animation/AnimatedPerson.d.ts +0 -4
  95. package/dist/types/animation/AnimationEditor.d.ts +1 -5
  96. package/dist/types/animation/Audience.d.ts +0 -4
  97. package/dist/types/animation/BodyRenderer.d.ts +0 -4
  98. package/dist/types/animation/rig/RigPlayer.d.ts +0 -7
  99. package/dist/types/animation/rig/RiggedBody.d.ts +0 -4
  100. package/dist/types/animation/shapes/heads.d.ts +0 -4
  101. package/dist/types/core/LocalUI.d.ts +1 -2
  102. package/dist/types/core/editorAsk.d.ts +26 -0
  103. package/dist/types/core/i18n.d.ts +1 -17
  104. package/dist/types/game/GameAsset2dEditor.d.ts +0 -4
  105. package/dist/types/game/index.d.ts +1 -1
  106. package/dist/types/index.d.ts +9 -19
  107. package/dist/types/photo/index.d.ts +0 -2
  108. package/dist/types/pixel/PixelEditor.d.ts +0 -4
  109. package/dist/types/pixel/SpriteGeneratorPanel.d.ts +0 -4
  110. package/dist/types/pixel/usePixelEditor.d.ts +3 -0
  111. package/dist/types/vector/VectorEditor.d.ts +0 -4
  112. package/dist/types/vector/useVectorEditor.d.ts +2 -0
  113. package/package.json +5 -5
@@ -49,7 +49,7 @@ const CLOTHING_PALETTES = {
49
49
  16×16 CHARACTER PARTS — HEADS
50
50
  ════════════════════════════════════════════════════════════════ */
51
51
  const _ = -1; // transparent shorthand
52
- const HEAD_ROUND_S = spriteGeneratorCore.createPartData(8, 8, [
52
+ const HEAD_ROUND_S = /* @__PURE__ */ spriteGeneratorCore.createPartData(8, 8, [
53
53
  [_, _, 1, 1, 1, 1, _, _],
54
54
  [_, 1, 0, 0, 0, 0, 1, _],
55
55
  [1, 0, 0, 0, 0, 0, 0, 1],
@@ -59,7 +59,7 @@ const HEAD_ROUND_S = spriteGeneratorCore.createPartData(8, 8, [
59
59
  [_, 1, 0, 0, 0, 0, 1, _],
60
60
  [_, _, 1, 1, 1, 1, _, _],
61
61
  ], ['var(--nice-warning-bg, #ffecd2)', '#c07848', '#e05050', '#2a2a4e']);
62
- const HEAD_ROUND_E = spriteGeneratorCore.createPartData(7, 8, [
62
+ const HEAD_ROUND_E = /* @__PURE__ */ spriteGeneratorCore.createPartData(7, 8, [
63
63
  [_, _, 1, 1, 1, _, _],
64
64
  [_, 1, 0, 0, 0, 1, _],
65
65
  [1, 0, 0, 0, 0, 0, 1],
@@ -69,7 +69,7 @@ const HEAD_ROUND_E = spriteGeneratorCore.createPartData(7, 8, [
69
69
  [_, 1, 0, 0, 0, 1, _],
70
70
  [_, _, 1, 1, 1, _, _],
71
71
  ], ['var(--nice-warning-bg, #ffecd2)', '#c07848', '#e05050', '#2a2a4e']);
72
- const HEAD_ROUND_N = spriteGeneratorCore.createPartData(8, 8, [
72
+ const HEAD_ROUND_N = /* @__PURE__ */ spriteGeneratorCore.createPartData(8, 8, [
73
73
  [_, _, 1, 1, 1, 1, _, _],
74
74
  [_, 1, 0, 0, 0, 0, 1, _],
75
75
  [1, 0, 0, 0, 0, 0, 0, 1],
@@ -79,7 +79,7 @@ const HEAD_ROUND_N = spriteGeneratorCore.createPartData(8, 8, [
79
79
  [_, 1, 0, 0, 0, 0, 1, _],
80
80
  [_, _, 1, 1, 1, 1, _, _],
81
81
  ], ['var(--nice-warning-bg, #ffecd2)', '#c07848', '#e05050', '#2a2a4e']);
82
- const HEAD_SQUARE_S = spriteGeneratorCore.createPartData(8, 7, [
82
+ const HEAD_SQUARE_S = /* @__PURE__ */ spriteGeneratorCore.createPartData(8, 7, [
83
83
  [_, 1, 1, 1, 1, 1, 1, _],
84
84
  [1, 0, 0, 0, 0, 0, 0, 1],
85
85
  [1, 0, 3, 0, 0, 3, 0, 1],
@@ -88,7 +88,7 @@ const HEAD_SQUARE_S = spriteGeneratorCore.createPartData(8, 7, [
88
88
  [1, 0, 0, 0, 0, 0, 0, 1],
89
89
  [_, 1, 1, 1, 1, 1, 1, _],
90
90
  ], ['var(--nice-warning-bg, #ffecd2)', '#c07848', '#e05050', '#2a2a4e']);
91
- const HEAD_CHIBI_S = spriteGeneratorCore.createPartData(10, 10, [
91
+ const HEAD_CHIBI_S = /* @__PURE__ */ spriteGeneratorCore.createPartData(10, 10, [
92
92
  [_, _, _, 1, 1, 1, 1, _, _, _],
93
93
  [_, _, 1, 0, 0, 0, 0, 1, _, _],
94
94
  [_, 1, 0, 0, 0, 0, 0, 0, 1, _],
@@ -101,13 +101,13 @@ const HEAD_CHIBI_S = spriteGeneratorCore.createPartData(10, 10, [
101
101
  [_, _, 1, 1, 1, 1, 1, 1, _, _],
102
102
  ], ['var(--nice-warning-bg, #ffecd2)', '#c07848', '#e05050', '#2a2a4e']);
103
103
  /* ── HAIR ── */
104
- const HAIR_SHORT_S = spriteGeneratorCore.createPartData(8, 4, [
104
+ const HAIR_SHORT_S = /* @__PURE__ */ spriteGeneratorCore.createPartData(8, 4, [
105
105
  [_, _, 0, 0, 0, 0, _, _],
106
106
  [_, 0, 0, 0, 0, 0, 0, _],
107
107
  [0, 0, 1, 1, 1, 1, 0, 0],
108
108
  [0, 1, _, _, _, _, 1, 0],
109
109
  ], ['#4a3508', '#6b4e0a']);
110
- const HAIR_LONG_S = spriteGeneratorCore.createPartData(10, 10, [
110
+ const HAIR_LONG_S = /* @__PURE__ */ spriteGeneratorCore.createPartData(10, 10, [
111
111
  [_, _, _, 0, 0, 0, 0, _, _, _],
112
112
  [_, _, 0, 0, 0, 0, 0, 0, _, _],
113
113
  [_, 0, 0, 1, 1, 1, 1, 0, 0, _],
@@ -119,7 +119,7 @@ const HAIR_LONG_S = spriteGeneratorCore.createPartData(10, 10, [
119
119
  [_, 0, _, _, _, _, _, _, 0, _],
120
120
  [_, 0, 0, _, _, _, _, 0, 0, _],
121
121
  ], ['#4a3508', '#6b4e0a']);
122
- const HAIR_MOHAWK_S = spriteGeneratorCore.createPartData(8, 6, [
122
+ const HAIR_MOHAWK_S = /* @__PURE__ */ spriteGeneratorCore.createPartData(8, 6, [
123
123
  [_, _, _, 0, 0, _, _, _],
124
124
  [_, _, 0, 0, 0, 0, _, _],
125
125
  [_, _, 0, 0, 0, 0, _, _],
@@ -127,7 +127,7 @@ const HAIR_MOHAWK_S = spriteGeneratorCore.createPartData(8, 6, [
127
127
  [_, 0, 1, _, _, 1, 0, _],
128
128
  [0, 1, _, _, _, _, 1, 0],
129
129
  ], ['#d03020', '#a02018']);
130
- const HAIR_PONYTAIL_S = spriteGeneratorCore.createPartData(10, 8, [
130
+ const HAIR_PONYTAIL_S = /* @__PURE__ */ spriteGeneratorCore.createPartData(10, 8, [
131
131
  [_, _, _, 0, 0, 0, 0, _, _, _],
132
132
  [_, _, 0, 0, 0, 0, 0, 0, _, _],
133
133
  [_, 0, 0, 1, 1, 1, 1, 0, 0, _],
@@ -137,7 +137,7 @@ const HAIR_PONYTAIL_S = spriteGeneratorCore.createPartData(10, 8, [
137
137
  [_, _, _, _, _, _, _, _, _, 0],
138
138
  [_, _, _, _, _, _, _, _, 0, _],
139
139
  ], ['#f0d060', '#d0b040']);
140
- const HAIR_SPIKY_S = spriteGeneratorCore.createPartData(10, 6, [
140
+ const HAIR_SPIKY_S = /* @__PURE__ */ spriteGeneratorCore.createPartData(10, 6, [
141
141
  [_, 0, _, _, 0, _, 0, _, _, _],
142
142
  [_, 0, 0, 0, 0, 0, 0, 0, _, _],
143
143
  [0, 0, 0, 0, 0, 0, 0, 0, 0, _],
@@ -146,7 +146,7 @@ const HAIR_SPIKY_S = spriteGeneratorCore.createPartData(10, 6, [
146
146
  [_, _, _, _, _, _, _, _, _, _],
147
147
  ], ['var(--nice-bg, #1a1a2e)', '#101020']);
148
148
  /* ── TORSOS ── */
149
- const TORSO_BASIC_S = spriteGeneratorCore.createPartData(8, 6, [
149
+ const TORSO_BASIC_S = /* @__PURE__ */ spriteGeneratorCore.createPartData(8, 6, [
150
150
  [_, _, 1, 1, 1, 1, _, _],
151
151
  [_, 1, 0, 0, 0, 0, 1, _],
152
152
  [1, 0, 0, 0, 0, 0, 0, 1],
@@ -154,7 +154,7 @@ const TORSO_BASIC_S = spriteGeneratorCore.createPartData(8, 6, [
154
154
  [_, 1, 0, 0, 0, 0, 1, _],
155
155
  [_, _, 1, 1, 1, 1, _, _],
156
156
  ], ['#4060d0', '#3040b0']);
157
- const TORSO_ARMOR_S = spriteGeneratorCore.createPartData(10, 7, [
157
+ const TORSO_ARMOR_S = /* @__PURE__ */ spriteGeneratorCore.createPartData(10, 7, [
158
158
  [_, _, _, 1, 1, 1, 1, _, _, _],
159
159
  [_, _, 1, 0, 2, 2, 0, 1, _, _],
160
160
  [_, 1, 0, 0, 2, 2, 0, 0, 1, _],
@@ -163,7 +163,7 @@ const TORSO_ARMOR_S = spriteGeneratorCore.createPartData(10, 7, [
163
163
  [_, 1, 0, 0, 0, 0, 0, 0, 1, _],
164
164
  [_, _, 1, 1, 1, 1, 1, 1, _, _],
165
165
  ], ['var(--nice-border, #c0c0c8)', '#909098', '#f0d060']);
166
- const TORSO_ROBE_S = spriteGeneratorCore.createPartData(10, 10, [
166
+ const TORSO_ROBE_S = /* @__PURE__ */ spriteGeneratorCore.createPartData(10, 10, [
167
167
  [_, _, _, 1, 1, 1, 1, _, _, _],
168
168
  [_, _, 1, 0, 0, 0, 0, 1, _, _],
169
169
  [_, 1, 0, 0, 2, 2, 0, 0, 1, _],
@@ -176,14 +176,14 @@ const TORSO_ROBE_S = spriteGeneratorCore.createPartData(10, 10, [
176
176
  [_, _, _, 1, 1, 1, 1, _, _, _],
177
177
  ], ['#8020a0', '#601080', '#f0d060']);
178
178
  /* ── ARMS ── */
179
- const ARM_BASIC_S = spriteGeneratorCore.createPartData(3, 5, [
179
+ const ARM_BASIC_S = /* @__PURE__ */ spriteGeneratorCore.createPartData(3, 5, [
180
180
  [_, 0, _],
181
181
  [0, 0, 1],
182
182
  [0, 0, 1],
183
183
  [0, 0, 1],
184
184
  [_, 0, _],
185
185
  ], ['var(--nice-warning-bg, #ffecd2)', '#c07848']);
186
- const ARM_ARMORED_S = spriteGeneratorCore.createPartData(4, 5, [
186
+ const ARM_ARMORED_S = /* @__PURE__ */ spriteGeneratorCore.createPartData(4, 5, [
187
187
  [_, 0, 1, _],
188
188
  [0, 0, 0, 1],
189
189
  [0, 0, 0, 1],
@@ -191,14 +191,14 @@ const ARM_ARMORED_S = spriteGeneratorCore.createPartData(4, 5, [
191
191
  [_, 0, 1, _],
192
192
  ], ['var(--nice-border, #c0c0c8)', '#909098']);
193
193
  /* ── LEGS ── */
194
- const LEG_BASIC_S = spriteGeneratorCore.createPartData(3, 5, [
194
+ const LEG_BASIC_S = /* @__PURE__ */ spriteGeneratorCore.createPartData(3, 5, [
195
195
  [_, 0, _],
196
196
  [0, 0, 1],
197
197
  [0, 0, 1],
198
198
  [0, 0, 1],
199
199
  [0, 1, 1],
200
200
  ], ['#4060d0', '#3040b0']);
201
- const LEG_BOOT_S = spriteGeneratorCore.createPartData(4, 5, [
201
+ const LEG_BOOT_S = /* @__PURE__ */ spriteGeneratorCore.createPartData(4, 5, [
202
202
  [_, 0, 0, _],
203
203
  [_, 0, 0, _],
204
204
  [_, 0, 0, _],
@@ -206,7 +206,7 @@ const LEG_BOOT_S = spriteGeneratorCore.createPartData(4, 5, [
206
206
  [0, 0, 0, 1],
207
207
  ], ['#b08060', '#906840']);
208
208
  /* ── HATS ── */
209
- const HAT_WIZARD_S = spriteGeneratorCore.createPartData(10, 8, [
209
+ const HAT_WIZARD_S = /* @__PURE__ */ spriteGeneratorCore.createPartData(10, 8, [
210
210
  [_, _, _, _, 0, _, _, _, _, _],
211
211
  [_, _, _, 0, 0, 0, _, _, _, _],
212
212
  [_, _, 0, 0, 0, 0, 0, _, _, _],
@@ -216,7 +216,7 @@ const HAT_WIZARD_S = spriteGeneratorCore.createPartData(10, 8, [
216
216
  [0, 1, 1, 1, 1, 1, 1, 1, 0, _],
217
217
  [_, _, _, _, _, _, _, _, _, _],
218
218
  ], ['#8020a0', '#601080', '#f0d060']);
219
- const HAT_KNIGHT_S = spriteGeneratorCore.createPartData(10, 6, [
219
+ const HAT_KNIGHT_S = /* @__PURE__ */ spriteGeneratorCore.createPartData(10, 6, [
220
220
  [_, _, _, 0, 0, 0, 0, _, _, _],
221
221
  [_, _, 0, 0, 0, 0, 0, 0, _, _],
222
222
  [_, 0, 0, 0, 0, 0, 0, 0, 0, _],
@@ -224,14 +224,14 @@ const HAT_KNIGHT_S = spriteGeneratorCore.createPartData(10, 6, [
224
224
  [0, 0, 2, 2, 2, 2, 2, 2, 0, 0],
225
225
  [_, _, _, 1, 1, 1, 1, _, _, _],
226
226
  ], ['var(--nice-border, #c0c0c8)', '#606068', '#f0d060']);
227
- const HAT_CROWN_S = spriteGeneratorCore.createPartData(10, 5, [
227
+ const HAT_CROWN_S = /* @__PURE__ */ spriteGeneratorCore.createPartData(10, 5, [
228
228
  [_, 2, _, _, 2, _, _, 2, _, _],
229
229
  [_, 0, 2, _, 0, _, 2, 0, _, _],
230
230
  [_, 0, 0, 2, 0, 2, 0, 0, _, _],
231
231
  [_, 0, 0, 0, 0, 0, 0, 0, _, _],
232
232
  [_, 1, 1, 1, 1, 1, 1, 1, _, _],
233
233
  ], ['#f0d060', '#d0b040', '#ff4040']);
234
- const HAT_CAP_S = spriteGeneratorCore.createPartData(9, 5, [
234
+ const HAT_CAP_S = /* @__PURE__ */ spriteGeneratorCore.createPartData(9, 5, [
235
235
  [_, _, _, 0, 0, 0, _, _, _],
236
236
  [_, _, 0, 0, 0, 0, 0, _, _],
237
237
  [_, 0, 0, 0, 0, 0, 0, 0, _],
@@ -239,7 +239,7 @@ const HAT_CAP_S = spriteGeneratorCore.createPartData(9, 5, [
239
239
  [_, _, 1, 1, 1, 1, 1, _, _],
240
240
  ], ['#d04040', '#b02020']);
241
241
  /* ── WEAPONS ── */
242
- const WEAPON_SWORD_S = spriteGeneratorCore.createPartData(3, 10, [
242
+ const WEAPON_SWORD_S = /* @__PURE__ */ spriteGeneratorCore.createPartData(3, 10, [
243
243
  [_, 0, _],
244
244
  [_, 0, _],
245
245
  [_, 0, _],
@@ -251,7 +251,7 @@ const WEAPON_SWORD_S = spriteGeneratorCore.createPartData(3, 10, [
251
251
  [_, 2, _],
252
252
  [_, 2, _],
253
253
  ], ['var(--nice-border, #c0c0c8)', '#f0d060', '#8b5e3c']);
254
- const WEAPON_STAFF_S = spriteGeneratorCore.createPartData(3, 12, [
254
+ const WEAPON_STAFF_S = /* @__PURE__ */ spriteGeneratorCore.createPartData(3, 12, [
255
255
  [_, 1, _],
256
256
  [1, 1, 1],
257
257
  [_, 1, _],
@@ -265,7 +265,7 @@ const WEAPON_STAFF_S = spriteGeneratorCore.createPartData(3, 12, [
265
265
  [_, 0, _],
266
266
  [_, 0, _],
267
267
  ], ['#8b5e3c', '#4080e0']);
268
- const WEAPON_BOW_S = spriteGeneratorCore.createPartData(5, 10, [
268
+ const WEAPON_BOW_S = /* @__PURE__ */ spriteGeneratorCore.createPartData(5, 10, [
269
269
  [_, _, _, 0, _],
270
270
  [_, _, 0, _, 1],
271
271
  [_, 0, _, _, 1],
@@ -277,7 +277,7 @@ const WEAPON_BOW_S = spriteGeneratorCore.createPartData(5, 10, [
277
277
  [_, _, 0, _, 1],
278
278
  [_, _, _, 0, _],
279
279
  ], ['#8b5e3c', 'var(--nice-border, #c0c0c8)']);
280
- const SHIELD_ROUND_S = spriteGeneratorCore.createPartData(6, 7, [
280
+ const SHIELD_ROUND_S = /* @__PURE__ */ spriteGeneratorCore.createPartData(6, 7, [
281
281
  [_, _, 1, 1, _, _],
282
282
  [_, 1, 0, 0, 1, _],
283
283
  [1, 0, 0, 2, 0, 1],
@@ -2,6 +2,7 @@
2
2
 
3
3
  var uiCore = require('@nice2dev/ui-core');
4
4
  var React = require('react');
5
+ var editorAsk = require('../core/editorAsk.js');
5
6
  var asepriteFormat = require('./asepriteFormat.js');
6
7
  var pixelEditorExports = require('./pixelEditorExports.js');
7
8
  var pixelEditorTypes = require('./pixelEditorTypes.js');
@@ -11,11 +12,12 @@ var pixelEditorUtils = require('./pixelEditorUtils.js');
11
12
  * usePixelEditor — custom hook encapsulating ALL state, refs, callbacks,
12
13
  * side-effects and memos for the PixelEditor component.
13
14
  */
14
- const log = { warn: console.warn, error: console.error, info: console.info, debug: console.debug };
15
+ const log = { warn: console.warn, error: console.error };
15
16
  /* ═══════════════════════════════════════════
16
17
  Hook
17
18
  ═══════════════════════════════════════════ */
18
19
  function usePixelEditor({ initialWidth = 64, initialHeight = 64, onSaveToLibrary, }) {
20
+ const { pendingAsk, ask } = editorAsk.useEditorAsk();
19
21
  /* ── state ── */
20
22
  const [dw, setDw] = React.useState(initialWidth);
21
23
  const [dh, setDh] = React.useState(initialHeight);
@@ -296,7 +298,7 @@ function usePixelEditor({ initialWidth = 64, initialHeight = 64, onSaveToLibrary
296
298
  }
297
299
  // symmetry guides
298
300
  if (symmetry !== 'none') {
299
- ctx.strokeStyle = 'rgba(255,100,100,0.3)';
301
+ ctx.strokeStyle = uiCore.resolveCssColor('var(--nice-danger-tint-30, rgba(255,100,100,0.3))', ctx.canvas);
300
302
  ctx.lineWidth = 1 / zoom;
301
303
  ctx.setLineDash([4 / zoom, 4 / zoom]);
302
304
  if (symmetry === 'h' || symmetry === 'both') {
@@ -331,6 +333,7 @@ function usePixelEditor({ initialWidth = 64, initialHeight = 64, onSaveToLibrary
331
333
  }
332
334
  // grid
333
335
  if (grid && zoom >= 4) {
336
+ // audit-allow: literal-color — a faint light grid over the pixels, the same on every theme's canvas
334
337
  ctx.strokeStyle = 'rgba(255,255,255,0.07)';
335
338
  ctx.lineWidth = 1 / zoom;
336
339
  for (let x = 0; x <= dw; x++) {
@@ -347,7 +350,7 @@ function usePixelEditor({ initialWidth = 64, initialHeight = 64, onSaveToLibrary
347
350
  }
348
351
  }
349
352
  // border
350
- ctx.strokeStyle = 'rgba(80,100,200,0.4)';
353
+ ctx.strokeStyle = uiCore.resolveCssColor('var(--nice-primary-tint-40, rgba(80,100,200,0.4))', ctx.canvas);
351
354
  ctx.lineWidth = 1 / zoom;
352
355
  ctx.strokeRect(-0.5 / zoom, -0.5 / zoom, dw + 1 / zoom, dh + 1 / zoom);
353
356
  // brush cursor preview
@@ -834,13 +837,12 @@ function usePixelEditor({ initialWidth = 64, initialHeight = 64, onSaveToLibrary
834
837
  cv.height = dh;
835
838
  cv.getContext('2d').putImageData(data, 0, 0);
836
839
  const dataUrl = cv.toDataURL('image/png');
837
- const defaultName = `sprite-${dw}x${dh}.png`;
838
- const name = window.prompt('Save to library as:', defaultName);
839
- if (!name || !name.trim()) {
840
- return;
841
- }
842
- onSaveToLibrary(dataUrl, name.trim(), 'image/png');
843
- }, [onSaveToLibrary, afi, dw, dh, compFrame]);
840
+ void ask('prompt', 'Save to library as:', `sprite-${dw}x${dh}.png`).then((name) => {
841
+ if (name && name.trim()) {
842
+ onSaveToLibrary(dataUrl, name.trim(), 'image/png');
843
+ }
844
+ });
845
+ }, [onSaveToLibrary, afi, dw, dh, compFrame, ask]);
844
846
  /* ── layer management ── */
845
847
  const addLayer = React.useCallback(() => {
846
848
  snap('Add Layer');
@@ -1274,6 +1276,7 @@ function usePixelEditor({ initialWidth = 64, initialHeight = 64, onSaveToLibrary
1274
1276
  }, [fc, dw, dh, layers, tick]);
1275
1277
  /* ── return API ── */
1276
1278
  return {
1279
+ pendingAsk,
1277
1280
  dw,
1278
1281
  dh,
1279
1282
  layers,
@@ -3,6 +3,7 @@
3
3
  var jsxRuntime = require('react/jsx-runtime');
4
4
  var uiCore = require('@nice2dev/ui-core');
5
5
  var React = require('react');
6
+ var i18n = require('../core/i18n.js');
6
7
 
7
8
  // ── Default Config ──────────────────────────────────────────────
8
9
  const DEFAULT_BRUSH = {
@@ -203,6 +204,7 @@ function useTexturePainter(width, height) {
203
204
  // ── Component ───────────────────────────────────────────────────
204
205
  /** 3D texture painting tool with UV-space brush painting, zoom/pan, and layers. */
205
206
  const Nice3DTexturePainter = ({ textureWidth = 1024, textureHeight = 1024, onSave, className = '', }) => {
207
+ const { t } = i18n.useNiceTranslation();
206
208
  const painter = useTexturePainter(textureWidth, textureHeight);
207
209
  const canvasRef = React.useRef(null);
208
210
  const isPainting = React.useRef(false);
@@ -315,7 +317,7 @@ const Nice3DTexturePainter = ({ textureWidth = 1024, textureHeight = 1024, onSav
315
317
  cursor: 'pointer',
316
318
  fontSize: 11,
317
319
  background: active ? 'var(--nice-info, #339af0)' : 'var(--nice-bg-secondary, #2c2e33)',
318
- color: active ? 'var(--nice-text-on-primary, #fff)' : 'var(--nice-text, #c1c2c5)',
320
+ color: active ? 'var(--nice-color-white, #fff)' : 'var(--nice-text, #c1c2c5)',
319
321
  display: 'flex',
320
322
  alignItems: 'center',
321
323
  gap: 4,
@@ -334,17 +336,17 @@ const Nice3DTexturePainter = ({ textureWidth = 1024, textureHeight = 1024, onSav
334
336
  color: 'var(--nice-text, #c1c2c5)',
335
337
  padding: 12,
336
338
  borderRadius: 8,
337
- }, children: [jsxRuntime.jsxs("div", { style: { width: 140, fontSize: 11, display: 'flex', flexDirection: 'column', gap: 4 }, children: [jsxRuntime.jsx("strong", { style: { fontSize: 12 }, children: "Tools" }), ['brush', 'eraser', 'eyedropper', 'fill'].map((t) => (jsxRuntime.jsxs("button", { onClick: () => painter.setTool(t), style: btnStyle(painter.tool === t), children: [jsxRuntime.jsx(uiCore.NiceIcon, { name: toolIcons[t], size: 14 }), " ", t.charAt(0).toUpperCase() + t.slice(1), ' ', jsxRuntime.jsx("span", { style: { color: 'var(--nice-text-secondary, #868e96)', marginLeft: 'auto' }, children: t === 'brush' ? 'B' : t === 'eraser' ? 'E' : t === 'eyedropper' ? 'I' : 'G' })] }, t))), jsxRuntime.jsx("hr", { style: {
339
+ }, children: [jsxRuntime.jsxs("div", { style: { width: 140, fontSize: 11, display: 'flex', flexDirection: 'column', gap: 4 }, children: [jsxRuntime.jsx("strong", { style: { fontSize: 12 }, children: t('texturePainter3d.tools', 'Tools') }), ['brush', 'eraser', 'eyedropper', 'fill'].map((t) => (jsxRuntime.jsxs("button", { onClick: () => painter.setTool(t), style: btnStyle(painter.tool === t), children: [jsxRuntime.jsx(uiCore.NiceIcon, { name: toolIcons[t], size: 14 }), " ", t.charAt(0).toUpperCase() + t.slice(1), ' ', jsxRuntime.jsx("span", { style: { color: 'var(--nice-text-secondary, #868e96)', marginLeft: 'auto' }, children: t === 'brush' ? 'B' : t === 'eraser' ? 'E' : t === 'eyedropper' ? 'I' : 'G' })] }, t))), jsxRuntime.jsx("hr", { style: {
338
340
  border: 'none',
339
341
  borderTop: '1px solid var(--nice-border, #373a40)',
340
342
  width: '100%',
341
343
  margin: '4px 0',
342
- } }), jsxRuntime.jsx("div", { style: { display: 'flex', justifyContent: 'space-between' }, children: jsxRuntime.jsxs("button", { onClick: () => painter.undo(), style: btnStyle(false), title: "Undo (Ctrl+Z)", children: [jsxRuntime.jsx(uiCore.NiceIcon, { name: "reply", size: 14 }), " Undo"] }) }), jsxRuntime.jsx("hr", { style: {
344
+ } }), jsxRuntime.jsx("div", { style: { display: 'flex', justifyContent: 'space-between' }, children: jsxRuntime.jsxs("button", { onClick: () => painter.undo(), style: btnStyle(false), title: t('texturePainter3d.undoCtrlZ', 'Undo (Ctrl+Z)'), children: [jsxRuntime.jsx(uiCore.NiceIcon, { name: "reply", size: 14 }), " ", t('texturePainter3d.undo', 'Undo')] }) }), jsxRuntime.jsx("hr", { style: {
343
345
  border: 'none',
344
346
  borderTop: '1px solid var(--nice-border, #373a40)',
345
347
  width: '100%',
346
348
  margin: '4px 0',
347
- } }), jsxRuntime.jsxs("label", { children: ["Size: ", painter.brush.size, "px"] }), jsxRuntime.jsx("input", { type: "range", min: 1, max: 100, value: painter.brush.size, onChange: (e) => painter.setBrush({ ...painter.brush, size: Number(e.target.value) }), style: { width: '100%' } }), jsxRuntime.jsxs("label", { children: ["Opacity: ", Math.round(painter.brush.opacity * 100), "%"] }), jsxRuntime.jsx("input", { type: "range", min: 0, max: 1, step: 0.01, value: painter.brush.opacity, onChange: (e) => painter.setBrush({ ...painter.brush, opacity: Number(e.target.value) }), style: { width: '100%' } }), jsxRuntime.jsxs("label", { children: ["Hardness: ", Math.round(painter.brush.hardness * 100), "%"] }), jsxRuntime.jsx("input", { type: "range", min: 0, max: 1, step: 0.01, value: painter.brush.hardness, onChange: (e) => painter.setBrush({ ...painter.brush, hardness: Number(e.target.value) }), style: { width: '100%' } }), jsxRuntime.jsx("label", { children: "Blend Mode" }), jsxRuntime.jsxs("select", { value: painter.brush.blendMode, onChange: (e) => painter.setBrush({
349
+ } }), jsxRuntime.jsxs("label", { children: ["Size: ", painter.brush.size, "px"] }), jsxRuntime.jsx("input", { type: "range", min: 1, max: 100, value: painter.brush.size, onChange: (e) => painter.setBrush({ ...painter.brush, size: Number(e.target.value) }), style: { width: '100%' } }), jsxRuntime.jsxs("label", { children: ["Opacity: ", Math.round(painter.brush.opacity * 100), "%"] }), jsxRuntime.jsx("input", { type: "range", min: 0, max: 1, step: 0.01, value: painter.brush.opacity, onChange: (e) => painter.setBrush({ ...painter.brush, opacity: Number(e.target.value) }), style: { width: '100%' } }), jsxRuntime.jsxs("label", { children: ["Hardness: ", Math.round(painter.brush.hardness * 100), "%"] }), jsxRuntime.jsx("input", { type: "range", min: 0, max: 1, step: 0.01, value: painter.brush.hardness, onChange: (e) => painter.setBrush({ ...painter.brush, hardness: Number(e.target.value) }), style: { width: '100%' } }), jsxRuntime.jsx("label", { children: t('texturePainter3d.blendMode', 'Blend Mode') }), jsxRuntime.jsxs("select", { value: painter.brush.blendMode, onChange: (e) => painter.setBrush({
348
350
  ...painter.brush,
349
351
  blendMode: e.target.value,
350
352
  }), style: {
@@ -355,12 +357,12 @@ const Nice3DTexturePainter = ({ textureWidth = 1024, textureHeight = 1024, onSav
355
357
  border: '1px solid var(--nice-border, #373a40)',
356
358
  borderRadius: 3,
357
359
  fontSize: 10,
358
- }, children: [jsxRuntime.jsx("option", { value: "normal", children: "Normal" }), jsxRuntime.jsx("option", { value: "multiply", children: "Multiply" }), jsxRuntime.jsx("option", { value: "screen", children: "Screen" }), jsxRuntime.jsx("option", { value: "overlay", children: "Overlay" })] }), jsxRuntime.jsx("label", { children: "Color" }), jsxRuntime.jsxs("div", { style: { display: 'flex', gap: 4, alignItems: 'center' }, children: [jsxRuntime.jsx("input", { type: "color", value: painter.brush.color, onChange: (e) => painter.setBrush({ ...painter.brush, color: e.target.value }), style: { width: 32, height: 24, border: 'none', cursor: 'pointer' } }), jsxRuntime.jsx("span", { style: { fontFamily: 'monospace', fontSize: 10 }, children: painter.brush.color })] }), jsxRuntime.jsx("hr", { style: {
360
+ }, children: [jsxRuntime.jsx("option", { value: "normal", children: t('texturePainter3d.normal', 'Normal') }), jsxRuntime.jsx("option", { value: "multiply", children: t('texturePainter3d.multiply', 'Multiply') }), jsxRuntime.jsx("option", { value: "screen", children: t('texturePainter3d.screen', 'Screen') }), jsxRuntime.jsx("option", { value: "overlay", children: t('texturePainter3d.overlay', 'Overlay') })] }), jsxRuntime.jsx("label", { children: t('texturePainter3d.color', 'Color') }), jsxRuntime.jsxs("div", { style: { display: 'flex', gap: 4, alignItems: 'center' }, children: [jsxRuntime.jsx("input", { type: "color", value: painter.brush.color, onChange: (e) => painter.setBrush({ ...painter.brush, color: e.target.value }), style: { width: 32, height: 24, border: 'none', cursor: 'pointer' } }), jsxRuntime.jsx("span", { style: { fontFamily: 'monospace', fontSize: 10 }, children: painter.brush.color })] }), jsxRuntime.jsx("hr", { style: {
359
361
  border: 'none',
360
362
  borderTop: '1px solid var(--nice-border, #373a40)',
361
363
  width: '100%',
362
364
  margin: '4px 0',
363
- } }), jsxRuntime.jsxs("label", { children: ["Zoom: ", Math.round(zoom * 100), "%"] }), jsxRuntime.jsxs("div", { style: { display: 'flex', gap: 2 }, children: [jsxRuntime.jsx("button", { onClick: () => setZoom((z) => Math.max(0.1, z - 0.1)), style: btnStyle(false), children: "\u2212" }), jsxRuntime.jsx("button", { onClick: () => setZoom(0.5), style: btnStyle(false), children: "Reset" }), jsxRuntime.jsx("button", { onClick: () => setZoom((z) => Math.min(4, z + 0.1)), style: btnStyle(false), children: "+" })] })] }), jsxRuntime.jsxs("div", { style: {
365
+ } }), jsxRuntime.jsxs("label", { children: ["Zoom: ", Math.round(zoom * 100), "%"] }), jsxRuntime.jsxs("div", { style: { display: 'flex', gap: 2 }, children: [jsxRuntime.jsx("button", { onClick: () => setZoom((z) => Math.max(0.1, z - 0.1)), style: btnStyle(false), children: "\u2212" }), jsxRuntime.jsx("button", { onClick: () => setZoom(0.5), style: btnStyle(false), children: t('texturePainter3d.reset', 'Reset') }), jsxRuntime.jsx("button", { onClick: () => setZoom((z) => Math.min(4, z + 0.1)), style: btnStyle(false), children: "+" })] })] }), jsxRuntime.jsxs("div", { style: {
364
366
  flex: 1,
365
367
  overflow: 'hidden',
366
368
  position: 'relative',
@@ -382,14 +384,14 @@ const Nice3DTexturePainter = ({ textureWidth = 1024, textureHeight = 1024, onSav
382
384
  color: 'var(--nice-text-secondary, #868e96)',
383
385
  display: 'flex',
384
386
  gap: 12,
385
- }, children: [jsxRuntime.jsxs("span", { children: [textureWidth, "\u00D7", textureHeight] }), cursorPos && (jsxRuntime.jsxs("span", { children: ["X: ", cursorPos.x, " Y: ", cursorPos.y] })), jsxRuntime.jsxs("span", { children: ["Zoom: ", Math.round(zoom * 100), "%"] })] })] }), jsxRuntime.jsxs("div", { style: { width: 160, fontSize: 11, display: 'flex', flexDirection: 'column', gap: 4 }, children: [jsxRuntime.jsx("strong", { style: { fontSize: 12 }, children: "Layers" }), jsxRuntime.jsx("div", { style: { flex: 1, overflowY: 'auto', display: 'flex', flexDirection: 'column', gap: 2 }, children: [...painter.layers].reverse().map((l) => (jsxRuntime.jsxs("div", { style: {
387
+ }, children: [jsxRuntime.jsxs("span", { children: [textureWidth, "\u00D7", textureHeight] }), cursorPos && (jsxRuntime.jsxs("span", { children: ["X: ", cursorPos.x, " Y: ", cursorPos.y] })), jsxRuntime.jsxs("span", { children: ["Zoom: ", Math.round(zoom * 100), "%"] })] })] }), jsxRuntime.jsxs("div", { style: { width: 160, fontSize: 11, display: 'flex', flexDirection: 'column', gap: 4 }, children: [jsxRuntime.jsx("strong", { style: { fontSize: 12 }, children: t('texturePainter3d.layers', 'Layers') }), jsxRuntime.jsx("div", { style: { flex: 1, overflowY: 'auto', display: 'flex', flexDirection: 'column', gap: 2 }, children: [...painter.layers].reverse().map((l) => (jsxRuntime.jsxs("div", { style: {
386
388
  padding: '4px 6px',
387
389
  borderRadius: 3,
388
390
  background: painter.activeLayerId === l.id
389
391
  ? 'var(--nice-info, #339af0)'
390
392
  : 'var(--nice-bg-secondary, #2c2e33)',
391
393
  color: painter.activeLayerId === l.id
392
- ? 'var(--nice-text-on-primary, #fff)'
394
+ ? 'var(--nice-color-white, #fff)'
393
395
  : 'var(--nice-text, #c1c2c5)',
394
396
  }, children: [jsxRuntime.jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: 4, cursor: 'pointer' }, onClick: () => painter.setActiveLayerId(l.id), children: [jsxRuntime.jsx("button", { onClick: (e) => {
395
397
  e.stopPropagation();
@@ -418,7 +420,7 @@ const Nice3DTexturePainter = ({ textureWidth = 1024, textureHeight = 1024, onSav
418
420
  cursor: 'pointer',
419
421
  padding: 0,
420
422
  fontSize: 10,
421
- }, "aria-label": "Remove layer", title: "Remove layer", children: jsxRuntime.jsx(uiCore.NiceIcon, { name: "close", size: 10 }) }))] }), jsxRuntime.jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: 4, marginTop: 2 }, children: [jsxRuntime.jsx("span", { style: { fontSize: 9, color: 'var(--nice-text-secondary, #868e96)' }, children: "\u03B1" }), jsxRuntime.jsx("input", { type: "range", min: 0, max: 1, step: 0.01, value: l.opacity, onChange: (e) => painter.setLayerOpacity(l.id, Number(e.target.value)), style: { flex: 1, height: 12 } }), jsxRuntime.jsxs("span", { style: { fontSize: 9, minWidth: 24, textAlign: 'right' }, children: [Math.round(l.opacity * 100), "%"] })] })] }, l.id))) }), jsxRuntime.jsx("button", { onClick: () => painter.addLayer(`Layer ${painter.layers.length + 1}`), style: {
423
+ }, "aria-label": t('texturePainter3d.removeLayer', 'Remove layer'), title: t('texturePainter3d.removeLayer', 'Remove layer'), children: jsxRuntime.jsx(uiCore.NiceIcon, { name: "close", size: 10 }) }))] }), jsxRuntime.jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: 4, marginTop: 2 }, children: [jsxRuntime.jsx("span", { style: { fontSize: 9, color: 'var(--nice-text-secondary, #868e96)' }, children: "\u03B1" }), jsxRuntime.jsx("input", { type: "range", min: 0, max: 1, step: 0.01, value: l.opacity, onChange: (e) => painter.setLayerOpacity(l.id, Number(e.target.value)), style: { flex: 1, height: 12 } }), jsxRuntime.jsxs("span", { style: { fontSize: 9, minWidth: 24, textAlign: 'right' }, children: [Math.round(l.opacity * 100), "%"] })] })] }, l.id))) }), jsxRuntime.jsx("button", { onClick: () => painter.addLayer(`Layer ${painter.layers.length + 1}`), style: {
422
424
  padding: '4px 8px',
423
425
  border: 'none',
424
426
  borderRadius: 3,
@@ -438,7 +440,7 @@ const Nice3DTexturePainter = ({ textureWidth = 1024, textureHeight = 1024, onSav
438
440
  borderRadius: 3,
439
441
  cursor: 'pointer',
440
442
  fontWeight: 'bold',
441
- }, children: "Save Texture" })] })] }));
443
+ }, children: t('texturePainter3d.saveTexture', 'Save Texture') })] })] }));
442
444
  };
443
445
 
444
446
  exports.Nice3DTexturePainter = Nice3DTexturePainter;
@@ -4,6 +4,7 @@ var jsxRuntime = require('react/jsx-runtime');
4
4
  var ui = require('@nice2dev/ui');
5
5
  var uiCore = require('@nice2dev/ui-core');
6
6
  var React = require('react');
7
+ var i18n = require('../core/i18n.js');
7
8
 
8
9
  /** Built-in guided tour (EN inline + i18n keys → PL and other locales). */
9
10
  const UI_DESIGNER_TOUR = [
@@ -312,6 +313,7 @@ function updateInTree(nodes, id, updates) {
312
313
  /** Visual drag & drop UI builder that generates React code. */
313
314
  const NiceUIDesigner = ({ onChange, onExport, className = '', tutorial, }) => {
314
315
  var _a, _b, _c, _d, _e;
316
+ const { t } = i18n.useNiceTranslation();
315
317
  const designer = useUIDesigner();
316
318
  const [breakpoint, setBreakpoint] = React.useState('desktop');
317
319
  const [dragType, setDragType] = React.useState(null);
@@ -346,7 +348,7 @@ const NiceUIDesigner = ({ onChange, onExport, className = '', tutorial, }) => {
346
348
  cursor: 'pointer',
347
349
  fontSize: 11,
348
350
  background: active ? 'var(--nice-info, #339af0)' : 'var(--nice-bg-secondary, #2c2e33)',
349
- color: active ? 'var(--nice-text-on-primary, #fff)' : 'var(--nice-text, #c1c2c5)',
351
+ color: active ? 'var(--nice-color-white, #fff)' : 'var(--nice-text, #c1c2c5)',
350
352
  });
351
353
  const fieldStyle = {
352
354
  width: '100%',
@@ -395,7 +397,7 @@ const NiceUIDesigner = ({ onChange, onExport, className = '', tutorial, }) => {
395
397
  color: 'var(--nice-text-secondary, #868e96)',
396
398
  fontSize: 11,
397
399
  gap: 4,
398
- }, children: [jsxRuntime.jsx(uiCore.NiceIcon, { name: "image", size: 14 }), " Image"] })) : node.type === 'List' ? (jsxRuntime.jsx("ul", { style: { margin: 0, ...node.style }, children: ((_d = node.props.items) !== null && _d !== void 0 ? _d : []).map((item, i) => (jsxRuntime.jsx("li", { children: item }, i))) })) : node.type === 'Divider' ? (jsxRuntime.jsx("hr", { style: {
400
+ }, children: [jsxRuntime.jsx(uiCore.NiceIcon, { name: "image", size: 14 }), " ", t('uiDesigner.image', 'Image')] })) : node.type === 'List' ? (jsxRuntime.jsx("ul", { style: { margin: 0, ...node.style }, children: ((_d = node.props.items) !== null && _d !== void 0 ? _d : []).map((item, i) => (jsxRuntime.jsx("li", { children: item }, i))) })) : node.type === 'Divider' ? (jsxRuntime.jsx("hr", { style: {
399
401
  margin: 0,
400
402
  border: 'none',
401
403
  borderTop: '1px solid var(--nice-border, #dee2e6)',
@@ -421,7 +423,9 @@ const NiceUIDesigner = ({ onChange, onExport, className = '', tutorial, }) => {
421
423
  display: 'flex',
422
424
  alignItems: 'center',
423
425
  gap: 4,
424
- background: designer.selectedId === node.id ? 'rgba(51,154,240,0.2)' : 'transparent',
426
+ background: designer.selectedId === node.id
427
+ ? 'color-mix(in srgb, var(--nice-color-primary, #339af0) 20%, transparent)'
428
+ : 'transparent',
425
429
  borderRadius: 2,
426
430
  }, children: [(def === null || def === void 0 ? void 0 : def.icon) && jsxRuntime.jsx(uiCore.NiceIcon, { name: def.icon, size: 12 }), jsxRuntime.jsxs("span", { style: { flex: 1, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }, children: [node.type, node.props.text ? `: ${String(node.props.text).slice(0, 15)}` : ''] })] }), node.children.map((c) => renderTreeItem(c, depth + 1))] }, node.id));
427
431
  };
@@ -435,7 +439,7 @@ const NiceUIDesigner = ({ onChange, onExport, className = '', tutorial, }) => {
435
439
  height: '100%',
436
440
  overflowY: 'auto',
437
441
  boxSizing: 'border-box',
438
- }, children: [jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("strong", { style: { fontSize: 12, display: 'block', marginBottom: 4 }, children: "Components" }), jsxRuntime.jsx("div", { style: { display: 'flex', flexDirection: 'column', gap: 2 }, children: COMPONENT_DEFS.map((def) => (jsxRuntime.jsxs("button", { draggable: true, onDragStart: () => setDragType(def.type), onDragEnd: () => setDragType(null), onClick: () => { var _a; return designer.addNode(def.type, (_a = designer.selectedId) !== null && _a !== void 0 ? _a : undefined); }, style: {
442
+ }, children: [jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("strong", { style: { fontSize: 12, display: 'block', marginBottom: 4 }, children: t('uiDesigner.components', 'Components') }), jsxRuntime.jsx("div", { style: { display: 'flex', flexDirection: 'column', gap: 2 }, children: COMPONENT_DEFS.map((def) => (jsxRuntime.jsxs("button", { draggable: true, onDragStart: () => setDragType(def.type), onDragEnd: () => setDragType(null), onClick: () => { var _a; return designer.addNode(def.type, (_a = designer.selectedId) !== null && _a !== void 0 ? _a : undefined); }, style: {
439
443
  display: 'flex',
440
444
  alignItems: 'center',
441
445
  gap: 4,
@@ -447,8 +451,8 @@ const NiceUIDesigner = ({ onChange, onExport, className = '', tutorial, }) => {
447
451
  cursor: 'grab',
448
452
  textAlign: 'left',
449
453
  fontSize: 11,
450
- }, children: [jsxRuntime.jsx(uiCore.NiceIcon, { name: def.icon, size: 14 }), " ", def.label] }, def.type))) })] }), jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("strong", { style: { fontSize: 12, display: 'block', marginBottom: 4 }, children: "Tree" }), jsxRuntime.jsx("div", { style: { maxHeight: 200, overflowY: 'auto' }, children: designer.tree.length === 0 ? (jsxRuntime.jsx("div", { style: { color: 'var(--nice-text-secondary, #5c5f66)', padding: 4 }, children: "Empty" })) : (designer.tree.map((n) => renderTreeItem(n))) })] })] }));
451
- const toolbarContent = (jsxRuntime.jsxs("div", { style: { display: 'flex', gap: 4, alignItems: 'center', fontSize: 11, padding: '4px 8px' }, children: [jsxRuntime.jsx("button", { onClick: () => designer.undo(), disabled: !designer.canUndo, style: { ...btnStyle(false), opacity: designer.canUndo ? 1 : 0.4 }, title: "Undo (Ctrl+Z)", "aria-label": "Undo", children: jsxRuntime.jsx(uiCore.NiceIcon, { name: "reply", size: 14 }) }), jsxRuntime.jsx("button", { onClick: () => designer.redo(), disabled: !designer.canRedo, style: { ...btnStyle(false), opacity: designer.canRedo ? 1 : 0.4 }, title: "Redo (Ctrl+Y)", "aria-label": "Redo", children: jsxRuntime.jsx(uiCore.NiceIcon, { name: "forward", size: 14 }) }), jsxRuntime.jsx("div", { style: { width: 1, height: 16, background: 'var(--nice-border, #373a40)' } }), jsxRuntime.jsxs("button", { onClick: () => setBreakpoint('desktop'), style: btnStyle(breakpoint === 'desktop'), children: [jsxRuntime.jsx(uiCore.NiceIcon, { name: "monitor", size: 14 }), " Desktop"] }), jsxRuntime.jsxs("button", { onClick: () => setBreakpoint('tablet'), style: btnStyle(breakpoint === 'tablet'), children: [jsxRuntime.jsx(uiCore.NiceIcon, { name: "window", size: 14 }), " Tablet"] }), jsxRuntime.jsxs("button", { onClick: () => setBreakpoint('mobile'), style: btnStyle(breakpoint === 'mobile'), children: [jsxRuntime.jsx(uiCore.NiceIcon, { name: "phone", size: 14 }), " Mobile"] }), jsxRuntime.jsx("div", { style: { flex: 1 } }), designer.selectedId && (jsxRuntime.jsxs("button", { onClick: () => designer.removeNode(designer.selectedId), style: { ...btnStyle(false), color: 'var(--nice-danger, #ff6b6b)' }, children: [jsxRuntime.jsx(uiCore.NiceIcon, { name: "trash", size: 14 }), " Delete"] })), jsxRuntime.jsxs("button", { onClick: () => setShowCode((v) => !v), style: btnStyle(showCode), children: ['</>', " Code"] }), jsxRuntime.jsx("button", { onClick: () => onExport === null || onExport === void 0 ? void 0 : onExport(designer.exportCode()), style: {
454
+ }, children: [jsxRuntime.jsx(uiCore.NiceIcon, { name: def.icon, size: 14 }), " ", def.label] }, def.type))) })] }), jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("strong", { style: { fontSize: 12, display: 'block', marginBottom: 4 }, children: t('uiDesigner.tree', 'Tree') }), jsxRuntime.jsx("div", { style: { maxHeight: 200, overflowY: 'auto' }, children: designer.tree.length === 0 ? (jsxRuntime.jsx("div", { style: { color: 'var(--nice-text-secondary, #5c5f66)', padding: 4 }, children: t('uiDesigner.empty', 'Empty') })) : (designer.tree.map((n) => renderTreeItem(n))) })] })] }));
455
+ const toolbarContent = (jsxRuntime.jsxs("div", { style: { display: 'flex', gap: 4, alignItems: 'center', fontSize: 11, padding: '4px 8px' }, children: [jsxRuntime.jsx("button", { onClick: () => designer.undo(), disabled: !designer.canUndo, style: { ...btnStyle(false), opacity: designer.canUndo ? 1 : 0.4 }, title: t('uiDesigner.undoCtrlZ', 'Undo (Ctrl+Z)'), "aria-label": t('uiDesigner.undo', 'Undo'), children: jsxRuntime.jsx(uiCore.NiceIcon, { name: "reply", size: 14 }) }), jsxRuntime.jsx("button", { onClick: () => designer.redo(), disabled: !designer.canRedo, style: { ...btnStyle(false), opacity: designer.canRedo ? 1 : 0.4 }, title: t('uiDesigner.redoCtrlY', 'Redo (Ctrl+Y)'), "aria-label": t('uiDesigner.redo', 'Redo'), children: jsxRuntime.jsx(uiCore.NiceIcon, { name: "forward", size: 14 }) }), jsxRuntime.jsx("div", { style: { width: 1, height: 16, background: 'var(--nice-border, #373a40)' } }), jsxRuntime.jsxs("button", { onClick: () => setBreakpoint('desktop'), style: btnStyle(breakpoint === 'desktop'), children: [jsxRuntime.jsx(uiCore.NiceIcon, { name: "monitor", size: 14 }), " ", t('uiDesigner.desktop', 'Desktop')] }), jsxRuntime.jsxs("button", { onClick: () => setBreakpoint('tablet'), style: btnStyle(breakpoint === 'tablet'), children: [jsxRuntime.jsx(uiCore.NiceIcon, { name: "window", size: 14 }), " ", t('uiDesigner.tablet', 'Tablet')] }), jsxRuntime.jsxs("button", { onClick: () => setBreakpoint('mobile'), style: btnStyle(breakpoint === 'mobile'), children: [jsxRuntime.jsx(uiCore.NiceIcon, { name: "phone", size: 14 }), " ", t('uiDesigner.mobile', 'Mobile')] }), jsxRuntime.jsx("div", { style: { flex: 1 } }), designer.selectedId && (jsxRuntime.jsxs("button", { onClick: () => designer.removeNode(designer.selectedId), style: { ...btnStyle(false), color: 'var(--nice-danger, #ff6b6b)' }, children: [jsxRuntime.jsx(uiCore.NiceIcon, { name: "trash", size: 14 }), " ", t('uiDesigner.delete', 'Delete')] })), jsxRuntime.jsxs("button", { onClick: () => setShowCode((v) => !v), style: btnStyle(showCode), children: ['</>', " ", t('uiDesigner.code', 'Code')] }), jsxRuntime.jsx("button", { onClick: () => onExport === null || onExport === void 0 ? void 0 : onExport(designer.exportCode()), style: {
452
456
  padding: '4px 8px',
453
457
  background: 'var(--nice-primary, #228be6)',
454
458
  color: 'var(--nice-text-on-primary, #fff)',
@@ -456,7 +460,7 @@ const NiceUIDesigner = ({ onChange, onExport, className = '', tutorial, }) => {
456
460
  borderRadius: 3,
457
461
  cursor: 'pointer',
458
462
  fontSize: 11,
459
- }, children: "Export" })] }));
463
+ }, children: t('uiDesigner.export', 'Export') })] }));
460
464
  const mainContent = (jsxRuntime.jsx("div", { style: {
461
465
  flex: 1,
462
466
  display: 'flex',
@@ -472,7 +476,7 @@ const NiceUIDesigner = ({ onChange, onExport, className = '', tutorial, }) => {
472
476
  margin: 0,
473
477
  overflow: 'auto',
474
478
  fontSize: 11,
475
- color: '#a6e3a1',
479
+ color: 'var(--nice-color-success, #a6e3a1)',
476
480
  fontFamily: 'monospace',
477
481
  }, children: designer.exportCode() })) : (jsxRuntime.jsx("div", { style: {
478
482
  flex: 1,
@@ -489,7 +493,7 @@ const NiceUIDesigner = ({ onChange, onExport, className = '', tutorial, }) => {
489
493
  textAlign: 'center',
490
494
  padding: 40,
491
495
  color: 'var(--nice-text-secondary, #868e96)',
492
- }, children: "Drag or click a component to add it" })) : (designer.tree.map((n) => renderNode(n))) })) }));
496
+ }, children: t('uiDesigner.dragOrClickAComponent', 'Drag or click a component to add it') })) : (designer.tree.map((n) => renderNode(n))) })) }));
493
497
  const rightPanel = (jsxRuntime.jsxs("div", { style: {
494
498
  width: 200,
495
499
  fontSize: 11,
@@ -500,7 +504,7 @@ const NiceUIDesigner = ({ onChange, onExport, className = '', tutorial, }) => {
500
504
  overflowY: 'auto',
501
505
  padding: 8,
502
506
  boxSizing: 'border-box',
503
- }, children: [jsxRuntime.jsx("strong", { style: { fontSize: 12 }, children: "Properties" }), selectedNode ? (jsxRuntime.jsxs("div", { style: { display: 'flex', flexDirection: 'column', gap: 6 }, children: [jsxRuntime.jsxs("div", { style: {
507
+ }, children: [jsxRuntime.jsx("strong", { style: { fontSize: 12 }, children: t('uiDesigner.properties', 'Properties') }), selectedNode ? (jsxRuntime.jsxs("div", { style: { display: 'flex', flexDirection: 'column', gap: 6 }, children: [jsxRuntime.jsxs("div", { style: {
504
508
  color: 'var(--nice-text-secondary, #868e96)',
505
509
  display: 'flex',
506
510
  alignItems: 'center',
@@ -509,13 +513,13 @@ const NiceUIDesigner = ({ onChange, onExport, className = '', tutorial, }) => {
509
513
  var _a;
510
514
  const di = (_a = COMPONENT_DEFS.find((d) => d.type === selectedNode.type)) === null || _a === void 0 ? void 0 : _a.icon;
511
515
  return di ? jsxRuntime.jsx(uiCore.NiceIcon, { name: di, size: 14 }) : null;
512
- })(), ' ', selectedNode.type] }), selectedNode.props.text !== undefined && (jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("label", { children: "Text" }), jsxRuntime.jsx("input", { value: String(selectedNode.props.text), onChange: (e) => designer.updateNode(selectedNode.id, { props: { text: e.target.value } }), style: fieldStyle })] })), selectedNode.props.placeholder !== undefined && (jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("label", { children: "Placeholder" }), jsxRuntime.jsx("input", { value: String(selectedNode.props.placeholder), onChange: (e) => designer.updateNode(selectedNode.id, { props: { placeholder: e.target.value } }), style: fieldStyle })] })), selectedNode.props.level !== undefined && (jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("label", { children: "Heading Level" }), jsxRuntime.jsx("select", { value: Number(selectedNode.props.level), onChange: (e) => designer.updateNode(selectedNode.id, {
516
+ })(), ' ', selectedNode.type] }), selectedNode.props.text !== undefined && (jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("label", { children: t('uiDesigner.text', 'Text') }), jsxRuntime.jsx("input", { value: String(selectedNode.props.text), onChange: (e) => designer.updateNode(selectedNode.id, { props: { text: e.target.value } }), style: fieldStyle })] })), selectedNode.props.placeholder !== undefined && (jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("label", { children: t('uiDesigner.placeholder', 'Placeholder') }), jsxRuntime.jsx("input", { value: String(selectedNode.props.placeholder), onChange: (e) => designer.updateNode(selectedNode.id, { props: { placeholder: e.target.value } }), style: fieldStyle })] })), selectedNode.props.level !== undefined && (jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("label", { children: t('uiDesigner.headingLevel', 'Heading Level') }), jsxRuntime.jsx("select", { value: Number(selectedNode.props.level), onChange: (e) => designer.updateNode(selectedNode.id, {
513
517
  props: { level: Number(e.target.value) },
514
- }), style: fieldStyle, children: [1, 2, 3, 4, 5, 6].map((v) => (jsxRuntime.jsxs("option", { value: v, children: ["H", v] }, v))) })] })), selectedNode.props.variant !== undefined && (jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("label", { children: "Variant" }), jsxRuntime.jsx("select", { value: String(selectedNode.props.variant), onChange: (e) => designer.updateNode(selectedNode.id, { props: { variant: e.target.value } }), style: fieldStyle, children: ['primary', 'secondary', 'outline', 'ghost'].map((v) => (jsxRuntime.jsx("option", { value: v, children: v }, v))) })] })), selectedNode.props.src !== undefined && (jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("label", { children: "Image URL" }), jsxRuntime.jsx("input", { value: String(selectedNode.props.src), onChange: (e) => designer.updateNode(selectedNode.id, { props: { src: e.target.value } }), style: fieldStyle })] })), selectedNode.props.alt !== undefined && (jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("label", { children: "Alt Text" }), jsxRuntime.jsx("input", { value: String(selectedNode.props.alt), onChange: (e) => designer.updateNode(selectedNode.id, { props: { alt: e.target.value } }), style: fieldStyle })] })), jsxRuntime.jsx("hr", { style: {
518
+ }), style: fieldStyle, children: [1, 2, 3, 4, 5, 6].map((v) => (jsxRuntime.jsxs("option", { value: v, children: ["H", v] }, v))) })] })), selectedNode.props.variant !== undefined && (jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("label", { children: t('uiDesigner.variant', 'Variant') }), jsxRuntime.jsx("select", { value: String(selectedNode.props.variant), onChange: (e) => designer.updateNode(selectedNode.id, { props: { variant: e.target.value } }), style: fieldStyle, children: ['primary', 'secondary', 'outline', 'ghost'].map((v) => (jsxRuntime.jsx("option", { value: v, children: v }, v))) })] })), selectedNode.props.src !== undefined && (jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("label", { children: t('uiDesigner.imageUrl', 'Image URL') }), jsxRuntime.jsx("input", { value: String(selectedNode.props.src), onChange: (e) => designer.updateNode(selectedNode.id, { props: { src: e.target.value } }), style: fieldStyle })] })), selectedNode.props.alt !== undefined && (jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("label", { children: t('uiDesigner.altText', 'Alt Text') }), jsxRuntime.jsx("input", { value: String(selectedNode.props.alt), onChange: (e) => designer.updateNode(selectedNode.id, { props: { alt: e.target.value } }), style: fieldStyle })] })), jsxRuntime.jsx("hr", { style: {
515
519
  border: 'none',
516
520
  borderTop: '1px solid var(--nice-border, #373a40)',
517
521
  margin: '4px 0',
518
- } }), jsxRuntime.jsx("strong", { style: { color: 'var(--nice-text-secondary, #868e96)' }, children: "Style" }), ['padding', 'margin', 'gap', 'borderRadius'].map((prop) => (jsxRuntime.jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: 4 }, children: [jsxRuntime.jsx("label", { style: { minWidth: 60 }, children: prop }), jsxRuntime.jsx("input", { type: "number", value: typeof selectedNode.style[prop] === 'number'
522
+ } }), jsxRuntime.jsx("strong", { style: { color: 'var(--nice-text-secondary, #868e96)' }, children: t('uiDesigner.style', 'Style') }), ['padding', 'margin', 'gap', 'borderRadius'].map((prop) => (jsxRuntime.jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: 4 }, children: [jsxRuntime.jsx("label", { style: { minWidth: 60 }, children: prop }), jsxRuntime.jsx("input", { type: "number", value: typeof selectedNode.style[prop] === 'number'
519
523
  ? selectedNode.style[prop]
520
524
  : 0, onChange: (e) => designer.updateNode(selectedNode.id, {
521
525
  style: { [prop]: Number(e.target.value) },
@@ -545,7 +549,7 @@ const NiceUIDesigner = ({ onChange, onExport, className = '', tutorial, }) => {
545
549
  color: 'var(--nice-text-secondary, #5c5f66)',
546
550
  padding: 8,
547
551
  textAlign: 'center',
548
- }, children: "Select an element" }))] }));
552
+ }, children: t('uiDesigner.selectAnElement', 'Select an element') }))] }));
549
553
  return (jsxRuntime.jsxs("div", { className: `nice-ui-designer ${className}`, style: { position: 'relative', height: '100%' }, children: [jsxRuntime.jsx("span", { style: { position: 'absolute', top: 6, right: 6, zIndex: 20 }, children: jsxRuntime.jsx(ui.NiceTutorialButton, { steps: ui.resolveTutorial(tutorial, UI_DESIGNER_TOUR) }) }), jsxRuntime.jsx(ui.NiceAppShell, { flush: true, toolbar: toolbarContent, sidebar: leftPanel, rightSidebar: rightPanel, children: mainContent })] }));
550
554
  };
551
555
 
@@ -3,6 +3,7 @@
3
3
  var jsxRuntime = require('react/jsx-runtime');
4
4
  var uiCore = require('@nice2dev/ui-core');
5
5
  var React = require('react');
6
+ var i18n = require('../core/i18n.js');
6
7
 
7
8
  /* ── Default config ── */
8
9
  const DEFAULT_CONFIG = {
@@ -419,6 +420,7 @@ function useSvgToCode() {
419
420
  }
420
421
  /* ── Component ── */
421
422
  const NiceSvgToCode = ({ initialSvg = '', onConvert, className = '', }) => {
423
+ const { t } = i18n.useNiceTranslation();
422
424
  const { svgInput, setSvgInput, config, updateConfig, convert, result } = useSvgToCode();
423
425
  // Initialize with provided SVG
424
426
  React.useEffect(() => {
@@ -437,21 +439,21 @@ const NiceSvgToCode = ({ initialSvg = '', onConvert, className = '', }) => {
437
439
  navigator.clipboard.writeText(result.code);
438
440
  }
439
441
  };
440
- return (jsxRuntime.jsxs("div", { className: `nice-svg-to-code ${className}`, style: { display: 'grid', gap: 8, fontSize: 13 }, children: [jsxRuntime.jsxs("strong", { children: [jsxRuntime.jsx(uiCore.NiceIcon, { name: "refresh", size: 14 }), " SVG \u2192 Code"] }), jsxRuntime.jsx("textarea", { value: svgInput, onChange: (e) => setSvgInput(e.target.value), placeholder: "Paste SVG markup here\u2026", rows: 6, style: {
442
+ return (jsxRuntime.jsxs("div", { className: `nice-svg-to-code ${className}`, style: { display: 'grid', gap: 8, fontSize: 13 }, children: [jsxRuntime.jsxs("strong", { children: [jsxRuntime.jsx(uiCore.NiceIcon, { name: "refresh", size: 14 }), " SVG \u2192 Code"] }), jsxRuntime.jsx("textarea", { value: svgInput, onChange: (e) => setSvgInput(e.target.value), placeholder: t('svgToCode.pasteSvgMarkupHere', 'Paste SVG markup here…'), rows: 6, style: {
441
443
  width: '100%',
442
444
  fontFamily: 'monospace',
443
445
  fontSize: 11,
444
446
  padding: 6,
445
447
  borderRadius: 4,
446
448
  border: '1px solid var(--nice-border, #e2e8f0)',
447
- } }), jsxRuntime.jsxs("div", { style: { display: 'grid', gap: 4 }, children: [jsxRuntime.jsxs("label", { children: ["Framework:", jsxRuntime.jsxs("select", { value: config.framework, onChange: (e) => updateConfig({ framework: e.target.value }), style: { width: '100%' }, children: [jsxRuntime.jsx("option", { value: "react", children: "React (JSX/TSX)" }), jsxRuntime.jsx("option", { value: "vue", children: "Vue (SFC)" }), jsxRuntime.jsx("option", { value: "web-component", children: "Web Component" }), jsxRuntime.jsx("option", { value: "typescript", children: "TypeScript (utility)" })] })] }), jsxRuntime.jsxs("label", { children: ["Component name:", jsxRuntime.jsx("input", { type: "text", value: config.componentName, onChange: (e) => updateConfig({ componentName: e.target.value.replace(/[^a-zA-Z0-9]/g, '') }), style: { width: '100%', padding: '3px 6px' } })] }), jsxRuntime.jsxs("div", { style: { display: 'flex', gap: 8, flexWrap: 'wrap', fontSize: 11 }, children: [jsxRuntime.jsxs("label", { children: [jsxRuntime.jsx("input", { type: "checkbox", checked: config.typescript, onChange: (e) => updateConfig({ typescript: e.target.checked }) }), ' ', "TypeScript"] }), jsxRuntime.jsxs("label", { children: [jsxRuntime.jsx("input", { type: "checkbox", checked: config.optimize, onChange: (e) => updateConfig({ optimize: e.target.checked }) }), ' ', "Optimize"] }), jsxRuntime.jsxs("label", { children: [jsxRuntime.jsx("input", { type: "checkbox", checked: config.sizeProps, onChange: (e) => updateConfig({ sizeProps: e.target.checked }) }), ' ', "Size props"] }), jsxRuntime.jsxs("label", { children: [jsxRuntime.jsx("input", { type: "checkbox", checked: config.useCurrentColor, onChange: (e) => updateConfig({ useCurrentColor: e.target.checked }) }), ' ', "currentColor"] }), jsxRuntime.jsxs("label", { children: [jsxRuntime.jsx("input", { type: "checkbox", checked: config.memo, onChange: (e) => updateConfig({ memo: e.target.checked }) }), ' ', "memo"] })] })] }), jsxRuntime.jsxs("button", { type: "button", onClick: handleConvert, disabled: !svgInput.trim(), style: {
449
+ } }), jsxRuntime.jsxs("div", { style: { display: 'grid', gap: 4 }, children: [jsxRuntime.jsxs("label", { children: ["Framework:", jsxRuntime.jsxs("select", { value: config.framework, onChange: (e) => updateConfig({ framework: e.target.value }), style: { width: '100%' }, children: [jsxRuntime.jsx("option", { value: "react", children: "React (JSX/TSX)" }), jsxRuntime.jsx("option", { value: "vue", children: "Vue (SFC)" }), jsxRuntime.jsx("option", { value: "web-component", children: t('svgToCode.webComponent', 'Web Component') }), jsxRuntime.jsx("option", { value: "typescript", children: "TypeScript (utility)" })] })] }), jsxRuntime.jsxs("label", { children: ["Component name:", jsxRuntime.jsx("input", { type: "text", value: config.componentName, onChange: (e) => updateConfig({ componentName: e.target.value.replace(/[^a-zA-Z0-9]/g, '') }), style: { width: '100%', padding: '3px 6px' } })] }), jsxRuntime.jsxs("div", { style: { display: 'flex', gap: 8, flexWrap: 'wrap', fontSize: 11 }, children: [jsxRuntime.jsxs("label", { children: [jsxRuntime.jsx("input", { type: "checkbox", checked: config.typescript, onChange: (e) => updateConfig({ typescript: e.target.checked }) }), ' ', t('svgToCode.typescript', 'TypeScript')] }), jsxRuntime.jsxs("label", { children: [jsxRuntime.jsx("input", { type: "checkbox", checked: config.optimize, onChange: (e) => updateConfig({ optimize: e.target.checked }) }), ' ', t('svgToCode.optimize', 'Optimize')] }), jsxRuntime.jsxs("label", { children: [jsxRuntime.jsx("input", { type: "checkbox", checked: config.sizeProps, onChange: (e) => updateConfig({ sizeProps: e.target.checked }) }), ' ', t('svgToCode.sizeProps', 'Size props')] }), jsxRuntime.jsxs("label", { children: [jsxRuntime.jsx("input", { type: "checkbox", checked: config.useCurrentColor, onChange: (e) => updateConfig({ useCurrentColor: e.target.checked }) }), ' ', "currentColor"] }), jsxRuntime.jsxs("label", { children: [jsxRuntime.jsx("input", { type: "checkbox", checked: config.memo, onChange: (e) => updateConfig({ memo: e.target.checked }) }), ' ', "memo"] })] })] }), jsxRuntime.jsxs("button", { type: "button", onClick: handleConvert, disabled: !svgInput.trim(), style: {
448
450
  background: 'var(--nice-color-accent, #6366f1)',
449
451
  color: 'var(--nice-text-on-primary, #fff)',
450
452
  border: 'none',
451
453
  borderRadius: 4,
452
454
  padding: '8px 12px',
453
455
  cursor: 'pointer',
454
- }, children: [jsxRuntime.jsx(uiCore.NiceIcon, { name: "refresh", size: 14 }), " Convert to", ' ', config.framework.charAt(0).toUpperCase() + config.framework.slice(1)] }), result && (jsxRuntime.jsxs("div", { children: [jsxRuntime.jsxs("div", { style: {
456
+ }, children: [jsxRuntime.jsx(uiCore.NiceIcon, { name: "refresh", size: 14 }), ' ', t('svgToCode.convertTo', 'Convert to {framework}').replace('{framework}', config.framework.charAt(0).toUpperCase() + config.framework.slice(1))] }), result && (jsxRuntime.jsxs("div", { children: [jsxRuntime.jsxs("div", { style: {
455
457
  display: 'flex',
456
458
  justifyContent: 'space-between',
457
459
  alignItems: 'center',
@@ -463,7 +465,7 @@ const NiceSvgToCode = ({ initialSvg = '', onConvert, className = '', }) => {
463
465
  borderRadius: 3,
464
466
  border: '1px solid var(--nice-border, #e2e8f0)',
465
467
  background: 'transparent',
466
- }, children: [jsxRuntime.jsx(uiCore.NiceIcon, { name: "clipboard", size: 12 }), " Copy"] })] }), jsxRuntime.jsx("pre", { style: {
468
+ }, children: [jsxRuntime.jsx(uiCore.NiceIcon, { name: "clipboard", size: 12 }), " ", t('svgToCode.copy', 'Copy')] })] }), jsxRuntime.jsx("pre", { style: {
467
469
  background: 'var(--nice-code-bg, #1e293b)',
468
470
  color: 'var(--nice-code-color, #e2e8f0)',
469
471
  padding: 8,