@fibery/ui-kit 1.31.0 → 1.32.1

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 (40) hide show
  1. package/package.json +10 -13
  2. package/src/actions-menu/actions-menu-confirmation.tsx +3 -3
  3. package/src/actions-menu/actions-menu-sub-menu.tsx +5 -2
  4. package/src/actions-menu/actions-menu.tsx +6 -1
  5. package/src/actions-menu/contexts/actions-menu-context.tsx +11 -2
  6. package/src/button/actions-button-compact.tsx +1 -1
  7. package/src/button/actions-button.tsx +1 -17
  8. package/src/button/add-button.tsx +13 -6
  9. package/src/button/back-button.tsx +12 -23
  10. package/src/button/base-button.tsx +189 -0
  11. package/src/button/button.tsx +84 -237
  12. package/src/button/icon-button.tsx +71 -0
  13. package/src/button/make-button-colors.ts +33 -0
  14. package/src/design-system.ts +6 -5
  15. package/src/dropdown-menu/index.tsx +15 -14
  16. package/src/emoji-picker/emoji-picker-content-with-color.tsx +1 -1
  17. package/src/emoji-picker/emoji-picker-preview-footer.tsx +2 -2
  18. package/src/emoji-picker/icon-emoji-picker.tsx +3 -3
  19. package/src/emoji-picker/primitives/category-label.tsx +1 -1
  20. package/src/emoji-picker/primitives/grid-item.tsx +1 -1
  21. package/src/emoji-picker/primitives/search.tsx +1 -1
  22. package/src/emoji-picker/primitives/skin-tone.tsx +1 -1
  23. package/src/error-alert/error-alert-action.tsx +9 -6
  24. package/src/error-alert/error-alert.tsx +1 -1
  25. package/src/icons/Icon.tsx +1 -0
  26. package/src/icons/ast/Folder.ts +8 -0
  27. package/src/icons/ast/SmartFolder.ts +1 -1
  28. package/src/icons/ast/index.tsx +1 -0
  29. package/src/icons/react/Folder.tsx +13 -0
  30. package/src/icons/react/index.tsx +1 -0
  31. package/src/integration-compact-info-button.tsx +4 -3
  32. package/src/select/custom-select-partials/clear-indicator.tsx +1 -1
  33. package/src/toast/primitives.tsx +1 -1
  34. package/src/toast/toast-action.tsx +3 -6
  35. package/src/toast/toaster.tsx +18 -2
  36. package/src/toggle.tsx +22 -16
  37. package/src/back-button.tsx +0 -3
  38. package/src/button/button-base.tsx +0 -180
  39. package/src/button.tsx +0 -3
  40. package/src/icon-button.tsx +0 -3
package/package.json CHANGED
@@ -1,11 +1,9 @@
1
1
  {
2
2
  "name": "@fibery/ui-kit",
3
- "version": "1.31.0",
3
+ "version": "1.32.1",
4
4
  "private": false,
5
5
  "files": [
6
6
  "src/antd/styles.ts",
7
- "src/icon-button.tsx",
8
- "src/button.tsx",
9
7
  "src/design-system.ts",
10
8
  "src/theme-styles.ts",
11
9
  "src/theme-settings.ts",
@@ -23,7 +21,6 @@
23
21
  "src/palette.ts",
24
22
  "src/tooltip.tsx",
25
23
  "src/tooltip-if-overflown.tsx",
26
- "src/back-button.tsx",
27
24
  "src/button",
28
25
  "src/emoji-picker/**/*.ts*",
29
26
  "src/toast/**/*.ts*",
@@ -41,11 +38,11 @@
41
38
  "@linaria/core": "5.0.1",
42
39
  "@linaria/react": "5.0.1",
43
40
  "@popperjs/core": "2.11.6",
44
- "@radix-ui/react-collapsible": "1.0.3",
45
- "@radix-ui/react-context-menu": "2.1.5",
46
- "@radix-ui/react-dropdown-menu": "2.0.6",
47
- "@radix-ui/react-toast": "1.1.5",
48
- "@radix-ui/react-tooltip": "1.0.7",
41
+ "@radix-ui/react-collapsible": "1.1.0",
42
+ "@radix-ui/react-context-menu": "2.2.1",
43
+ "@radix-ui/react-dropdown-menu": "2.1.1",
44
+ "@radix-ui/react-toast": "1.2.1",
45
+ "@radix-ui/react-tooltip": "1.1.2",
49
46
  "@types/d3-shape": "^3.1.3",
50
47
  "@types/react-select-country-list": "^2.2.1",
51
48
  "@types/setimmediate": "^1.0.2",
@@ -75,9 +72,9 @@
75
72
  "react-virtuoso": "4.6.0",
76
73
  "screenfull": "6.0.1",
77
74
  "ua-parser-js": "0.7.24",
78
- "@fibery/helpers": "1.3.0",
75
+ "@fibery/emoji-data": "2.6.0",
79
76
  "@fibery/react": "1.4.0",
80
- "@fibery/emoji-data": "2.6.0"
77
+ "@fibery/helpers": "1.3.0"
81
78
  },
82
79
  "peerDependencies": {
83
80
  "react": "^18.2.0",
@@ -111,8 +108,8 @@
111
108
  "svgo": "2.8.0",
112
109
  "typescript": "5.4.3",
113
110
  "unist-util-reduce": "0.2.2",
114
- "@fibery/babel-preset": "7.4.0",
115
- "@fibery/eslint-config": "8.6.0"
111
+ "@fibery/eslint-config": "8.6.0",
112
+ "@fibery/babel-preset": "7.4.0"
116
113
  },
117
114
  "jest": {
118
115
  "testEnvironment": "jsdom",
@@ -1,8 +1,8 @@
1
1
  import {css} from "@linaria/core";
2
+ import {ActionsPanel} from "../actions-panel";
2
3
  import {AntModal} from "../antd/ant-modal";
4
+ import {Button} from "../button/button";
3
5
  import {border, space, themeVars} from "../design-system";
4
- import {ActionsPanel} from "../actions-panel";
5
- import {Button} from "../button";
6
6
  import {useActionsMenuContext} from "./contexts/actions-menu-context";
7
7
 
8
8
  const modalClass = css`
@@ -47,7 +47,6 @@ export const ActionsMenuConfirmation: React.FC<ActionsMenuConfirmationProps> = (
47
47
  >
48
48
  <ActionsPanel inline>
49
49
  <Button
50
- primary
51
50
  onClick={() => {
52
51
  onConfirm();
53
52
  showConfirmation(null);
@@ -56,6 +55,7 @@ export const ActionsMenuConfirmation: React.FC<ActionsMenuConfirmationProps> = (
56
55
  Proceed
57
56
  </Button>
58
57
  <Button
58
+ variant="outline"
59
59
  onClick={() => {
60
60
  showConfirmation(null);
61
61
  onCancel?.();
@@ -23,6 +23,7 @@ type Props = React.PropsWithChildren<{
23
23
  onOpenChange?: (v: boolean) => void;
24
24
  disabled?: boolean;
25
25
  contentClassName?: string;
26
+ container?: HTMLElement | null;
26
27
  }>;
27
28
 
28
29
  export const ActionsMenuSubMenu: React.FC<Props> = ({
@@ -34,7 +35,7 @@ export const ActionsMenuSubMenu: React.FC<Props> = ({
34
35
  disabled = false,
35
36
  contentClassName,
36
37
  }) => {
37
- const {MenuPrimitive} = useActionsMenuContext();
38
+ const {MenuPrimitive, container} = useActionsMenuContext();
38
39
 
39
40
  return (
40
41
  <MenuPrimitive.Sub open={open} onOpenChange={onOpenChange}>
@@ -53,7 +54,9 @@ export const ActionsMenuSubMenu: React.FC<Props> = ({
53
54
  />
54
55
  </div>
55
56
  </MenuPrimitive.SubTrigger>
56
- <MenuPrimitive.SubContent className={contentClassName}>{children}</MenuPrimitive.SubContent>
57
+ <MenuPrimitive.SubContent container={container} className={contentClassName}>
58
+ {children}
59
+ </MenuPrimitive.SubContent>
57
60
  </MenuPrimitive.Sub>
58
61
  );
59
62
  };
@@ -40,7 +40,12 @@ export const ActionsMenu = ({
40
40
  const [confirmation, setConfirmation] = useState<ActionsMenuConfirmationProps | null>(null);
41
41
 
42
42
  return (
43
- <ActionsMenuContextProvider setOpen={setOpen} showConfirmation={setConfirmation} MenuPrimitive={DropdownMenu}>
43
+ <ActionsMenuContextProvider
44
+ setOpen={setOpen}
45
+ showConfirmation={setConfirmation}
46
+ MenuPrimitive={DropdownMenu}
47
+ container={container}
48
+ >
44
49
  <DropdownMenu.Root open={isOpen} onOpenChange={setOpen} modal={modal || false}>
45
50
  <DropdownMenu.Trigger
46
51
  // backward compatibility for dropdown styles
@@ -16,6 +16,7 @@ type ActionsMenuContext = {
16
16
  close: () => void;
17
17
  showConfirmation: (args: ActionsMenuConfirmationProps | null) => void;
18
18
  MenuPrimitive: MenuPrimitive;
19
+ container?: HTMLElement | null;
19
20
  };
20
21
 
21
22
  const [Provider, useContext] = createContext<ActionsMenuContext>("ActionsMenuContext");
@@ -24,16 +25,24 @@ type Props = React.PropsWithChildren<{
24
25
  setOpen: (value: boolean) => void;
25
26
  showConfirmation: (args: ActionsMenuConfirmationProps | null) => void;
26
27
  MenuPrimitive: MenuPrimitive;
28
+ container?: HTMLElement | null;
27
29
  }>;
28
30
 
29
- export const ActionsMenuContextProvider: React.FC<Props> = ({setOpen, showConfirmation, MenuPrimitive, children}) => {
31
+ export const ActionsMenuContextProvider: React.FC<Props> = ({
32
+ setOpen,
33
+ showConfirmation,
34
+ MenuPrimitive,
35
+ container,
36
+ children,
37
+ }) => {
30
38
  const context = useMemo<ActionsMenuContext>(
31
39
  () => ({
32
40
  close: () => setOpen(false),
33
41
  MenuPrimitive,
34
42
  showConfirmation,
43
+ container,
35
44
  }),
36
- [MenuPrimitive, showConfirmation, setOpen]
45
+ [MenuPrimitive, showConfirmation, container, setOpen]
37
46
  );
38
47
 
39
48
  return <Provider value={context}>{children}</Provider>;
@@ -1,5 +1,5 @@
1
1
  import {forwardRef} from "react";
2
- import {IconButton, IconButtonProps} from "../button-v2/icon-button";
2
+ import {IconButton, IconButtonProps} from "./icon-button";
3
3
  import MoreCompactIcon from "../icons/react/MoreCompact";
4
4
 
5
5
  export const ActionsButtonCompact = forwardRef<HTMLButtonElement, IconButtonProps>(
@@ -1,7 +1,5 @@
1
- import {css} from "@linaria/core";
2
1
  import {forwardRef} from "react";
3
- import {IconButton, IconButtonProps} from "../button-v2/icon-button";
4
- import {border, themeVars} from "../design-system";
2
+ import {IconButton, IconButtonProps} from "./icon-button";
5
3
  import MoreCompact from "../icons/react/MoreCompact";
6
4
 
7
5
  export const ActionsButton = forwardRef<HTMLButtonElement, IconButtonProps>(function ActionsButtonComponent(
@@ -14,17 +12,3 @@ export const ActionsButton = forwardRef<HTMLButtonElement, IconButtonProps>(func
14
12
  </IconButton>
15
13
  );
16
14
  });
17
-
18
- // TODO: Shoud be a variant inside button?
19
- export const actionButtonInlineStyle = css`
20
- background-color: ${themeVars.actionMenuButtonColor};
21
- box-shadow: ${themeVars.entityCardShadow};
22
- border-radius: ${border.radius6}px;
23
-
24
- .Button:hover {
25
- background-color: ${themeVars.actionMenuButtonHoverColor} !important;
26
- }
27
- .Button:focus {
28
- background-color: ${themeVars.actionMenuButtonHoverColor} !important;
29
- }
30
- `;
@@ -1,13 +1,20 @@
1
1
  import {forwardRef} from "react";
2
2
  import AddIcon from "../icons/react/Add";
3
- import {Button, ButtonProps} from "./button";
3
+ import {ButtonProps, Button} from "./button";
4
4
 
5
- type Props = {
6
- disableReason?: string;
7
- } & ButtonProps;
5
+ type Props = ButtonProps;
8
6
 
9
7
  export const AddButton = forwardRef<HTMLButtonElement, Props>(
10
- ({disableReason = "", Icon = AddIcon, ...rest}, forwardedRef) => {
11
- return <Button ref={forwardedRef} borderless Icon={Icon} title={disableReason} {...rest} />;
8
+ ({iconStart = <AddIcon />, className, ...rest}, forwardedRef) => {
9
+ return (
10
+ <Button
11
+ ref={forwardedRef}
12
+ iconStart={iconStart}
13
+ variant="ghost"
14
+ color="neutral"
15
+ className={className}
16
+ {...rest}
17
+ />
18
+ );
12
19
  }
13
20
  );
@@ -1,26 +1,15 @@
1
- import {ButtonSize, Button} from "./button";
1
+ import {forwardRef} from "react";
2
2
  import BackIcon from "../icons/react/Back";
3
+ import {ButtonProps, Button} from "./button";
3
4
 
4
- type Props = {
5
- disabled?: boolean;
6
- pending?: boolean;
7
- onClick: () => unknown;
8
- size?: ButtonSize;
9
- color?: string;
10
- };
5
+ type Props = ButtonProps;
11
6
 
12
- export function BackButton({disabled, onClick, pending, size, color}: Props) {
13
- return (
14
- <Button
15
- borderless
16
- Icon={BackIcon}
17
- disabled={disabled}
18
- onClick={onClick}
19
- pending={pending}
20
- size={size}
21
- color={color}
22
- >
23
- Back
24
- </Button>
25
- );
26
- }
7
+ export const BackButton = forwardRef<HTMLButtonElement, Props>(
8
+ ({iconStart = <BackIcon />, className, ...rest}, forwardedRef) => {
9
+ return (
10
+ <Button ref={forwardedRef} iconStart={iconStart} variant="ghost" color="neutral" className={className} {...rest}>
11
+ Back
12
+ </Button>
13
+ );
14
+ }
15
+ );
@@ -0,0 +1,189 @@
1
+ import {CSSProperties, css, cx} from "@linaria/core";
2
+ import {forwardRef} from "react";
3
+ import {themeVars} from "../design-system";
4
+ import {iconColorVar} from "../icons/Icon";
5
+
6
+ export type ButtonSize = "tiny" | "small" | "medium" | "large";
7
+ export type ButtonVariant = "solid" | "outline" | "soft" | "ghost";
8
+ export type ButtonColor = "accent" | "neutral" | "error";
9
+ type PositionInGroup = "first" | "middle" | "last";
10
+
11
+ export type BaseButtonProps = {
12
+ variant?: ButtonVariant;
13
+ color?: ButtonColor;
14
+ pressed?: boolean;
15
+
16
+ // kept for backward compatibility with old buttons. Ideally should be reprsented as a separate component (ButtonGroup/SegmentedControl)
17
+ inGroup?: PositionInGroup;
18
+ } & React.ComponentPropsWithRef<"button">;
19
+
20
+ const baseButton = css`
21
+ all: unset;
22
+ position: relative;
23
+ box-sizing: border-box;
24
+
25
+ flex-shrink: 0;
26
+ cursor: pointer;
27
+ user-select: none;
28
+
29
+ transition-property: border, background-color, color, opacity;
30
+ transition-duration: 0.15s;
31
+
32
+ color: var(--fibery-button-text-color);
33
+ ${iconColorVar}: var(--fibery-button-text-color);
34
+
35
+ background-color: var(--fibery-button-color);
36
+
37
+ box-shadow: inset 0 0 0 1px var(--fibery-button-border-color);
38
+
39
+ :hover:not(:disabled) {
40
+ background-color: var(--fibery-button-hover-color);
41
+ }
42
+ :active {
43
+ color: var(--fibery-button-text-active-color);
44
+ ${iconColorVar}: var(--fibery-button-text-active-color);
45
+ }
46
+
47
+ &[aria-pressed="true"] {
48
+ color: var(--fibery-button-text-active-color);
49
+ ${iconColorVar}: var(--fibery-button-text-active-color);
50
+ background-color: var(--fibery-button-hover-color);
51
+ }
52
+
53
+ :disabled {
54
+ cursor: default;
55
+ opacity: 0.4;
56
+ }
57
+
58
+ :focus {
59
+ outline: none;
60
+ }
61
+
62
+ :focus-visible {
63
+ background-color: var(--fibery-button-hover-color);
64
+ outline: 2px solid var(--fibery-button-focus-color);
65
+ }
66
+ `;
67
+
68
+ const variantToThemeMod = {
69
+ solid: "Solid",
70
+ soft: "Soft",
71
+ ghost: "Ghost",
72
+ outline: "Outline",
73
+ } as const;
74
+ const colorToThemeMod = {
75
+ accent: "Accent",
76
+ neutral: "Neutral",
77
+ error: "Destructive",
78
+ } as const;
79
+
80
+ const getColors = (variant: ButtonVariant, color: ButtonColor) => {
81
+ const variantMod = variantToThemeMod[variant];
82
+ const colorMod = colorToThemeMod[color];
83
+
84
+ let borderColors;
85
+
86
+ if (variantMod === "Outline") {
87
+ borderColors = {
88
+ "--fibery-button-border-color": themeVars[`colorBorderButton${variantMod}${colorMod}Default` as const],
89
+ };
90
+ }
91
+
92
+ return {
93
+ "--fibery-button-color": themeVars[`colorBgButton${variantMod}${colorMod}Default`],
94
+ "--fibery-button-hover-color": themeVars[`colorBgButton${variantMod}${colorMod}Hover`],
95
+ "--fibery-button-text-color": themeVars[`colorTextButton${variantMod}${colorMod}`],
96
+ "--fibery-button-text-active-color": themeVars[`colorTextButton${variantMod}${colorMod}Active`],
97
+ "--fibery-button-focus-color": themeVars[`colorBorder${colorMod}FocusRing`],
98
+
99
+ ...borderColors,
100
+ } as CSSProperties;
101
+ };
102
+
103
+ const buttonGroup = {
104
+ first: css`
105
+ &:is(&) {
106
+ display: inline-flex;
107
+ vertical-align: middle;
108
+ border-top-right-radius: 0;
109
+ border-bottom-right-radius: 0;
110
+
111
+ &:not([data-variant="outline"]) + * {
112
+ position: relative;
113
+ :after {
114
+ content: "";
115
+ left: -1px;
116
+ position: absolute;
117
+ width: 1px;
118
+ top: 4px;
119
+ bottom: 4px;
120
+ background-color: rgba(255, 255, 255, 0.2);
121
+ }
122
+ }
123
+ }
124
+ `,
125
+ middle: css`
126
+ &:is(&) {
127
+ display: inline-flex;
128
+ vertical-align: middle;
129
+ margin-left: -1px;
130
+ border-radius: 0;
131
+
132
+ &:not([data-variant="outline"]) + * {
133
+ position: relative;
134
+ :after {
135
+ content: "";
136
+ left: -1px;
137
+ position: absolute;
138
+ width: 1px;
139
+ top: 4px;
140
+ bottom: 4px;
141
+ background-color: rgba(255, 255, 255, 0.2);
142
+ }
143
+ }
144
+ }
145
+ `,
146
+ last: css`
147
+ &:is(&) {
148
+ display: inline-flex;
149
+ vertical-align: middle;
150
+ margin-left: -1px;
151
+ border-top-left-radius: 0;
152
+ border-bottom-left-radius: 0;
153
+ }
154
+ `,
155
+ };
156
+
157
+ export const BaseButton = forwardRef<HTMLButtonElement, BaseButtonProps>(
158
+ (
159
+ {
160
+ variant = "solid",
161
+ color = "accent",
162
+ type = "button",
163
+ className,
164
+ children,
165
+ inGroup,
166
+ style,
167
+ pressed,
168
+ ...buttonProps
169
+ },
170
+ ref
171
+ ) => {
172
+ const colors = getColors(variant, color);
173
+
174
+ return (
175
+ <button
176
+ style={{...colors, ...style}}
177
+ aria-pressed={pressed || buttonProps["aria-pressed"]}
178
+ data-variant={variant}
179
+ className={cx(baseButton, inGroup && buttonGroup[inGroup], className)}
180
+ ref={ref}
181
+ // eslint-disable-next-line react/button-has-type
182
+ type={type}
183
+ {...buttonProps}
184
+ >
185
+ {children}
186
+ </button>
187
+ );
188
+ }
189
+ );