@bitrise/bitkit-v2 0.3.220 → 0.3.221
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/AGENTS.md +15 -0
- package/dist/components/BitkitActionMenu/BitkitActionMenu.d.ts +16 -3
- package/dist/components/BitkitActionMenu/BitkitActionMenu.js +31 -11
- package/dist/components/BitkitActionMenu/BitkitActionMenu.js.map +1 -1
- package/dist/components/BitkitButton/BitkitButton.d.ts +27 -4
- package/dist/components/BitkitButton/BitkitButton.js +85 -8
- package/dist/components/BitkitButton/BitkitButton.js.map +1 -1
- package/dist/components/BitkitControlButton/BitkitControlButton.d.ts +11 -2
- package/dist/components/BitkitControlButton/BitkitControlButton.js +46 -3
- package/dist/components/BitkitControlButton/BitkitControlButton.js.map +1 -1
- package/dist/components/BitkitIconButton/BitkitIconButton.d.ts +25 -3
- package/dist/components/BitkitIconButton/BitkitIconButton.js +80 -7
- package/dist/components/BitkitIconButton/BitkitIconButton.js.map +1 -1
- package/dist/components/BitkitLink/BitkitLink.d.ts +1 -0
- package/dist/components/BitkitLink/BitkitLink.js +18 -3
- package/dist/components/BitkitLink/BitkitLink.js.map +1 -1
- package/dist/components/BitkitNoteCard/BitkitNoteCard.js +11 -8
- package/dist/components/BitkitNoteCard/BitkitNoteCard.js.map +1 -1
- package/dist/components/BitkitSplitButton/BitkitSplitButton.d.ts +4 -4
- package/dist/components/BitkitSplitButton/BitkitSplitButton.js +11 -3
- package/dist/components/BitkitSplitButton/BitkitSplitButton.js.map +1 -1
- package/docs/v1-to-v2-migration-guide.md +33 -1
- package/package.json +1 -1
package/AGENTS.md
CHANGED
|
@@ -91,6 +91,21 @@ Bitkit components use consistent prop names across the library:
|
|
|
91
91
|
<BitkitButton icon={IconCheck}>Save</BitkitButton>
|
|
92
92
|
<BitkitAccordion.ItemTrigger suffix={<Badge>3</Badge>}>Files</BitkitAccordion.ItemTrigger>
|
|
93
93
|
```
|
|
94
|
+
- **Buttons can render as links** — `BitkitButton`, `BitkitIconButton`, and `BitkitControlButton` render an `<a>` when `href` is passed. The button-recipe styles apply to the anchor. Pass `isExternal` to auto-add `target="_blank" rel="noreferrer noopener"`. For routing libraries (Next.js, React Router), use `asChild` with your own anchor element:
|
|
95
|
+
```tsx
|
|
96
|
+
<BitkitButton href="/internal">Internal link</BitkitButton>
|
|
97
|
+
<BitkitButton href="https://example.com" isExternal>External</BitkitButton>
|
|
98
|
+
<BitkitButton asChild icon={IconCheck}>
|
|
99
|
+
<NextLink href="/route">Routed</NextLink>
|
|
100
|
+
</BitkitButton>
|
|
101
|
+
```
|
|
102
|
+
`state="loading"` is button-only — not valid in anchor mode.
|
|
103
|
+
- **`BitkitLink` external convenience** — `BitkitLink` accepts `isExternal` for the same auto target+rel behavior.
|
|
104
|
+
- **`BitkitActionMenu.Item` as a link** — pass `href` to make a menu item render as an anchor; `target`, `rel`, and `isExternal` work the same way as on the button family. Without `href` it stays a normal menu item:
|
|
105
|
+
```tsx
|
|
106
|
+
<BitkitActionMenu.Item href="/settings" value="settings">Settings</BitkitActionMenu.Item>
|
|
107
|
+
<BitkitActionMenu.Item href="https://example.com" isExternal value="docs">Open docs</BitkitActionMenu.Item>
|
|
108
|
+
```
|
|
94
109
|
- **Form components are flat** — `BitkitTextInput`, `BitkitSelect`, `BitkitCombobox`, etc. expose `label`, `errorText`, `helperText`, etc. directly as props. No need to wrap in a separate field component.
|
|
95
110
|
- **`BitkitDialog` non-dismissible + post-close callback** — pass `closable={false}` to make the dialog fully non-dismissible: the close button is rendered but disabled (kept for layout consistency), ESC is blocked, and outside clicks are ignored. The only way out is an explicit footer action. Pass `onExitComplete` to run code after the close animation finishes (navigation, focus restoration, cleanup):
|
|
96
111
|
```tsx
|
|
@@ -5,11 +5,24 @@ interface BitkitMenuRootProps extends Omit<MenuRootProps, 'children'> {
|
|
|
5
5
|
trigger: ReactNode;
|
|
6
6
|
children?: ReactNode;
|
|
7
7
|
}
|
|
8
|
-
|
|
8
|
+
interface BitkitMenuItemCommonProps extends MenuItemProps {
|
|
9
9
|
danger?: boolean;
|
|
10
|
-
secondaryText?: ReactNode;
|
|
11
10
|
icon?: BitkitIconComponent;
|
|
11
|
+
secondaryText?: ReactNode;
|
|
12
|
+
}
|
|
13
|
+
interface BitkitMenuItemAsButtonProps extends BitkitMenuItemCommonProps {
|
|
14
|
+
href?: undefined;
|
|
15
|
+
isExternal?: undefined;
|
|
16
|
+
rel?: undefined;
|
|
17
|
+
target?: undefined;
|
|
18
|
+
}
|
|
19
|
+
interface BitkitMenuItemAsAnchorProps extends BitkitMenuItemCommonProps {
|
|
20
|
+
href: string;
|
|
21
|
+
isExternal?: boolean;
|
|
22
|
+
rel?: string;
|
|
23
|
+
target?: string;
|
|
12
24
|
}
|
|
25
|
+
export type BitkitMenuItemProps = BitkitMenuItemAsButtonProps | BitkitMenuItemAsAnchorProps;
|
|
13
26
|
export interface BitkitMenuGroupProps extends MenuItemGroupProps {
|
|
14
27
|
label: ReactNode;
|
|
15
28
|
}
|
|
@@ -22,7 +35,7 @@ declare const BitkitActionMenu: {
|
|
|
22
35
|
(): import("react/jsx-runtime").JSX.Element;
|
|
23
36
|
displayName: string;
|
|
24
37
|
};
|
|
25
|
-
Item: import('react').ForwardRefExoticComponent<BitkitMenuItemProps & import('react').RefAttributes<
|
|
38
|
+
Item: import('react').ForwardRefExoticComponent<BitkitMenuItemProps & import('react').RefAttributes<HTMLElement>>;
|
|
26
39
|
Group: import('react').ForwardRefExoticComponent<BitkitMenuGroupProps & import('react').RefAttributes<HTMLDivElement>>;
|
|
27
40
|
};
|
|
28
41
|
export default BitkitActionMenu;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Box } from "@chakra-ui/react/box";
|
|
2
2
|
import { Text } from "@chakra-ui/react/text";
|
|
3
3
|
import { createContext, forwardRef, useContext } from "react";
|
|
4
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
4
|
+
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
5
5
|
import { Portal } from "@chakra-ui/react/portal";
|
|
6
6
|
import { Menu, useMenuStyles } from "@chakra-ui/react/menu";
|
|
7
7
|
import { Separator } from "@chakra-ui/react/separator";
|
|
@@ -20,20 +20,40 @@ var Root = ({ trigger, children, ...props }) => {
|
|
|
20
20
|
});
|
|
21
21
|
};
|
|
22
22
|
Root.displayName = "BitkitActionMenu.Root";
|
|
23
|
-
var Item = forwardRef((
|
|
23
|
+
var Item = forwardRef((props, ref) => {
|
|
24
|
+
const { children, danger, icon: Icon, secondaryText } = props;
|
|
24
25
|
const style = useMenuStyles();
|
|
25
26
|
const menuCtx = useContext(BitkitMenuContext);
|
|
26
|
-
|
|
27
|
+
const content = /* @__PURE__ */ jsxs(Fragment$1, { children: [Icon && /* @__PURE__ */ jsx(Icon, { size: menuCtx === "lg" ? "24" : "16" }), /* @__PURE__ */ jsxs(Box, {
|
|
28
|
+
flex: "1",
|
|
29
|
+
children: [/* @__PURE__ */ jsx(Text, { children }), secondaryText && /* @__PURE__ */ jsx(Text, {
|
|
30
|
+
css: style.itemHelper,
|
|
31
|
+
children: secondaryText
|
|
32
|
+
})]
|
|
33
|
+
})] });
|
|
34
|
+
if (props.href !== void 0) {
|
|
35
|
+
const { children: _children, danger: _danger, href, icon: _icon, isExternal, rel, secondaryText: _secondaryText, target, ...rest } = props;
|
|
36
|
+
const effectiveTarget = isExternal ? "_blank" : target;
|
|
37
|
+
const effectiveRel = isExternal ? rel ? `${rel} noreferrer noopener` : "noreferrer noopener" : rel;
|
|
38
|
+
return /* @__PURE__ */ jsx(Menu.Item, {
|
|
39
|
+
asChild: true,
|
|
40
|
+
"data-danger": danger,
|
|
41
|
+
...rest,
|
|
42
|
+
children: /* @__PURE__ */ jsx("a", {
|
|
43
|
+
ref,
|
|
44
|
+
href,
|
|
45
|
+
rel: effectiveRel,
|
|
46
|
+
target: effectiveTarget,
|
|
47
|
+
children: content
|
|
48
|
+
})
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
const { children: _children, danger: _danger, icon: _icon, secondaryText: _secondaryText, ...rest } = props;
|
|
52
|
+
return /* @__PURE__ */ jsx(Menu.Item, {
|
|
27
53
|
"data-danger": danger,
|
|
28
54
|
ref,
|
|
29
|
-
...
|
|
30
|
-
children:
|
|
31
|
-
flex: "1",
|
|
32
|
-
children: [/* @__PURE__ */ jsx(Text, { children }), secondaryText && /* @__PURE__ */ jsx(Text, {
|
|
33
|
-
css: style.itemHelper,
|
|
34
|
-
children: secondaryText
|
|
35
|
-
})]
|
|
36
|
-
})]
|
|
55
|
+
...rest,
|
|
56
|
+
children: content
|
|
37
57
|
});
|
|
38
58
|
});
|
|
39
59
|
Item.displayName = "BitkitActionMenu.Item";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BitkitActionMenu.js","names":[],"sources":["../../../lib/components/BitkitActionMenu/BitkitActionMenu.tsx"],"sourcesContent":["import { Box } from '@chakra-ui/react/box';\nimport {\n Menu,\n type MenuItemGroupProps,\n type MenuItemProps,\n type MenuRootProps,\n useMenuStyles,\n} from '@chakra-ui/react/menu';\nimport { Portal } from '@chakra-ui/react/portal';\nimport { Separator as ChakraSeparator } from '@chakra-ui/react/separator';\nimport { Text } from '@chakra-ui/react/text';\nimport { createContext, forwardRef, type ReactNode, useContext } from 'react';\n\nimport { type BitkitIconComponent } from '../../icons';\n\nconst BitkitMenuContext = createContext<MenuRootProps['size']>('lg');\n\ninterface BitkitMenuRootProps extends Omit<MenuRootProps, 'children'> {\n trigger: ReactNode;\n children?: ReactNode;\n}\n\nconst Root = ({ trigger, children, ...props }: BitkitMenuRootProps) => {\n return (\n <Menu.Root {...props}>\n <Menu.Trigger asChild>{trigger}</Menu.Trigger>\n <Portal>\n <Menu.Positioner>\n <BitkitMenuContext.Provider value={props.size}>\n <Menu.Content>{children}</Menu.Content>\n </BitkitMenuContext.Provider>\n </Menu.Positioner>\n </Portal>\n </Menu.Root>\n );\n};\nRoot.displayName = 'BitkitActionMenu.Root';\n\
|
|
1
|
+
{"version":3,"file":"BitkitActionMenu.js","names":[],"sources":["../../../lib/components/BitkitActionMenu/BitkitActionMenu.tsx"],"sourcesContent":["import { Box } from '@chakra-ui/react/box';\nimport {\n Menu,\n type MenuItemGroupProps,\n type MenuItemProps,\n type MenuRootProps,\n useMenuStyles,\n} from '@chakra-ui/react/menu';\nimport { Portal } from '@chakra-ui/react/portal';\nimport { Separator as ChakraSeparator } from '@chakra-ui/react/separator';\nimport { Text } from '@chakra-ui/react/text';\nimport { createContext, forwardRef, type ReactNode, type Ref, useContext } from 'react';\n\nimport { type BitkitIconComponent } from '../../icons';\n\nconst BitkitMenuContext = createContext<MenuRootProps['size']>('lg');\n\ninterface BitkitMenuRootProps extends Omit<MenuRootProps, 'children'> {\n trigger: ReactNode;\n children?: ReactNode;\n}\n\nconst Root = ({ trigger, children, ...props }: BitkitMenuRootProps) => {\n return (\n <Menu.Root {...props}>\n <Menu.Trigger asChild>{trigger}</Menu.Trigger>\n <Portal>\n <Menu.Positioner>\n <BitkitMenuContext.Provider value={props.size}>\n <Menu.Content>{children}</Menu.Content>\n </BitkitMenuContext.Provider>\n </Menu.Positioner>\n </Portal>\n </Menu.Root>\n );\n};\nRoot.displayName = 'BitkitActionMenu.Root';\n\ninterface BitkitMenuItemCommonProps extends MenuItemProps {\n danger?: boolean;\n icon?: BitkitIconComponent;\n secondaryText?: ReactNode;\n}\n\ninterface BitkitMenuItemAsButtonProps extends BitkitMenuItemCommonProps {\n href?: undefined;\n isExternal?: undefined;\n rel?: undefined;\n target?: undefined;\n}\n\ninterface BitkitMenuItemAsAnchorProps extends BitkitMenuItemCommonProps {\n href: string;\n isExternal?: boolean;\n rel?: string;\n target?: string;\n}\n\nexport type BitkitMenuItemProps = BitkitMenuItemAsButtonProps | BitkitMenuItemAsAnchorProps;\n\nconst Item = forwardRef<HTMLElement, BitkitMenuItemProps>((props, ref) => {\n const { children, danger, icon: Icon, secondaryText } = props;\n const style = useMenuStyles();\n const menuCtx = useContext(BitkitMenuContext);\n\n const content = (\n <>\n {Icon && <Icon size={menuCtx === 'lg' ? '24' : '16'} />}\n <Box flex=\"1\">\n <Text>{children}</Text>\n {secondaryText && <Text css={style.itemHelper}>{secondaryText}</Text>}\n </Box>\n </>\n );\n\n if (props.href !== undefined) {\n const {\n children: _children,\n danger: _danger,\n href,\n icon: _icon,\n isExternal,\n rel,\n secondaryText: _secondaryText,\n target,\n ...rest\n } = props;\n const effectiveTarget = isExternal ? '_blank' : target;\n const effectiveRel = isExternal ? (rel ? `${rel} noreferrer noopener` : 'noreferrer noopener') : rel;\n return (\n <Menu.Item asChild data-danger={danger} {...rest}>\n <a ref={ref as Ref<HTMLAnchorElement>} href={href} rel={effectiveRel} target={effectiveTarget}>\n {content}\n </a>\n </Menu.Item>\n );\n }\n\n const { children: _children, danger: _danger, icon: _icon, secondaryText: _secondaryText, ...rest } = props;\n return (\n <Menu.Item data-danger={danger} ref={ref as Ref<HTMLDivElement>} {...rest}>\n {content}\n </Menu.Item>\n );\n});\nItem.displayName = 'BitkitActionMenu.Item';\n\nexport interface BitkitMenuGroupProps extends MenuItemGroupProps {\n label: ReactNode;\n}\nconst Group = forwardRef<HTMLDivElement, BitkitMenuGroupProps>(({ label, children, ...props }, ref) => {\n return (\n <Menu.ItemGroup ref={ref} {...props}>\n <Menu.ItemGroupLabel>\n <Text>{label}</Text>\n <ChakraSeparator flex=\"1\" />\n </Menu.ItemGroupLabel>\n {children}\n </Menu.ItemGroup>\n );\n});\nGroup.displayName = 'BitkitActionMenu.Group';\n\nconst Separator = () => {\n return <Menu.Separator />;\n};\nSeparator.displayName = 'BitkitActionMenu.Separator';\n\nconst BitkitActionMenu = {\n Root,\n Separator,\n Item,\n Group,\n};\n\nexport default BitkitActionMenu;\n"],"mappings":";;;;;;;;AAeA,IAAM,oBAAoB,cAAqC,IAAI;AAOnE,IAAM,QAAQ,EAAE,SAAS,UAAU,GAAG,YAAiC;CACrE,OACE,qBAAC,KAAK,MAAN;EAAW,GAAI;YAAf,CACE,oBAAC,KAAK,SAAN;GAAc,SAAA;aAAS;EAAsB,CAAA,GAC7C,oBAAC,QAAD,EAAA,UACE,oBAAC,KAAK,YAAN,EAAA,UACE,oBAAC,kBAAkB,UAAnB;GAA4B,OAAO,MAAM;aACvC,oBAAC,KAAK,SAAN,EAAe,SAAuB,CAAA;EACZ,CAAA,EACb,CAAA,EACX,CAAA,CACC;;AAEf;AACA,KAAK,cAAc;AAwBnB,IAAM,OAAO,YAA8C,OAAO,QAAQ;CACxE,MAAM,EAAE,UAAU,QAAQ,MAAM,MAAM,kBAAkB;CACxD,MAAM,QAAQ,cAAc;CAC5B,MAAM,UAAU,WAAW,iBAAiB;CAE5C,MAAM,UACJ,qBAAA,YAAA,EAAA,UAAA,CACG,QAAQ,oBAAC,MAAD,EAAM,MAAM,YAAY,OAAO,OAAO,KAAO,CAAA,GACtD,qBAAC,KAAD;EAAK,MAAK;YAAV,CACE,oBAAC,MAAD,EAAO,SAAe,CAAA,GACrB,iBAAiB,oBAAC,MAAD;GAAM,KAAK,MAAM;aAAa;EAAoB,CAAA,CACjE;GACL,EAAA,CAAA;CAGJ,IAAI,MAAM,SAAS,KAAA,GAAW;EAC5B,MAAM,EACJ,UAAU,WACV,QAAQ,SACR,MACA,MAAM,OACN,YACA,KACA,eAAe,gBACf,QACA,GAAG,SACD;EACJ,MAAM,kBAAkB,aAAa,WAAW;EAChD,MAAM,eAAe,aAAc,MAAM,GAAG,IAAI,wBAAwB,wBAAyB;EACjG,OACE,oBAAC,KAAK,MAAN;GAAW,SAAA;GAAQ,eAAa;GAAQ,GAAI;aAC1C,oBAAC,KAAD;IAAQ;IAAqC;IAAM,KAAK;IAAc,QAAQ;cAC3E;GACA,CAAA;EACM,CAAA;CAEf;CAEA,MAAM,EAAE,UAAU,WAAW,QAAQ,SAAS,MAAM,OAAO,eAAe,gBAAgB,GAAG,SAAS;CACtG,OACE,oBAAC,KAAK,MAAN;EAAW,eAAa;EAAa;EAA4B,GAAI;YAClE;CACQ,CAAA;AAEf,CAAC;AACD,KAAK,cAAc;AAKnB,IAAM,QAAQ,YAAkD,EAAE,OAAO,UAAU,GAAG,SAAS,QAAQ;CACrG,OACE,qBAAC,KAAK,WAAN;EAAqB;EAAK,GAAI;YAA9B,CACE,qBAAC,KAAK,gBAAN,EAAA,UAAA,CACE,oBAAC,MAAD,EAAA,UAAO,MAAY,CAAA,GACnB,oBAAC,WAAD,EAAiB,MAAK,IAAK,CAAA,CACR,EAAA,CAAA,GACpB,QACa;;AAEpB,CAAC;AACD,MAAM,cAAc;AAEpB,IAAM,oBAAkB;CACtB,OAAO,oBAAC,KAAK,WAAN,CAAiB,CAAA;AAC1B;AACA,YAAU,cAAc;AAExB,IAAM,mBAAmB;CACvB;CACA,WAAA;CACA;CACA;AACF"}
|
|
@@ -1,10 +1,33 @@
|
|
|
1
1
|
import { ButtonProps } from '@chakra-ui/react/button';
|
|
2
|
+
import { HTMLChakraProps, RecipeProps } from '@chakra-ui/react/styled-system';
|
|
3
|
+
import { ReactElement } from 'react';
|
|
2
4
|
import { BitkitIconComponent } from '../../icons';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
+
type BitkitButtonOmittedFromButton = 'asChild' | 'children' | 'colorPalette' | 'disabled' | 'loading' | 'loadingText' | 'spinner' | 'spinnerPlacement';
|
|
6
|
+
interface BitkitButtonCommonProps {
|
|
5
7
|
icon?: BitkitIconComponent;
|
|
6
|
-
state?: 'disabled' | 'loading' | 'skeleton';
|
|
7
8
|
suffixIcon?: BitkitIconComponent;
|
|
8
9
|
}
|
|
9
|
-
|
|
10
|
+
export interface BitkitButtonAsButtonProps extends BitkitButtonCommonProps, Omit<ButtonProps, BitkitButtonOmittedFromButton> {
|
|
11
|
+
asChild?: false;
|
|
12
|
+
children: string;
|
|
13
|
+
href?: undefined;
|
|
14
|
+
isExternal?: undefined;
|
|
15
|
+
state?: 'disabled' | 'loading' | 'skeleton';
|
|
16
|
+
}
|
|
17
|
+
export interface BitkitButtonAsAnchorProps extends BitkitButtonCommonProps, Omit<HTMLChakraProps<'a'>, 'children' | 'colorPalette'>, RecipeProps<'button'> {
|
|
18
|
+
asChild?: false;
|
|
19
|
+
children: string;
|
|
20
|
+
href: string;
|
|
21
|
+
isExternal?: boolean;
|
|
22
|
+
state?: 'disabled' | 'skeleton';
|
|
23
|
+
}
|
|
24
|
+
interface BitkitButtonAsChildProps extends BitkitButtonCommonProps, Omit<ButtonProps, BitkitButtonOmittedFromButton> {
|
|
25
|
+
asChild: true;
|
|
26
|
+
children: ReactElement;
|
|
27
|
+
href?: undefined;
|
|
28
|
+
isExternal?: undefined;
|
|
29
|
+
state?: 'disabled' | 'loading' | 'skeleton';
|
|
30
|
+
}
|
|
31
|
+
export type BitkitButtonProps = BitkitButtonAsButtonProps | BitkitButtonAsAnchorProps | BitkitButtonAsChildProps;
|
|
32
|
+
declare const BitkitButton: import('react').ForwardRefExoticComponent<BitkitButtonProps & import('react').RefAttributes<HTMLElement>>;
|
|
10
33
|
export default BitkitButton;
|
|
@@ -1,20 +1,97 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { chakra, useRecipe } from "@chakra-ui/react/styled-system";
|
|
2
|
+
import { Children, cloneElement, forwardRef } from "react";
|
|
3
|
+
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
3
4
|
import { Skeleton } from "@chakra-ui/react/skeleton";
|
|
4
5
|
import { Button } from "@chakra-ui/react/button";
|
|
5
6
|
//#region lib/components/BitkitButton/BitkitButton.tsx
|
|
6
7
|
var BitkitButton = forwardRef((props, ref) => {
|
|
7
|
-
const
|
|
8
|
-
const
|
|
8
|
+
const buttonRecipe = useRecipe({ key: "button" });
|
|
9
|
+
const Icon = props.icon;
|
|
10
|
+
const SuffixIcon = props.suffixIcon;
|
|
11
|
+
const iconSize = props.size === "sm" ? "16" : "24";
|
|
12
|
+
const isDisabled = props.state === "disabled";
|
|
13
|
+
const isSkeleton = props.state === "skeleton";
|
|
14
|
+
if (props.asChild) {
|
|
15
|
+
const { asChild: _asChild, children, icon: _icon, state, suffixIcon: _suffixIcon, ...buttonRest } = props;
|
|
16
|
+
const onlyChild = Children.only(children);
|
|
17
|
+
const buttonElement = /* @__PURE__ */ jsx(Button, {
|
|
18
|
+
asChild: true,
|
|
19
|
+
disabled: isDisabled,
|
|
20
|
+
loading: state === "loading",
|
|
21
|
+
ref,
|
|
22
|
+
...buttonRest,
|
|
23
|
+
children: cloneElement(onlyChild, void 0, /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
24
|
+
Icon && /* @__PURE__ */ jsx(Icon, {
|
|
25
|
+
marginInlineStart: "-4",
|
|
26
|
+
size: iconSize
|
|
27
|
+
}),
|
|
28
|
+
onlyChild.props.children,
|
|
29
|
+
SuffixIcon && /* @__PURE__ */ jsx(SuffixIcon, {
|
|
30
|
+
marginInlineEnd: "-4",
|
|
31
|
+
size: iconSize
|
|
32
|
+
})
|
|
33
|
+
] }))
|
|
34
|
+
});
|
|
35
|
+
return isSkeleton ? /* @__PURE__ */ jsx(Skeleton, {
|
|
36
|
+
asChild: true,
|
|
37
|
+
loading: true,
|
|
38
|
+
children: buttonElement
|
|
39
|
+
}) : buttonElement;
|
|
40
|
+
}
|
|
41
|
+
if (props.href !== void 0) {
|
|
42
|
+
const { children, css, href, icon: _icon, isExternal, onClick, onKeyDown, rel, size, state: _state, suffixIcon: _suffixIcon, target, variant, ...anchorRest } = props;
|
|
43
|
+
const effectiveTarget = isExternal ? "_blank" : target;
|
|
44
|
+
const effectiveRel = isExternal ? rel ? `${rel} noreferrer noopener` : "noreferrer noopener" : rel;
|
|
45
|
+
const handleClick = isDisabled ? (e) => {
|
|
46
|
+
e.preventDefault();
|
|
47
|
+
e.stopPropagation();
|
|
48
|
+
} : onClick;
|
|
49
|
+
const handleKeyDown = isDisabled ? (e) => {
|
|
50
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
51
|
+
e.preventDefault();
|
|
52
|
+
e.stopPropagation();
|
|
53
|
+
}
|
|
54
|
+
} : onKeyDown;
|
|
55
|
+
const anchorElement = /* @__PURE__ */ jsxs(chakra.a, {
|
|
56
|
+
ref,
|
|
57
|
+
...anchorRest,
|
|
58
|
+
"aria-disabled": isDisabled || void 0,
|
|
59
|
+
css: [buttonRecipe({
|
|
60
|
+
size,
|
|
61
|
+
variant
|
|
62
|
+
}), css],
|
|
63
|
+
href: isDisabled ? void 0 : href,
|
|
64
|
+
onClick: handleClick,
|
|
65
|
+
onKeyDown: handleKeyDown,
|
|
66
|
+
rel: effectiveRel,
|
|
67
|
+
target: effectiveTarget,
|
|
68
|
+
children: [
|
|
69
|
+
Icon && /* @__PURE__ */ jsx(Icon, {
|
|
70
|
+
marginInlineStart: "-4",
|
|
71
|
+
size: iconSize
|
|
72
|
+
}),
|
|
73
|
+
children,
|
|
74
|
+
SuffixIcon && /* @__PURE__ */ jsx(SuffixIcon, {
|
|
75
|
+
marginInlineEnd: "-4",
|
|
76
|
+
size: iconSize
|
|
77
|
+
})
|
|
78
|
+
]
|
|
79
|
+
});
|
|
80
|
+
return isSkeleton ? /* @__PURE__ */ jsx(Skeleton, {
|
|
81
|
+
asChild: true,
|
|
82
|
+
loading: true,
|
|
83
|
+
children: anchorElement
|
|
84
|
+
}) : anchorElement;
|
|
85
|
+
}
|
|
86
|
+
const { children, icon: _icon, state, suffixIcon: _suffixIcon, ...buttonRest } = props;
|
|
9
87
|
return /* @__PURE__ */ jsx(Skeleton, {
|
|
10
88
|
asChild: true,
|
|
11
|
-
loading:
|
|
89
|
+
loading: isSkeleton,
|
|
12
90
|
children: /* @__PURE__ */ jsxs(Button, {
|
|
13
|
-
disabled:
|
|
91
|
+
disabled: isDisabled,
|
|
14
92
|
loading: state === "loading",
|
|
15
93
|
ref,
|
|
16
|
-
|
|
17
|
-
...rest,
|
|
94
|
+
...buttonRest,
|
|
18
95
|
children: [
|
|
19
96
|
Icon && /* @__PURE__ */ jsx(Icon, {
|
|
20
97
|
marginInlineStart: "-4",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BitkitButton.js","names":[],"sources":["../../../lib/components/BitkitButton/BitkitButton.tsx"],"sourcesContent":["import { Button, type ButtonProps } from '@chakra-ui/react/button';\nimport { Skeleton } from '@chakra-ui/react/skeleton';\nimport { forwardRef } from 'react';\n\nimport { type BitkitIconComponent } from '../../icons';\n\
|
|
1
|
+
{"version":3,"file":"BitkitButton.js","names":[],"sources":["../../../lib/components/BitkitButton/BitkitButton.tsx"],"sourcesContent":["import { Button, type ButtonProps } from '@chakra-ui/react/button';\nimport { Skeleton } from '@chakra-ui/react/skeleton';\nimport { chakra, type HTMLChakraProps, type RecipeProps, useRecipe } from '@chakra-ui/react/styled-system';\nimport {\n Children,\n cloneElement,\n forwardRef,\n type KeyboardEvent,\n type MouseEvent,\n type ReactElement,\n type ReactNode,\n type Ref,\n} from 'react';\n\nimport { type BitkitIconComponent } from '../../icons';\n\ntype BitkitButtonOmittedFromButton =\n | 'asChild'\n | 'children'\n | 'colorPalette'\n | 'disabled'\n | 'loading'\n | 'loadingText'\n | 'spinner'\n | 'spinnerPlacement';\n\ninterface BitkitButtonCommonProps {\n icon?: BitkitIconComponent;\n suffixIcon?: BitkitIconComponent;\n}\n\nexport interface BitkitButtonAsButtonProps\n extends BitkitButtonCommonProps, Omit<ButtonProps, BitkitButtonOmittedFromButton> {\n asChild?: false;\n children: string;\n href?: undefined;\n isExternal?: undefined;\n state?: 'disabled' | 'loading' | 'skeleton';\n}\n\nexport interface BitkitButtonAsAnchorProps\n extends BitkitButtonCommonProps, Omit<HTMLChakraProps<'a'>, 'children' | 'colorPalette'>, RecipeProps<'button'> {\n asChild?: false;\n children: string;\n href: string;\n isExternal?: boolean;\n state?: 'disabled' | 'skeleton';\n}\n\ninterface BitkitButtonAsChildProps extends BitkitButtonCommonProps, Omit<ButtonProps, BitkitButtonOmittedFromButton> {\n asChild: true;\n children: ReactElement;\n href?: undefined;\n isExternal?: undefined;\n state?: 'disabled' | 'loading' | 'skeleton';\n}\n\nexport type BitkitButtonProps = BitkitButtonAsButtonProps | BitkitButtonAsAnchorProps | BitkitButtonAsChildProps;\n\n// The forwarded ref is typed as HTMLElement to cover all three modes (button, anchor, slot/asChild),\n// since asChild can render any element (router Link, custom wrappers, etc.). Inner narrow casts\n// satisfy the wrapped Chakra components without affecting the consumer-visible ref shape.\nconst BitkitButton = forwardRef<HTMLElement, BitkitButtonProps>((props, ref) => {\n const buttonRecipe = useRecipe({ key: 'button' });\n const Icon = props.icon;\n const SuffixIcon = props.suffixIcon;\n const iconSize = props.size === 'sm' ? '16' : '24';\n const isDisabled = props.state === 'disabled';\n const isSkeleton = props.state === 'skeleton';\n\n // --- Slot mode (asChild) ---\n if (props.asChild) {\n const { asChild: _asChild, children, icon: _icon, state, suffixIcon: _suffixIcon, ...buttonRest } = props;\n const onlyChild = Children.only(children) as ReactElement<{ children?: ReactNode }>;\n const buttonElement = (\n <Button\n asChild\n disabled={isDisabled}\n loading={state === 'loading'}\n ref={ref as Ref<HTMLButtonElement>}\n {...buttonRest}\n >\n {cloneElement(\n onlyChild,\n undefined,\n <>\n {Icon && <Icon marginInlineStart=\"-4\" size={iconSize} />}\n {onlyChild.props.children}\n {SuffixIcon && <SuffixIcon marginInlineEnd=\"-4\" size={iconSize} />}\n </>,\n )}\n </Button>\n );\n return isSkeleton ? (\n <Skeleton asChild loading>\n {buttonElement}\n </Skeleton>\n ) : (\n buttonElement\n );\n }\n\n // --- Anchor mode (href) ---\n if (props.href !== undefined) {\n const {\n children,\n css,\n href,\n icon: _icon,\n isExternal,\n onClick,\n onKeyDown,\n rel,\n size,\n state: _state,\n suffixIcon: _suffixIcon,\n target,\n variant,\n ...anchorRest\n } = props;\n const effectiveTarget = isExternal ? '_blank' : target;\n const effectiveRel = isExternal ? (rel ? `${rel} noreferrer noopener` : 'noreferrer noopener') : rel;\n const handleClick = isDisabled\n ? (e: MouseEvent<HTMLAnchorElement>) => {\n e.preventDefault();\n e.stopPropagation();\n }\n : onClick;\n const handleKeyDown = isDisabled\n ? (e: KeyboardEvent<HTMLAnchorElement>) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n e.stopPropagation();\n }\n }\n : onKeyDown;\n const anchorElement = (\n <chakra.a\n ref={ref as Ref<HTMLAnchorElement>}\n {...anchorRest}\n aria-disabled={isDisabled || undefined}\n css={[buttonRecipe({ size, variant }), css]}\n href={isDisabled ? undefined : href}\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n rel={effectiveRel}\n target={effectiveTarget}\n >\n {Icon && <Icon marginInlineStart=\"-4\" size={iconSize} />}\n {children}\n {SuffixIcon && <SuffixIcon marginInlineEnd=\"-4\" size={iconSize} />}\n </chakra.a>\n );\n return isSkeleton ? (\n <Skeleton asChild loading>\n {anchorElement}\n </Skeleton>\n ) : (\n anchorElement\n );\n }\n\n // --- Button mode (default) ---\n const { children, icon: _icon, state, suffixIcon: _suffixIcon, ...buttonRest } = props;\n return (\n <Skeleton asChild loading={isSkeleton}>\n <Button disabled={isDisabled} loading={state === 'loading'} ref={ref as Ref<HTMLButtonElement>} {...buttonRest}>\n {Icon && <Icon marginInlineStart=\"-4\" size={iconSize} />}\n {children}\n {SuffixIcon && <SuffixIcon marginInlineEnd=\"-4\" size={iconSize} />}\n </Button>\n </Skeleton>\n );\n});\n\nBitkitButton.displayName = 'BitkitButton';\n\nexport default BitkitButton;\n"],"mappings":";;;;;;AA8DA,IAAM,eAAe,YAA4C,OAAO,QAAQ;CAC9E,MAAM,eAAe,UAAU,EAAE,KAAK,SAAS,CAAC;CAChD,MAAM,OAAO,MAAM;CACnB,MAAM,aAAa,MAAM;CACzB,MAAM,WAAW,MAAM,SAAS,OAAO,OAAO;CAC9C,MAAM,aAAa,MAAM,UAAU;CACnC,MAAM,aAAa,MAAM,UAAU;CAGnC,IAAI,MAAM,SAAS;EACjB,MAAM,EAAE,SAAS,UAAU,UAAU,MAAM,OAAO,OAAO,YAAY,aAAa,GAAG,eAAe;EACpG,MAAM,YAAY,SAAS,KAAK,QAAQ;EACxC,MAAM,gBACJ,oBAAC,QAAD;GACE,SAAA;GACA,UAAU;GACV,SAAS,UAAU;GACd;GACL,GAAI;aAEH,aACC,WACA,KAAA,GACA,qBAAA,YAAA,EAAA,UAAA;IACG,QAAQ,oBAAC,MAAD;KAAM,mBAAkB;KAAK,MAAM;IAAW,CAAA;IACtD,UAAU,MAAM;IAChB,cAAc,oBAAC,YAAD;KAAY,iBAAgB;KAAK,MAAM;IAAW,CAAA;GACjE,EAAA,CAAA,CACJ;EACM,CAAA;EAEV,OAAO,aACL,oBAAC,UAAD;GAAU,SAAA;GAAQ,SAAA;aACf;EACO,CAAA,IAEV;CAEJ;CAGA,IAAI,MAAM,SAAS,KAAA,GAAW;EAC5B,MAAM,EACJ,UACA,KACA,MACA,MAAM,OACN,YACA,SACA,WACA,KACA,MACA,OAAO,QACP,YAAY,aACZ,QACA,SACA,GAAG,eACD;EACJ,MAAM,kBAAkB,aAAa,WAAW;EAChD,MAAM,eAAe,aAAc,MAAM,GAAG,IAAI,wBAAwB,wBAAyB;EACjG,MAAM,cAAc,cACf,MAAqC;GACpC,EAAE,eAAe;GACjB,EAAE,gBAAgB;EACpB,IACA;EACJ,MAAM,gBAAgB,cACjB,MAAwC;GACvC,IAAI,EAAE,QAAQ,WAAW,EAAE,QAAQ,KAAK;IACtC,EAAE,eAAe;IACjB,EAAE,gBAAgB;GACpB;EACF,IACA;EACJ,MAAM,gBACJ,qBAAC,OAAO,GAAR;GACO;GACL,GAAI;GACJ,iBAAe,cAAc,KAAA;GAC7B,KAAK,CAAC,aAAa;IAAE;IAAM;GAAQ,CAAC,GAAG,GAAG;GAC1C,MAAM,aAAa,KAAA,IAAY;GAC/B,SAAS;GACT,WAAW;GACX,KAAK;GACL,QAAQ;aATV;IAWG,QAAQ,oBAAC,MAAD;KAAM,mBAAkB;KAAK,MAAM;IAAW,CAAA;IACtD;IACA,cAAc,oBAAC,YAAD;KAAY,iBAAgB;KAAK,MAAM;IAAW,CAAA;GACzD;;EAEZ,OAAO,aACL,oBAAC,UAAD;GAAU,SAAA;GAAQ,SAAA;aACf;EACO,CAAA,IAEV;CAEJ;CAGA,MAAM,EAAE,UAAU,MAAM,OAAO,OAAO,YAAY,aAAa,GAAG,eAAe;CACjF,OACE,oBAAC,UAAD;EAAU,SAAA;EAAQ,SAAS;YACzB,qBAAC,QAAD;GAAQ,UAAU;GAAY,SAAS,UAAU;GAAgB;GAA+B,GAAI;aAApG;IACG,QAAQ,oBAAC,MAAD;KAAM,mBAAkB;KAAK,MAAM;IAAW,CAAA;IACtD;IACA,cAAc,oBAAC,YAAD;KAAY,iBAAgB;KAAK,MAAM;IAAW,CAAA;GAC3D;;CACA,CAAA;AAEd,CAAC;AAED,aAAa,cAAc"}
|
|
@@ -2,7 +2,7 @@ import { HTMLChakraProps } from '@chakra-ui/react/styled-system';
|
|
|
2
2
|
import { BitkitIconComponent } from '../../icons';
|
|
3
3
|
import { BitkitLabelTooltipProps } from '../BitkitLabelTooltip/BitkitLabelTooltip';
|
|
4
4
|
type ControlButtonSize = 'xxs' | 'xs' | 'sm' | 'md' | 'lg';
|
|
5
|
-
|
|
5
|
+
interface BitkitControlButtonCommonProps {
|
|
6
6
|
icon: BitkitIconComponent;
|
|
7
7
|
isDanger?: boolean;
|
|
8
8
|
label: string;
|
|
@@ -10,5 +10,14 @@ export interface BitkitControlButtonProps extends Omit<HTMLChakraProps<'button'>
|
|
|
10
10
|
state?: 'disabled' | 'skeleton';
|
|
11
11
|
tooltipProps?: Partial<Omit<BitkitLabelTooltipProps, 'children' | 'text'>>;
|
|
12
12
|
}
|
|
13
|
-
|
|
13
|
+
interface BitkitControlButtonAsButtonProps extends BitkitControlButtonCommonProps, Omit<HTMLChakraProps<'button'>, 'children' | 'disabled' | 'size'> {
|
|
14
|
+
href?: undefined;
|
|
15
|
+
isExternal?: undefined;
|
|
16
|
+
}
|
|
17
|
+
interface BitkitControlButtonAsAnchorProps extends BitkitControlButtonCommonProps, Omit<HTMLChakraProps<'a'>, 'children' | 'size'> {
|
|
18
|
+
href: string;
|
|
19
|
+
isExternal?: boolean;
|
|
20
|
+
}
|
|
21
|
+
export type BitkitControlButtonProps = BitkitControlButtonAsButtonProps | BitkitControlButtonAsAnchorProps;
|
|
22
|
+
declare const BitkitControlButton: import('react').ForwardRefExoticComponent<BitkitControlButtonProps & import('react').RefAttributes<HTMLButtonElement | HTMLAnchorElement>>;
|
|
14
23
|
export default BitkitControlButton;
|
|
@@ -5,9 +5,52 @@ import { jsx } from "react/jsx-runtime";
|
|
|
5
5
|
import { Skeleton } from "@chakra-ui/react/skeleton";
|
|
6
6
|
//#region lib/components/BitkitControlButton/BitkitControlButton.tsx
|
|
7
7
|
var BitkitControlButton = forwardRef((props, ref) => {
|
|
8
|
-
const
|
|
8
|
+
const Icon = props.icon;
|
|
9
|
+
const size = props.size ?? "sm";
|
|
9
10
|
const recipe = useRecipe({ key: "controlButton" });
|
|
10
11
|
const iconSize = size === "xxs" || size === "xs" ? "16" : "24";
|
|
12
|
+
const isDisabled = props.state === "disabled";
|
|
13
|
+
const isSkeleton = props.state === "skeleton";
|
|
14
|
+
const inertOnClick = isDisabled || isSkeleton;
|
|
15
|
+
if (props.href !== void 0) {
|
|
16
|
+
const { href, icon: _icon, isDanger, isExternal, label, onClick, onKeyDown, rel, size: _size, state: _state, target, tooltipProps, ...anchorRest } = props;
|
|
17
|
+
const effectiveTarget = isExternal ? "_blank" : target;
|
|
18
|
+
const effectiveRel = isExternal ? rel ? `${rel} noreferrer noopener` : "noreferrer noopener" : rel;
|
|
19
|
+
const handleClick = inertOnClick ? (e) => {
|
|
20
|
+
e.preventDefault();
|
|
21
|
+
e.stopPropagation();
|
|
22
|
+
} : onClick;
|
|
23
|
+
const handleKeyDown = inertOnClick ? (e) => {
|
|
24
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
25
|
+
e.preventDefault();
|
|
26
|
+
e.stopPropagation();
|
|
27
|
+
}
|
|
28
|
+
} : onKeyDown;
|
|
29
|
+
return /* @__PURE__ */ jsx(BitkitLabelTooltip, {
|
|
30
|
+
text: label,
|
|
31
|
+
...tooltipProps,
|
|
32
|
+
children: /* @__PURE__ */ jsx(chakra.a, {
|
|
33
|
+
ref,
|
|
34
|
+
"aria-disabled": inertOnClick || void 0,
|
|
35
|
+
"aria-label": label,
|
|
36
|
+
...anchorRest,
|
|
37
|
+
css: recipe({
|
|
38
|
+
isDanger,
|
|
39
|
+
size
|
|
40
|
+
}),
|
|
41
|
+
href: inertOnClick ? void 0 : href,
|
|
42
|
+
onClick: handleClick,
|
|
43
|
+
onKeyDown: handleKeyDown,
|
|
44
|
+
rel: effectiveRel,
|
|
45
|
+
target: effectiveTarget,
|
|
46
|
+
children: /* @__PURE__ */ jsx(Skeleton, {
|
|
47
|
+
loading: isSkeleton,
|
|
48
|
+
children: /* @__PURE__ */ jsx(Icon, { size: iconSize })
|
|
49
|
+
})
|
|
50
|
+
})
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
const { icon: _icon, isDanger, label, size: _size, state, tooltipProps, ...buttonRest } = props;
|
|
11
54
|
return /* @__PURE__ */ jsx(BitkitLabelTooltip, {
|
|
12
55
|
text: label,
|
|
13
56
|
...tooltipProps,
|
|
@@ -15,13 +58,13 @@ var BitkitControlButton = forwardRef((props, ref) => {
|
|
|
15
58
|
ref,
|
|
16
59
|
"aria-label": label,
|
|
17
60
|
disabled: state === "disabled" || state === "skeleton",
|
|
18
|
-
...
|
|
61
|
+
...buttonRest,
|
|
19
62
|
css: recipe({
|
|
20
63
|
isDanger,
|
|
21
64
|
size
|
|
22
65
|
}),
|
|
23
66
|
children: /* @__PURE__ */ jsx(Skeleton, {
|
|
24
|
-
loading:
|
|
67
|
+
loading: isSkeleton,
|
|
25
68
|
children: /* @__PURE__ */ jsx(Icon, { size: iconSize })
|
|
26
69
|
})
|
|
27
70
|
})
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BitkitControlButton.js","names":[],"sources":["../../../lib/components/BitkitControlButton/BitkitControlButton.tsx"],"sourcesContent":["import { Skeleton } from '@chakra-ui/react/skeleton';\nimport { chakra, type HTMLChakraProps, useRecipe } from '@chakra-ui/react/styled-system';\nimport { forwardRef } from 'react';\n\nimport { type BitkitIconComponent } from '../../icons';\nimport BitkitLabelTooltip, { type BitkitLabelTooltipProps } from '../BitkitLabelTooltip/BitkitLabelTooltip';\n\ntype ControlButtonSize = 'xxs' | 'xs' | 'sm' | 'md' | 'lg';\n\
|
|
1
|
+
{"version":3,"file":"BitkitControlButton.js","names":[],"sources":["../../../lib/components/BitkitControlButton/BitkitControlButton.tsx"],"sourcesContent":["import { Skeleton } from '@chakra-ui/react/skeleton';\nimport { chakra, type HTMLChakraProps, useRecipe } from '@chakra-ui/react/styled-system';\nimport { forwardRef, type KeyboardEvent, type MouseEvent, type Ref } from 'react';\n\nimport { type BitkitIconComponent } from '../../icons';\nimport BitkitLabelTooltip, { type BitkitLabelTooltipProps } from '../BitkitLabelTooltip/BitkitLabelTooltip';\n\ntype ControlButtonSize = 'xxs' | 'xs' | 'sm' | 'md' | 'lg';\n\ninterface BitkitControlButtonCommonProps {\n icon: BitkitIconComponent;\n isDanger?: boolean;\n label: string;\n size?: ControlButtonSize;\n state?: 'disabled' | 'skeleton';\n tooltipProps?: Partial<Omit<BitkitLabelTooltipProps, 'children' | 'text'>>;\n}\n\ninterface BitkitControlButtonAsButtonProps\n extends BitkitControlButtonCommonProps, Omit<HTMLChakraProps<'button'>, 'children' | 'disabled' | 'size'> {\n href?: undefined;\n isExternal?: undefined;\n}\n\ninterface BitkitControlButtonAsAnchorProps\n extends BitkitControlButtonCommonProps, Omit<HTMLChakraProps<'a'>, 'children' | 'size'> {\n href: string;\n isExternal?: boolean;\n}\n\nexport type BitkitControlButtonProps = BitkitControlButtonAsButtonProps | BitkitControlButtonAsAnchorProps;\n\nconst BitkitControlButton = forwardRef<HTMLButtonElement | HTMLAnchorElement, BitkitControlButtonProps>(\n (props, ref) => {\n const Icon = props.icon;\n const size = props.size ?? 'sm';\n const recipe = useRecipe({ key: 'controlButton' });\n const iconSize = size === 'xxs' || size === 'xs' ? '16' : '24';\n const isDisabled = props.state === 'disabled';\n const isSkeleton = props.state === 'skeleton';\n const inertOnClick = isDisabled || isSkeleton;\n\n // --- Anchor mode (href) ---\n if (props.href !== undefined) {\n const {\n href,\n icon: _icon,\n isDanger,\n isExternal,\n label,\n onClick,\n onKeyDown,\n rel,\n size: _size,\n state: _state,\n target,\n tooltipProps,\n ...anchorRest\n } = props;\n const effectiveTarget = isExternal ? '_blank' : target;\n const effectiveRel = isExternal ? (rel ? `${rel} noreferrer noopener` : 'noreferrer noopener') : rel;\n const handleClick = inertOnClick\n ? (e: MouseEvent<HTMLAnchorElement>) => {\n e.preventDefault();\n e.stopPropagation();\n }\n : onClick;\n const handleKeyDown = inertOnClick\n ? (e: KeyboardEvent<HTMLAnchorElement>) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n e.stopPropagation();\n }\n }\n : onKeyDown;\n return (\n <BitkitLabelTooltip text={label} {...tooltipProps}>\n <chakra.a\n ref={ref as Ref<HTMLAnchorElement>}\n aria-disabled={inertOnClick || undefined}\n aria-label={label}\n {...anchorRest}\n css={recipe({ isDanger, size })}\n href={inertOnClick ? undefined : href}\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n rel={effectiveRel}\n target={effectiveTarget}\n >\n <Skeleton loading={isSkeleton}>\n <Icon size={iconSize} />\n </Skeleton>\n </chakra.a>\n </BitkitLabelTooltip>\n );\n }\n\n // --- Button mode (default) ---\n const { icon: _icon, isDanger, label, size: _size, state, tooltipProps, ...buttonRest } = props;\n return (\n <BitkitLabelTooltip text={label} {...tooltipProps}>\n <chakra.button\n ref={ref as Ref<HTMLButtonElement>}\n aria-label={label}\n disabled={state === 'disabled' || state === 'skeleton'}\n {...buttonRest}\n css={recipe({ isDanger, size })}\n >\n <Skeleton loading={isSkeleton}>\n <Icon size={iconSize} />\n </Skeleton>\n </chakra.button>\n </BitkitLabelTooltip>\n );\n },\n);\n\nBitkitControlButton.displayName = 'BitkitControlButton';\n\nexport default BitkitControlButton;\n"],"mappings":";;;;;;AAgCA,IAAM,sBAAsB,YACzB,OAAO,QAAQ;CACd,MAAM,OAAO,MAAM;CACnB,MAAM,OAAO,MAAM,QAAQ;CAC3B,MAAM,SAAS,UAAU,EAAE,KAAK,gBAAgB,CAAC;CACjD,MAAM,WAAW,SAAS,SAAS,SAAS,OAAO,OAAO;CAC1D,MAAM,aAAa,MAAM,UAAU;CACnC,MAAM,aAAa,MAAM,UAAU;CACnC,MAAM,eAAe,cAAc;CAGnC,IAAI,MAAM,SAAS,KAAA,GAAW;EAC5B,MAAM,EACJ,MACA,MAAM,OACN,UACA,YACA,OACA,SACA,WACA,KACA,MAAM,OACN,OAAO,QACP,QACA,cACA,GAAG,eACD;EACJ,MAAM,kBAAkB,aAAa,WAAW;EAChD,MAAM,eAAe,aAAc,MAAM,GAAG,IAAI,wBAAwB,wBAAyB;EACjG,MAAM,cAAc,gBACf,MAAqC;GACpC,EAAE,eAAe;GACjB,EAAE,gBAAgB;EACpB,IACA;EACJ,MAAM,gBAAgB,gBACjB,MAAwC;GACvC,IAAI,EAAE,QAAQ,WAAW,EAAE,QAAQ,KAAK;IACtC,EAAE,eAAe;IACjB,EAAE,gBAAgB;GACpB;EACF,IACA;EACJ,OACE,oBAAC,oBAAD;GAAoB,MAAM;GAAO,GAAI;aACnC,oBAAC,OAAO,GAAR;IACO;IACL,iBAAe,gBAAgB,KAAA;IAC/B,cAAY;IACZ,GAAI;IACJ,KAAK,OAAO;KAAE;KAAU;IAAK,CAAC;IAC9B,MAAM,eAAe,KAAA,IAAY;IACjC,SAAS;IACT,WAAW;IACX,KAAK;IACL,QAAQ;cAER,oBAAC,UAAD;KAAU,SAAS;eACjB,oBAAC,MAAD,EAAM,MAAM,SAAW,CAAA;IACf,CAAA;GACF,CAAA;EACQ,CAAA;CAExB;CAGA,MAAM,EAAE,MAAM,OAAO,UAAU,OAAO,MAAM,OAAO,OAAO,cAAc,GAAG,eAAe;CAC1F,OACE,oBAAC,oBAAD;EAAoB,MAAM;EAAO,GAAI;YACnC,oBAAC,OAAO,QAAR;GACO;GACL,cAAY;GACZ,UAAU,UAAU,cAAc,UAAU;GAC5C,GAAI;GACJ,KAAK,OAAO;IAAE;IAAU;GAAK,CAAC;aAE9B,oBAAC,UAAD;IAAU,SAAS;cACjB,oBAAC,MAAD,EAAM,MAAM,SAAW,CAAA;GACf,CAAA;EACG,CAAA;CACG,CAAA;AAExB,CACF;AAEA,oBAAoB,cAAc"}
|
|
@@ -1,11 +1,33 @@
|
|
|
1
1
|
import { IconButtonProps } from '@chakra-ui/react/button';
|
|
2
|
+
import { HTMLChakraProps, RecipeProps } from '@chakra-ui/react/styled-system';
|
|
3
|
+
import { ReactElement } from 'react';
|
|
2
4
|
import { BitkitIconComponent } from '../../icons';
|
|
3
5
|
import { BitkitLabelTooltipProps } from '../BitkitLabelTooltip/BitkitLabelTooltip';
|
|
4
|
-
|
|
6
|
+
type BitkitIconButtonOmittedFromButton = 'aria-label' | 'asChild' | 'children' | 'colorPalette' | 'disabled' | 'loading' | 'loadingText' | 'spinner' | 'spinnerPlacement';
|
|
7
|
+
interface BitkitIconButtonCommonProps {
|
|
5
8
|
icon: BitkitIconComponent;
|
|
6
9
|
label: string;
|
|
7
|
-
state?: 'disabled' | 'loading' | 'skeleton';
|
|
8
10
|
tooltipProps?: Partial<Omit<BitkitLabelTooltipProps, 'children' | 'text'>>;
|
|
9
11
|
}
|
|
10
|
-
|
|
12
|
+
interface BitkitIconButtonAsButtonProps extends BitkitIconButtonCommonProps, Omit<IconButtonProps, BitkitIconButtonOmittedFromButton> {
|
|
13
|
+
asChild?: false;
|
|
14
|
+
href?: undefined;
|
|
15
|
+
isExternal?: undefined;
|
|
16
|
+
state?: 'disabled' | 'loading' | 'skeleton';
|
|
17
|
+
}
|
|
18
|
+
interface BitkitIconButtonAsAnchorProps extends BitkitIconButtonCommonProps, Omit<HTMLChakraProps<'a'>, 'aria-label' | 'children' | 'colorPalette'>, RecipeProps<'button'> {
|
|
19
|
+
asChild?: false;
|
|
20
|
+
href: string;
|
|
21
|
+
isExternal?: boolean;
|
|
22
|
+
state?: 'disabled' | 'skeleton';
|
|
23
|
+
}
|
|
24
|
+
interface BitkitIconButtonAsChildProps extends BitkitIconButtonCommonProps, Omit<IconButtonProps, BitkitIconButtonOmittedFromButton> {
|
|
25
|
+
asChild: true;
|
|
26
|
+
children: ReactElement;
|
|
27
|
+
href?: undefined;
|
|
28
|
+
isExternal?: undefined;
|
|
29
|
+
state?: 'disabled' | 'loading' | 'skeleton';
|
|
30
|
+
}
|
|
31
|
+
export type BitkitIconButtonProps = BitkitIconButtonAsButtonProps | BitkitIconButtonAsAnchorProps | BitkitIconButtonAsChildProps;
|
|
32
|
+
declare const BitkitIconButton: import('react').ForwardRefExoticComponent<BitkitIconButtonProps & import('react').RefAttributes<HTMLElement>>;
|
|
11
33
|
export default BitkitIconButton;
|
|
@@ -1,25 +1,98 @@
|
|
|
1
1
|
import BitkitLabelTooltip from "../BitkitLabelTooltip/BitkitLabelTooltip.js";
|
|
2
|
-
import {
|
|
2
|
+
import { chakra, useRecipe } from "@chakra-ui/react/styled-system";
|
|
3
|
+
import { Children, cloneElement, forwardRef } from "react";
|
|
3
4
|
import { jsx } from "react/jsx-runtime";
|
|
4
5
|
import { Skeleton } from "@chakra-ui/react/skeleton";
|
|
5
6
|
import { IconButton } from "@chakra-ui/react/button";
|
|
6
7
|
//#region lib/components/BitkitIconButton/BitkitIconButton.tsx
|
|
7
8
|
var BitkitIconButton = forwardRef((props, ref) => {
|
|
8
|
-
const {
|
|
9
|
-
const
|
|
9
|
+
const buttonRecipe = useRecipe({ key: "button" });
|
|
10
|
+
const Icon = props.icon;
|
|
11
|
+
const iconSize = props.size === "lg" ? "24" : "16";
|
|
12
|
+
const isDisabled = props.state === "disabled";
|
|
13
|
+
const isSkeleton = props.state === "skeleton";
|
|
14
|
+
if (props.asChild) {
|
|
15
|
+
const { asChild: _asChild, children, icon: _icon, label, state, tooltipProps, ...buttonRest } = props;
|
|
16
|
+
const onlyChild = Children.only(children);
|
|
17
|
+
const iconButtonElement = /* @__PURE__ */ jsx(IconButton, {
|
|
18
|
+
asChild: true,
|
|
19
|
+
"aria-label": label,
|
|
20
|
+
disabled: isDisabled,
|
|
21
|
+
loading: state === "loading",
|
|
22
|
+
ref,
|
|
23
|
+
...buttonRest,
|
|
24
|
+
children: cloneElement(onlyChild, { "aria-label": onlyChild.props["aria-label"] ?? label }, /* @__PURE__ */ jsx(Icon, { size: iconSize }))
|
|
25
|
+
});
|
|
26
|
+
return /* @__PURE__ */ jsx(BitkitLabelTooltip, {
|
|
27
|
+
text: label,
|
|
28
|
+
...tooltipProps,
|
|
29
|
+
children: isSkeleton ? /* @__PURE__ */ jsx(Skeleton, {
|
|
30
|
+
asChild: true,
|
|
31
|
+
loading: true,
|
|
32
|
+
children: iconButtonElement
|
|
33
|
+
}) : iconButtonElement
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
if (props.href !== void 0) {
|
|
37
|
+
const { css, href, icon: _icon, isExternal, label, onClick, onKeyDown, rel, size, state: _state, target, tooltipProps, variant, ...anchorRest } = props;
|
|
38
|
+
const effectiveTarget = isExternal ? "_blank" : target;
|
|
39
|
+
const effectiveRel = isExternal ? rel ? `${rel} noreferrer noopener` : "noreferrer noopener" : rel;
|
|
40
|
+
const handleClick = isDisabled ? (e) => {
|
|
41
|
+
e.preventDefault();
|
|
42
|
+
e.stopPropagation();
|
|
43
|
+
} : onClick;
|
|
44
|
+
const handleKeyDown = isDisabled ? (e) => {
|
|
45
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
46
|
+
e.preventDefault();
|
|
47
|
+
e.stopPropagation();
|
|
48
|
+
}
|
|
49
|
+
} : onKeyDown;
|
|
50
|
+
const anchorElement = /* @__PURE__ */ jsx(chakra.a, {
|
|
51
|
+
ref,
|
|
52
|
+
...anchorRest,
|
|
53
|
+
"aria-disabled": isDisabled || void 0,
|
|
54
|
+
"aria-label": label,
|
|
55
|
+
css: [
|
|
56
|
+
buttonRecipe({
|
|
57
|
+
size,
|
|
58
|
+
variant
|
|
59
|
+
}),
|
|
60
|
+
{
|
|
61
|
+
paddingBlock: 0,
|
|
62
|
+
paddingInline: 0
|
|
63
|
+
},
|
|
64
|
+
css
|
|
65
|
+
],
|
|
66
|
+
href: isDisabled ? void 0 : href,
|
|
67
|
+
onClick: handleClick,
|
|
68
|
+
onKeyDown: handleKeyDown,
|
|
69
|
+
rel: effectiveRel,
|
|
70
|
+
target: effectiveTarget,
|
|
71
|
+
children: /* @__PURE__ */ jsx(Icon, { size: iconSize })
|
|
72
|
+
});
|
|
73
|
+
return /* @__PURE__ */ jsx(BitkitLabelTooltip, {
|
|
74
|
+
text: label,
|
|
75
|
+
...tooltipProps,
|
|
76
|
+
children: isSkeleton ? /* @__PURE__ */ jsx(Skeleton, {
|
|
77
|
+
asChild: true,
|
|
78
|
+
loading: true,
|
|
79
|
+
children: anchorElement
|
|
80
|
+
}) : anchorElement
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
const { icon: _icon, label, state, tooltipProps, ...buttonRest } = props;
|
|
10
84
|
return /* @__PURE__ */ jsx(BitkitLabelTooltip, {
|
|
11
85
|
text: label,
|
|
12
86
|
...tooltipProps,
|
|
13
87
|
children: /* @__PURE__ */ jsx(Skeleton, {
|
|
14
88
|
asChild: true,
|
|
15
|
-
loading:
|
|
89
|
+
loading: isSkeleton,
|
|
16
90
|
children: /* @__PURE__ */ jsx(IconButton, {
|
|
17
91
|
"aria-label": label,
|
|
18
|
-
disabled:
|
|
92
|
+
disabled: isDisabled,
|
|
19
93
|
loading: state === "loading",
|
|
20
94
|
ref,
|
|
21
|
-
|
|
22
|
-
...rest,
|
|
95
|
+
...buttonRest,
|
|
23
96
|
children: /* @__PURE__ */ jsx(Icon, { size: iconSize })
|
|
24
97
|
})
|
|
25
98
|
})
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BitkitIconButton.js","names":[],"sources":["../../../lib/components/BitkitIconButton/BitkitIconButton.tsx"],"sourcesContent":["import { IconButton, type IconButtonProps } from '@chakra-ui/react/button';\nimport { Skeleton } from '@chakra-ui/react/skeleton';\nimport { forwardRef } from 'react';\n\nimport { type BitkitIconComponent } from '../../icons';\nimport BitkitLabelTooltip, { type BitkitLabelTooltipProps } from '../BitkitLabelTooltip/BitkitLabelTooltip';\n\
|
|
1
|
+
{"version":3,"file":"BitkitIconButton.js","names":[],"sources":["../../../lib/components/BitkitIconButton/BitkitIconButton.tsx"],"sourcesContent":["import { IconButton, type IconButtonProps } from '@chakra-ui/react/button';\nimport { Skeleton } from '@chakra-ui/react/skeleton';\nimport { chakra, type HTMLChakraProps, type RecipeProps, useRecipe } from '@chakra-ui/react/styled-system';\nimport {\n Children,\n cloneElement,\n forwardRef,\n type KeyboardEvent,\n type MouseEvent,\n type ReactElement,\n type Ref,\n} from 'react';\n\nimport { type BitkitIconComponent } from '../../icons';\nimport BitkitLabelTooltip, { type BitkitLabelTooltipProps } from '../BitkitLabelTooltip/BitkitLabelTooltip';\n\ntype BitkitIconButtonOmittedFromButton =\n | 'aria-label'\n | 'asChild'\n | 'children'\n | 'colorPalette'\n | 'disabled'\n | 'loading'\n | 'loadingText'\n | 'spinner'\n | 'spinnerPlacement';\n\ninterface BitkitIconButtonCommonProps {\n icon: BitkitIconComponent;\n label: string;\n tooltipProps?: Partial<Omit<BitkitLabelTooltipProps, 'children' | 'text'>>;\n}\n\ninterface BitkitIconButtonAsButtonProps\n extends BitkitIconButtonCommonProps, Omit<IconButtonProps, BitkitIconButtonOmittedFromButton> {\n asChild?: false;\n href?: undefined;\n isExternal?: undefined;\n state?: 'disabled' | 'loading' | 'skeleton';\n}\n\ninterface BitkitIconButtonAsAnchorProps\n extends\n BitkitIconButtonCommonProps,\n Omit<HTMLChakraProps<'a'>, 'aria-label' | 'children' | 'colorPalette'>,\n RecipeProps<'button'> {\n asChild?: false;\n href: string;\n isExternal?: boolean;\n state?: 'disabled' | 'skeleton';\n}\n\ninterface BitkitIconButtonAsChildProps\n extends BitkitIconButtonCommonProps, Omit<IconButtonProps, BitkitIconButtonOmittedFromButton> {\n asChild: true;\n children: ReactElement;\n href?: undefined;\n isExternal?: undefined;\n state?: 'disabled' | 'loading' | 'skeleton';\n}\n\nexport type BitkitIconButtonProps =\n | BitkitIconButtonAsButtonProps\n | BitkitIconButtonAsAnchorProps\n | BitkitIconButtonAsChildProps;\n\n// The forwarded ref is typed as HTMLElement to cover all three modes (button, anchor, slot/asChild),\n// since asChild can render any element (router Link, custom wrappers, etc.). Inner narrow casts\n// satisfy the wrapped Chakra components without affecting the consumer-visible ref shape.\nconst BitkitIconButton = forwardRef<HTMLElement, BitkitIconButtonProps>((props, ref) => {\n const buttonRecipe = useRecipe({ key: 'button' });\n const Icon = props.icon;\n const iconSize = props.size === 'lg' ? '24' : '16';\n const isDisabled = props.state === 'disabled';\n const isSkeleton = props.state === 'skeleton';\n\n // --- Slot mode (asChild) ---\n if (props.asChild) {\n const { asChild: _asChild, children, icon: _icon, label, state, tooltipProps, ...buttonRest } = props;\n const onlyChild = Children.only(children) as ReactElement<{ 'aria-label'?: string }>;\n const iconButtonElement = (\n <IconButton\n asChild\n aria-label={label}\n disabled={isDisabled}\n loading={state === 'loading'}\n ref={ref as Ref<HTMLButtonElement>}\n {...buttonRest}\n >\n {cloneElement(onlyChild, { 'aria-label': onlyChild.props['aria-label'] ?? label }, <Icon size={iconSize} />)}\n </IconButton>\n );\n return (\n <BitkitLabelTooltip text={label} {...tooltipProps}>\n {isSkeleton ? (\n <Skeleton asChild loading>\n {iconButtonElement}\n </Skeleton>\n ) : (\n iconButtonElement\n )}\n </BitkitLabelTooltip>\n );\n }\n\n // --- Anchor mode (href) ---\n if (props.href !== undefined) {\n const {\n css,\n href,\n icon: _icon,\n isExternal,\n label,\n onClick,\n onKeyDown,\n rel,\n size,\n state: _state,\n target,\n tooltipProps,\n variant,\n ...anchorRest\n } = props;\n const effectiveTarget = isExternal ? '_blank' : target;\n const effectiveRel = isExternal ? (rel ? `${rel} noreferrer noopener` : 'noreferrer noopener') : rel;\n const handleClick = isDisabled\n ? (e: MouseEvent<HTMLAnchorElement>) => {\n e.preventDefault();\n e.stopPropagation();\n }\n : onClick;\n const handleKeyDown = isDisabled\n ? (e: KeyboardEvent<HTMLAnchorElement>) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n e.stopPropagation();\n }\n }\n : onKeyDown;\n const anchorElement = (\n <chakra.a\n ref={ref as Ref<HTMLAnchorElement>}\n {...anchorRest}\n aria-disabled={isDisabled || undefined}\n aria-label={label}\n css={[buttonRecipe({ size, variant }), { paddingBlock: 0, paddingInline: 0 }, css]}\n href={isDisabled ? undefined : href}\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n rel={effectiveRel}\n target={effectiveTarget}\n >\n <Icon size={iconSize} />\n </chakra.a>\n );\n return (\n <BitkitLabelTooltip text={label} {...tooltipProps}>\n {isSkeleton ? (\n <Skeleton asChild loading>\n {anchorElement}\n </Skeleton>\n ) : (\n anchorElement\n )}\n </BitkitLabelTooltip>\n );\n }\n\n // --- Button mode (default) ---\n const { icon: _icon, label, state, tooltipProps, ...buttonRest } = props;\n return (\n <BitkitLabelTooltip text={label} {...tooltipProps}>\n <Skeleton asChild loading={isSkeleton}>\n <IconButton\n aria-label={label}\n disabled={isDisabled}\n loading={state === 'loading'}\n ref={ref as Ref<HTMLButtonElement>}\n {...buttonRest}\n >\n <Icon size={iconSize} />\n </IconButton>\n </Skeleton>\n </BitkitLabelTooltip>\n );\n});\n\nBitkitIconButton.displayName = 'BitkitIconButton';\n\nexport default BitkitIconButton;\n"],"mappings":";;;;;;;AAqEA,IAAM,mBAAmB,YAAgD,OAAO,QAAQ;CACtF,MAAM,eAAe,UAAU,EAAE,KAAK,SAAS,CAAC;CAChD,MAAM,OAAO,MAAM;CACnB,MAAM,WAAW,MAAM,SAAS,OAAO,OAAO;CAC9C,MAAM,aAAa,MAAM,UAAU;CACnC,MAAM,aAAa,MAAM,UAAU;CAGnC,IAAI,MAAM,SAAS;EACjB,MAAM,EAAE,SAAS,UAAU,UAAU,MAAM,OAAO,OAAO,OAAO,cAAc,GAAG,eAAe;EAChG,MAAM,YAAY,SAAS,KAAK,QAAQ;EACxC,MAAM,oBACJ,oBAAC,YAAD;GACE,SAAA;GACA,cAAY;GACZ,UAAU;GACV,SAAS,UAAU;GACd;GACL,GAAI;aAEH,aAAa,WAAW,EAAE,cAAc,UAAU,MAAM,iBAAiB,MAAM,GAAG,oBAAC,MAAD,EAAM,MAAM,SAAW,CAAA,CAAC;EACjG,CAAA;EAEd,OACE,oBAAC,oBAAD;GAAoB,MAAM;GAAO,GAAI;aAClC,aACC,oBAAC,UAAD;IAAU,SAAA;IAAQ,SAAA;cACf;GACO,CAAA,IAEV;EAEgB,CAAA;CAExB;CAGA,IAAI,MAAM,SAAS,KAAA,GAAW;EAC5B,MAAM,EACJ,KACA,MACA,MAAM,OACN,YACA,OACA,SACA,WACA,KACA,MACA,OAAO,QACP,QACA,cACA,SACA,GAAG,eACD;EACJ,MAAM,kBAAkB,aAAa,WAAW;EAChD,MAAM,eAAe,aAAc,MAAM,GAAG,IAAI,wBAAwB,wBAAyB;EACjG,MAAM,cAAc,cACf,MAAqC;GACpC,EAAE,eAAe;GACjB,EAAE,gBAAgB;EACpB,IACA;EACJ,MAAM,gBAAgB,cACjB,MAAwC;GACvC,IAAI,EAAE,QAAQ,WAAW,EAAE,QAAQ,KAAK;IACtC,EAAE,eAAe;IACjB,EAAE,gBAAgB;GACpB;EACF,IACA;EACJ,MAAM,gBACJ,oBAAC,OAAO,GAAR;GACO;GACL,GAAI;GACJ,iBAAe,cAAc,KAAA;GAC7B,cAAY;GACZ,KAAK;IAAC,aAAa;KAAE;KAAM;IAAQ,CAAC;IAAG;KAAE,cAAc;KAAG,eAAe;IAAE;IAAG;GAAG;GACjF,MAAM,aAAa,KAAA,IAAY;GAC/B,SAAS;GACT,WAAW;GACX,KAAK;GACL,QAAQ;aAER,oBAAC,MAAD,EAAM,MAAM,SAAW,CAAA;EACf,CAAA;EAEZ,OACE,oBAAC,oBAAD;GAAoB,MAAM;GAAO,GAAI;aAClC,aACC,oBAAC,UAAD;IAAU,SAAA;IAAQ,SAAA;cACf;GACO,CAAA,IAEV;EAEgB,CAAA;CAExB;CAGA,MAAM,EAAE,MAAM,OAAO,OAAO,OAAO,cAAc,GAAG,eAAe;CACnE,OACE,oBAAC,oBAAD;EAAoB,MAAM;EAAO,GAAI;YACnC,oBAAC,UAAD;GAAU,SAAA;GAAQ,SAAS;aACzB,oBAAC,YAAD;IACE,cAAY;IACZ,UAAU;IACV,SAAS,UAAU;IACd;IACL,GAAI;cAEJ,oBAAC,MAAD,EAAM,MAAM,SAAW,CAAA;GACb,CAAA;EACJ,CAAA;CACQ,CAAA;AAExB,CAAC;AAED,iBAAiB,cAAc"}
|
|
@@ -2,6 +2,7 @@ import { LinkProps } from '@chakra-ui/react/link';
|
|
|
2
2
|
import { ComponentPropsWithoutRef } from 'react';
|
|
3
3
|
import { BitkitIconComponent } from '../../icons';
|
|
4
4
|
export interface BitkitLinkProps extends LinkProps {
|
|
5
|
+
isExternal?: boolean;
|
|
5
6
|
suffixIcon?: BitkitIconComponent;
|
|
6
7
|
suffixIconSize?: ComponentPropsWithoutRef<BitkitIconComponent>['size'];
|
|
7
8
|
state?: 'disabled';
|
|
@@ -3,11 +3,26 @@ import { jsx, jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
import { Link } from "@chakra-ui/react/link";
|
|
4
4
|
//#region lib/components/BitkitLink/BitkitLink.tsx
|
|
5
5
|
var BitkitLink = forwardRef((props, ref) => {
|
|
6
|
-
const { children, href, suffixIcon: SuffixIcon, suffixIconSize, state, ...rest } = props;
|
|
6
|
+
const { children, href, isExternal, onClick, onKeyDown, rel, suffixIcon: SuffixIcon, suffixIconSize, state, target, ...rest } = props;
|
|
7
|
+
const isDisabled = state === "disabled";
|
|
8
|
+
const effectiveTarget = isExternal ? "_blank" : target;
|
|
9
|
+
const effectiveRel = isExternal ? rel ? `${rel} noreferrer noopener` : "noreferrer noopener" : rel;
|
|
7
10
|
return /* @__PURE__ */ jsxs(Link, {
|
|
8
|
-
"aria-disabled":
|
|
9
|
-
href:
|
|
11
|
+
"aria-disabled": isDisabled || void 0,
|
|
12
|
+
href: isDisabled ? void 0 : href,
|
|
13
|
+
onClick: isDisabled ? (e) => {
|
|
14
|
+
e.preventDefault();
|
|
15
|
+
e.stopPropagation();
|
|
16
|
+
} : onClick,
|
|
17
|
+
onKeyDown: isDisabled ? (e) => {
|
|
18
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
19
|
+
e.preventDefault();
|
|
20
|
+
e.stopPropagation();
|
|
21
|
+
}
|
|
22
|
+
} : onKeyDown,
|
|
10
23
|
ref,
|
|
24
|
+
rel: effectiveRel,
|
|
25
|
+
target: effectiveTarget,
|
|
11
26
|
...rest,
|
|
12
27
|
children: [children, SuffixIcon && (suffixIconSize ? /* @__PURE__ */ jsx(SuffixIcon, { size: suffixIconSize }) : /* @__PURE__ */ jsx(SuffixIcon, { css: {
|
|
13
28
|
height: "1lh",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BitkitLink.js","names":[],"sources":["../../../lib/components/BitkitLink/BitkitLink.tsx"],"sourcesContent":["import { Link, type LinkProps } from '@chakra-ui/react/link';\nimport { type ComponentPropsWithoutRef, forwardRef } from 'react';\n\nimport { type BitkitIconComponent } from '../../icons';\n\nexport interface BitkitLinkProps extends LinkProps {\n suffixIcon?: BitkitIconComponent;\n suffixIconSize?: ComponentPropsWithoutRef<BitkitIconComponent>['size'];\n state?: 'disabled';\n}\n\nconst BitkitLink = forwardRef<HTMLAnchorElement, BitkitLinkProps>((props, ref) => {\n const {
|
|
1
|
+
{"version":3,"file":"BitkitLink.js","names":[],"sources":["../../../lib/components/BitkitLink/BitkitLink.tsx"],"sourcesContent":["import { Link, type LinkProps } from '@chakra-ui/react/link';\nimport { type ComponentPropsWithoutRef, forwardRef, type KeyboardEvent, type MouseEvent } from 'react';\n\nimport { type BitkitIconComponent } from '../../icons';\n\nexport interface BitkitLinkProps extends LinkProps {\n isExternal?: boolean;\n suffixIcon?: BitkitIconComponent;\n suffixIconSize?: ComponentPropsWithoutRef<BitkitIconComponent>['size'];\n state?: 'disabled';\n}\n\nconst BitkitLink = forwardRef<HTMLAnchorElement, BitkitLinkProps>((props, ref) => {\n const {\n children,\n href,\n isExternal,\n onClick,\n onKeyDown,\n rel,\n suffixIcon: SuffixIcon,\n suffixIconSize,\n state,\n target,\n ...rest\n } = props;\n const isDisabled = state === 'disabled';\n const effectiveTarget = isExternal ? '_blank' : target;\n const effectiveRel = isExternal ? (rel ? `${rel} noreferrer noopener` : 'noreferrer noopener') : rel;\n const handleClick = isDisabled\n ? (e: MouseEvent<HTMLAnchorElement>) => {\n e.preventDefault();\n e.stopPropagation();\n }\n : onClick;\n const handleKeyDown = isDisabled\n ? (e: KeyboardEvent<HTMLAnchorElement>) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n e.stopPropagation();\n }\n }\n : onKeyDown;\n\n return (\n <Link\n aria-disabled={isDisabled || undefined}\n href={isDisabled ? undefined : href}\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n ref={ref}\n rel={effectiveRel}\n target={effectiveTarget}\n {...rest}\n >\n {children}\n {SuffixIcon &&\n (suffixIconSize ? <SuffixIcon size={suffixIconSize} /> : <SuffixIcon css={{ height: '1lh', width: '1lh' }} />)}\n </Link>\n );\n});\n\nBitkitLink.displayName = 'BitkitLink';\n\nexport default BitkitLink;\n"],"mappings":";;;;AAYA,IAAM,aAAa,YAAgD,OAAO,QAAQ;CAChF,MAAM,EACJ,UACA,MACA,YACA,SACA,WACA,KACA,YAAY,YACZ,gBACA,OACA,QACA,GAAG,SACD;CACJ,MAAM,aAAa,UAAU;CAC7B,MAAM,kBAAkB,aAAa,WAAW;CAChD,MAAM,eAAe,aAAc,MAAM,GAAG,IAAI,wBAAwB,wBAAyB;CAgBjG,OACE,qBAAC,MAAD;EACE,iBAAe,cAAc,KAAA;EAC7B,MAAM,aAAa,KAAA,IAAY;EAC/B,SAnBgB,cACf,MAAqC;GACpC,EAAE,eAAe;GACjB,EAAE,gBAAgB;EACpB,IACA;EAeA,WAdkB,cACjB,MAAwC;GACvC,IAAI,EAAE,QAAQ,WAAW,EAAE,QAAQ,KAAK;IACtC,EAAE,eAAe;IACjB,EAAE,gBAAgB;GACpB;EACF,IACA;EAQK;EACL,KAAK;EACL,QAAQ;EACR,GAAI;YARN,CAUG,UACA,eACE,iBAAiB,oBAAC,YAAD,EAAY,MAAM,eAAiB,CAAA,IAAI,oBAAC,YAAD,EAAY,KAAK;GAAE,QAAQ;GAAO,OAAO;EAAM,EAAI,CAAA,EAC1G;;AAEV,CAAC;AAED,WAAW,cAAc"}
|
|
@@ -32,19 +32,22 @@ var BitkitNoteCard = forwardRef((props, ref) => {
|
|
|
32
32
|
css: title ? styles.message : styles.messageSolo,
|
|
33
33
|
children: message
|
|
34
34
|
})]
|
|
35
|
-
}), action && /* @__PURE__ */ jsx(BitkitButton, {
|
|
35
|
+
}), action && (action.href !== void 0 ? /* @__PURE__ */ jsx(BitkitButton, {
|
|
36
36
|
css: styles.actionArea,
|
|
37
|
+
href: action.href,
|
|
38
|
+
onClick: action.onClick,
|
|
39
|
+
rel: action.target === "_blank" ? "noopener noreferrer" : void 0,
|
|
37
40
|
size: "sm",
|
|
41
|
+
target: action.target,
|
|
38
42
|
variant: "tertiary",
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
rel: action.target === "_blank" ? "noopener noreferrer" : void 0,
|
|
43
|
-
target: action.target
|
|
44
|
-
},
|
|
43
|
+
children: action.label
|
|
44
|
+
}) : /* @__PURE__ */ jsx(BitkitButton, {
|
|
45
|
+
css: styles.actionArea,
|
|
45
46
|
onClick: action.onClick,
|
|
47
|
+
size: "sm",
|
|
48
|
+
variant: "tertiary",
|
|
46
49
|
children: action.label
|
|
47
|
-
})]
|
|
50
|
+
}))]
|
|
48
51
|
})]
|
|
49
52
|
});
|
|
50
53
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BitkitNoteCard.js","names":[],"sources":["../../../lib/components/BitkitNoteCard/BitkitNoteCard.tsx"],"sourcesContent":["import { Box, type BoxProps } from '@chakra-ui/react/box';\nimport { useSlotRecipe } from '@chakra-ui/react/styled-system';\nimport { Text } from '@chakra-ui/react/text';\nimport { type ElementType, forwardRef, type ReactNode } from 'react';\n\nimport { type NotificationVariant } from '../../theme/common/AlertAndToast.common';\nimport BitkitButton from '../BitkitButton/BitkitButton';\nimport { ICON_COMPONENTS_MAP, type NotificationAction } from '../common/notificationMaps';\n\n// ----- Props -----\n\nexport type BitkitNoteCardProps = Omit<BoxProps, 'children' | 'title'> & {\n action?: NotificationAction;\n message: ReactNode;\n status?: NotificationVariant;\n title?: string;\n};\n\n// ----- Component -----\n\nconst BitkitNoteCard = forwardRef<HTMLDivElement, BitkitNoteCardProps>((props, ref) => {\n const { action, message, status = 'info', title, ...rest } = props;\n\n const recipe = useSlotRecipe({ key: 'noteCard' });\n const styles = recipe({ status });\n\n const IconComponent: ElementType = ICON_COMPONENTS_MAP[status];\n const isProgress = status === 'progress';\n\n return (\n <Box ref={ref} css={styles.root} {...rest}>\n <Box css={styles.iconBar}>\n <Box css={styles.iconWrapper}>{isProgress ? <IconComponent size=\"lg\" /> : <IconComponent size=\"24\" />}</Box>\n </Box>\n <Box css={styles.content}>\n <Box css={styles.messageBlock}>\n {title && <Text css={styles.title}>{title}</Text>}\n <Text css={title ? styles.message : styles.messageSolo}>{message}</Text>\n </Box>\n {action
|
|
1
|
+
{"version":3,"file":"BitkitNoteCard.js","names":[],"sources":["../../../lib/components/BitkitNoteCard/BitkitNoteCard.tsx"],"sourcesContent":["import { Box, type BoxProps } from '@chakra-ui/react/box';\nimport { useSlotRecipe } from '@chakra-ui/react/styled-system';\nimport { Text } from '@chakra-ui/react/text';\nimport { type ElementType, forwardRef, type ReactNode } from 'react';\n\nimport { type NotificationVariant } from '../../theme/common/AlertAndToast.common';\nimport BitkitButton from '../BitkitButton/BitkitButton';\nimport { ICON_COMPONENTS_MAP, type NotificationAction } from '../common/notificationMaps';\n\n// ----- Props -----\n\nexport type BitkitNoteCardProps = Omit<BoxProps, 'children' | 'title'> & {\n action?: NotificationAction;\n message: ReactNode;\n status?: NotificationVariant;\n title?: string;\n};\n\n// ----- Component -----\n\nconst BitkitNoteCard = forwardRef<HTMLDivElement, BitkitNoteCardProps>((props, ref) => {\n const { action, message, status = 'info', title, ...rest } = props;\n\n const recipe = useSlotRecipe({ key: 'noteCard' });\n const styles = recipe({ status });\n\n const IconComponent: ElementType = ICON_COMPONENTS_MAP[status];\n const isProgress = status === 'progress';\n\n return (\n <Box ref={ref} css={styles.root} {...rest}>\n <Box css={styles.iconBar}>\n <Box css={styles.iconWrapper}>{isProgress ? <IconComponent size=\"lg\" /> : <IconComponent size=\"24\" />}</Box>\n </Box>\n <Box css={styles.content}>\n <Box css={styles.messageBlock}>\n {title && <Text css={styles.title}>{title}</Text>}\n <Text css={title ? styles.message : styles.messageSolo}>{message}</Text>\n </Box>\n {action &&\n (action.href !== undefined ? (\n <BitkitButton\n css={styles.actionArea}\n href={action.href}\n onClick={action.onClick}\n rel={action.target === '_blank' ? 'noopener noreferrer' : undefined}\n size=\"sm\"\n target={action.target}\n variant=\"tertiary\"\n >\n {action.label}\n </BitkitButton>\n ) : (\n <BitkitButton css={styles.actionArea} onClick={action.onClick} size=\"sm\" variant=\"tertiary\">\n {action.label}\n </BitkitButton>\n ))}\n </Box>\n </Box>\n );\n});\n\nBitkitNoteCard.displayName = 'BitkitNoteCard';\n\nexport default BitkitNoteCard;\n"],"mappings":";;;;;;;;AAoBA,IAAM,iBAAiB,YAAiD,OAAO,QAAQ;CACrF,MAAM,EAAE,QAAQ,SAAS,SAAS,QAAQ,OAAO,GAAG,SAAS;CAG7D,MAAM,SADS,cAAc,EAAE,KAAK,WAAW,CAChC,EAAO,EAAE,OAAO,CAAC;CAEhC,MAAM,gBAA6B,oBAAoB;CACvD,MAAM,aAAa,WAAW;CAE9B,OACE,qBAAC,KAAD;EAAU;EAAK,KAAK,OAAO;EAAM,GAAI;YAArC,CACE,oBAAC,KAAD;GAAK,KAAK,OAAO;aACf,oBAAC,KAAD;IAAK,KAAK,OAAO;cAAc,aAAa,oBAAC,eAAD,EAAe,MAAK,KAAM,CAAA,IAAI,oBAAC,eAAD,EAAe,MAAK,KAAM,CAAA;GAAO,CAAA;EACxG,CAAA,GACL,qBAAC,KAAD;GAAK,KAAK,OAAO;aAAjB,CACE,qBAAC,KAAD;IAAK,KAAK,OAAO;cAAjB,CACG,SAAS,oBAAC,MAAD;KAAM,KAAK,OAAO;eAAQ;IAAY,CAAA,GAChD,oBAAC,MAAD;KAAM,KAAK,QAAQ,OAAO,UAAU,OAAO;eAAc;IAAc,CAAA,CACpE;OACJ,WACE,OAAO,SAAS,KAAA,IACf,oBAAC,cAAD;IACE,KAAK,OAAO;IACZ,MAAM,OAAO;IACb,SAAS,OAAO;IAChB,KAAK,OAAO,WAAW,WAAW,wBAAwB,KAAA;IAC1D,MAAK;IACL,QAAQ,OAAO;IACf,SAAQ;cAEP,OAAO;GACI,CAAA,IAEd,oBAAC,cAAD;IAAc,KAAK,OAAO;IAAY,SAAS,OAAO;IAAS,MAAK;IAAK,SAAQ;cAC9E,OAAO;GACI,CAAA,EAEf;IACF;;AAET,CAAC;AAED,eAAe,cAAc"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { GroupProps } from '@chakra-ui/react/group';
|
|
2
2
|
import { PropsWithChildren, ReactNode } from 'react';
|
|
3
|
-
import {
|
|
3
|
+
import { BitkitButtonAsAnchorProps, BitkitButtonAsButtonProps } from '../BitkitButton/BitkitButton';
|
|
4
4
|
type Size = 'lg' | 'md' | 'sm';
|
|
5
5
|
type Variant = 'primary' | 'secondary';
|
|
6
6
|
type State = 'disabled' | 'loading' | 'skeleton';
|
|
7
|
-
type BitkitSplitButtonActionProps = Omit<
|
|
7
|
+
type BitkitSplitButtonActionProps = Omit<BitkitButtonAsButtonProps | BitkitButtonAsAnchorProps, 'size' | 'variant' | 'state'>;
|
|
8
8
|
export type BitkitSplitButtonProps = PropsWithChildren<Omit<GroupProps, 'attached' | 'children' | 'display'> & {
|
|
9
9
|
size?: Size;
|
|
10
10
|
variant?: Variant;
|
|
@@ -17,9 +17,9 @@ declare const _default: import('react').ForwardRefExoticComponent<Omit<GroupProp
|
|
|
17
17
|
} & {
|
|
18
18
|
children?: ReactNode | undefined;
|
|
19
19
|
} & import('react').RefAttributes<HTMLDivElement>> & {
|
|
20
|
-
Action: import('react').ForwardRefExoticComponent<BitkitSplitButtonActionProps & import('react').RefAttributes<
|
|
20
|
+
Action: import('react').ForwardRefExoticComponent<BitkitSplitButtonActionProps & import('react').RefAttributes<HTMLElement>>;
|
|
21
21
|
Group: import('react').ForwardRefExoticComponent<import('..').BitkitMenuGroupProps & import('react').RefAttributes<HTMLDivElement>>;
|
|
22
|
-
Item: import('react').ForwardRefExoticComponent<import('..').BitkitMenuItemProps & import('react').RefAttributes<
|
|
22
|
+
Item: import('react').ForwardRefExoticComponent<import('..').BitkitMenuItemProps & import('react').RefAttributes<HTMLElement>>;
|
|
23
23
|
Separator: {
|
|
24
24
|
(): import("react/jsx-runtime").JSX.Element;
|
|
25
25
|
displayName: string;
|
|
@@ -22,13 +22,21 @@ var [SplitButtonProvider, useSplitButtonContext] = createContext$1({
|
|
|
22
22
|
});
|
|
23
23
|
var BitkitSplitButtonAction = forwardRef((props, ref) => {
|
|
24
24
|
const { size, state, styles, variant } = useSplitButtonContext();
|
|
25
|
-
return /* @__PURE__ */ jsx(BitkitButton, {
|
|
25
|
+
if (props.href !== void 0) return /* @__PURE__ */ jsx(BitkitButton, {
|
|
26
|
+
...props,
|
|
27
|
+
css: styles.action,
|
|
26
28
|
ref,
|
|
29
|
+
size,
|
|
30
|
+
state: state === "loading" ? "disabled" : state,
|
|
31
|
+
variant
|
|
32
|
+
});
|
|
33
|
+
return /* @__PURE__ */ jsx(BitkitButton, {
|
|
34
|
+
...props,
|
|
27
35
|
css: styles.action,
|
|
36
|
+
ref,
|
|
28
37
|
size,
|
|
29
|
-
variant,
|
|
30
38
|
state,
|
|
31
|
-
|
|
39
|
+
variant
|
|
32
40
|
});
|
|
33
41
|
});
|
|
34
42
|
BitkitSplitButtonAction.displayName = "BitkitSplitButtonAction";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BitkitSplitButton.js","names":[],"sources":["../../../lib/components/BitkitSplitButton/BitkitSplitButton.tsx"],"sourcesContent":["// eslint-disable-next-line no-restricted-imports\nimport { createContext } from '@chakra-ui/react';\nimport { Group, type GroupProps } from '@chakra-ui/react/group';\nimport { Skeleton } from '@chakra-ui/react/skeleton';\nimport { type SystemStyleObject, useSlotRecipe } from '@chakra-ui/react/styled-system';\nimport { Children, forwardRef, isValidElement, type PropsWithChildren, type ReactElement, type ReactNode } from 'react';\n\nimport { IconChevronDown } from '../../icons';\nimport BitkitActionMenu from '../BitkitActionMenu/BitkitActionMenu';\nimport BitkitButton, { type
|
|
1
|
+
{"version":3,"file":"BitkitSplitButton.js","names":[],"sources":["../../../lib/components/BitkitSplitButton/BitkitSplitButton.tsx"],"sourcesContent":["// eslint-disable-next-line no-restricted-imports\nimport { createContext } from '@chakra-ui/react';\nimport { Group, type GroupProps } from '@chakra-ui/react/group';\nimport { Skeleton } from '@chakra-ui/react/skeleton';\nimport { type SystemStyleObject, useSlotRecipe } from '@chakra-ui/react/styled-system';\nimport { Children, forwardRef, isValidElement, type PropsWithChildren, type ReactElement, type ReactNode } from 'react';\n\nimport { IconChevronDown } from '../../icons';\nimport BitkitActionMenu from '../BitkitActionMenu/BitkitActionMenu';\nimport BitkitButton, {\n type BitkitButtonAsAnchorProps,\n type BitkitButtonAsButtonProps,\n} from '../BitkitButton/BitkitButton';\nimport BitkitIconButton from '../BitkitIconButton/BitkitIconButton';\n\ntype Size = 'lg' | 'md' | 'sm';\ntype Variant = 'primary' | 'secondary';\ntype State = 'disabled' | 'loading' | 'skeleton';\n\nconst isValidActionItem = (child: ReactNode): child is ReactElement => {\n return isValidElement(child) && child.type === BitkitSplitButtonAction;\n};\n\nconst isValidMenuItem = (child: ReactNode): child is ReactElement => {\n return (\n isValidElement(child) &&\n (child.type === BitkitActionMenu.Group ||\n child.type === BitkitActionMenu.Item ||\n child.type === BitkitActionMenu.Separator)\n );\n};\n\n// --- Context ---\ninterface SplitButtonContext {\n size: Size;\n variant: Variant;\n state: State | undefined;\n styles: Record<string, SystemStyleObject>;\n}\n\nconst [SplitButtonProvider, useSplitButtonContext] = createContext<SplitButtonContext>({\n name: 'SplitButtonContext',\n hookName: 'useSplitButtonContext',\n providerName: '<BitkitSplitButton />',\n});\n\n// --- Action ---\n// Split-button action can be a button (default) or anchor (when href is set). asChild is intentionally\n// not part of the API — routing-library elements don't fit cleanly into the Group attached layout.\n// The forwarded ref is HTMLElement so it covers both <button> and <a>.\ntype BitkitSplitButtonActionProps = Omit<\n BitkitButtonAsButtonProps | BitkitButtonAsAnchorProps,\n 'size' | 'variant' | 'state'\n>;\n\nconst BitkitSplitButtonAction = forwardRef<HTMLElement, BitkitSplitButtonActionProps>((props, ref) => {\n const { size, state, styles, variant } = useSplitButtonContext();\n\n if (props.href !== undefined) {\n // Anchor branch: BitkitButton's anchor variant doesn't allow state=\"loading\". Coerce to \"disabled\"\n // so a SplitButton-wide loading state still surfaces visually on a link-mode action.\n return (\n <BitkitButton\n {...(props as BitkitButtonAsAnchorProps)}\n css={styles.action}\n ref={ref}\n size={size}\n state={state === 'loading' ? 'disabled' : state}\n variant={variant}\n />\n );\n }\n\n return (\n <BitkitButton\n {...(props as BitkitButtonAsButtonProps)}\n css={styles.action}\n ref={ref}\n size={size}\n state={state}\n variant={variant}\n />\n );\n});\n\nBitkitSplitButtonAction.displayName = 'BitkitSplitButtonAction';\n\n// --- Root ---\nexport type BitkitSplitButtonProps = PropsWithChildren<\n Omit<GroupProps, 'attached' | 'children' | 'display'> & {\n size?: Size;\n variant?: Variant;\n state?: State;\n }\n>;\n\nconst BitkitSplitButton = forwardRef<HTMLDivElement, BitkitSplitButtonProps>((props, ref) => {\n const { children, size = 'lg', state, variant = 'primary', ...rest } = props;\n\n const childArray = Children.toArray(children);\n const actionChild = childArray.find(isValidActionItem);\n const menuItems = childArray.filter(isValidMenuItem);\n\n const menuSize = size === 'lg' ? 'lg' : 'md';\n const recipe = useSlotRecipe({ key: 'splitButton' });\n const styles = recipe({ variant });\n\n return (\n <SplitButtonProvider value={{ size, state, styles, variant }}>\n <Skeleton asChild loading={state === 'skeleton'}>\n <Group ref={ref} {...rest} attached display=\"inline-flex\">\n {actionChild}\n <BitkitActionMenu.Root\n size={menuSize}\n trigger={\n <BitkitIconButton\n css={styles.trigger}\n icon={IconChevronDown}\n label=\"Toggle menu\"\n size={size}\n state={state === 'loading' ? 'disabled' : state}\n variant={variant}\n />\n }\n positioning={{ placement: 'bottom-end' }}\n >\n {menuItems}\n </BitkitActionMenu.Root>\n </Group>\n </Skeleton>\n </SplitButtonProvider>\n );\n});\nBitkitSplitButton.displayName = 'BitkitSplitButton';\n\nexport default Object.assign(BitkitSplitButton, {\n Action: BitkitSplitButtonAction,\n Group: BitkitActionMenu.Group,\n Item: BitkitActionMenu.Item,\n Separator: BitkitActionMenu.Separator,\n});\n"],"mappings":";;;;;;;;;;;AAmBA,IAAM,qBAAqB,UAA4C;CACrE,OAAO,eAAe,KAAK,KAAK,MAAM,SAAS;AACjD;AAEA,IAAM,mBAAmB,UAA4C;CACnE,OACE,eAAe,KAAK,MACnB,MAAM,SAAS,iBAAiB,SAC/B,MAAM,SAAS,iBAAiB,QAChC,MAAM,SAAS,iBAAiB;AAEtC;AAUA,IAAM,CAAC,qBAAqB,yBAAyB,gBAAkC;CACrF,MAAM;CACN,UAAU;CACV,cAAc;AAChB,CAAC;AAWD,IAAM,0BAA0B,YAAuD,OAAO,QAAQ;CACpG,MAAM,EAAE,MAAM,OAAO,QAAQ,YAAY,sBAAsB;CAE/D,IAAI,MAAM,SAAS,KAAA,GAGjB,OACE,oBAAC,cAAD;EACE,GAAK;EACL,KAAK,OAAO;EACP;EACC;EACN,OAAO,UAAU,YAAY,aAAa;EACjC;CACV,CAAA;CAIL,OACE,oBAAC,cAAD;EACE,GAAK;EACL,KAAK,OAAO;EACP;EACC;EACC;EACE;CACV,CAAA;AAEL,CAAC;AAED,wBAAwB,cAAc;AAWtC,IAAM,oBAAoB,YAAoD,OAAO,QAAQ;CAC3F,MAAM,EAAE,UAAU,OAAO,MAAM,OAAO,UAAU,WAAW,GAAG,SAAS;CAEvE,MAAM,aAAa,SAAS,QAAQ,QAAQ;CAC5C,MAAM,cAAc,WAAW,KAAK,iBAAiB;CACrD,MAAM,YAAY,WAAW,OAAO,eAAe;CAEnD,MAAM,WAAW,SAAS,OAAO,OAAO;CAExC,MAAM,SADS,cAAc,EAAE,KAAK,cAAc,CACnC,EAAO,EAAE,QAAQ,CAAC;CAEjC,OACE,oBAAC,qBAAD;EAAqB,OAAO;GAAE;GAAM;GAAO;GAAQ;EAAQ;YACzD,oBAAC,UAAD;GAAU,SAAA;GAAQ,SAAS,UAAU;aACnC,qBAAC,OAAD;IAAY;IAAK,GAAI;IAAM,UAAA;IAAS,SAAQ;cAA5C,CACG,aACD,oBAAC,iBAAiB,MAAlB;KACE,MAAM;KACN,SACE,oBAAC,kBAAD;MACE,KAAK,OAAO;MACZ,MAAM;MACN,OAAM;MACA;MACN,OAAO,UAAU,YAAY,aAAa;MACjC;KACV,CAAA;KAEH,aAAa,EAAE,WAAW,aAAa;eAEtC;IACoB,CAAA,CAClB;;EACC,CAAA;CACS,CAAA;AAEzB,CAAC;AACD,kBAAkB,cAAc;AAEhC,IAAA,4BAAe,OAAO,OAAO,mBAAmB;CAC9C,QAAQ;CACR,OAAO,iBAAiB;CACxB,MAAM,iBAAiB;CACvB,WAAW,iBAAiB;AAC9B,CAAC"}
|
|
@@ -63,11 +63,43 @@ Chakra v2 → v3 prop changes on primitives:
|
|
|
63
63
|
|----|----|
|
|
64
64
|
| `Button` | `BitkitButton` |
|
|
65
65
|
| `IconButton` | `BitkitIconButton` |
|
|
66
|
+
| `ControlButton` | `BitkitControlButton` |
|
|
67
|
+
| `Button as="a" href="..."` | `BitkitButton href="..."` (renders `<a>`) |
|
|
68
|
+
| `IconButton as="a" href="..."` | `BitkitIconButton href="..."` |
|
|
69
|
+
| `<Link isExternal>` | `BitkitLink isExternal` |
|
|
66
70
|
| `leftIconName` | `icon` |
|
|
67
71
|
| `isDisabled` | `state="disabled"` |
|
|
68
72
|
| `isLoading` | `state="loading"` |
|
|
69
73
|
|
|
70
|
-
**
|
|
74
|
+
**Polymorphism**: `BitkitButton`, `BitkitIconButton`, and `BitkitControlButton` all render as `<a>` when `href` is passed — the button recipe styles apply to the anchor. The `state` prop's `'loading'` value is not valid in anchor mode (semantically a button thing).
|
|
75
|
+
|
|
76
|
+
```tsx
|
|
77
|
+
// Renders <button>
|
|
78
|
+
<BitkitButton onClick={save}>Save</BitkitButton>
|
|
79
|
+
|
|
80
|
+
// Renders <a href="/details"> with the button visual style
|
|
81
|
+
<BitkitButton href="/details">View details</BitkitButton>
|
|
82
|
+
|
|
83
|
+
// External link — auto-adds target="_blank" rel="noreferrer noopener"
|
|
84
|
+
<BitkitButton href="https://example.com" isExternal>External</BitkitButton>
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
**Routing library integration** — for routers that render their own `<a>` (Next.js Link, React Router Link), use `asChild`:
|
|
88
|
+
|
|
89
|
+
```tsx
|
|
90
|
+
<BitkitButton asChild icon={IconCheck}>
|
|
91
|
+
<NextLink href="/route">Navigate</NextLink>
|
|
92
|
+
</BitkitButton>
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
`BitkitLink` also supports `isExternal` for the same target+rel convenience. `BitkitActionMenu.Item` accepts `href` (with optional `target`, `rel`, and `isExternal`) for link-style menu items:
|
|
96
|
+
|
|
97
|
+
```tsx
|
|
98
|
+
<BitkitActionMenu.Item href="/internal" value="v1">Go to settings</BitkitActionMenu.Item>
|
|
99
|
+
<BitkitActionMenu.Item href="https://example.com" isExternal value="v2">Open docs</BitkitActionMenu.Item>
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
**Gotcha**: `BitkitButton` requires `children` to be a `string` in button/anchor modes. For complex layout (multiple text nodes, conditional JSX), use `asChild` mode with your own element, or compose with `chakra.button` from `@chakra-ui/react/styled-system` for full freedom.
|
|
71
103
|
|
|
72
104
|
### Badge / Tag
|
|
73
105
|
|