@fibery/ui-kit 1.40.4 → 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 +6 -0
- package/eslint.config.mjs +16 -0
- package/package.json +8 -7
- package/src/a11y-color.test.ts +5 -24
- package/src/actions-menu/actions-menu-item.tsx +6 -9
- 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/index.tsx +3 -0
- package/src/antd/input.tsx +0 -1
- package/src/antd/styles.ts +9 -9
- package/src/app-icon-with-fallback.tsx +5 -5
- package/src/app-icon-wrapper.tsx +2 -3
- package/src/app-icon.tsx +3 -3
- package/src/avatar.tsx +3 -3
- package/src/button/base-button.tsx +0 -1
- package/src/button/make-button-colors.ts +2 -2
- package/src/checkbox.tsx +1 -1
- package/src/collapsible-section.tsx +11 -1
- package/src/color-utils.test.ts +15 -25
- package/src/color-utils.ts +43 -8
- package/src/command-menu/index.tsx +1 -0
- package/src/context-menu/index.tsx +5 -5
- 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 → design-system/colors.ts} +133 -134
- 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 +46 -303
- package/src/design-system.ts +25 -545
- package/src/dropdown-menu/index.tsx +5 -5
- package/src/emoji-picker/icon-emoji-picker.tsx +1 -1
- package/src/fibermoji-placeholder.tsx +3 -3
- package/src/field-container.tsx +11 -2
- package/src/file-item/file-icon.tsx +3 -3
- package/src/file-item-2.tsx +4 -10
- package/src/file-item.tsx +0 -1
- 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/FileOther.ts +8 -0
- package/src/icons/ast/NoBorder.ts +8 -0
- package/src/icons/ast/NoFill.ts +8 -0
- package/src/icons/ast/index.tsx +6 -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/FileOther.tsx +13 -0
- package/src/icons/react/NoBorder.tsx +13 -0
- package/src/icons/react/NoFill.tsx +13 -0
- package/src/icons/react/index.tsx +6 -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-other.svg +3 -0
- package/src/icons/svg/no-border.svg +17 -0
- package/src/icons/svg/no-fill.svg +4 -0
- package/src/images-gallery/images-gallery.tsx +8 -6
- package/src/images-gallery/slide-buttons.tsx +2 -2
- package/src/is-iOS.ts +0 -1
- package/src/is-in-popup.ts +2 -1
- package/src/lists/actions-menu-row-surface.tsx +4 -4
- package/src/loading-sausage.tsx +2 -2
- package/src/media-query-utils.ts +1 -2
- package/src/mobile-keyboard-aware-popup.tsx +2 -2
- 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 +24 -281
- package/src/palette-generator.ts +39 -45
- 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/popover/get-element-ref.ts +28 -0
- package/src/popover/index.tsx +232 -333
- 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/root-theme-provider.test.tsx +114 -19
- package/src/scale-generator.ts +31 -22
- package/src/select/components/menu-list-virtualized.tsx +5 -3
- package/src/select/index.tsx +6 -5
- package/src/select/select.tsx +36 -38
- package/src/select/util.ts +1 -1
- package/src/static-palettes.ts +221 -11
- package/src/thematic-controls.tsx +6 -6
- package/src/thematic-scales.tsx +15 -15
- package/src/thematic-state.ts +57 -20
- package/src/thematic.tsx +36 -32
- package/src/theme-provider.test.tsx +31 -19
- package/src/theme-provider.tsx +41 -38
- package/src/theme-settings.ts +66 -11
- package/src/theme-styles.ts +53 -8
- package/src/toast/toast.tsx +1 -2
- package/src/toggle.tsx +2 -2
- package/src/tooltip.tsx +4 -3
- package/src/type-badge.tsx +4 -11
- package/src/unit/styles.ts +0 -23
- package/src/use-is-phone.tsx +7 -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/__snapshots__/design-system.test.ts.snap +0 -7265
- package/src/create-inline-theme.ts +0 -67
- package/src/number-input/index.js +0 -191
- package/src/palette.ts +0 -253
package/CHANGELOG.md
CHANGED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import baseConfig from "@fibery/eslint-config";
|
|
2
|
+
|
|
3
|
+
export default [
|
|
4
|
+
...baseConfig,
|
|
5
|
+
{
|
|
6
|
+
rules: {
|
|
7
|
+
"no-restricted-imports": ["error", {patterns: ["@fibery/ui-kit/*"]}],
|
|
8
|
+
},
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
files: ["src/icons/**/*"],
|
|
12
|
+
rules: {
|
|
13
|
+
"unicorn/filename-case": "off",
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fibery/ui-kit",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.41.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"dependencies": {
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
"@radix-ui/react-collapsible": "1.1.0",
|
|
11
11
|
"@radix-ui/react-context-menu": "2.2.1",
|
|
12
12
|
"@radix-ui/react-dropdown-menu": "2.1.1",
|
|
13
|
+
"@radix-ui/react-focus-scope": "^1.1.8",
|
|
13
14
|
"@radix-ui/react-navigation-menu": "1.2.1",
|
|
14
15
|
"@radix-ui/react-slot": "1.2.4",
|
|
15
16
|
"@radix-ui/react-toast": "1.2.2",
|
|
@@ -20,7 +21,7 @@
|
|
|
20
21
|
"@types/react-select-country-list": "^2.2.3",
|
|
21
22
|
"@types/setimmediate": "^1.0.4",
|
|
22
23
|
"antd": "4.24.7",
|
|
23
|
-
"chrono-node": "^2.
|
|
24
|
+
"chrono-node": "^2.9.0",
|
|
24
25
|
"classnames": "2.3.1",
|
|
25
26
|
"cmdk": "1.0.0",
|
|
26
27
|
"color-hash": "1.0.3",
|
|
@@ -42,7 +43,7 @@
|
|
|
42
43
|
"react-popper": "2.3.0",
|
|
43
44
|
"react-select": "5.3.2",
|
|
44
45
|
"react-select-country-list": "2.2.1",
|
|
45
|
-
"react-virtuoso": "4.
|
|
46
|
+
"react-virtuoso": "4.18.1",
|
|
46
47
|
"screenfull": "6.0.2",
|
|
47
48
|
"tabbable": "5.2.1",
|
|
48
49
|
"@fibery/emoji-data": "2.7.1",
|
|
@@ -81,7 +82,7 @@
|
|
|
81
82
|
"typescript": "5.9.3",
|
|
82
83
|
"unist-util-reduce": "0.2.2",
|
|
83
84
|
"@fibery/babel-preset": "7.4.1",
|
|
84
|
-
"@fibery/eslint-config": "
|
|
85
|
+
"@fibery/eslint-config": "9.0.0"
|
|
85
86
|
},
|
|
86
87
|
"jest": {
|
|
87
88
|
"testEnvironment": "jsdom",
|
|
@@ -97,8 +98,7 @@
|
|
|
97
98
|
"cobertura"
|
|
98
99
|
],
|
|
99
100
|
"moduleNameMapper": {
|
|
100
|
-
"\\.(css)$": "<rootDir>/src/__mocks__/styleMock.js"
|
|
101
|
-
"createInlineTheme\\.js$": "<rootDir>/src/__mocks__/createInlineTheme.js"
|
|
101
|
+
"\\.(css)$": "<rootDir>/src/__mocks__/styleMock.js"
|
|
102
102
|
},
|
|
103
103
|
"transform": {
|
|
104
104
|
"^.+\\.(js|jsx|ts|tsx)$": [
|
|
@@ -129,6 +129,7 @@
|
|
|
129
129
|
"test:ci": "pnpm run test --reporters=default --reporters=jest-junit",
|
|
130
130
|
"test:coverage": "pnpm run test --coverage --coverageDirectory=${JEST_COVERAGE_RESULT_DIR:-$(pwd)}/coverage/ui-kit --reporters=default --reporters=jest-junit",
|
|
131
131
|
"lint": "eslint .",
|
|
132
|
-
"generate-icons": "node scripts/generate-icons.mjs"
|
|
132
|
+
"generate-icons": "node scripts/generate-icons.mjs",
|
|
133
|
+
"typecheck": "tsc --noEmit"
|
|
133
134
|
}
|
|
134
135
|
}
|
package/src/a11y-color.test.ts
CHANGED
|
@@ -11,27 +11,27 @@ describe("a11yColor", () => {
|
|
|
11
11
|
it("color already passes contrast on dark background", () => {
|
|
12
12
|
// White on black should already pass
|
|
13
13
|
const result = a11yColor("#ffffff", "#000000");
|
|
14
|
-
expect(result).
|
|
14
|
+
expect(result).toMatchInlineSnapshot(`"rgb(255,255,255)"`);
|
|
15
15
|
});
|
|
16
16
|
|
|
17
17
|
it("invalid toMakeA11y color is provided", () => {
|
|
18
18
|
const result = a11yColor("invalid-color", "#ffffff");
|
|
19
|
-
expect(result).
|
|
19
|
+
expect(result).toMatchInlineSnapshot(`"invalid-color"`);
|
|
20
20
|
});
|
|
21
21
|
|
|
22
22
|
it("invalid background color is provided", () => {
|
|
23
23
|
const result = a11yColor("#ff0000", "invalid-bg");
|
|
24
|
-
expect(result).
|
|
24
|
+
expect(result).toMatchInlineSnapshot(`"#ff0000"`);
|
|
25
25
|
});
|
|
26
26
|
|
|
27
27
|
it("transparent is provided as toMakeA11y", () => {
|
|
28
28
|
const result = a11yColor("transparent", "#ffffff");
|
|
29
|
-
expect(result).
|
|
29
|
+
expect(result).toMatchInlineSnapshot(`"transparent"`);
|
|
30
30
|
});
|
|
31
31
|
|
|
32
32
|
it("transparent is provided as background", () => {
|
|
33
33
|
const result = a11yColor("#ff0000", "transparent");
|
|
34
|
-
expect(result).
|
|
34
|
+
expect(result).toMatchInlineSnapshot(`"#ff0000"`);
|
|
35
35
|
});
|
|
36
36
|
});
|
|
37
37
|
|
|
@@ -40,16 +40,12 @@ describe("a11yColor", () => {
|
|
|
40
40
|
// Light yellow on white needs to be darker
|
|
41
41
|
const result = a11yColor("#ffff00", "#ffffff");
|
|
42
42
|
expect(result).toMatchInlineSnapshot(`"rgb(154,154,0)"`);
|
|
43
|
-
// Result should be different (darker) than input
|
|
44
|
-
expect(result).not.toBe("rgb(255,255,0)");
|
|
45
43
|
});
|
|
46
44
|
|
|
47
45
|
it("makes dark color lighter on black background", () => {
|
|
48
46
|
// Dark blue on black needs to be lighter
|
|
49
47
|
const result = a11yColor("#000033", "#000000");
|
|
50
48
|
expect(result).toMatchInlineSnapshot(`"rgb(49,49,255)"`);
|
|
51
|
-
// Result should be different (lighter) than input
|
|
52
|
-
expect(result).not.toBe("rgb(0,0,51)");
|
|
53
49
|
});
|
|
54
50
|
|
|
55
51
|
it("handles medium colors on light backgrounds", () => {
|
|
@@ -109,21 +105,6 @@ describe("a11yColor", () => {
|
|
|
109
105
|
});
|
|
110
106
|
});
|
|
111
107
|
|
|
112
|
-
describe("caching", () => {
|
|
113
|
-
it("returns same result for same inputs", () => {
|
|
114
|
-
const result1 = a11yColor("#ff0000", "#ffffff");
|
|
115
|
-
const result2 = a11yColor("#ff0000", "#ffffff");
|
|
116
|
-
expect(result1).toBe(result2);
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
it("returns different results for different contrast ratios", () => {
|
|
120
|
-
const result1 = a11yColor("#cccccc", "#ffffff", 3.0);
|
|
121
|
-
const result2 = a11yColor("#cccccc", "#ffffff", 7.0);
|
|
122
|
-
// Higher contrast requirement may produce different result
|
|
123
|
-
expect(result1).not.toBe(result2);
|
|
124
|
-
});
|
|
125
|
-
});
|
|
126
|
-
|
|
127
108
|
describe("real-world use cases", () => {
|
|
128
109
|
it("brand green on white background", () => {
|
|
129
110
|
const result = a11yColor("#69AC5E", "#ffffff");
|
|
@@ -12,7 +12,7 @@ import {useTheme} from "../theme-provider";
|
|
|
12
12
|
import {useIsPhone} from "../use-is-phone";
|
|
13
13
|
import {useActionsMenuContext} from "./contexts/actions-menu-context";
|
|
14
14
|
import {useActiveDangerousRow, useSetActiveDangerousRow} from "./contexts/actions-menu-dangerous-rows";
|
|
15
|
-
import
|
|
15
|
+
import noop from "lodash/noop";
|
|
16
16
|
|
|
17
17
|
const hiddenTextCss = css`
|
|
18
18
|
visibility: hidden;
|
|
@@ -55,18 +55,18 @@ export const dangerousItemCss = css`
|
|
|
55
55
|
export const dangerousConfirmationCss = css`
|
|
56
56
|
&.${rowCss} {
|
|
57
57
|
background-color: ${themeVars.colorBgActionsMenuItemDangerActive};
|
|
58
|
-
color: ${themeVars.
|
|
58
|
+
color: ${themeVars.whiteColor};
|
|
59
59
|
border-radius: ${border.radius6}px;
|
|
60
60
|
|
|
61
|
-
--actions-menu-item-icon-color: ${themeVars.
|
|
61
|
+
--actions-menu-item-icon-color: ${themeVars.whiteColor};
|
|
62
62
|
|
|
63
63
|
&:hover,
|
|
64
64
|
&[data-highlighted] {
|
|
65
65
|
background-color: ${themeVars.colorBgActionsMenuItemDangerActive};
|
|
66
|
-
color: ${themeVars.
|
|
66
|
+
color: ${themeVars.whiteColor};
|
|
67
67
|
border-radius: ${border.radius6}px;
|
|
68
68
|
|
|
69
|
-
--actions-menu-item-icon-color: ${themeVars.
|
|
69
|
+
--actions-menu-item-icon-color: ${themeVars.whiteColor};
|
|
70
70
|
}
|
|
71
71
|
}
|
|
72
72
|
`;
|
|
@@ -95,7 +95,7 @@ const RightCorner = ({shortcut, loading, checked}: {shortcut?: string[]; loading
|
|
|
95
95
|
const theme = useTheme();
|
|
96
96
|
const isPhone = useIsPhone();
|
|
97
97
|
|
|
98
|
-
const shortcuts =
|
|
98
|
+
const shortcuts = Array.isArray(shortcut) ? shortcut : shortcut ? [shortcut] : null;
|
|
99
99
|
|
|
100
100
|
return loading || shortcuts || checked ? (
|
|
101
101
|
<div className={cornerCss}>
|
|
@@ -218,9 +218,6 @@ const ActionsMenuItemComponent: React.FC<
|
|
|
218
218
|
);
|
|
219
219
|
});
|
|
220
220
|
|
|
221
|
-
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
222
|
-
const noop = () => {};
|
|
223
|
-
|
|
224
221
|
export const ActionsMenuItem: React.FC<ActionsMenuItemProps> = ({className, ...props}) => {
|
|
225
222
|
const id = useId();
|
|
226
223
|
const activeDangerousRow = useActiveDangerousRow();
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import noop from "lodash/noop";
|
|
2
2
|
import {useControllableState} from "@fibery/react/src/use-controllable-state";
|
|
3
3
|
import {ActionsMenuContextProvider} from "./contexts/actions-menu-context";
|
|
4
4
|
import * as ContextMenu from "../context-menu";
|
|
@@ -12,13 +12,14 @@ import {useState} from "react";
|
|
|
12
12
|
|
|
13
13
|
export const ContextActionsMenu = ({
|
|
14
14
|
open,
|
|
15
|
-
onOpenChange =
|
|
15
|
+
onOpenChange = noop,
|
|
16
16
|
trigger,
|
|
17
17
|
children,
|
|
18
18
|
disabled,
|
|
19
19
|
mobileTitle,
|
|
20
20
|
supportsMobile,
|
|
21
21
|
autoFocusOnClose = true,
|
|
22
|
+
contentStyles,
|
|
22
23
|
}: ActionsMenuProps): JSX.Element => {
|
|
23
24
|
const isPhone = useIsPhone();
|
|
24
25
|
const [isOpen = false, setOpen] = useControllableState({value: open, onChange: onOpenChange});
|
|
@@ -31,6 +32,7 @@ export const ContextActionsMenu = ({
|
|
|
31
32
|
open={open}
|
|
32
33
|
onOpenChange={onOpenChange}
|
|
33
34
|
mobileTitle={mobileTitle}
|
|
35
|
+
contentStyles={contentStyles}
|
|
34
36
|
supportsMobile
|
|
35
37
|
// Extra div is important here to not loose the original onClick handler
|
|
36
38
|
trigger={<div>{trigger}</div>}
|
|
@@ -48,7 +50,10 @@ export const ContextActionsMenu = ({
|
|
|
48
50
|
{trigger}
|
|
49
51
|
</ContextMenu.Trigger>
|
|
50
52
|
<ContextMenu.Portal>
|
|
51
|
-
<ContextMenu.Content
|
|
53
|
+
<ContextMenu.Content
|
|
54
|
+
className={contentStyles}
|
|
55
|
+
onCloseAutoFocus={autoFocusOnClose ? undefined : preventDefault}
|
|
56
|
+
>
|
|
52
57
|
<ActionsMenuDangerousRowsProvider open={isOpen}>{children}</ActionsMenuDangerousRowsProvider>
|
|
53
58
|
</ContextMenu.Content>
|
|
54
59
|
</ContextMenu.Portal>
|
package/src/ai/model.tsx
CHANGED
package/src/ai/temperature.tsx
CHANGED
|
@@ -60,7 +60,6 @@ export const Temperature = ({initialValue, onChange}: Props) => {
|
|
|
60
60
|
<Tooltip
|
|
61
61
|
// props
|
|
62
62
|
title={`Click to change`}
|
|
63
|
-
// eslint-disable-next-line
|
|
64
63
|
description={`Model's temperature: ${temperature.toFixed(
|
|
65
64
|
2
|
|
66
65
|
)}. Temperature controls the degree of randomness in generated output. A lower temperature setting will result in more predictable and less creative outputs while a higher temperature setting will result in more unpredictable and more creative outputs.`}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {useSize} from "@fibery/react/src/use-size";
|
|
2
2
|
import React, {ComponentProps, forwardRef, useEffect, useRef, useState} from "react";
|
|
3
3
|
import {duration, transition} from "./design-system";
|
|
4
|
-
import
|
|
4
|
+
import noop from "lodash/noop";
|
|
5
5
|
import {useComposedRefs} from "@fibery/react/src/use-composed-refs";
|
|
6
6
|
|
|
7
7
|
type AnimatedHeightContainerProps = ComponentProps<"div"> & {
|
|
@@ -12,7 +12,7 @@ type AnimatedHeightContainerProps = ComponentProps<"div"> & {
|
|
|
12
12
|
|
|
13
13
|
export const AnimatedHeightContainer = forwardRef<HTMLDivElement, AnimatedHeightContainerProps>(
|
|
14
14
|
function AnimatedHeightContainerComponent(
|
|
15
|
-
{className, noAnimation = false, onTransitionStart =
|
|
15
|
+
{className, noAnimation = false, onTransitionStart = noop, onTransitionEnd = noop, children, ...otherProps},
|
|
16
16
|
ref
|
|
17
17
|
) {
|
|
18
18
|
const measuredContainer = useRef<HTMLDivElement | null>(null);
|
|
@@ -46,7 +46,7 @@ export const AnimatedHeightContainer = forwardRef<HTMLDivElement, AnimatedHeight
|
|
|
46
46
|
// Disable scroll so that overflowed contend won't show on focus
|
|
47
47
|
// https://stackoverflow.com/questions/67694101/overflowed-content-is-showing-on-focus
|
|
48
48
|
useEffect(() => {
|
|
49
|
-
let cleanup =
|
|
49
|
+
let cleanup = noop;
|
|
50
50
|
|
|
51
51
|
if (animating && containerRef.current) {
|
|
52
52
|
const element = containerRef.current;
|
package/src/antd/index.tsx
CHANGED
package/src/antd/input.tsx
CHANGED
|
@@ -4,7 +4,6 @@ import "antd/lib/input/style/css";
|
|
|
4
4
|
import {css} from "@linaria/core";
|
|
5
5
|
import {mobileRootSelector} from "../mobile-styles";
|
|
6
6
|
import {opacity, textStyles, themeVars} from "../design-system";
|
|
7
|
-
|
|
8
7
|
import {inputStyles} from "./styles";
|
|
9
8
|
import {wrapWith} from "./utils";
|
|
10
9
|
|
package/src/antd/styles.ts
CHANGED
|
@@ -3,16 +3,16 @@ import {border, layout, shadows, space, textStyles, themeVars, transition} from
|
|
|
3
3
|
|
|
4
4
|
const inputVariables = {
|
|
5
5
|
default: {
|
|
6
|
-
"--input-border": themeVars.inputBorderColor
|
|
7
|
-
"--input-hover-border": `0 0 0 1px ${themeVars.opacity.opacity40}`,
|
|
8
|
-
"--input-focus-border": `0 0 0 1px ${themeVars.opacity.
|
|
9
|
-
"--input-focus-shadow": `0 0 0
|
|
6
|
+
"--input-border": `${themeVars.inputBorderColor} inset`,
|
|
7
|
+
"--input-hover-border": `0 0 0 1px ${themeVars.opacity.opacity40} inset`,
|
|
8
|
+
"--input-focus-border": `0 0 0 1px ${themeVars.opacity.opacity50} inset`,
|
|
9
|
+
"--input-focus-shadow": `0 0 0 2px ${themeVars.focus}`,
|
|
10
10
|
},
|
|
11
11
|
error: {
|
|
12
|
-
"--input-border": `0 0 0 1px ${themeVars.warning}`,
|
|
13
|
-
"--input-hover-border": `0 0 0 1px ${themeVars.warning}`,
|
|
14
|
-
"--input-focus-border": `0 0 0 1px ${themeVars.warning}`,
|
|
15
|
-
"--input-focus-shadow": `0 0 0
|
|
12
|
+
"--input-border": `0 0 0 1px ${themeVars.warning} inset`,
|
|
13
|
+
"--input-hover-border": `0 0 0 1px ${themeVars.warning} inset`,
|
|
14
|
+
"--input-focus-border": `0 0 0 1px ${themeVars.warning} inset`,
|
|
15
|
+
"--input-focus-shadow": `0 0 0 2px ${themeVars.warning}`,
|
|
16
16
|
},
|
|
17
17
|
};
|
|
18
18
|
|
|
@@ -43,7 +43,7 @@ export const inputOverrides = {
|
|
|
43
43
|
transition: `box-shadow ${transition}`,
|
|
44
44
|
},
|
|
45
45
|
focus: {
|
|
46
|
-
boxShadow: `var(--input-focus-border, 0 0 0 1px ${themeVars.opacity.opacity25}) !important`,
|
|
46
|
+
boxShadow: `var(--input-focus-border, 0 0 0 1px ${themeVars.opacity.opacity25}), var(--input-focus-shadow) !important`,
|
|
47
47
|
transition: `box-shadow ${transition}`,
|
|
48
48
|
},
|
|
49
49
|
disabled: {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {css} from "@linaria/core";
|
|
2
|
-
import
|
|
3
|
-
import {FC,
|
|
2
|
+
import fromPairs from "lodash/fromPairs";
|
|
3
|
+
import {FC, lazy, Suspense} from "react";
|
|
4
4
|
import {a11yColor} from "./a11y-color";
|
|
5
5
|
import {AppIconWrapper} from "./app-icon-wrapper";
|
|
6
|
-
import {getOpacities,
|
|
6
|
+
import {getOpacities, iconSize, layout} from "./design-system";
|
|
7
7
|
import {Icon} from "./icons/Icon";
|
|
8
8
|
import {useTheme} from "./theme-provider";
|
|
9
9
|
import {useIsPhone} from "./use-is-phone";
|
|
@@ -89,7 +89,7 @@ type UglyExternalIconProps = Omit<UglyExternalIconImplProps, "appIconsLookup">;
|
|
|
89
89
|
|
|
90
90
|
const UglyExternalIcon = lazy(async () => {
|
|
91
91
|
const appIcons = await import("./appIcons.json");
|
|
92
|
-
const appIconsLookup =
|
|
92
|
+
const appIconsLookup = fromPairs(
|
|
93
93
|
appIcons.default.flatMap((appIcon) => appIcon.short_names.map((shortName) => [shortName, appIcon]))
|
|
94
94
|
);
|
|
95
95
|
|
|
@@ -128,7 +128,7 @@ export const AppIcon: FC<AppIconProps> = ({icon, color, isSelected, ...rest}) =>
|
|
|
128
128
|
const isPhone = useIsPhone();
|
|
129
129
|
const defaultIconSize = isPhone ? layout.mobileSidebarIconSize : layout.newMenuIconSize;
|
|
130
130
|
const {iconSize = defaultIconSize, containerSize = defaultIconSize} = rest;
|
|
131
|
-
const iconColor =
|
|
131
|
+
const iconColor = theme.select({
|
|
132
132
|
dark: a11yColor(getOpacities(color).opacity95, theme.menuBg, 5),
|
|
133
133
|
light: a11yColor(getOpacities(color).opacity95, theme.whiteColor, 3),
|
|
134
134
|
light2: a11yColor(getOpacities(color).opacity95, theme.menuBg, 5),
|
package/src/app-icon-wrapper.tsx
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {css} from "@linaria/core";
|
|
2
2
|
import cn from "classnames";
|
|
3
3
|
import {ReactNode} from "react";
|
|
4
|
-
import {border,
|
|
4
|
+
import {border, layout} from "./design-system";
|
|
5
5
|
import {useTheme} from "./theme-provider";
|
|
6
6
|
import {useIsPhone} from "./use-is-phone";
|
|
7
7
|
|
|
@@ -34,8 +34,7 @@ export const AppIconWrapper = ({
|
|
|
34
34
|
style={{backgroundColor: borderless ? "transparent" : color, width: containerSize, height: containerSize}}
|
|
35
35
|
className={cn(
|
|
36
36
|
appIconContainerStyle,
|
|
37
|
-
!borderless &&
|
|
38
|
-
getThemeValue(theme.mode, {light2: appIconGradientStyle, dark: appIconGradientStyle, light: null})
|
|
37
|
+
!borderless && theme.select({light2: appIconGradientStyle, dark: appIconGradientStyle, light: null})
|
|
39
38
|
)}
|
|
40
39
|
>
|
|
41
40
|
{children}
|
package/src/app-icon.tsx
CHANGED
|
@@ -3,7 +3,7 @@ import cx from "classnames";
|
|
|
3
3
|
import {FC} from "react";
|
|
4
4
|
import {a11yColor} from "./a11y-color";
|
|
5
5
|
import {AppIconWithFallback} from "./app-icon-with-fallback";
|
|
6
|
-
import {border, getOpacities
|
|
6
|
+
import {border, getOpacities} from "./design-system";
|
|
7
7
|
import {useTheme} from "./theme-provider";
|
|
8
8
|
|
|
9
9
|
interface AppIconProps {
|
|
@@ -16,7 +16,7 @@ interface AppIconProps {
|
|
|
16
16
|
|
|
17
17
|
export const AppIcon: FC<AppIconProps> = ({color, icon, containerSize = 54, iconSize = 36, className}) => {
|
|
18
18
|
const theme = useTheme();
|
|
19
|
-
const iconColor =
|
|
19
|
+
const iconColor = theme.select({
|
|
20
20
|
dark: a11yColor(getOpacities(color).opacity95, theme.menuBg, 5),
|
|
21
21
|
light: a11yColor(getOpacities(color).opacity95, theme.whiteColor, 3),
|
|
22
22
|
light2: a11yColor(getOpacities(color).opacity95, theme.menuBg, 5),
|
|
@@ -24,7 +24,7 @@ export const AppIcon: FC<AppIconProps> = ({color, icon, containerSize = 54, icon
|
|
|
24
24
|
|
|
25
25
|
const bgColor = theme.fns.getAppIconBackground(color);
|
|
26
26
|
|
|
27
|
-
const appIconGradientStyle =
|
|
27
|
+
const appIconGradientStyle = theme.select({
|
|
28
28
|
dark: "linear-gradient(180deg, rgba(255, 255, 255, 0.08), rgba(255, 255, 255, 0))",
|
|
29
29
|
light: "none",
|
|
30
30
|
light2: "linear-gradient(180deg, rgba(255, 255, 255, 0.08), rgba(255, 255, 255, 0))",
|
package/src/avatar.tsx
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {css} from "@linaria/core";
|
|
2
|
-
import
|
|
2
|
+
import memoize from "lodash/memoize";
|
|
3
3
|
import {CSSProperties, FC, memo, useCallback, useMemo, useState} from "react";
|
|
4
4
|
import {getDarkenColor, getObjectColorMemoized, textStyles, themeVars} from "./design-system";
|
|
5
5
|
import {FibermojiPlaceholder} from "./fibermoji-placeholder";
|
|
@@ -7,7 +7,7 @@ import {getShiftStyle} from "./icons/get-shift-style";
|
|
|
7
7
|
import {useFeatures} from "./features";
|
|
8
8
|
import {abbreviateName} from "./abbreviate-name";
|
|
9
9
|
|
|
10
|
-
export const getContainerStyle =
|
|
10
|
+
export const getContainerStyle = memoize((containerSize) => {
|
|
11
11
|
return {
|
|
12
12
|
width: containerSize,
|
|
13
13
|
height: containerSize,
|
|
@@ -22,7 +22,7 @@ const statusIconPositionByIndex = [
|
|
|
22
22
|
{top: 0, left: 0},
|
|
23
23
|
];
|
|
24
24
|
|
|
25
|
-
const getStatusIconStyle =
|
|
25
|
+
const getStatusIconStyle = memoize(
|
|
26
26
|
(size, index): CSSProperties => {
|
|
27
27
|
const iconSize = Math.ceil(size / 2);
|
|
28
28
|
const position = statusIconPositionByIndex[index];
|
|
@@ -139,7 +139,6 @@ export const BaseButton = forwardRef<HTMLButtonElement, BaseButtonProps>(
|
|
|
139
139
|
data-variant={variant}
|
|
140
140
|
className={cx(reset, baseButton, className)}
|
|
141
141
|
ref={ref}
|
|
142
|
-
// eslint-disable-next-line react/button-has-type
|
|
143
142
|
type={type}
|
|
144
143
|
{...buttonProps}
|
|
145
144
|
>
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// so it's easier to find buttons with custom colors
|
|
4
4
|
|
|
5
5
|
import {CSSProperties} from "@linaria/core";
|
|
6
|
-
import {getDarkenColor, getOpacities,
|
|
6
|
+
import {getDarkenColor, getOpacities, ThemeColors, themeVars} from "../design-system";
|
|
7
7
|
import {ButtonVariant} from "./base-button";
|
|
8
8
|
|
|
9
9
|
export const makeButtonColors = (color: string, variant: ButtonVariant, theme: ThemeColors): CSSProperties => {
|
|
@@ -40,7 +40,7 @@ export const makeButtonColors = (color: string, variant: ButtonVariant, theme: T
|
|
|
40
40
|
|
|
41
41
|
return {
|
|
42
42
|
"--fibery-button-color": bgColor,
|
|
43
|
-
"--fibery-button-hover-color":
|
|
43
|
+
"--fibery-button-hover-color": theme.select({
|
|
44
44
|
light: getOpacities(color).opacity30,
|
|
45
45
|
dark: getOpacities(color).opacity45,
|
|
46
46
|
}),
|
package/src/checkbox.tsx
CHANGED
|
@@ -127,7 +127,7 @@ const checkmarkStyle = css`
|
|
|
127
127
|
opacity: 0;
|
|
128
128
|
transition: transform 0.2s, opacity 0.2s;
|
|
129
129
|
pointer-events: none;
|
|
130
|
-
color: ${themeVars.
|
|
130
|
+
color: ${themeVars.whiteColor};
|
|
131
131
|
width: ${layout.checkboxSize}px;
|
|
132
132
|
height: ${layout.checkboxSize}px;
|
|
133
133
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {css, cx} from "@linaria/core";
|
|
2
2
|
import ArrowBottom from "./icons/react/ArrowBottom";
|
|
3
3
|
import ArrowTop from "./icons/react/ArrowTop";
|
|
4
|
-
import {ReactNode, useCallback} from "react";
|
|
4
|
+
import {ReactNode, useCallback, useEffect, useRef} from "react";
|
|
5
5
|
import {useControllableState} from "@fibery/react/src/use-controllable-state";
|
|
6
6
|
import {space} from "./design-system";
|
|
7
7
|
|
|
@@ -48,6 +48,16 @@ export const CollapsibleSection = ({
|
|
|
48
48
|
|
|
49
49
|
const onToggle = useCallback(() => setIsCollapsed(!isCollapsed), [isCollapsed, setIsCollapsed]);
|
|
50
50
|
|
|
51
|
+
// Ugly one-time auto-expand logic, in case of collapsedDefault is changed from false to true shortly after render
|
|
52
|
+
// (i.e. when something is loaded asynchronously)
|
|
53
|
+
const expandedOnce = useRef(false);
|
|
54
|
+
useEffect(() => {
|
|
55
|
+
if (isCollapsed && !collapsedDefault && !expandedOnce.current) {
|
|
56
|
+
expandedOnce.current = true;
|
|
57
|
+
setIsCollapsed(false);
|
|
58
|
+
}
|
|
59
|
+
}, [isCollapsed, collapsedDefault, setIsCollapsed]);
|
|
60
|
+
|
|
51
61
|
const collapsibleHeader = (
|
|
52
62
|
<div
|
|
53
63
|
tabIndex={0}
|
package/src/color-utils.test.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/* eslint-disable max-lines */
|
|
2
1
|
import {
|
|
3
2
|
fromHSL,
|
|
4
3
|
fromOKLCH,
|
|
@@ -8,32 +7,31 @@ import {
|
|
|
8
7
|
getHsl,
|
|
9
8
|
getLuminance,
|
|
10
9
|
isValidColor,
|
|
11
|
-
OKLCH,
|
|
12
|
-
produceColor,
|
|
13
10
|
toCss,
|
|
11
|
+
toOKLCH,
|
|
14
12
|
} from "./color-utils";
|
|
15
13
|
|
|
16
14
|
describe("color-utils", () => {
|
|
17
15
|
describe("css", () => {
|
|
18
16
|
it("normalizes hex to rgb", () => {
|
|
19
|
-
expect(toCss("#ff0000")).
|
|
17
|
+
expect(toCss("#ff0000")).toMatchInlineSnapshot(`"rgb(255,0,0)"`);
|
|
20
18
|
});
|
|
21
19
|
|
|
22
20
|
it("normalizes named colors to rgb", () => {
|
|
23
|
-
expect(toCss("red")).
|
|
24
|
-
expect(toCss("blue")).
|
|
21
|
+
expect(toCss("red")).toMatchInlineSnapshot(`"rgb(255,0,0)"`);
|
|
22
|
+
expect(toCss("blue")).toMatchInlineSnapshot(`"rgb(0,0,255)"`);
|
|
25
23
|
});
|
|
26
24
|
|
|
27
25
|
it("preserves alpha in rgba", () => {
|
|
28
|
-
expect(toCss("rgba(255, 0, 0, 0.5)")).
|
|
26
|
+
expect(toCss("rgba(255, 0, 0, 0.5)")).toMatchInlineSnapshot(`"rgba(255,0,0,0.5)"`);
|
|
29
27
|
});
|
|
30
28
|
|
|
31
29
|
it("converts hsl to rgb", () => {
|
|
32
|
-
expect(toCss("hsl(0, 100%, 50%)")).
|
|
30
|
+
expect(toCss("hsl(0, 100%, 50%)")).toMatchInlineSnapshot(`"rgb(255,0,0)"`);
|
|
33
31
|
});
|
|
34
32
|
|
|
35
33
|
it("returns fallback for invalid color", () => {
|
|
36
|
-
expect(toCss("invalid")).
|
|
34
|
+
expect(toCss("invalid")).toMatchInlineSnapshot(`"rgb(73,120,212)"`);
|
|
37
35
|
});
|
|
38
36
|
});
|
|
39
37
|
|
|
@@ -99,12 +97,12 @@ describe("color-utils", () => {
|
|
|
99
97
|
describe("toCss", () => {
|
|
100
98
|
it("converts to rgb for opaque colors", () => {
|
|
101
99
|
const result = toCss("#ff0000");
|
|
102
|
-
expect(result).
|
|
100
|
+
expect(result).toMatchInlineSnapshot(`"rgb(255,0,0)"`);
|
|
103
101
|
});
|
|
104
102
|
|
|
105
103
|
it("converts to rgba for colors with alpha", () => {
|
|
106
104
|
const result = toCss("rgba(255, 0, 0, 0.5)");
|
|
107
|
-
expect(result).
|
|
105
|
+
expect(result).toMatchInlineSnapshot(`"rgba(255,0,0,0.5)"`);
|
|
108
106
|
});
|
|
109
107
|
});
|
|
110
108
|
|
|
@@ -295,23 +293,15 @@ describe("color-utils", () => {
|
|
|
295
293
|
|
|
296
294
|
describe("produceColor", () => {
|
|
297
295
|
it("outputs oklch format when OKLCH space is specified", () => {
|
|
298
|
-
expect(
|
|
299
|
-
expect(
|
|
300
|
-
expect(
|
|
301
|
-
`"oklch(61.517% 0.21082 256.1)"`
|
|
302
|
-
);
|
|
296
|
+
expect(toOKLCH("#ff0000")).toMatchInlineSnapshot(`"oklch(62.796% 0.25768 29.234)"`);
|
|
297
|
+
expect(toOKLCH("rgb(0, 128, 255)")).toMatchInlineSnapshot(`"oklch(61.517% 0.21082 256.1)"`);
|
|
298
|
+
expect(toOKLCH("oklch(61.517% 0.21082 256.1)")).toMatchInlineSnapshot(`"oklch(61.517% 0.21082 256.1)"`);
|
|
303
299
|
});
|
|
304
300
|
|
|
305
301
|
it("parses display-p3 colors correctly (P3 space removed for bundle size)", () => {
|
|
306
|
-
expect(
|
|
307
|
-
|
|
308
|
-
);
|
|
309
|
-
expect(produceColor("color(display-p3 0.995 0.99 0.922)", [], OKLCH)).toMatchInlineSnapshot(
|
|
310
|
-
`"oklch(98.841% 0.02505 102.92)"`
|
|
311
|
-
);
|
|
312
|
-
expect(produceColor("color(display-p3 0.997 0.982 0.749)", [], OKLCH)).toMatchInlineSnapshot(
|
|
313
|
-
`"oklch(97.402% 0.08449 104.36)"`
|
|
314
|
-
);
|
|
302
|
+
expect(toOKLCH("color(display-p3 0.992 0.992 0.978)")).toMatchInlineSnapshot(`"oklch(99.285% 0.00516 106.49)"`);
|
|
303
|
+
expect(toOKLCH("color(display-p3 0.995 0.99 0.922)")).toMatchInlineSnapshot(`"oklch(98.841% 0.02505 102.92)"`);
|
|
304
|
+
expect(toOKLCH("color(display-p3 0.997 0.982 0.749)")).toMatchInlineSnapshot(`"oklch(97.402% 0.08449 104.36)"`);
|
|
315
305
|
});
|
|
316
306
|
});
|
|
317
307
|
});
|