@nice2dev/ui-graphics 1.3.15 → 1.3.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (294) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/cjs/animation/AnimatedPerson.js +470 -143
  3. package/dist/cjs/animation/AnimationEditor.js +289 -101
  4. package/dist/cjs/animation/Audience.js +83 -61
  5. package/dist/cjs/animation/BodyRenderer.js +69 -28
  6. package/dist/cjs/animation/animationHelper.js +281 -288
  7. package/dist/cjs/animation/characterTypes.js +200 -203
  8. package/dist/cjs/animation/choreoDSL.js +205 -219
  9. package/dist/cjs/animation/choreography.js +4 -32
  10. package/dist/cjs/animation/karaokeIntegration.js +68 -77
  11. package/dist/cjs/animation/lottieExport.js +108 -114
  12. package/dist/cjs/animation/motionPath.js +225 -248
  13. package/dist/cjs/animation/physics.js +227 -254
  14. package/dist/cjs/animation/rig/RigPlayer.js +53 -56
  15. package/dist/cjs/animation/rig/RiggedBody.js +71 -26
  16. package/dist/cjs/animation/rig/choreoRigBridge.js +72 -77
  17. package/dist/cjs/animation/rig/ik.js +13 -18
  18. package/dist/cjs/animation/rig/poseOps.js +34 -41
  19. package/dist/cjs/animation/rig/presets.js +64 -72
  20. package/dist/cjs/animation/rig/rigMath.js +25 -32
  21. package/dist/cjs/animation/rig/rigTypes.js +59 -63
  22. package/dist/cjs/animation/shapes/arms.js +31 -13
  23. package/dist/cjs/animation/shapes/eyes.js +129 -47
  24. package/dist/cjs/animation/shapes/hair.js +72 -45
  25. package/dist/cjs/animation/shapes/heads.js +131 -57
  26. package/dist/cjs/animation/shapes/headwear.js +47 -38
  27. package/dist/cjs/animation/shapes/legs.js +31 -13
  28. package/dist/cjs/animation/shapes/mouths.js +120 -44
  29. package/dist/cjs/animation/shapes/noses.js +80 -25
  30. package/dist/cjs/animation/shapes/outfits.js +101 -39
  31. package/dist/cjs/animation/shapes/torsos.js +15 -11
  32. package/dist/cjs/animation/spineExport.js +103 -121
  33. package/dist/cjs/core/LocalUI.js +108 -43
  34. package/dist/cjs/core/NiceBrushEngine.js +758 -552
  35. package/dist/cjs/core/collaboration.js +249 -251
  36. package/dist/cjs/core/colorBlindness.js +100 -115
  37. package/dist/cjs/core/dragDrop.js +155 -158
  38. package/dist/cjs/core/editorAsk.js +51 -41
  39. package/dist/cjs/core/fixes.js +140 -171
  40. package/dist/cjs/core/gridGuides.js +166 -201
  41. package/dist/cjs/core/historyVisual.js +156 -135
  42. package/dist/cjs/core/i18n.js +13 -14
  43. package/dist/cjs/core/integrations.js +238 -249
  44. package/dist/cjs/core/minimap.js +149 -151
  45. package/dist/cjs/core/plugins.js +98 -113
  46. package/dist/cjs/core/rtl.js +71 -83
  47. package/dist/cjs/core/shortcuts.js +196 -225
  48. package/dist/cjs/core/theme.js +142 -149
  49. package/dist/cjs/core/yjsCollaboration.js +232 -293
  50. package/dist/cjs/design/design-tools.js +12 -22
  51. package/dist/cjs/font/NiceFontEditor.js +877 -316
  52. package/dist/cjs/font/fontFormatUtils.js +388 -448
  53. package/dist/cjs/game/GameAsset2dEditor.js +1201 -392
  54. package/dist/cjs/game/GameAsset2dEditor.module.css.js +146 -5
  55. package/dist/cjs/game/gameAssetTypes.js +7 -16
  56. package/dist/cjs/game/gameAssetUtils.js +390 -413
  57. package/dist/cjs/game/useGameAssetEditor.js +820 -763
  58. package/dist/cjs/index.js +81 -84
  59. package/dist/cjs/nice2dev-ui-graphics.css +1 -1
  60. package/dist/cjs/node_modules/lib0/array.js +8 -70
  61. package/dist/cjs/node_modules/lib0/binary.js +3 -20
  62. package/dist/cjs/node_modules/lib0/broadcastchannel.js +24 -86
  63. package/dist/cjs/node_modules/lib0/buffer.js +15 -82
  64. package/dist/cjs/node_modules/lib0/conditions.js +3 -16
  65. package/dist/cjs/node_modules/lib0/decoding.js +108 -287
  66. package/dist/cjs/node_modules/lib0/dom.js +14 -44
  67. package/dist/cjs/node_modules/lib0/encoding.js +68 -418
  68. package/dist/cjs/node_modules/lib0/environment.js +26 -92
  69. package/dist/cjs/node_modules/lib0/error.js +5 -29
  70. package/dist/cjs/node_modules/lib0/function.js +27 -66
  71. package/dist/cjs/node_modules/lib0/iterator.js +8 -33
  72. package/dist/cjs/node_modules/lib0/logging.common.js +12 -22
  73. package/dist/cjs/node_modules/lib0/logging.js +32 -71
  74. package/dist/cjs/node_modules/lib0/map.js +16 -86
  75. package/dist/cjs/node_modules/lib0/math.js +3 -32
  76. package/dist/cjs/node_modules/lib0/number.js +4 -15
  77. package/dist/cjs/node_modules/lib0/object.js +14 -88
  78. package/dist/cjs/node_modules/lib0/observable.js +38 -78
  79. package/dist/cjs/node_modules/lib0/pair.js +3 -20
  80. package/dist/cjs/node_modules/lib0/prng.js +8 -77
  81. package/dist/cjs/node_modules/lib0/promise.js +6 -30
  82. package/dist/cjs/node_modules/lib0/random.js +8 -23
  83. package/dist/cjs/node_modules/lib0/schema.js +313 -687
  84. package/dist/cjs/node_modules/lib0/set.js +3 -10
  85. package/dist/cjs/node_modules/lib0/storage.js +20 -55
  86. package/dist/cjs/node_modules/lib0/string.js +17 -72
  87. package/dist/cjs/node_modules/lib0/symbol.js +2 -12
  88. package/dist/cjs/node_modules/lib0/time.js +2 -15
  89. package/dist/cjs/node_modules/lib0/trait/equality.js +3 -28
  90. package/dist/cjs/node_modules/lib0/url.js +4 -18
  91. package/dist/cjs/node_modules/lib0/webcrypto.js +2 -5
  92. package/dist/cjs/node_modules/y-protocols/auth.js +5 -19
  93. package/dist/cjs/node_modules/y-protocols/awareness.js +53 -116
  94. package/dist/cjs/node_modules/y-protocols/sync.js +16 -103
  95. package/dist/cjs/node_modules/y-websocket/src/y-websocket.js +77 -219
  96. package/dist/cjs/node_modules/yjs/dist/yjs.js +2128 -4868
  97. package/dist/cjs/photo/FilterThumb.js +37 -25
  98. package/dist/cjs/photo/NiceAITools.js +679 -467
  99. package/dist/cjs/photo/PhotoEditor.js +34 -20
  100. package/dist/cjs/photo/PhotoEditor.module.css.js +296 -5
  101. package/dist/cjs/photo/PhotoEditorCanvas.js +250 -91
  102. package/dist/cjs/photo/PhotoEditorLeftPanel.js +1086 -224
  103. package/dist/cjs/photo/PhotoEditorToolbar.js +135 -19
  104. package/dist/cjs/photo/photoEditorActions.js +89 -72
  105. package/dist/cjs/photo/photoEditorTypes.js +29 -32
  106. package/dist/cjs/photo/photoFilters.js +959 -985
  107. package/dist/cjs/photo/photoOverlays.js +899 -945
  108. package/dist/cjs/photo/photoSelection.js +427 -499
  109. package/dist/cjs/photo/usePhotoEditor.js +739 -741
  110. package/dist/cjs/pixel/HSVPicker.js +191 -175
  111. package/dist/cjs/pixel/PixelEditor.js +159 -48
  112. package/dist/cjs/pixel/PixelEditor.module.css.js +209 -5
  113. package/dist/cjs/pixel/PixelEditorCanvas.js +29 -16
  114. package/dist/cjs/pixel/PixelEditorMenuBar.js +160 -162
  115. package/dist/cjs/pixel/PixelEditorRightPanel.js +377 -45
  116. package/dist/cjs/pixel/PixelEditorStatusBar.js +47 -20
  117. package/dist/cjs/pixel/PixelEditorTimeline.js +106 -23
  118. package/dist/cjs/pixel/PixelEditorToolbar.js +99 -21
  119. package/dist/cjs/pixel/SpriteGeneratorPanel.js +483 -303
  120. package/dist/cjs/pixel/animalGeneratorPresets.js +776 -601
  121. package/dist/cjs/pixel/asepriteFormat.js +511 -560
  122. package/dist/cjs/pixel/buildingGeneratorPresets.js +693 -520
  123. package/dist/cjs/pixel/characterGeneratorPresets.js +644 -544
  124. package/dist/cjs/pixel/pixel-pro.js +52 -63
  125. package/dist/cjs/pixel/pixelEditorExports.js +388 -428
  126. package/dist/cjs/pixel/pixelEditorTypes.js +91 -108
  127. package/dist/cjs/pixel/pixelEditorUtils.js +519 -561
  128. package/dist/cjs/pixel/spriteGeneratorCore.js +206 -257
  129. package/dist/cjs/pixel/usePixelEditor.js +1321 -1343
  130. package/dist/cjs/texture/Nice3DTexturePainter.js +707 -440
  131. package/dist/cjs/ui/NiceUIDesigner.js +954 -527
  132. package/dist/cjs/vector/NiceSvgToCode.js +586 -446
  133. package/dist/cjs/vector/VectorEditor.js +290 -117
  134. package/dist/cjs/vector/VectorEditor.module.css.js +86 -5
  135. package/dist/cjs/vector/VectorEditorMenuBar.js +333 -275
  136. package/dist/cjs/vector/VectorEditorRightPanel.js +1094 -371
  137. package/dist/cjs/vector/VectorEditorShapeRenderer.js +198 -60
  138. package/dist/cjs/vector/VectorEditorStatusBar.js +39 -13
  139. package/dist/cjs/vector/useVectorEditor.js +848 -889
  140. package/dist/cjs/vector/vectorAnimation.js +110 -137
  141. package/dist/cjs/vector/vectorBooleanOps.js +398 -485
  142. package/dist/cjs/vector/vectorEditorExport.js +201 -203
  143. package/dist/cjs/vector/vectorEditorImport.js +173 -189
  144. package/dist/cjs/vector/vectorEditorTypes.js +42 -49
  145. package/dist/cjs/vector/vectorGradients.js +151 -174
  146. package/dist/cjs/vector/vectorIconExport.js +52 -59
  147. package/dist/cjs/vector/vectorIconImport.js +169 -219
  148. package/dist/esm/animation/AnimatedPerson.js +470 -141
  149. package/dist/esm/animation/AnimationEditor.js +290 -100
  150. package/dist/esm/animation/Audience.js +83 -59
  151. package/dist/esm/animation/BodyRenderer.js +71 -25
  152. package/dist/esm/animation/animationHelper.js +284 -287
  153. package/dist/esm/animation/characterTypes.js +204 -202
  154. package/dist/esm/animation/choreoDSL.js +212 -218
  155. package/dist/esm/animation/choreography.js +8 -31
  156. package/dist/esm/animation/karaokeIntegration.js +74 -76
  157. package/dist/esm/animation/lottieExport.js +112 -113
  158. package/dist/esm/animation/motionPath.js +235 -247
  159. package/dist/esm/animation/physics.js +235 -253
  160. package/dist/esm/animation/rig/RigPlayer.js +53 -54
  161. package/dist/esm/animation/rig/RiggedBody.js +71 -24
  162. package/dist/esm/animation/rig/choreoRigBridge.js +74 -76
  163. package/dist/esm/animation/rig/ik.js +14 -17
  164. package/dist/esm/animation/rig/poseOps.js +37 -40
  165. package/dist/esm/animation/rig/presets.js +70 -71
  166. package/dist/esm/animation/rig/rigMath.js +28 -31
  167. package/dist/esm/animation/rig/rigTypes.js +62 -62
  168. package/dist/esm/animation/shapes/arms.js +32 -12
  169. package/dist/esm/animation/shapes/eyes.js +135 -46
  170. package/dist/esm/animation/shapes/hair.js +80 -44
  171. package/dist/esm/animation/shapes/heads.js +140 -56
  172. package/dist/esm/animation/shapes/headwear.js +54 -37
  173. package/dist/esm/animation/shapes/legs.js +32 -12
  174. package/dist/esm/animation/shapes/mouths.js +127 -43
  175. package/dist/esm/animation/shapes/noses.js +87 -24
  176. package/dist/esm/animation/shapes/outfits.js +106 -38
  177. package/dist/esm/animation/shapes/torsos.js +16 -10
  178. package/dist/esm/animation/spineExport.js +106 -120
  179. package/dist/esm/core/LocalUI.js +111 -42
  180. package/dist/esm/core/NiceBrushEngine.js +761 -551
  181. package/dist/esm/core/collaboration.js +255 -250
  182. package/dist/esm/core/colorBlindness.js +106 -114
  183. package/dist/esm/core/dragDrop.js +157 -157
  184. package/dist/esm/core/editorAsk.js +53 -40
  185. package/dist/esm/core/fixes.js +145 -170
  186. package/dist/esm/core/gridGuides.js +178 -200
  187. package/dist/esm/core/historyVisual.js +158 -134
  188. package/dist/esm/core/i18n.js +15 -13
  189. package/dist/esm/core/integrations.js +244 -248
  190. package/dist/esm/core/minimap.js +151 -150
  191. package/dist/esm/core/plugins.js +102 -112
  192. package/dist/esm/core/rtl.js +77 -82
  193. package/dist/esm/core/shortcuts.js +200 -224
  194. package/dist/esm/core/theme.js +150 -148
  195. package/dist/esm/core/yjsCollaboration.js +240 -292
  196. package/dist/esm/design/design-tools.js +13 -21
  197. package/dist/esm/font/NiceFontEditor.js +880 -315
  198. package/dist/esm/font/fontFormatUtils.js +394 -447
  199. package/dist/esm/game/GameAsset2dEditor.js +1202 -391
  200. package/dist/esm/game/GameAsset2dEditor.module.css.js +146 -3
  201. package/dist/esm/game/gameAssetTypes.js +8 -15
  202. package/dist/esm/game/gameAssetUtils.js +408 -412
  203. package/dist/esm/game/useGameAssetEditor.js +821 -762
  204. package/dist/esm/index.js +332 -69
  205. package/dist/esm/nice2dev-ui-graphics.css +1 -1
  206. package/dist/esm/node_modules/lib0/array.js +15 -69
  207. package/dist/esm/node_modules/lib0/binary.js +14 -19
  208. package/dist/esm/node_modules/lib0/broadcastchannel.js +27 -85
  209. package/dist/esm/node_modules/lib0/buffer.js +20 -80
  210. package/dist/esm/node_modules/lib0/conditions.js +4 -15
  211. package/dist/esm/node_modules/lib0/decoding.js +128 -286
  212. package/dist/esm/node_modules/lib0/dom.js +20 -43
  213. package/dist/esm/node_modules/lib0/encoding.js +90 -415
  214. package/dist/esm/node_modules/lib0/environment.js +33 -91
  215. package/dist/esm/node_modules/lib0/error.js +8 -28
  216. package/dist/esm/node_modules/lib0/function.js +31 -65
  217. package/dist/esm/node_modules/lib0/iterator.js +11 -32
  218. package/dist/esm/node_modules/lib0/logging.common.js +22 -21
  219. package/dist/esm/node_modules/lib0/logging.js +44 -70
  220. package/dist/esm/node_modules/lib0/map.js +21 -85
  221. package/dist/esm/node_modules/lib0/math.js +9 -31
  222. package/dist/esm/node_modules/lib0/number.js +7 -14
  223. package/dist/esm/node_modules/lib0/object.js +26 -87
  224. package/dist/esm/node_modules/lib0/observable.js +40 -77
  225. package/dist/esm/node_modules/lib0/pair.js +5 -19
  226. package/dist/esm/node_modules/lib0/prng.js +15 -76
  227. package/dist/esm/node_modules/lib0/promise.js +7 -29
  228. package/dist/esm/node_modules/lib0/random.js +10 -22
  229. package/dist/esm/node_modules/lib0/schema.js +367 -686
  230. package/dist/esm/node_modules/lib0/set.js +4 -9
  231. package/dist/esm/node_modules/lib0/storage.js +23 -54
  232. package/dist/esm/node_modules/lib0/string.js +26 -71
  233. package/dist/esm/node_modules/lib0/symbol.js +3 -11
  234. package/dist/esm/node_modules/lib0/time.js +3 -14
  235. package/dist/esm/node_modules/lib0/trait/equality.js +5 -27
  236. package/dist/esm/node_modules/lib0/url.js +5 -17
  237. package/dist/esm/node_modules/lib0/webcrypto.js +3 -4
  238. package/dist/esm/node_modules/y-protocols/auth.js +7 -18
  239. package/dist/esm/node_modules/y-protocols/awareness.js +58 -115
  240. package/dist/esm/node_modules/y-protocols/sync.js +26 -102
  241. package/dist/esm/node_modules/y-websocket/src/y-websocket.js +82 -218
  242. package/dist/esm/node_modules/yjs/dist/yjs.js +2263 -4899
  243. package/dist/esm/photo/FilterThumb.js +37 -23
  244. package/dist/esm/photo/NiceAITools.js +685 -466
  245. package/dist/esm/photo/PhotoEditor.js +34 -18
  246. package/dist/esm/photo/PhotoEditor.module.css.js +296 -3
  247. package/dist/esm/photo/PhotoEditorCanvas.js +250 -89
  248. package/dist/esm/photo/PhotoEditorLeftPanel.js +1086 -222
  249. package/dist/esm/photo/PhotoEditorToolbar.js +135 -17
  250. package/dist/esm/photo/photoEditorActions.js +93 -71
  251. package/dist/esm/photo/photoEditorTypes.js +32 -31
  252. package/dist/esm/photo/photoFilters.js +967 -984
  253. package/dist/esm/photo/photoOverlays.js +913 -944
  254. package/dist/esm/photo/photoSelection.js +438 -498
  255. package/dist/esm/photo/usePhotoEditor.js +740 -740
  256. package/dist/esm/pixel/HSVPicker.js +192 -174
  257. package/dist/esm/pixel/PixelEditor.js +160 -47
  258. package/dist/esm/pixel/PixelEditor.module.css.js +209 -3
  259. package/dist/esm/pixel/PixelEditorCanvas.js +29 -14
  260. package/dist/esm/pixel/PixelEditorMenuBar.js +160 -160
  261. package/dist/esm/pixel/PixelEditorRightPanel.js +377 -43
  262. package/dist/esm/pixel/PixelEditorStatusBar.js +47 -18
  263. package/dist/esm/pixel/PixelEditorTimeline.js +106 -21
  264. package/dist/esm/pixel/PixelEditorToolbar.js +99 -19
  265. package/dist/esm/pixel/SpriteGeneratorPanel.js +483 -301
  266. package/dist/esm/pixel/animalGeneratorPresets.js +782 -600
  267. package/dist/esm/pixel/asepriteFormat.js +517 -559
  268. package/dist/esm/pixel/buildingGeneratorPresets.js +699 -519
  269. package/dist/esm/pixel/characterGeneratorPresets.js +650 -543
  270. package/dist/esm/pixel/pixel-pro.js +53 -62
  271. package/dist/esm/pixel/pixelEditorExports.js +397 -427
  272. package/dist/esm/pixel/pixelEditorTypes.js +103 -107
  273. package/dist/esm/pixel/pixelEditorUtils.js +551 -560
  274. package/dist/esm/pixel/spriteGeneratorCore.js +223 -256
  275. package/dist/esm/pixel/usePixelEditor.js +1322 -1342
  276. package/dist/esm/texture/Nice3DTexturePainter.js +709 -439
  277. package/dist/esm/ui/NiceUIDesigner.js +957 -526
  278. package/dist/esm/vector/NiceSvgToCode.js +589 -445
  279. package/dist/esm/vector/VectorEditor.js +291 -116
  280. package/dist/esm/vector/VectorEditor.module.css.js +86 -3
  281. package/dist/esm/vector/VectorEditorMenuBar.js +333 -273
  282. package/dist/esm/vector/VectorEditorRightPanel.js +1094 -369
  283. package/dist/esm/vector/VectorEditorShapeRenderer.js +199 -59
  284. package/dist/esm/vector/VectorEditorStatusBar.js +39 -11
  285. package/dist/esm/vector/useVectorEditor.js +849 -888
  286. package/dist/esm/vector/vectorAnimation.js +115 -136
  287. package/dist/esm/vector/vectorBooleanOps.js +401 -484
  288. package/dist/esm/vector/vectorEditorExport.js +207 -202
  289. package/dist/esm/vector/vectorEditorImport.js +174 -188
  290. package/dist/esm/vector/vectorEditorTypes.js +50 -48
  291. package/dist/esm/vector/vectorGradients.js +158 -173
  292. package/dist/esm/vector/vectorIconExport.js +53 -58
  293. package/dist/esm/vector/vectorIconImport.js +171 -218
  294. package/package.json +9 -15
@@ -1,319 +1,501 @@
1
- import { jsx, jsxs } from 'react/jsx-runtime';
2
- import { NiceModal, NiceButton, NiceSelect, NiceNumberInput, NiceCheckbox } from '@nice2dev/ui';
3
- import { NiceIcon } from '@nice2dev/ui-core';
4
- import { useState, useRef, useEffect, useMemo, useCallback } from 'react';
5
- import { useNiceTranslation } from '../core/i18n.js';
6
- import { ANIMAL_PRESETS, initAnimalParts, FUR_PALETTES } from './animalGeneratorPresets.js';
7
- import { BUILDING_PRESETS, assembleBuildingFromConfig, initBuildingParts, WALL_PALETTES, ROOF_PALETTES } from './buildingGeneratorPresets.js';
8
- import { CHARACTER_PRESETS, initCharacterParts, SKIN_PALETTES, HAIR_PALETTES, CLOTHING_PALETTES } from './characterGeneratorPresets.js';
9
- import styles from './PixelEditor.module.css.js';
10
- import { getAllParts, assembleSprite, applyIsometricProjection, getPart, generateAllDirections, render8DirSpriteSheet, getPartsByCategory, ALL_DIRECTIONS } from './spriteGeneratorCore.js';
11
-
12
- /* ════════════════════════════════════════════════════════════════
13
- INITIALIZATION
14
- ════════════════════════════════════════════════════════════════ */
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { NiceModal, NiceButton, NiceSelect, NiceNumberInput, NiceCheckbox } from "@nice2dev/ui";
3
+ import { NiceIcon } from "@nice2dev/ui-core";
4
+ import { useState, useRef, useEffect, useMemo, useCallback } from "react";
5
+ import { useNiceTranslation } from "../core/i18n.js";
6
+ import { ANIMAL_PRESETS, initAnimalParts, FUR_PALETTES } from "./animalGeneratorPresets.js";
7
+ import { BUILDING_PRESETS, assembleBuildingFromConfig, initBuildingParts, WALL_PALETTES, ROOF_PALETTES } from "./buildingGeneratorPresets.js";
8
+ import { CHARACTER_PRESETS, initCharacterParts, SKIN_PALETTES, HAIR_PALETTES, CLOTHING_PALETTES } from "./characterGeneratorPresets.js";
9
+ import styles from "./PixelEditor.module.css.js";
10
+ import { getAllParts, assembleSprite, applyIsometricProjection, getPart, generateAllDirections, render8DirSpriteSheet, getPartsByCategory, ALL_DIRECTIONS } from "./spriteGeneratorCore.js";
15
11
  let _initialized = false;
16
12
  function ensureInitialized() {
17
- if (_initialized) {
18
- return;
19
- }
20
- _initialized = true;
21
- initCharacterParts();
22
- initBuildingParts();
23
- initAnimalParts();
13
+ if (_initialized) {
14
+ return;
15
+ }
16
+ _initialized = true;
17
+ initCharacterParts();
18
+ initBuildingParts();
19
+ initAnimalParts();
24
20
  }
25
- /* ════════════════════════════════════════════════════════════════
26
- HELPERS
27
- ════════════════════════════════════════════════════════════════ */
28
21
  function palettesToOptions(palettes) {
29
- return Object.entries(palettes).map(([id, colors]) => ({
30
- id,
31
- name: id.replace(/_/g, ' ').replace(/\b\w/g, (c) => c.toUpperCase()),
32
- colors,
33
- }));
22
+ return Object.entries(palettes).map(([id, colors]) => ({
23
+ id,
24
+ name: id.replace(/_/g, " ").replace(/\b\w/g, (c) => c.toUpperCase()),
25
+ colors
26
+ }));
34
27
  }
35
28
  const CHAR_CATEGORIES = [
36
- 'head',
37
- 'hair',
38
- 'face',
39
- 'torso',
40
- 'arm',
41
- 'leg',
42
- 'hat',
43
- 'helmet',
44
- 'armor',
45
- 'cape',
46
- 'weapon',
47
- 'shield',
29
+ "head",
30
+ "hair",
31
+ "face",
32
+ "torso",
33
+ "arm",
34
+ "leg",
35
+ "hat",
36
+ "helmet",
37
+ "armor",
38
+ "cape",
39
+ "weapon",
40
+ "shield"
48
41
  ];
49
42
  const BUILDING_CATEGORIES = [
50
- 'foundation',
51
- 'wall',
52
- 'floor',
53
- 'roof',
54
- 'door',
55
- 'window',
56
- 'chimney',
57
- 'decoration',
43
+ "foundation",
44
+ "wall",
45
+ "floor",
46
+ "roof",
47
+ "door",
48
+ "window",
49
+ "chimney",
50
+ "decoration"
58
51
  ];
59
52
  const ANIMAL_CATEGORIES = [
60
- 'animalHead',
61
- 'animalBody',
62
- 'animalLeg',
63
- 'animalTail',
64
- 'animalWing',
65
- 'animalMane',
53
+ "animalHead",
54
+ "animalBody",
55
+ "animalLeg",
56
+ "animalTail",
57
+ "animalWing",
58
+ "animalMane"
66
59
  ];
67
- const NiceSpriteGeneratorPanel = ({ onSendToCanvas, onClose, mode,
68
- // presets and onGenerate are exposed for forward-compat; not currently consumed.
69
- }) => {
70
- const { t } = useNiceTranslation();
71
- ensureInitialized();
72
- /* ── State ── */
73
- const [tab, setTab] = useState(mode !== null && mode !== void 0 ? mode : 'character');
74
- const [selectedPresetIdx, setSelectedPresetIdx] = useState(0);
75
- const [selectedParts, setSelectedParts] = useState([]);
76
- const [canvasW, setCanvasW] = useState(32);
77
- const [canvasH, setCanvasH] = useState(32);
78
- const [direction, setDirection] = useState('S');
79
- const [projection, setProjection] = useState('topDown');
80
- const [generate8Dir, setGenerate8Dir] = useState(false);
81
- // Color overrides
82
- const [skinPalette, setSkinPalette] = useState('light');
83
- const [hairPalette, setHairPalette] = useState('brown');
84
- const [clothPalette, setClothPalette] = useState('leather');
85
- const [furPalette, setFurPalette] = useState('orange');
86
- const [wallPalette, setWallPalette] = useState('grey_stone');
87
- const [roofPalette, setRoofPalette] = useState('terracotta');
88
- const previewRef = useRef(null);
89
- const partsMapRef = useRef(new Map());
90
- /* ── Build parts map ── */
91
- useEffect(() => {
92
- const map = new Map();
93
- for (const p of getAllParts()) {
94
- map.set(p.id, p);
95
- }
96
- partsMapRef.current = map;
97
- }, []);
98
- /* ── Get presets for current tab ── */
99
- const presets = useMemo(() => {
100
- switch (tab) {
101
- case 'character':
102
- return CHARACTER_PRESETS;
103
- case 'building':
104
- return BUILDING_PRESETS;
105
- case 'animal':
106
- return ANIMAL_PRESETS;
107
- }
108
- }, [tab]);
109
- /* ── Apply preset ── */
110
- const applyPreset = useCallback((presetIdx) => {
111
- setSelectedPresetIdx(presetIdx);
112
- const preset = presets[presetIdx];
113
- if (!preset) {
114
- return;
115
- }
116
- if (tab === 'building') {
117
- const bp = preset;
118
- const assembly = assembleBuildingFromConfig(bp.config);
119
- setSelectedParts(assembly.parts);
120
- setCanvasW(assembly.canvasWidth);
121
- setCanvasH(assembly.canvasHeight);
122
- }
123
- else {
124
- const cp = preset;
125
- const assembly = cp.assembly;
126
- setSelectedParts([...assembly.parts]);
127
- setCanvasW(assembly.canvasWidth);
128
- setCanvasH(assembly.canvasHeight);
129
- }
130
- }, [tab, presets]);
131
- /* ── Initial preset ── */
132
- useEffect(() => {
133
- applyPreset(0);
134
- }, [tab, applyPreset]);
135
- /* ── Build current assembly ── */
136
- const currentAssembly = useMemo(() => {
137
- var _a;
138
- return ({
139
- id: `gen_${tab}_${selectedPresetIdx}`,
140
- name: ((_a = presets[selectedPresetIdx]) === null || _a === void 0 ? void 0 : _a.name) || 'Custom',
141
- parts: selectedParts,
142
- canvasWidth: canvasW,
143
- canvasHeight: canvasH,
144
- projection,
145
- });
146
- }, [tab, selectedPresetIdx, selectedParts, canvasW, canvasH, projection, presets]);
147
- /* ── Render preview ── */
148
- useEffect(() => {
149
- const canvas = previewRef.current;
150
- if (!canvas) {
151
- return;
152
- }
153
- const img = assembleSprite(currentAssembly, partsMapRef.current, direction);
154
- let finalImg = img;
155
- if (projection === 'iso25d') {
156
- finalImg = applyIsometricProjection(img);
157
- }
158
- canvas.width = finalImg.width;
159
- canvas.height = finalImg.height;
160
- const ctx = canvas.getContext('2d');
161
- if (ctx) {
162
- ctx.clearRect(0, 0, canvas.width, canvas.height);
163
- ctx.putImageData(finalImg, 0, 0);
164
- }
165
- }, [currentAssembly, direction, projection]);
166
- /* ── Toggle part visibility ── */
167
- const togglePart = useCallback((partId) => {
168
- setSelectedParts((prev) => prev.map((p) => { var _a; return (p.partId === partId ? { ...p, visible: !((_a = p.visible) !== null && _a !== void 0 ? _a : true) } : p); }));
169
- }, []);
170
- /* ── Add part ── */
171
- const addPart = useCallback((partId) => {
172
- if (selectedParts.some((p) => p.partId === partId)) {
173
- return;
174
- }
175
- const part = getPart(partId);
176
- if (!part) {
177
- return;
60
+ const NiceSpriteGeneratorPanel = ({
61
+ onSendToCanvas,
62
+ onClose,
63
+ mode
64
+ // presets and onGenerate are exposed for forward-compat; not currently consumed.
65
+ }) => {
66
+ const { t } = useNiceTranslation();
67
+ ensureInitialized();
68
+ const [tab, setTab] = useState(mode ?? "character");
69
+ const [selectedPresetIdx, setSelectedPresetIdx] = useState(0);
70
+ const [selectedParts, setSelectedParts] = useState([]);
71
+ const [canvasW, setCanvasW] = useState(32);
72
+ const [canvasH, setCanvasH] = useState(32);
73
+ const [direction, setDirection] = useState("S");
74
+ const [projection, setProjection] = useState("topDown");
75
+ const [generate8Dir, setGenerate8Dir] = useState(false);
76
+ const [skinPalette, setSkinPalette] = useState("light");
77
+ const [hairPalette, setHairPalette] = useState("brown");
78
+ const [clothPalette, setClothPalette] = useState("leather");
79
+ const [furPalette, setFurPalette] = useState("orange");
80
+ const [wallPalette, setWallPalette] = useState("grey_stone");
81
+ const [roofPalette, setRoofPalette] = useState("terracotta");
82
+ const previewRef = useRef(null);
83
+ const partsMapRef = useRef(/* @__PURE__ */ new Map());
84
+ useEffect(() => {
85
+ const map = /* @__PURE__ */ new Map();
86
+ for (const p of getAllParts()) {
87
+ map.set(p.id, p);
88
+ }
89
+ partsMapRef.current = map;
90
+ }, []);
91
+ const presets = useMemo(() => {
92
+ switch (tab) {
93
+ case "character":
94
+ return CHARACTER_PRESETS;
95
+ case "building":
96
+ return BUILDING_PRESETS;
97
+ case "animal":
98
+ return ANIMAL_PRESETS;
99
+ }
100
+ }, [tab]);
101
+ const applyPreset = useCallback(
102
+ (presetIdx) => {
103
+ setSelectedPresetIdx(presetIdx);
104
+ const preset = presets[presetIdx];
105
+ if (!preset) {
106
+ return;
107
+ }
108
+ if (tab === "building") {
109
+ const bp = preset;
110
+ const assembly = assembleBuildingFromConfig(bp.config);
111
+ setSelectedParts(assembly.parts);
112
+ setCanvasW(assembly.canvasWidth);
113
+ setCanvasH(assembly.canvasHeight);
114
+ } else {
115
+ const cp = preset;
116
+ const assembly = cp.assembly;
117
+ setSelectedParts([...assembly.parts]);
118
+ setCanvasW(assembly.canvasWidth);
119
+ setCanvasH(assembly.canvasHeight);
120
+ }
121
+ },
122
+ [tab, presets]
123
+ );
124
+ useEffect(() => {
125
+ applyPreset(0);
126
+ }, [tab, applyPreset]);
127
+ const currentAssembly = useMemo(
128
+ () => ({
129
+ id: `gen_${tab}_${selectedPresetIdx}`,
130
+ name: presets[selectedPresetIdx]?.name || "Custom",
131
+ parts: selectedParts,
132
+ canvasWidth: canvasW,
133
+ canvasHeight: canvasH,
134
+ projection
135
+ }),
136
+ [tab, selectedPresetIdx, selectedParts, canvasW, canvasH, projection, presets]
137
+ );
138
+ useEffect(() => {
139
+ const canvas = previewRef.current;
140
+ if (!canvas) {
141
+ return;
142
+ }
143
+ const img = assembleSprite(currentAssembly, partsMapRef.current, direction);
144
+ let finalImg = img;
145
+ if (projection === "iso25d") {
146
+ finalImg = applyIsometricProjection(img);
147
+ }
148
+ canvas.width = finalImg.width;
149
+ canvas.height = finalImg.height;
150
+ const ctx = canvas.getContext("2d");
151
+ if (ctx) {
152
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
153
+ ctx.putImageData(finalImg, 0, 0);
154
+ }
155
+ }, [currentAssembly, direction, projection]);
156
+ const togglePart = useCallback((partId) => {
157
+ setSelectedParts(
158
+ (prev) => prev.map((p) => p.partId === partId ? { ...p, visible: !(p.visible ?? true) } : p)
159
+ );
160
+ }, []);
161
+ const addPart = useCallback(
162
+ (partId) => {
163
+ if (selectedParts.some((p) => p.partId === partId)) {
164
+ return;
165
+ }
166
+ const part = getPart(partId);
167
+ if (!part) {
168
+ return;
169
+ }
170
+ setSelectedParts((prev) => [
171
+ ...prev,
172
+ {
173
+ partId,
174
+ offsetX: Math.floor(canvasW / 2) - Math.floor((part.pixels.S?.width ?? 8) / 2),
175
+ offsetY: Math.floor(canvasH / 2) - Math.floor((part.pixels.S?.height ?? 8) / 2),
176
+ visible: true
178
177
  }
179
- setSelectedParts((prev) => {
180
- var _a, _b, _c, _d;
181
- return [
182
- ...prev,
178
+ ]);
179
+ },
180
+ [selectedParts, canvasW, canvasH]
181
+ );
182
+ const removePart = useCallback((partId) => {
183
+ setSelectedParts((prev) => prev.filter((p) => p.partId !== partId));
184
+ }, []);
185
+ const handleSendToCanvas = useCallback(() => {
186
+ if (generate8Dir) {
187
+ const frames = generateAllDirections(currentAssembly, partsMapRef.current);
188
+ const sheet = render8DirSpriteSheet(frames);
189
+ onSendToCanvas?.(sheet);
190
+ } else {
191
+ let img = assembleSprite(currentAssembly, partsMapRef.current, direction);
192
+ if (projection === "iso25d") {
193
+ img = applyIsometricProjection(img);
194
+ }
195
+ onSendToCanvas?.(img);
196
+ }
197
+ onClose?.();
198
+ }, [generate8Dir, currentAssembly, direction, projection, onSendToCanvas, onClose]);
199
+ const categories = useMemo(() => {
200
+ switch (tab) {
201
+ case "character":
202
+ return CHAR_CATEGORIES;
203
+ case "building":
204
+ return BUILDING_CATEGORIES;
205
+ case "animal":
206
+ return ANIMAL_CATEGORIES;
207
+ }
208
+ }, [tab]);
209
+ const paletteGroups = useMemo(() => {
210
+ switch (tab) {
211
+ case "character":
212
+ return [
213
+ {
214
+ label: t("spriteGeneratorPanel.skin", "Skin"),
215
+ options: palettesToOptions(SKIN_PALETTES),
216
+ value: skinPalette,
217
+ set: setSkinPalette
218
+ },
219
+ {
220
+ label: t("spriteGeneratorPanel.hair", "Hair"),
221
+ options: palettesToOptions(HAIR_PALETTES),
222
+ value: hairPalette,
223
+ set: setHairPalette
224
+ },
225
+ {
226
+ label: t("spriteGeneratorPanel.clothing", "Clothing"),
227
+ options: palettesToOptions(CLOTHING_PALETTES),
228
+ value: clothPalette,
229
+ set: setClothPalette
230
+ }
231
+ ];
232
+ case "building":
233
+ return [
234
+ {
235
+ label: t("spriteGeneratorPanel.walls", "Walls"),
236
+ options: palettesToOptions(WALL_PALETTES),
237
+ value: wallPalette,
238
+ set: setWallPalette
239
+ },
240
+ {
241
+ label: t("spriteGeneratorPanel.roof", "Roof"),
242
+ options: palettesToOptions(ROOF_PALETTES),
243
+ value: roofPalette,
244
+ set: setRoofPalette
245
+ }
246
+ ];
247
+ case "animal":
248
+ return [
249
+ {
250
+ label: t("spriteGeneratorPanel.fur", "Fur"),
251
+ options: palettesToOptions(FUR_PALETTES),
252
+ value: furPalette,
253
+ set: setFurPalette
254
+ }
255
+ ];
256
+ }
257
+ }, [tab, skinPalette, hairPalette, clothPalette, wallPalette, roofPalette, furPalette, t]);
258
+ return /* @__PURE__ */ jsx(
259
+ NiceModal,
260
+ {
261
+ open: true,
262
+ onClose: onClose ?? (() => {
263
+ }),
264
+ title: t("spriteGeneratorPanel.spriteGenerator", "Sprite Generator"),
265
+ size: "xl",
266
+ children: /* @__PURE__ */ jsxs("div", { className: styles.genPanel, children: [
267
+ /* @__PURE__ */ jsx("div", { className: styles.genTabs, children: ["character", "building", "animal"].map((t2) => /* @__PURE__ */ jsxs(
268
+ NiceButton,
269
+ {
270
+ className: `${styles.genTabBtn} ${tab === t2 ? styles.genTabBtnActive : ""}`,
271
+ variant: tab === t2 ? "primary" : "ghost",
272
+ size: "sm",
273
+ onClick: () => setTab(t2),
274
+ children: [
275
+ /* @__PURE__ */ jsx(
276
+ NiceIcon,
277
+ {
278
+ name: t2 === "character" ? "user" : t2 === "building" ? "home" : "heart",
279
+ size: 14
280
+ }
281
+ ),
282
+ " ",
283
+ t2.charAt(0).toUpperCase() + t2.slice(1)
284
+ ]
285
+ },
286
+ t2
287
+ )) }),
288
+ /* @__PURE__ */ jsxs("div", { className: styles.genBody, children: [
289
+ /* @__PURE__ */ jsxs("div", { className: styles.genLeft, children: [
290
+ /* @__PURE__ */ jsxs("div", { className: styles.panelSection, children: [
291
+ /* @__PURE__ */ jsx("div", { className: styles.panelTitle, children: /* @__PURE__ */ jsx("span", { children: t("spriteGeneratorPanel.presets", "Presets") }) }),
292
+ /* @__PURE__ */ jsx("div", { className: styles.genPresetGrid, children: presets.map((preset, i) => /* @__PURE__ */ jsx(
293
+ NiceButton,
183
294
  {
184
- partId,
185
- offsetX: Math.floor(canvasW / 2) - Math.floor(((_b = (_a = part.pixels.S) === null || _a === void 0 ? void 0 : _a.width) !== null && _b !== void 0 ? _b : 8) / 2),
186
- offsetY: Math.floor(canvasH / 2) - Math.floor(((_d = (_c = part.pixels.S) === null || _c === void 0 ? void 0 : _c.height) !== null && _d !== void 0 ? _d : 8) / 2),
187
- visible: true,
295
+ className: `${styles.genPresetBtn} ${i === selectedPresetIdx ? styles.genPresetBtnActive : ""}`,
296
+ variant: i === selectedPresetIdx ? "primary" : "ghost",
297
+ size: "sm",
298
+ onClick: () => applyPreset(i),
299
+ title: preset.name,
300
+ children: preset.name
188
301
  },
189
- ];
190
- });
191
- }, [selectedParts, canvasW, canvasH]);
192
- /* ── Remove part ── */
193
- const removePart = useCallback((partId) => {
194
- setSelectedParts((prev) => prev.filter((p) => p.partId !== partId));
195
- }, []);
196
- /* ── Send to canvas ── */
197
- const handleSendToCanvas = useCallback(() => {
198
- if (generate8Dir) {
199
- const frames = generateAllDirections(currentAssembly, partsMapRef.current);
200
- const sheet = render8DirSpriteSheet(frames);
201
- onSendToCanvas === null || onSendToCanvas === void 0 ? void 0 : onSendToCanvas(sheet);
202
- }
203
- else {
204
- let img = assembleSprite(currentAssembly, partsMapRef.current, direction);
205
- if (projection === 'iso25d') {
206
- img = applyIsometricProjection(img);
207
- }
208
- onSendToCanvas === null || onSendToCanvas === void 0 ? void 0 : onSendToCanvas(img);
209
- }
210
- onClose === null || onClose === void 0 ? void 0 : onClose();
211
- }, [generate8Dir, currentAssembly, direction, projection, onSendToCanvas, onClose]);
212
- /* ── Categories for current tab ── */
213
- const categories = useMemo(() => {
214
- switch (tab) {
215
- case 'character':
216
- return CHAR_CATEGORIES;
217
- case 'building':
218
- return BUILDING_CATEGORIES;
219
- case 'animal':
220
- return ANIMAL_CATEGORIES;
221
- }
222
- }, [tab]);
223
- /* ── Available palette options ── */
224
- const paletteGroups = useMemo(() => {
225
- switch (tab) {
226
- case 'character':
227
- return [
228
- {
229
- label: t('spriteGeneratorPanel.skin', 'Skin'),
230
- options: palettesToOptions(SKIN_PALETTES),
231
- value: skinPalette,
232
- set: setSkinPalette,
233
- },
302
+ i
303
+ )) })
304
+ ] }),
305
+ /* @__PURE__ */ jsxs("div", { className: styles.panelSection, style: { flex: 1, overflowY: "auto" }, children: [
306
+ /* @__PURE__ */ jsx("div", { className: styles.panelTitle, children: /* @__PURE__ */ jsx("span", { children: t("spriteGeneratorPanel.parts", "Parts") }) }),
307
+ categories.map((cat) => {
308
+ const parts = getPartsByCategory(cat);
309
+ if (parts.length === 0) {
310
+ return null;
311
+ }
312
+ return /* @__PURE__ */ jsxs("div", { style: { marginBottom: 6 }, children: [
313
+ /* @__PURE__ */ jsx(
314
+ "div",
234
315
  {
235
- label: t('spriteGeneratorPanel.hair', 'Hair'),
236
- options: palettesToOptions(HAIR_PALETTES),
237
- value: hairPalette,
238
- set: setHairPalette,
239
- },
240
- {
241
- label: t('spriteGeneratorPanel.clothing', 'Clothing'),
242
- options: palettesToOptions(CLOTHING_PALETTES),
243
- value: clothPalette,
244
- set: setClothPalette,
245
- },
246
- ];
247
- case 'building':
248
- return [
249
- {
250
- label: t('spriteGeneratorPanel.walls', 'Walls'),
251
- options: palettesToOptions(WALL_PALETTES),
252
- value: wallPalette,
253
- set: setWallPalette,
254
- },
255
- {
256
- label: t('spriteGeneratorPanel.roof', 'Roof'),
257
- options: palettesToOptions(ROOF_PALETTES),
258
- value: roofPalette,
259
- set: setRoofPalette,
260
- },
261
- ];
262
- case 'animal':
263
- return [
316
+ style: {
317
+ fontSize: 9,
318
+ color: "var(--nice-text-muted)",
319
+ marginBottom: 2,
320
+ textTransform: "uppercase"
321
+ },
322
+ children: cat.replace(/([A-Z])/g, " $1").trim()
323
+ }
324
+ ),
325
+ /* @__PURE__ */ jsx("div", { className: styles.genPartGrid, children: parts.map((part) => {
326
+ const active = selectedParts.some(
327
+ (p) => p.partId === part.id && (p.visible ?? true)
328
+ );
329
+ return /* @__PURE__ */ jsx(
330
+ NiceButton,
331
+ {
332
+ className: `${styles.miniBtn} ${styles.genPartBtn} ${active ? styles.miniBtnActive : ""}`,
333
+ variant: active ? "primary" : "ghost",
334
+ size: "sm",
335
+ onClick: () => active ? removePart(part.id) : addPart(part.id),
336
+ title: part.name,
337
+ children: part.name
338
+ },
339
+ part.id
340
+ );
341
+ }) })
342
+ ] }, cat);
343
+ })
344
+ ] })
345
+ ] }),
346
+ /* @__PURE__ */ jsxs("div", { className: styles.genCenter, children: [
347
+ /* @__PURE__ */ jsx("div", { className: styles.genPreviewWrap, children: /* @__PURE__ */ jsx("canvas", { ref: previewRef, className: styles.genPreviewCanvas }) }),
348
+ /* @__PURE__ */ jsx("div", { className: styles.genDirGrid, children: ALL_DIRECTIONS.map((d) => /* @__PURE__ */ jsx(
349
+ NiceButton,
350
+ {
351
+ className: `${styles.miniBtn} ${direction === d ? styles.miniBtnActive : ""}`,
352
+ variant: direction === d ? "primary" : "ghost",
353
+ size: "sm",
354
+ onClick: () => setDirection(d),
355
+ children: d
356
+ },
357
+ d
358
+ )) }),
359
+ /* @__PURE__ */ jsxs("div", { className: styles.genRow, children: [
360
+ /* @__PURE__ */ jsx("label", { style: { fontSize: 10, color: "var(--nice-text-muted)" }, children: t("spriteGeneratorPanel.projection", "Projection") }),
361
+ /* @__PURE__ */ jsx(
362
+ NiceSelect,
363
+ {
364
+ className: styles.propSelect,
365
+ value: projection,
366
+ onChange: (val) => setProjection(val),
367
+ options: [
368
+ { value: "topDown", label: t("spriteGeneratorPanel.topDown", "Top-Down") },
369
+ { value: "sideView", label: t("spriteGeneratorPanel.sideView", "Side View") },
264
370
  {
265
- label: t('spriteGeneratorPanel.fur', 'Fur'),
266
- options: palettesToOptions(FUR_PALETTES),
267
- value: furPalette,
268
- set: setFurPalette,
269
- },
270
- ];
271
- }
272
- }, [tab, skinPalette, hairPalette, clothPalette, wallPalette, roofPalette, furPalette, t]);
273
- /* ── Render ── */
274
- return (jsx(NiceModal, { open: true, onClose: onClose !== null && onClose !== void 0 ? onClose : (() => { }), title: t('spriteGeneratorPanel.spriteGenerator', 'Sprite Generator'), size: "xl", children: jsxs("div", { className: styles.genPanel, children: [jsx("div", { className: styles.genTabs, children: ['character', 'building', 'animal'].map((t) => (jsxs(NiceButton, { className: `${styles.genTabBtn} ${tab === t ? styles.genTabBtnActive : ''}`, variant: tab === t ? 'primary' : 'ghost', size: "sm", onClick: () => setTab(t), children: [jsx(NiceIcon, { name: t === 'character' ? 'user' : t === 'building' ? 'home' : 'heart', size: 14 }), ' ', t.charAt(0).toUpperCase() + t.slice(1)] }, t))) }), jsxs("div", { className: styles.genBody, children: [jsxs("div", { className: styles.genLeft, children: [jsxs("div", { className: styles.panelSection, children: [jsx("div", { className: styles.panelTitle, children: jsx("span", { children: t('spriteGeneratorPanel.presets', 'Presets') }) }), jsx("div", { className: styles.genPresetGrid, children: presets.map((preset, i) => (jsx(NiceButton, { className: `${styles.genPresetBtn} ${i === selectedPresetIdx ? styles.genPresetBtnActive : ''}`, variant: i === selectedPresetIdx ? 'primary' : 'ghost', size: "sm", onClick: () => applyPreset(i), title: preset.name, children: preset.name }, i))) })] }), jsxs("div", { className: styles.panelSection, style: { flex: 1, overflowY: 'auto' }, children: [jsx("div", { className: styles.panelTitle, children: jsx("span", { children: t('spriteGeneratorPanel.parts', 'Parts') }) }), categories.map((cat) => {
275
- const parts = getPartsByCategory(cat);
276
- if (parts.length === 0) {
277
- return null;
278
- }
279
- return (jsxs("div", { style: { marginBottom: 6 }, children: [jsx("div", { style: {
280
- fontSize: 9,
281
- color: 'var(--nice-text-muted)',
282
- marginBottom: 2,
283
- textTransform: 'uppercase',
284
- }, children: cat.replace(/([A-Z])/g, ' $1').trim() }), jsx("div", { className: styles.genPartGrid, children: parts.map((part) => {
285
- const active = selectedParts.some((p) => { var _a; return p.partId === part.id && ((_a = p.visible) !== null && _a !== void 0 ? _a : true); });
286
- return (jsx(NiceButton, { className: `${styles.miniBtn} ${styles.genPartBtn} ${active ? styles.miniBtnActive : ''}`, variant: active ? 'primary' : 'ghost', size: "sm", onClick: () => (active ? removePart(part.id) : addPart(part.id)), title: part.name, children: part.name }, part.id));
287
- }) })] }, cat));
288
- })] })] }), jsxs("div", { className: styles.genCenter, children: [jsx("div", { className: styles.genPreviewWrap, children: jsx("canvas", { ref: previewRef, className: styles.genPreviewCanvas }) }), jsx("div", { className: styles.genDirGrid, children: ALL_DIRECTIONS.map((d) => (jsx(NiceButton, { className: `${styles.miniBtn} ${direction === d ? styles.miniBtnActive : ''}`, variant: direction === d ? 'primary' : 'ghost', size: "sm", onClick: () => setDirection(d), children: d }, d))) }), jsxs("div", { className: styles.genRow, children: [jsx("label", { style: { fontSize: 10, color: 'var(--nice-text-muted)' }, children: t('spriteGeneratorPanel.projection', 'Projection') }), jsx(NiceSelect, { className: styles.propSelect, value: projection, onChange: (val) => setProjection(val), options: [
289
- { value: 'topDown', label: t('spriteGeneratorPanel.topDown', 'Top-Down') },
290
- { value: 'sideView', label: t('spriteGeneratorPanel.sideView', 'Side View') },
291
- {
292
- value: 'iso25d',
293
- label: t('spriteGeneratorPanel.n25dIsometric', '2.5D Isometric'),
294
- },
295
- ] })] }), jsxs("div", { className: styles.genRow, children: [jsx("label", { style: { fontSize: 10, color: 'var(--nice-text-muted)' }, children: t('spriteGeneratorPanel.size', 'Size') }), jsx(NiceNumberInput, { min: 8, max: 256, value: canvasW, onChange: (val) => setCanvasW(val !== null && val !== void 0 ? val : 32) }), jsx("span", { style: { fontSize: 10, color: 'var(--nice-text-muted)' }, children: "\u00D7" }), jsx(NiceNumberInput, { min: 8, max: 256, value: canvasH, onChange: (val) => setCanvasH(val !== null && val !== void 0 ? val : 32) })] }), jsx(NiceCheckbox, { checked: generate8Dir, onChange: (checked) => setGenerate8Dir(checked), label: t('spriteGeneratorPanel.generate8DirectionSheet', 'Generate 8-direction sheet'), className: styles.checkLabel })] }), jsxs("div", { className: styles.genRight, children: [jsxs("div", { className: styles.panelSection, children: [jsx("div", { className: styles.panelTitle, children: jsx("span", { children: t('spriteGeneratorPanel.colors', 'Colors') }) }), paletteGroups.map((group) => {
296
- var _a;
297
- return (jsxs("div", { style: { marginBottom: 6 }, children: [jsx("div", { style: { fontSize: 9, color: 'var(--nice-text-muted)', marginBottom: 2 }, children: group.label }), jsx(NiceSelect, { className: styles.propSelect, value: group.value, onChange: (val) => group.set(val), options: group.options.map((opt) => ({
298
- value: opt.id,
299
- label: opt.name,
300
- })) }), jsx("div", { className: styles.genColorSwatches, children: (_a = group.options
301
- .find((o) => o.id === group.value)) === null || _a === void 0 ? void 0 : _a.colors.map((c, i) => (jsx("div", { className: styles.genColorSwatch, style: { backgroundColor: c }, title: c }, i))) })] }, group.label));
302
- })] }), jsxs("div", { className: styles.panelSection, style: { flex: 1, overflowY: 'auto' }, children: [jsx("div", { className: styles.panelTitle, children: jsx("span", { children: t('spriteGeneratorPanel.assembly', 'Assembly') }) }), selectedParts.map((ap, i) => {
303
- var _a, _b, _c, _d, _e;
304
- const part = partsMapRef.current.get(ap.partId);
305
- return (
306
- // A part can be placed twice (left and right leg, flipped), so its id
307
- // alone is not a unique key.
308
- jsxs("div", { className: styles.genAssemblyItem, children: [jsx(NiceButton, { className: styles.btnIcon, variant: "ghost", size: "sm", onClick: () => togglePart(ap.partId), title: ((_a = ap.visible) !== null && _a !== void 0 ? _a : true)
309
- ? t('spriteGeneratorPanel.hide', 'Hide')
310
- : t('spriteGeneratorPanel.show', 'Show'), "aria-label": ((_b = ap.visible) !== null && _b !== void 0 ? _b : true)
311
- ? t('spriteGeneratorPanel.hide', 'Hide')
312
- : t('spriteGeneratorPanel.show', 'Show'), children: jsx(NiceIcon, { name: ((_c = ap.visible) !== null && _c !== void 0 ? _c : true) ? 'eye' : 'eye-off', size: 14 }) }), jsx("span", { className: styles.genAssemblyName, children: (_d = part === null || part === void 0 ? void 0 : part.name) !== null && _d !== void 0 ? _d : ap.partId }), jsxs("span", { style: { fontSize: 9, color: 'var(--nice-text-muted)' }, children: ["z:", (_e = part === null || part === void 0 ? void 0 : part.zOrder) !== null && _e !== void 0 ? _e : 0] }), jsx(NiceButton, { className: styles.btnIcon, variant: "ghost", size: "sm", onClick: () => removePart(ap.partId), title: t('spriteGeneratorPanel.remove', 'Remove'), "aria-label": t('spriteGeneratorPanel.remove', 'Remove'), children: jsx(NiceIcon, { name: "close", size: 14 }) })] }, `${ap.partId}-${i}`));
313
- })] })] })] }), jsxs("div", { className: styles.genFooter, children: [jsx(NiceButton, { className: styles.btnSecondary, variant: "ghost", onClick: onClose, children: t('spriteGeneratorPanel.cancel', 'Cancel') }), jsxs(NiceButton, { className: styles.btnPrimary, variant: "primary", onClick: handleSendToCanvas, children: [jsx(NiceIcon, { name: "clipboard", size: 14 }), ' ', t('spriteGeneratorPanel.sendToCanvas', 'Send to Canvas')] })] })] }) }));
371
+ value: "iso25d",
372
+ label: t("spriteGeneratorPanel.n25dIsometric", "2.5D Isometric")
373
+ }
374
+ ]
375
+ }
376
+ )
377
+ ] }),
378
+ /* @__PURE__ */ jsxs("div", { className: styles.genRow, children: [
379
+ /* @__PURE__ */ jsx("label", { style: { fontSize: 10, color: "var(--nice-text-muted)" }, children: t("spriteGeneratorPanel.size", "Size") }),
380
+ /* @__PURE__ */ jsx(
381
+ NiceNumberInput,
382
+ {
383
+ min: 8,
384
+ max: 256,
385
+ value: canvasW,
386
+ onChange: (val) => setCanvasW(val ?? 32)
387
+ }
388
+ ),
389
+ /* @__PURE__ */ jsx("span", { style: { fontSize: 10, color: "var(--nice-text-muted)" }, children: "×" }),
390
+ /* @__PURE__ */ jsx(
391
+ NiceNumberInput,
392
+ {
393
+ min: 8,
394
+ max: 256,
395
+ value: canvasH,
396
+ onChange: (val) => setCanvasH(val ?? 32)
397
+ }
398
+ )
399
+ ] }),
400
+ /* @__PURE__ */ jsx(
401
+ NiceCheckbox,
402
+ {
403
+ checked: generate8Dir,
404
+ onChange: (checked) => setGenerate8Dir(checked),
405
+ label: t(
406
+ "spriteGeneratorPanel.generate8DirectionSheet",
407
+ "Generate 8-direction sheet"
408
+ ),
409
+ className: styles.checkLabel
410
+ }
411
+ )
412
+ ] }),
413
+ /* @__PURE__ */ jsxs("div", { className: styles.genRight, children: [
414
+ /* @__PURE__ */ jsxs("div", { className: styles.panelSection, children: [
415
+ /* @__PURE__ */ jsx("div", { className: styles.panelTitle, children: /* @__PURE__ */ jsx("span", { children: t("spriteGeneratorPanel.colors", "Colors") }) }),
416
+ paletteGroups.map((group) => /* @__PURE__ */ jsxs("div", { style: { marginBottom: 6 }, children: [
417
+ /* @__PURE__ */ jsx("div", { style: { fontSize: 9, color: "var(--nice-text-muted)", marginBottom: 2 }, children: group.label }),
418
+ /* @__PURE__ */ jsx(
419
+ NiceSelect,
420
+ {
421
+ className: styles.propSelect,
422
+ value: group.value,
423
+ onChange: (val) => group.set(val),
424
+ options: group.options.map((opt) => ({
425
+ value: opt.id,
426
+ label: opt.name
427
+ }))
428
+ }
429
+ ),
430
+ /* @__PURE__ */ jsx("div", { className: styles.genColorSwatches, children: group.options.find((o) => o.id === group.value)?.colors.map((c, i) => /* @__PURE__ */ jsx(
431
+ "div",
432
+ {
433
+ className: styles.genColorSwatch,
434
+ style: { backgroundColor: c },
435
+ title: c
436
+ },
437
+ i
438
+ )) })
439
+ ] }, group.label))
440
+ ] }),
441
+ /* @__PURE__ */ jsxs("div", { className: styles.panelSection, style: { flex: 1, overflowY: "auto" }, children: [
442
+ /* @__PURE__ */ jsx("div", { className: styles.panelTitle, children: /* @__PURE__ */ jsx("span", { children: t("spriteGeneratorPanel.assembly", "Assembly") }) }),
443
+ selectedParts.map((ap, i) => {
444
+ const part = partsMapRef.current.get(ap.partId);
445
+ return (
446
+ // A part can be placed twice (left and right leg, flipped), so its id
447
+ // alone is not a unique key.
448
+ /* @__PURE__ */ jsxs("div", { className: styles.genAssemblyItem, children: [
449
+ /* @__PURE__ */ jsx(
450
+ NiceButton,
451
+ {
452
+ className: styles.btnIcon,
453
+ variant: "ghost",
454
+ size: "sm",
455
+ onClick: () => togglePart(ap.partId),
456
+ title: ap.visible ?? true ? t("spriteGeneratorPanel.hide", "Hide") : t("spriteGeneratorPanel.show", "Show"),
457
+ "aria-label": ap.visible ?? true ? t("spriteGeneratorPanel.hide", "Hide") : t("spriteGeneratorPanel.show", "Show"),
458
+ children: /* @__PURE__ */ jsx(NiceIcon, { name: ap.visible ?? true ? "eye" : "eye-off", size: 14 })
459
+ }
460
+ ),
461
+ /* @__PURE__ */ jsx("span", { className: styles.genAssemblyName, children: part?.name ?? ap.partId }),
462
+ /* @__PURE__ */ jsxs("span", { style: { fontSize: 9, color: "var(--nice-text-muted)" }, children: [
463
+ "z:",
464
+ part?.zOrder ?? 0
465
+ ] }),
466
+ /* @__PURE__ */ jsx(
467
+ NiceButton,
468
+ {
469
+ className: styles.btnIcon,
470
+ variant: "ghost",
471
+ size: "sm",
472
+ onClick: () => removePart(ap.partId),
473
+ title: t("spriteGeneratorPanel.remove", "Remove"),
474
+ "aria-label": t("spriteGeneratorPanel.remove", "Remove"),
475
+ children: /* @__PURE__ */ jsx(NiceIcon, { name: "close", size: 14 })
476
+ }
477
+ )
478
+ ] }, `${ap.partId}-${i}`)
479
+ );
480
+ })
481
+ ] })
482
+ ] })
483
+ ] }),
484
+ /* @__PURE__ */ jsxs("div", { className: styles.genFooter, children: [
485
+ /* @__PURE__ */ jsx(NiceButton, { className: styles.btnSecondary, variant: "ghost", onClick: onClose, children: t("spriteGeneratorPanel.cancel", "Cancel") }),
486
+ /* @__PURE__ */ jsxs(NiceButton, { className: styles.btnPrimary, variant: "primary", onClick: handleSendToCanvas, children: [
487
+ /* @__PURE__ */ jsx(NiceIcon, { name: "clipboard", size: 14 }),
488
+ " ",
489
+ t("spriteGeneratorPanel.sendToCanvas", "Send to Canvas")
490
+ ] })
491
+ ] })
492
+ ] })
493
+ }
494
+ );
314
495
  };
315
- if (process.env.NODE_ENV !== 'production') {
316
- NiceSpriteGeneratorPanel.displayName = 'NiceSpriteGeneratorPanel';
496
+ if (process.env.NODE_ENV !== "production") {
497
+ NiceSpriteGeneratorPanel.displayName = "NiceSpriteGeneratorPanel";
317
498
  }
318
-
319
- export { NiceSpriteGeneratorPanel as default };
499
+ export {
500
+ NiceSpriteGeneratorPanel as default
501
+ };