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