@oxyhq/bloom 0.35.8 → 0.37.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/commonjs/frosted-icon-button/FrostedIconButton.js +148 -0
- package/lib/commonjs/frosted-icon-button/FrostedIconButton.js.map +1 -0
- package/lib/commonjs/frosted-icon-button/FrostedIconButton.web.js +166 -0
- package/lib/commonjs/frosted-icon-button/FrostedIconButton.web.js.map +1 -0
- package/lib/commonjs/frosted-icon-button/index.js +13 -0
- package/lib/commonjs/frosted-icon-button/index.js.map +1 -0
- package/lib/commonjs/frosted-icon-button/index.web.js +13 -0
- package/lib/commonjs/frosted-icon-button/index.web.js.map +1 -0
- package/lib/commonjs/frosted-icon-button/shared.js +112 -0
- package/lib/commonjs/frosted-icon-button/shared.js.map +1 -0
- package/lib/commonjs/frosted-icon-button/types.js +6 -0
- package/lib/commonjs/frosted-icon-button/types.js.map +1 -0
- package/lib/commonjs/index.js +10 -1
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/index.web.js +46 -37
- package/lib/commonjs/index.web.js.map +1 -1
- package/lib/commonjs/theme/build-theme.js +31 -43
- package/lib/commonjs/theme/build-theme.js.map +1 -1
- package/lib/commonjs/theme/color-engine/cam16.js +161 -0
- package/lib/commonjs/theme/color-engine/cam16.js.map +1 -0
- package/lib/commonjs/theme/color-engine/color-role.js +183 -0
- package/lib/commonjs/theme/color-engine/color-role.js.map +1 -0
- package/lib/commonjs/theme/color-engine/color-roles.js +416 -0
- package/lib/commonjs/theme/color-engine/color-roles.js.map +1 -0
- package/lib/commonjs/theme/color-engine/color-utils.js +157 -0
- package/lib/commonjs/theme/color-engine/color-utils.js.map +1 -0
- package/lib/commonjs/theme/color-engine/contrast-curve.js +32 -0
- package/lib/commonjs/theme/color-engine/contrast-curve.js.map +1 -0
- package/lib/commonjs/theme/color-engine/contrast.js +70 -0
- package/lib/commonjs/theme/color-engine/contrast.js.map +1 -0
- package/lib/commonjs/theme/color-engine/dislike-analyzer.js +26 -0
- package/lib/commonjs/theme/color-engine/dislike-analyzer.js.map +1 -0
- package/lib/commonjs/theme/color-engine/dynamic-scheme.js +70 -0
- package/lib/commonjs/theme/color-engine/dynamic-scheme.js.map +1 -0
- package/lib/commonjs/theme/color-engine/hct-solver.js +236 -0
- package/lib/commonjs/theme/color-engine/hct-solver.js.map +1 -0
- package/lib/commonjs/theme/color-engine/hct.js +67 -0
- package/lib/commonjs/theme/color-engine/hct.js.map +1 -0
- package/lib/commonjs/theme/color-engine/index.js +173 -0
- package/lib/commonjs/theme/color-engine/index.js.map +1 -0
- package/lib/commonjs/theme/color-engine/lab-point-provider.js +32 -0
- package/lib/commonjs/theme/color-engine/lab-point-provider.js.map +1 -0
- package/lib/commonjs/theme/color-engine/math-utils.js +77 -0
- package/lib/commonjs/theme/color-engine/math-utils.js.map +1 -0
- package/lib/commonjs/theme/color-engine/quantizer-map.js +24 -0
- package/lib/commonjs/theme/color-engine/quantizer-map.js.map +1 -0
- package/lib/commonjs/theme/color-engine/quantizer-wu.js +266 -0
- package/lib/commonjs/theme/color-engine/quantizer-wu.js.map +1 -0
- package/lib/commonjs/theme/color-engine/scheme-variants.js +102 -0
- package/lib/commonjs/theme/color-engine/scheme-variants.js.map +1 -0
- package/lib/commonjs/theme/color-engine/score.js +80 -0
- package/lib/commonjs/theme/color-engine/score.js.map +1 -0
- package/lib/commonjs/theme/color-engine/seed-from-image.js +73 -0
- package/lib/commonjs/theme/color-engine/seed-from-image.js.map +1 -0
- package/lib/commonjs/theme/color-engine/tonal-palette.js +95 -0
- package/lib/commonjs/theme/color-engine/tonal-palette.js.map +1 -0
- package/lib/commonjs/theme/color-engine/tone-delta-pair.js +26 -0
- package/lib/commonjs/theme/color-engine/tone-delta-pair.js.map +1 -0
- package/lib/commonjs/theme/color-engine/variant.js +26 -0
- package/lib/commonjs/theme/color-engine/variant.js.map +1 -0
- package/lib/commonjs/theme/color-engine/viewing-conditions.js +61 -0
- package/lib/commonjs/theme/color-engine/viewing-conditions.js.map +1 -0
- package/lib/commonjs/theme/color-presets.js +44 -572
- package/lib/commonjs/theme/color-presets.js.map +1 -1
- package/lib/commonjs/theme/preset-vars.js +64 -47
- package/lib/commonjs/theme/preset-vars.js.map +1 -1
- package/lib/module/frosted-icon-button/FrostedIconButton.js +143 -0
- package/lib/module/frosted-icon-button/FrostedIconButton.js.map +1 -0
- package/lib/module/frosted-icon-button/FrostedIconButton.web.js +161 -0
- package/lib/module/frosted-icon-button/FrostedIconButton.web.js.map +1 -0
- package/lib/module/frosted-icon-button/index.js +4 -0
- package/lib/module/frosted-icon-button/index.js.map +1 -0
- package/lib/module/frosted-icon-button/index.web.js +11 -0
- package/lib/module/frosted-icon-button/index.web.js.map +1 -0
- package/lib/module/frosted-icon-button/shared.js +107 -0
- package/lib/module/frosted-icon-button/shared.js.map +1 -0
- package/lib/module/frosted-icon-button/types.js +4 -0
- package/lib/module/frosted-icon-button/types.js.map +1 -0
- package/lib/module/index.js +1 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/index.web.js +1 -0
- package/lib/module/index.web.js.map +1 -1
- package/lib/module/theme/build-theme.js +32 -44
- package/lib/module/theme/build-theme.js.map +1 -1
- package/lib/module/theme/color-engine/cam16.js +155 -0
- package/lib/module/theme/color-engine/cam16.js.map +1 -0
- package/lib/module/theme/color-engine/color-role.js +177 -0
- package/lib/module/theme/color-engine/color-role.js.map +1 -0
- package/lib/module/theme/color-engine/color-roles.js +411 -0
- package/lib/module/theme/color-engine/color-roles.js.map +1 -0
- package/lib/module/theme/color-engine/color-utils.js +135 -0
- package/lib/module/theme/color-engine/color-utils.js.map +1 -0
- package/lib/module/theme/color-engine/contrast-curve.js +26 -0
- package/lib/module/theme/color-engine/contrast-curve.js.map +1 -0
- package/lib/module/theme/color-engine/contrast.js +61 -0
- package/lib/module/theme/color-engine/contrast.js.map +1 -0
- package/lib/module/theme/color-engine/dislike-analyzer.js +20 -0
- package/lib/module/theme/color-engine/dislike-analyzer.js.map +1 -0
- package/lib/module/theme/color-engine/dynamic-scheme.js +65 -0
- package/lib/module/theme/color-engine/dynamic-scheme.js.map +1 -0
- package/lib/module/theme/color-engine/hct-solver.js +231 -0
- package/lib/module/theme/color-engine/hct-solver.js.map +1 -0
- package/lib/module/theme/color-engine/hct.js +61 -0
- package/lib/module/theme/color-engine/hct.js.map +1 -0
- package/lib/module/theme/color-engine/index.js +57 -0
- package/lib/module/theme/color-engine/index.js.map +1 -0
- package/lib/module/theme/color-engine/lab-point-provider.js +25 -0
- package/lib/module/theme/color-engine/lab-point-provider.js.map +1 -0
- package/lib/module/theme/color-engine/math-utils.js +65 -0
- package/lib/module/theme/color-engine/math-utils.js.map +1 -0
- package/lib/module/theme/color-engine/quantizer-map.js +20 -0
- package/lib/module/theme/color-engine/quantizer-map.js.map +1 -0
- package/lib/module/theme/color-engine/quantizer-wu.js +261 -0
- package/lib/module/theme/color-engine/quantizer-wu.js.map +1 -0
- package/lib/module/theme/color-engine/scheme-variants.js +93 -0
- package/lib/module/theme/color-engine/scheme-variants.js.map +1 -0
- package/lib/module/theme/color-engine/score.js +75 -0
- package/lib/module/theme/color-engine/score.js.map +1 -0
- package/lib/module/theme/color-engine/seed-from-image.js +67 -0
- package/lib/module/theme/color-engine/seed-from-image.js.map +1 -0
- package/lib/module/theme/color-engine/tonal-palette.js +89 -0
- package/lib/module/theme/color-engine/tonal-palette.js.map +1 -0
- package/lib/module/theme/color-engine/tone-delta-pair.js +21 -0
- package/lib/module/theme/color-engine/tone-delta-pair.js.map +1 -0
- package/lib/module/theme/color-engine/variant.js +22 -0
- package/lib/module/theme/color-engine/variant.js.map +1 -0
- package/lib/module/theme/color-engine/viewing-conditions.js +55 -0
- package/lib/module/theme/color-engine/viewing-conditions.js.map +1 -0
- package/lib/module/theme/color-presets.js +44 -572
- package/lib/module/theme/color-presets.js.map +1 -1
- package/lib/module/theme/preset-vars.js +64 -46
- package/lib/module/theme/preset-vars.js.map +1 -1
- package/lib/typescript/commonjs/frosted-icon-button/FrostedIconButton.d.ts +5 -0
- package/lib/typescript/commonjs/frosted-icon-button/FrostedIconButton.d.ts.map +1 -0
- package/lib/typescript/commonjs/frosted-icon-button/FrostedIconButton.web.d.ts +5 -0
- package/lib/typescript/commonjs/frosted-icon-button/FrostedIconButton.web.d.ts.map +1 -0
- package/lib/typescript/commonjs/frosted-icon-button/index.d.ts +3 -0
- package/lib/typescript/commonjs/frosted-icon-button/index.d.ts.map +1 -0
- package/lib/typescript/commonjs/frosted-icon-button/index.web.d.ts +3 -0
- package/lib/typescript/commonjs/frosted-icon-button/index.web.d.ts.map +1 -0
- package/lib/typescript/commonjs/frosted-icon-button/shared.d.ts +60 -0
- package/lib/typescript/commonjs/frosted-icon-button/shared.d.ts.map +1 -0
- package/lib/typescript/commonjs/frosted-icon-button/types.d.ts +69 -0
- package/lib/typescript/commonjs/frosted-icon-button/types.d.ts.map +1 -0
- package/lib/typescript/commonjs/index.d.ts +2 -0
- package/lib/typescript/commonjs/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/index.web.d.ts +2 -0
- package/lib/typescript/commonjs/index.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/theme/build-theme.d.ts.map +1 -1
- package/lib/typescript/commonjs/theme/color-engine/cam16.d.ts +26 -0
- package/lib/typescript/commonjs/theme/color-engine/cam16.d.ts.map +1 -0
- package/lib/typescript/commonjs/theme/color-engine/color-role.d.ts +36 -0
- package/lib/typescript/commonjs/theme/color-engine/color-role.d.ts.map +1 -0
- package/lib/typescript/commonjs/theme/color-engine/color-roles.d.ts +58 -0
- package/lib/typescript/commonjs/theme/color-engine/color-roles.d.ts.map +1 -0
- package/lib/typescript/commonjs/theme/color-engine/color-utils.d.ts +32 -0
- package/lib/typescript/commonjs/theme/color-engine/color-utils.d.ts.map +1 -0
- package/lib/typescript/commonjs/theme/color-engine/contrast-curve.d.ts +9 -0
- package/lib/typescript/commonjs/theme/color-engine/contrast-curve.d.ts.map +1 -0
- package/lib/typescript/commonjs/theme/color-engine/contrast.d.ts +12 -0
- package/lib/typescript/commonjs/theme/color-engine/contrast.d.ts.map +1 -0
- package/lib/typescript/commonjs/theme/color-engine/dislike-analyzer.d.ts +11 -0
- package/lib/typescript/commonjs/theme/color-engine/dislike-analyzer.d.ts.map +1 -0
- package/lib/typescript/commonjs/theme/color-engine/dynamic-scheme.d.ts +47 -0
- package/lib/typescript/commonjs/theme/color-engine/dynamic-scheme.d.ts.map +1 -0
- package/lib/typescript/commonjs/theme/color-engine/hct-solver.d.ts +6 -0
- package/lib/typescript/commonjs/theme/color-engine/hct-solver.d.ts.map +1 -0
- package/lib/typescript/commonjs/theme/color-engine/hct.d.ts +20 -0
- package/lib/typescript/commonjs/theme/color-engine/hct.d.ts.map +1 -0
- package/lib/typescript/commonjs/theme/color-engine/index.d.ts +44 -0
- package/lib/typescript/commonjs/theme/color-engine/index.d.ts.map +1 -0
- package/lib/typescript/commonjs/theme/color-engine/lab-point-provider.d.ts +6 -0
- package/lib/typescript/commonjs/theme/color-engine/lab-point-provider.d.ts.map +1 -0
- package/lib/typescript/commonjs/theme/color-engine/math-utils.d.ts +46 -0
- package/lib/typescript/commonjs/theme/color-engine/math-utils.d.ts.map +1 -0
- package/lib/typescript/commonjs/theme/color-engine/quantizer-map.d.ts +3 -0
- package/lib/typescript/commonjs/theme/color-engine/quantizer-map.d.ts.map +1 -0
- package/lib/typescript/commonjs/theme/color-engine/quantizer-wu.d.ts +3 -0
- package/lib/typescript/commonjs/theme/color-engine/quantizer-wu.d.ts.map +1 -0
- package/lib/typescript/commonjs/theme/color-engine/scheme-variants.d.ts +23 -0
- package/lib/typescript/commonjs/theme/color-engine/scheme-variants.d.ts.map +1 -0
- package/lib/typescript/commonjs/theme/color-engine/score.d.ts +8 -0
- package/lib/typescript/commonjs/theme/color-engine/score.d.ts.map +1 -0
- package/lib/typescript/commonjs/theme/color-engine/seed-from-image.d.ts +13 -0
- package/lib/typescript/commonjs/theme/color-engine/seed-from-image.d.ts.map +1 -0
- package/lib/typescript/commonjs/theme/color-engine/tonal-palette.d.ts +24 -0
- package/lib/typescript/commonjs/theme/color-engine/tonal-palette.d.ts.map +1 -0
- package/lib/typescript/commonjs/theme/color-engine/tone-delta-pair.d.ts +19 -0
- package/lib/typescript/commonjs/theme/color-engine/tone-delta-pair.d.ts.map +1 -0
- package/lib/typescript/commonjs/theme/color-engine/variant.d.ts +19 -0
- package/lib/typescript/commonjs/theme/color-engine/variant.d.ts.map +1 -0
- package/lib/typescript/commonjs/theme/color-engine/viewing-conditions.d.ts +18 -0
- package/lib/typescript/commonjs/theme/color-engine/viewing-conditions.d.ts.map +1 -0
- package/lib/typescript/commonjs/theme/color-presets.d.ts +25 -20
- package/lib/typescript/commonjs/theme/color-presets.d.ts.map +1 -1
- package/lib/typescript/commonjs/theme/preset-vars.d.ts +16 -12
- package/lib/typescript/commonjs/theme/preset-vars.d.ts.map +1 -1
- package/lib/typescript/module/frosted-icon-button/FrostedIconButton.d.ts +5 -0
- package/lib/typescript/module/frosted-icon-button/FrostedIconButton.d.ts.map +1 -0
- package/lib/typescript/module/frosted-icon-button/FrostedIconButton.web.d.ts +5 -0
- package/lib/typescript/module/frosted-icon-button/FrostedIconButton.web.d.ts.map +1 -0
- package/lib/typescript/module/frosted-icon-button/index.d.ts +3 -0
- package/lib/typescript/module/frosted-icon-button/index.d.ts.map +1 -0
- package/lib/typescript/module/frosted-icon-button/index.web.d.ts +3 -0
- package/lib/typescript/module/frosted-icon-button/index.web.d.ts.map +1 -0
- package/lib/typescript/module/frosted-icon-button/shared.d.ts +60 -0
- package/lib/typescript/module/frosted-icon-button/shared.d.ts.map +1 -0
- package/lib/typescript/module/frosted-icon-button/types.d.ts +69 -0
- package/lib/typescript/module/frosted-icon-button/types.d.ts.map +1 -0
- package/lib/typescript/module/index.d.ts +2 -0
- package/lib/typescript/module/index.d.ts.map +1 -1
- package/lib/typescript/module/index.web.d.ts +2 -0
- package/lib/typescript/module/index.web.d.ts.map +1 -1
- package/lib/typescript/module/theme/build-theme.d.ts.map +1 -1
- package/lib/typescript/module/theme/color-engine/cam16.d.ts +26 -0
- package/lib/typescript/module/theme/color-engine/cam16.d.ts.map +1 -0
- package/lib/typescript/module/theme/color-engine/color-role.d.ts +36 -0
- package/lib/typescript/module/theme/color-engine/color-role.d.ts.map +1 -0
- package/lib/typescript/module/theme/color-engine/color-roles.d.ts +58 -0
- package/lib/typescript/module/theme/color-engine/color-roles.d.ts.map +1 -0
- package/lib/typescript/module/theme/color-engine/color-utils.d.ts +32 -0
- package/lib/typescript/module/theme/color-engine/color-utils.d.ts.map +1 -0
- package/lib/typescript/module/theme/color-engine/contrast-curve.d.ts +9 -0
- package/lib/typescript/module/theme/color-engine/contrast-curve.d.ts.map +1 -0
- package/lib/typescript/module/theme/color-engine/contrast.d.ts +12 -0
- package/lib/typescript/module/theme/color-engine/contrast.d.ts.map +1 -0
- package/lib/typescript/module/theme/color-engine/dislike-analyzer.d.ts +11 -0
- package/lib/typescript/module/theme/color-engine/dislike-analyzer.d.ts.map +1 -0
- package/lib/typescript/module/theme/color-engine/dynamic-scheme.d.ts +47 -0
- package/lib/typescript/module/theme/color-engine/dynamic-scheme.d.ts.map +1 -0
- package/lib/typescript/module/theme/color-engine/hct-solver.d.ts +6 -0
- package/lib/typescript/module/theme/color-engine/hct-solver.d.ts.map +1 -0
- package/lib/typescript/module/theme/color-engine/hct.d.ts +20 -0
- package/lib/typescript/module/theme/color-engine/hct.d.ts.map +1 -0
- package/lib/typescript/module/theme/color-engine/index.d.ts +44 -0
- package/lib/typescript/module/theme/color-engine/index.d.ts.map +1 -0
- package/lib/typescript/module/theme/color-engine/lab-point-provider.d.ts +6 -0
- package/lib/typescript/module/theme/color-engine/lab-point-provider.d.ts.map +1 -0
- package/lib/typescript/module/theme/color-engine/math-utils.d.ts +46 -0
- package/lib/typescript/module/theme/color-engine/math-utils.d.ts.map +1 -0
- package/lib/typescript/module/theme/color-engine/quantizer-map.d.ts +3 -0
- package/lib/typescript/module/theme/color-engine/quantizer-map.d.ts.map +1 -0
- package/lib/typescript/module/theme/color-engine/quantizer-wu.d.ts +3 -0
- package/lib/typescript/module/theme/color-engine/quantizer-wu.d.ts.map +1 -0
- package/lib/typescript/module/theme/color-engine/scheme-variants.d.ts +23 -0
- package/lib/typescript/module/theme/color-engine/scheme-variants.d.ts.map +1 -0
- package/lib/typescript/module/theme/color-engine/score.d.ts +8 -0
- package/lib/typescript/module/theme/color-engine/score.d.ts.map +1 -0
- package/lib/typescript/module/theme/color-engine/seed-from-image.d.ts +13 -0
- package/lib/typescript/module/theme/color-engine/seed-from-image.d.ts.map +1 -0
- package/lib/typescript/module/theme/color-engine/tonal-palette.d.ts +24 -0
- package/lib/typescript/module/theme/color-engine/tonal-palette.d.ts.map +1 -0
- package/lib/typescript/module/theme/color-engine/tone-delta-pair.d.ts +19 -0
- package/lib/typescript/module/theme/color-engine/tone-delta-pair.d.ts.map +1 -0
- package/lib/typescript/module/theme/color-engine/variant.d.ts +19 -0
- package/lib/typescript/module/theme/color-engine/variant.d.ts.map +1 -0
- package/lib/typescript/module/theme/color-engine/viewing-conditions.d.ts +18 -0
- package/lib/typescript/module/theme/color-engine/viewing-conditions.d.ts.map +1 -0
- package/lib/typescript/module/theme/color-presets.d.ts +25 -20
- package/lib/typescript/module/theme/color-presets.d.ts.map +1 -1
- package/lib/typescript/module/theme/preset-vars.d.ts +16 -12
- package/lib/typescript/module/theme/preset-vars.d.ts.map +1 -1
- package/package.json +17 -1
- package/src/__tests__/BloomThemeProvider.test.tsx +9 -4
- package/src/__tests__/FrostedIconButton.test.tsx +137 -0
- package/src/__tests__/FrostedIconButton.web.test.tsx +246 -0
- package/src/__tests__/native-root-vars.test.ts +8 -4
- package/src/__tests__/preset-vars.test.ts +66 -37
- package/src/__tests__/theme.test.ts +20 -12
- package/src/frosted-icon-button/FrostedIconButton.stories.tsx +65 -0
- package/src/frosted-icon-button/FrostedIconButton.tsx +156 -0
- package/src/frosted-icon-button/FrostedIconButton.web.tsx +207 -0
- package/src/frosted-icon-button/index.ts +2 -0
- package/src/frosted-icon-button/index.web.ts +9 -0
- package/src/frosted-icon-button/shared.ts +118 -0
- package/src/frosted-icon-button/types.ts +81 -0
- package/src/index.ts +2 -0
- package/src/index.web.ts +2 -0
- package/src/theme/__tests__/__fixtures__/golden-resolved-tokens.json +509 -509
- package/src/theme/__tests__/__snapshots__/visual-gallery.test.tsx.snap +613 -613
- package/src/theme/__tests__/color-engine-golden.test.ts +81 -0
- package/src/theme/__tests__/fixtures/color-engine-golden.json +1 -0
- package/src/theme/__tests__/golden-tokens.test.ts +6 -7
- package/src/theme/__tests__/runtime-contract.test.ts +8 -8
- package/src/theme/__tests__/theme-colors-parity.test.ts +44 -88
- package/src/theme/build-theme.ts +32 -44
- package/src/theme/color-engine/cam16.ts +179 -0
- package/src/theme/color-engine/color-role.ts +217 -0
- package/src/theme/color-engine/color-roles.ts +435 -0
- package/src/theme/color-engine/color-utils.ts +157 -0
- package/src/theme/color-engine/contrast-curve.ts +25 -0
- package/src/theme/color-engine/contrast.ts +59 -0
- package/src/theme/color-engine/dislike-analyzer.ts +19 -0
- package/src/theme/color-engine/dynamic-scheme.ts +90 -0
- package/src/theme/color-engine/hct-solver.ts +263 -0
- package/src/theme/color-engine/hct.ts +69 -0
- package/src/theme/color-engine/index.ts +73 -0
- package/src/theme/color-engine/lab-point-provider.ts +26 -0
- package/src/theme/color-engine/math-utils.ts +69 -0
- package/src/theme/color-engine/quantizer-map.ts +17 -0
- package/src/theme/color-engine/quantizer-wu.ts +320 -0
- package/src/theme/color-engine/scheme-variants.ts +113 -0
- package/src/theme/color-engine/score.ts +82 -0
- package/src/theme/color-engine/seed-from-image.ts +64 -0
- package/src/theme/color-engine/tonal-palette.ts +94 -0
- package/src/theme/color-engine/tone-delta-pair.ts +21 -0
- package/src/theme/color-engine/variant.ts +18 -0
- package/src/theme/color-engine/viewing-conditions.ts +77 -0
- package/src/theme/color-presets.ts +54 -631
- package/src/theme/preset-vars.ts +65 -49
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bloom colour engine — CAM16 colour appearance model.
|
|
3
|
+
*
|
|
4
|
+
* Faithful port of Material Color Utilities' `Cam16` (Apache-2.0) into Bloom's
|
|
5
|
+
* own code. A colour is defined by its ARGB AND the viewing conditions; CAM16
|
|
6
|
+
* also exposes CAM16-UCS coordinates (jstar/astar/bstar) for perceptual
|
|
7
|
+
* distance. Underpins the HCT colour space.
|
|
8
|
+
*/
|
|
9
|
+
import { argbFromXyz, linearized } from './color-utils';
|
|
10
|
+
import { signum } from './math-utils';
|
|
11
|
+
import { ViewingConditions } from './viewing-conditions';
|
|
12
|
+
|
|
13
|
+
export class Cam16 {
|
|
14
|
+
constructor(
|
|
15
|
+
readonly hue: number,
|
|
16
|
+
readonly chroma: number,
|
|
17
|
+
readonly j: number,
|
|
18
|
+
readonly q: number,
|
|
19
|
+
readonly m: number,
|
|
20
|
+
readonly s: number,
|
|
21
|
+
readonly jstar: number,
|
|
22
|
+
readonly astar: number,
|
|
23
|
+
readonly bstar: number,
|
|
24
|
+
) {}
|
|
25
|
+
|
|
26
|
+
/** CAM16-UCS perceptual distance to another colour. */
|
|
27
|
+
distance(other: Cam16): number {
|
|
28
|
+
const dJ = this.jstar - other.jstar;
|
|
29
|
+
const dA = this.astar - other.astar;
|
|
30
|
+
const dB = this.bstar - other.bstar;
|
|
31
|
+
const dEPrime = Math.sqrt(dJ * dJ + dA * dA + dB * dB);
|
|
32
|
+
return 1.41 * Math.pow(dEPrime, 0.63);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
static fromInt(argb: number): Cam16 {
|
|
36
|
+
return Cam16.fromIntInViewingConditions(argb, ViewingConditions.DEFAULT);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
static fromIntInViewingConditions(argb: number, vc: ViewingConditions): Cam16 {
|
|
40
|
+
const red = (argb & 0x00ff0000) >> 16;
|
|
41
|
+
const green = (argb & 0x0000ff00) >> 8;
|
|
42
|
+
const blue = argb & 0x000000ff;
|
|
43
|
+
const redL = linearized(red);
|
|
44
|
+
const greenL = linearized(green);
|
|
45
|
+
const blueL = linearized(blue);
|
|
46
|
+
const x = 0.41233895 * redL + 0.35762064 * greenL + 0.18051042 * blueL;
|
|
47
|
+
const y = 0.2126 * redL + 0.7152 * greenL + 0.0722 * blueL;
|
|
48
|
+
const z = 0.01932141 * redL + 0.11916382 * greenL + 0.95034478 * blueL;
|
|
49
|
+
return Cam16.fromXyzInViewingConditions(x, y, z, vc);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
static fromXyzInViewingConditions(
|
|
53
|
+
x: number,
|
|
54
|
+
y: number,
|
|
55
|
+
z: number,
|
|
56
|
+
vc: ViewingConditions,
|
|
57
|
+
): Cam16 {
|
|
58
|
+
const rC = 0.401288 * x + 0.650173 * y - 0.051461 * z;
|
|
59
|
+
const gC = -0.250268 * x + 1.204414 * y + 0.045854 * z;
|
|
60
|
+
const bC = -0.002079 * x + 0.048952 * y + 0.953127 * z;
|
|
61
|
+
const rD = vc.rgbD[0] * rC;
|
|
62
|
+
const gD = vc.rgbD[1] * gC;
|
|
63
|
+
const bD = vc.rgbD[2] * bC;
|
|
64
|
+
const rAF = Math.pow((vc.fl * Math.abs(rD)) / 100.0, 0.42);
|
|
65
|
+
const gAF = Math.pow((vc.fl * Math.abs(gD)) / 100.0, 0.42);
|
|
66
|
+
const bAF = Math.pow((vc.fl * Math.abs(bD)) / 100.0, 0.42);
|
|
67
|
+
const rA = (signum(rD) * 400.0 * rAF) / (rAF + 27.13);
|
|
68
|
+
const gA = (signum(gD) * 400.0 * gAF) / (gAF + 27.13);
|
|
69
|
+
const bA = (signum(bD) * 400.0 * bAF) / (bAF + 27.13);
|
|
70
|
+
const a = (11.0 * rA + -12.0 * gA + bA) / 11.0;
|
|
71
|
+
const b = (rA + gA - 2.0 * bA) / 9.0;
|
|
72
|
+
const u = (20.0 * rA + 20.0 * gA + 21.0 * bA) / 20.0;
|
|
73
|
+
const p2 = (40.0 * rA + 20.0 * gA + bA) / 20.0;
|
|
74
|
+
const atan2 = Math.atan2(b, a);
|
|
75
|
+
const atanDegrees = (atan2 * 180.0) / Math.PI;
|
|
76
|
+
const hue =
|
|
77
|
+
atanDegrees < 0 ? atanDegrees + 360.0 : atanDegrees >= 360 ? atanDegrees - 360 : atanDegrees;
|
|
78
|
+
const hueRadians = (hue * Math.PI) / 180.0;
|
|
79
|
+
const ac = p2 * vc.nbb;
|
|
80
|
+
const J = 100.0 * Math.pow(ac / vc.aw, vc.c * vc.z);
|
|
81
|
+
const Q = (4.0 / vc.c) * Math.sqrt(J / 100.0) * (vc.aw + 4.0) * vc.fLRoot;
|
|
82
|
+
const huePrime = hue < 20.14 ? hue + 360 : hue;
|
|
83
|
+
const eHue = (1.0 / 4.0) * (Math.cos((huePrime * Math.PI) / 180.0 + 2.0) + 3.8);
|
|
84
|
+
const p1 = ((50000.0 / 13.0) * eHue * vc.nc * vc.ncb);
|
|
85
|
+
const t = (p1 * Math.sqrt(a * a + b * b)) / (u + 0.305);
|
|
86
|
+
const alpha = Math.pow(t, 0.9) * Math.pow(1.64 - Math.pow(0.29, vc.n), 0.73);
|
|
87
|
+
const C = alpha * Math.sqrt(J / 100.0);
|
|
88
|
+
const M = C * vc.fLRoot;
|
|
89
|
+
const s = 50.0 * Math.sqrt((alpha * vc.c) / (vc.aw + 4.0));
|
|
90
|
+
const jstar = ((1.0 + 100.0 * 0.007) * J) / (1.0 + 0.007 * J);
|
|
91
|
+
const mstar = Math.log(1.0 + 0.0228 * M) / 0.0228;
|
|
92
|
+
const astar = mstar * Math.cos(hueRadians);
|
|
93
|
+
const bstar = mstar * Math.sin(hueRadians);
|
|
94
|
+
return new Cam16(hue, C, J, Q, M, s, jstar, astar, bstar);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
static fromJch(j: number, c: number, h: number): Cam16 {
|
|
98
|
+
return Cam16.fromJchInViewingConditions(j, c, h, ViewingConditions.DEFAULT);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
static fromJchInViewingConditions(
|
|
102
|
+
j: number,
|
|
103
|
+
c: number,
|
|
104
|
+
h: number,
|
|
105
|
+
vc: ViewingConditions,
|
|
106
|
+
): Cam16 {
|
|
107
|
+
const q = (4.0 / vc.c) * Math.sqrt(j / 100.0) * (vc.aw + 4.0) * vc.fLRoot;
|
|
108
|
+
const m = c * vc.fLRoot;
|
|
109
|
+
const alpha = c / Math.sqrt(j / 100.0);
|
|
110
|
+
const s = 50.0 * Math.sqrt((alpha * vc.c) / (vc.aw + 4.0));
|
|
111
|
+
const hueRadians = (h * Math.PI) / 180.0;
|
|
112
|
+
const jstar = ((1.0 + 100.0 * 0.007) * j) / (1.0 + 0.007 * j);
|
|
113
|
+
const mstar = (1.0 / 0.0228) * Math.log(1.0 + 0.0228 * m);
|
|
114
|
+
const astar = mstar * Math.cos(hueRadians);
|
|
115
|
+
const bstar = mstar * Math.sin(hueRadians);
|
|
116
|
+
return new Cam16(h, c, j, q, m, s, jstar, astar, bstar);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
static fromUcs(jstar: number, astar: number, bstar: number): Cam16 {
|
|
120
|
+
return Cam16.fromUcsInViewingConditions(jstar, astar, bstar, ViewingConditions.DEFAULT);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
static fromUcsInViewingConditions(
|
|
124
|
+
jstar: number,
|
|
125
|
+
astar: number,
|
|
126
|
+
bstar: number,
|
|
127
|
+
vc: ViewingConditions,
|
|
128
|
+
): Cam16 {
|
|
129
|
+
const a = astar;
|
|
130
|
+
const b = bstar;
|
|
131
|
+
const m = Math.sqrt(a * a + b * b);
|
|
132
|
+
const M = (Math.exp(m * 0.0228) - 1.0) / 0.0228;
|
|
133
|
+
const c = M / vc.fLRoot;
|
|
134
|
+
let h = Math.atan2(b, a) * (180.0 / Math.PI);
|
|
135
|
+
if (h < 0.0) h += 360.0;
|
|
136
|
+
const j = jstar / (1 - (jstar - 100) * 0.007);
|
|
137
|
+
return Cam16.fromJchInViewingConditions(j, c, h, vc);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
toInt(): number {
|
|
141
|
+
return this.viewed(ViewingConditions.DEFAULT);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
viewed(vc: ViewingConditions): number {
|
|
145
|
+
const xyz = this.xyzInViewingConditions(vc);
|
|
146
|
+
return argbFromXyz(xyz[0], xyz[1], xyz[2]);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
xyzInViewingConditions(vc: ViewingConditions): [number, number, number] {
|
|
150
|
+
const alpha = this.chroma === 0.0 || this.j === 0.0 ? 0.0 : this.chroma / Math.sqrt(this.j / 100.0);
|
|
151
|
+
const t = Math.pow(alpha / Math.pow(1.64 - Math.pow(0.29, vc.n), 0.73), 1.0 / 0.9);
|
|
152
|
+
const hRad = (this.hue * Math.PI) / 180.0;
|
|
153
|
+
const eHue = 0.25 * (Math.cos(hRad + 2.0) + 3.8);
|
|
154
|
+
const ac = vc.aw * Math.pow(this.j / 100.0, 1.0 / vc.c / vc.z);
|
|
155
|
+
const p1 = eHue * (50000.0 / 13.0) * vc.nc * vc.ncb;
|
|
156
|
+
const p2 = ac / vc.nbb;
|
|
157
|
+
const hSin = Math.sin(hRad);
|
|
158
|
+
const hCos = Math.cos(hRad);
|
|
159
|
+
const gamma = (23.0 * (p2 + 0.305) * t) / (23.0 * p1 + 11.0 * t * hCos + 108.0 * t * hSin);
|
|
160
|
+
const a = gamma * hCos;
|
|
161
|
+
const b = gamma * hSin;
|
|
162
|
+
const rA = (460.0 * p2 + 451.0 * a + 288.0 * b) / 1403.0;
|
|
163
|
+
const gA = (460.0 * p2 - 891.0 * a - 261.0 * b) / 1403.0;
|
|
164
|
+
const bA = (460.0 * p2 - 220.0 * a - 6300.0 * b) / 1403.0;
|
|
165
|
+
const rCBase = Math.max(0, (27.13 * Math.abs(rA)) / (400.0 - Math.abs(rA)));
|
|
166
|
+
const rC = signum(rA) * (100.0 / vc.fl) * Math.pow(rCBase, 1.0 / 0.42);
|
|
167
|
+
const gCBase = Math.max(0, (27.13 * Math.abs(gA)) / (400.0 - Math.abs(gA)));
|
|
168
|
+
const gC = signum(gA) * (100.0 / vc.fl) * Math.pow(gCBase, 1.0 / 0.42);
|
|
169
|
+
const bCBase = Math.max(0, (27.13 * Math.abs(bA)) / (400.0 - Math.abs(bA)));
|
|
170
|
+
const bC = signum(bA) * (100.0 / vc.fl) * Math.pow(bCBase, 1.0 / 0.42);
|
|
171
|
+
const rF = rC / vc.rgbD[0];
|
|
172
|
+
const gF = gC / vc.rgbD[1];
|
|
173
|
+
const bF = bC / vc.rgbD[2];
|
|
174
|
+
const x = 1.86206786 * rF - 1.01125463 * gF + 0.14918677 * bF;
|
|
175
|
+
const y = 0.38752654 * rF + 0.62144744 * gF - 0.00897398 * bF;
|
|
176
|
+
const z = -0.0158415 * rF - 0.03412294 * gF + 1.04996444 * bF;
|
|
177
|
+
return [x, y, z];
|
|
178
|
+
}
|
|
179
|
+
}
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bloom colour engine — a colour role.
|
|
3
|
+
*
|
|
4
|
+
* Faithful port of Material Color Utilities' `DynamicColor` (Apache-2.0),
|
|
5
|
+
* renamed to Bloom's own `ColorRole`. A role is a *recipe*, not a fixed colour:
|
|
6
|
+
* a palette + a base tone + (optionally) a background to contrast against and a
|
|
7
|
+
* paired role to keep tonal distance from. `getArgb(scheme)` resolves the recipe
|
|
8
|
+
* against a scheme's palettes, dark mode and contrast level into a concrete
|
|
9
|
+
* colour — guaranteeing legibility. This is the heart of the system.
|
|
10
|
+
*/
|
|
11
|
+
import { darker, darkerUnsafe, lighter, lighterUnsafe, ratioOfTones } from './contrast';
|
|
12
|
+
import type { ContrastCurve } from './contrast-curve';
|
|
13
|
+
import type { DynamicScheme } from './dynamic-scheme';
|
|
14
|
+
import { Hct } from './hct';
|
|
15
|
+
import { clampDouble } from './math-utils';
|
|
16
|
+
import type { TonalPalette } from './tonal-palette';
|
|
17
|
+
import type { ToneDeltaPair } from './tone-delta-pair';
|
|
18
|
+
|
|
19
|
+
export interface ColorRoleArgs {
|
|
20
|
+
name?: string;
|
|
21
|
+
palette: (scheme: DynamicScheme) => TonalPalette;
|
|
22
|
+
tone: (scheme: DynamicScheme) => number;
|
|
23
|
+
isBackground?: boolean;
|
|
24
|
+
background?: (scheme: DynamicScheme) => ColorRole | undefined;
|
|
25
|
+
secondBackground?: (scheme: DynamicScheme) => ColorRole | undefined;
|
|
26
|
+
contrastCurve?: ContrastCurve;
|
|
27
|
+
toneDeltaPair?: (scheme: DynamicScheme) => ToneDeltaPair;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export class ColorRole {
|
|
31
|
+
readonly name: string;
|
|
32
|
+
readonly palette: (scheme: DynamicScheme) => TonalPalette;
|
|
33
|
+
readonly tone: (scheme: DynamicScheme) => number;
|
|
34
|
+
readonly isBackground: boolean;
|
|
35
|
+
readonly background?: (scheme: DynamicScheme) => ColorRole | undefined;
|
|
36
|
+
readonly secondBackground?: (scheme: DynamicScheme) => ColorRole | undefined;
|
|
37
|
+
readonly contrastCurve?: ContrastCurve;
|
|
38
|
+
readonly toneDeltaPair?: (scheme: DynamicScheme) => ToneDeltaPair;
|
|
39
|
+
private readonly hctCache = new Map<DynamicScheme, Hct>();
|
|
40
|
+
|
|
41
|
+
static fromPalette(args: ColorRoleArgs): ColorRole {
|
|
42
|
+
return new ColorRole(args);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
constructor(args: ColorRoleArgs) {
|
|
46
|
+
this.name = args.name ?? '';
|
|
47
|
+
this.palette = args.palette;
|
|
48
|
+
this.tone = args.tone;
|
|
49
|
+
this.isBackground = args.isBackground ?? false;
|
|
50
|
+
this.background = args.background;
|
|
51
|
+
this.secondBackground = args.secondBackground;
|
|
52
|
+
this.contrastCurve = args.contrastCurve;
|
|
53
|
+
this.toneDeltaPair = args.toneDeltaPair;
|
|
54
|
+
if (!args.background && args.secondBackground) {
|
|
55
|
+
throw new Error(`Color ${this.name} has secondBackground defined, but background is not.`);
|
|
56
|
+
}
|
|
57
|
+
if (!args.background && args.contrastCurve) {
|
|
58
|
+
throw new Error(`Color ${this.name} has contrastCurve defined, but background is not.`);
|
|
59
|
+
}
|
|
60
|
+
if (args.background && !args.contrastCurve) {
|
|
61
|
+
throw new Error(`Color ${this.name} has background defined, but contrastCurve is not.`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
getArgb(scheme: DynamicScheme): number {
|
|
66
|
+
return this.getHct(scheme).toInt();
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
getHct(scheme: DynamicScheme): Hct {
|
|
70
|
+
const cached = this.hctCache.get(scheme);
|
|
71
|
+
if (cached != null) return cached;
|
|
72
|
+
const tone = this.getTone(scheme);
|
|
73
|
+
const answer = this.palette(scheme).getHct(tone);
|
|
74
|
+
if (this.hctCache.size > 4) this.hctCache.clear();
|
|
75
|
+
this.hctCache.set(scheme, answer);
|
|
76
|
+
return answer;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
getTone(scheme: DynamicScheme): number {
|
|
80
|
+
const decreasingContrast = scheme.contrastLevel < 0;
|
|
81
|
+
if (this.toneDeltaPair) {
|
|
82
|
+
const pair = this.toneDeltaPair(scheme);
|
|
83
|
+
const { roleA, roleB, delta, polarity, stayTogether } = pair;
|
|
84
|
+
const bg = this.background!(scheme)!;
|
|
85
|
+
const bgTone = bg.getTone(scheme);
|
|
86
|
+
const aIsNearer =
|
|
87
|
+
polarity === 'nearer' ||
|
|
88
|
+
(polarity === 'lighter' && !scheme.isDark) ||
|
|
89
|
+
(polarity === 'darker' && scheme.isDark);
|
|
90
|
+
const nearer = aIsNearer ? roleA : roleB;
|
|
91
|
+
const farther = aIsNearer ? roleB : roleA;
|
|
92
|
+
const amNearer = this.name === nearer.name;
|
|
93
|
+
const expansionDir = scheme.isDark ? 1 : -1;
|
|
94
|
+
const nContrast = nearer.contrastCurve!.get(scheme.contrastLevel);
|
|
95
|
+
const fContrast = farther.contrastCurve!.get(scheme.contrastLevel);
|
|
96
|
+
const nInitialTone = nearer.tone(scheme);
|
|
97
|
+
let nTone =
|
|
98
|
+
ratioOfTones(bgTone, nInitialTone) >= nContrast
|
|
99
|
+
? nInitialTone
|
|
100
|
+
: ColorRole.foregroundTone(bgTone, nContrast);
|
|
101
|
+
const fInitialTone = farther.tone(scheme);
|
|
102
|
+
let fTone =
|
|
103
|
+
ratioOfTones(bgTone, fInitialTone) >= fContrast
|
|
104
|
+
? fInitialTone
|
|
105
|
+
: ColorRole.foregroundTone(bgTone, fContrast);
|
|
106
|
+
if (decreasingContrast) {
|
|
107
|
+
nTone = ColorRole.foregroundTone(bgTone, nContrast);
|
|
108
|
+
fTone = ColorRole.foregroundTone(bgTone, fContrast);
|
|
109
|
+
}
|
|
110
|
+
if ((fTone - nTone) * expansionDir >= delta) {
|
|
111
|
+
// constraint already satisfied
|
|
112
|
+
} else {
|
|
113
|
+
fTone = clampDouble(0, 100, nTone + delta * expansionDir);
|
|
114
|
+
if ((fTone - nTone) * expansionDir >= delta) {
|
|
115
|
+
// satisfied after expanding farther
|
|
116
|
+
} else {
|
|
117
|
+
nTone = clampDouble(0, 100, fTone - delta * expansionDir);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
if (50 <= nTone && nTone < 60) {
|
|
121
|
+
if (expansionDir > 0) {
|
|
122
|
+
nTone = 60;
|
|
123
|
+
fTone = Math.max(fTone, nTone + delta * expansionDir);
|
|
124
|
+
} else {
|
|
125
|
+
nTone = 49;
|
|
126
|
+
fTone = Math.min(fTone, nTone + delta * expansionDir);
|
|
127
|
+
}
|
|
128
|
+
} else if (50 <= fTone && fTone < 60) {
|
|
129
|
+
if (stayTogether) {
|
|
130
|
+
if (expansionDir > 0) {
|
|
131
|
+
nTone = 60;
|
|
132
|
+
fTone = Math.max(fTone, nTone + delta * expansionDir);
|
|
133
|
+
} else {
|
|
134
|
+
nTone = 49;
|
|
135
|
+
fTone = Math.min(fTone, nTone + delta * expansionDir);
|
|
136
|
+
}
|
|
137
|
+
} else if (expansionDir > 0) {
|
|
138
|
+
fTone = 60;
|
|
139
|
+
} else {
|
|
140
|
+
fTone = 49;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return amNearer ? nTone : fTone;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
let answer = this.tone(scheme);
|
|
147
|
+
if (this.background == null) return answer;
|
|
148
|
+
const bgTone = this.background(scheme)!.getTone(scheme);
|
|
149
|
+
const desiredRatio = this.contrastCurve!.get(scheme.contrastLevel);
|
|
150
|
+
if (ratioOfTones(bgTone, answer) >= desiredRatio) {
|
|
151
|
+
// already contrasts enough
|
|
152
|
+
} else {
|
|
153
|
+
answer = ColorRole.foregroundTone(bgTone, desiredRatio);
|
|
154
|
+
}
|
|
155
|
+
if (decreasingContrast) {
|
|
156
|
+
answer = ColorRole.foregroundTone(bgTone, desiredRatio);
|
|
157
|
+
}
|
|
158
|
+
if (this.isBackground && 50 <= answer && answer < 60) {
|
|
159
|
+
answer = ratioOfTones(49, bgTone) >= desiredRatio ? 49 : 60;
|
|
160
|
+
}
|
|
161
|
+
if (this.secondBackground) {
|
|
162
|
+
const bg1 = this.background;
|
|
163
|
+
const bg2 = this.secondBackground;
|
|
164
|
+
const bgTone1 = bg1(scheme)!.getTone(scheme);
|
|
165
|
+
const bgTone2 = bg2(scheme)!.getTone(scheme);
|
|
166
|
+
const upper = Math.max(bgTone1, bgTone2);
|
|
167
|
+
const lower = Math.min(bgTone1, bgTone2);
|
|
168
|
+
if (ratioOfTones(upper, answer) >= desiredRatio && ratioOfTones(lower, answer) >= desiredRatio) {
|
|
169
|
+
return answer;
|
|
170
|
+
}
|
|
171
|
+
const lightOption = lighter(upper, desiredRatio);
|
|
172
|
+
const darkOption = darker(lower, desiredRatio);
|
|
173
|
+
const availables: number[] = [];
|
|
174
|
+
if (lightOption !== -1) availables.push(lightOption);
|
|
175
|
+
if (darkOption !== -1) availables.push(darkOption);
|
|
176
|
+
const prefersLight =
|
|
177
|
+
ColorRole.tonePrefersLightForeground(bgTone1) ||
|
|
178
|
+
ColorRole.tonePrefersLightForeground(bgTone2);
|
|
179
|
+
if (prefersLight) return lightOption < 0 ? 100 : lightOption;
|
|
180
|
+
const onlyAvailable = availables[0];
|
|
181
|
+
if (availables.length === 1 && onlyAvailable !== undefined) return onlyAvailable;
|
|
182
|
+
return darkOption < 0 ? 0 : darkOption;
|
|
183
|
+
}
|
|
184
|
+
return answer;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
static foregroundTone(bgTone: number, ratio: number): number {
|
|
188
|
+
const lighterTone = lighterUnsafe(bgTone, ratio);
|
|
189
|
+
const darkerTone = darkerUnsafe(bgTone, ratio);
|
|
190
|
+
const lighterRatio = ratioOfTones(lighterTone, bgTone);
|
|
191
|
+
const darkerRatio = ratioOfTones(darkerTone, bgTone);
|
|
192
|
+
const preferLighter = ColorRole.tonePrefersLightForeground(bgTone);
|
|
193
|
+
if (preferLighter) {
|
|
194
|
+
const negligibleDifference =
|
|
195
|
+
Math.abs(lighterRatio - darkerRatio) < 0.1 && lighterRatio < ratio && darkerRatio < ratio;
|
|
196
|
+
return lighterRatio >= ratio || lighterRatio >= darkerRatio || negligibleDifference
|
|
197
|
+
? lighterTone
|
|
198
|
+
: darkerTone;
|
|
199
|
+
}
|
|
200
|
+
return darkerRatio >= ratio || darkerRatio >= lighterRatio ? darkerTone : lighterTone;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
static tonePrefersLightForeground(tone: number): boolean {
|
|
204
|
+
return Math.round(tone) < 60.0;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
static toneAllowsLightForeground(tone: number): boolean {
|
|
208
|
+
return Math.round(tone) <= 49.0;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
static enableLightForeground(tone: number): number {
|
|
212
|
+
if (ColorRole.tonePrefersLightForeground(tone) && !ColorRole.toneAllowsLightForeground(tone)) {
|
|
213
|
+
return 49.0;
|
|
214
|
+
}
|
|
215
|
+
return tone;
|
|
216
|
+
}
|
|
217
|
+
}
|