@coze-arch/cli 0.0.1-alpha.ef8b63 → 0.0.1-alpha.f0fbc7

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