@coze-arch/cli 0.0.10 → 0.0.11

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 (437) hide show
  1. package/lib/__templates__/expo/AGENTS.md +3 -3
  2. package/lib/__templates__/expo/README.md +3 -3
  3. package/lib/__templates__/expo/client/components/Provider.tsx +4 -1
  4. package/lib/__templates__/expo/client/components/Screen.tsx +4 -1
  5. package/lib/__templates__/expo/client/eslint.config.mjs +2 -0
  6. package/lib/__templates__/expo/client/global.css +1 -0
  7. package/lib/__templates__/expo/client/heroui/components/accordion/accordion.animation.ts +178 -0
  8. package/lib/__templates__/expo/client/heroui/components/accordion/accordion.constants.ts +62 -0
  9. package/lib/__templates__/expo/client/heroui/components/accordion/accordion.md +437 -0
  10. package/lib/__templates__/expo/client/heroui/components/accordion/accordion.styles.ts +95 -0
  11. package/lib/__templates__/expo/client/heroui/components/accordion/accordion.tsx +340 -0
  12. package/lib/__templates__/expo/client/heroui/components/accordion/accordion.types.ts +267 -0
  13. package/lib/__templates__/expo/client/heroui/components/accordion/index.ts +17 -0
  14. package/lib/__templates__/expo/client/heroui/components/alert/alert.constants.ts +13 -0
  15. package/lib/__templates__/expo/client/heroui/components/alert/alert.hooks.ts +28 -0
  16. package/lib/__templates__/expo/client/heroui/components/alert/alert.md +263 -0
  17. package/lib/__templates__/expo/client/heroui/components/alert/alert.styles.ts +65 -0
  18. package/lib/__templates__/expo/client/heroui/components/alert/alert.tsx +181 -0
  19. package/lib/__templates__/expo/client/heroui/components/alert/alert.types.ts +99 -0
  20. package/lib/__templates__/expo/client/heroui/components/alert/alert.utils.tsx +25 -0
  21. package/lib/__templates__/expo/client/heroui/components/alert/default-icon.tsx +28 -0
  22. package/lib/__templates__/expo/client/heroui/components/alert/index.ts +15 -0
  23. package/lib/__templates__/expo/client/heroui/components/alert/success-icon.tsx +28 -0
  24. package/lib/__templates__/expo/client/heroui/components/alert/warning-icon.tsx +28 -0
  25. package/lib/__templates__/expo/client/heroui/components/avatar/avatar.animation.ts +123 -0
  26. package/lib/__templates__/expo/client/heroui/components/avatar/avatar.constants.ts +19 -0
  27. package/lib/__templates__/expo/client/heroui/components/avatar/avatar.context.ts +11 -0
  28. package/lib/__templates__/expo/client/heroui/components/avatar/avatar.md +386 -0
  29. package/lib/__templates__/expo/client/heroui/components/avatar/avatar.styles.ts +145 -0
  30. package/lib/__templates__/expo/client/heroui/components/avatar/avatar.tsx +307 -0
  31. package/lib/__templates__/expo/client/heroui/components/avatar/avatar.types.ts +239 -0
  32. package/lib/__templates__/expo/client/heroui/components/avatar/index.ts +13 -0
  33. package/lib/__templates__/expo/client/heroui/components/avatar/person-icon.tsx +23 -0
  34. package/lib/__templates__/expo/client/heroui/components/bottom-sheet/bottom-sheet.animation.ts +42 -0
  35. package/lib/__templates__/expo/client/heroui/components/bottom-sheet/bottom-sheet.constants.ts +13 -0
  36. package/lib/__templates__/expo/client/heroui/components/bottom-sheet/bottom-sheet.md +349 -0
  37. package/lib/__templates__/expo/client/heroui/components/bottom-sheet/bottom-sheet.styles.ts +66 -0
  38. package/lib/__templates__/expo/client/heroui/components/bottom-sheet/bottom-sheet.tsx +351 -0
  39. package/lib/__templates__/expo/client/heroui/components/bottom-sheet/bottom-sheet.types.ts +150 -0
  40. package/lib/__templates__/expo/client/heroui/components/bottom-sheet/index.ts +16 -0
  41. package/lib/__templates__/expo/client/heroui/components/button/button.constants.ts +7 -0
  42. package/lib/__templates__/expo/client/heroui/components/button/button.md +381 -0
  43. package/lib/__templates__/expo/client/heroui/components/button/button.styles.ts +89 -0
  44. package/lib/__templates__/expo/client/heroui/components/button/button.tsx +284 -0
  45. package/lib/__templates__/expo/client/heroui/components/button/button.types.ts +175 -0
  46. package/lib/__templates__/expo/client/heroui/components/button/button.utils.ts +34 -0
  47. package/lib/__templates__/expo/client/heroui/components/button/index.ts +9 -0
  48. package/lib/__templates__/expo/client/heroui/components/card/card.constants.ts +11 -0
  49. package/lib/__templates__/expo/client/heroui/components/card/card.md +186 -0
  50. package/lib/__templates__/expo/client/heroui/components/card/card.styles.ts +35 -0
  51. package/lib/__templates__/expo/client/heroui/components/card/card.tsx +153 -0
  52. package/lib/__templates__/expo/client/heroui/components/card/card.types.ts +77 -0
  53. package/lib/__templates__/expo/client/heroui/components/card/index.ts +10 -0
  54. package/lib/__templates__/expo/client/heroui/components/checkbox/checkbox.animation.ts +202 -0
  55. package/lib/__templates__/expo/client/heroui/components/checkbox/checkbox.constants.ts +6 -0
  56. package/lib/__templates__/expo/client/heroui/components/checkbox/checkbox.md +311 -0
  57. package/lib/__templates__/expo/client/heroui/components/checkbox/checkbox.styles.ts +105 -0
  58. package/lib/__templates__/expo/client/heroui/components/checkbox/checkbox.tsx +251 -0
  59. package/lib/__templates__/expo/client/heroui/components/checkbox/checkbox.types.ts +216 -0
  60. package/lib/__templates__/expo/client/heroui/components/checkbox/index.ts +3 -0
  61. package/lib/__templates__/expo/client/heroui/components/chip/chip.animation.ts +18 -0
  62. package/lib/__templates__/expo/client/heroui/components/chip/chip.constants.ts +7 -0
  63. package/lib/__templates__/expo/client/heroui/components/chip/chip.md +190 -0
  64. package/lib/__templates__/expo/client/heroui/components/chip/chip.styles.ts +234 -0
  65. package/lib/__templates__/expo/client/heroui/components/chip/chip.tsx +125 -0
  66. package/lib/__templates__/expo/client/heroui/components/chip/chip.types.ts +69 -0
  67. package/lib/__templates__/expo/client/heroui/components/chip/index.ts +3 -0
  68. package/lib/__templates__/expo/client/heroui/components/close-button/close-button.constants.ts +6 -0
  69. package/lib/__templates__/expo/client/heroui/components/close-button/close-button.md +109 -0
  70. package/lib/__templates__/expo/client/heroui/components/close-button/close-button.styles.ts +13 -0
  71. package/lib/__templates__/expo/client/heroui/components/close-button/close-button.tsx +57 -0
  72. package/lib/__templates__/expo/client/heroui/components/close-button/close-button.types.ts +30 -0
  73. package/lib/__templates__/expo/client/heroui/components/close-button/index.ts +6 -0
  74. package/lib/__templates__/expo/client/heroui/components/control-field/control-field.animation.ts +18 -0
  75. package/lib/__templates__/expo/client/heroui/components/control-field/control-field.constants.ts +7 -0
  76. package/lib/__templates__/expo/client/heroui/components/control-field/control-field.context.ts +14 -0
  77. package/lib/__templates__/expo/client/heroui/components/control-field/control-field.md +241 -0
  78. package/lib/__templates__/expo/client/heroui/components/control-field/control-field.styles.ts +15 -0
  79. package/lib/__templates__/expo/client/heroui/components/control-field/control-field.tsx +245 -0
  80. package/lib/__templates__/expo/client/heroui/components/control-field/control-field.types.ts +67 -0
  81. package/lib/__templates__/expo/client/heroui/components/control-field/index.ts +6 -0
  82. package/lib/__templates__/expo/client/heroui/components/description/description.animation.ts +53 -0
  83. package/lib/__templates__/expo/client/heroui/components/description/description.constants.ts +30 -0
  84. package/lib/__templates__/expo/client/heroui/components/description/description.md +129 -0
  85. package/lib/__templates__/expo/client/heroui/components/description/description.styles.ts +25 -0
  86. package/lib/__templates__/expo/client/heroui/components/description/description.tsx +81 -0
  87. package/lib/__templates__/expo/client/heroui/components/description/description.types.ts +77 -0
  88. package/lib/__templates__/expo/client/heroui/components/description/index.ts +3 -0
  89. package/lib/__templates__/expo/client/heroui/components/dialog/dialog.animation.ts +9 -0
  90. package/lib/__templates__/expo/client/heroui/components/dialog/dialog.constants.ts +13 -0
  91. package/lib/__templates__/expo/client/heroui/components/dialog/dialog.md +288 -0
  92. package/lib/__templates__/expo/client/heroui/components/dialog/dialog.styles.ts +77 -0
  93. package/lib/__templates__/expo/client/heroui/components/dialog/dialog.tsx +379 -0
  94. package/lib/__templates__/expo/client/heroui/components/dialog/dialog.types.ts +199 -0
  95. package/lib/__templates__/expo/client/heroui/components/dialog/index.ts +12 -0
  96. package/lib/__templates__/expo/client/heroui/components/field-error/field-error.animation.ts +50 -0
  97. package/lib/__templates__/expo/client/heroui/components/field-error/field-error.constants.ts +31 -0
  98. package/lib/__templates__/expo/client/heroui/components/field-error/field-error.md +204 -0
  99. package/lib/__templates__/expo/client/heroui/components/field-error/field-error.styles.ts +23 -0
  100. package/lib/__templates__/expo/client/heroui/components/field-error/field-error.tsx +91 -0
  101. package/lib/__templates__/expo/client/heroui/components/field-error/field-error.types.ts +79 -0
  102. package/lib/__templates__/expo/client/heroui/components/field-error/index.ts +3 -0
  103. package/lib/__templates__/expo/client/heroui/components/input/index.ts +3 -0
  104. package/lib/__templates__/expo/client/heroui/components/input/input.constants.ts +6 -0
  105. package/lib/__templates__/expo/client/heroui/components/input/input.md +193 -0
  106. package/lib/__templates__/expo/client/heroui/components/input/input.styles.ts +51 -0
  107. package/lib/__templates__/expo/client/heroui/components/input/input.tsx +96 -0
  108. package/lib/__templates__/expo/client/heroui/components/input/input.types.ts +44 -0
  109. package/lib/__templates__/expo/client/heroui/components/input-group/index.ts +9 -0
  110. package/lib/__templates__/expo/client/heroui/components/input-group/input-group.animation.ts +14 -0
  111. package/lib/__templates__/expo/client/heroui/components/input-group/input-group.constants.ts +6 -0
  112. package/lib/__templates__/expo/client/heroui/components/input-group/input-group.md +197 -0
  113. package/lib/__templates__/expo/client/heroui/components/input-group/input-group.styles.ts +31 -0
  114. package/lib/__templates__/expo/client/heroui/components/input-group/input-group.tsx +239 -0
  115. package/lib/__templates__/expo/client/heroui/components/input-group/input-group.types.ts +98 -0
  116. package/lib/__templates__/expo/client/heroui/components/input-otp/index.ts +9 -0
  117. package/lib/__templates__/expo/client/heroui/components/input-otp/input-otp.animation.ts +199 -0
  118. package/lib/__templates__/expo/client/heroui/components/input-otp/input-otp.constants.ts +12 -0
  119. package/lib/__templates__/expo/client/heroui/components/input-otp/input-otp.md +376 -0
  120. package/lib/__templates__/expo/client/heroui/components/input-otp/input-otp.styles.ts +68 -0
  121. package/lib/__templates__/expo/client/heroui/components/input-otp/input-otp.tsx +414 -0
  122. package/lib/__templates__/expo/client/heroui/components/input-otp/input-otp.types.ts +275 -0
  123. package/lib/__templates__/expo/client/heroui/components/label/index.ts +3 -0
  124. package/lib/__templates__/expo/client/heroui/components/label/label.animation.ts +18 -0
  125. package/lib/__templates__/expo/client/heroui/components/label/label.constants.ts +7 -0
  126. package/lib/__templates__/expo/client/heroui/components/label/label.md +187 -0
  127. package/lib/__templates__/expo/client/heroui/components/label/label.styles.ts +44 -0
  128. package/lib/__templates__/expo/client/heroui/components/label/label.tsx +172 -0
  129. package/lib/__templates__/expo/client/heroui/components/label/label.types.ts +86 -0
  130. package/lib/__templates__/expo/client/heroui/components/list-group/index.ts +17 -0
  131. package/lib/__templates__/expo/client/heroui/components/list-group/list-group.constants.ts +17 -0
  132. package/lib/__templates__/expo/client/heroui/components/list-group/list-group.md +387 -0
  133. package/lib/__templates__/expo/client/heroui/components/list-group/list-group.styles.ts +40 -0
  134. package/lib/__templates__/expo/client/heroui/components/list-group/list-group.tsx +206 -0
  135. package/lib/__templates__/expo/client/heroui/components/list-group/list-group.types.ts +132 -0
  136. package/lib/__templates__/expo/client/heroui/components/menu/index.ts +38 -0
  137. package/lib/__templates__/expo/client/heroui/components/menu/menu.animation.ts +121 -0
  138. package/lib/__templates__/expo/client/heroui/components/menu/menu.constants.ts +37 -0
  139. package/lib/__templates__/expo/client/heroui/components/menu/menu.md +620 -0
  140. package/lib/__templates__/expo/client/heroui/components/menu/menu.styles.ts +107 -0
  141. package/lib/__templates__/expo/client/heroui/components/menu/menu.tsx +664 -0
  142. package/lib/__templates__/expo/client/heroui/components/menu/menu.types.ts +394 -0
  143. package/lib/__templates__/expo/client/heroui/components/popover/arrow-svg.tsx +180 -0
  144. package/lib/__templates__/expo/client/heroui/components/popover/index.ts +18 -0
  145. package/lib/__templates__/expo/client/heroui/components/popover/popover.animation.ts +9 -0
  146. package/lib/__templates__/expo/client/heroui/components/popover/popover.constants.ts +34 -0
  147. package/lib/__templates__/expo/client/heroui/components/popover/popover.md +508 -0
  148. package/lib/__templates__/expo/client/heroui/components/popover/popover.styles.ts +98 -0
  149. package/lib/__templates__/expo/client/heroui/components/popover/popover.tsx +624 -0
  150. package/lib/__templates__/expo/client/heroui/components/popover/popover.types.ts +290 -0
  151. package/lib/__templates__/expo/client/heroui/components/pressable-feedback/index.ts +3 -0
  152. package/lib/__templates__/expo/client/heroui/components/pressable-feedback/pressable-feedback.animation.ts +450 -0
  153. package/lib/__templates__/expo/client/heroui/components/pressable-feedback/pressable-feedback.constants.ts +12 -0
  154. package/lib/__templates__/expo/client/heroui/components/pressable-feedback/pressable-feedback.md +328 -0
  155. package/lib/__templates__/expo/client/heroui/components/pressable-feedback/pressable-feedback.styles.ts +84 -0
  156. package/lib/__templates__/expo/client/heroui/components/pressable-feedback/pressable-feedback.tsx +330 -0
  157. package/lib/__templates__/expo/client/heroui/components/pressable-feedback/pressable-feedback.types.ts +386 -0
  158. package/lib/__templates__/expo/client/heroui/components/radio/index.ts +9 -0
  159. package/lib/__templates__/expo/client/heroui/components/radio/radio.animation.ts +92 -0
  160. package/lib/__templates__/expo/client/heroui/components/radio/radio.constants.ts +11 -0
  161. package/lib/__templates__/expo/client/heroui/components/radio/radio.md +339 -0
  162. package/lib/__templates__/expo/client/heroui/components/radio/radio.styles.ts +80 -0
  163. package/lib/__templates__/expo/client/heroui/components/radio/radio.tsx +217 -0
  164. package/lib/__templates__/expo/client/heroui/components/radio/radio.types.ts +106 -0
  165. package/lib/__templates__/expo/client/heroui/components/radio-group/index.ts +9 -0
  166. package/lib/__templates__/expo/client/heroui/components/radio-group/radio-group.animation.ts +20 -0
  167. package/lib/__templates__/expo/client/heroui/components/radio-group/radio-group.constants.ts +7 -0
  168. package/lib/__templates__/expo/client/heroui/components/radio-group/radio-group.context.ts +14 -0
  169. package/lib/__templates__/expo/client/heroui/components/radio-group/radio-group.md +273 -0
  170. package/lib/__templates__/expo/client/heroui/components/radio-group/radio-group.styles.ts +15 -0
  171. package/lib/__templates__/expo/client/heroui/components/radio-group/radio-group.tsx +220 -0
  172. package/lib/__templates__/expo/client/heroui/components/radio-group/radio-group.types.ts +64 -0
  173. package/lib/__templates__/expo/client/heroui/components/scroll-shadow/index.ts +7 -0
  174. package/lib/__templates__/expo/client/heroui/components/scroll-shadow/scroll-shadow.animation.ts +132 -0
  175. package/lib/__templates__/expo/client/heroui/components/scroll-shadow/scroll-shadow.constants.ts +21 -0
  176. package/lib/__templates__/expo/client/heroui/components/scroll-shadow/scroll-shadow.md +206 -0
  177. package/lib/__templates__/expo/client/heroui/components/scroll-shadow/scroll-shadow.styles.ts +52 -0
  178. package/lib/__templates__/expo/client/heroui/components/scroll-shadow/scroll-shadow.tsx +262 -0
  179. package/lib/__templates__/expo/client/heroui/components/scroll-shadow/scroll-shadow.types.ts +121 -0
  180. package/lib/__templates__/expo/client/heroui/components/search-field/index.ts +17 -0
  181. package/lib/__templates__/expo/client/heroui/components/search-field/search-field.animation.ts +18 -0
  182. package/lib/__templates__/expo/client/heroui/components/search-field/search-field.constants.ts +10 -0
  183. package/lib/__templates__/expo/client/heroui/components/search-field/search-field.md +231 -0
  184. package/lib/__templates__/expo/client/heroui/components/search-field/search-field.styles.ts +35 -0
  185. package/lib/__templates__/expo/client/heroui/components/search-field/search-field.tsx +253 -0
  186. package/lib/__templates__/expo/client/heroui/components/search-field/search-field.types.ts +160 -0
  187. package/lib/__templates__/expo/client/heroui/components/search-field/search-icon.tsx +37 -0
  188. package/lib/__templates__/expo/client/heroui/components/select/index.ts +28 -0
  189. package/lib/__templates__/expo/client/heroui/components/select/select.animation.ts +92 -0
  190. package/lib/__templates__/expo/client/heroui/components/select/select.constants.ts +53 -0
  191. package/lib/__templates__/expo/client/heroui/components/select/select.md +796 -0
  192. package/lib/__templates__/expo/client/heroui/components/select/select.styles.ts +149 -0
  193. package/lib/__templates__/expo/client/heroui/components/select/select.tsx +828 -0
  194. package/lib/__templates__/expo/client/heroui/components/select/select.types.ts +438 -0
  195. package/lib/__templates__/expo/client/heroui/components/separator/index.ts +7 -0
  196. package/lib/__templates__/expo/client/heroui/components/separator/separator.constants.ts +6 -0
  197. package/lib/__templates__/expo/client/heroui/components/separator/separator.md +106 -0
  198. package/lib/__templates__/expo/client/heroui/components/separator/separator.styles.ts +50 -0
  199. package/lib/__templates__/expo/client/heroui/components/separator/separator.tsx +62 -0
  200. package/lib/__templates__/expo/client/heroui/components/separator/separator.types.ts +40 -0
  201. package/lib/__templates__/expo/client/heroui/components/skeleton/index.ts +7 -0
  202. package/lib/__templates__/expo/client/heroui/components/skeleton/linear-gradient.tsx +45 -0
  203. package/lib/__templates__/expo/client/heroui/components/skeleton/skeleton.animation.ts +351 -0
  204. package/lib/__templates__/expo/client/heroui/components/skeleton/skeleton.constants.ts +39 -0
  205. package/lib/__templates__/expo/client/heroui/components/skeleton/skeleton.md +208 -0
  206. package/lib/__templates__/expo/client/heroui/components/skeleton/skeleton.styles.ts +49 -0
  207. package/lib/__templates__/expo/client/heroui/components/skeleton/skeleton.tsx +183 -0
  208. package/lib/__templates__/expo/client/heroui/components/skeleton/skeleton.types.ts +191 -0
  209. package/lib/__templates__/expo/client/heroui/components/skeleton-group/index.ts +7 -0
  210. package/lib/__templates__/expo/client/heroui/components/skeleton-group/skeleton-group.constants.ts +7 -0
  211. package/lib/__templates__/expo/client/heroui/components/skeleton-group/skeleton-group.md +247 -0
  212. package/lib/__templates__/expo/client/heroui/components/skeleton-group/skeleton-group.styles.ts +10 -0
  213. package/lib/__templates__/expo/client/heroui/components/skeleton-group/skeleton-group.tsx +94 -0
  214. package/lib/__templates__/expo/client/heroui/components/skeleton-group/skeleton-group.types.ts +28 -0
  215. package/lib/__templates__/expo/client/heroui/components/slider/index.ts +23 -0
  216. package/lib/__templates__/expo/client/heroui/components/slider/slider.animation.ts +87 -0
  217. package/lib/__templates__/expo/client/heroui/components/slider/slider.constants.ts +24 -0
  218. package/lib/__templates__/expo/client/heroui/components/slider/slider.md +348 -0
  219. package/lib/__templates__/expo/client/heroui/components/slider/slider.styles.ts +85 -0
  220. package/lib/__templates__/expo/client/heroui/components/slider/slider.tsx +413 -0
  221. package/lib/__templates__/expo/client/heroui/components/slider/slider.types.ts +120 -0
  222. package/lib/__templates__/expo/client/heroui/components/spinner/index.ts +10 -0
  223. package/lib/__templates__/expo/client/heroui/components/spinner/spinner-icon.tsx +49 -0
  224. package/lib/__templates__/expo/client/heroui/components/spinner/spinner.animation.ts +150 -0
  225. package/lib/__templates__/expo/client/heroui/components/spinner/spinner.constants.ts +36 -0
  226. package/lib/__templates__/expo/client/heroui/components/spinner/spinner.md +199 -0
  227. package/lib/__templates__/expo/client/heroui/components/spinner/spinner.styles.ts +44 -0
  228. package/lib/__templates__/expo/client/heroui/components/spinner/spinner.tsx +198 -0
  229. package/lib/__templates__/expo/client/heroui/components/spinner/spinner.types.ts +158 -0
  230. package/lib/__templates__/expo/client/heroui/components/surface/index.ts +3 -0
  231. package/lib/__templates__/expo/client/heroui/components/surface/surface.animation.ts +18 -0
  232. package/lib/__templates__/expo/client/heroui/components/surface/surface.constants.ts +6 -0
  233. package/lib/__templates__/expo/client/heroui/components/surface/surface.md +136 -0
  234. package/lib/__templates__/expo/client/heroui/components/surface/surface.styles.ts +28 -0
  235. package/lib/__templates__/expo/client/heroui/components/surface/surface.tsx +66 -0
  236. package/lib/__templates__/expo/client/heroui/components/surface/surface.types.ts +46 -0
  237. package/lib/__templates__/expo/client/heroui/components/switch/index.ts +3 -0
  238. package/lib/__templates__/expo/client/heroui/components/switch/switch.animation.ts +243 -0
  239. package/lib/__templates__/expo/client/heroui/components/switch/switch.constants.ts +26 -0
  240. package/lib/__templates__/expo/client/heroui/components/switch/switch.md +334 -0
  241. package/lib/__templates__/expo/client/heroui/components/switch/switch.styles.ts +83 -0
  242. package/lib/__templates__/expo/client/heroui/components/switch/switch.tsx +280 -0
  243. package/lib/__templates__/expo/client/heroui/components/switch/switch.types.ts +208 -0
  244. package/lib/__templates__/expo/client/heroui/components/tabs/index.ts +8 -0
  245. package/lib/__templates__/expo/client/heroui/components/tabs/tabs.animation.ts +246 -0
  246. package/lib/__templates__/expo/client/heroui/components/tabs/tabs.constants.ts +17 -0
  247. package/lib/__templates__/expo/client/heroui/components/tabs/tabs.context.ts +28 -0
  248. package/lib/__templates__/expo/client/heroui/components/tabs/tabs.md +565 -0
  249. package/lib/__templates__/expo/client/heroui/components/tabs/tabs.styles.ts +168 -0
  250. package/lib/__templates__/expo/client/heroui/components/tabs/tabs.tsx +445 -0
  251. package/lib/__templates__/expo/client/heroui/components/tabs/tabs.types.ts +341 -0
  252. package/lib/__templates__/expo/client/heroui/components/tag-group/index.ts +15 -0
  253. package/lib/__templates__/expo/client/heroui/components/tag-group/tag-group.animation.ts +17 -0
  254. package/lib/__templates__/expo/client/heroui/components/tag-group/tag-group.constants.ts +10 -0
  255. package/lib/__templates__/expo/client/heroui/components/tag-group/tag-group.md +404 -0
  256. package/lib/__templates__/expo/client/heroui/components/tag-group/tag-group.styles.ts +74 -0
  257. package/lib/__templates__/expo/client/heroui/components/tag-group/tag-group.tsx +325 -0
  258. package/lib/__templates__/expo/client/heroui/components/tag-group/tag-group.types.ts +125 -0
  259. package/lib/__templates__/expo/client/heroui/components/text-area/index.ts +3 -0
  260. package/lib/__templates__/expo/client/heroui/components/text-area/text-area.constants.ts +6 -0
  261. package/lib/__templates__/expo/client/heroui/components/text-area/text-area.md +133 -0
  262. package/lib/__templates__/expo/client/heroui/components/text-area/text-area.styles.ts +10 -0
  263. package/lib/__templates__/expo/client/heroui/components/text-area/text-area.tsx +44 -0
  264. package/lib/__templates__/expo/client/heroui/components/text-area/text-area.types.ts +6 -0
  265. package/lib/__templates__/expo/client/heroui/components/text-field/index.ts +3 -0
  266. package/lib/__templates__/expo/client/heroui/components/text-field/text-field.animation.ts +20 -0
  267. package/lib/__templates__/expo/client/heroui/components/text-field/text-field.constants.ts +6 -0
  268. package/lib/__templates__/expo/client/heroui/components/text-field/text-field.md +256 -0
  269. package/lib/__templates__/expo/client/heroui/components/text-field/text-field.styles.ts +10 -0
  270. package/lib/__templates__/expo/client/heroui/components/text-field/text-field.tsx +82 -0
  271. package/lib/__templates__/expo/client/heroui/components/text-field/text-field.types.ts +56 -0
  272. package/lib/__templates__/expo/client/heroui/components/toast/index.ts +4 -0
  273. package/lib/__templates__/expo/client/heroui/components/toast/toast.animation.ts +381 -0
  274. package/lib/__templates__/expo/client/heroui/components/toast/toast.constants.ts +10 -0
  275. package/lib/__templates__/expo/client/heroui/components/toast/toast.hooks.ts +73 -0
  276. package/lib/__templates__/expo/client/heroui/components/toast/toast.md +420 -0
  277. package/lib/__templates__/expo/client/heroui/components/toast/toast.styles.ts +89 -0
  278. package/lib/__templates__/expo/client/heroui/components/toast/toast.tsx +472 -0
  279. package/lib/__templates__/expo/client/heroui/components/toast/toast.types.ts +320 -0
  280. package/lib/__templates__/expo/client/heroui/docs.md +47 -0
  281. package/lib/__templates__/expo/client/heroui/helpers/external/hooks/index.ts +3 -0
  282. package/lib/__templates__/expo/client/heroui/helpers/external/hooks/use-is-on-surface.ts +8 -0
  283. package/lib/__templates__/expo/client/heroui/helpers/external/hooks/use-theme-color.ts +137 -0
  284. package/lib/__templates__/expo/client/heroui/helpers/external/utils/cn.ts +12 -0
  285. package/lib/__templates__/expo/client/heroui/helpers/external/utils/color-kit/index.ts +2395 -0
  286. package/lib/__templates__/expo/client/heroui/helpers/external/utils/color-kit/types.ts +212 -0
  287. package/lib/__templates__/expo/client/heroui/helpers/external/utils/index.ts +2 -0
  288. package/lib/__templates__/expo/client/heroui/helpers/internal/components/animated-check-icon.tsx +78 -0
  289. package/lib/__templates__/expo/client/heroui/helpers/internal/components/bottom-sheet-content-container.tsx +97 -0
  290. package/lib/__templates__/expo/client/heroui/helpers/internal/components/bottom-sheet-content.tsx +158 -0
  291. package/lib/__templates__/expo/client/heroui/helpers/internal/components/check-icon.tsx +28 -0
  292. package/lib/__templates__/expo/client/heroui/helpers/internal/components/chevron-down-icon.tsx +28 -0
  293. package/lib/__templates__/expo/client/heroui/helpers/internal/components/chevron-right-icon.tsx +29 -0
  294. package/lib/__templates__/expo/client/heroui/helpers/internal/components/close-icon.tsx +29 -0
  295. package/lib/__templates__/expo/client/heroui/helpers/internal/components/full-window-overlay.tsx +48 -0
  296. package/lib/__templates__/expo/client/heroui/helpers/internal/components/hero-text.tsx +71 -0
  297. package/lib/__templates__/expo/client/heroui/helpers/internal/components/index.ts +9 -0
  298. package/lib/__templates__/expo/client/heroui/helpers/internal/contexts/animation-settings-context.ts +19 -0
  299. package/lib/__templates__/expo/client/heroui/helpers/internal/contexts/bottom-sheet-is-dragging-context.ts +11 -0
  300. package/lib/__templates__/expo/client/heroui/helpers/internal/contexts/form-field-context.ts +36 -0
  301. package/lib/__templates__/expo/client/heroui/helpers/internal/contexts/index.ts +3 -0
  302. package/lib/__templates__/expo/client/heroui/helpers/internal/hooks/index.ts +14 -0
  303. package/lib/__templates__/expo/client/heroui/helpers/internal/hooks/use-augmented-ref.ts +32 -0
  304. package/lib/__templates__/expo/client/heroui/helpers/internal/hooks/use-bottom-sheet-aware-handlers.ts +94 -0
  305. package/lib/__templates__/expo/client/heroui/helpers/internal/hooks/use-bottom-sheet-gesture-handlers.ts +52 -0
  306. package/lib/__templates__/expo/client/heroui/helpers/internal/hooks/use-combined-animation-disabled-state.ts +49 -0
  307. package/lib/__templates__/expo/client/heroui/helpers/internal/hooks/use-controllable-state.ts +124 -0
  308. package/lib/__templates__/expo/client/heroui/helpers/internal/hooks/use-dev-info.ts +38 -0
  309. package/lib/__templates__/expo/client/heroui/helpers/internal/hooks/use-keyboard-status.ts +22 -0
  310. package/lib/__templates__/expo/client/heroui/helpers/internal/hooks/use-popup-bottom-sheet-content-animation.ts +67 -0
  311. package/lib/__templates__/expo/client/heroui/helpers/internal/hooks/use-popup-dialog-content-animation.ts +296 -0
  312. package/lib/__templates__/expo/client/heroui/helpers/internal/hooks/use-popup-overlay-animation.ts +91 -0
  313. package/lib/__templates__/expo/client/heroui/helpers/internal/hooks/use-popup-popover-content-animation.ts +199 -0
  314. package/lib/__templates__/expo/client/heroui/helpers/internal/hooks/use-popup-root-animation.ts +26 -0
  315. package/lib/__templates__/expo/client/heroui/helpers/internal/hooks/use-relative-position.ts +353 -0
  316. package/lib/__templates__/expo/client/heroui/helpers/internal/hooks/use-resolved-style-property.ts +118 -0
  317. package/lib/__templates__/expo/client/heroui/helpers/internal/types/animation.ts +131 -0
  318. package/lib/__templates__/expo/client/heroui/helpers/internal/types/bottom-sheet.ts +99 -0
  319. package/lib/__templates__/expo/client/heroui/helpers/internal/types/index.ts +5 -0
  320. package/lib/__templates__/expo/client/heroui/helpers/internal/types/misc.ts +10 -0
  321. package/lib/__templates__/expo/client/heroui/helpers/internal/types/primitives.ts +146 -0
  322. package/lib/__templates__/expo/client/heroui/helpers/internal/types/theme.ts +18 -0
  323. package/lib/__templates__/expo/client/heroui/helpers/internal/utils/animation.ts +266 -0
  324. package/lib/__templates__/expo/client/heroui/helpers/internal/utils/children-to-string.ts +117 -0
  325. package/lib/__templates__/expo/client/heroui/helpers/internal/utils/combine-styles.ts +17 -0
  326. package/lib/__templates__/expo/client/heroui/helpers/internal/utils/create-context.ts +60 -0
  327. package/lib/__templates__/expo/client/heroui/helpers/internal/utils/ease-gradient/create-interpolation.ts +35 -0
  328. package/lib/__templates__/expo/client/heroui/helpers/internal/utils/ease-gradient/index.ts +97 -0
  329. package/lib/__templates__/expo/client/heroui/helpers/internal/utils/get-element-by-display-name.ts +15 -0
  330. package/lib/__templates__/expo/client/heroui/helpers/internal/utils/get-element-with-default.ts +17 -0
  331. package/lib/__templates__/expo/client/heroui/helpers/internal/utils/has-prop.ts +18 -0
  332. package/lib/__templates__/expo/client/heroui/helpers/internal/utils/index.ts +8 -0
  333. package/lib/__templates__/expo/client/heroui/index.tsx +51 -0
  334. package/lib/__templates__/expo/client/heroui/primitives/README.md +27 -0
  335. package/lib/__templates__/expo/client/heroui/primitives/accordion/accordion.tsx +270 -0
  336. package/lib/__templates__/expo/client/heroui/primitives/accordion/accordion.types.ts +117 -0
  337. package/lib/__templates__/expo/client/heroui/primitives/accordion/accordion.utils.ts +12 -0
  338. package/lib/__templates__/expo/client/heroui/primitives/accordion/index.ts +2 -0
  339. package/lib/__templates__/expo/client/heroui/primitives/activity-indicator/activity-indicator.tsx +50 -0
  340. package/lib/__templates__/expo/client/heroui/primitives/activity-indicator/activity-indicator.types.ts +24 -0
  341. package/lib/__templates__/expo/client/heroui/primitives/activity-indicator/index.ts +2 -0
  342. package/lib/__templates__/expo/client/heroui/primitives/alert/alert.tsx +124 -0
  343. package/lib/__templates__/expo/client/heroui/primitives/alert/alert.types.ts +87 -0
  344. package/lib/__templates__/expo/client/heroui/primitives/alert/index.ts +2 -0
  345. package/lib/__templates__/expo/client/heroui/primitives/avatar/avatar.tsx +171 -0
  346. package/lib/__templates__/expo/client/heroui/primitives/avatar/avatar.types.ts +62 -0
  347. package/lib/__templates__/expo/client/heroui/primitives/avatar/avatar.utils.ts +102 -0
  348. package/lib/__templates__/expo/client/heroui/primitives/avatar/index.ts +2 -0
  349. package/lib/__templates__/expo/client/heroui/primitives/bottom-sheet/bottom-sheet.tsx +235 -0
  350. package/lib/__templates__/expo/client/heroui/primitives/bottom-sheet/bottom-sheet.types.ts +127 -0
  351. package/lib/__templates__/expo/client/heroui/primitives/bottom-sheet/index.ts +2 -0
  352. package/lib/__templates__/expo/client/heroui/primitives/checkbox/checkbox.tsx +119 -0
  353. package/lib/__templates__/expo/client/heroui/primitives/checkbox/checkbox.types.ts +37 -0
  354. package/lib/__templates__/expo/client/heroui/primitives/checkbox/index.ts +2 -0
  355. package/lib/__templates__/expo/client/heroui/primitives/dialog/dialog.tsx +274 -0
  356. package/lib/__templates__/expo/client/heroui/primitives/dialog/dialog.types.ts +129 -0
  357. package/lib/__templates__/expo/client/heroui/primitives/dialog/index.ts +2 -0
  358. package/lib/__templates__/expo/client/heroui/primitives/input-otp/index.ts +3 -0
  359. package/lib/__templates__/expo/client/heroui/primitives/input-otp/input-otp.tsx +431 -0
  360. package/lib/__templates__/expo/client/heroui/primitives/input-otp/input-otp.types.ts +169 -0
  361. package/lib/__templates__/expo/client/heroui/primitives/input-otp/input-otp.utils.ts +31 -0
  362. package/lib/__templates__/expo/client/heroui/primitives/label/index.ts +2 -0
  363. package/lib/__templates__/expo/client/heroui/primitives/label/label.tsx +24 -0
  364. package/lib/__templates__/expo/client/heroui/primitives/label/label.types.ts +39 -0
  365. package/lib/__templates__/expo/client/heroui/primitives/menu/index.ts +2 -0
  366. package/lib/__templates__/expo/client/heroui/primitives/menu/menu.tsx +765 -0
  367. package/lib/__templates__/expo/client/heroui/primitives/menu/menu.types.ts +401 -0
  368. package/lib/__templates__/expo/client/heroui/primitives/popover/index.ts +2 -0
  369. package/lib/__templates__/expo/client/heroui/primitives/popover/popover.tsx +382 -0
  370. package/lib/__templates__/expo/client/heroui/primitives/popover/popover.types.ts +201 -0
  371. package/lib/__templates__/expo/client/heroui/primitives/portal/index.ts +1 -0
  372. package/lib/__templates__/expo/client/heroui/primitives/portal/portal.tsx +126 -0
  373. package/lib/__templates__/expo/client/heroui/primitives/radio/index.ts +2 -0
  374. package/lib/__templates__/expo/client/heroui/primitives/radio/radio.tsx +133 -0
  375. package/lib/__templates__/expo/client/heroui/primitives/radio/radio.types.ts +47 -0
  376. package/lib/__templates__/expo/client/heroui/primitives/radio-group/index.ts +2 -0
  377. package/lib/__templates__/expo/client/heroui/primitives/radio-group/radio-group.tsx +114 -0
  378. package/lib/__templates__/expo/client/heroui/primitives/radio-group/radio-group.types.ts +65 -0
  379. package/lib/__templates__/expo/client/heroui/primitives/select/index.ts +2 -0
  380. package/lib/__templates__/expo/client/heroui/primitives/select/select.tsx +705 -0
  381. package/lib/__templates__/expo/client/heroui/primitives/select/select.types.ts +409 -0
  382. package/lib/__templates__/expo/client/heroui/primitives/select/select.utils.ts +35 -0
  383. package/lib/__templates__/expo/client/heroui/primitives/slider/index.ts +3 -0
  384. package/lib/__templates__/expo/client/heroui/primitives/slider/slider.tsx +464 -0
  385. package/lib/__templates__/expo/client/heroui/primitives/slider/slider.types.ts +208 -0
  386. package/lib/__templates__/expo/client/heroui/primitives/slider/slider.utils.ts +93 -0
  387. package/lib/__templates__/expo/client/heroui/primitives/slot/index.ts +1 -0
  388. package/lib/__templates__/expo/client/heroui/primitives/slot/slot.tsx +122 -0
  389. package/lib/__templates__/expo/client/heroui/primitives/slot/types.ts +19 -0
  390. package/lib/__templates__/expo/client/heroui/primitives/slot/utils.ts +96 -0
  391. package/lib/__templates__/expo/client/heroui/primitives/switch/index.ts +2 -0
  392. package/lib/__templates__/expo/client/heroui/primitives/switch/switch.tsx +61 -0
  393. package/lib/__templates__/expo/client/heroui/primitives/switch/switch.types.ts +55 -0
  394. package/lib/__templates__/expo/client/heroui/primitives/tabs/index.ts +2 -0
  395. package/lib/__templates__/expo/client/heroui/primitives/tabs/tabs.tsx +202 -0
  396. package/lib/__templates__/expo/client/heroui/primitives/tabs/tabs.types.ts +77 -0
  397. package/lib/__templates__/expo/client/heroui/primitives/tag-group/index.ts +2 -0
  398. package/lib/__templates__/expo/client/heroui/primitives/tag-group/tag-group.tsx +324 -0
  399. package/lib/__templates__/expo/client/heroui/primitives/tag-group/tag-group.types.ts +119 -0
  400. package/lib/__templates__/expo/client/heroui/primitives/toast/index.ts +2 -0
  401. package/lib/__templates__/expo/client/heroui/primitives/toast/toast.tsx +138 -0
  402. package/lib/__templates__/expo/client/heroui/primitives/toast/toast.types.ts +86 -0
  403. package/lib/__templates__/expo/client/heroui/providers/animation-settings/index.ts +8 -0
  404. package/lib/__templates__/expo/client/heroui/providers/animation-settings/provider.tsx +47 -0
  405. package/lib/__templates__/expo/client/heroui/providers/animation-settings/types.ts +27 -0
  406. package/lib/__templates__/expo/client/heroui/providers/hero-ui-native/index.ts +2 -0
  407. package/lib/__templates__/expo/client/heroui/providers/hero-ui-native/provider.tsx +67 -0
  408. package/lib/__templates__/expo/client/heroui/providers/hero-ui-native/types.ts +114 -0
  409. package/lib/__templates__/expo/client/heroui/providers/hero-ui-native-raw/index.ts +2 -0
  410. package/lib/__templates__/expo/client/heroui/providers/hero-ui-native-raw/provider.tsx +50 -0
  411. package/lib/__templates__/expo/client/heroui/providers/hero-ui-native-raw/types.ts +39 -0
  412. package/lib/__templates__/expo/client/heroui/providers/text-component/index.ts +2 -0
  413. package/lib/__templates__/expo/client/heroui/providers/text-component/provider.tsx +9 -0
  414. package/lib/__templates__/expo/client/heroui/providers/text-component/types.ts +52 -0
  415. package/lib/__templates__/expo/client/heroui/providers/toast/index.ts +3 -0
  416. package/lib/__templates__/expo/client/heroui/providers/toast/insets-container.tsx +87 -0
  417. package/lib/__templates__/expo/client/heroui/providers/toast/provider.tsx +431 -0
  418. package/lib/__templates__/expo/client/heroui/providers/toast/reducer.ts +34 -0
  419. package/lib/__templates__/expo/client/heroui/providers/toast/toast-config.context.ts +27 -0
  420. package/lib/__templates__/expo/client/heroui/providers/toast/toast-item-renderer.tsx +45 -0
  421. package/lib/__templates__/expo/client/heroui/providers/toast/types.ts +373 -0
  422. package/lib/__templates__/expo/client/heroui/styles/index.css +3 -0
  423. package/lib/__templates__/expo/client/heroui/styles/theme.css +112 -0
  424. package/lib/__templates__/expo/client/heroui/styles/utilities.css +8 -0
  425. package/lib/__templates__/expo/client/heroui/styles/variables.css +146 -0
  426. package/lib/__templates__/expo/client/package.json +4 -1
  427. package/lib/__templates__/expo/package.json +1 -1
  428. package/lib/__templates__/expo/pnpm-lock.yaml +68 -0
  429. package/lib/__templates__/nextjs/AGENTS.md +6 -4
  430. package/lib/__templates__/nextjs/eslint.config.mjs +9 -0
  431. package/lib/__templates__/taro/.coze +2 -0
  432. package/lib/__templates__/taro/.cozeproj/scripts/pack.sh +1 -2
  433. package/lib/__templates__/taro/config/index.ts +1 -1
  434. package/lib/__templates__/taro/package.json +1 -0
  435. package/lib/__templates__/taro/project.config.json +1 -1
  436. package/lib/cli.js +246 -252
  437. package/package.json +3 -2
@@ -0,0 +1,2395 @@
1
+ /* eslint-disable regexp/use-ignore-case */
2
+ /* eslint-disable regexp/optimal-quantifier-concatenation */
3
+ /* eslint-disable regexp/no-useless-quantifier */
4
+ /**
5
+ * Color manipulation utilities adapted from reanimated-color-picker
6
+ *
7
+ * Original source: https://github.com/alabsi91/reanimated-color-picker
8
+ * Author: @alabsi91
9
+ * License: MIT
10
+ *
11
+ * This code has been adapted for use in HeroUI Native with modifications
12
+ * for TypeScript compatibility and integration with the theme system.
13
+ */
14
+
15
+ import type {
16
+ ColorFormats,
17
+ ColorTypes,
18
+ ConversionMethods,
19
+ hslaT,
20
+ hslT,
21
+ hsvaT,
22
+ hsvT,
23
+ hwbaT,
24
+ hwbT,
25
+ rgbaT,
26
+ rgbT,
27
+ SupportedColorFormats,
28
+ } from './types';
29
+
30
+ // If you find yourself wondering why all of this is within a single function,
31
+ // the reason is that to execute each method on the UI thread, you must include the 'worklet' directive.
32
+ // Functions marked with this directive are transformed by the Reanimated Babel plugin
33
+ // into IIFE — IMMEDIATELY INVOKED FUNCTION EXPRESSION: `const fun = (function{})()`.
34
+ // Due to the presence of numerous methods,
35
+ // this transformation can lead to a slow initial execution.
36
+ // To address this issue, I consolidated them into a single worklet function.
37
+
38
+ export const colorKitUI = () => {
39
+ 'worklet';
40
+
41
+ const NAMED_COLORS = {
42
+ aliceblue: '#f0f8ff',
43
+ antiquewhite: '#faebd7',
44
+ aqua: '#00ffff',
45
+ aquamarine: '#7fffd4',
46
+ azure: '#f0ffff',
47
+ beige: '#f5f5dc',
48
+ bisque: '#ffe4c4',
49
+ black: '#000000',
50
+ blanchedalmond: '#ffebcd',
51
+ blue: '#0000ff',
52
+ blueviolet: '#8a2be2',
53
+ brown: '#a52a2a',
54
+ burlywood: '#deb887',
55
+ cadetblue: '#5f9ea0',
56
+ chartreuse: '#7fff00',
57
+ chocolate: '#d2691e',
58
+ coral: '#ff7f50',
59
+ cornflowerblue: '#6495ed',
60
+ cornsilk: '#fff8dc',
61
+ crimson: '#dc143c',
62
+ cyan: '#00ffff',
63
+ darkblue: '#00008b',
64
+ darkcyan: '#008b8b',
65
+ darkgoldenrod: '#b8860b',
66
+ darkgray: '#a9a9a9',
67
+ darkgreen: '#006400',
68
+ darkgrey: '#a9a9a9',
69
+ darkkhaki: '#bdb76b',
70
+ darkmagenta: '#8b008b',
71
+ darkolivegreen: '#556b2f',
72
+ darkorange: '#ff8c00',
73
+ darkorchid: '#9932cc',
74
+ darkred: '#8b0000',
75
+ darksalmon: '#e9967a',
76
+ darkseagreen: '#8fbc8f',
77
+ darkslateblue: '#483d8b',
78
+ darkslategrey: '#2f4f4f',
79
+ darkturquoise: '#00ced1',
80
+ darkviolet: '#9400d3',
81
+ deeppink: '#ff1493',
82
+ deepskyblue: '#00bfff',
83
+ dimgray: '#696969',
84
+ dimgrey: '#696969',
85
+ dodgerblue: '#1e90ff',
86
+ firebrick: '#b22222',
87
+ floralwhite: '#fffaf0',
88
+ forestgreen: '#228b22',
89
+ fuchsia: '#ff00ff',
90
+ gainsboro: '#dcdcdc',
91
+ ghostwhite: '#f8f8ff',
92
+ gold: '#ffd700',
93
+ goldenrod: '#daa520',
94
+ gray: '#808080',
95
+ green: '#008000',
96
+ greenyellow: '#adff2f',
97
+ grey: '#808080',
98
+ honeydew: '#f0fff0',
99
+ hotpink: '#ff69b4',
100
+ indianred: '#cd5c5c',
101
+ indigo: '#4b0082',
102
+ ivory: '#fffff0',
103
+ khaki: '#f0e68c',
104
+ lavender: '#e6e6fa',
105
+ lavenderblush: '#fff0f5',
106
+ lawngreen: '#7cfc00',
107
+ lemonchiffon: '#fffacd',
108
+ lightblue: '#add8e6',
109
+ lightcoral: '#f08080',
110
+ lightcyan: '#e0ffff',
111
+ lightgoldenrodyellow: '#fafad2',
112
+ lightgray: '#d3d3d3',
113
+ lightgreen: '#90ee90',
114
+ lightgrey: '#d3d3d3',
115
+ lightpink: '#ffb6c1',
116
+ lightsalmon: '#ffa07a',
117
+ lightseagreen: '#20b2aa',
118
+ lightskyblue: '#87cefa',
119
+ lightslategrey: '#778899',
120
+ lightsteelblue: '#b0c4de',
121
+ lightyellow: '#ffffe0',
122
+ lime: '#00ff00',
123
+ limegreen: '#32cd32',
124
+ linen: '#faf0e6',
125
+ magenta: '#ff00ff',
126
+ maroon: '#800000',
127
+ mediumaquamarine: '#66cdaa',
128
+ mediumblue: '#0000cd',
129
+ mediumorchid: '#ba55d3',
130
+ mediumpurple: '#9370db',
131
+ mediumseagreen: '#3cb371',
132
+ mediumslateblue: '#7b68ee',
133
+ mediumspringgreen: '#00fa9a',
134
+ mediumturquoise: '#48d1cc',
135
+ mediumvioletred: '#c71585',
136
+ midnightblue: '#191970',
137
+ mintcream: '#f5fffa',
138
+ mistyrose: '#ffe4e1',
139
+ moccasin: '#ffe4b5',
140
+ navajowhite: '#ffdead',
141
+ navy: '#000080',
142
+ oldlace: '#fdf5e6',
143
+ olive: '#808000',
144
+ olivedrab: '#6b8e23',
145
+ orange: '#ffa500',
146
+ orangered: '#ff4500',
147
+ orchid: '#da70d6',
148
+ palegoldenrod: '#eee8aa',
149
+ palegreen: '#98fb98',
150
+ paleturquoise: '#afeeee',
151
+ palevioletred: '#db7093',
152
+ papayawhip: '#ffefd5',
153
+ peachpuff: '#ffdab9',
154
+ peru: '#cd853f',
155
+ pink: '#ffc0cb',
156
+ plum: '#dda0dd',
157
+ powderblue: '#b0e0e6',
158
+ purple: '#800080',
159
+ rebeccapurple: '#663399',
160
+ red: '#ff0000',
161
+ rosybrown: '#bc8f8f',
162
+ royalblue: '#4169e1',
163
+ saddlebrown: '#8b4513',
164
+ salmon: '#fa8072',
165
+ sandybrown: '#f4a460',
166
+ seagreen: '#2e8b57',
167
+ seashell: '#fff5ee',
168
+ sienna: '#a0522d',
169
+ silver: '#c0c0c0',
170
+ skyblue: '#87ceeb',
171
+ slateblue: '#6a5acd',
172
+ slategray: '#708090',
173
+ snow: '#fffafa',
174
+ springgreen: '#00ff7f',
175
+ steelblue: '#4682b4',
176
+ tan: '#d2b48c',
177
+ teal: '#008080',
178
+ thistle: '#d8bfd8',
179
+ tomato: '#ff6347',
180
+ turquoise: '#40e0d0',
181
+ violet: '#ee82ee',
182
+ wheat: '#f5deb3',
183
+ white: '#ffffff',
184
+ whitesmoke: '#f5f5f5',
185
+ yellow: '#ffff00',
186
+ yellowgreen: '#9acd32',
187
+ };
188
+
189
+ const COLORS_REGEX: Record<ColorFormats, RegExp | RegExp[]> = {
190
+ // #rgb
191
+ hex3: /^#([A-Fa-f0-9]{3})$/,
192
+ // #rgba
193
+ hex4: /^#([A-Fa-f0-9]{3}[A-Fa-f0-9]{1})$/,
194
+ // #rrggbb
195
+ hex6: /^#([A-Fa-f0-9]{6})$/,
196
+ // #rrggbbaa
197
+ hex8: /^#([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i,
198
+
199
+ hsl: [
200
+ // hsl(360deg, 100%, 100%) hsl(360, 100%, 100%) hsl(23.55, 12.22%, 34.56%)
201
+ /^hsl\s*\(\s*([\d.]+)(?:deg)?\s*,\s*([\d.]+)%\s*,\s*([\d.]+)%\s*\)$/i,
202
+ // hsl(360deg 100% 100%) hsl(360 100% 100%) hsl(23.55 12.22% 34.56%)
203
+ /^hsl\s*\(\s*([\d.]+)(?:deg)?\s+([\d.]+)%\s+([\d.]+)%\s*\)$/i,
204
+ ],
205
+ hsla: [
206
+ // hsla(360deg, 100%, 100%, 1.0) hsla(360, 100%, 100%, 1.0) hsl(360deg, 100%, 100%, 1.0) hsl(360, 100%, 100%, 1.0)
207
+ /^hsla?\s*\(\s*([\d.]+)(?:deg)?\s*,\s*([\d.]+)%\s*,\s*([\d.]+)%\s*,\s*(\d|\d\.\d+)\s*\)$/i,
208
+ // hsla(360deg 100% 100% / 1.0) hsla(360 100% 100% / 1.0) hsl(360deg 100% 100% / 1.0) hsl(360 100% 100% / 1.0)
209
+ /^hsla?\s*\(\s*([\d.]+)(?:deg)?\s+([\d.]+)%\s+([\d.]+)%\s*\/\s*(\d|\d\.\d+)\s*\)$/i,
210
+ ],
211
+
212
+ hsv: [
213
+ // hsv(360deg, 000%, 000%) hsv(360, 100%, 100%)
214
+ /^hsv\s*\(\s*(\d{1,3})(?:deg)?\s*,\s*([\d.]+)%\s*,\s*([\d.]+)%\s*\)$/i,
215
+ // hsv(360deg 000% 000%) hsv(360 100% 100%)
216
+ /^hsv\s*\(\s*(\d{1,3})(?:deg)?\s+([\d.]+)%\s+([\d.]+)%\s*\)$/i,
217
+ ],
218
+ hsva: [
219
+ // hsva(360deg, 100%, 100%, 1.0) hsva(360, 100%, 100%, 1.0) hsv(360deg, 100%, 100%, 1.0) hsv(360, 100%, 100%, 1.0)
220
+ /^hsva?\s*\(\s*(\d{1,3})(?:deg)?\s*,\s*([\d.]+)%\s*,\s*([\d.]+)%\s*,\s*(\d|\d\.\d+)\s*\)$/i,
221
+ // hsva(360deg 100% 100% / 1.0) hsva(360 100% 100% / 1.0) hsv(360deg 100% 100% / 1.0) hsv(360 100% 100% / 1.0)
222
+ /^hsva?\s*\(\s*(\d{1,3})(?:deg)?\s+([\d.]+)%\s+([\d.]+)%\s*\/\s*(\d|\d\.\d+)\s*\)$/i,
223
+ ],
224
+
225
+ hwb: [
226
+ // hwb(360deg, 100%, 100%) hwb(360, 100%, 100%)
227
+ /^hwb\s*\(\s*(\d{1,3})(?:deg)?\s*,\s*([\d.]+)%\s*,\s*([\d.]+)%\s*\)$/i,
228
+ // hwb(360deg 100% 100%) hwb(360 100% 100%)
229
+ /^hwb\s*\(\s*(\d{1,3})(?:deg)?\s+([\d.]+)%\s+([\d.]+)%\s*\)$/i,
230
+ ],
231
+ hwba: [
232
+ // hwba(360deg, 100%, 100%, 1.0) hwba(360, 100%, 100%, 1.0) hwb(360deg, 100%, 100%, 1.0) hwb(360, 100%, 100%, 1.0)
233
+ /^hwba?\s*\(\s*(\d{1,3})(?:deg)?\s*,\s*([\d.]+)%\s*,\s*([\d.]+)%\s*,\s*(\d|\d\.\d+)\s*\)$/i,
234
+ // hwb(360deg 100% 100% 1.0) hwb(360 100% 100% / 1.0) hwba(360deg 100% 100% 1.0) hwba(360 100% 100% / 1.0)
235
+ /^hwba?\s*\(\s*(\d{1,3})(?:deg)?\s+([\d.]+)%\s+([\d.]+)%\s*\/\s*(\d|\d\.\d+)\s*\)$/i,
236
+ ],
237
+
238
+ rgb: [
239
+ // rgb(255, 255, 255)
240
+ /^rgb\s*\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*\)$/i,
241
+ // rgb(255 255 255)
242
+ /^rgb\s*\(\s*(\d{1,3})\s+(\d{1,3})\s+(\d{1,3})\s*\)$/i,
243
+ ],
244
+ rgba: [
245
+ // rgba(255, 255, 255, 1.0) rgb(255, 255, 255, 1.0)
246
+ /^rgba?\s*\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*([\d.]+)\s*\)$/i,
247
+ // rgba(255 255 255 / 1.0) rgb(255 255 255 / 1.0)
248
+ /^rgba?\s*\(\s*(\d{1,3})\s+(\d{1,3})\s+(\d{1,3})\s*\/\s*([\d.]+)\s*\)$/i,
249
+ ],
250
+ };
251
+
252
+ // * MARK: General utilities
253
+
254
+ const clamp = (value: number, min: number, max: number) => {
255
+ return Math.max(min, Math.min(value, max));
256
+ };
257
+
258
+ const clampRGB = (value: number) => {
259
+ return clamp(value, 0, 255);
260
+ };
261
+
262
+ const clampHue = (value: number) => {
263
+ return clamp(value, 0, 360);
264
+ };
265
+
266
+ const clamp100 = (value: number) => {
267
+ return clamp(value, 0, 100);
268
+ };
269
+
270
+ const clampAlpha = (value: number) => {
271
+ return clamp(+value.toFixed(2), 0, 1);
272
+ };
273
+
274
+ const randomNumber = (min: number, max: number) => {
275
+ return Math.random() * (max - min) + min;
276
+ };
277
+
278
+ const numberToHexString = (c: number): string => {
279
+ c = clampRGB(Math.round(c));
280
+ const hex = c.toString(16).padStart(2, '0');
281
+ return hex;
282
+ };
283
+
284
+ const calculateHueValue = (p: number, q: number, t: number): number => {
285
+ if (t < 0) t += 1;
286
+ if (t > 1) t -= 1;
287
+ if (t < 1 / 6) return p + (q - p) * 6 * t;
288
+ if (t < 1 / 2) return q;
289
+ if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
290
+ return p;
291
+ };
292
+
293
+ /** - Identify the color format of a given `string` or `object` */
294
+ const detectColorFormat = (
295
+ color: SupportedColorFormats
296
+ ): ColorFormats | null => {
297
+ // color int
298
+ if (typeof color === 'number') {
299
+
300
+ if (color >>> 0 === color && color >= 0 && color <= 0xffffffff)
301
+ return 'hex8';
302
+ return null;
303
+ }
304
+
305
+ // color string
306
+ if (typeof color === 'string') {
307
+ color = color.trim().toLowerCase();
308
+ for (const key in COLORS_REGEX) {
309
+ const format = key as ColorFormats;
310
+ const entry = COLORS_REGEX[format];
311
+ if (Array.isArray(entry)) {
312
+ for (let i = 0; i < entry.length; i++) {
313
+ const regex = entry[i];
314
+ if (regex && regex.test(color)) return format;
315
+ }
316
+ continue;
317
+ }
318
+ if (entry.test(color)) return format;
319
+ }
320
+ }
321
+
322
+ // color object
323
+ if (typeof color === 'object') {
324
+ const rgbaKeys = ['r', 'g', 'b', 'a'] as (keyof rgbaT)[];
325
+ const isRgbaOb = rgbaKeys.every(
326
+ (k) =>
327
+ color.hasOwnProperty(k) && typeof (color as rgbaT)[k] === 'number'
328
+ );
329
+ if (isRgbaOb) return 'rgba';
330
+
331
+ const rgbKeys = ['r', 'g', 'b'] as (keyof rgbT)[];
332
+ const isRgbOb = rgbKeys.every(
333
+ (k) => color.hasOwnProperty(k) && typeof (color as rgbT)[k] === 'number'
334
+ );
335
+ if (isRgbOb) return 'rgb';
336
+
337
+ const hslaKeys = ['h', 's', 'l', 'a'] as (keyof hslaT)[];
338
+ const isHslaOb = hslaKeys.every(
339
+ (k) =>
340
+ color.hasOwnProperty(k) && typeof (color as hslaT)[k] === 'number'
341
+ );
342
+ if (isHslaOb) return 'hsla';
343
+
344
+ const hslKeys = ['h', 's', 'l'] as (keyof hslT)[];
345
+ const isHslOb = hslKeys.every(
346
+ (k) => color.hasOwnProperty(k) && typeof (color as hslT)[k] === 'number'
347
+ );
348
+ if (isHslOb) return 'hsl';
349
+
350
+ const hsvaKeys = ['h', 's', 'v', 'a'] as (keyof hsvaT)[];
351
+ const isHsvaOb = hsvaKeys.every(
352
+ (k) =>
353
+ color.hasOwnProperty(k) && typeof (color as hsvaT)[k] === 'number'
354
+ );
355
+ if (isHsvaOb) return 'hsva';
356
+
357
+ const hsvKeys = ['h', 's', 'v'] as (keyof hsvT)[];
358
+ const isHsvOb = hsvKeys.every(
359
+ (k) => color.hasOwnProperty(k) && typeof (color as hsvT)[k] === 'number'
360
+ );
361
+ if (isHsvOb) return 'hsv';
362
+
363
+ const hwbaKeys = ['h', 'w', 'b', 'a'] as (keyof hwbaT)[];
364
+ const isHwbaOb = hwbaKeys.every(
365
+ (k) =>
366
+ color.hasOwnProperty(k) && typeof (color as hwbaT)[k] === 'number'
367
+ );
368
+ if (isHwbaOb) return 'hwba';
369
+
370
+ const hwbKeys = ['h', 'w', 'b'] as (keyof hwbT)[];
371
+ const isHwbOb = hwbKeys.every(
372
+ (k) => color.hasOwnProperty(k) && typeof (color as hwbT)[k] === 'number'
373
+ );
374
+ if (isHwbOb) return 'hwb';
375
+ }
376
+
377
+ return null;
378
+ };
379
+
380
+ // * MARK: RGB
381
+
382
+ /** - Parse `RGB` or `RGBA` color string to an `object` */
383
+ const RGB_string_to_object = (color: string): rgbaT => {
384
+ color = color.trim().toLowerCase();
385
+ const colorType = detectColorFormat(color);
386
+
387
+ if (!colorType || !colorType.includes('rgb')) {
388
+ console.error(
389
+ '[colorKit.getRgbObject] is unable to parse the string into an `RGB` object. As a result, the color "black" will be returned instead.'
390
+ );
391
+ return { r: 0, g: 0, b: 0, a: 1 };
392
+ }
393
+
394
+ let matches: RegExpMatchArray | null = null;
395
+ const entry = COLORS_REGEX[colorType];
396
+ if (Array.isArray(entry)) {
397
+ for (let i = 0; i < entry.length; i++) {
398
+ const regex = entry[i];
399
+ if (regex && regex.test(color)) {
400
+ matches = color.match(regex);
401
+ }
402
+ }
403
+ } else {
404
+ matches = color.match(entry);
405
+ }
406
+
407
+ if (!matches || matches.length < 4) {
408
+ console.error(
409
+ '[colorKit.getRgbObject] An error occurred while attempting to destructuring `RGB` values from the given string. As a result, the color "black" will be returned instead.'
410
+ );
411
+ return { r: 0, g: 0, b: 0, a: 1 };
412
+ }
413
+
414
+ const r = parseInt(matches[1] || '0', 10),
415
+ g = parseInt(matches[2] || '0', 10),
416
+ b = parseInt(matches[3] || '0', 10),
417
+ a = parseFloat(matches[4] ?? '1');
418
+
419
+ return {
420
+ r: clampRGB(r),
421
+ g: clampRGB(g),
422
+ b: clampRGB(b),
423
+ a: clampAlpha(a),
424
+ };
425
+ };
426
+
427
+ /** - Ensure that the `RGB` object values are within the correct range and that it has the alpha channel */
428
+ const normalize_RGB_object = (color: rgbaT | rgbT): rgbaT => {
429
+ return {
430
+ r: clampRGB(color.r),
431
+ g: clampRGB(color.g),
432
+ b: clampRGB(color.b),
433
+ a: clampAlpha((color as rgbaT).a ?? 1),
434
+ };
435
+ };
436
+
437
+ /** - Convert an `RGB` or `RGBA` color to its corresponding `Hex` color */
438
+ const RGB_to_HEX = (color: string | rgbaT | rgbT): string => {
439
+ const { r, g, b, a } =
440
+ typeof color === 'string'
441
+ ? RGB_string_to_object(color)
442
+ : normalize_RGB_object(color);
443
+
444
+ const red = numberToHexString(r),
445
+ green = numberToHexString(g),
446
+ blue = numberToHexString(b),
447
+ alpha = a === 1 ? '' : numberToHexString(a * 255);
448
+
449
+ return `#${red + green + blue + alpha}`;
450
+ };
451
+
452
+ /** - Convert `RGB` or `RGBA` color to an `RGBA` object representation */
453
+ const RGB_to_RGB = (color: string | rgbaT | rgbT): rgbaT => {
454
+ return typeof color === 'string'
455
+ ? RGB_string_to_object(color)
456
+ : normalize_RGB_object(color);
457
+ };
458
+
459
+ /** - Convert an `RGB` or `RGBA` color to an `HSLA` object representation */
460
+ const RGB_to_HSLA = (color: string | rgbaT | rgbT): hslaT => {
461
+ const rgb =
462
+ typeof color === 'string'
463
+ ? RGB_string_to_object(color)
464
+ : normalize_RGB_object(color),
465
+ r = rgb.r / 255,
466
+ g = rgb.g / 255,
467
+ b = rgb.b / 255,
468
+ a = rgb.a;
469
+
470
+ const max = Math.max(r, g, b),
471
+ min = Math.min(r, g, b);
472
+
473
+ let h = 0,
474
+ s,
475
+ l = (max + min) / 2;
476
+
477
+ if (max === min) {
478
+ h = s = 0;
479
+ } else {
480
+ const d = max - min;
481
+ s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
482
+
483
+ if (max === r) {
484
+ h = (g - b) / d + (g < b ? 6 : 0);
485
+ } else if (max === g) {
486
+ h = (b - r) / d + 2;
487
+ } else if (max === b) {
488
+ h = (r - g) / d + 4;
489
+ }
490
+
491
+ h /= 6;
492
+ }
493
+
494
+ h = clampHue(h * 360);
495
+ s = clamp100(s * 100);
496
+ l = clamp100(l * 100);
497
+
498
+ return { h, s, l, a: clampAlpha(a) };
499
+ };
500
+
501
+ /** - Convert `RGB` or `RGBA` color to an `HSVA` object representation */
502
+ const RGB_to_HSVA = (color: string | rgbaT | rgbT): hsvaT => {
503
+ const rgb =
504
+ typeof color === 'string'
505
+ ? RGB_string_to_object(color)
506
+ : normalize_RGB_object(color),
507
+ r = rgb.r / 255,
508
+ g = rgb.g / 255,
509
+ b = rgb.b / 255,
510
+ a = rgb.a;
511
+
512
+ const max = Math.max(r, g, b),
513
+ min = Math.min(r, g, b),
514
+ d = max - min,
515
+ v = max,
516
+ s = max === 0 ? 0 : d / max;
517
+
518
+ let h = 0;
519
+
520
+ if (max === min) {
521
+ h = 0;
522
+ } else {
523
+ if (max === r) {
524
+ h = (g - b) / d + (g < b ? 6 : 0);
525
+ } else if (max === g) {
526
+ h = (b - r) / d + 2;
527
+ } else if (max === b) {
528
+ h = (r - g) / d + 4;
529
+ }
530
+
531
+ h = h / 6;
532
+ }
533
+
534
+ return {
535
+ h: clampHue(h * 360),
536
+ s: clamp100(s * 100),
537
+ v: clamp100(v * 100),
538
+ a: clampAlpha(a),
539
+ };
540
+ };
541
+
542
+ /** - Convert `RGB` or `RGBA` color to an `HWBA` object representation */
543
+ const RGB_to_HWBA = (color: string | rgbaT | rgbT): hwbaT => {
544
+ const rgb =
545
+ typeof color === 'string'
546
+ ? RGB_string_to_object(color)
547
+ : normalize_RGB_object(color),
548
+ red = rgb.r / 255,
549
+ green = rgb.g / 255,
550
+ blue = rgb.b / 255,
551
+ a = rgb.a;
552
+
553
+ const { h } = RGB_to_HSLA(color);
554
+
555
+ const white = Math.min(red, green, blue) * 100;
556
+ const black = (1 - Math.max(red, green, blue)) * 100;
557
+
558
+ return {
559
+ h: clampHue(h),
560
+ w: clamp100(white),
561
+ b: clamp100(black),
562
+ a: clampAlpha(a),
563
+ };
564
+ };
565
+
566
+ /** - Return the `RGB` color as a string, an array, or an object */
567
+ const RGB_types = ({ r, g, b, a }: rgbaT): ColorTypes<rgbaT> => {
568
+ return {
569
+ string: (forceAlpha?: boolean) => {
570
+ r = Math.round(r);
571
+ g = Math.round(g);
572
+ b = Math.round(b);
573
+
574
+ // auto
575
+ if (typeof forceAlpha === 'undefined') {
576
+ if (typeof a === 'number' && a !== 1)
577
+ return `rgba(${r}, ${g}, ${b}, ${a})`;
578
+ return `rgb(${r}, ${g}, ${b})`;
579
+ }
580
+
581
+ if (forceAlpha) return `rgba(${r}, ${g}, ${b}, ${a ?? 1})`;
582
+
583
+ return `rgb(${r}, ${g}, ${b})`;
584
+ },
585
+ array: (roundValues = true) => {
586
+ if (roundValues) {
587
+ r = Math.round(r);
588
+ g = Math.round(g);
589
+ b = Math.round(b);
590
+ }
591
+ return [r, g, b, a];
592
+ },
593
+ object: (roundValues = true) => {
594
+ if (roundValues) {
595
+ r = Math.round(r);
596
+ g = Math.round(g);
597
+ b = Math.round(b);
598
+ }
599
+ return { r, g, b, a };
600
+ },
601
+ };
602
+ };
603
+
604
+ // * MARK: HSL
605
+
606
+ /** - Parse `HSL` or `HSLA` color string to an `object` */
607
+ const HSL_string_to_object = (color: string): hslaT => {
608
+ color = color.trim().toLowerCase();
609
+ const colorType = detectColorFormat(color);
610
+
611
+ if (!colorType || !colorType.includes('hsl')) {
612
+ console.error(
613
+ '[colorKit.getHslObject] is unable to parse the string into an `HSL` object. As a result, the color "black" will be returned instead.'
614
+ );
615
+ return { h: 0, s: 0, l: 0, a: 1 };
616
+ }
617
+
618
+ let matches: RegExpMatchArray | null = null;
619
+ const entry = COLORS_REGEX[colorType as 'hsl' | 'hsla'];
620
+ if (Array.isArray(entry)) {
621
+ for (let i = 0; i < entry.length; i++) {
622
+ const regex = entry[i];
623
+ if (regex && regex.test(color)) {
624
+ matches = color.match(regex);
625
+ }
626
+ }
627
+ } else {
628
+ matches = color.match(entry);
629
+ }
630
+
631
+ if (!matches || matches.length < 3) {
632
+ console.error(
633
+ '[colorKit.getHslObject] An error occurred while attempting to destructuring `HSL` values from the given string. As a result, the color "black" will be returned instead.'
634
+ );
635
+ return { h: 0, s: 0, l: 0, a: 1 };
636
+ }
637
+
638
+ const h = parseInt(matches[1] || '0', 10),
639
+ s = parseInt(matches[2] || '0', 10),
640
+ l = parseInt(matches[3] || '0', 10),
641
+ a = parseFloat(matches[4] ?? '1');
642
+
643
+ return {
644
+ h: clampHue(h),
645
+ s: clamp100(s),
646
+ l: clamp100(l),
647
+ a: clampAlpha(a),
648
+ };
649
+ };
650
+
651
+ /** - Ensure that the `HSL` object values are within the correct range and that it has the alpha channel */
652
+ const normalize_HSL_object = (color: hslaT | hslT): hslaT => {
653
+ return {
654
+ h: clampHue(color.h),
655
+ s: clamp100(color.s),
656
+ l: clamp100(color.l),
657
+ a: clampAlpha((color as hslaT).a ?? 1),
658
+ };
659
+ };
660
+
661
+ /** - Convert `HSL` or `HSLA` color to an `RGBA` object representation */
662
+ const HSL_to_RGBA = (color: string | hslaT | hslT): rgbaT => {
663
+ const hsla =
664
+ typeof color === 'string'
665
+ ? HSL_string_to_object(color)
666
+ : normalize_HSL_object(color);
667
+
668
+ const h = hsla.h / 360,
669
+ s = hsla.s / 100,
670
+ l = hsla.l / 100,
671
+ a = hsla.a;
672
+
673
+ const q = l < 0.5 ? l * (1 + s) : l + s - l * s,
674
+ p = 2 * l - q;
675
+
676
+ const r = calculateHueValue(p, q, h + 1 / 3),
677
+ g = calculateHueValue(p, q, h),
678
+ b = calculateHueValue(p, q, h - 1 / 3);
679
+
680
+ return {
681
+ r: clampRGB(r * 255),
682
+ g: clampRGB(g * 255),
683
+ b: clampRGB(b * 255),
684
+ a: clampAlpha(a),
685
+ };
686
+ };
687
+
688
+ /** - Convert `HSL` or `HSLA` color to `HEX` color */
689
+ const HSL_to_HEX = (color: string | hslaT | hslT): string => {
690
+ const hsla =
691
+ typeof color === 'string'
692
+ ? HSL_string_to_object(color)
693
+ : normalize_HSL_object(color);
694
+ const rgb = HSL_to_RGBA(hsla);
695
+
696
+ const r = numberToHexString(rgb.r),
697
+ g = numberToHexString(rgb.g),
698
+ b = numberToHexString(rgb.b),
699
+ a = rgb.a === 1 ? '' : numberToHexString(rgb.a * 255);
700
+
701
+ return `#${r + g + b + a}`;
702
+ };
703
+
704
+ /** - Convert `HSL` or `HSLA` color to an `HSVA` object representation */
705
+ const HSL_to_HSVA = (color: string | hslaT | hslT): hsvaT => {
706
+ const hsla =
707
+ typeof color === 'string'
708
+ ? HSL_string_to_object(color)
709
+ : normalize_HSL_object(color);
710
+ const h = hsla.h;
711
+
712
+ const s = hsla.s / 100,
713
+ l = hsla.l / 100,
714
+ a = (hsla as hslaT).a ?? 1,
715
+ v = l + s * Math.min(l, 1 - l),
716
+ sNew = v === 0 ? 0 : 2 - (2 * l) / v;
717
+
718
+ return {
719
+ h: clampHue(h),
720
+ s: clamp100(sNew * 100),
721
+ v: clamp100(v * 100),
722
+ a: clampAlpha(a),
723
+ };
724
+ };
725
+
726
+ /** - Convert `HSL` or `HSLA` color to an `HWBA` object representation */
727
+ const HSL_to_HWBA = (color: string | hslaT | hslT): hwbaT => {
728
+ const hsva = HSL_to_HSVA(color);
729
+ return HSV_to_HWBA(hsva);
730
+ };
731
+
732
+ /** - Convert `HSL` or `HSLA` color to an `HSLA` object representation */
733
+ const HSL_to_HSL = (color: string | hslaT | hslT): hslaT => {
734
+ return typeof color === 'string'
735
+ ? HSL_string_to_object(color)
736
+ : normalize_HSL_object(color);
737
+ };
738
+
739
+ /** - Return the `HSL` color as a string, an array, or an object */
740
+ const HSL_types = ({ h, s, l, a }: hslaT): ColorTypes<hslaT> => {
741
+ return {
742
+ string: (forceAlpha?: boolean) => {
743
+ h = Math.round(h);
744
+ s = Math.round(s);
745
+ l = Math.round(l);
746
+
747
+ // auto
748
+ if (typeof forceAlpha === 'undefined') {
749
+ if (typeof a === 'number' && a !== 1)
750
+ return `hsla(${h}, ${s}%, ${l}%, ${a})`;
751
+ return `hsl(${h}, ${s}%, ${l}%)`;
752
+ }
753
+
754
+ if (forceAlpha) return `hsla(${h}, ${s}%, ${l}%, ${a ?? 1})`;
755
+
756
+ return `hsl(${h}, ${s}%, ${l}%)`;
757
+ },
758
+ array: (roundValues = true) => {
759
+ if (roundValues) {
760
+ h = Math.round(h);
761
+ s = Math.round(s);
762
+ l = Math.round(l);
763
+ }
764
+ return [h, s, l, a];
765
+ },
766
+ object: (roundValues = true) => {
767
+ if (roundValues) {
768
+ h = Math.round(h);
769
+ s = Math.round(s);
770
+ l = Math.round(l);
771
+ }
772
+ return { h, s, l, a };
773
+ },
774
+ };
775
+ };
776
+
777
+ // * MARK: HWB
778
+
779
+ /** - Parse `HWB` or `HWBA` color strong to an `object` */
780
+ const HWB_string_to_object = (color: string): hwbaT => {
781
+ color = color.trim().toLowerCase();
782
+ const colorType = detectColorFormat(color);
783
+
784
+ if (!colorType || !colorType.includes('hwb')) {
785
+ console.error(
786
+ '[colorKit.getHwbObject] is unable to parse the string into an `HWB` object. As a result, the color "black" will be returned instead.'
787
+ );
788
+ return { h: 0, w: 0, b: 0, a: 1 };
789
+ }
790
+
791
+ let matches: RegExpMatchArray | null = null;
792
+ const entry = COLORS_REGEX[colorType as 'hwb' | 'hwba'];
793
+ if (Array.isArray(entry)) {
794
+ for (let i = 0; i < entry.length; i++) {
795
+ const regex = entry[i];
796
+ if (regex && regex.test(color)) {
797
+ matches = color.match(regex);
798
+ }
799
+ }
800
+ } else {
801
+ matches = color.match(entry);
802
+ }
803
+
804
+ if (!matches || matches.length < 4) {
805
+ console.error(
806
+ '[colorKit.getHwbObject] An error occurred while attempting to destructuring `HWB` values from the given string. As a result, the color "black" will be returned instead.'
807
+ );
808
+ return { h: 0, w: 0, b: 0, a: 1 };
809
+ }
810
+
811
+ const h = parseInt(matches[1] || '0', 10),
812
+ w = parseInt(matches[2] || '0', 10),
813
+ b = parseInt(matches[3] || '0', 10),
814
+ a = parseFloat(matches[4] ?? '1');
815
+
816
+ return {
817
+ h: clampHue(h),
818
+ w: clamp100(w),
819
+ b: clamp100(b),
820
+ a: clampAlpha(a),
821
+ };
822
+ };
823
+
824
+ /** - Ensure that the `HWB` object values are within the correct range and that it has the alpha channel */
825
+ const normalize_HWB_object = (color: hwbaT | hwbT): hwbaT => {
826
+ return {
827
+ h: clampHue(color.h),
828
+ w: clamp100(color.w),
829
+ b: clamp100(color.b),
830
+ a: clampAlpha((color as hwbaT).a ?? 1),
831
+ };
832
+ };
833
+
834
+ /** - Convert `HWB` or `HWBA` color to an `RGBA` object representation */
835
+ const HWB_to_RGBA = (color: hwbaT | hwbT | string): rgbaT => {
836
+ const hwba =
837
+ typeof color === 'string'
838
+ ? HWB_string_to_object(color)
839
+ : normalize_HWB_object(color);
840
+
841
+ const h = hwba.h / 360,
842
+ w = hwba.w / 100,
843
+ b = hwba.b / 100,
844
+ a = hwba.a;
845
+
846
+ if (w + b >= 1) {
847
+ const gray = clampRGB((w * 255) / (w + b));
848
+ return {
849
+ r: gray,
850
+ g: gray,
851
+ b: gray,
852
+ a,
853
+ };
854
+ }
855
+
856
+ const red = calculateHueValue(0, 1, h + 1 / 3) * (1 - w - b) + w,
857
+ green = calculateHueValue(0, 1, h) * (1 - w - b) + w,
858
+ blue = calculateHueValue(0, 1, h - 1 / 3) * (1 - w - b) + w;
859
+
860
+ return {
861
+ r: clampRGB(red * 255),
862
+ g: clampRGB(green * 255),
863
+ b: clampRGB(blue * 255),
864
+ a: clampAlpha(a),
865
+ };
866
+ };
867
+
868
+ /** - Convert `HWB` or `HWBA` color to an `Hex` color */
869
+ const HWB_to_HEX = (color: hwbaT | hwbT | string): string => {
870
+ const rgba = HWB_to_RGBA(color);
871
+ return RGB_to_HEX(rgba);
872
+ };
873
+
874
+ /** - Convert `HWB` or `HWBA` color to an `HSVA` object representation */
875
+ function HWB_to_HSVA(color: hwbaT | hwbT | string): hsvaT {
876
+ const hwba =
877
+ typeof color === 'string'
878
+ ? HWB_string_to_object(color)
879
+ : normalize_HWB_object(color);
880
+
881
+ const h = hwba.h % 360,
882
+ w = hwba.w / 100,
883
+ b = hwba.b / 100,
884
+ a = hwba.a;
885
+
886
+ const v = (1 - b) * 100;
887
+ let s = (1 - w / (v / 100)) * 100;
888
+ s = isNaN(s) ? 0 : s;
889
+
890
+ return {
891
+ h: clampHue(h),
892
+ s: clamp100(s),
893
+ v: clamp100(v),
894
+ a: clampAlpha(a),
895
+ };
896
+ }
897
+
898
+ /** - Convert `HWB` or `HWBA` color to an `HSLA` object representation */
899
+ const HWB_to_HSLA = (color: hwbaT | hwbT | string): hslaT => {
900
+ const hsva = HWB_to_HSVA(color);
901
+ return HSV_to_HSLA(hsva);
902
+ };
903
+
904
+ /** - Convert `HWB` or `HWBA` color to an `HWBA` object representation */
905
+ const HWB_to_HWB = (color: hwbaT | hwbT | string): hwbaT => {
906
+ return typeof color === 'string'
907
+ ? HWB_string_to_object(color)
908
+ : normalize_HWB_object(color);
909
+ };
910
+
911
+ /** - Return the `HWB` color as a string, an array, or an object */
912
+ const HWB_types = ({ h, w, b, a }: hwbaT): ColorTypes<hwbaT> => {
913
+ return {
914
+ string: (forceAlpha?: boolean) => {
915
+ h = Math.round(h);
916
+ w = Math.round(w);
917
+ b = Math.round(b);
918
+
919
+ // auto
920
+ if (typeof forceAlpha === 'undefined') {
921
+ if (typeof a === 'number' && a !== 1)
922
+ return `hwb(${h} ${w}% ${b}% / ${a})`;
923
+ return `hwb(${h}, ${w}%, ${b}%)`;
924
+ }
925
+
926
+ if (forceAlpha) return `hwb(${h} ${w}% ${b}% / ${a ?? 1})`;
927
+
928
+ return `hwb(${h} ${w}% ${b}%)`;
929
+ },
930
+ array: (roundValues = true) => {
931
+ if (roundValues) {
932
+ h = Math.round(h);
933
+ w = Math.round(w);
934
+ b = Math.round(b);
935
+ }
936
+ return [h, w, b, a];
937
+ },
938
+ object: (roundValues = true) => {
939
+ if (roundValues) {
940
+ h = Math.round(h);
941
+ w = Math.round(w);
942
+ b = Math.round(b);
943
+ }
944
+ return { h, w, b, a };
945
+ },
946
+ };
947
+ };
948
+
949
+ // * MARK: HSV
950
+
951
+ /** - Parse `HSV` or `HSVA` color string to an `object` */
952
+ const HSV_string_to_object = (color: string): hsvaT => {
953
+ color = color.trim().toLowerCase();
954
+ const colorType = detectColorFormat(color);
955
+
956
+ if (!colorType || !colorType.includes('hsv')) {
957
+ console.error(
958
+ '[colorKit.getHsvObject] is unable to parse the string into an `HSV` object. As a result, the color "black" will be returned instead.'
959
+ );
960
+ return { h: 0, s: 0, v: 0, a: 1 };
961
+ }
962
+
963
+ let matches: RegExpMatchArray | null = null;
964
+ const entry = COLORS_REGEX[colorType as 'hsv' | 'hsva'];
965
+ if (Array.isArray(entry)) {
966
+ for (let i = 0; i < entry.length; i++) {
967
+ const regex = entry[i];
968
+ if (regex && regex.test(color)) {
969
+ matches = color.match(regex);
970
+ }
971
+ }
972
+ } else {
973
+ matches = color.match(entry);
974
+ }
975
+
976
+ if (!matches || matches.length < 4) {
977
+ console.error(
978
+ '[colorKit.getHsvObject] An error occurred while attempting to destructuring `HSV` values from the given string. As a result, the color "black" will be returned instead.'
979
+ );
980
+ return { h: 0, s: 0, v: 0, a: 1 };
981
+ }
982
+
983
+ const h = parseInt(matches[1] || '0', 10),
984
+ s = parseInt(matches[2] || '0', 10),
985
+ v = parseInt(matches[3] || '0', 10),
986
+ a = parseFloat(matches[4] ?? '1');
987
+
988
+ return {
989
+ h: clampHue(h),
990
+ s: clamp100(s),
991
+ v: clamp100(v),
992
+ a: clampAlpha(a),
993
+ };
994
+ };
995
+
996
+ /** - Ensure that the `HSV` object values are within the correct range and that it has the alpha channel */
997
+ const normalize_HSV_object = (color: hsvaT | hsvT): hsvaT => {
998
+ return {
999
+ h: clampHue(color.h),
1000
+ s: clamp100(color.s),
1001
+ v: clamp100(color.v),
1002
+ a: clampAlpha((color as hsvaT).a ?? 1),
1003
+ };
1004
+ };
1005
+
1006
+ /** - Convert `HSV` color to an `RGBA` object representation */
1007
+ const HSV_to_RGBA = (color: hsvaT | hsvT | string): rgbaT => {
1008
+ const hsva =
1009
+ typeof color === 'string'
1010
+ ? HSV_string_to_object(color)
1011
+ : normalize_HSV_object(color);
1012
+
1013
+ const h = hsva.h / 360,
1014
+ s = hsva.s / 100,
1015
+ v = hsva.v / 100,
1016
+ a = hsva.a;
1017
+
1018
+ const i = Math.floor(h * 6),
1019
+ f = h * 6 - i,
1020
+ p = v * (1 - s),
1021
+ q = v * (1 - f * s),
1022
+ t = v * (1 - (1 - f) * s);
1023
+
1024
+ let r = 0,
1025
+ g = 0,
1026
+ b = 0;
1027
+
1028
+ if (i % 6 === 0) {
1029
+ r = v;
1030
+ g = t;
1031
+ b = p;
1032
+ } else if (i % 6 === 1) {
1033
+ r = q;
1034
+ g = v;
1035
+ b = p;
1036
+ } else if (i % 6 === 2) {
1037
+ r = p;
1038
+ g = v;
1039
+ b = t;
1040
+ } else if (i % 6 === 3) {
1041
+ r = p;
1042
+ g = q;
1043
+ b = v;
1044
+ } else if (i % 6 === 4) {
1045
+ r = t;
1046
+ g = p;
1047
+ b = v;
1048
+ } else if (i % 6 === 5) {
1049
+ r = v;
1050
+ g = p;
1051
+ b = q;
1052
+ }
1053
+
1054
+ return {
1055
+ r: clampRGB(r * 255),
1056
+ g: clampRGB(g * 255),
1057
+ b: clampRGB(b * 255),
1058
+ a: clampAlpha(a),
1059
+ };
1060
+ };
1061
+
1062
+ /** - Convert `HSV` color to an `HSLA` object representation */
1063
+ const HSV_to_HSLA = (color: hsvaT | hsvT | string): hslaT => {
1064
+ const hsva =
1065
+ typeof color === 'string'
1066
+ ? HSV_string_to_object(color)
1067
+ : normalize_HSV_object(color);
1068
+
1069
+ const h = hsva.h,
1070
+ s = hsva.s / 100,
1071
+ v = hsva.v / 100,
1072
+ a = hsva.a;
1073
+
1074
+ const l = ((2 - s) * v) / 2,
1075
+ sl = s * v,
1076
+ sln = l !== 0 && l !== 1 ? sl / (l < 0.5 ? l * 2 : 2 - l * 2) : sl;
1077
+
1078
+ return {
1079
+ h: clampHue(h),
1080
+ s: clamp100(sln * 100),
1081
+ l: clamp100(l * 100),
1082
+ a: clampAlpha(a),
1083
+ };
1084
+ };
1085
+
1086
+ /** - Convert `HSV` color to an `Hex` color */
1087
+ const HSV_to_HEX = (color: hsvaT | hsvT | string): string => {
1088
+ const rgba = HSV_to_RGBA(color);
1089
+ const hex = RGB_to_HEX(rgba);
1090
+ return hex;
1091
+ };
1092
+
1093
+ /** - Convert `HSV` color to an `HWBA` object representation */
1094
+ const HSV_to_HWBA = (color: hsvaT | hsvT | string): hwbaT => {
1095
+ const { h, s, v, a } =
1096
+ typeof color === 'string'
1097
+ ? HSV_string_to_object(color)
1098
+ : normalize_HSV_object(color);
1099
+
1100
+ const w = (1 - s / 100) * v,
1101
+ b = (1 - v / 100) * 100;
1102
+
1103
+ return {
1104
+ h: clampHue(h),
1105
+ w: clamp100(w),
1106
+ b: clamp100(b),
1107
+ a: clampAlpha(a),
1108
+ };
1109
+ };
1110
+
1111
+ /** - Convert `HSV` color to an `HSVA` object representation */
1112
+ const HSV_to_HSV = (color: hsvaT | hsvT | string): hsvaT => {
1113
+ return typeof color === 'string'
1114
+ ? HSV_string_to_object(color)
1115
+ : normalize_HSV_object(color);
1116
+ };
1117
+
1118
+ /** - Return the `HSV` color as a string, an array, or an object */
1119
+ const HSV_types = ({ h, s, v, a }: hsvaT): ColorTypes<hsvaT> => {
1120
+ return {
1121
+ string: (forceAlpha?: boolean) => {
1122
+ h = Math.round(h);
1123
+ s = Math.round(s);
1124
+ v = Math.round(v);
1125
+
1126
+ // auto
1127
+ if (typeof forceAlpha === 'undefined') {
1128
+ if (typeof a === 'number' && a !== 1)
1129
+ return `hsva(${h}, ${s}%, ${v}%, ${a})`;
1130
+ return `hsv(${h}, ${s}%, ${v}%)`;
1131
+ }
1132
+
1133
+ if (forceAlpha) return `hsva(${h}, ${s}%, ${v}%, ${a ?? 1})`;
1134
+
1135
+ return `hsv(${h}, ${s}%, ${v}%)`;
1136
+ },
1137
+ array: (roundValues = true) => {
1138
+ if (roundValues) {
1139
+ h = Math.round(h);
1140
+ s = Math.round(s);
1141
+ v = Math.round(v);
1142
+ }
1143
+ return [h, s, v, a];
1144
+ },
1145
+ object: (roundValues = true) => {
1146
+ if (roundValues) {
1147
+ h = Math.round(h);
1148
+ s = Math.round(s);
1149
+ v = Math.round(v);
1150
+ }
1151
+ return { h, s, v, a };
1152
+ },
1153
+ };
1154
+ };
1155
+
1156
+ // * MARK: HEX
1157
+
1158
+ /** - Convert any `HEX` color to 8-digit `HEX` color (#rrggbbaa) */
1159
+ const normalize_HEX = (color: string | number): string => {
1160
+ if (typeof color === 'number') {
1161
+ return '#' + color.toString(16).padStart(8, '0');
1162
+ }
1163
+
1164
+ color = color.trim().toLowerCase();
1165
+ const colorType = detectColorFormat(color);
1166
+
1167
+ if (!colorType || !colorType.includes('hex')) {
1168
+ console.error(
1169
+ '[colorKit.normalizeHexColor] is unable to normalize the `HEX` string provided. As a result, the color "black" will be returned instead.'
1170
+ );
1171
+ return '#000000ff';
1172
+ }
1173
+
1174
+ const hex = color.replace(/^#/, '').split('');
1175
+
1176
+ if (hex.length === 3) return `#${hex.map((x) => x + x).join('')}ff`;
1177
+ if (hex.length === 4) return `#${hex.map((x) => x + x).join('')}`;
1178
+ if (hex.length === 6) return `#${hex.join('')}ff`;
1179
+
1180
+ return color;
1181
+ };
1182
+
1183
+ /** - Convert any `HEX` color to an `RGBA` object representation */
1184
+ const HEX_to_RGBA = (color: string | number): rgbaT => {
1185
+ const hex = normalize_HEX(color);
1186
+
1187
+ let matches: RegExpMatchArray | null = null;
1188
+ const entry = COLORS_REGEX.hex8;
1189
+ if (Array.isArray(entry)) {
1190
+ for (let i = 0; i < entry.length; i++) {
1191
+ const regex = entry[i];
1192
+ if (regex && regex.test(hex)) matches = hex.match(regex);
1193
+ }
1194
+ } else {
1195
+ matches = hex.match(entry);
1196
+ }
1197
+
1198
+ if (!matches || matches.length < 4) {
1199
+ console.error(
1200
+ '[colorKit.HEX_RGBA] An error occurred while attempting to destructuring `HEX` values from the given string. As a result, the color "black" will be returned instead.'
1201
+ );
1202
+ return { r: 0, g: 0, b: 0, a: 1 };
1203
+ }
1204
+
1205
+ const r = parseInt(matches[1] || '0', 16),
1206
+ g = parseInt(matches[2] || '0', 16),
1207
+ b = parseInt(matches[3] || '0', 16),
1208
+ a = parseInt(matches[4] || 'ff', 16) / 255;
1209
+
1210
+ return {
1211
+ r: clampRGB(r),
1212
+ g: clampRGB(g),
1213
+ b: clampRGB(b),
1214
+ a: clampAlpha(a),
1215
+ };
1216
+ };
1217
+
1218
+ /** - Convert any `HEX` color to an `HSVA` object representation */
1219
+ const HEX_to_HSVA = (color: string | number): hsvaT => {
1220
+ const rgb = HEX_to_RGBA(color);
1221
+ const hsva = RGB_to_HSVA(rgb);
1222
+ return hsva;
1223
+ };
1224
+
1225
+ /** - Convert any `HEX` color to an `HSLA` object representation */
1226
+ const HEX_to_HSLA = (color: string): hslaT => {
1227
+ const rgb = HEX_to_RGBA(color);
1228
+ return RGB_to_HSLA(rgb);
1229
+ };
1230
+
1231
+ /** - Convert any `HEX` color to an `HWBA` object representation */
1232
+ const HEX_to_HWBA = (color: string): hwbaT => {
1233
+ const rgba = HEX_to_RGBA(color);
1234
+ return RGB_to_HWBA(rgba);
1235
+ };
1236
+
1237
+ // * MARK: Color conversions
1238
+
1239
+ /** - Convert `HSL`, `HSV`, `HWB`, or `RGB` color to the `HEX` color format. */
1240
+ const HEX = (color: SupportedColorFormats): string => {
1241
+ // named color
1242
+ if (typeof color === 'string') {
1243
+ color = color.trim().toLowerCase();
1244
+
1245
+ if (NAMED_COLORS.hasOwnProperty(color)) {
1246
+ color = NAMED_COLORS[color as keyof typeof NAMED_COLORS] as string;
1247
+ }
1248
+ }
1249
+
1250
+ const colorType = detectColorFormat(color);
1251
+
1252
+ // RGB to HEX
1253
+ if (colorType === 'rgb' || colorType === 'rgba') {
1254
+ return RGB_to_HEX(color as string | rgbT | rgbaT);
1255
+ }
1256
+
1257
+ // HSL to HEX
1258
+ if (colorType === 'hsl' || colorType === 'hsla') {
1259
+ return HSL_to_HEX(color as string | hslaT | hslT);
1260
+ }
1261
+
1262
+ // HSV to HEX
1263
+ if (colorType === 'hsv' || colorType === 'hsva') {
1264
+ return HSV_to_HEX(color as string | hsvaT | hsvT);
1265
+ }
1266
+
1267
+ // HWB to HEX
1268
+ if (colorType === 'hwb' || colorType === 'hwba') {
1269
+ return HWB_to_HEX(color as string | hwbaT | hwbT);
1270
+ }
1271
+
1272
+ // HEX
1273
+ if (colorType?.includes('hex')) {
1274
+ return normalize_HEX(color as string | number);
1275
+ }
1276
+
1277
+ // ! error
1278
+ console.error(
1279
+ '[colorKit.HEX] An error occurred while attempting to convert the provided parameter into an `HEX` color. As a result, the default color "black" will be used instead.'
1280
+ );
1281
+
1282
+ return '#000000';
1283
+ };
1284
+
1285
+ /** - Convert `HSL`, `HSV`, `HWB`, or `HEX` color to the `RGB` color format. */
1286
+ const RGB = (color: SupportedColorFormats): ColorTypes<rgbaT> => {
1287
+ // named color
1288
+ if (typeof color === 'string') {
1289
+ color = color.trim().toLowerCase();
1290
+
1291
+ if (NAMED_COLORS.hasOwnProperty(color)) {
1292
+ color = NAMED_COLORS[color as keyof typeof NAMED_COLORS] as string;
1293
+ }
1294
+ }
1295
+
1296
+ const colorType = detectColorFormat(color);
1297
+
1298
+ // HEX to RGB
1299
+ if (colorType?.includes('hex')) {
1300
+ const rgb = HEX_to_RGBA(color as string | number);
1301
+ return RGB_types(rgb);
1302
+ }
1303
+
1304
+ // HSL to RGB
1305
+ if (colorType === 'hsl' || colorType === 'hsla') {
1306
+ const rgb = HSL_to_RGBA(color as string | hslaT | hslT);
1307
+ return RGB_types(rgb);
1308
+ }
1309
+
1310
+ // HSV to RGB
1311
+ if (colorType === 'hsv' || colorType === 'hsva') {
1312
+ const rgb = HSV_to_RGBA(color as string | hsvaT | hsvT);
1313
+ return RGB_types(rgb);
1314
+ }
1315
+
1316
+ // HWB to RGB
1317
+ if (colorType === 'hwb' || colorType === 'hwba') {
1318
+ const rgb = HWB_to_RGBA(color as string | hwbaT | hwbT);
1319
+ return RGB_types(rgb);
1320
+ }
1321
+
1322
+ // RGB to normalized RGB
1323
+ if (colorType === 'rgb' || colorType === 'rgba') {
1324
+ const rgba = RGB_to_RGB(color as string | rgbaT | rgbT);
1325
+ return RGB_types(rgba);
1326
+ }
1327
+
1328
+ // ! error
1329
+ console.error(
1330
+ '[colorKit.RGB] An error occurred while attempting to convert the provided parameter into an `RGB` color. As a result, the default color "black" will be used instead.'
1331
+ );
1332
+
1333
+ return RGB_types({ r: 0, g: 0, b: 0, a: 1 });
1334
+ };
1335
+
1336
+ /** - Convert `HEX`, `HSV`, `HWB`, or `RGB` color to the `HSL` color format. */
1337
+ const HSL = (color: SupportedColorFormats): ColorTypes<hslaT> => {
1338
+ // named color
1339
+ if (typeof color === 'string') {
1340
+ color = color.trim().toLowerCase();
1341
+
1342
+ if (NAMED_COLORS.hasOwnProperty(color)) {
1343
+ color = NAMED_COLORS[color as keyof typeof NAMED_COLORS] as string;
1344
+ }
1345
+ }
1346
+
1347
+ const colorType = detectColorFormat(color);
1348
+
1349
+ // HEX to HSL
1350
+ if (colorType?.includes('hex')) {
1351
+ const hsla = HEX_to_HSLA(color as string);
1352
+ return HSL_types(hsla);
1353
+ }
1354
+
1355
+ // RGB to HSL
1356
+ if (colorType === 'rgb' || colorType === 'rgba') {
1357
+ const hsla = RGB_to_HSLA(color as string | rgbaT | rgbT);
1358
+ return HSL_types(hsla);
1359
+ }
1360
+
1361
+ // HSV to HSL
1362
+ if (colorType === 'hsv' || colorType === 'hsva') {
1363
+ const hsla = HSV_to_HSLA(color as string | hsvaT | hsvT);
1364
+ return HSL_types(hsla);
1365
+ }
1366
+
1367
+ // HWB to HSL
1368
+ if (colorType === 'hwb' || colorType === 'hwba') {
1369
+ const hsla = HWB_to_HSLA(color as string | hwbaT | hwbT);
1370
+ return HSL_types(hsla);
1371
+ }
1372
+
1373
+ // HSL to normalized HSL
1374
+ if (colorType === 'hsl' || colorType === 'hsla') {
1375
+ const hsla = HSL_to_HSL(color as string | hslaT | hslT);
1376
+ return HSL_types(hsla);
1377
+ }
1378
+
1379
+ // ! error
1380
+ console.error(
1381
+ '[colorKit.HSL] An error occurred while attempting to convert the provided parameter into an `HSL` color. As a result, the default color "black" will be used instead.'
1382
+ );
1383
+
1384
+ return HSL_types({ h: 0, s: 0, l: 0, a: 1 });
1385
+ };
1386
+
1387
+ /** - Convert `HSL`, `HEX`, `HSV`, or `RGB` color to the `HWB` color format. */
1388
+ const HWB = (color: SupportedColorFormats): ColorTypes<hwbaT> => {
1389
+ // named color
1390
+ if (typeof color === 'string') {
1391
+ color = color.trim().toLowerCase();
1392
+
1393
+ if (NAMED_COLORS.hasOwnProperty(color)) {
1394
+ color = NAMED_COLORS[color as keyof typeof NAMED_COLORS] as string;
1395
+ }
1396
+ }
1397
+
1398
+ const colorType = detectColorFormat(color);
1399
+
1400
+ // HEX to HWB
1401
+ if (colorType?.includes('hex')) {
1402
+ const hwba = HEX_to_HWBA(color as string);
1403
+ return HWB_types(hwba);
1404
+ }
1405
+
1406
+ // RGB to HWB
1407
+ if (colorType === 'rgb' || colorType === 'rgba') {
1408
+ const hwba = RGB_to_HWBA(color as string | rgbaT | rgbT);
1409
+ return HWB_types(hwba);
1410
+ }
1411
+
1412
+ // HSL to HWB
1413
+ if (colorType === 'hsl' || colorType === 'hsla') {
1414
+ const hwba = HSL_to_HWBA(color as string | hslaT | hslT);
1415
+ return HWB_types(hwba);
1416
+ }
1417
+
1418
+ // HSV to HWB
1419
+ if (colorType === 'hsv' || colorType === 'hsva') {
1420
+ const hwba = HSV_to_HWBA(color as string | hsvaT | hsvT);
1421
+ return HWB_types(hwba);
1422
+ }
1423
+
1424
+ // HWB to normalized HWB
1425
+ if (colorType === 'hwb' || colorType === 'hwba') {
1426
+ const hwba = HWB_to_HWB(color as string | hwbaT | hwbT);
1427
+ return HWB_types(hwba);
1428
+ }
1429
+
1430
+ // ! error
1431
+ console.error(
1432
+ '[colorKit.HWB] An error occurred while attempting to convert the provided parameter into an `HWB` color. As a result, the default color "black" will be used instead.'
1433
+ );
1434
+
1435
+ return HWB_types({ h: 0, w: 0, b: 100, a: 1 });
1436
+ };
1437
+
1438
+ /** - Convert `HSL`, `HEX`, `HWB`, or `RGB` color to the `HSV` color format. */
1439
+ const HSV = (color: SupportedColorFormats): ColorTypes<hsvaT> => {
1440
+ // named color
1441
+ if (typeof color === 'string') {
1442
+ color = color.trim().toLowerCase();
1443
+
1444
+ if (NAMED_COLORS.hasOwnProperty(color)) {
1445
+ color = NAMED_COLORS[color as keyof typeof NAMED_COLORS] as string;
1446
+ }
1447
+ }
1448
+
1449
+ const colorType = detectColorFormat(color);
1450
+
1451
+ // HEX to HSV
1452
+ if (colorType?.includes('hex')) {
1453
+ const hsva = HEX_to_HSVA(color as string);
1454
+ return HSV_types(hsva);
1455
+ }
1456
+
1457
+ // RGB to HSV
1458
+ if (colorType === 'rgb' || colorType === 'rgba') {
1459
+ const hsva = RGB_to_HSVA(color as string | rgbaT | rgbT);
1460
+ return HSV_types(hsva);
1461
+ }
1462
+
1463
+ // HSL to HSV
1464
+ if (colorType === 'hsl' || colorType === 'hsla') {
1465
+ const hsva = HSL_to_HSVA(color as string | hslaT | hslT);
1466
+ return HSV_types(hsva);
1467
+ }
1468
+
1469
+ // HWB to HSV
1470
+ if (colorType === 'hwb' || colorType === 'hwba') {
1471
+ const hsva = HWB_to_HSVA(color as string | hwbaT | hwbT);
1472
+ return HSV_types(hsva);
1473
+ }
1474
+
1475
+ // HSV to normalized HSV
1476
+ if (colorType === 'hsv' || colorType === 'hsva') {
1477
+ const hsva = HSV_to_HSV(color as string | hsvaT | hsvT);
1478
+ return HSV_types(hsva);
1479
+ }
1480
+
1481
+ // ! error
1482
+ console.error(
1483
+ '[colorKit.HSV] An error occurred while attempting to convert the provided parameter into an `HSV` color. As a result, the default color "black" will be used instead.'
1484
+ );
1485
+
1486
+ return HSV_types({ h: 0, s: 0, v: 0, a: 1 });
1487
+ };
1488
+
1489
+ // * MARK: Color Information
1490
+
1491
+ /** - Identify the color format of a given `string` or `object`, and return `null` for invalid colors. */
1492
+ const getFormat = (
1493
+ color: SupportedColorFormats
1494
+ ): ColorFormats | 'named' | null => {
1495
+ // color int
1496
+ if (typeof color === 'number') {
1497
+
1498
+ if (color >>> 0 === color && color >= 0 && color <= 0xffffffff)
1499
+ return 'hex8';
1500
+ return null;
1501
+ }
1502
+
1503
+ // color string
1504
+ if (typeof color === 'string') {
1505
+ color = color.trim().toLowerCase();
1506
+ if (NAMED_COLORS.hasOwnProperty(color)) return 'named';
1507
+
1508
+ for (const key in COLORS_REGEX) {
1509
+ const format = key as ColorFormats;
1510
+ const entry = COLORS_REGEX[format];
1511
+ if (Array.isArray(entry)) {
1512
+ for (let i = 0; i < entry.length; i++) {
1513
+ const regex = entry[i];
1514
+ if (regex && regex.test(color)) return format;
1515
+ }
1516
+ continue;
1517
+ }
1518
+ if (entry.test(color)) return format;
1519
+ }
1520
+ }
1521
+
1522
+ // color object
1523
+ if (typeof color === 'object') {
1524
+ const rgbaKeys = ['r', 'g', 'b', 'a'] as (keyof rgbaT)[];
1525
+ const isRgbaOb = rgbaKeys.every(
1526
+ (k) =>
1527
+ color.hasOwnProperty(k) && typeof (color as rgbaT)[k] === 'number'
1528
+ );
1529
+ if (isRgbaOb) return 'rgba';
1530
+
1531
+ const rgbKeys = ['r', 'g', 'b'] as (keyof rgbT)[];
1532
+ const isRgbOb = rgbKeys.every(
1533
+ (k) => color.hasOwnProperty(k) && typeof (color as rgbT)[k] === 'number'
1534
+ );
1535
+ if (isRgbOb) return 'rgb';
1536
+
1537
+ const hslaKeys = ['h', 's', 'l', 'a'] as (keyof hslaT)[];
1538
+ const isHslaOb = hslaKeys.every(
1539
+ (k) =>
1540
+ color.hasOwnProperty(k) && typeof (color as hslaT)[k] === 'number'
1541
+ );
1542
+ if (isHslaOb) return 'hsla';
1543
+
1544
+ const hslKeys = ['h', 's', 'l'] as (keyof hslT)[];
1545
+ const isHslOb = hslKeys.every(
1546
+ (k) => color.hasOwnProperty(k) && typeof (color as hslT)[k] === 'number'
1547
+ );
1548
+ if (isHslOb) return 'hsl';
1549
+
1550
+ const hsvaKeys = ['h', 's', 'v', 'a'] as (keyof hsvaT)[];
1551
+ const isHsvaOb = hsvaKeys.every(
1552
+ (k) =>
1553
+ color.hasOwnProperty(k) && typeof (color as hsvaT)[k] === 'number'
1554
+ );
1555
+ if (isHsvaOb) return 'hsva';
1556
+
1557
+ const hsvKeys = ['h', 's', 'v'] as (keyof hsvT)[];
1558
+ const isHsvOb = hsvKeys.every(
1559
+ (k) => color.hasOwnProperty(k) && typeof (color as hsvT)[k] === 'number'
1560
+ );
1561
+ if (isHsvOb) return 'hsv';
1562
+
1563
+ const hwbaKeys = ['h', 'w', 'b', 'a'] as (keyof hwbaT)[];
1564
+ const isHwbaOb = hwbaKeys.every(
1565
+ (k) =>
1566
+ color.hasOwnProperty(k) && typeof (color as hwbaT)[k] === 'number'
1567
+ );
1568
+ if (isHwbaOb) return 'hwba';
1569
+
1570
+ const hwbKeys = ['h', 'w', 'b'] as (keyof hwbT)[];
1571
+ const isHwbOb = hwbKeys.every(
1572
+ (k) => color.hasOwnProperty(k) && typeof (color as hwbT)[k] === 'number'
1573
+ );
1574
+ if (isHwbOb) return 'hwb';
1575
+ }
1576
+
1577
+ return null;
1578
+ };
1579
+
1580
+ /** - Get the `red` channel value of a given color. */
1581
+ const getRed = (color: SupportedColorFormats): number => {
1582
+ const { r } = RGB(color).object();
1583
+ return r;
1584
+ };
1585
+
1586
+ /** - Get the `green` channel value of a given color. */
1587
+ const getGreen = (color: SupportedColorFormats): number => {
1588
+ const { g } = RGB(color).object();
1589
+ return g;
1590
+ };
1591
+
1592
+ /** - Get the `blue` channel value of a given color. */
1593
+ const getBlue = (color: SupportedColorFormats): number => {
1594
+ const { b } = RGB(color).object();
1595
+ return b;
1596
+ };
1597
+
1598
+ /** - Get the `hue` channel value of a given color. */
1599
+ const getHue = (color: SupportedColorFormats): number => {
1600
+ const { h } = HSL(color).object();
1601
+ return h;
1602
+ };
1603
+
1604
+ /** - Get the `saturation` value of a given color. */
1605
+ const getSaturation = (color: SupportedColorFormats): number => {
1606
+ const { s } = HSL(color).object();
1607
+ return s;
1608
+ };
1609
+
1610
+ /**
1611
+ * - Get color's HSL `luminosity` channel value.
1612
+ * - If you want the overall `luminosity` of a color use `getLuminanceWCAG` method.
1613
+ */
1614
+ const getLuminance = (color: SupportedColorFormats): number => {
1615
+ const { l } = HSL(color).object();
1616
+ return l;
1617
+ };
1618
+
1619
+ /** - Get the HSV's `value` (brightness) channel value of a given color. */
1620
+ const getBrightness = (color: SupportedColorFormats): number => {
1621
+ const { v } = HSV(color).object();
1622
+ return v;
1623
+ };
1624
+
1625
+ /** - Returns the perceived `luminance` of a color, from `0-1` as defined by Web Content Accessibility Guidelines (Version 2.0). */
1626
+ const getLuminanceWCAG = (color: SupportedColorFormats): number => {
1627
+ const { r, g, b } = RGB(color).object(false);
1628
+ const a = [r, g, b].map((v) =>
1629
+ v / 255 <= 0.03928
1630
+ ? v / 255 / 12.92
1631
+ : Math.pow((v / 255 + 0.055) / 1.055, 2.4)
1632
+ );
1633
+ return (a[0] || 0) * 0.2126 + (a[1] || 0) * 0.7152 + (a[2] || 0) * 0.0722;
1634
+ };
1635
+
1636
+ /** - Returns a boolean indicating whether the color is considered "dark" or not */
1637
+ const isDark = (color: SupportedColorFormats): boolean => {
1638
+ const luminance = getLuminanceWCAG(color);
1639
+ return luminance < 0.5;
1640
+ };
1641
+
1642
+ /** - Returns a boolean indicating whether the color is considered "light" or not */
1643
+ const isLight = (color: SupportedColorFormats): boolean => {
1644
+ const luminance = getLuminanceWCAG(color);
1645
+ return luminance >= 0.5;
1646
+ };
1647
+
1648
+ /**
1649
+ * - Check if two colors are similar within a specified tolerance.
1650
+ *
1651
+ * @example
1652
+ * const tolerance = 0;
1653
+ * const isEqual = colorKit.areColorsEqual('#f00', 'red', tolerance); // true
1654
+ */
1655
+ const areColorsEqual = (
1656
+ color1: SupportedColorFormats,
1657
+ color2: SupportedColorFormats,
1658
+ tolerance = 0
1659
+ ): boolean => {
1660
+ const rgb1 = RGB(color1).object();
1661
+ const rgb2 = RGB(color2).object();
1662
+
1663
+ const deltaR = rgb1.r - rgb2.r;
1664
+ const deltaG = rgb1.g - rgb2.g;
1665
+ const deltaB = rgb1.b - rgb2.b;
1666
+ const difference = Math.sqrt(
1667
+ deltaR * deltaR + deltaG * deltaG + deltaB * deltaB
1668
+ );
1669
+
1670
+ return difference <= tolerance;
1671
+ };
1672
+
1673
+ /** - Calculates the contrast ratio between two colors, useful for ensuring accessibility and readability. */
1674
+ const contrastRatio = (
1675
+ color1: SupportedColorFormats,
1676
+ color2: SupportedColorFormats
1677
+ ): number => {
1678
+ const luminance1 = getLuminanceWCAG(color1);
1679
+ const luminance2 = getLuminanceWCAG(color2);
1680
+ const contrast =
1681
+ (Math.max(luminance1, luminance2) + 0.05) /
1682
+ (Math.min(luminance1, luminance2) + 0.05);
1683
+ return Math.round(contrast * 100) / 100;
1684
+ };
1685
+
1686
+ // * MARK: Color Manipulation
1687
+
1688
+ const returnColorObject = (color: SupportedColorFormats) => {
1689
+ return {
1690
+ hex() {
1691
+ return HEX(color);
1692
+ },
1693
+ rgb() {
1694
+ return RGB(color);
1695
+ },
1696
+ hsl() {
1697
+ return HSL(color);
1698
+ },
1699
+ hsv() {
1700
+ return HSV(color);
1701
+ },
1702
+ hwb() {
1703
+ return HWB(color);
1704
+ },
1705
+ };
1706
+ };
1707
+
1708
+ // * MARK: Red Manuipulation
1709
+ /** Set the `red` value of a color to a specific amount. */
1710
+ const setRed = (
1711
+ color: SupportedColorFormats,
1712
+ amount: number
1713
+ ): ConversionMethods => {
1714
+ const { g, b, a } = RGB(color).object();
1715
+ const newR = clampRGB(amount);
1716
+ const newColor = { r: newR, g, b, a };
1717
+
1718
+ return returnColorObject(newColor);
1719
+ };
1720
+
1721
+ /**
1722
+ * Increase the `red` value of a color by the given percentage/amount.
1723
+ *
1724
+ * @example
1725
+ * increaseRed('rgb(100, 100, 100)', 20).hex();
1726
+ * increaseRed('rgb(100, 100, 100)', '20%').rgb().string();
1727
+ */
1728
+ const increaseRed = (
1729
+ color: SupportedColorFormats,
1730
+ amount: number | string
1731
+ ): ConversionMethods => {
1732
+ const { r, g, b, a } = RGB(color).object();
1733
+ const red =
1734
+ typeof amount === 'string'
1735
+ ? r + r * (parseFloat(amount) / 100)
1736
+ : r + amount;
1737
+ const newR = clampRGB(red);
1738
+ const newColor = { r: newR, g, b, a };
1739
+
1740
+ return returnColorObject(newColor);
1741
+ };
1742
+
1743
+ /**
1744
+ * Decrease the `red` value of a color by the given percentage/amount
1745
+ *
1746
+ * @example
1747
+ * decreaseRed('rgb(100, 100, 100)', 20).hex();
1748
+ * decreaseRed('rgb(100, 100, 100)', '20%').rgb().string();
1749
+ */
1750
+ const decreaseRed = (
1751
+ color: SupportedColorFormats,
1752
+ amount: number | string
1753
+ ): ConversionMethods => {
1754
+ const { r, g, b, a } = RGB(color).object();
1755
+ const red =
1756
+ typeof amount === 'string'
1757
+ ? r - r * (parseFloat(amount) / 100)
1758
+ : r - amount;
1759
+ const newR = clampRGB(red);
1760
+ const newColor = { r: newR, g, b, a };
1761
+
1762
+ return returnColorObject(newColor);
1763
+ };
1764
+
1765
+ // * MARK: Green Manuipulation
1766
+ /** - Set the `green` value of a color to a specific amount. */
1767
+ const setGreen = (
1768
+ color: SupportedColorFormats,
1769
+ amount: number
1770
+ ): ConversionMethods => {
1771
+ const { r, b, a } = RGB(color).object();
1772
+ const newG = clampRGB(amount);
1773
+ const newColor = { r, g: newG, b, a };
1774
+
1775
+ return returnColorObject(newColor);
1776
+ };
1777
+
1778
+ /**
1779
+ * Increase the `green` value of a color by the given percentage.
1780
+ *
1781
+ * @example
1782
+ * increaseGreen('rgb(100, 100, 100)', 20).hex();
1783
+ * increaseGreen('rgb(100, 100, 100)', '20%').rgb().string();
1784
+ */
1785
+ const increaseGreen = (
1786
+ color: SupportedColorFormats,
1787
+ amount: number | string
1788
+ ): ConversionMethods => {
1789
+ const { r, g, b, a } = RGB(color).object();
1790
+ const green =
1791
+ typeof amount === 'string'
1792
+ ? g + g * (parseFloat(amount) / 100)
1793
+ : g + amount;
1794
+ const newG = clampRGB(green);
1795
+ const newColor = { r, g: newG, b, a };
1796
+
1797
+ return returnColorObject(newColor);
1798
+ };
1799
+
1800
+ /**
1801
+ * Decrease the `green` value of a color by the given percentage.
1802
+ *
1803
+ * @example
1804
+ * decreaseGreen('rgb(100, 100, 100)', 20).hex();
1805
+ * decreaseGreen('rgb(100, 100, 100)', '20%').rgb().string();
1806
+ */
1807
+ const decreaseGreen = (
1808
+ color: SupportedColorFormats,
1809
+ amount: number | string
1810
+ ): ConversionMethods => {
1811
+ const { r, g, b, a } = RGB(color).object();
1812
+ const green =
1813
+ typeof amount === 'string'
1814
+ ? g - g * (parseFloat(amount) / 100)
1815
+ : g - amount;
1816
+ const newG = clampRGB(green);
1817
+ const newColor = { r, g: newG, b, a };
1818
+
1819
+ return returnColorObject(newColor);
1820
+ };
1821
+
1822
+ // * MARK: Blue Manuipulation
1823
+ /** - Set the `blue` value of a color to a specific amount. */
1824
+ const setBlue = (
1825
+ color: SupportedColorFormats,
1826
+ amount: number
1827
+ ): ConversionMethods => {
1828
+ const { r, g, a } = RGB(color).object();
1829
+ const newB = clampRGB(amount);
1830
+ const newColor = { r, g, b: newB, a };
1831
+
1832
+ return returnColorObject(newColor);
1833
+ };
1834
+
1835
+ /**
1836
+ * Increase the `blue` value of a color by the given percentage.
1837
+ *
1838
+ * @example
1839
+ * increaseBlue('rgb(100, 100, 100)', 20).hex();
1840
+ * increaseBlue('rgb(100, 100, 100)', '20%').rgb().string();
1841
+ */
1842
+ const increaseBlue = (
1843
+ color: SupportedColorFormats,
1844
+ amount: number | string
1845
+ ): ConversionMethods => {
1846
+ const { r, g, b, a } = RGB(color).object();
1847
+ const blue =
1848
+ typeof amount === 'string'
1849
+ ? b + b * (parseFloat(amount) / 100)
1850
+ : b + amount;
1851
+ const newB = clampRGB(blue);
1852
+ const newColor = { r, g, b: newB, a };
1853
+
1854
+ return returnColorObject(newColor);
1855
+ };
1856
+
1857
+ /**
1858
+ * Decrease the `blue` value of a color by the given percentage.
1859
+ *
1860
+ * @example
1861
+ * decreaseBlue('rgb(100, 100, 100)', 20).hex();
1862
+ * decreaseBlue('rgb(100, 100, 100)', '20%').rgb().string();
1863
+ */
1864
+ const decreaseBlue = (
1865
+ color: SupportedColorFormats,
1866
+ amount: number | string
1867
+ ): ConversionMethods => {
1868
+ const { r, g, b, a } = RGB(color).object();
1869
+ const blue =
1870
+ typeof amount === 'string'
1871
+ ? b - b * (parseFloat(amount) / 100)
1872
+ : b - amount;
1873
+ const newB = clampRGB(blue);
1874
+ const newColor = { r, g, b: newB, a };
1875
+
1876
+ return returnColorObject(newColor);
1877
+ };
1878
+
1879
+ //* MARK: Alpha Manuipulation
1880
+ /** - Get the `alpha` value of a given color. */
1881
+ const getAlpha = (color: SupportedColorFormats): number => {
1882
+ const { a } = RGB(color).object();
1883
+ return a;
1884
+ };
1885
+
1886
+ /** - Set the `alpha` value of a color to a specific amount. */
1887
+ const setAlpha = (
1888
+ color: SupportedColorFormats,
1889
+ amount: number
1890
+ ): ConversionMethods => {
1891
+ const { r, g, b } = RGB(color).object();
1892
+ const newA = clampAlpha(amount);
1893
+ const newColor = { r, g, b, a: newA };
1894
+
1895
+ return returnColorObject(newColor);
1896
+ };
1897
+
1898
+ /** Increase the `alpha` value of a color by the given percentage. */
1899
+ const increaseAlpha = (
1900
+ color: SupportedColorFormats,
1901
+ amount: number | string
1902
+ ): ConversionMethods => {
1903
+ const { r, g, b, a } = RGB(color).object();
1904
+ const alpha =
1905
+ typeof amount === 'string'
1906
+ ? a + a * (parseFloat(amount) / 100)
1907
+ : a + amount;
1908
+ const newA = clampAlpha(alpha);
1909
+ const newColor = { r, g, b, a: newA };
1910
+
1911
+ return returnColorObject(newColor);
1912
+ };
1913
+
1914
+ /** Decrease the `alpha` value of a color by the given percentage. */
1915
+ const decreaseAlpha = (
1916
+ color: SupportedColorFormats,
1917
+ amount: number | string
1918
+ ): ConversionMethods => {
1919
+ const { r, g, b, a } = RGB(color).object();
1920
+ const alpha =
1921
+ typeof amount === 'string'
1922
+ ? a - a * (parseFloat(amount) / 100)
1923
+ : a - amount;
1924
+ const newA = clampAlpha(alpha);
1925
+ const newColor = { r, g, b, a: newA };
1926
+
1927
+ return returnColorObject(newColor);
1928
+ };
1929
+
1930
+ // * MARK: Hue Manuipulation
1931
+ /** - Set the `hue` value of a color to a specific amount. */
1932
+ const setHue = (
1933
+ color: SupportedColorFormats,
1934
+ amount: number
1935
+ ): ConversionMethods => {
1936
+ const { s, l, a } = HSL(color).object();
1937
+ const newH = clampHue(amount);
1938
+ const newColor = { h: newH, s, l, a };
1939
+
1940
+ return returnColorObject(newColor);
1941
+ };
1942
+
1943
+ /**
1944
+ * Increase the `hue` value of a color by the given percentage/amount.
1945
+ *
1946
+ * @example
1947
+ * increaseHue('rgb(100, 100, 100)', 20).hex();
1948
+ * increaseHue('rgb(100, 100, 100)', '20%').rgb().string();
1949
+ */
1950
+ const increaseHue = (
1951
+ color: SupportedColorFormats,
1952
+ amount: number | string
1953
+ ): ConversionMethods => {
1954
+ const { h, s, l, a } = HSL(color).object();
1955
+ const hue =
1956
+ typeof amount === 'string'
1957
+ ? h + h * (parseFloat(amount) / 100)
1958
+ : h + amount;
1959
+ const newH = clampHue(hue);
1960
+ const newColor = { h: newH, s, l, a };
1961
+
1962
+ return returnColorObject(newColor);
1963
+ };
1964
+
1965
+ /**
1966
+ * Decrease the `hue` value of a color by the given percentage/amount.
1967
+ *
1968
+ * @example
1969
+ * decreaseHue('rgb(100, 100, 100)', 20).hex();
1970
+ * decreaseHue('rgb(100, 100, 100)', '20%').rgb().string();
1971
+ */
1972
+ const decreaseHue = (
1973
+ color: SupportedColorFormats,
1974
+ amount: number | string
1975
+ ): ConversionMethods => {
1976
+ const { h, s, l, a } = HSL(color).object();
1977
+ const hue =
1978
+ typeof amount === 'string'
1979
+ ? h - h * (parseFloat(amount) / 100)
1980
+ : h - amount;
1981
+ const newH = clampHue(hue);
1982
+ const newColor = { h: newH, s, l, a };
1983
+
1984
+ return returnColorObject(newColor);
1985
+ };
1986
+
1987
+ /**
1988
+ * - Spin the `hue` channel by a certain percentage/amount.
1989
+ *
1990
+ * @example
1991
+ * spin('red', 20).hex();
1992
+ * spin('rgb(255, 0, 0)', '20%').rgb().string();
1993
+ */
1994
+ const spin = (
1995
+ color: SupportedColorFormats,
1996
+ degree: number | string
1997
+ ): ConversionMethods => {
1998
+ const { h, s, l, a } = HSL(color).object();
1999
+ const spinDegree =
2000
+ typeof degree === 'string' ? s * (parseFloat(degree) / 100) : degree;
2001
+ const newColor = { h: Math.round((h + spinDegree) % 360), s, l, a };
2002
+
2003
+ return returnColorObject(newColor);
2004
+ };
2005
+
2006
+ // * MARK: Saturation Manuipulation
2007
+ /** - Set the `saturation` value of a color to a specific amount. */
2008
+ const setSaturation = (
2009
+ color: SupportedColorFormats,
2010
+ amount: number
2011
+ ): ConversionMethods => {
2012
+ const { h, l, a } = HSL(color).object();
2013
+ const newS = clamp100(amount);
2014
+ const saturatedColor = { h, s: newS, l, a };
2015
+
2016
+ return returnColorObject(saturatedColor);
2017
+ };
2018
+
2019
+ /**
2020
+ * - Increase the saturation of the given color by a certain percentage/amount.
2021
+ *
2022
+ * @example
2023
+ * saturate('red', 20).hex();
2024
+ * saturate('rgb(255, 0, 0)', '20%').rgb().string();
2025
+ */
2026
+ const saturate = (
2027
+ color: SupportedColorFormats,
2028
+ amount: number | string
2029
+ ): ConversionMethods => {
2030
+ const { h, s, l, a } = HSL(color).object();
2031
+ const saturation =
2032
+ typeof amount === 'string'
2033
+ ? s + s * (parseFloat(amount) / 100)
2034
+ : s + amount;
2035
+ const newS = clamp100(saturation);
2036
+ const saturatedColor = { h, s: newS, l, a };
2037
+
2038
+ return returnColorObject(saturatedColor);
2039
+ };
2040
+
2041
+ /**
2042
+ * - Decrease the saturation of the given color by a certain percentage/amount.
2043
+ *
2044
+ * @example
2045
+ * saturate('red', 20).hex();
2046
+ * saturate('rgb(255, 0, 0)', '20%').rgb().string();
2047
+ */
2048
+ const desaturate = (
2049
+ color: SupportedColorFormats,
2050
+ amount: number | string
2051
+ ): ConversionMethods => {
2052
+ const { h, s, l, a } = HSL(color).object();
2053
+ const saturation =
2054
+ typeof amount === 'string'
2055
+ ? s - s * (parseFloat(amount) / 100)
2056
+ : s - amount;
2057
+ const newS = clamp100(saturation);
2058
+ const desaturatedColor = { h, s: newS, l, a };
2059
+
2060
+ return returnColorObject(desaturatedColor);
2061
+ };
2062
+
2063
+ // * MARK: Brightness Manuipulation
2064
+ /** - Set HSL's `luminosity` channel for a given color to a specific amount. */
2065
+ const setLuminance = (
2066
+ color: SupportedColorFormats,
2067
+ amount: number
2068
+ ): ConversionMethods => {
2069
+ const { h, s, a } = HSL(color).object();
2070
+ const newL = clamp100(amount);
2071
+ const newColor = { h, s, l: newL, a };
2072
+
2073
+ return returnColorObject(newColor);
2074
+ };
2075
+
2076
+ /**
2077
+ * - Increase the brightness of the given color by a certain percentage/amount.
2078
+ *
2079
+ * @example
2080
+ * brighten('red', 20).hex();
2081
+ * brighten('rgb(255, 0, 0)', '20%').rgb().string();
2082
+ */
2083
+ const brighten = (
2084
+ color: SupportedColorFormats,
2085
+ amount: number | string
2086
+ ): ConversionMethods => {
2087
+ const { h, s, l, a } = HSL(color).object();
2088
+ const lum =
2089
+ typeof amount === 'string'
2090
+ ? l + l * (parseFloat(amount) / 100)
2091
+ : l + amount;
2092
+ const newL = clamp100(lum);
2093
+ const brightenedColor = { h, s, l: newL, a };
2094
+
2095
+ return returnColorObject(brightenedColor);
2096
+ };
2097
+
2098
+ /**
2099
+ * - Decrease the brightness of the given color by a certain percentage/amount.
2100
+ *
2101
+ * @example
2102
+ * darken('red', 20).hex();
2103
+ * darken('rgb(255, 0, 0)', '20%').rgb().string();
2104
+ */
2105
+ const darken = (
2106
+ color: SupportedColorFormats,
2107
+ amount: number | string
2108
+ ): ConversionMethods => {
2109
+ const { h, s, l, a } = HSL(color).object();
2110
+ const lum =
2111
+ typeof amount === 'string'
2112
+ ? l - l * (parseFloat(amount) / 100)
2113
+ : l - amount;
2114
+ const newL = clamp100(lum);
2115
+ const darkenedColor = { h, s, l: newL, a };
2116
+
2117
+ return returnColorObject(darkenedColor);
2118
+ };
2119
+
2120
+ /** - Set HSV's `value` (brightness) channel for a given color to a specific amount. */
2121
+ const setBrightness = (
2122
+ color: SupportedColorFormats,
2123
+ amount: number
2124
+ ): ConversionMethods => {
2125
+ const { h, s, a } = HSV(color).object();
2126
+ const newV = clamp100(amount);
2127
+ const newColor = { h, s, v: newV, a };
2128
+
2129
+ return returnColorObject(newColor);
2130
+ };
2131
+
2132
+ /** Increase HSV's `value` (brightness) channel value of a color by the given percentage/amount. */
2133
+ const increaseBrightness = (
2134
+ color: SupportedColorFormats,
2135
+ amount: number | string
2136
+ ): ConversionMethods => {
2137
+ const { h, s, v, a } = HSV(color).object();
2138
+ const value =
2139
+ typeof amount === 'string'
2140
+ ? v + v * (parseFloat(amount) / 100)
2141
+ : v + amount;
2142
+ const newV = clamp100(value);
2143
+ const newColor = { h, s, v: newV, a };
2144
+
2145
+ return returnColorObject(newColor);
2146
+ };
2147
+
2148
+ /** Decrease HSV's `value` (brightness) channel value of a color by the given percentage/amount. */
2149
+ const decreaseBrightness = (
2150
+ color: SupportedColorFormats,
2151
+ amount: number | string
2152
+ ): ConversionMethods => {
2153
+ const { h, s, v, a } = HSV(color).object();
2154
+ const value =
2155
+ typeof amount === 'string'
2156
+ ? v - v * (parseFloat(amount) / 100)
2157
+ : v - amount;
2158
+ const newV = clamp100(value);
2159
+ const newColor = { h, s, v: newV, a };
2160
+
2161
+ return returnColorObject(newColor);
2162
+ };
2163
+
2164
+ // * MARK: Color Utilities
2165
+
2166
+ /**
2167
+ * - Blends two colors by a certain amount.
2168
+ *
2169
+ * @example
2170
+ * blend('yellow', 'red', 50).hex(); // #ff8000
2171
+ */
2172
+ const blend = (
2173
+ color1: SupportedColorFormats,
2174
+ color2: SupportedColorFormats,
2175
+ percentage: number
2176
+ ): ConversionMethods => {
2177
+ percentage = percentage / 100;
2178
+
2179
+ const rgba1 = RGB(color1).object();
2180
+ const rgba2 = RGB(color2).object();
2181
+
2182
+ const r = clampRGB(rgba1.r * (1 - percentage) + rgba2.r * percentage),
2183
+ g = clampRGB(rgba1.g * (1 - percentage) + rgba2.g * percentage),
2184
+ b = clampRGB(rgba1.b * (1 - percentage) + rgba2.b * percentage),
2185
+ a = clampAlpha(rgba1.a * (1 - percentage) + rgba2.a * percentage);
2186
+
2187
+ const blendedColor = { r, g, b, a };
2188
+
2189
+ return returnColorObject(blendedColor);
2190
+ };
2191
+
2192
+ /** - Invert (negate) a color, black becomes white, white becomes black, blue becomes orange and so on. */
2193
+ const invert = (color: SupportedColorFormats): ConversionMethods => {
2194
+ const { r, g, b, a } = RGB(color).object();
2195
+ const invertedColor = { r: 255 - r, g: 255 - g, b: 255 - b, a };
2196
+ return returnColorObject(invertedColor);
2197
+ };
2198
+
2199
+ /** - Completely desaturate a color into grayscale. */
2200
+ const grayscale = (color: SupportedColorFormats): ConversionMethods => {
2201
+ const { r, g, b, a } = RGB(color).object();
2202
+ const gray = clampRGB(r * 0.3 + g * 0.59 + b * 0.11);
2203
+ const grayColor = { r: gray, g: gray, b: gray, a };
2204
+
2205
+ return returnColorObject(grayColor);
2206
+ };
2207
+
2208
+ /** - Generate a random color from `HSL` values. */
2209
+ const randomHslColor = ({
2210
+ h = [0, 360],
2211
+ s = [0, 100],
2212
+ l = [0, 100],
2213
+ a = [1, 1],
2214
+ } = {}): ConversionMethods => {
2215
+ const random = {
2216
+ h: clampHue(randomNumber(h[0] ?? 0, h[1] ?? 360)),
2217
+ s: clamp100(randomNumber(s[0] ?? 0, s[1] ?? 100)),
2218
+ l: clamp100(randomNumber(l[0] ?? 0, l[1] ?? 100)),
2219
+ a: clampAlpha(randomNumber(a[0] ?? 1, a[1] ?? 1)),
2220
+ };
2221
+
2222
+ return returnColorObject(random);
2223
+ };
2224
+
2225
+ /** - Generate a random color from `HSV` values. */
2226
+ const randomHsvColor = ({
2227
+ h = [0, 360],
2228
+ s = [0, 100],
2229
+ v = [0, 100],
2230
+ a = [1, 1],
2231
+ } = {}): ConversionMethods => {
2232
+ const random = {
2233
+ h: clampHue(randomNumber(h[0] ?? 0, h[1] ?? 360)),
2234
+ s: clamp100(randomNumber(s[0] ?? 0, s[1] ?? 100)),
2235
+ v: clamp100(randomNumber(v[0] ?? 0, v[1] ?? 100)),
2236
+ a: clampAlpha(randomNumber(a[0] ?? 1, a[1] ?? 1)),
2237
+ };
2238
+
2239
+ return returnColorObject(random);
2240
+ };
2241
+
2242
+ /** - Generate a random color from `RGB` values. */
2243
+ const randomRgbColor = ({
2244
+ r = [0, 255],
2245
+ g = [0, 255],
2246
+ b = [0, 255],
2247
+ a = [1, 1],
2248
+ } = {}): ConversionMethods => {
2249
+ const random = {
2250
+ r: clampRGB(randomNumber(r[0] ?? 0, r[1] ?? 255)),
2251
+ g: clampRGB(randomNumber(g[0] ?? 0, g[1] ?? 255)),
2252
+ b: clampRGB(randomNumber(b[0] ?? 0, b[1] ?? 255)),
2253
+ a: clampAlpha(randomNumber(a[0] ?? 1, a[1] ?? 1)),
2254
+ };
2255
+
2256
+ return returnColorObject(random);
2257
+ };
2258
+
2259
+ /** - Generate a random color from `HWB` values. */
2260
+ const randomHwbColor = ({
2261
+ h = [0, 360],
2262
+ w = [0, 100],
2263
+ b = [0, 100],
2264
+ a = [1, 1],
2265
+ } = {}): ConversionMethods => {
2266
+ const random = {
2267
+ h: clampHue(randomNumber(h[0] ?? 0, h[1] ?? 360)),
2268
+ w: clamp100(randomNumber(w[0] ?? 0, w[1] ?? 100)),
2269
+ b: clamp100(randomNumber(b[0] ?? 0, b[1] ?? 100)),
2270
+ a: clampAlpha(randomNumber(a[0] ?? 1, a[1] ?? 1)),
2271
+ };
2272
+
2273
+ return returnColorObject(random);
2274
+ };
2275
+
2276
+ /** - Returns the first color with the desired contrast ratio against the second color */
2277
+ const adjustContrast = (
2278
+ color1: SupportedColorFormats,
2279
+ color2: SupportedColorFormats,
2280
+ ratio = 4.5
2281
+ ): ConversionMethods => {
2282
+ const contrast = contrastRatio(color1, color2);
2283
+ const color1RGB = RGB(color1).object();
2284
+ const channels = ['r', 'g', 'b'] as const;
2285
+
2286
+ function adjustLuminance(colorRGB: rgbaT, by: number) {
2287
+ const r = clampRGB(colorRGB.r + by);
2288
+ const g = clampRGB(colorRGB.g + by);
2289
+ const b = clampRGB(colorRGB.b + by);
2290
+ return { r, g, b, a: colorRGB.a };
2291
+ }
2292
+
2293
+ let newColor = color1RGB;
2294
+
2295
+ //* increase contrast
2296
+ if (ratio && contrast < ratio) {
2297
+ while (contrastRatio(newColor, color2) < ratio) {
2298
+ const adjustBy = isDark(color2) ? 1 : -1; // increase or decrease relative to the background color
2299
+ newColor = adjustLuminance(newColor, adjustBy);
2300
+
2301
+ // break if the color reached the limit
2302
+ if (channels.every((e) => newColor[e] === 0)) break;
2303
+ if (channels.every((e) => newColor[e] === 255)) break;
2304
+ }
2305
+ //* decrease contrast
2306
+ } else if (ratio && contrast > ratio) {
2307
+ while (contrastRatio(newColor, color2) > ratio) {
2308
+ const adjustBy = !isDark(color2) ? 1 : -1; // increase or decrease relative to the background color
2309
+ newColor = adjustLuminance(newColor, adjustBy);
2310
+
2311
+ // break if the color reached the limit
2312
+ if (channels.every((e) => newColor[e] === 0)) break;
2313
+ if (channels.every((e) => newColor[e] === 255)) break;
2314
+ }
2315
+ }
2316
+
2317
+ return returnColorObject(newColor);
2318
+ };
2319
+
2320
+ return {
2321
+ // color conversion
2322
+ HEX,
2323
+ RGB,
2324
+ HSL,
2325
+ HWB,
2326
+ HSV,
2327
+ // color information
2328
+ getFormat,
2329
+ getRed,
2330
+ getGreen,
2331
+ getBlue,
2332
+ getHue,
2333
+ getSaturation,
2334
+ getBrightness,
2335
+ getLuminance,
2336
+ getLuminanceWCAG,
2337
+ isDark,
2338
+ isLight,
2339
+ areColorsEqual,
2340
+ contrastRatio,
2341
+
2342
+ // color manipulation
2343
+ setRed,
2344
+ increaseRed,
2345
+ decreaseRed,
2346
+
2347
+ setGreen,
2348
+ increaseGreen,
2349
+ decreaseGreen,
2350
+
2351
+ setBlue,
2352
+ increaseBlue,
2353
+ decreaseBlue,
2354
+
2355
+ getAlpha,
2356
+ setAlpha,
2357
+ increaseAlpha,
2358
+ decreaseAlpha,
2359
+
2360
+ setHue,
2361
+ increaseHue,
2362
+ decreaseHue,
2363
+ spin,
2364
+
2365
+ setSaturation,
2366
+ saturate,
2367
+ desaturate,
2368
+
2369
+ setLuminance,
2370
+ brighten,
2371
+ darken,
2372
+ setBrightness,
2373
+ increaseBrightness,
2374
+ decreaseBrightness,
2375
+
2376
+ // color utilities
2377
+ blend,
2378
+ invert,
2379
+ grayscale,
2380
+ randomHslColor,
2381
+ randomHsvColor,
2382
+ randomRgbColor,
2383
+ randomHwbColor,
2384
+ adjustContrast,
2385
+ };
2386
+ };
2387
+
2388
+ type ColorKit = ReturnType<typeof colorKitUI> & {
2389
+ /** - Initiates the asynchronous execution of a workletized colorKit function on the UI thread. */
2390
+ runOnUI: typeof colorKitUI;
2391
+ };
2392
+
2393
+ const colorKit = colorKitUI() as ColorKit;
2394
+ colorKit.runOnUI = colorKitUI;
2395
+ export default colorKit;