@bitrise/bitkit-v2 0.3.281 → 0.3.283
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/dist/components/BitkitButton/BitkitButton.js +1 -0
- package/dist/components/BitkitButton/BitkitButton.js.map +1 -1
- package/dist/theme/recipes/Button.recipe.js +13 -11
- package/dist/theme/recipes/Button.recipe.js.map +1 -1
- package/dist/theme/slot-recipes/QrCode.recipe.js +2 -0
- package/dist/theme/slot-recipes/QrCode.recipe.js.map +1 -1
- package/package.json +1 -1
|
@@ -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 { 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 // Only `lg` takes the 24px icon; `sm`/`md` take 16px. `size` is `undefined` when unset — the\n // recipe applies its `lg` default in CSS, not on the prop — so an unset button must fall through\n // to 24, which is why we enumerate the small sizes instead of checking `=== 'lg'`.\n const iconSize = props.size === 'sm' || props.size === 'md' ? '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;CAIzB,MAAM,WAAW,MAAM,SAAS,QAAQ,MAAM,SAAS,OAAO,OAAO;CACrE,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;
|
|
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 // Only `lg` takes the 24px icon; `sm`/`md` take 16px. `size` is `undefined` when unset — the\n // recipe applies its `lg` default in CSS, not on the prop — so an unset button must fall through\n // to 24, which is why we enumerate the small sizes instead of checking `=== 'lg'`.\n const iconSize = props.size === 'sm' || props.size === 'md' ? '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 // A native <a> can't be `:disabled`, so mark `data-disabled` too: it's the styling/interaction hook the\n // recipe's `_hover`/`_active` conditions exclude (`:not(…, [data-disabled])`), while `aria-disabled` stays\n // for a11y. Without it, hover/active would still match a disabled anchor and override the disabled colors.\n css={[buttonRecipe({ size, variant }), css]}\n data-disabled={isDisabled || undefined}\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;CAIzB,MAAM,WAAW,MAAM,SAAS,QAAQ,MAAM,SAAS,OAAO,OAAO;CACrE,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;GAI7B,KAAK,CAAC,aAAa;IAAE;IAAM;GAAQ,CAAC,GAAG,GAAG;GAC1C,iBAAe,cAAc,KAAA;GAC7B,MAAM,aAAa,KAAA,IAAY;GAC/B,SAAS;GACT,WAAW;GACX,KAAK;GACL,QAAQ;aAbV;IAeG,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"}
|
|
@@ -36,23 +36,25 @@ var buttonRecipe = defineRecipe({
|
|
|
36
36
|
disabledBorderColor = "transparent";
|
|
37
37
|
}
|
|
38
38
|
const isSecondary = variant === "secondary";
|
|
39
|
+
const activeStyles = {
|
|
40
|
+
backgroundColor: `button/${variant}/bg-active`,
|
|
41
|
+
borderColor: variant?.includes("secondary") ? `button/${variant}/border-active` : `button/${variant}/bg-active`,
|
|
42
|
+
color: isSecondary ? "button/secondary/text-active" : `button/${variant}/fg-active`,
|
|
43
|
+
_icon: { color: isSecondary ? "button/secondary/icon-active" : void 0 }
|
|
44
|
+
};
|
|
39
45
|
obj[variant] = {
|
|
40
|
-
|
|
46
|
+
_hover: {
|
|
41
47
|
backgroundColor: `button/${variant}/bg-hover`,
|
|
42
48
|
borderColor: variant?.includes("secondary") ? `button/${variant}/border-hover` : `button/${variant}/bg-hover`,
|
|
43
49
|
color: isSecondary ? "button/secondary/text-hover" : `button/${variant}/fg-hover`,
|
|
44
|
-
_icon: { color: isSecondary ? "button/secondary/icon-hover" : void 0 }
|
|
45
|
-
|
|
46
|
-
"&:active": {
|
|
47
|
-
backgroundColor: `button/${variant}/bg-active`,
|
|
48
|
-
borderColor: variant?.includes("secondary") ? `button/${variant}/border-active` : `button/${variant}/bg-active`,
|
|
49
|
-
color: isSecondary ? "button/secondary/text-active" : `button/${variant}/fg-active`,
|
|
50
|
-
_icon: { color: isSecondary ? "button/secondary/icon-active" : void 0 }
|
|
50
|
+
_icon: { color: isSecondary ? "button/secondary/icon-hover" : void 0 },
|
|
51
|
+
_active: activeStyles
|
|
51
52
|
},
|
|
53
|
+
_active: activeStyles,
|
|
52
54
|
_disabled: {
|
|
53
|
-
backgroundColor: `button/${variant}/bg-disabled
|
|
54
|
-
borderColor:
|
|
55
|
-
color: isSecondary ? "button/secondary/text-disabled
|
|
55
|
+
backgroundColor: `button/${variant}/bg-disabled`,
|
|
56
|
+
borderColor: disabledBorderColor,
|
|
57
|
+
color: isSecondary ? "button/secondary/text-disabled" : `button/${variant}/fg-disabled`,
|
|
56
58
|
cursor: "not-allowed",
|
|
57
59
|
_icon: { color: isSecondary ? "button/secondary/icon-disabled" : void 0 }
|
|
58
60
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Button.recipe.js","names":[],"sources":["../../../lib/theme/recipes/Button.recipe.ts"],"sourcesContent":["import { defineRecipe, type SystemStyleObject } from '@chakra-ui/react/styled-system';\n\nimport { rem } from '../themeUtils';\n\n// `as const` is load-bearing: without it `(typeof buttonVariants)[number]` widens to `string`,\n// which collapses the recipe's `variant` prop type to `string` — losing TS autocomplete/checking\n// and leaving Storybook/docgen (and the bitkit-storybook MCP) unable to enumerate the variants.\nconst buttonVariants = [\n 'primary',\n 'secondary',\n 'tertiary',\n 'danger-primary',\n 'danger-secondary',\n 'danger-tertiary',\n 'ai-primary',\n 'ai-secondary',\n 'ai-tertiary',\n] as const;\n\nexport type Variant = (typeof buttonVariants)[number];\n\nconst variantStyles = buttonVariants.reduce(\n (obj, variant) => {\n let borderColor = variant?.includes('secondary') ? `button/${variant}/border` : `button/${variant}/bg`;\n let disabledBorderColor = variant?.includes('secondary')\n ? `button/${variant}/border-disabled`\n : `button/${variant}/bg-disabled`;\n if (variant?.includes('tertiary')) {\n borderColor = 'transparent';\n disabledBorderColor = 'transparent';\n }\n const isSecondary = variant === 'secondary';\n
|
|
1
|
+
{"version":3,"file":"Button.recipe.js","names":[],"sources":["../../../lib/theme/recipes/Button.recipe.ts"],"sourcesContent":["import { defineRecipe, type SystemStyleObject } from '@chakra-ui/react/styled-system';\n\nimport { rem } from '../themeUtils';\n\n// `as const` is load-bearing: without it `(typeof buttonVariants)[number]` widens to `string`,\n// which collapses the recipe's `variant` prop type to `string` — losing TS autocomplete/checking\n// and leaving Storybook/docgen (and the bitkit-storybook MCP) unable to enumerate the variants.\nconst buttonVariants = [\n 'primary',\n 'secondary',\n 'tertiary',\n 'danger-primary',\n 'danger-secondary',\n 'danger-tertiary',\n 'ai-primary',\n 'ai-secondary',\n 'ai-tertiary',\n] as const;\n\nexport type Variant = (typeof buttonVariants)[number];\n\nconst variantStyles = buttonVariants.reduce(\n (obj, variant) => {\n let borderColor = variant?.includes('secondary') ? `button/${variant}/border` : `button/${variant}/bg`;\n let disabledBorderColor = variant?.includes('secondary')\n ? `button/${variant}/border-disabled`\n : `button/${variant}/bg-disabled`;\n if (variant?.includes('tertiary')) {\n borderColor = 'transparent';\n disabledBorderColor = 'transparent';\n }\n const isSecondary = variant === 'secondary';\n const activeStyles: SystemStyleObject = {\n backgroundColor: `button/${variant}/bg-active`,\n borderColor: variant?.includes('secondary') ? `button/${variant}/border-active` : `button/${variant}/bg-active`,\n color: isSecondary ? 'button/secondary/text-active' : `button/${variant}/fg-active`,\n _icon: {\n color: isSecondary ? 'button/secondary/icon-active' : undefined,\n },\n };\n obj[variant as NonNullable<Variant>] = {\n // `_hover`/`_active` (not raw `&:hover`/`&:active`) compile to `:not(:disabled, [data-disabled])`,\n // so they never match a disabled button — the `_disabled` styles win naturally, no `!important` needed.\n _hover: {\n backgroundColor: `button/${variant}/bg-hover`,\n borderColor: variant?.includes('secondary') ? `button/${variant}/border-hover` : `button/${variant}/bg-hover`,\n color: isSecondary ? 'button/secondary/text-hover' : `button/${variant}/fg-hover`,\n _icon: {\n color: isSecondary ? 'button/secondary/icon-hover' : undefined,\n },\n // Repeat active under hover so clicking-while-hovering keeps active styles (see CLAUDE.md).\n _active: activeStyles,\n },\n _active: activeStyles,\n _disabled: {\n backgroundColor: `button/${variant}/bg-disabled`,\n borderColor: disabledBorderColor,\n color: isSecondary ? 'button/secondary/text-disabled' : `button/${variant}/fg-disabled`,\n cursor: 'not-allowed',\n _icon: {\n color: isSecondary ? 'button/secondary/icon-disabled' : undefined,\n },\n },\n _icon: {\n color: isSecondary ? 'button/secondary/icon' : undefined,\n },\n backgroundColor: `button/${variant}/bg`,\n borderColor,\n borderStyle: 'solid',\n borderWidth: '1',\n color: isSecondary ? 'button/secondary/text' : `button/${variant}/fg`,\n };\n return obj;\n },\n {} as Record<NonNullable<Variant>, SystemStyleObject>,\n);\n\nconst buttonRecipe = defineRecipe({\n className: 'button',\n base: {\n borderRadius: '4',\n cursor: 'pointer',\n fontWeight: 600,\n border: '1px solid transparent',\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n gap: '8',\n position: 'relative',\n '--spinner-color': 'currentColor',\n '--spinner-size': 'sizes.16',\n _disabled: {\n cursor: 'not-allowed',\n },\n },\n variants: {\n variant: variantStyles,\n size: {\n sm: {\n minWidth: '32',\n height: '32',\n paddingInline: rem(11),\n paddingBlock: rem(5),\n textStyle: 'comp/button/sm',\n },\n md: {\n minWidth: '40',\n height: '40',\n paddingInline: rem(15),\n paddingBlock: rem(7),\n textStyle: 'comp/button/md',\n },\n lg: {\n minWidth: '48',\n height: '48',\n padding: rem(15),\n textStyle: 'comp/button/lg',\n },\n },\n },\n defaultVariants: {\n variant: 'primary',\n size: 'lg',\n },\n});\n\nexport default buttonRecipe;\n"],"mappings":";;;AA6EA,IAAM,eAAe,aAAa;CAChC,WAAW;CACX,MAAM;EACJ,cAAc;EACd,QAAQ;EACR,YAAY;EACZ,QAAQ;EACR,SAAS;EACT,YAAY;EACZ,gBAAgB;EAChB,KAAK;EACL,UAAU;EACV,mBAAmB;EACnB,kBAAkB;EAClB,WAAW,EACT,QAAQ,cACV;CACF;CACA,UAAU;EACR,SA3EkB;GAbpB;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EAKoB,EAAe,QAClC,KAAK,YAAY;GAChB,IAAI,cAAc,SAAS,SAAS,WAAW,IAAI,UAAU,QAAQ,WAAW,UAAU,QAAQ;GAClG,IAAI,sBAAsB,SAAS,SAAS,WAAW,IACnD,UAAU,QAAQ,oBAClB,UAAU,QAAQ;GACtB,IAAI,SAAS,SAAS,UAAU,GAAG;IACjC,cAAc;IACd,sBAAsB;GACxB;GACA,MAAM,cAAc,YAAY;GAChC,MAAM,eAAkC;IACtC,iBAAiB,UAAU,QAAQ;IACnC,aAAa,SAAS,SAAS,WAAW,IAAI,UAAU,QAAQ,kBAAkB,UAAU,QAAQ;IACpG,OAAO,cAAc,iCAAiC,UAAU,QAAQ;IACxE,OAAO,EACL,OAAO,cAAc,iCAAiC,KAAA,EACxD;GACF;GACA,IAAI,WAAmC;IAGrC,QAAQ;KACN,iBAAiB,UAAU,QAAQ;KACnC,aAAa,SAAS,SAAS,WAAW,IAAI,UAAU,QAAQ,iBAAiB,UAAU,QAAQ;KACnG,OAAO,cAAc,gCAAgC,UAAU,QAAQ;KACvE,OAAO,EACL,OAAO,cAAc,gCAAgC,KAAA,EACvD;KAEA,SAAS;IACX;IACA,SAAS;IACT,WAAW;KACT,iBAAiB,UAAU,QAAQ;KACnC,aAAa;KACb,OAAO,cAAc,mCAAmC,UAAU,QAAQ;KAC1E,QAAQ;KACR,OAAO,EACL,OAAO,cAAc,mCAAmC,KAAA,EAC1D;IACF;IACA,OAAO,EACL,OAAO,cAAc,0BAA0B,KAAA,EACjD;IACA,iBAAiB,UAAU,QAAQ;IACnC;IACA,aAAa;IACb,aAAa;IACb,OAAO,cAAc,0BAA0B,UAAU,QAAQ;GACnE;GACA,OAAO;EACT,GACA,CAAC,CAsBU;EACT,MAAM;GACJ,IAAI;IACF,UAAU;IACV,QAAQ;IACR,eAAe,IAAI,EAAE;IACrB,cAAc,IAAI,CAAC;IACnB,WAAW;GACb;GACA,IAAI;IACF,UAAU;IACV,QAAQ;IACR,eAAe,IAAI,EAAE;IACrB,cAAc,IAAI,CAAC;IACnB,WAAW;GACb;GACA,IAAI;IACF,UAAU;IACV,QAAQ;IACR,SAAS,IAAI,EAAE;IACf,WAAW;GACb;EACF;CACF;CACA,iBAAiB;EACf,SAAS;EACT,MAAM;CACR;AACF,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"QrCode.recipe.js","names":[],"sources":["../../../lib/theme/slot-recipes/QrCode.recipe.ts"],"sourcesContent":["import { qrCodeAnatomy } from '@chakra-ui/react/anatomy';\nimport { defineSlotRecipe } from '@chakra-ui/react/styled-system';\n\n// The size is driven by the `--qr-code-size` CSS variable that the `frame` slot\n// sizes off. The `size` variant sets that variable to a preset, and\n// `defaultVariants` guarantees a value so the component is never broken when no\n// size is passed. Consumers who need an arbitrary size can still override the\n// variable directly (`<QrCode.Root css={{ '--qr-code-size': '160px' }} />`) —\n// the `css` prop wins over the variant.\nconst qrCodeSlotRecipe = defineSlotRecipe({\n slots: qrCodeAnatomy.keys(),\n className: 'chakra-qr-code',\n base: {\n root: {\n position: 'relative',\n width: 'fit-content',\n
|
|
1
|
+
{"version":3,"file":"QrCode.recipe.js","names":[],"sources":["../../../lib/theme/slot-recipes/QrCode.recipe.ts"],"sourcesContent":["import { qrCodeAnatomy } from '@chakra-ui/react/anatomy';\nimport { defineSlotRecipe } from '@chakra-ui/react/styled-system';\n\n// The size is driven by the `--qr-code-size` CSS variable that the `frame` slot\n// sizes off. The `size` variant sets that variable to a preset, and\n// `defaultVariants` guarantees a value so the component is never broken when no\n// size is passed. Consumers who need an arbitrary size can still override the\n// variable directly (`<QrCode.Root css={{ '--qr-code-size': '160px' }} />`) —\n// the `css` prop wins over the variant.\nconst qrCodeSlotRecipe = defineSlotRecipe({\n slots: qrCodeAnatomy.keys(),\n className: 'chakra-qr-code',\n base: {\n root: {\n position: 'relative',\n width: 'fit-content',\n // A QR must be dark modules on a light surface to scan reliably. Bake the\n // default contrast in (dark foreground + light surface) so consumers get a\n // scannable code from `<QrCode.Root value size>` alone; both are plain\n // style props, so an unusual case can still override them. `icon/primary`\n // (not `text/primary`) because the pattern is a graphic mark, not text.\n // Neither token flips (the theme is light-only), which is what a QR needs.\n color: 'icon/primary',\n backgroundColor: 'background/primary',\n '--qr-code-overlay-size': 'calc(var(--qr-code-size) / 3)',\n },\n frame: {\n // The pattern draws with `currentColor` (the root's `color`), on the\n // root's light `backgroundColor`. The frame itself stays transparent.\n width: 'var(--qr-code-size)',\n height: 'var(--qr-code-size)',\n fill: 'currentColor',\n },\n overlay: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: 'var(--qr-code-overlay-size)',\n height: 'var(--qr-code-overlay-size)',\n padding: '1',\n backgroundColor: 'background/primary',\n borderRadius: '4',\n },\n },\n variants: {\n size: {\n '104': { root: { '--qr-code-size': '104px' } },\n '240': { root: { '--qr-code-size': '240px' } },\n },\n },\n defaultVariants: {\n size: '104',\n },\n});\n\nexport default qrCodeSlotRecipe;\n"],"mappings":";;;AASA,IAAM,mBAAmB,iBAAiB;CACxC,OAAO,cAAc,KAAK;CAC1B,WAAW;CACX,MAAM;EACJ,MAAM;GACJ,UAAU;GACV,OAAO;GAOP,OAAO;GACP,iBAAiB;GACjB,0BAA0B;EAC5B;EACA,OAAO;GAGL,OAAO;GACP,QAAQ;GACR,MAAM;EACR;EACA,SAAS;GACP,SAAS;GACT,YAAY;GACZ,gBAAgB;GAChB,OAAO;GACP,QAAQ;GACR,SAAS;GACT,iBAAiB;GACjB,cAAc;EAChB;CACF;CACA,UAAU,EACR,MAAM;EACJ,OAAO,EAAE,MAAM,EAAE,kBAAkB,QAAQ,EAAE;EAC7C,OAAO,EAAE,MAAM,EAAE,kBAAkB,QAAQ,EAAE;CAC/C,EACF;CACA,iBAAiB,EACf,MAAM,MACR;AACF,CAAC"}
|