@fibery/ui-kit 1.40.3 → 1.41.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/CHANGELOG.md +14 -0
- package/eslint.config.mjs +16 -0
- package/package.json +11 -13
- package/src/a11y-color.test.ts +162 -0
- package/src/a11y-color.ts +13 -20
- package/src/actions-menu/actions-menu-item.tsx +9 -12
- package/src/actions-menu/context-actions-menu.tsx +8 -3
- package/src/ai/model.tsx +0 -1
- package/src/ai/temperature.tsx +0 -1
- package/src/animated-height-container.tsx +3 -3
- package/src/antd/ant-modal.tsx +10 -5
- package/src/antd/index.tsx +3 -0
- package/src/antd/input.tsx +0 -1
- package/src/antd/styles.ts +15 -15
- package/src/app-icon-with-fallback.tsx +6 -6
- package/src/app-icon-wrapper.tsx +2 -3
- package/src/app-icon.tsx +4 -4
- package/src/avatar.tsx +3 -3
- package/src/button/base-button.tsx +0 -1
- package/src/button/button.tsx +1 -0
- package/src/button/make-button-colors.ts +5 -13
- package/src/checkbox.tsx +2 -2
- package/src/collapsible-section.tsx +11 -1
- package/src/color-picker/ColorPickerOrLoader.js +2 -2
- package/src/color-utils.test.ts +307 -0
- package/src/color-utils.ts +215 -0
- package/src/command-menu/index.tsx +1 -0
- package/src/comment.tsx +3 -2
- package/src/context-menu/index.tsx +12 -7
- package/src/date-picker/contexts.ts +2 -2
- package/src/date-picker/date-range-picker.tsx +3 -4
- package/src/date-picker/single-date-picker.tsx +147 -119
- package/src/date-picker/types.ts +4 -3
- package/src/day-select/iso-week-day-select.tsx +2 -2
- package/src/day-select/week-day-select.tsx +2 -2
- package/src/delayed.tsx +0 -1
- package/src/design-system/alpha.test.ts +59 -0
- package/src/design-system/alpha.ts +41 -0
- package/src/design-system/animation.ts +10 -0
- package/src/design-system/colors-css.test.ts +39 -0
- package/src/design-system/colors-css.ts +25 -0
- package/src/design-system/colors-js.test.ts +232 -0
- package/src/design-system/colors-js.ts +107 -0
- package/src/design-system/colors.test.ts +74 -0
- package/src/design-system/colors.ts +759 -0
- package/src/design-system/date.ts +3 -0
- package/src/design-system/layout.ts +106 -0
- package/src/design-system/theme.test.ts +94 -0
- package/src/design-system/theme.ts +93 -0
- package/src/design-system/typography.ts +179 -0
- package/src/design-system/vars.test.ts +1679 -0
- package/src/design-system/vars.ts +52 -0
- package/src/design-system.test.ts +45 -22
- package/src/design-system.ts +25 -1339
- package/src/dropdown-menu/index.tsx +21 -16
- package/src/emoji-picker/app-icon-picker.tsx +5 -5
- package/src/emoji-picker/emoji-picker-content-with-color.tsx +4 -4
- package/src/emoji-picker/icon-emoji-picker.tsx +3 -3
- package/src/favorites-icon.tsx +1 -1
- package/src/fibermoji-placeholder.tsx +3 -3
- package/src/field-container.tsx +11 -2
- package/src/file-item/file-icon.tsx +169 -0
- package/src/file-item/file-menu-items.tsx +68 -0
- package/src/file-item/file-preview-actions.tsx +38 -0
- package/src/file-item/file-title.tsx +48 -0
- package/src/file-item/types.ts +27 -0
- package/src/file-item/use-register-in-image-gallery.tsx +70 -0
- package/src/file-item-2.tsx +32 -348
- package/src/file-item.tsx +6 -3
- package/src/hue-shift.test.ts +91 -0
- package/src/icons/ast/ChatBubble.ts +8 -0
- package/src/icons/ast/ChatFloat.ts +8 -0
- package/src/icons/ast/ChatSidebar.ts +8 -0
- package/src/icons/ast/FileCounter.ts +8 -0
- package/src/icons/ast/FileMultiple.ts +8 -0
- package/src/icons/ast/FileOther.ts +8 -0
- package/src/icons/ast/NoBorder.ts +8 -0
- package/src/icons/ast/NoFill.ts +8 -0
- package/src/icons/ast/ValueEdit.ts +8 -0
- package/src/icons/ast/index.tsx +9 -0
- package/src/icons/react/ChatBubble.tsx +13 -0
- package/src/icons/react/ChatFloat.tsx +13 -0
- package/src/icons/react/ChatSidebar.tsx +13 -0
- package/src/icons/react/FileCounter.tsx +13 -0
- package/src/icons/react/FileMultiple.tsx +13 -0
- package/src/icons/react/FileOther.tsx +13 -0
- package/src/icons/react/NoBorder.tsx +13 -0
- package/src/icons/react/NoFill.tsx +13 -0
- package/src/icons/react/ValueEdit.tsx +13 -0
- package/src/icons/react/index.tsx +9 -0
- package/src/icons/svg/chat-bubble.svg +4 -0
- package/src/icons/svg/chat-float.svg +4 -0
- package/src/icons/svg/chat-sidebar.svg +4 -0
- package/src/icons/svg/file-counter.svg +3 -0
- package/src/icons/svg/file-multiple.svg +3 -0
- package/src/icons/svg/file-other.svg +3 -0
- package/src/icons/svg/no-border.svg +17 -0
- package/src/icons/svg/no-fill.svg +4 -0
- package/src/icons/svg/value-edit.svg +3 -0
- package/src/images-gallery/images-gallery.tsx +8 -6
- package/src/images-gallery/slide-buttons.tsx +4 -11
- package/src/is-iOS.ts +0 -1
- package/src/is-in-popup.ts +2 -1
- package/src/lists/actions-menu-row-surface.tsx +7 -7
- package/src/loading-sausage.tsx +2 -2
- package/src/media-query-utils.ts +1 -2
- package/src/mobile-keyboard-aware-popup.tsx +6 -5
- package/src/modal-menu/modal-menu-content.tsx +2 -2
- package/src/number-input/decimal.js +9 -7
- package/src/number-input/{number-inline-input-with-autosize.tsx → number-input-inline-with-autosize.tsx} +20 -41
- package/src/number-input/number-input-inline.tsx +118 -0
- package/src/number-input/{index.test.js → number-input.test.tsx} +38 -43
- package/src/number-input/number-input.tsx +63 -121
- package/src/number-input/types.ts +19 -0
- package/src/number-input/utils.ts +61 -0
- package/src/online-users.tsx +2 -2
- package/src/palette-generator.test.ts +309 -0
- package/src/palette-generator.ts +160 -0
- package/src/palettes/_.ts +72 -0
- package/src/palettes/slate-arch.colors-snapshot.test.ts +1689 -0
- package/src/palettes/slate-arch.ts +188 -0
- package/src/palettes/slate-user.colors-snapshot.test.ts +1689 -0
- package/src/palettes/slate-user.ts +187 -0
- package/src/palettes/warm-arch.colors-snapshot.test.ts +1689 -0
- package/src/palettes/warm-arch.ts +222 -0
- package/src/palettes/warm-user.colors-snapshot.test.ts +1689 -0
- package/src/palettes/warm-user.ts +222 -0
- package/src/platform.ts +0 -3
- package/src/popover/get-element-ref.ts +28 -0
- package/src/popover/index.tsx +236 -339
- package/src/popover/{mobile-popup-context.tsx → mobile-popover-context.tsx} +7 -7
- package/src/popover/mobile-popover.tsx +169 -0
- package/src/popover/modifiers.tsx +2 -2
- package/src/popover/popup-stack-context.tsx +8 -9
- package/src/progress.tsx +2 -2
- package/src/reactions/reaction-button.tsx +12 -6
- package/src/root-theme-provider.test.tsx +411 -0
- package/src/scale-generator.ts +356 -0
- package/src/select/components/menu-list-virtualized.tsx +12 -25
- package/src/select/components/menu.tsx +12 -2
- package/src/select/index.tsx +6 -5
- package/src/select/select.tsx +38 -39
- package/src/select/styles.ts +0 -1
- package/src/select/util.ts +1 -1
- package/src/static-palettes.ts +356 -0
- package/src/thematic-color-picker.tsx +266 -0
- package/src/thematic-constants.tsx +27 -0
- package/src/thematic-controls.tsx +144 -0
- package/src/thematic-scales.tsx +122 -0
- package/src/thematic-state.ts +370 -0
- package/src/thematic.tsx +386 -0
- package/src/theme-provider.test.tsx +820 -0
- package/src/theme-provider.tsx +158 -92
- package/src/theme-settings.ts +67 -12
- package/src/theme-styles.ts +58 -6
- package/src/toast/toast-action.tsx +1 -1
- package/src/toast/toast.tsx +1 -2
- package/src/toggle-on-off.tsx +2 -2
- package/src/toggle.tsx +7 -8
- package/src/tooltip.tsx +14 -10
- package/src/type-badge.tsx +7 -14
- package/src/unit/styles.ts +2 -25
- package/src/unit/unit-with-tooltip.tsx +3 -2
- package/src/use-is-phone.tsx +7 -2
- package/src/use-long-press.tsx +2 -2
- package/src/use-on-screen-keyboard-data.tsx +2 -2
- package/src/with-data.tsx +4 -3
- package/src/workflow-progress-icon.tsx +2 -2
- package/.eslintignore +0 -3
- package/.eslintrc +0 -14
- package/src/__mocks__/createInlineTheme.js +0 -3
- package/src/create-inline-theme.ts +0 -66
- package/src/number-input/index.js +0 -191
- package/src/palette.ts +0 -237
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import memoize from "lodash/memoize";
|
|
2
2
|
import {DaySelect, Props} from "./day-select";
|
|
3
3
|
|
|
4
4
|
export enum Days {
|
|
@@ -21,7 +21,7 @@ const WeekDayMap = {
|
|
|
21
21
|
SU: Days.SU,
|
|
22
22
|
};
|
|
23
23
|
|
|
24
|
-
export const getDays =
|
|
24
|
+
export const getDays = memoize((firstDay) => {
|
|
25
25
|
const entries = Object.entries(WeekDayMap);
|
|
26
26
|
const firstDayIndex = entries.findIndex((entry) => entry[1] === firstDay);
|
|
27
27
|
const partA = entries.slice(firstDayIndex);
|
package/src/delayed.tsx
CHANGED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import {getOpacities, transparent} from "./alpha";
|
|
2
|
+
|
|
3
|
+
describe("getOpacities", () => {
|
|
4
|
+
test("color maps to alphas", () => {
|
|
5
|
+
expect(getOpacities("#f00")).toMatchInlineSnapshot(`
|
|
6
|
+
{
|
|
7
|
+
"opacity0": "rgba(255,0,0,0)",
|
|
8
|
+
"opacity10": "rgba(255,0,0,0.1)",
|
|
9
|
+
"opacity100": "rgb(255,0,0)",
|
|
10
|
+
"opacity15": "rgba(255,0,0,0.15)",
|
|
11
|
+
"opacity20": "rgba(255,0,0,0.2)",
|
|
12
|
+
"opacity25": "rgba(255,0,0,0.25)",
|
|
13
|
+
"opacity30": "rgba(255,0,0,0.3)",
|
|
14
|
+
"opacity35": "rgba(255,0,0,0.35)",
|
|
15
|
+
"opacity40": "rgba(255,0,0,0.4)",
|
|
16
|
+
"opacity45": "rgba(255,0,0,0.45)",
|
|
17
|
+
"opacity5": "rgba(255,0,0,0.05)",
|
|
18
|
+
"opacity50": "rgba(255,0,0,0.5)",
|
|
19
|
+
"opacity55": "rgba(255,0,0,0.55)",
|
|
20
|
+
"opacity60": "rgba(255,0,0,0.6)",
|
|
21
|
+
"opacity65": "rgba(255,0,0,0.65)",
|
|
22
|
+
"opacity70": "rgba(255,0,0,0.7)",
|
|
23
|
+
"opacity75": "rgba(255,0,0,0.75)",
|
|
24
|
+
"opacity80": "rgba(255,0,0,0.8)",
|
|
25
|
+
"opacity85": "rgba(255,0,0,0.85)",
|
|
26
|
+
"opacity90": "rgba(255,0,0,0.9)",
|
|
27
|
+
"opacity95": "rgba(255,0,0,0.95)",
|
|
28
|
+
}
|
|
29
|
+
`);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
test("transparent is identity map", () => {
|
|
33
|
+
expect(getOpacities(transparent)).toMatchInlineSnapshot(`
|
|
34
|
+
{
|
|
35
|
+
"opacity0": "rgba(255, 255, 255, 0)",
|
|
36
|
+
"opacity10": "rgba(255, 255, 255, 0)",
|
|
37
|
+
"opacity100": "rgba(255, 255, 255, 0)",
|
|
38
|
+
"opacity15": "rgba(255, 255, 255, 0)",
|
|
39
|
+
"opacity20": "rgba(255, 255, 255, 0)",
|
|
40
|
+
"opacity25": "rgba(255, 255, 255, 0)",
|
|
41
|
+
"opacity30": "rgba(255, 255, 255, 0)",
|
|
42
|
+
"opacity35": "rgba(255, 255, 255, 0)",
|
|
43
|
+
"opacity40": "rgba(255, 255, 255, 0)",
|
|
44
|
+
"opacity45": "rgba(255, 255, 255, 0)",
|
|
45
|
+
"opacity5": "rgba(255, 255, 255, 0)",
|
|
46
|
+
"opacity50": "rgba(255, 255, 255, 0)",
|
|
47
|
+
"opacity55": "rgba(255, 255, 255, 0)",
|
|
48
|
+
"opacity60": "rgba(255, 255, 255, 0)",
|
|
49
|
+
"opacity65": "rgba(255, 255, 255, 0)",
|
|
50
|
+
"opacity70": "rgba(255, 255, 255, 0)",
|
|
51
|
+
"opacity75": "rgba(255, 255, 255, 0)",
|
|
52
|
+
"opacity80": "rgba(255, 255, 255, 0)",
|
|
53
|
+
"opacity85": "rgba(255, 255, 255, 0)",
|
|
54
|
+
"opacity90": "rgba(255, 255, 255, 0)",
|
|
55
|
+
"opacity95": "rgba(255, 255, 255, 0)",
|
|
56
|
+
}
|
|
57
|
+
`);
|
|
58
|
+
});
|
|
59
|
+
});
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import {produceColor, setAlpha} from "../color-utils";
|
|
2
|
+
import mapValues from "lodash/mapValues";
|
|
3
|
+
import memoize from "lodash/memoize";
|
|
4
|
+
export const transparent = "rgba(255, 255, 255, 0)";
|
|
5
|
+
|
|
6
|
+
export const opacity = {
|
|
7
|
+
opacity100: 1,
|
|
8
|
+
opacity95: 0.95,
|
|
9
|
+
opacity90: 0.9,
|
|
10
|
+
opacity85: 0.85,
|
|
11
|
+
opacity80: 0.8,
|
|
12
|
+
opacity75: 0.75,
|
|
13
|
+
opacity70: 0.7,
|
|
14
|
+
opacity65: 0.65,
|
|
15
|
+
opacity60: 0.6,
|
|
16
|
+
opacity55: 0.55,
|
|
17
|
+
opacity50: 0.5,
|
|
18
|
+
opacity45: 0.45,
|
|
19
|
+
opacity40: 0.4,
|
|
20
|
+
opacity35: 0.35,
|
|
21
|
+
opacity30: 0.3,
|
|
22
|
+
opacity25: 0.25,
|
|
23
|
+
opacity20: 0.2,
|
|
24
|
+
opacity15: 0.15,
|
|
25
|
+
opacity10: 0.1,
|
|
26
|
+
opacity5: 0.05,
|
|
27
|
+
opacity0: 0,
|
|
28
|
+
} as const;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* @deprecated I would think thrice on semantic value of this wrapper before one more usage
|
|
32
|
+
* maybe you will come up with something better
|
|
33
|
+
*/
|
|
34
|
+
export const getOpacities = memoize((color: string) =>
|
|
35
|
+
mapValues(opacity, (opacityValue) => {
|
|
36
|
+
if (color === transparent) {
|
|
37
|
+
return transparent;
|
|
38
|
+
}
|
|
39
|
+
return produceColor(color, (c) => setAlpha(c, opacityValue));
|
|
40
|
+
})
|
|
41
|
+
);
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import {getEnumTextColor, getLinearGradient} from "./colors-css";
|
|
2
|
+
|
|
3
|
+
describe("getLinearGradient", () => {
|
|
4
|
+
test("single color", () => {
|
|
5
|
+
expect(getLinearGradient(["#FF5400"])).toEqual("linear-gradient(to bottom, #FF5400 0%, #FF5400 100%)");
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
test("two colors", () => {
|
|
9
|
+
expect(getLinearGradient(["#FF5400", "#4978D4"])).toEqual(
|
|
10
|
+
"linear-gradient(to bottom, #FF5400 0%, #FF5400 50%, #4978D4 50%, #4978D4 100%)"
|
|
11
|
+
);
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
test("three colors", () => {
|
|
15
|
+
expect(getLinearGradient(["#FF5400", "#4978D4", "#08BD9F"])).toEqual(
|
|
16
|
+
"linear-gradient(to bottom, #FF5400 0%, #FF5400 33.33333333333333%, #4978D4 33.33333333333333%, #4978D4 66.66666666666666%, #08BD9F 66.66666666666666%, #08BD9F 100%)"
|
|
17
|
+
);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
test("four colors", () => {
|
|
21
|
+
expect(getLinearGradient(["#FF5400", "#4978D4", "#08BD9F", "#FFFFFF"])).toEqual(
|
|
22
|
+
"linear-gradient(to bottom, #FF5400 0%, #FF5400 25%, #4978D4 25%, #4978D4 50%, #08BD9F 50%, #08BD9F 75%, #FFFFFF 75%, #FFFFFF 100%)"
|
|
23
|
+
);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
test("card type colors subset", () => {
|
|
27
|
+
expect(getLinearGradient(["#4A4A4A", "#6A849B", "#99A2AB", "#D40915", "#E72065"])).toEqual(
|
|
28
|
+
"linear-gradient(to bottom, #4A4A4A 0%, #4A4A4A 20%, #6A849B 20%, #6A849B 40%, #99A2AB 40%, #99A2AB 60%, #D40915 60%, #D40915 80%, #E72065 80%, #E72065 100%)"
|
|
29
|
+
);
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
describe("getEnumTextColor", () => {
|
|
34
|
+
test("snapshot", () => {
|
|
35
|
+
expect(getEnumTextColor("#4978D4")).toMatchInlineSnapshot(
|
|
36
|
+
`"color-mix(in srgb, #4978D4 25%, var(--fibery-color-textColor) 75%)"`
|
|
37
|
+
);
|
|
38
|
+
});
|
|
39
|
+
});
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import {themeVars} from "./theme";
|
|
2
|
+
|
|
3
|
+
export function getLinearGradient(backgroundColors: Array<string>): string {
|
|
4
|
+
const parts = backgroundColors.flatMap((color, index, arr) => [
|
|
5
|
+
`${color} ${(index / arr.length) * 100}%`,
|
|
6
|
+
`${color} ${((index + 1) / arr.length) * 100}%`,
|
|
7
|
+
]);
|
|
8
|
+
return `linear-gradient(to bottom, ${parts.join(", ")})`;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function getEnumTextColor(color: string) {
|
|
12
|
+
return `color-mix(in srgb, ${color} 25%, ${themeVars.textColor} 75%)`;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function themeVarWithAlpha(themeVar: string, alpha: number) {
|
|
16
|
+
return `color-mix(in srgb, ${themeVar} ${Math.round(alpha * 100)}%, transparent)`;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export const dropCursorColor = themeVarWithAlpha(themeVars.primary, 0.7);
|
|
20
|
+
|
|
21
|
+
export const shadows = {
|
|
22
|
+
border: `0 0 0 1px ${themeVars.shades.opacity10}`,
|
|
23
|
+
inversedBorder: `0 0 0 1px ${themeVars.lights.opacity10}`,
|
|
24
|
+
videoPreview: "0 4px 30px 4px rgba(0, 0, 0, .15)",
|
|
25
|
+
} as const;
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
import {getDarkenColor, getObjectColorMemoized as getObjectColor, getTextColor} from "./colors-js";
|
|
2
|
+
import {getThemeColors} from "./theme";
|
|
3
|
+
|
|
4
|
+
const testColors = [
|
|
5
|
+
"#FF5400", // red
|
|
6
|
+
"#4978D4", // blue
|
|
7
|
+
"#08BD9F", // green
|
|
8
|
+
"#FBA32F", // yellow/orange
|
|
9
|
+
"#673DB6", // purple
|
|
10
|
+
"#000000", // black
|
|
11
|
+
"#FFFFFF", // white
|
|
12
|
+
];
|
|
13
|
+
|
|
14
|
+
describe("getDarkenColor", () => {
|
|
15
|
+
test("snapshot", () => {
|
|
16
|
+
expect(testColors.map((color) => getDarkenColor(color))).toEqual([
|
|
17
|
+
"rgb(212,74,29)",
|
|
18
|
+
"rgb(70,98,162)",
|
|
19
|
+
"rgb(82,159,138)",
|
|
20
|
+
"rgb(214,143,56)",
|
|
21
|
+
"rgb(78,46,138)",
|
|
22
|
+
"rgb(0,0,0)",
|
|
23
|
+
"rgb(229,229,229)",
|
|
24
|
+
]);
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
describe("getTextColor", () => {
|
|
29
|
+
test("snapshot", () => {
|
|
30
|
+
expect(testColors.map((color) => getTextColor(color))).toEqual([
|
|
31
|
+
"rgb(255,84,0)",
|
|
32
|
+
"rgb(73,120,212)",
|
|
33
|
+
"rgb(8,189,159)",
|
|
34
|
+
"rgb(251,163,47)",
|
|
35
|
+
"rgb(103,61,182)",
|
|
36
|
+
"rgb(0,0,0)",
|
|
37
|
+
"rgb(255,255,255)",
|
|
38
|
+
]);
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
const themes = {
|
|
43
|
+
light: getThemeColors(null, "light"),
|
|
44
|
+
dark: getThemeColors(null, "dark"),
|
|
45
|
+
light2: getThemeColors(null, "light2"),
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
const colors = {
|
|
49
|
+
red: "#FF5400",
|
|
50
|
+
blue: "#4978D4",
|
|
51
|
+
green: "#08BD9F",
|
|
52
|
+
yellow: "#FBA32F",
|
|
53
|
+
purple: "#673DB6",
|
|
54
|
+
black: "#000000",
|
|
55
|
+
white: "#FFFFFF",
|
|
56
|
+
} as const;
|
|
57
|
+
|
|
58
|
+
function mapColors(fn: (color: string) => string) {
|
|
59
|
+
return Object.fromEntries(Object.entries(colors).map(([k, hex]) => [k, fn(hex)]));
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
describe("getEnumBackground", () => {
|
|
63
|
+
test("light", () => {
|
|
64
|
+
expect(mapColors(themes.light.fns.getEnumBackground)).toEqual({
|
|
65
|
+
black: "rgba(0,0,0,0.15)",
|
|
66
|
+
blue: "rgba(73,120,212,0.15)",
|
|
67
|
+
green: "rgba(8,189,159,0.15)",
|
|
68
|
+
purple: "rgba(103,61,182,0.15)",
|
|
69
|
+
red: "rgba(255,84,0,0.15)",
|
|
70
|
+
white: "rgba(255,255,255,0.15)",
|
|
71
|
+
yellow: "rgba(251,163,47,0.15)",
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
test("dark", () => {
|
|
75
|
+
expect(mapColors(themes.dark.fns.getEnumBackground)).toEqual({
|
|
76
|
+
black: "rgb(39,39,39)",
|
|
77
|
+
blue: "rgba(73,120,212,0.3)",
|
|
78
|
+
green: "rgba(8,189,159,0.3)",
|
|
79
|
+
purple: "rgba(103,61,182,0.3)",
|
|
80
|
+
red: "rgba(255,84,0,0.3)",
|
|
81
|
+
white: "rgba(255,255,255,0.3)",
|
|
82
|
+
yellow: "rgba(251,163,47,0.3)",
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
test("light2 defaults to light", () => {
|
|
86
|
+
expect(mapColors(themes.light2.fns.getEnumBackground)).toEqual(mapColors(themes.light.fns.getEnumBackground));
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
describe("getIconColor", () => {
|
|
91
|
+
test("light", () => {
|
|
92
|
+
expect(mapColors(themes.light.fns.getIconColor)).toEqual({
|
|
93
|
+
black: "rgba(0,0,0,0.95)",
|
|
94
|
+
blue: "rgba(73,120,212,0.95)",
|
|
95
|
+
green: "rgb(7,168,141)",
|
|
96
|
+
purple: "rgba(103,61,182,0.95)",
|
|
97
|
+
red: "rgba(255,84,0,0.95)",
|
|
98
|
+
white: "rgb(148,148,148)",
|
|
99
|
+
yellow: "rgb(219,126,4)",
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
test("dark", () => {
|
|
103
|
+
expect(mapColors(themes.dark.fns.getIconColor)).toEqual({
|
|
104
|
+
black: "rgb(130,130,130)",
|
|
105
|
+
blue: "rgb(84,128,215)",
|
|
106
|
+
green: "rgba(8,189,159,0.95)",
|
|
107
|
+
purple: "rgb(145,112,207)",
|
|
108
|
+
red: "rgba(255,84,0,0.95)",
|
|
109
|
+
white: "rgba(255,255,255,0.95)",
|
|
110
|
+
yellow: "rgba(251,163,47,0.95)",
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
describe("getAppIconBackground", () => {
|
|
116
|
+
test("light", () => {
|
|
117
|
+
expect(mapColors(themes.light.fns.getAppIconBackground)).toEqual({
|
|
118
|
+
black: "rgba(0,0,0,0.15)",
|
|
119
|
+
blue: "rgba(73,120,212,0.15)",
|
|
120
|
+
green: "rgba(8,189,159,0.15)",
|
|
121
|
+
purple: "rgba(103,61,182,0.15)",
|
|
122
|
+
red: "rgba(255,84,0,0.15)",
|
|
123
|
+
white: "rgba(255,255,255,0.15)",
|
|
124
|
+
yellow: "rgba(251,163,47,0.15)",
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
test("dark", () => {
|
|
128
|
+
expect(mapColors(themes.dark.fns.getAppIconBackground)).toEqual({
|
|
129
|
+
black: "rgb(39,39,39)",
|
|
130
|
+
blue: "rgba(73,120,212,0.3)",
|
|
131
|
+
green: "rgba(8,189,159,0.3)",
|
|
132
|
+
purple: "rgba(103,61,182,0.3)",
|
|
133
|
+
red: "rgba(255,84,0,0.3)",
|
|
134
|
+
white: "rgba(255,255,255,0.3)",
|
|
135
|
+
yellow: "rgba(251,163,47,0.3)",
|
|
136
|
+
});
|
|
137
|
+
});
|
|
138
|
+
test("light2 uses dark fn", () => {
|
|
139
|
+
expect(mapColors(themes.light2.fns.getAppIconBackground)).toEqual(mapColors(themes.dark.fns.getAppIconBackground));
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
describe("getLinkedHighlightBackground", () => {
|
|
144
|
+
test("light", () => {
|
|
145
|
+
expect(mapColors(themes.light.fns.getLinkedHighlightBackground)).toEqual({
|
|
146
|
+
black: "rgba(203,203,203,0.3)",
|
|
147
|
+
blue: "rgba(187,204,239,0.3)",
|
|
148
|
+
green: "rgba(125,220,204,0.3)",
|
|
149
|
+
purple: "rgba(210,198,234,0.3)",
|
|
150
|
+
red: "rgba(255,189,156,0.3)",
|
|
151
|
+
white: "rgba(203,203,203,0.3)",
|
|
152
|
+
yellow: "rgba(252,193,114,0.3)",
|
|
153
|
+
});
|
|
154
|
+
});
|
|
155
|
+
test("dark", () => {
|
|
156
|
+
expect(mapColors(themes.dark.fns.getLinkedHighlightBackground)).toEqual({
|
|
157
|
+
black: "rgba(188,188,188,0.4)",
|
|
158
|
+
blue: "rgba(165,188,234,0.4)",
|
|
159
|
+
green: "rgba(77,208,186,0.4)",
|
|
160
|
+
purple: "rgba(196,180,227,0.4)",
|
|
161
|
+
red: "rgba(255,166,122,0.4)",
|
|
162
|
+
white: "rgba(188,188,188,0.4)",
|
|
163
|
+
yellow: "rgba(251,171,65,0.4)",
|
|
164
|
+
});
|
|
165
|
+
});
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
describe("getLinkedHighlightDecorationBackground", () => {
|
|
169
|
+
test("light", () => {
|
|
170
|
+
expect(mapColors(themes.light.fns.getLinkedHighlightDecorationBackground)).toEqual({
|
|
171
|
+
black: "rgba(188,188,188,0.9)",
|
|
172
|
+
blue: "rgba(165,188,234,0.9)",
|
|
173
|
+
green: "rgba(77,208,186,0.9)",
|
|
174
|
+
purple: "rgba(196,180,227,0.9)",
|
|
175
|
+
red: "rgba(255,166,122,0.9)",
|
|
176
|
+
white: "rgba(188,188,188,0.9)",
|
|
177
|
+
yellow: "rgba(251,171,65,0.9)",
|
|
178
|
+
});
|
|
179
|
+
});
|
|
180
|
+
test("dark", () => {
|
|
181
|
+
expect(mapColors(themes.dark.fns.getLinkedHighlightDecorationBackground)).toEqual({
|
|
182
|
+
black: "rgba(178,178,178,0.9)",
|
|
183
|
+
blue: "rgba(155,178,223,0.9)",
|
|
184
|
+
green: "rgba(65,197,176,0.9)",
|
|
185
|
+
purple: "rgba(186,170,217,0.9)",
|
|
186
|
+
red: "rgba(244,156,113,0.9)",
|
|
187
|
+
white: "rgba(178,178,178,0.9)",
|
|
188
|
+
yellow: "rgba(240,161,55,0.9)",
|
|
189
|
+
});
|
|
190
|
+
});
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
describe("getObjectColor", () => {
|
|
194
|
+
test("empty name returns default", () => {
|
|
195
|
+
expect(getObjectColor("")).toEqual("#999999");
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
test("null/undefined returns default", () => {
|
|
199
|
+
expect(getObjectColor(null)).toEqual("#999999");
|
|
200
|
+
expect(getObjectColor(undefined)).toEqual("#999999");
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
test("typical entity names", () => {
|
|
204
|
+
expect(getObjectColor("Task")).toEqual("#d6895c");
|
|
205
|
+
expect(getObjectColor("Feature")).toEqual("#d47de8");
|
|
206
|
+
expect(getObjectColor("Bug")).toEqual("#cc33c2");
|
|
207
|
+
expect(getObjectColor("User Story")).toEqual("#85d3e0");
|
|
208
|
+
expect(getObjectColor("Epic")).toEqual("#e085cd");
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
test("database names", () => {
|
|
212
|
+
expect(getObjectColor("Product Management")).toEqual("#66b8ff");
|
|
213
|
+
expect(getObjectColor("Engineering")).toEqual("#ff002f");
|
|
214
|
+
expect(getObjectColor("Design")).toEqual("#0d18f2");
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
test("special characters", () => {
|
|
218
|
+
expect(getObjectColor("Task #1")).toEqual("#e87d89");
|
|
219
|
+
expect(getObjectColor("Feature (v2)")).toEqual("#f09e75");
|
|
220
|
+
expect(getObjectColor("Bug-123")).toEqual("#66c7ff");
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
test("long names", () => {
|
|
224
|
+
expect(getObjectColor("This is a very long entity name that might be used in some cases")).toEqual("#ff6694");
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
test("unicode names", () => {
|
|
228
|
+
expect(getObjectColor("Задача")).toEqual("#cc7a33");
|
|
229
|
+
expect(getObjectColor("機能")).toEqual("#72e619");
|
|
230
|
+
expect(getObjectColor("🚀 Feature")).toEqual("#dfe619");
|
|
231
|
+
});
|
|
232
|
+
});
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import ColorHash from "color-hash";
|
|
2
|
+
import {ThemeMode} from "../theme-settings";
|
|
3
|
+
import {
|
|
4
|
+
clampRgb,
|
|
5
|
+
darkenChroma,
|
|
6
|
+
desaturateChroma,
|
|
7
|
+
produceColor,
|
|
8
|
+
set,
|
|
9
|
+
setAlpha,
|
|
10
|
+
setLuminanceChroma,
|
|
11
|
+
toCss,
|
|
12
|
+
} from "../color-utils";
|
|
13
|
+
import memoize from "lodash/memoize";
|
|
14
|
+
import {getOpacities} from "./alpha";
|
|
15
|
+
|
|
16
|
+
export const getDarkenColor = memoize((color: string): string => {
|
|
17
|
+
return produceColor(color, [(c) => darkenChroma(c, 0.5), clampRgb, (c) => desaturateChroma(c, 0.8)]);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
export const getTextColor = memoize((color: string): string => {
|
|
21
|
+
return toCss(color);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
export const getObjectColorMemoized = memoize((name) => {
|
|
25
|
+
if (!name) {
|
|
26
|
+
return "#999999";
|
|
27
|
+
}
|
|
28
|
+
const colorHash = new ColorHash({
|
|
29
|
+
lightness: [0.5, 0.6, 0.7],
|
|
30
|
+
saturation: [0.6, 0.7, 0.8, 0.9, 1],
|
|
31
|
+
});
|
|
32
|
+
return colorHash.hex(name);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
export type TypeColors = ReturnType<typeof getTypeColors>;
|
|
36
|
+
|
|
37
|
+
export function getTypeColors(color: string, theme: ThemeMode) {
|
|
38
|
+
const makeBrightenPrimary = () => {
|
|
39
|
+
return produceColor(color, [
|
|
40
|
+
(c) => setLuminanceChroma(c, 0.92),
|
|
41
|
+
(c) => desaturateChroma(c, 0.1),
|
|
42
|
+
(c) => setAlpha(c, 0.98),
|
|
43
|
+
]);
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const makeHeaderBg = () => {
|
|
47
|
+
return produceColor(color, [
|
|
48
|
+
(c) => setLuminanceChroma(c, 0.7),
|
|
49
|
+
(c) => desaturateChroma(c, 0.5),
|
|
50
|
+
(c) => set(c, "hsl.h", (h) => h + 2),
|
|
51
|
+
]);
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
const makeLightDetailsBg = () => {
|
|
55
|
+
return produceColor(color, [(c) => setAlpha(c, 0.5), (c) => setLuminanceChroma(c, 0.85)]);
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
const makeDarkDetailsBg = () => {
|
|
59
|
+
return produceColor(color, [
|
|
60
|
+
(c) => setAlpha(c, 0.03),
|
|
61
|
+
(c) => setLuminanceChroma(c, 0.8),
|
|
62
|
+
(c) => desaturateChroma(c, 0.8),
|
|
63
|
+
(c) => darkenChroma(c, 0.1),
|
|
64
|
+
]);
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const makeFocus = () => {
|
|
68
|
+
return produceColor(color, (c) => setAlpha(c, 0.25));
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
const makeSeparator = () => {
|
|
72
|
+
return produceColor(color, (c) => setAlpha(c, 0.3));
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
const lightTypeColors = {
|
|
76
|
+
primary: color,
|
|
77
|
+
opacity: getOpacities(color),
|
|
78
|
+
darkenPrimary: getDarkenColor(color),
|
|
79
|
+
brightenPrimary: makeBrightenPrimary(),
|
|
80
|
+
headerBg: makeHeaderBg(),
|
|
81
|
+
detailsBg: makeLightDetailsBg(),
|
|
82
|
+
focus: makeFocus(),
|
|
83
|
+
separator: makeSeparator(),
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
const darkTypeColors = {
|
|
87
|
+
primary: color,
|
|
88
|
+
opacity: getOpacities(color),
|
|
89
|
+
darkenPrimary: getDarkenColor(color),
|
|
90
|
+
brightenPrimary: makeBrightenPrimary(),
|
|
91
|
+
headerBg: makeHeaderBg(),
|
|
92
|
+
detailsBg: makeDarkDetailsBg(),
|
|
93
|
+
focus: makeFocus(),
|
|
94
|
+
separator: makeSeparator(),
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
switch (theme) {
|
|
98
|
+
case "light":
|
|
99
|
+
return lightTypeColors;
|
|
100
|
+
case "dark":
|
|
101
|
+
return darkTypeColors;
|
|
102
|
+
case "light2":
|
|
103
|
+
return lightTypeColors;
|
|
104
|
+
default:
|
|
105
|
+
return lightTypeColors;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import {pickColors, type ThemeDefs} from "./colors";
|
|
2
|
+
|
|
3
|
+
describe("pickColors", () => {
|
|
4
|
+
const themeDefs = {
|
|
5
|
+
colors: {
|
|
6
|
+
mode: ["light", "dark"],
|
|
7
|
+
colorAI: ["hsla(271, 57%, 61%, 1)", "hsla(272, 43%, 50%, 1)"],
|
|
8
|
+
transparent: ["rgba(255, 255, 255, 0)", "rgba(0, 0, 0, 0)"],
|
|
9
|
+
lights: [{opacity5: "light5"}, {opacity5: "dark-light5"}],
|
|
10
|
+
shades: [{opacity5: "shade5"}, {opacity5: "dark-shade5"}],
|
|
11
|
+
separators: [{opacity5: "separator5"}, {opacity5: "dark-separator5"}],
|
|
12
|
+
} as unknown as ThemeDefs["colors"],
|
|
13
|
+
fns: {
|
|
14
|
+
getIconColor: {light: (_: string) => "IconColor", dark: (_: string) => "DarkIconColor"},
|
|
15
|
+
} as unknown as ThemeDefs["fns"],
|
|
16
|
+
} satisfies Partial<ThemeDefs> as ThemeDefs;
|
|
17
|
+
|
|
18
|
+
test("light", () => {
|
|
19
|
+
expect(pickColors(themeDefs, "light")).toMatchInlineSnapshot(`
|
|
20
|
+
{
|
|
21
|
+
"colorAI": "hsla(271, 57%, 61%, 1)",
|
|
22
|
+
"lights": {
|
|
23
|
+
"opacity5": "light5",
|
|
24
|
+
},
|
|
25
|
+
"mode": "light",
|
|
26
|
+
"separators": {
|
|
27
|
+
"opacity5": "separator5",
|
|
28
|
+
},
|
|
29
|
+
"shades": {
|
|
30
|
+
"opacity5": "shade5",
|
|
31
|
+
},
|
|
32
|
+
"transparent": "rgba(255, 255, 255, 0)",
|
|
33
|
+
}
|
|
34
|
+
`);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
test("dark", () => {
|
|
38
|
+
expect(pickColors(themeDefs, "dark")).toMatchInlineSnapshot(`
|
|
39
|
+
{
|
|
40
|
+
"colorAI": "hsla(272, 43%, 50%, 1)",
|
|
41
|
+
"lights": {
|
|
42
|
+
"opacity5": "dark-light5",
|
|
43
|
+
},
|
|
44
|
+
"mode": "dark",
|
|
45
|
+
"separators": {
|
|
46
|
+
"opacity5": "dark-separator5",
|
|
47
|
+
},
|
|
48
|
+
"shades": {
|
|
49
|
+
"opacity5": "dark-shade5",
|
|
50
|
+
},
|
|
51
|
+
"transparent": "rgba(0, 0, 0, 0)",
|
|
52
|
+
}
|
|
53
|
+
`);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
test("light2 overrides mode", () => {
|
|
57
|
+
expect(pickColors(themeDefs, "light2")).toMatchInlineSnapshot(`
|
|
58
|
+
{
|
|
59
|
+
"colorAI": "hsla(271, 57%, 61%, 1)",
|
|
60
|
+
"lights": {
|
|
61
|
+
"opacity5": "light5",
|
|
62
|
+
},
|
|
63
|
+
"mode": "light2",
|
|
64
|
+
"separators": {
|
|
65
|
+
"opacity5": "separator5",
|
|
66
|
+
},
|
|
67
|
+
"shades": {
|
|
68
|
+
"opacity5": "shade5",
|
|
69
|
+
},
|
|
70
|
+
"transparent": "rgba(255, 255, 255, 0)",
|
|
71
|
+
}
|
|
72
|
+
`);
|
|
73
|
+
});
|
|
74
|
+
});
|