@easemate/web-kit 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (358) hide show
  1. package/README.md +824 -0
  2. package/build/components/code/index.cjs +152 -0
  3. package/build/components/code/index.d.cts +11 -0
  4. package/build/components/code/index.d.ts +11 -0
  5. package/build/components/code/index.js +148 -0
  6. package/build/components/code/utils/highlight-api.cjs +18 -0
  7. package/build/components/code/utils/highlight-api.d.cts +7 -0
  8. package/build/components/code/utils/highlight-api.d.ts +7 -0
  9. package/build/components/code/utils/highlight-api.js +14 -0
  10. package/build/components/code/utils/syntax-grammars.cjs +62 -0
  11. package/build/components/code/utils/syntax-grammars.d.cts +7 -0
  12. package/build/components/code/utils/syntax-grammars.d.ts +7 -0
  13. package/build/components/code/utils/syntax-grammars.js +59 -0
  14. package/build/components/code/utils/syntax-highlighter-theme.cjs +27 -0
  15. package/build/components/code/utils/syntax-highlighter-theme.d.cts +3 -0
  16. package/build/components/code/utils/syntax-highlighter-theme.d.ts +3 -0
  17. package/build/components/code/utils/syntax-highlighter-theme.js +23 -0
  18. package/build/components/code/utils/syntax-highlighter-types.cjs +2 -0
  19. package/build/components/code/utils/syntax-highlighter-types.d.cts +12 -0
  20. package/build/components/code/utils/syntax-highlighter-types.d.ts +12 -0
  21. package/build/components/code/utils/syntax-highlighter-types.js +1 -0
  22. package/build/components/code/utils/syntax-tokenizer.cjs +63 -0
  23. package/build/components/code/utils/syntax-tokenizer.d.cts +3 -0
  24. package/build/components/code/utils/syntax-tokenizer.d.ts +3 -0
  25. package/build/components/code/utils/syntax-tokenizer.js +58 -0
  26. package/build/components/curve/bezier-conversion.cjs +23 -0
  27. package/build/components/curve/bezier-conversion.d.cts +2 -0
  28. package/build/components/curve/bezier-conversion.d.ts +2 -0
  29. package/build/components/curve/bezier-conversion.js +19 -0
  30. package/build/components/curve/canvas-controls.cjs +300 -0
  31. package/build/components/curve/canvas-controls.d.cts +12 -0
  32. package/build/components/curve/canvas-controls.d.ts +12 -0
  33. package/build/components/curve/canvas-controls.js +296 -0
  34. package/build/components/curve/canvas.cjs +1208 -0
  35. package/build/components/curve/canvas.d.cts +24 -0
  36. package/build/components/curve/canvas.d.ts +24 -0
  37. package/build/components/curve/canvas.js +1204 -0
  38. package/build/components/curve/constants.cjs +203 -0
  39. package/build/components/curve/constants.d.cts +23 -0
  40. package/build/components/curve/constants.d.ts +23 -0
  41. package/build/components/curve/constants.js +200 -0
  42. package/build/components/curve/controls.cjs +942 -0
  43. package/build/components/curve/controls.d.cts +37 -0
  44. package/build/components/curve/controls.d.ts +37 -0
  45. package/build/components/curve/controls.js +938 -0
  46. package/build/components/curve/index.cjs +335 -0
  47. package/build/components/curve/index.d.cts +31 -0
  48. package/build/components/curve/index.d.ts +31 -0
  49. package/build/components/curve/index.js +330 -0
  50. package/build/components/curve/output.cjs +141 -0
  51. package/build/components/curve/output.d.cts +19 -0
  52. package/build/components/curve/output.d.ts +19 -0
  53. package/build/components/curve/output.js +137 -0
  54. package/build/components/curve/styles.cjs +493 -0
  55. package/build/components/curve/styles.d.cts +6 -0
  56. package/build/components/curve/styles.d.ts +6 -0
  57. package/build/components/curve/styles.js +490 -0
  58. package/build/components/curve/svg-renderer.cjs +185 -0
  59. package/build/components/curve/svg-renderer.d.cts +9 -0
  60. package/build/components/curve/svg-renderer.d.ts +9 -0
  61. package/build/components/curve/svg-renderer.js +175 -0
  62. package/build/components/curve/toolbar.cjs +368 -0
  63. package/build/components/curve/toolbar.d.cts +26 -0
  64. package/build/components/curve/toolbar.d.ts +26 -0
  65. package/build/components/curve/toolbar.js +364 -0
  66. package/build/components/curve/types.cjs +10 -0
  67. package/build/components/curve/types.d.cts +33 -0
  68. package/build/components/curve/types.d.ts +33 -0
  69. package/build/components/curve/types.js +7 -0
  70. package/build/components/curve/utils.cjs +541 -0
  71. package/build/components/curve/utils.d.cts +33 -0
  72. package/build/components/curve/utils.d.ts +33 -0
  73. package/build/components/curve/utils.js +521 -0
  74. package/build/components/index.cjs +18 -0
  75. package/build/components/index.d.cts +2 -0
  76. package/build/components/index.d.ts +2 -0
  77. package/build/components/index.js +2 -0
  78. package/build/decorators/Component.cjs +127 -0
  79. package/build/decorators/Component.d.cts +28 -0
  80. package/build/decorators/Component.d.ts +28 -0
  81. package/build/decorators/Component.js +123 -0
  82. package/build/decorators/Listen.cjs +154 -0
  83. package/build/decorators/Listen.d.cts +18 -0
  84. package/build/decorators/Listen.d.ts +18 -0
  85. package/build/decorators/Listen.js +151 -0
  86. package/build/decorators/OutsideClick.cjs +64 -0
  87. package/build/decorators/OutsideClick.d.cts +16 -0
  88. package/build/decorators/OutsideClick.d.ts +16 -0
  89. package/build/decorators/OutsideClick.js +59 -0
  90. package/build/decorators/Prop.cjs +273 -0
  91. package/build/decorators/Prop.d.cts +22 -0
  92. package/build/decorators/Prop.d.ts +22 -0
  93. package/build/decorators/Prop.js +270 -0
  94. package/build/decorators/Query.cjs +79 -0
  95. package/build/decorators/Query.d.cts +27 -0
  96. package/build/decorators/Query.d.ts +27 -0
  97. package/build/decorators/Query.js +76 -0
  98. package/build/decorators/Watch.cjs +52 -0
  99. package/build/decorators/Watch.d.cts +11 -0
  100. package/build/decorators/Watch.d.ts +11 -0
  101. package/build/decorators/Watch.js +49 -0
  102. package/build/decorators/index.cjs +15 -0
  103. package/build/decorators/index.d.cts +6 -0
  104. package/build/decorators/index.d.ts +6 -0
  105. package/build/decorators/index.js +6 -0
  106. package/build/elements/button/index.cjs +214 -0
  107. package/build/elements/button/index.d.cts +11 -0
  108. package/build/elements/button/index.d.ts +11 -0
  109. package/build/elements/button/index.js +210 -0
  110. package/build/elements/checkbox/index.cjs +316 -0
  111. package/build/elements/checkbox/index.d.cts +14 -0
  112. package/build/elements/checkbox/index.d.ts +14 -0
  113. package/build/elements/checkbox/index.js +312 -0
  114. package/build/elements/color/index.cjs +154 -0
  115. package/build/elements/color/index.d.cts +18 -0
  116. package/build/elements/color/index.d.ts +18 -0
  117. package/build/elements/color/index.js +150 -0
  118. package/build/elements/color/picker.cjs +544 -0
  119. package/build/elements/color/picker.d.cts +37 -0
  120. package/build/elements/color/picker.d.ts +37 -0
  121. package/build/elements/color/picker.js +540 -0
  122. package/build/elements/color/utils.cjs +235 -0
  123. package/build/elements/color/utils.d.cts +37 -0
  124. package/build/elements/color/utils.d.ts +37 -0
  125. package/build/elements/color/utils.js +218 -0
  126. package/build/elements/dropdown/index.cjs +875 -0
  127. package/build/elements/dropdown/index.d.cts +30 -0
  128. package/build/elements/dropdown/index.d.ts +30 -0
  129. package/build/elements/dropdown/index.js +871 -0
  130. package/build/elements/field/index.cjs +82 -0
  131. package/build/elements/field/index.d.cts +4 -0
  132. package/build/elements/field/index.d.ts +4 -0
  133. package/build/elements/field/index.js +78 -0
  134. package/build/elements/icons/animation/chevron.cjs +57 -0
  135. package/build/elements/icons/animation/chevron.d.cts +10 -0
  136. package/build/elements/icons/animation/chevron.d.ts +10 -0
  137. package/build/elements/icons/animation/chevron.js +53 -0
  138. package/build/elements/icons/animation/clear.cjs +74 -0
  139. package/build/elements/icons/animation/clear.d.cts +3 -0
  140. package/build/elements/icons/animation/clear.d.ts +3 -0
  141. package/build/elements/icons/animation/clear.js +70 -0
  142. package/build/elements/icons/animation/grid.cjs +77 -0
  143. package/build/elements/icons/animation/grid.d.cts +8 -0
  144. package/build/elements/icons/animation/grid.d.ts +8 -0
  145. package/build/elements/icons/animation/grid.js +73 -0
  146. package/build/elements/icons/animation/loading.cjs +68 -0
  147. package/build/elements/icons/animation/loading.d.cts +3 -0
  148. package/build/elements/icons/animation/loading.d.ts +3 -0
  149. package/build/elements/icons/animation/loading.js +64 -0
  150. package/build/elements/icons/animation/snap.cjs +133 -0
  151. package/build/elements/icons/animation/snap.d.cts +8 -0
  152. package/build/elements/icons/animation/snap.d.ts +8 -0
  153. package/build/elements/icons/animation/snap.js +129 -0
  154. package/build/elements/icons/index.cjs +40 -0
  155. package/build/elements/icons/index.d.cts +24 -0
  156. package/build/elements/icons/index.d.ts +24 -0
  157. package/build/elements/icons/index.js +24 -0
  158. package/build/elements/icons/interface/anchor-add.cjs +35 -0
  159. package/build/elements/icons/interface/anchor-add.d.cts +3 -0
  160. package/build/elements/icons/interface/anchor-add.d.ts +3 -0
  161. package/build/elements/icons/interface/anchor-add.js +31 -0
  162. package/build/elements/icons/interface/anchor-remove.cjs +34 -0
  163. package/build/elements/icons/interface/anchor-remove.d.cts +3 -0
  164. package/build/elements/icons/interface/anchor-remove.d.ts +3 -0
  165. package/build/elements/icons/interface/anchor-remove.js +30 -0
  166. package/build/elements/icons/interface/arrow-up.cjs +30 -0
  167. package/build/elements/icons/interface/arrow-up.d.cts +3 -0
  168. package/build/elements/icons/interface/arrow-up.d.ts +3 -0
  169. package/build/elements/icons/interface/arrow-up.js +26 -0
  170. package/build/elements/icons/interface/arrows-vertical.cjs +30 -0
  171. package/build/elements/icons/interface/arrows-vertical.d.cts +3 -0
  172. package/build/elements/icons/interface/arrows-vertical.d.ts +3 -0
  173. package/build/elements/icons/interface/arrows-vertical.js +26 -0
  174. package/build/elements/icons/interface/bezier-angle.cjs +33 -0
  175. package/build/elements/icons/interface/bezier-angle.d.cts +3 -0
  176. package/build/elements/icons/interface/bezier-angle.d.ts +3 -0
  177. package/build/elements/icons/interface/bezier-angle.js +29 -0
  178. package/build/elements/icons/interface/bezier-distribute.cjs +34 -0
  179. package/build/elements/icons/interface/bezier-distribute.d.cts +3 -0
  180. package/build/elements/icons/interface/bezier-distribute.d.ts +3 -0
  181. package/build/elements/icons/interface/bezier-distribute.js +30 -0
  182. package/build/elements/icons/interface/bezier-length.cjs +31 -0
  183. package/build/elements/icons/interface/bezier-length.d.cts +3 -0
  184. package/build/elements/icons/interface/bezier-length.d.ts +3 -0
  185. package/build/elements/icons/interface/bezier-length.js +27 -0
  186. package/build/elements/icons/interface/bezier-mirror.cjs +31 -0
  187. package/build/elements/icons/interface/bezier-mirror.d.cts +3 -0
  188. package/build/elements/icons/interface/bezier-mirror.d.ts +3 -0
  189. package/build/elements/icons/interface/bezier-mirror.js +27 -0
  190. package/build/elements/icons/interface/bezier.cjs +26 -0
  191. package/build/elements/icons/interface/bezier.d.cts +3 -0
  192. package/build/elements/icons/interface/bezier.d.ts +3 -0
  193. package/build/elements/icons/interface/bezier.js +22 -0
  194. package/build/elements/icons/interface/check.cjs +30 -0
  195. package/build/elements/icons/interface/check.d.cts +3 -0
  196. package/build/elements/icons/interface/check.d.ts +3 -0
  197. package/build/elements/icons/interface/check.js +26 -0
  198. package/build/elements/icons/interface/circle-arrow-left.cjs +30 -0
  199. package/build/elements/icons/interface/circle-arrow-left.d.cts +3 -0
  200. package/build/elements/icons/interface/circle-arrow-left.d.ts +3 -0
  201. package/build/elements/icons/interface/circle-arrow-left.js +26 -0
  202. package/build/elements/icons/interface/circle-arrow-right.cjs +30 -0
  203. package/build/elements/icons/interface/circle-arrow-right.d.cts +3 -0
  204. package/build/elements/icons/interface/circle-arrow-right.d.ts +3 -0
  205. package/build/elements/icons/interface/circle-arrow-right.js +26 -0
  206. package/build/elements/icons/interface/code.cjs +30 -0
  207. package/build/elements/icons/interface/code.d.cts +3 -0
  208. package/build/elements/icons/interface/code.d.ts +3 -0
  209. package/build/elements/icons/interface/code.js +26 -0
  210. package/build/elements/icons/interface/dots.cjs +32 -0
  211. package/build/elements/icons/interface/dots.d.cts +3 -0
  212. package/build/elements/icons/interface/dots.d.ts +3 -0
  213. package/build/elements/icons/interface/dots.js +28 -0
  214. package/build/elements/icons/interface/mention.cjs +30 -0
  215. package/build/elements/icons/interface/mention.d.cts +3 -0
  216. package/build/elements/icons/interface/mention.d.ts +3 -0
  217. package/build/elements/icons/interface/mention.js +26 -0
  218. package/build/elements/icons/interface/minus.cjs +30 -0
  219. package/build/elements/icons/interface/minus.d.cts +3 -0
  220. package/build/elements/icons/interface/minus.d.ts +3 -0
  221. package/build/elements/icons/interface/minus.js +26 -0
  222. package/build/elements/icons/interface/picker.cjs +34 -0
  223. package/build/elements/icons/interface/picker.d.cts +3 -0
  224. package/build/elements/icons/interface/picker.d.ts +3 -0
  225. package/build/elements/icons/interface/picker.js +30 -0
  226. package/build/elements/icons/interface/plus.cjs +30 -0
  227. package/build/elements/icons/interface/plus.d.cts +3 -0
  228. package/build/elements/icons/interface/plus.d.ts +3 -0
  229. package/build/elements/icons/interface/plus.js +26 -0
  230. package/build/elements/icons/interface/settings.cjs +30 -0
  231. package/build/elements/icons/interface/settings.d.cts +3 -0
  232. package/build/elements/icons/interface/settings.d.ts +3 -0
  233. package/build/elements/icons/interface/settings.js +26 -0
  234. package/build/elements/index.cjs +62 -0
  235. package/build/elements/index.d.cts +22 -0
  236. package/build/elements/index.d.ts +22 -0
  237. package/build/elements/index.js +22 -0
  238. package/build/elements/input/index.cjs +273 -0
  239. package/build/elements/input/index.d.cts +17 -0
  240. package/build/elements/input/index.d.ts +17 -0
  241. package/build/elements/input/index.js +269 -0
  242. package/build/elements/logo/index.cjs +732 -0
  243. package/build/elements/logo/index.d.cts +17 -0
  244. package/build/elements/logo/index.d.ts +17 -0
  245. package/build/elements/logo/index.js +728 -0
  246. package/build/elements/monitor/fps.cjs +432 -0
  247. package/build/elements/monitor/fps.d.cts +21 -0
  248. package/build/elements/monitor/fps.d.ts +21 -0
  249. package/build/elements/monitor/fps.js +428 -0
  250. package/build/elements/monitor/index.cjs +670 -0
  251. package/build/elements/monitor/index.d.cts +112 -0
  252. package/build/elements/monitor/index.d.ts +112 -0
  253. package/build/elements/monitor/index.js +666 -0
  254. package/build/elements/number/index.cjs +173 -0
  255. package/build/elements/number/index.d.cts +19 -0
  256. package/build/elements/number/index.d.ts +19 -0
  257. package/build/elements/number/index.js +169 -0
  258. package/build/elements/origin/index.cjs +169 -0
  259. package/build/elements/origin/index.d.cts +12 -0
  260. package/build/elements/origin/index.d.ts +12 -0
  261. package/build/elements/origin/index.js +165 -0
  262. package/build/elements/popover/index.cjs +209 -0
  263. package/build/elements/popover/index.d.cts +19 -0
  264. package/build/elements/popover/index.d.ts +19 -0
  265. package/build/elements/popover/index.js +205 -0
  266. package/build/elements/radio/index.cjs +301 -0
  267. package/build/elements/radio/index.d.cts +13 -0
  268. package/build/elements/radio/index.d.ts +13 -0
  269. package/build/elements/radio/index.js +283 -0
  270. package/build/elements/radio/input.cjs +329 -0
  271. package/build/elements/radio/input.d.cts +15 -0
  272. package/build/elements/radio/input.d.ts +15 -0
  273. package/build/elements/radio/input.js +325 -0
  274. package/build/elements/radio/option.cjs +15 -0
  275. package/build/elements/radio/option.d.cts +3 -0
  276. package/build/elements/radio/option.d.ts +3 -0
  277. package/build/elements/radio/option.js +11 -0
  278. package/build/elements/shared.cjs +66 -0
  279. package/build/elements/shared.d.cts +40 -0
  280. package/build/elements/shared.d.ts +40 -0
  281. package/build/elements/shared.js +59 -0
  282. package/build/elements/slider/index.cjs +232 -0
  283. package/build/elements/slider/index.d.cts +20 -0
  284. package/build/elements/slider/index.d.ts +20 -0
  285. package/build/elements/slider/index.js +228 -0
  286. package/build/elements/state/index.cjs +681 -0
  287. package/build/elements/state/index.d.cts +86 -0
  288. package/build/elements/state/index.d.ts +86 -0
  289. package/build/elements/state/index.js +677 -0
  290. package/build/elements/toggle/index.cjs +151 -0
  291. package/build/elements/toggle/index.d.cts +9 -0
  292. package/build/elements/toggle/index.d.ts +9 -0
  293. package/build/elements/toggle/index.js +147 -0
  294. package/build/elements/tooltip/index.cjs +187 -0
  295. package/build/elements/tooltip/index.d.cts +17 -0
  296. package/build/elements/tooltip/index.d.ts +17 -0
  297. package/build/elements/tooltip/index.js +183 -0
  298. package/build/index.cjs +40 -0
  299. package/build/index.d.cts +6 -0
  300. package/build/index.d.ts +6 -0
  301. package/build/index.js +12 -0
  302. package/build/init.cjs +325 -0
  303. package/build/init.d.cts +157 -0
  304. package/build/init.d.ts +157 -0
  305. package/build/init.js +289 -0
  306. package/build/internal/component-loaders.cjs +206 -0
  307. package/build/internal/component-loaders.d.cts +52 -0
  308. package/build/internal/component-loaders.d.ts +52 -0
  309. package/build/internal/component-loaders.js +167 -0
  310. package/build/internal/fonts.cjs +128 -0
  311. package/build/internal/fonts.d.cts +32 -0
  312. package/build/internal/fonts.d.ts +32 -0
  313. package/build/internal/fonts.js +123 -0
  314. package/build/internal/lazy-load.cjs +89 -0
  315. package/build/internal/lazy-load.d.cts +32 -0
  316. package/build/internal/lazy-load.d.ts +32 -0
  317. package/build/internal/lazy-load.js +86 -0
  318. package/build/internal/style-inject.cjs +236 -0
  319. package/build/internal/style-inject.d.cts +44 -0
  320. package/build/internal/style-inject.d.ts +44 -0
  321. package/build/internal/style-inject.js +226 -0
  322. package/build/register.cjs +36 -0
  323. package/build/register.d.cts +32 -0
  324. package/build/register.d.ts +32 -0
  325. package/build/register.js +34 -0
  326. package/build/theme/index.cjs +452 -0
  327. package/build/theme/index.d.cts +146 -0
  328. package/build/theme/index.d.ts +146 -0
  329. package/build/theme/index.js +423 -0
  330. package/build/theme/presets.cjs +54 -0
  331. package/build/theme/presets.d.cts +19 -0
  332. package/build/theme/presets.d.ts +19 -0
  333. package/build/theme/presets.js +51 -0
  334. package/build/theme/registry.cjs +204 -0
  335. package/build/theme/registry.d.cts +99 -0
  336. package/build/theme/registry.d.ts +99 -0
  337. package/build/theme/registry.js +194 -0
  338. package/build/theme/tokens.cjs +148 -0
  339. package/build/theme/tokens.d.cts +163 -0
  340. package/build/theme/tokens.d.ts +163 -0
  341. package/build/theme/tokens.js +145 -0
  342. package/build/utils/dismiss-controller.cjs +77 -0
  343. package/build/utils/dismiss-controller.d.cts +14 -0
  344. package/build/utils/dismiss-controller.d.ts +14 -0
  345. package/build/utils/dismiss-controller.js +73 -0
  346. package/build/utils/index.cjs +18 -0
  347. package/build/utils/index.d.cts +3 -0
  348. package/build/utils/index.d.ts +3 -0
  349. package/build/utils/index.js +3 -0
  350. package/build/utils/outside-click.cjs +82 -0
  351. package/build/utils/outside-click.d.cts +18 -0
  352. package/build/utils/outside-click.d.ts +18 -0
  353. package/build/utils/outside-click.js +74 -0
  354. package/build/utils/template-helpers.cjs +39 -0
  355. package/build/utils/template-helpers.d.cts +13 -0
  356. package/build/utils/template-helpers.d.ts +13 -0
  357. package/build/utils/template-helpers.js +28 -0
  358. package/package.json +96 -0
@@ -0,0 +1,942 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CurveControls = void 0;
4
+ const lit_html_1 = require("lit-html");
5
+ const constants_1 = require("./constants.cjs");
6
+ const styles_1 = require("./styles.cjs");
7
+ const types_1 = require("./types.cjs");
8
+ const utils_1 = require("./utils.cjs");
9
+ const Component_1 = require("~/decorators/Component");
10
+ const Prop_1 = require("~/decorators/Prop");
11
+ const shared_1 = require("~/elements/shared");
12
+ require("~/elements/icons/interface/minus");
13
+ require("~/elements/icons/interface/plus");
14
+ require("~/elements/button");
15
+ const HOST_HANDLER_MAP = {
16
+ 'easing-type-change': 'handleEasingTypeChange',
17
+ 'grid-toggle': 'handleGridToggle',
18
+ 'snap-toggle': 'handleSnapToggle',
19
+ 'grid-size-change': 'handleGridSizeChange',
20
+ 'points-change': 'handlePointsChange',
21
+ 'linear-point-focus': 'handleLinearPointFocus'
22
+ };
23
+ @(0, Component_1.Component)({
24
+ tag: 'ease-curve-controls',
25
+ styles: styles_1.controlsStyles,
26
+ template() {
27
+ return (0, lit_html_1.html) `
28
+ <ease-field label="Easing">
29
+ <ease-dropdown
30
+ part="easing-type-dropdown"
31
+ placeholder="Select"
32
+ id="demo-easing-type"
33
+ name="demo-easing-type"
34
+ searchable
35
+ .value=${this._activePresetValue}
36
+ @change=${this.handlePresetSelection}
37
+ >
38
+ ${constants_1.EASING_PRESETS.map(({ label, options }, index) => (0, lit_html_1.html) `
39
+ ${index > 0 ? (0, lit_html_1.html) `<hr slot="content" />` : null}
40
+
41
+ <h4 slot="content">${label}</h4>
42
+ ${options.map(({ value, label }) => (0, lit_html_1.html) `
43
+ <button slot="content" type="button" value=${value}>${label}</button>`)}
44
+ `)}
45
+ </ease-dropdown>
46
+ </ease-field>
47
+
48
+ <ease-field label="Type">
49
+ <ease-radio-group .value=${this.easingType} @change=${this.handleTypeChange} part="radio-group">
50
+ <button slot="content" value=${types_1.EasingType.CUBIC_BEZIER}>Cubic</button>
51
+ <button slot="content" value=${types_1.EasingType.LINEAR}>Linear</button>
52
+ </ease-radio-group>
53
+ </ease-field>
54
+ `;
55
+ }
56
+ })
57
+ class CurveControls extends HTMLElement {
58
+ @(0, Prop_1.Prop)({ reflect: true })
59
+ accessor easingType;
60
+ @(0, Prop_1.Prop)({
61
+ type: Object,
62
+ reflect: false,
63
+ onChange() {
64
+ this.handlePointsPropChange();
65
+ }
66
+ })
67
+ accessor points;
68
+ @(0, Prop_1.Prop)({ type: Boolean, reflect: true, defaultValue: true })
69
+ accessor showGrid;
70
+ @(0, Prop_1.Prop)({ type: Boolean, reflect: true, defaultValue: false })
71
+ accessor snapToGrid;
72
+ @(0, Prop_1.Prop)({ type: Number, reflect: true, defaultValue: 8 })
73
+ accessor gridSize = 8;
74
+ @(0, Prop_1.Prop)({
75
+ type: Number,
76
+ reflect: false,
77
+ defaultValue: null,
78
+ onChange(value) {
79
+ this.handleFocusedLinearIndexPropChange(value);
80
+ }
81
+ })
82
+ accessor focusedLinearIndex = null;
83
+ _activePresetValue = null;
84
+ isApplyingPreset = false;
85
+ #setActivePreset(value) {
86
+ if (this._activePresetValue === value) {
87
+ return;
88
+ }
89
+ this._activePresetValue = value;
90
+ this.requestRender();
91
+ }
92
+ #clearActivePreset() {
93
+ if (this._activePresetValue === null) {
94
+ return;
95
+ }
96
+ this._activePresetValue = null;
97
+ this.requestRender();
98
+ }
99
+ handleFocusedLinearIndexPropChange(_value) {
100
+ this.requestRender();
101
+ }
102
+ handlePointsPropChange() {
103
+ if (this.isApplyingPreset) {
104
+ return;
105
+ }
106
+ this.#clearActivePreset();
107
+ }
108
+ get maxPointsReached() {
109
+ const points = this.#getLinearPoints();
110
+ return points !== null && points.length >= types_1.MAX_LINEAR_POINTS;
111
+ }
112
+ get minPointsReached() {
113
+ const points = this.#getLinearPoints();
114
+ return points !== null && points.length <= types_1.MIN_LINEAR_POINTS;
115
+ }
116
+ #getEventTarget = () => {
117
+ const root = this.getRootNode();
118
+ if (root instanceof ShadowRoot && root.host instanceof HTMLElement) {
119
+ return root.host;
120
+ }
121
+ return this;
122
+ };
123
+ #getLinearPoints = () => {
124
+ if (!Array.isArray(this.points)) {
125
+ return null;
126
+ }
127
+ return this.points;
128
+ };
129
+ renderLinearDetailsControls() {
130
+ const points = this.#getLinearPoints();
131
+ if (!points) {
132
+ return null;
133
+ }
134
+ if (points.length < types_1.MIN_LINEAR_POINTS) {
135
+ return (0, lit_html_1.html) `
136
+ <div class="control-group details-group">
137
+ <span class="details-empty">Curve requires at least 2 points.</span>
138
+ </div>
139
+ `;
140
+ }
141
+ const focusedIndex = this.focusedLinearIndex;
142
+ if (focusedIndex === null) {
143
+ return (0, lit_html_1.html) `
144
+ <div class="control-group details-group">
145
+ <div class="details-panel">
146
+ <span class="details-empty">Select a point on the canvas to edit its details.</span>
147
+ </div>
148
+ </div>
149
+ `;
150
+ }
151
+ const selectedPoint = points[focusedIndex];
152
+ if (!selectedPoint) {
153
+ return null;
154
+ }
155
+ const previousIndex = focusedIndex > 0 ? focusedIndex - 1 : null;
156
+ const nextIndex = focusedIndex < points.length - 1 ? focusedIndex + 1 : null;
157
+ const isInnerPoint = focusedIndex > 0 && focusedIndex < points.length - 1;
158
+ const pointMeta = `${(selectedPoint.x * 100).toFixed(0)}%, ${(selectedPoint.y * 100).toFixed(0)}%`;
159
+ const pointType = selectedPoint.isLinked ? 'Smooth' : 'Corner';
160
+ const hasInHandle = selectedPoint.cpInX !== undefined || selectedPoint.cpInY !== undefined;
161
+ const hasOutHandle = selectedPoint.cpOutX !== undefined || selectedPoint.cpOutY !== undefined;
162
+ const hasAnyHandle = hasInHandle || hasOutHandle;
163
+ return (0, lit_html_1.html) `
164
+ <div class="control-group details-group">
165
+ <div class="details-panel" role="group" aria-label="Linear point details">
166
+ <div class="point-navigation">
167
+ <button
168
+ type="button"
169
+ class="control-button"
170
+ @click=${(event) => this.#focusIndex(event, previousIndex)}
171
+ ?disabled=${previousIndex === null}
172
+ >
173
+ Previous
174
+ </button>
175
+ <div class="point-state" aria-live="polite">
176
+ <span>P${focusedIndex + 1}</span>
177
+ <span>${pointMeta}</span>
178
+ <span>(${pointType})</span>
179
+ </div>
180
+ <button
181
+ type="button"
182
+ class="control-button"
183
+ @click=${(event) => this.#focusIndex(event, nextIndex)}
184
+ ?disabled=${nextIndex === null}
185
+ >
186
+ Next
187
+ </button>
188
+ </div>
189
+
190
+ <div class="coordinate-editor" role="group" aria-label="Point coordinates">
191
+ <label class="coordinate-field">
192
+ <span>X</span>
193
+ <input
194
+ type="number"
195
+ min="0"
196
+ max="1"
197
+ step="0.01"
198
+ .value=${selectedPoint.x.toFixed(2)}
199
+ data-axis="x"
200
+ ?disabled=${!isInnerPoint}
201
+ @change=${this.#handleCoordinateInput}
202
+ />
203
+ </label>
204
+ <label class="coordinate-field">
205
+ <span>Y</span>
206
+ <input
207
+ type="number"
208
+ min="0"
209
+ max="1"
210
+ step="0.01"
211
+ .value=${selectedPoint.y.toFixed(2)}
212
+ data-axis="y"
213
+ @change=${this.#handleCoordinateInput}
214
+ />
215
+ </label>
216
+ <button
217
+ type="button"
218
+ class="coordinate-remove"
219
+ ?disabled=${!isInnerPoint || points.length <= types_1.MIN_LINEAR_POINTS}
220
+ @click=${this.#handleRemoveSelectedPoint}
221
+ >
222
+ Remove
223
+ </button>
224
+ </div>
225
+
226
+ ${isInnerPoint
227
+ ? (0, lit_html_1.html) `
228
+ <div class="point-type-controls" role="group" aria-label="Point type controls">
229
+ <button
230
+ type="button"
231
+ class="control-button ${!selectedPoint.isLinked ? 'active' : ''}"
232
+ data-type="corner"
233
+ @click=${this.#handlePointTypeChange}
234
+ >
235
+ Corner (Independent)
236
+ </button>
237
+ <button
238
+ type="button"
239
+ class="control-button ${selectedPoint.isLinked ? 'active' : ''}"
240
+ data-type="smooth"
241
+ @click=${this.#handlePointTypeChange}
242
+ >
243
+ Smooth (Linked)
244
+ </button>
245
+ <button
246
+ type="button"
247
+ class="control-button ${selectedPoint.isLinked ? 'active' : ''}"
248
+ data-type="mirror-angle"
249
+ @click=${this.#handlePointTypeChange}
250
+ >
251
+ Mirror Angle: ${selectedPoint.isLinked ? 'On' : 'Off'}
252
+ </button>
253
+ <button
254
+ type="button"
255
+ class="control-button ${selectedPoint.mirrorLength !== false ? 'active' : ''}"
256
+ data-type="mirror-length"
257
+ @click=${this.#handlePointTypeChange}
258
+ ?disabled=${!selectedPoint.isLinked}
259
+ >
260
+ Mirror Length: ${selectedPoint.mirrorLength === false ? 'Off' : 'On'}
261
+ </button>
262
+ </div>
263
+
264
+ <div class="handle-actions" role="group" aria-label="Handle removal controls">
265
+ <button
266
+ type="button"
267
+ class="control-button"
268
+ data-handle="both"
269
+ @click=${this.#handleRemoveHandles}
270
+ ?disabled=${!hasAnyHandle}
271
+ >
272
+ Remove Both Handles
273
+ </button>
274
+ <button
275
+ type="button"
276
+ class="control-button"
277
+ data-handle="in"
278
+ @click=${this.#handleRemoveHandles}
279
+ ?disabled=${!hasInHandle}
280
+ >
281
+ Remove Incoming Handle
282
+ </button>
283
+ <button
284
+ type="button"
285
+ class="control-button"
286
+ data-handle="out"
287
+ @click=${this.#handleRemoveHandles}
288
+ ?disabled=${!hasOutHandle}
289
+ >
290
+ Remove Outgoing Handle
291
+ </button>
292
+ </div>
293
+ `
294
+ : this.#renderEndpointHandleControls(selectedPoint, focusedIndex)}
295
+ </div>
296
+ </div>
297
+ `;
298
+ }
299
+ #handleCoordinateInput = (event) => {
300
+ const target = event.target;
301
+ if (!(target instanceof HTMLInputElement)) {
302
+ return;
303
+ }
304
+ const axis = target.dataset.axis;
305
+ if (axis !== 'x' && axis !== 'y') {
306
+ return;
307
+ }
308
+ const points = this.#getLinearPoints();
309
+ if (!points) {
310
+ return;
311
+ }
312
+ const index = this.focusedLinearIndex;
313
+ if (index === null) {
314
+ return;
315
+ }
316
+ const selectedPoint = points[index];
317
+ if (!selectedPoint) {
318
+ return;
319
+ }
320
+ const parsed = Number.parseFloat(target.value);
321
+ if (Number.isNaN(parsed)) {
322
+ target.value = selectedPoint[axis].toFixed(2);
323
+ return;
324
+ }
325
+ const updatedPoints = points.map((point, pointIndex) => {
326
+ if (pointIndex !== index) {
327
+ return { ...point };
328
+ }
329
+ const updated = { ...point };
330
+ if (axis === 'x') {
331
+ if (index === 0 || index === points.length - 1) {
332
+ return updated;
333
+ }
334
+ const previous = points[index - 1];
335
+ const next = points[index + 1];
336
+ const minX = previous ? previous.x + utils_1.MIN_LINEAR_DELTA : 0;
337
+ const maxX = next ? next.x - utils_1.MIN_LINEAR_DELTA : 1;
338
+ updated.x = Math.min(Math.max(parsed, minX), maxX);
339
+ }
340
+ else {
341
+ updated.y = Math.min(Math.max(parsed, 0), 1);
342
+ }
343
+ return updated;
344
+ });
345
+ const normalizedPoints = (0, utils_1.normalizeLinearPoints)(updatedPoints);
346
+ this.#emitPoints(normalizedPoints, event);
347
+ this.focusedLinearIndex = index;
348
+ this.#notifyHost('linear-point-focus', index, event);
349
+ const refreshedPoint = normalizedPoints[index];
350
+ if (refreshedPoint) {
351
+ target.value = refreshedPoint[axis].toFixed(2);
352
+ }
353
+ };
354
+ #handleRemoveSelectedPoint = (event) => {
355
+ const index = this.focusedLinearIndex;
356
+ if (index === null) {
357
+ return;
358
+ }
359
+ this.#removeLinearPointAt(index, event);
360
+ };
361
+ #handlePointTypeChange = (event) => {
362
+ event.preventDefault();
363
+ const target = event.currentTarget;
364
+ if (!(target instanceof HTMLButtonElement)) {
365
+ return;
366
+ }
367
+ const type = target.dataset.type;
368
+ const points = this.#getLinearPoints();
369
+ if (!points) {
370
+ return;
371
+ }
372
+ const index = this.focusedLinearIndex;
373
+ if (index === null) {
374
+ return;
375
+ }
376
+ const point = points[index];
377
+ if (!point) {
378
+ return;
379
+ }
380
+ const updatedPoints = [...points];
381
+ const updatedPoint = { ...point };
382
+ updatedPoints[index] = updatedPoint;
383
+ switch (type) {
384
+ case 'corner': {
385
+ updatedPoint.isLinked = false;
386
+ updatedPoint.mirrorLength = false;
387
+ break;
388
+ }
389
+ case 'smooth': {
390
+ this.#ensureSmoothHandles(updatedPoint, index, points);
391
+ updatedPoint.isLinked = true;
392
+ updatedPoint.mirrorLength = true;
393
+ this.#alignMirrorLength(updatedPoint);
394
+ break;
395
+ }
396
+ case 'mirror-angle': {
397
+ const nextState = !updatedPoint.isLinked;
398
+ if (nextState) {
399
+ this.#ensureSmoothHandles(updatedPoint, index, points);
400
+ updatedPoint.mirrorLength = true;
401
+ this.#alignMirrorLength(updatedPoint);
402
+ }
403
+ else {
404
+ updatedPoint.mirrorLength = false;
405
+ }
406
+ updatedPoint.isLinked = nextState;
407
+ break;
408
+ }
409
+ case 'mirror-length': {
410
+ if (!updatedPoint.isLinked) {
411
+ break;
412
+ }
413
+ const nextState = updatedPoint.mirrorLength === false;
414
+ updatedPoint.mirrorLength = nextState;
415
+ if (nextState) {
416
+ this.#ensureSmoothHandles(updatedPoint, index, points);
417
+ this.#alignMirrorLength(updatedPoint);
418
+ }
419
+ break;
420
+ }
421
+ default:
422
+ return;
423
+ }
424
+ const normalizedPoints = (0, utils_1.normalizeLinearPoints)(updatedPoints);
425
+ this.#emitPoints(normalizedPoints, event);
426
+ this.focusedLinearIndex = index;
427
+ this.#notifyHost('linear-point-focus', index, event);
428
+ };
429
+ #ensureSmoothHandles(point, index, points) {
430
+ const prev = points[index - 1];
431
+ const next = points[index + 1];
432
+ let refDx = point.cpOutX ?? -(point.cpInX ?? 0);
433
+ let refDy = point.cpOutY ?? -(point.cpInY ?? 0);
434
+ if (refDx === 0 && refDy === 0) {
435
+ let dirX = 0;
436
+ let dirY = 0;
437
+ if (prev && next) {
438
+ dirX = next.x - prev.x;
439
+ dirY = next.y - prev.y;
440
+ }
441
+ else if (next) {
442
+ dirX = next.x - point.x;
443
+ dirY = next.y - point.y;
444
+ }
445
+ else if (prev) {
446
+ dirX = point.x - prev.x;
447
+ dirY = point.y - prev.y;
448
+ }
449
+ else {
450
+ dirX = 1;
451
+ dirY = 0;
452
+ }
453
+ const direction = (0, utils_1.normalizeVector)(dirX, dirY);
454
+ const length = constants_1.DEFAULT_HANDLE_LENGTH;
455
+ point.cpInX = -direction.dx * length;
456
+ point.cpInY = -direction.dy * length;
457
+ point.cpOutX = direction.dx * length;
458
+ point.cpOutY = direction.dy * length;
459
+ refDx = point.cpOutX;
460
+ refDy = point.cpOutY;
461
+ }
462
+ if (refDx === 0 && refDy === 0) {
463
+ return;
464
+ }
465
+ const normalized = (0, utils_1.normalizeVector)(refDx, refDy);
466
+ const referenceLength = (0, utils_1.vectorLength)(refDx, refDy);
467
+ const inLength = (0, utils_1.vectorLength)(point.cpInX ?? 0, point.cpInY ?? 0) || referenceLength;
468
+ point.cpInX = -normalized.dx * inLength;
469
+ point.cpInY = -normalized.dy * inLength;
470
+ const outLength = (0, utils_1.vectorLength)(point.cpOutX ?? 0, point.cpOutY ?? 0) || referenceLength;
471
+ point.cpOutX = normalized.dx * outLength;
472
+ point.cpOutY = normalized.dy * outLength;
473
+ }
474
+ #alignMirrorLength(point) {
475
+ if (!point.isLinked) {
476
+ point.mirrorLength = false;
477
+ return;
478
+ }
479
+ const outLength = (0, utils_1.vectorLength)(point.cpOutX ?? 0, point.cpOutY ?? 0);
480
+ const inLength = (0, utils_1.vectorLength)(point.cpInX ?? 0, point.cpInY ?? 0);
481
+ const targetLength = Math.max(outLength, inLength);
482
+ if (targetLength <= 0) {
483
+ return;
484
+ }
485
+ if (outLength > 0) {
486
+ const outDirection = (0, utils_1.normalizeVector)(point.cpOutX ?? 0, point.cpOutY ?? 0);
487
+ point.cpOutX = outDirection.dx * targetLength;
488
+ point.cpOutY = outDirection.dy * targetLength;
489
+ }
490
+ else if (inLength > 0) {
491
+ const inDirection = (0, utils_1.normalizeVector)(point.cpInX ?? 0, point.cpInY ?? 0);
492
+ point.cpOutX = -inDirection.dx * targetLength;
493
+ point.cpOutY = -inDirection.dy * targetLength;
494
+ }
495
+ if (inLength > 0) {
496
+ const inDirection = (0, utils_1.normalizeVector)(point.cpInX ?? 0, point.cpInY ?? 0);
497
+ point.cpInX = inDirection.dx * targetLength;
498
+ point.cpInY = inDirection.dy * targetLength;
499
+ }
500
+ else if (outLength > 0) {
501
+ const outDirection = (0, utils_1.normalizeVector)(point.cpOutX ?? 0, point.cpOutY ?? 0);
502
+ point.cpInX = -outDirection.dx * targetLength;
503
+ point.cpInY = -outDirection.dy * targetLength;
504
+ }
505
+ }
506
+ #handleRemoveHandles = (event) => {
507
+ event.preventDefault();
508
+ const target = event.currentTarget;
509
+ if (!(target instanceof HTMLButtonElement)) {
510
+ return;
511
+ }
512
+ const mode = target.dataset.handle ?? 'both';
513
+ const points = this.#getLinearPoints();
514
+ if (!points) {
515
+ return;
516
+ }
517
+ const index = this.focusedLinearIndex;
518
+ if (index === null) {
519
+ return;
520
+ }
521
+ const updatedPoints = [...points];
522
+ const existingPoint = updatedPoints[index];
523
+ if (!existingPoint) {
524
+ return;
525
+ }
526
+ const updatedPoint = { ...existingPoint };
527
+ updatedPoints[index] = updatedPoint;
528
+ const removeIncoming = mode === 'both' || mode === 'in';
529
+ const removeOutgoing = mode === 'both' || mode === 'out';
530
+ if (removeIncoming) {
531
+ delete updatedPoint.cpInX;
532
+ delete updatedPoint.cpInY;
533
+ }
534
+ if (removeOutgoing) {
535
+ delete updatedPoint.cpOutX;
536
+ delete updatedPoint.cpOutY;
537
+ }
538
+ if (removeIncoming && removeOutgoing) {
539
+ delete updatedPoint.isLinked;
540
+ delete updatedPoint.mirrorLength;
541
+ }
542
+ else if (removeIncoming || removeOutgoing) {
543
+ updatedPoint.isLinked = false;
544
+ updatedPoint.mirrorLength = false;
545
+ }
546
+ const normalizedPoints = (0, utils_1.normalizeLinearPoints)(updatedPoints);
547
+ this.#emitPoints(normalizedPoints, event);
548
+ this.focusedLinearIndex = index;
549
+ this.#notifyHost('linear-point-focus', index, event);
550
+ };
551
+ #renderEndpointHandleControls(point, index) {
552
+ const isStart = index === 0;
553
+ const handleKey = isStart ? 'out' : 'in';
554
+ const handleLabel = isStart ? 'Outgoing' : 'Incoming';
555
+ const hasHandle = handleKey === 'out'
556
+ ? point.cpOutX !== undefined || point.cpOutY !== undefined
557
+ : point.cpInX !== undefined || point.cpInY !== undefined;
558
+ return (0, lit_html_1.html) `
559
+ <div class="handle-actions" role="group" aria-label="${handleLabel} handle controls">
560
+ <button
561
+ type="button"
562
+ class="control-button"
563
+ data-handle=${handleKey}
564
+ @click=${this.#handleEndpointHandleAdd}
565
+ ?disabled=${hasHandle}
566
+ >
567
+ Add ${handleLabel} Handle
568
+ </button>
569
+ <button
570
+ type="button"
571
+ class="control-button"
572
+ data-handle=${handleKey}
573
+ @click=${this.#handleRemoveHandles}
574
+ ?disabled=${!hasHandle}
575
+ >
576
+ Remove ${handleLabel} Handle
577
+ </button>
578
+ </div>
579
+ `;
580
+ }
581
+ #handleEndpointHandleAdd = (event) => {
582
+ event.preventDefault();
583
+ const target = event.currentTarget;
584
+ if (!(target instanceof HTMLButtonElement)) {
585
+ return;
586
+ }
587
+ const handle = target.dataset.handle;
588
+ if (handle !== 'in' && handle !== 'out') {
589
+ return;
590
+ }
591
+ const points = this.#getLinearPoints();
592
+ if (!points) {
593
+ return;
594
+ }
595
+ const index = this.focusedLinearIndex;
596
+ if (index === null) {
597
+ return;
598
+ }
599
+ const neighborIndex = handle === 'out' ? index + 1 : index - 1;
600
+ const neighbor = points[neighborIndex];
601
+ if (!neighbor) {
602
+ return;
603
+ }
604
+ const updatedPoints = [...points];
605
+ const existingPoint = updatedPoints[index];
606
+ if (!existingPoint) {
607
+ return;
608
+ }
609
+ const updatedPoint = { ...existingPoint };
610
+ updatedPoints[index] = updatedPoint;
611
+ this.#createEndpointHandle(updatedPoint, neighbor, handle);
612
+ const normalizedPoints = (0, utils_1.normalizeLinearPoints)(updatedPoints);
613
+ this.#emitPoints(normalizedPoints, event);
614
+ this.focusedLinearIndex = index;
615
+ this.#notifyHost('linear-point-focus', index, event);
616
+ };
617
+ #createEndpointHandle(point, neighbor, handle) {
618
+ const dx = neighbor.x - point.x;
619
+ const dy = neighbor.y - point.y;
620
+ const direction = (0, utils_1.normalizeVector)(dx, dy);
621
+ const fallbackDirection = handle === 'out' ? { dx: 1, dy: 0 } : { dx: -1, dy: 0 };
622
+ const finalDirection = direction.dx === 0 && direction.dy === 0 ? fallbackDirection : direction;
623
+ const gap = Math.abs(dx);
624
+ const baseLength = gap > 0 ? gap * 0.5 : utils_1.MIN_LINEAR_DELTA * 0.5;
625
+ const length = Math.min(constants_1.DEFAULT_HANDLE_LENGTH, Math.max(utils_1.MIN_LINEAR_DELTA * 0.5, baseLength));
626
+ if (handle === 'out') {
627
+ point.cpOutX = finalDirection.dx * length;
628
+ point.cpOutY = finalDirection.dy * length;
629
+ }
630
+ else {
631
+ point.cpInX = finalDirection.dx * length;
632
+ point.cpInY = finalDirection.dy * length;
633
+ }
634
+ point.isLinked = false;
635
+ point.mirrorLength = false;
636
+ }
637
+ #removeLinearPointAt(index, event) {
638
+ const points = this.#getLinearPoints();
639
+ if (!points || points.length <= types_1.MIN_LINEAR_POINTS) {
640
+ return;
641
+ }
642
+ if (index <= 0 || index >= points.length - 1) {
643
+ return;
644
+ }
645
+ const updatedPoints = points
646
+ .filter((_, pointIndex) => pointIndex !== index)
647
+ .map((point) => {
648
+ return { ...point };
649
+ });
650
+ const normalizedPoints = (0, utils_1.normalizeLinearPoints)(updatedPoints);
651
+ this.#emitPoints(normalizedPoints, event);
652
+ const nextIndex = index - 1;
653
+ this.focusedLinearIndex = nextIndex;
654
+ this.#notifyHost('linear-point-focus', nextIndex, event);
655
+ }
656
+ resetCurve = (event) => {
657
+ event.preventDefault();
658
+ this.#clearActivePreset();
659
+ if (this.easingType === types_1.EasingType.CUBIC_BEZIER) {
660
+ const defaults = {
661
+ p1: { x: 0.25, y: 0.1 },
662
+ p2: { x: 0.25, y: 1 }
663
+ };
664
+ this.points = defaults;
665
+ this.#notifyHost('points-change', defaults, event);
666
+ return;
667
+ }
668
+ const defaults = [
669
+ { x: 0, y: 0 },
670
+ { x: 1, y: 1 }
671
+ ];
672
+ this.points = defaults;
673
+ this.#notifyHost('points-change', defaults, event);
674
+ this.focusedLinearIndex = null;
675
+ this.#notifyHost('linear-point-focus', null, event);
676
+ };
677
+ distributeLinearPoints = (event) => {
678
+ event.preventDefault();
679
+ const points = this.#getLinearPoints();
680
+ if (!points || points.length <= types_1.MIN_LINEAR_POINTS) {
681
+ return;
682
+ }
683
+ const lastIndex = points.length - 1;
684
+ const step = lastIndex > 0 ? 1 / lastIndex : 0;
685
+ const distributed = points.map((point, index) => {
686
+ const updated = { ...point };
687
+ if (index === 0) {
688
+ updated.x = 0;
689
+ }
690
+ else if (index === lastIndex) {
691
+ updated.x = 1;
692
+ }
693
+ else {
694
+ updated.x = Number.parseFloat((step * index).toFixed(4));
695
+ }
696
+ delete updated.cpInX;
697
+ delete updated.cpInY;
698
+ delete updated.cpOutX;
699
+ delete updated.cpOutY;
700
+ delete updated.isLinked;
701
+ return updated;
702
+ });
703
+ const normalizedPoints = (0, utils_1.normalizeLinearPoints)(distributed);
704
+ this.#emitPoints(normalizedPoints, event);
705
+ if (this.focusedLinearIndex !== null) {
706
+ this.#notifyHost('linear-point-focus', this.focusedLinearIndex, event);
707
+ }
708
+ };
709
+ #focusIndex = (event, index) => {
710
+ event.preventDefault();
711
+ if (index !== null) {
712
+ this.focusedLinearIndex = index;
713
+ this.#notifyHost('linear-point-focus', index, event);
714
+ }
715
+ };
716
+ #setEasingType = (type, event) => {
717
+ if (this.easingType === type) {
718
+ return;
719
+ }
720
+ if (!this.isApplyingPreset) {
721
+ this.#clearActivePreset();
722
+ }
723
+ this.easingType = type;
724
+ this.#notifyHost('easing-type-change', type, event);
725
+ };
726
+ #emitPoints = (points, event) => {
727
+ if (!this.isApplyingPreset) {
728
+ this.#clearActivePreset();
729
+ }
730
+ this.points = points;
731
+ this.#notifyHost('points-change', points, event);
732
+ };
733
+ #applyPreset = (points, type, presetValue, event) => {
734
+ this.isApplyingPreset = true;
735
+ if (this.easingType !== type) {
736
+ this.#setEasingType(type, event);
737
+ }
738
+ this.points = points;
739
+ this.focusedLinearIndex = null;
740
+ this.#setActivePreset(presetValue);
741
+ this.#notifyHost('points-change', points, event);
742
+ if (type === types_1.EasingType.LINEAR) {
743
+ this.#notifyHost('linear-point-focus', null, event);
744
+ }
745
+ this.isApplyingPreset = false;
746
+ };
747
+ handleTypeChange = (event) => {
748
+ const detail = event.detail;
749
+ if (!detail) {
750
+ return;
751
+ }
752
+ const { value, event: originEvent } = detail;
753
+ if (value === types_1.EasingType.CUBIC_BEZIER || value === types_1.EasingType.LINEAR) {
754
+ this.#clearActivePreset();
755
+ this.#setEasingType(value, originEvent ?? event);
756
+ }
757
+ };
758
+ handlePresetSelection = (event) => {
759
+ const detail = event.detail;
760
+ if (!detail) {
761
+ return;
762
+ }
763
+ const rawValue = detail.value;
764
+ const originEvent = detail.event ?? event;
765
+ if (typeof rawValue !== 'string') {
766
+ return;
767
+ }
768
+ const cssValue = rawValue.trim();
769
+ if (cssValue.length === 0) {
770
+ this.#clearActivePreset();
771
+ return;
772
+ }
773
+ if (cssValue.startsWith(types_1.EasingType.CUBIC_BEZIER)) {
774
+ const parsed = (0, utils_1.parseCubicBezierValue)(cssValue);
775
+ if (!parsed) {
776
+ this.#clearActivePreset();
777
+ return;
778
+ }
779
+ this.#applyPreset(parsed, types_1.EasingType.CUBIC_BEZIER, cssValue, originEvent);
780
+ return;
781
+ }
782
+ if (cssValue.startsWith(types_1.EasingType.LINEAR)) {
783
+ const parsedLinear = (0, utils_1.parseLinearTimingFunction)(cssValue);
784
+ if (!parsedLinear) {
785
+ this.#clearActivePreset();
786
+ return;
787
+ }
788
+ // Apply smoothing to linear presets for better visual curves
789
+ const smoothedLinear = (0, utils_1.smoothLinearPoints)(parsedLinear, 0.3);
790
+ this.#applyPreset(smoothedLinear, types_1.EasingType.LINEAR, cssValue, originEvent);
791
+ return;
792
+ }
793
+ this.#clearActivePreset();
794
+ };
795
+ handleSelectCubic = (event) => {
796
+ event.preventDefault();
797
+ this.#setEasingType(types_1.EasingType.CUBIC_BEZIER, event);
798
+ };
799
+ handleSelectLinear = (event) => {
800
+ event.preventDefault();
801
+ this.#setEasingType(types_1.EasingType.LINEAR, event);
802
+ };
803
+ addLinearPoint = (event) => {
804
+ event.preventDefault();
805
+ if (this.easingType !== types_1.EasingType.LINEAR) {
806
+ return;
807
+ }
808
+ const points = this.#getLinearPoints();
809
+ if (!points || this.maxPointsReached) {
810
+ return;
811
+ }
812
+ let insertIndex = 0;
813
+ let largestGap = -Infinity;
814
+ for (let index = 0; index < points.length - 1; index += 1) {
815
+ const start = points[index];
816
+ const end = points[index + 1];
817
+ if (!start || !end) {
818
+ continue;
819
+ }
820
+ const gap = end.x - start.x;
821
+ if (gap > largestGap) {
822
+ largestGap = gap;
823
+ insertIndex = index;
824
+ }
825
+ }
826
+ const startPoint = points[insertIndex];
827
+ const endPoint = points[insertIndex + 1];
828
+ if (!startPoint || !endPoint) {
829
+ return;
830
+ }
831
+ const newPointPosition = (0, utils_1.clampPoint)({
832
+ x: (startPoint.x + endPoint.x) / 2,
833
+ y: (startPoint.y + endPoint.y) / 2
834
+ });
835
+ const newPoint = {
836
+ x: newPointPosition.x,
837
+ y: newPointPosition.y,
838
+ cpInX: -0.1,
839
+ cpInY: 0,
840
+ cpOutX: 0.1,
841
+ cpOutY: 0,
842
+ isLinked: true,
843
+ mirrorLength: true
844
+ };
845
+ const updatedPoints = [
846
+ ...points.slice(0, insertIndex + 1),
847
+ newPoint,
848
+ ...points.slice(insertIndex + 1)
849
+ ];
850
+ const insertedIndex = insertIndex + 1;
851
+ const normalizedPoints = (0, utils_1.normalizeLinearPoints)(updatedPoints);
852
+ this.#emitPoints(normalizedPoints, event);
853
+ this.focusedLinearIndex = insertedIndex;
854
+ this.#notifyHost('linear-point-focus', insertedIndex, event);
855
+ };
856
+ removeLinearPoint = (event) => {
857
+ event.preventDefault();
858
+ if (this.easingType !== types_1.EasingType.LINEAR) {
859
+ return;
860
+ }
861
+ const points = this.#getLinearPoints();
862
+ if (!points || this.minPointsReached) {
863
+ return;
864
+ }
865
+ let removeIndex = 1;
866
+ let smallestSpan = Number.POSITIVE_INFINITY;
867
+ for (let index = 1; index < points.length - 1; index += 1) {
868
+ const previous = points[index - 1];
869
+ const next = points[index + 1];
870
+ if (!previous || !next) {
871
+ continue;
872
+ }
873
+ const span = next.x - previous.x;
874
+ if (span < smallestSpan) {
875
+ smallestSpan = span;
876
+ removeIndex = index;
877
+ }
878
+ }
879
+ if (removeIndex > 0 && removeIndex < points.length - 1) {
880
+ this.#removeLinearPointAt(removeIndex, event);
881
+ }
882
+ };
883
+ toggleGrid = (event) => {
884
+ event.preventDefault();
885
+ const nextValue = !this.showGrid;
886
+ this.showGrid = nextValue;
887
+ this.#notifyHost('grid-toggle', nextValue, event);
888
+ };
889
+ toggleSnapToGrid = (event) => {
890
+ event.preventDefault();
891
+ const nextValue = !this.snapToGrid;
892
+ this.snapToGrid = nextValue;
893
+ this.#notifyHost('snap-toggle', nextValue, event);
894
+ };
895
+ incrementGridSize = (event) => {
896
+ event.preventDefault();
897
+ this.#commitGridSize(this.gridSize + 1, event);
898
+ };
899
+ decrementGridSize = (event) => {
900
+ event.preventDefault();
901
+ this.#commitGridSize(this.gridSize - 1, event);
902
+ };
903
+ handleGridSliderInput = (event) => {
904
+ event.preventDefault();
905
+ const target = event.target;
906
+ if (!(target instanceof HTMLInputElement)) {
907
+ return;
908
+ }
909
+ this.#commitGridSize(Number(target.value), event);
910
+ };
911
+ handleGridSizeChange = (event) => {
912
+ event.preventDefault();
913
+ const target = event.target;
914
+ if (!(target instanceof HTMLInputElement)) {
915
+ return;
916
+ }
917
+ const parsed = Number(target.value);
918
+ if (Number.isNaN(parsed)) {
919
+ target.value = String(this.gridSize);
920
+ return;
921
+ }
922
+ this.#commitGridSize(parsed, event);
923
+ target.value = String(this.gridSize);
924
+ };
925
+ #clampGridSize = (value) => Math.max(1, Math.min(24, Math.round(value)));
926
+ #commitGridSize = (value, event) => {
927
+ const nextValue = this.#clampGridSize(value);
928
+ if (this.gridSize === nextValue) {
929
+ this.requestRender();
930
+ return;
931
+ }
932
+ this.gridSize = nextValue;
933
+ this.#notifyHost('grid-size-change', this.gridSize, event);
934
+ this.requestRender();
935
+ };
936
+ #notifyHost = (type, value, event) => {
937
+ const target = this.#getEventTarget();
938
+ const detail = { value, event };
939
+ (0, shared_1.dispatchControlEvent)(target, type, detail);
940
+ };
941
+ }
942
+ exports.CurveControls = CurveControls;