@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.
Files changed (174) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/eslint.config.mjs +16 -0
  3. package/package.json +11 -13
  4. package/src/a11y-color.test.ts +162 -0
  5. package/src/a11y-color.ts +13 -20
  6. package/src/actions-menu/actions-menu-item.tsx +9 -12
  7. package/src/actions-menu/context-actions-menu.tsx +8 -3
  8. package/src/ai/model.tsx +0 -1
  9. package/src/ai/temperature.tsx +0 -1
  10. package/src/animated-height-container.tsx +3 -3
  11. package/src/antd/ant-modal.tsx +10 -5
  12. package/src/antd/index.tsx +3 -0
  13. package/src/antd/input.tsx +0 -1
  14. package/src/antd/styles.ts +15 -15
  15. package/src/app-icon-with-fallback.tsx +6 -6
  16. package/src/app-icon-wrapper.tsx +2 -3
  17. package/src/app-icon.tsx +4 -4
  18. package/src/avatar.tsx +3 -3
  19. package/src/button/base-button.tsx +0 -1
  20. package/src/button/button.tsx +1 -0
  21. package/src/button/make-button-colors.ts +5 -13
  22. package/src/checkbox.tsx +2 -2
  23. package/src/collapsible-section.tsx +11 -1
  24. package/src/color-picker/ColorPickerOrLoader.js +2 -2
  25. package/src/color-utils.test.ts +307 -0
  26. package/src/color-utils.ts +215 -0
  27. package/src/command-menu/index.tsx +1 -0
  28. package/src/comment.tsx +3 -2
  29. package/src/context-menu/index.tsx +12 -7
  30. package/src/date-picker/contexts.ts +2 -2
  31. package/src/date-picker/date-range-picker.tsx +3 -4
  32. package/src/date-picker/single-date-picker.tsx +147 -119
  33. package/src/date-picker/types.ts +4 -3
  34. package/src/day-select/iso-week-day-select.tsx +2 -2
  35. package/src/day-select/week-day-select.tsx +2 -2
  36. package/src/delayed.tsx +0 -1
  37. package/src/design-system/alpha.test.ts +59 -0
  38. package/src/design-system/alpha.ts +41 -0
  39. package/src/design-system/animation.ts +10 -0
  40. package/src/design-system/colors-css.test.ts +39 -0
  41. package/src/design-system/colors-css.ts +25 -0
  42. package/src/design-system/colors-js.test.ts +232 -0
  43. package/src/design-system/colors-js.ts +107 -0
  44. package/src/design-system/colors.test.ts +74 -0
  45. package/src/design-system/colors.ts +759 -0
  46. package/src/design-system/date.ts +3 -0
  47. package/src/design-system/layout.ts +106 -0
  48. package/src/design-system/theme.test.ts +94 -0
  49. package/src/design-system/theme.ts +93 -0
  50. package/src/design-system/typography.ts +179 -0
  51. package/src/design-system/vars.test.ts +1679 -0
  52. package/src/design-system/vars.ts +52 -0
  53. package/src/design-system.test.ts +45 -22
  54. package/src/design-system.ts +25 -1339
  55. package/src/dropdown-menu/index.tsx +21 -16
  56. package/src/emoji-picker/app-icon-picker.tsx +5 -5
  57. package/src/emoji-picker/emoji-picker-content-with-color.tsx +4 -4
  58. package/src/emoji-picker/icon-emoji-picker.tsx +3 -3
  59. package/src/favorites-icon.tsx +1 -1
  60. package/src/fibermoji-placeholder.tsx +3 -3
  61. package/src/field-container.tsx +11 -2
  62. package/src/file-item/file-icon.tsx +169 -0
  63. package/src/file-item/file-menu-items.tsx +68 -0
  64. package/src/file-item/file-preview-actions.tsx +38 -0
  65. package/src/file-item/file-title.tsx +48 -0
  66. package/src/file-item/types.ts +27 -0
  67. package/src/file-item/use-register-in-image-gallery.tsx +70 -0
  68. package/src/file-item-2.tsx +32 -348
  69. package/src/file-item.tsx +6 -3
  70. package/src/hue-shift.test.ts +91 -0
  71. package/src/icons/ast/ChatBubble.ts +8 -0
  72. package/src/icons/ast/ChatFloat.ts +8 -0
  73. package/src/icons/ast/ChatSidebar.ts +8 -0
  74. package/src/icons/ast/FileCounter.ts +8 -0
  75. package/src/icons/ast/FileMultiple.ts +8 -0
  76. package/src/icons/ast/FileOther.ts +8 -0
  77. package/src/icons/ast/NoBorder.ts +8 -0
  78. package/src/icons/ast/NoFill.ts +8 -0
  79. package/src/icons/ast/ValueEdit.ts +8 -0
  80. package/src/icons/ast/index.tsx +9 -0
  81. package/src/icons/react/ChatBubble.tsx +13 -0
  82. package/src/icons/react/ChatFloat.tsx +13 -0
  83. package/src/icons/react/ChatSidebar.tsx +13 -0
  84. package/src/icons/react/FileCounter.tsx +13 -0
  85. package/src/icons/react/FileMultiple.tsx +13 -0
  86. package/src/icons/react/FileOther.tsx +13 -0
  87. package/src/icons/react/NoBorder.tsx +13 -0
  88. package/src/icons/react/NoFill.tsx +13 -0
  89. package/src/icons/react/ValueEdit.tsx +13 -0
  90. package/src/icons/react/index.tsx +9 -0
  91. package/src/icons/svg/chat-bubble.svg +4 -0
  92. package/src/icons/svg/chat-float.svg +4 -0
  93. package/src/icons/svg/chat-sidebar.svg +4 -0
  94. package/src/icons/svg/file-counter.svg +3 -0
  95. package/src/icons/svg/file-multiple.svg +3 -0
  96. package/src/icons/svg/file-other.svg +3 -0
  97. package/src/icons/svg/no-border.svg +17 -0
  98. package/src/icons/svg/no-fill.svg +4 -0
  99. package/src/icons/svg/value-edit.svg +3 -0
  100. package/src/images-gallery/images-gallery.tsx +8 -6
  101. package/src/images-gallery/slide-buttons.tsx +4 -11
  102. package/src/is-iOS.ts +0 -1
  103. package/src/is-in-popup.ts +2 -1
  104. package/src/lists/actions-menu-row-surface.tsx +7 -7
  105. package/src/loading-sausage.tsx +2 -2
  106. package/src/media-query-utils.ts +1 -2
  107. package/src/mobile-keyboard-aware-popup.tsx +6 -5
  108. package/src/modal-menu/modal-menu-content.tsx +2 -2
  109. package/src/number-input/decimal.js +9 -7
  110. package/src/number-input/{number-inline-input-with-autosize.tsx → number-input-inline-with-autosize.tsx} +20 -41
  111. package/src/number-input/number-input-inline.tsx +118 -0
  112. package/src/number-input/{index.test.js → number-input.test.tsx} +38 -43
  113. package/src/number-input/number-input.tsx +63 -121
  114. package/src/number-input/types.ts +19 -0
  115. package/src/number-input/utils.ts +61 -0
  116. package/src/online-users.tsx +2 -2
  117. package/src/palette-generator.test.ts +309 -0
  118. package/src/palette-generator.ts +160 -0
  119. package/src/palettes/_.ts +72 -0
  120. package/src/palettes/slate-arch.colors-snapshot.test.ts +1689 -0
  121. package/src/palettes/slate-arch.ts +188 -0
  122. package/src/palettes/slate-user.colors-snapshot.test.ts +1689 -0
  123. package/src/palettes/slate-user.ts +187 -0
  124. package/src/palettes/warm-arch.colors-snapshot.test.ts +1689 -0
  125. package/src/palettes/warm-arch.ts +222 -0
  126. package/src/palettes/warm-user.colors-snapshot.test.ts +1689 -0
  127. package/src/palettes/warm-user.ts +222 -0
  128. package/src/platform.ts +0 -3
  129. package/src/popover/get-element-ref.ts +28 -0
  130. package/src/popover/index.tsx +236 -339
  131. package/src/popover/{mobile-popup-context.tsx → mobile-popover-context.tsx} +7 -7
  132. package/src/popover/mobile-popover.tsx +169 -0
  133. package/src/popover/modifiers.tsx +2 -2
  134. package/src/popover/popup-stack-context.tsx +8 -9
  135. package/src/progress.tsx +2 -2
  136. package/src/reactions/reaction-button.tsx +12 -6
  137. package/src/root-theme-provider.test.tsx +411 -0
  138. package/src/scale-generator.ts +356 -0
  139. package/src/select/components/menu-list-virtualized.tsx +12 -25
  140. package/src/select/components/menu.tsx +12 -2
  141. package/src/select/index.tsx +6 -5
  142. package/src/select/select.tsx +38 -39
  143. package/src/select/styles.ts +0 -1
  144. package/src/select/util.ts +1 -1
  145. package/src/static-palettes.ts +356 -0
  146. package/src/thematic-color-picker.tsx +266 -0
  147. package/src/thematic-constants.tsx +27 -0
  148. package/src/thematic-controls.tsx +144 -0
  149. package/src/thematic-scales.tsx +122 -0
  150. package/src/thematic-state.ts +370 -0
  151. package/src/thematic.tsx +386 -0
  152. package/src/theme-provider.test.tsx +820 -0
  153. package/src/theme-provider.tsx +158 -92
  154. package/src/theme-settings.ts +67 -12
  155. package/src/theme-styles.ts +58 -6
  156. package/src/toast/toast-action.tsx +1 -1
  157. package/src/toast/toast.tsx +1 -2
  158. package/src/toggle-on-off.tsx +2 -2
  159. package/src/toggle.tsx +7 -8
  160. package/src/tooltip.tsx +14 -10
  161. package/src/type-badge.tsx +7 -14
  162. package/src/unit/styles.ts +2 -25
  163. package/src/unit/unit-with-tooltip.tsx +3 -2
  164. package/src/use-is-phone.tsx +7 -2
  165. package/src/use-long-press.tsx +2 -2
  166. package/src/use-on-screen-keyboard-data.tsx +2 -2
  167. package/src/with-data.tsx +4 -3
  168. package/src/workflow-progress-icon.tsx +2 -2
  169. package/.eslintignore +0 -3
  170. package/.eslintrc +0 -14
  171. package/src/__mocks__/createInlineTheme.js +0 -3
  172. package/src/create-inline-theme.ts +0 -66
  173. package/src/number-input/index.js +0 -191
  174. package/src/palette.ts +0 -237
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # @fibery/ui-kit
2
2
 
3
+ ## 1.41.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 6139f68: ThemePalette, design-system restructuring
8
+
9
+ ## 1.40.4
10
+
11
+ ### Patch Changes
12
+
13
+ - Updated dependencies [16959b0]
14
+ - @fibery/helpers@1.4.0
15
+ - @fibery/react@1.4.7
16
+
3
17
  ## 1.40.3
4
18
 
5
19
  ### Patch Changes
@@ -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.40.3",
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",
@@ -19,13 +20,12 @@
19
20
  "@types/d3-shape": "^3.1.6",
20
21
  "@types/react-select-country-list": "^2.2.3",
21
22
  "@types/setimmediate": "^1.0.4",
22
- "@types/ua-parser-js": "0.7.36",
23
23
  "antd": "4.24.7",
24
- "chroma-js": "2.1.2",
25
- "chrono-node": "^2.7.5",
24
+ "chrono-node": "^2.9.0",
26
25
  "classnames": "2.3.1",
27
26
  "cmdk": "1.0.0",
28
27
  "color-hash": "1.0.3",
28
+ "colorjs.io": "0.6.1",
29
29
  "d3-shape": "1.3.7",
30
30
  "date-fns": "2.29.2",
31
31
  "invariant": "2.2.4",
@@ -43,13 +43,12 @@
43
43
  "react-popper": "2.3.0",
44
44
  "react-select": "5.3.2",
45
45
  "react-select-country-list": "2.2.1",
46
- "react-virtuoso": "4.14.1",
46
+ "react-virtuoso": "4.18.1",
47
47
  "screenfull": "6.0.2",
48
48
  "tabbable": "5.2.1",
49
- "ua-parser-js": "1.0.39",
50
49
  "@fibery/emoji-data": "2.7.1",
51
- "@fibery/helpers": "1.3.4",
52
- "@fibery/react": "1.4.6"
50
+ "@fibery/helpers": "1.4.0",
51
+ "@fibery/react": "1.4.7"
53
52
  },
54
53
  "peerDependencies": {
55
54
  "react": "18.3.1",
@@ -62,7 +61,6 @@
62
61
  "@testing-library/jest-dom": "6.9.1",
63
62
  "@testing-library/react": "16.3.1",
64
63
  "@testing-library/user-event": "14.6.1",
65
- "@types/chroma-js": "2.1.3",
66
64
  "@types/color-hash": "1.0.2",
67
65
  "@types/history": "4.7.11",
68
66
  "@types/invariant": "2.2.34",
@@ -84,7 +82,7 @@
84
82
  "typescript": "5.9.3",
85
83
  "unist-util-reduce": "0.2.2",
86
84
  "@fibery/babel-preset": "7.4.1",
87
- "@fibery/eslint-config": "8.6.2"
85
+ "@fibery/eslint-config": "9.0.0"
88
86
  },
89
87
  "jest": {
90
88
  "testEnvironment": "jsdom",
@@ -100,8 +98,7 @@
100
98
  "cobertura"
101
99
  ],
102
100
  "moduleNameMapper": {
103
- "\\.(css)$": "<rootDir>/src/__mocks__/styleMock.js",
104
- "createInlineTheme\\.js$": "<rootDir>/src/__mocks__/createInlineTheme.js"
101
+ "\\.(css)$": "<rootDir>/src/__mocks__/styleMock.js"
105
102
  },
106
103
  "transform": {
107
104
  "^.+\\.(js|jsx|ts|tsx)$": [
@@ -132,6 +129,7 @@
132
129
  "test:ci": "pnpm run test --reporters=default --reporters=jest-junit",
133
130
  "test:coverage": "pnpm run test --coverage --coverageDirectory=${JEST_COVERAGE_RESULT_DIR:-$(pwd)}/coverage/ui-kit --reporters=default --reporters=jest-junit",
134
131
  "lint": "eslint .",
135
- "generate-icons": "node scripts/generate-icons.mjs"
132
+ "generate-icons": "node scripts/generate-icons.mjs",
133
+ "typecheck": "tsc --noEmit"
136
134
  }
137
135
  }
@@ -0,0 +1,162 @@
1
+ import {a11yColor} from "./a11y-color";
2
+
3
+ describe("a11yColor", () => {
4
+ describe("returns original color when", () => {
5
+ it("color already passes contrast on light background", () => {
6
+ // Dark blue on white should already pass
7
+ const result = a11yColor("#000080", "#ffffff");
8
+ expect(result).toMatchInlineSnapshot(`"rgb(0,0,128)"`);
9
+ });
10
+
11
+ it("color already passes contrast on dark background", () => {
12
+ // White on black should already pass
13
+ const result = a11yColor("#ffffff", "#000000");
14
+ expect(result).toMatchInlineSnapshot(`"rgb(255,255,255)"`);
15
+ });
16
+
17
+ it("invalid toMakeA11y color is provided", () => {
18
+ const result = a11yColor("invalid-color", "#ffffff");
19
+ expect(result).toMatchInlineSnapshot(`"invalid-color"`);
20
+ });
21
+
22
+ it("invalid background color is provided", () => {
23
+ const result = a11yColor("#ff0000", "invalid-bg");
24
+ expect(result).toMatchInlineSnapshot(`"#ff0000"`);
25
+ });
26
+
27
+ it("transparent is provided as toMakeA11y", () => {
28
+ const result = a11yColor("transparent", "#ffffff");
29
+ expect(result).toMatchInlineSnapshot(`"transparent"`);
30
+ });
31
+
32
+ it("transparent is provided as background", () => {
33
+ const result = a11yColor("#ff0000", "transparent");
34
+ expect(result).toMatchInlineSnapshot(`"#ff0000"`);
35
+ });
36
+ });
37
+
38
+ describe("adjusts colors for contrast", () => {
39
+ it("makes light color darker on white background", () => {
40
+ // Light yellow on white needs to be darker
41
+ const result = a11yColor("#ffff00", "#ffffff");
42
+ expect(result).toMatchInlineSnapshot(`"rgb(154,154,0)"`);
43
+ });
44
+
45
+ it("makes dark color lighter on black background", () => {
46
+ // Dark blue on black needs to be lighter
47
+ const result = a11yColor("#000033", "#000000");
48
+ expect(result).toMatchInlineSnapshot(`"rgb(49,49,255)"`);
49
+ });
50
+
51
+ it("handles medium colors on light backgrounds", () => {
52
+ // Medium gray on white
53
+ const result = a11yColor("#808080", "#ffffff");
54
+ expect(result).toMatchInlineSnapshot(`"rgb(128,128,128)"`);
55
+ });
56
+
57
+ it("handles medium colors on dark backgrounds", () => {
58
+ // Medium gray on black
59
+ const result = a11yColor("#808080", "#000000");
60
+ expect(result).toMatchInlineSnapshot(`"rgb(128,128,128)"`);
61
+ });
62
+ });
63
+
64
+ describe("respects minimum contrast ratio", () => {
65
+ it("uses default 3.0 contrast ratio", () => {
66
+ const result = a11yColor("#cccccc", "#ffffff");
67
+ expect(result).toMatchInlineSnapshot(`"rgb(148,148,148)"`);
68
+ });
69
+
70
+ it("adjusts for higher contrast ratio (4.5 WCAG AA)", () => {
71
+ const result = a11yColor("#cccccc", "#ffffff", 4.5);
72
+ expect(result).toMatchInlineSnapshot(`"rgb(118,118,118)"`);
73
+ });
74
+
75
+ it("adjusts for highest contrast ratio (7.0 WCAG AAA)", () => {
76
+ const result = a11yColor("#cccccc", "#ffffff", 7.0);
77
+ expect(result).toMatchInlineSnapshot(`"rgb(89,89,89)"`);
78
+ });
79
+ });
80
+
81
+ describe("handles various color formats", () => {
82
+ it("handles 3-digit hex colors", () => {
83
+ const result = a11yColor("#f00", "#fff");
84
+ expect(result).toMatchInlineSnapshot(`"rgb(255,0,0)"`);
85
+ });
86
+
87
+ it("handles 6-digit hex colors", () => {
88
+ const result = a11yColor("#ff0000", "#ffffff");
89
+ expect(result).toMatchInlineSnapshot(`"rgb(255,0,0)"`);
90
+ });
91
+
92
+ it("handles rgb() colors", () => {
93
+ const result = a11yColor("rgb(255, 0, 0)", "#ffffff");
94
+ expect(result).toMatchInlineSnapshot(`"rgb(255,0,0)"`);
95
+ });
96
+
97
+ it("handles named colors", () => {
98
+ const result = a11yColor("red", "white");
99
+ expect(result).toMatchInlineSnapshot(`"rgb(255,0,0)"`);
100
+ });
101
+
102
+ it("handles hsl() colors", () => {
103
+ const result = a11yColor("hsl(0, 100%, 50%)", "#ffffff");
104
+ expect(result).toMatchInlineSnapshot(`"rgb(255,0,0)"`);
105
+ });
106
+ });
107
+
108
+ describe("real-world use cases", () => {
109
+ it("brand green on white background", () => {
110
+ const result = a11yColor("#69AC5E", "#ffffff");
111
+ expect(result).toMatchInlineSnapshot(`"rgb(96,164,85)"`);
112
+ });
113
+
114
+ it("brand blue on white background", () => {
115
+ const result = a11yColor("#4978D4", "#ffffff");
116
+ expect(result).toMatchInlineSnapshot(`"rgb(73,120,212)"`);
117
+ });
118
+
119
+ it("light text on dark theme background", () => {
120
+ const result = a11yColor("#aaaaaa", "#1a1a1a");
121
+ expect(result).toMatchInlineSnapshot(`"rgb(170,170,170)"`);
122
+ });
123
+
124
+ it("card type colors on white", () => {
125
+ const cardColors = [
126
+ "#F0D0DD",
127
+ "#F5D3CA",
128
+ "#FAE0B7",
129
+ "#FCEAA2",
130
+ "#E3ECAB",
131
+ "#CFEFC8",
132
+ "#C1F3DF",
133
+ "#C1EDF5",
134
+ "#C1E0F5",
135
+ "#C7D6F9",
136
+ "#D8D3F5",
137
+ "#E8D1EF",
138
+ "#E6DFDA",
139
+ "#D2D2D2",
140
+ "#FFFF8D",
141
+ ];
142
+
143
+ expect(cardColors.map((color) => a11yColor(color, "#ffffff"))).toEqual([
144
+ "rgb(212,120,158)",
145
+ "rgb(224,119,91)",
146
+ "rgb(207,132,14)",
147
+ "rgb(180,145,6)",
148
+ "rgb(140,157,36)",
149
+ "rgb(71,169,49)",
150
+ "rgb(33,169,115)",
151
+ "rgb(30,162,186)",
152
+ "rgb(57,156,223)",
153
+ "rgb(107,146,239)",
154
+ "rgb(150,137,228)",
155
+ "rgb(189,124,209)",
156
+ "rgb(169,144,127)",
157
+ "rgb(148,148,148)",
158
+ "rgb(154,154,0)",
159
+ ]);
160
+ });
161
+ });
162
+ });
package/src/a11y-color.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  // https://github.com/alex-page/a11ycolor
2
- import chroma from "chroma-js";
2
+ import {fromHSL, getContrastRatio, getHsl, isValidColor, toCss} from "./color-utils";
3
3
 
4
4
  class LRUCache<TKey, TValue> {
5
5
  #capacity: number;
@@ -41,12 +41,7 @@ const checkColor = (colorValue: string) => {
41
41
  if (colorValue === "transparent") {
42
42
  return false;
43
43
  }
44
-
45
- try {
46
- return chroma.valid(colorValue);
47
- } catch (error) {
48
- return false;
49
- }
44
+ return isValidColor(colorValue);
50
45
  };
51
46
 
52
47
  /**
@@ -58,10 +53,10 @@ const checkColor = (colorValue: string) => {
58
53
  *
59
54
  * @return {string} - The closest hex color for `toMakeA11y` on `background`
60
55
  */
61
- export function a11yColor(toMakeA11y: string, background: string, minimumContrast = 3.0) {
56
+ export function a11yColor(toMakeA11y: string, background: string, minimumContrast = 3.0): string {
62
57
  const key = toMakeA11y + background + minimumContrast;
63
58
  if (cache.has(key)) {
64
- return cache.get(key);
59
+ return cache.get(key)!;
65
60
  }
66
61
  if (!checkColor(toMakeA11y) || !checkColor(background)) {
67
62
  cache.put(key, toMakeA11y);
@@ -71,23 +66,21 @@ export function a11yColor(toMakeA11y: string, background: string, minimumContras
71
66
  if (minimumContrast < 0 && minimumContrast > 21) {
72
67
  throw new Error(`Minimum contrast must be a number between 0 and 21. It was ${minimumContrast}`);
73
68
  }
74
- const a11y = chroma(toMakeA11y);
75
- const bg = chroma(background);
76
69
 
77
70
  // Check the ratio straight away, if it passes return the value as hex
78
- if (chroma.contrast(background, toMakeA11y) >= minimumContrast) {
79
- const val = a11y.hex();
71
+ if (getContrastRatio(background, toMakeA11y) >= minimumContrast) {
72
+ const val = toCss(toMakeA11y);
80
73
  cache.put(key, val);
81
74
  return val;
82
75
  }
83
76
 
84
77
  // Ratio didn't pass so we need to find the nearest color
85
- const a11yHSL = a11y.hsl();
78
+ const a11yHSL = getHsl(toMakeA11y);
86
79
  const a11yLightness = a11yHSL[2] * 100;
87
80
  const minHexDiff = 100 / 255; // 255 Colors / 100% HSL
88
81
 
89
- const isBlackBgContrast = chroma.contrast(background, "#000") >= minimumContrast;
90
- const isWhiteBgContrast = chroma.contrast(background, "#FFF") >= minimumContrast;
82
+ const isBlackBgContrast = getContrastRatio(background, "#000") >= minimumContrast;
83
+ const isWhiteBgContrast = getContrastRatio(background, "#FFF") >= minimumContrast;
91
84
  let minLightness = 0;
92
85
  let maxLightness = 100;
93
86
  let isDarkColor = false;
@@ -117,19 +110,19 @@ export function a11yColor(toMakeA11y: string, background: string, minimumContras
117
110
  // Binary search until we find the colour that meets contrast
118
111
  while (!foundColor) {
119
112
  const midLightness = (minLightness + maxLightness) / 2;
120
- const midA11y = chroma.hsl(a11yHSL[0], a11yHSL[1], midLightness / 100);
113
+ const midA11yHex = fromHSL(a11yHSL[0], a11yHSL[1], midLightness / 100);
121
114
 
122
115
  // Give up if we are stuck
123
116
  if (Math.abs(maxLightness - minLightness) < 0.01) {
124
- foundColor = midA11y.hex();
117
+ foundColor = midA11yHex;
125
118
  break;
126
119
  }
127
120
 
128
121
  // The colour meets contrast
129
- if (chroma.contrast(midA11y.hex(), bg) >= minimumContrast) {
122
+ if (getContrastRatio(midA11yHex, background) >= minimumContrast) {
130
123
  // It is the minimal lightness range for one hexadecimal
131
124
  if (maxLightness - minLightness <= minHexDiff) {
132
- foundColor = midA11y.hex();
125
+ foundColor = midA11yHex;
133
126
  } else if (isDarkColor) {
134
127
  // If it is going to be a dark color move the min to mid
135
128
  minLightness = midLightness;
@@ -2,7 +2,7 @@ import {stopPropagation} from "@fibery/react/src/stop-propagation";
2
2
  import {useCallbackRef} from "@fibery/react/src/use-callback-ref";
3
3
  import {css, cx} from "@linaria/core";
4
4
  import {FunctionComponent, memo, ReactNode, useId} from "react";
5
- import {border, colors, layout, layoutVars, lineHeight, space, textStyles, themeVars} from "../design-system";
5
+ import {border, layout, layoutVars, lineHeight, space, textStyles, themeVars} from "../design-system";
6
6
  import CheckedIcon from "../icons/react/Checked";
7
7
  import {IconBaseProps} from "../icons/types";
8
8
  import {Spinner} from "../loaders";
@@ -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 _ from "lodash";
15
+ import noop from "lodash/noop";
16
16
 
17
17
  const hiddenTextCss = css`
18
18
  visibility: hidden;
@@ -41,7 +41,7 @@ const rowCss = css`
41
41
  }
42
42
  `;
43
43
 
44
- const dangerousItemCss = css`
44
+ export const dangerousItemCss = css`
45
45
  &.${rowCss} {
46
46
  &[data-highlighted] {
47
47
  color: ${themeVars.danger};
@@ -52,21 +52,21 @@ const dangerousItemCss = css`
52
52
  }
53
53
  `;
54
54
 
55
- const dangerousConfirmationCss = css`
55
+ export const dangerousConfirmationCss = css`
56
56
  &.${rowCss} {
57
57
  background-color: ${themeVars.colorBgActionsMenuItemDangerActive};
58
- color: ${colors.inversedTextColor};
58
+ color: ${themeVars.whiteColor};
59
59
  border-radius: ${border.radius6}px;
60
60
 
61
- --actions-menu-item-icon-color: ${colors.inversedTextColor};
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: ${colors.inversedTextColor};
66
+ color: ${themeVars.whiteColor};
67
67
  border-radius: ${border.radius6}px;
68
68
 
69
- --actions-menu-item-icon-color: ${colors.inversedTextColor};
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 = _.isArray(shortcut) ? shortcut : shortcut ? [shortcut] : null;
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 _ from "lodash";
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 = _.noop,
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 onCloseAutoFocus={autoFocusOnClose ? undefined : preventDefault}>
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
@@ -66,7 +66,6 @@ export const Model = ({initialValue, onChange}: Props) => {
66
66
  <Tooltip
67
67
  // props
68
68
  title={`Model: ${item.name}`}
69
- // eslint-disable-next-line
70
69
  description={item.desc}
71
70
  instant
72
71
  >
@@ -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 _ from "lodash";
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 = _.noop, onTransitionEnd = _.noop, children, ...otherProps},
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 = _.noop;
49
+ let cleanup = noop;
50
50
 
51
51
  if (animating && containerRef.current) {
52
52
  const element = containerRef.current;
@@ -1,9 +1,10 @@
1
1
  import Modal from "antd/lib/modal";
2
2
  import {ModalProps} from "antd/lib/modal/Modal";
3
3
  import "antd/lib/modal/style/css";
4
- import {border, createInlineTheme, space, themeVars} from "../design-system";
5
- import {useTheme} from "../theme-provider";
4
+ import {border, space, themeVars} from "../design-system";
5
+ import {ThemeProvider} from "../theme-provider";
6
6
  import {css, cx} from "@linaria/core";
7
+ import {ReactNode} from "react";
7
8
 
8
9
  const modalCss = css`
9
10
  & .ant-modal-content {
@@ -19,8 +20,12 @@ const modalCss = css`
19
20
  }
20
21
  `;
21
22
 
23
+ function renderWithTheme(node: ReactNode): ReactNode {
24
+ return <ThemeProvider portal>{node}</ThemeProvider>;
25
+ }
26
+
22
27
  export function AntModal({bodyStyle = {}, className, ...restProps}: ModalProps) {
23
- const theme = useTheme();
24
- const inlineTheme = createInlineTheme(theme);
25
- return <Modal bodyStyle={{...bodyStyle, ...inlineTheme}} className={cx(className, modalCss)} {...restProps} />;
28
+ return (
29
+ <Modal bodyStyle={bodyStyle} className={cx(className, modalCss)} modalRender={renderWithTheme} {...restProps} />
30
+ );
26
31
  }
@@ -1,4 +1,7 @@
1
1
  import {StyledInput, StyledTextArea} from "./input";
2
+ import {InputProps} from "antd/lib/input";
2
3
 
3
4
  export const AntInput = StyledInput;
4
5
  export const AntTextArea = StyledTextArea;
6
+
7
+ export type AntInputProps = InputProps;
@@ -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
 
@@ -1,18 +1,18 @@
1
1
  import {css} from "@linaria/core";
2
- import {border, colors, layout, shadows, space, textStyles, themeVars, transition} from "../design-system";
2
+ import {border, layout, shadows, space, textStyles, themeVars, transition} from "../design-system";
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.opacity25}`,
9
- "--input-focus-shadow": `0 0 0 3px ${themeVars.focus}`,
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 1px ${themeVars.warning}`,
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
 
@@ -30,7 +30,7 @@ export const inputOverrides = {
30
30
  paddingLeft: space.s12,
31
31
  paddingRight: space.s12,
32
32
  border: 0,
33
- borderColor: colors.transparent,
33
+ borderColor: themeVars.transparent,
34
34
  transition: `box-shadow ${transition}`,
35
35
  boxShadow: `var(--input-border, ${themeVars.inputBorderColor})`,
36
36
  letterSpacing: 0,
@@ -43,13 +43,13 @@ 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: {
50
50
  color: `${themeVars.textColor}`,
51
51
  backgroundColor: `${themeVars.inputDisabledBgColor} !important`,
52
- borderColor: colors.transparent,
52
+ borderColor: themeVars.transparent,
53
53
  boxShadow: `${themeVars.inputDisabledBorderColor} !important`,
54
54
  transition: `box-shadow ${transition}`,
55
55
  WebkitTextFillColor: "currentColor",
@@ -69,7 +69,7 @@ export const inputStyles = css`
69
69
  ${{
70
70
  ...textStyles.regular,
71
71
  "& .ant-input-group-addon": {
72
- backgroundColor: colors.transparent,
72
+ backgroundColor: themeVars.transparent,
73
73
  border: "none",
74
74
  padding: 0,
75
75
  textAlign: "left",
@@ -93,7 +93,7 @@ export const inputStyles = css`
93
93
  padding: 0,
94
94
  border: "none",
95
95
  boxShadow: "none",
96
- backgroundColor: colors.transparent,
96
+ backgroundColor: themeVars.transparent,
97
97
  },
98
98
  "& .ant-input-affix-wrapper.ant-input-affix-wrapper-readonly": {
99
99
  border: "none !important",
@@ -118,7 +118,7 @@ export const inputStyles = css`
118
118
  paddingBottom: space.s8,
119
119
  },
120
120
  "& .ant-select-disabled .ant-select-selection": {
121
- backgroundColor: colors.transparent,
121
+ backgroundColor: themeVars.transparent,
122
122
  },
123
123
  "&& input:hover:not(:focus):not(:disabled), && textarea:hover:not(:focus):not(:disabled), && .ant-input:hover:not(:focus):not(:disabled)":
124
124
  inputOverrides.hover,