@nice2dev/ui-graphics 1.2.0 → 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.
- package/CHANGELOG.md +103 -0
- package/dist/cjs/animation/Audience.js +3 -1
- package/dist/cjs/animation/rig/RigPlayer.js +1 -1
- package/dist/cjs/animation/rig/presets.js +67 -55
- package/dist/cjs/animation/shapes/headwear.js +4 -1
- package/dist/cjs/core/NiceBrushEngine.js +5 -3
- package/dist/cjs/core/editorAsk.js +48 -0
- package/dist/cjs/core/i18n.js +7 -3
- package/dist/cjs/core/plugins.js +1 -1
- package/dist/cjs/core/rtl.js +1 -1
- package/dist/cjs/core/theme.js +1 -1
- package/dist/cjs/font/NiceFontEditor.js +13 -11
- package/dist/cjs/game/GameAsset2dEditor.js +28 -16
- package/dist/cjs/nice2dev-ui-graphics.css +1 -1
- package/dist/cjs/photo/FilterThumb.js +3 -3
- package/dist/cjs/photo/NiceAITools.js +5 -3
- package/dist/cjs/photo/PhotoEditor.js +3 -1
- package/dist/cjs/photo/PhotoEditorCanvas.js +8 -6
- package/dist/cjs/photo/PhotoEditorLeftPanel.js +19 -19
- package/dist/cjs/photo/PhotoEditorToolbar.js +4 -4
- package/dist/cjs/photo/photoFilters.js +1 -0
- package/dist/cjs/pixel/PixelEditor.js +6 -3
- package/dist/cjs/pixel/PixelEditorCanvas.js +10 -6
- package/dist/cjs/pixel/PixelEditorMenuBar.js +3 -3
- package/dist/cjs/pixel/PixelEditorRightPanel.js +28 -24
- package/dist/cjs/pixel/PixelEditorStatusBar.js +8 -4
- package/dist/cjs/pixel/PixelEditorTimeline.js +11 -2
- package/dist/cjs/pixel/PixelEditorToolbar.js +10 -6
- package/dist/cjs/pixel/SpriteGeneratorPanel.js +11 -7
- package/dist/cjs/pixel/animalGeneratorPresets.js +31 -31
- package/dist/cjs/pixel/buildingGeneratorPresets.js +24 -24
- package/dist/cjs/pixel/characterGeneratorPresets.js +25 -25
- package/dist/cjs/pixel/usePixelEditor.js +13 -10
- package/dist/cjs/texture/Nice3DTexturePainter.js +10 -8
- package/dist/cjs/ui/NiceUIDesigner.js +17 -13
- package/dist/cjs/vector/NiceSvgToCode.js +6 -4
- package/dist/cjs/vector/VectorEditor.js +3 -2
- package/dist/cjs/vector/VectorEditorShapeRenderer.js +3 -1
- package/dist/cjs/vector/useVectorEditor.js +38 -29
- package/dist/cjs/vector/vectorEditorImport.js +1 -0
- package/dist/cjs/vector/vectorIconImport.js +1 -0
- package/dist/esm/animation/Audience.js +3 -1
- package/dist/esm/animation/rig/RigPlayer.js +1 -1
- package/dist/esm/animation/rig/presets.js +68 -56
- package/dist/esm/animation/shapes/headwear.js +4 -1
- package/dist/esm/animation/spineExport.js +1 -1
- package/dist/esm/core/NiceBrushEngine.js +5 -3
- package/dist/esm/core/editorAsk.js +45 -0
- package/dist/esm/core/i18n.js +8 -4
- package/dist/esm/core/plugins.js +1 -1
- package/dist/esm/core/rtl.js +1 -1
- package/dist/esm/core/theme.js +1 -1
- package/dist/esm/font/NiceFontEditor.js +13 -11
- package/dist/esm/game/GameAsset2dEditor.js +28 -16
- package/dist/esm/nice2dev-ui-graphics.css +1 -1
- package/dist/esm/photo/FilterThumb.js +3 -3
- package/dist/esm/photo/NiceAITools.js +5 -3
- package/dist/esm/photo/PhotoEditor.js +3 -1
- package/dist/esm/photo/PhotoEditorCanvas.js +8 -6
- package/dist/esm/photo/PhotoEditorLeftPanel.js +19 -19
- package/dist/esm/photo/PhotoEditorToolbar.js +4 -4
- package/dist/esm/photo/photoFilters.js +1 -0
- package/dist/esm/pixel/PixelEditor.js +6 -3
- package/dist/esm/pixel/PixelEditorCanvas.js +10 -6
- package/dist/esm/pixel/PixelEditorMenuBar.js +3 -3
- package/dist/esm/pixel/PixelEditorRightPanel.js +28 -24
- package/dist/esm/pixel/PixelEditorStatusBar.js +8 -4
- package/dist/esm/pixel/PixelEditorTimeline.js +11 -2
- package/dist/esm/pixel/PixelEditorToolbar.js +10 -6
- package/dist/esm/pixel/SpriteGeneratorPanel.js +11 -7
- package/dist/esm/pixel/animalGeneratorPresets.js +32 -32
- package/dist/esm/pixel/buildingGeneratorPresets.js +25 -25
- package/dist/esm/pixel/characterGeneratorPresets.js +26 -26
- package/dist/esm/pixel/usePixelEditor.js +13 -10
- package/dist/esm/texture/Nice3DTexturePainter.js +10 -8
- package/dist/esm/ui/NiceUIDesigner.js +17 -13
- package/dist/esm/vector/NiceSvgToCode.js +6 -4
- package/dist/esm/vector/VectorEditor.js +3 -2
- package/dist/esm/vector/VectorEditorShapeRenderer.js +3 -1
- package/dist/esm/vector/useVectorEditor.js +38 -29
- package/dist/esm/vector/vectorEditorImport.js +1 -0
- package/dist/esm/vector/vectorIconImport.js +1 -0
- package/dist/types/core/LocalUI.d.ts +1 -2
- package/dist/types/core/editorAsk.d.ts +26 -0
- package/dist/types/core/i18n.d.ts +1 -17
- package/dist/types/pixel/usePixelEditor.d.ts +3 -0
- package/dist/types/vector/useVectorEditor.d.ts +2 -0
- 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
|
|
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
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
}
|
|
842
|
-
|
|
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);
|
|
@@ -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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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,7 +384,7 @@ 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:
|
|
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
|
|
@@ -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":
|
|
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:
|
|
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);
|
|
@@ -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
|
|
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
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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 }),
|
|
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
|
|
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,
|