@bitrise/bitkit-v2 0.3.387 → 0.3.389

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 CHANGED
@@ -116,7 +116,7 @@ Bitkit components use consistent prop names across the library:
116
116
  <BitkitActionMenu.Item href="/settings" value="settings">Settings</BitkitActionMenu.Item>
117
117
  <BitkitActionMenu.Item href="https://example.com" isExternal value="docs">Open docs</BitkitActionMenu.Item>
118
118
  ```
119
- - **`BitkitActionMenu.Item` slots** — `icon` is the leading icon, sized from the menu's `size`; `secondaryText` adds a quieter second line; `isDanger` styles the row as destructive. There is no trailing-icon prop: the only trailing icon in the design is the "leaves this page" arrow, and `isExternal` adds it for you. Groups and rules are their own children, not props:
119
+ - **`BitkitActionMenu.Item` slots** — `icon` is the leading icon, sized from the menu's `size`; `secondaryText` adds a quieter second line; `isDanger` styles the row as destructive. There is no trailing-icon prop: the only trailing icon in the design is the "leaves this page" arrow, and `isExternal` adds it for you. `value` is optional — omit it for a command item that does its work in `onClick`, pass one only if you read `onSelect` on the menu. Groups and rules are their own children, not props:
120
120
  ```tsx
121
121
  <BitkitActionMenu size="md" trigger={<BitkitIconButton icon={IconDots} label="Actions" />}>
122
122
  <BitkitActionMenu.Item icon={IconPencil} value="rename">Rename</BitkitActionMenu.Item>
@@ -127,6 +127,7 @@ Bitkit components use consistent prop names across the library:
127
127
  <BitkitActionMenu.Item icon={IconTrash} isDanger secondaryText="This cannot be undone" value="delete">Delete</BitkitActionMenu.Item>
128
128
  </BitkitActionMenu>
129
129
  ```
130
+ `data-*` attributes on `BitkitActionMenu` reach the element carrying `role="menu"` (the portalled list), and nothing else passes through — the same contract the dialogs have.
130
131
  - **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.
131
132
  - **`BitkitTextInput` in-field slots** — all four slots take a `ReactNode`, not just icons/strings: `startElement` / `endElement` render inside the field (an icon, badge, text, or an interactive control like a reveal/clear button), and `startAddon` / `endAddon` render as a bordered, attached box outside the field (a text label like `$` / `USD`, or a component such as a `select` / button). These match the Figma slot names. The validation status icon (error/warning) is added automatically and sits left of `endElement`. For a component addon that brings its own styling, pass `startAddonProps={{ unstyled: true }}` (or `endAddonProps`) to drop the default grey box:
132
133
  ```tsx
@@ -1,7 +1,13 @@
1
1
  import { Menu, MenuItemGroupProps, MenuItemProps, MenuRootProps, MenuSeparatorProps } from '@chakra-ui/react/menu';
2
2
  import { ReactNode } from 'react';
3
3
  import { BitkitIconComponent } from '../../icons';
4
- export interface BitkitActionMenuProps extends Omit<MenuRootProps, 'children'> {
4
+ import { BitkitDataAttributes } from '../../utilities/dataAttributes';
5
+ /**
6
+ * `data-*` attributes are forwarded to the element carrying `role="menu"` (the menu content), and
7
+ * nothing else is — the same contract the dialogs have. The menu portals out, so this is the only
8
+ * way to address the rendered list, e.g. from a test.
9
+ */
10
+ export interface BitkitActionMenuProps extends Omit<MenuRootProps, 'children'>, BitkitDataAttributes {
5
11
  /** The menu's items — `BitkitActionMenu.Item`, `.Group` and `.Separator`. */
6
12
  children?: ReactNode;
7
13
  /**
@@ -15,7 +21,7 @@ export interface BitkitActionMenuProps extends Omit<MenuRootProps, 'children'> {
15
21
  */
16
22
  trigger: ReactNode;
17
23
  }
18
- interface BitkitActionMenuItemCommonProps extends MenuItemProps {
24
+ interface BitkitActionMenuItemCommonProps extends Omit<MenuItemProps, 'value'> {
19
25
  /** The item's label. */
20
26
  children?: ReactNode;
21
27
  /** Leading icon, sized from the menu's `size` (24 on `lg`, 16 on `md`). */
@@ -24,6 +30,12 @@ interface BitkitActionMenuItemCommonProps extends MenuItemProps {
24
30
  isDanger?: boolean;
25
31
  /** A second, quieter line under the label. Adding it makes the row taller and top-aligns the icon. */
26
32
  secondaryText?: ReactNode;
33
+ /**
34
+ * Identifies the item to the menu machine. Omit it for a command item that does its own work in
35
+ * `onClick` — a generated id is used, and typeahead matches the label either way. Pass one when
36
+ * you read `onSelect` on the menu itself and need to tell the items apart.
37
+ */
38
+ value?: string;
27
39
  }
28
40
  interface BitkitActionMenuItemAsButtonProps extends BitkitActionMenuItemCommonProps {
29
41
  href?: undefined;
@@ -1,7 +1,8 @@
1
1
  import { withSubComponents } from "../../utilities/withSubComponents.js";
2
2
  import IconArrowNortheast from "../../icons/IconArrowNortheast.js";
3
+ import { splitDataAttributes } from "../../utilities/dataAttributes.js";
3
4
  import { Box } from "@chakra-ui/react/box";
4
- import { createContext, forwardRef, useContext } from "react";
5
+ import { createContext, forwardRef, useContext, useId } from "react";
5
6
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
6
7
  import { Portal } from "@chakra-ui/react/portal";
7
8
  import { Menu, useMenuStyles } from "@chakra-ui/react/menu";
@@ -10,15 +11,19 @@ import { Text } from "@chakra-ui/react/text";
10
11
  //#region lib/components/BitkitActionMenu/BitkitActionMenu.tsx
11
12
  var BitkitActionMenuContext = createContext("lg");
12
13
  var BitkitActionMenu = ({ trigger, children, size = "lg", ...props }) => {
14
+ const { dataAttributes, rest: rootProps } = splitDataAttributes(props);
13
15
  return /* @__PURE__ */ jsxs(Menu.Root, {
14
16
  size,
15
- ...props,
17
+ ...rootProps,
16
18
  children: [/* @__PURE__ */ jsx(Menu.Trigger, {
17
19
  asChild: true,
18
20
  children: trigger
19
21
  }), /* @__PURE__ */ jsx(Portal, { children: /* @__PURE__ */ jsx(Menu.Positioner, { children: /* @__PURE__ */ jsx(BitkitActionMenuContext.Provider, {
20
22
  value: size,
21
- children: /* @__PURE__ */ jsx(Menu.Content, { children })
23
+ children: /* @__PURE__ */ jsx(Menu.Content, {
24
+ ...dataAttributes,
25
+ children
26
+ })
22
27
  }) }) })]
23
28
  });
24
29
  };
@@ -28,6 +33,7 @@ var BitkitActionMenuItem = forwardRef((props, ref) => {
28
33
  const style = useMenuStyles();
29
34
  const iconSize = useContext(BitkitActionMenuContext) === "lg" ? "24" : "16";
30
35
  const hasHelper = secondaryText ? true : void 0;
36
+ const fallbackValue = useId();
31
37
  const content = /* @__PURE__ */ jsxs(Fragment$1, { children: [
32
38
  Icon && /* @__PURE__ */ jsx(Icon, { size: iconSize }),
33
39
  /* @__PURE__ */ jsxs(Box, {
@@ -43,13 +49,14 @@ var BitkitActionMenuItem = forwardRef((props, ref) => {
43
49
  })
44
50
  ] });
45
51
  if (props.href !== void 0) {
46
- const { children: _children, href, icon: _icon, isDanger: _isDanger, isExternal, rel, secondaryText: _secondaryText, target, ...rest } = props;
52
+ const { children: _children, href, icon: _icon, isDanger: _isDanger, isExternal, rel, secondaryText: _secondaryText, target, value, ...rest } = props;
47
53
  const effectiveTarget = isExternal ? "_blank" : target;
48
54
  const effectiveRel = isExternal ? rel ? `${rel} noreferrer noopener` : "noreferrer noopener" : rel;
49
55
  return /* @__PURE__ */ jsx(Menu.Item, {
50
56
  asChild: true,
51
57
  "data-danger": isDanger,
52
58
  "data-helper": hasHelper,
59
+ value: value ?? fallbackValue,
53
60
  ...rest,
54
61
  children: /* @__PURE__ */ jsx("a", {
55
62
  ref,
@@ -60,11 +67,12 @@ var BitkitActionMenuItem = forwardRef((props, ref) => {
60
67
  })
61
68
  });
62
69
  }
63
- const { children: _children, icon: _icon, isDanger: _isDanger, secondaryText: _secondaryText, ...rest } = props;
70
+ const { children: _children, icon: _icon, isDanger: _isDanger, secondaryText: _secondaryText, value, ...rest } = props;
64
71
  return /* @__PURE__ */ jsx(Menu.Item, {
65
72
  "data-danger": isDanger,
66
73
  "data-helper": hasHelper,
67
74
  ref,
75
+ value: value ?? fallbackValue,
68
76
  ...rest,
69
77
  children: content
70
78
  });
@@ -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 type MenuSeparatorProps,\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, IconArrowNortheast } from '../../icons';\nimport { withSubComponents } from '../../utilities/withSubComponents';\n\nconst BitkitActionMenuContext = createContext<MenuRootProps['size']>('lg');\n\nexport interface BitkitActionMenuProps extends Omit<MenuRootProps, 'children'> {\n /** The menu's items — `BitkitActionMenu.Item`, `.Group` and `.Separator`. */\n children?: ReactNode;\n /**\n * Row density, inherited by every item. `lg` (default) is the standalone action menu; `md` is for\n * menus attached to dense UI, such as an overflow menu in a toolbar or a tab bar.\n */\n size?: MenuRootProps['size'];\n /**\n * The element the menu is anchored to — usually a `BitkitIconButton` or `BitkitButton`. Rendered\n * via `asChild`, so it must accept a ref.\n */\n trigger: ReactNode;\n}\n\nconst BitkitActionMenu = ({ trigger, children, size = 'lg', ...props }: BitkitActionMenuProps) => {\n return (\n <Menu.Root size={size} {...props}>\n <Menu.Trigger asChild>{trigger}</Menu.Trigger>\n <Portal>\n <Menu.Positioner>\n <BitkitActionMenuContext.Provider value={size}>\n <Menu.Content>{children}</Menu.Content>\n </BitkitActionMenuContext.Provider>\n </Menu.Positioner>\n </Portal>\n </Menu.Root>\n );\n};\nBitkitActionMenu.displayName = 'BitkitActionMenu';\n\ninterface BitkitActionMenuItemCommonProps extends MenuItemProps {\n /** The item's label. */\n children?: ReactNode;\n /** Leading icon, sized from the menu's `size` (24 on `lg`, 16 on `md`). */\n icon?: BitkitIconComponent;\n /** Style the item as destructive — red label and icon. Use it for delete and similar actions. */\n isDanger?: boolean;\n /** A second, quieter line under the label. Adding it makes the row taller and top-aligns the icon. */\n secondaryText?: ReactNode;\n}\n\ninterface BitkitActionMenuItemAsButtonProps extends BitkitActionMenuItemCommonProps {\n href?: undefined;\n isExternal?: undefined;\n rel?: undefined;\n target?: undefined;\n}\n\ninterface BitkitActionMenuItemAsAnchorProps extends BitkitActionMenuItemCommonProps {\n /** Renders the item as an `<a>` instead of a menu button. */\n href: string;\n /**\n * Shorthand for `target=\"_blank\"` plus `rel=\"noreferrer noopener\"`. Also puts an\n * `IconArrowNortheast` at the end of the row — the design system's \"leaves this page\" marker.\n */\n isExternal?: boolean;\n /** Extra `rel` tokens. With `isExternal` the safety tokens are appended to these. */\n rel?: string;\n /** Anchor target. Ignored when `isExternal` is set. */\n target?: string;\n}\n\nexport type BitkitActionMenuItemProps = BitkitActionMenuItemAsButtonProps | BitkitActionMenuItemAsAnchorProps;\n\nconst BitkitActionMenuItem = forwardRef<HTMLElement, BitkitActionMenuItemProps>((props, ref) => {\n const { children, icon: Icon, isDanger, secondaryText } = props;\n const style = useMenuStyles();\n const menuCtx = useContext(BitkitActionMenuContext);\n const iconSize = menuCtx === 'lg' ? '24' : '16';\n const hasHelper = secondaryText ? true : undefined;\n\n const content = (\n <>\n {Icon && <Icon size={iconSize} />}\n <Box flex=\"1\">\n <Text>{children}</Text>\n {secondaryText && <Text css={style.itemHelper}>{secondaryText}</Text>}\n </Box>\n {props.isExternal && <IconArrowNortheast data-suffix-icon size={iconSize} />}\n </>\n );\n\n if (props.href !== undefined) {\n const {\n children: _children,\n href,\n icon: _icon,\n isDanger: _isDanger,\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={isDanger} data-helper={hasHelper} {...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, icon: _icon, isDanger: _isDanger, secondaryText: _secondaryText, ...rest } = props;\n return (\n <Menu.Item data-danger={isDanger} data-helper={hasHelper} ref={ref as Ref<HTMLDivElement>} {...rest}>\n {content}\n </Menu.Item>\n );\n});\nBitkitActionMenuItem.displayName = 'BitkitActionMenu.Item';\n\nexport interface BitkitActionMenuGroupProps extends MenuItemGroupProps {\n /** The group's items. */\n children?: ReactNode;\n /** The group's heading, rendered uppercase with a rule filling the rest of the row. */\n label: ReactNode;\n}\n\nconst BitkitActionMenuGroup = forwardRef<HTMLDivElement, BitkitActionMenuGroupProps>(\n ({ 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 },\n);\nBitkitActionMenuGroup.displayName = 'BitkitActionMenu.Group';\n\nexport type BitkitActionMenuSeparatorProps = MenuSeparatorProps;\n\nconst BitkitActionMenuSeparator = forwardRef<HTMLHRElement, BitkitActionMenuSeparatorProps>((props, ref) => {\n return <Menu.Separator ref={ref} {...props} />;\n});\nBitkitActionMenuSeparator.displayName = 'BitkitActionMenu.Separator';\n\nexport default withSubComponents(BitkitActionMenu, {\n Group: BitkitActionMenuGroup,\n Item: BitkitActionMenuItem,\n Separator: BitkitActionMenuSeparator,\n});\n"],"mappings":";;;;;;;;;;AAiBA,IAAM,0BAA0B,cAAqC,IAAI;AAiBzE,IAAM,oBAAoB,EAAE,SAAS,UAAU,OAAO,MAAM,GAAG,YAAmC;CAChG,OACE,qBAAC,KAAK,MAAN;EAAiB;EAAM,GAAI;EAA3B,UAAA,CACE,oBAAC,KAAK,SAAN;GAAc,SAAA;GAAS,UAAA;EAAsB,CAAA,GAC7C,oBAAC,QAAD,EAAA,UACE,oBAAC,KAAK,YAAN,EAAA,UACE,oBAAC,wBAAwB,UAAzB;GAAkC,OAAO;GACvC,UAAA,oBAAC,KAAK,SAAN,EAAe,SAAuB,CAAA;EACN,CAAA,EACnB,CAAA,EACX,CAAA,CACC;;AAEf;AACA,iBAAiB,cAAc;AAoC/B,IAAM,uBAAuB,YAAoD,OAAO,QAAQ;CAC9F,MAAM,EAAE,UAAU,MAAM,MAAM,UAAU,kBAAkB;CAC1D,MAAM,QAAQ,cAAc;CAE5B,MAAM,WADU,WAAW,uBACV,MAAY,OAAO,OAAO;CAC3C,MAAM,YAAY,gBAAgB,OAAO,KAAA;CAEzC,MAAM,UACJ,qBAAA,YAAA,EAAA,UAAA;EACG,QAAQ,oBAAC,MAAD,EAAM,MAAM,SAAW,CAAA;EAChC,qBAAC,KAAD;GAAK,MAAK;GAAV,UAAA,CACE,oBAAC,MAAD,EAAO,SAAe,CAAA,GACrB,iBAAiB,oBAAC,MAAD;IAAM,KAAK,MAAM;IAAa,UAAA;GAAoB,CAAA,CACjE;;EACJ,MAAM,cAAc,oBAAC,oBAAD;GAAoB,oBAAA;GAAiB,MAAM;EAAW,CAAA;CAC3E,EAAA,CAAA;CAGJ,IAAI,MAAM,SAAS,KAAA,GAAW;EAC5B,MAAM,EACJ,UAAU,WACV,MACA,MAAM,OACN,UAAU,WACV,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;GAAU,eAAa;GAAW,GAAI;GACpE,UAAA,oBAAC,KAAD;IAAQ;IAAqC;IAAM,KAAK;IAAc,QAAQ;IAC3E,UAAA;GACA,CAAA;EACM,CAAA;CAEf;CAEA,MAAM,EAAE,UAAU,WAAW,MAAM,OAAO,UAAU,WAAW,eAAe,gBAAgB,GAAG,SAAS;CAC1G,OACE,oBAAC,KAAK,MAAN;EAAW,eAAa;EAAU,eAAa;EAAgB;EAA4B,GAAI;EAC5F,UAAA;CACQ,CAAA;AAEf,CAAC;AACD,qBAAqB,cAAc;AASnC,IAAM,wBAAwB,YAC3B,EAAE,OAAO,UAAU,GAAG,SAAS,QAAQ;CACtC,OACE,qBAAC,KAAK,WAAN;EAAqB;EAAK,GAAI;EAA9B,UAAA,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,CACF;AACA,sBAAsB,cAAc;AAIpC,IAAM,4BAA4B,YAA2D,OAAO,QAAQ;CAC1G,OAAO,oBAAC,KAAK,WAAN;EAAqB;EAAK,GAAI;CAAQ,CAAA;AAC/C,CAAC;AACD,0BAA0B,cAAc;AAExC,IAAA,2BAAe,kBAAkB,kBAAkB;CACjD,OAAO;CACP,MAAM;CACN,WAAW;AACb,CAAC"}
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 type MenuSeparatorProps,\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, useId } from 'react';\n\nimport { type BitkitIconComponent, IconArrowNortheast } from '../../icons';\nimport { type BitkitDataAttributes, splitDataAttributes } from '../../utilities/dataAttributes';\nimport { withSubComponents } from '../../utilities/withSubComponents';\n\nconst BitkitActionMenuContext = createContext<MenuRootProps['size']>('lg');\n\n/**\n * `data-*` attributes are forwarded to the element carrying `role=\"menu\"` (the menu content), and\n * nothing else is — the same contract the dialogs have. The menu portals out, so this is the only\n * way to address the rendered list, e.g. from a test.\n */\nexport interface BitkitActionMenuProps extends Omit<MenuRootProps, 'children'>, BitkitDataAttributes {\n /** The menu's items — `BitkitActionMenu.Item`, `.Group` and `.Separator`. */\n children?: ReactNode;\n /**\n * Row density, inherited by every item. `lg` (default) is the standalone action menu; `md` is for\n * menus attached to dense UI, such as an overflow menu in a toolbar or a tab bar.\n */\n size?: MenuRootProps['size'];\n /**\n * The element the menu is anchored to — usually a `BitkitIconButton` or `BitkitButton`. Rendered\n * via `asChild`, so it must accept a ref.\n */\n trigger: ReactNode;\n}\n\nconst BitkitActionMenu = ({ trigger, children, size = 'lg', ...props }: BitkitActionMenuProps) => {\n // `Menu.Root` is a provider, not an element, so it drops the `data-*` attributes — they belong on\n // the content, which is the element carrying `role=\"menu\"`.\n const { dataAttributes, rest: rootProps } = splitDataAttributes(props);\n\n return (\n <Menu.Root size={size} {...rootProps}>\n <Menu.Trigger asChild>{trigger}</Menu.Trigger>\n <Portal>\n <Menu.Positioner>\n <BitkitActionMenuContext.Provider value={size}>\n <Menu.Content {...dataAttributes}>{children}</Menu.Content>\n </BitkitActionMenuContext.Provider>\n </Menu.Positioner>\n </Portal>\n </Menu.Root>\n );\n};\nBitkitActionMenu.displayName = 'BitkitActionMenu';\n\ninterface BitkitActionMenuItemCommonProps extends Omit<MenuItemProps, 'value'> {\n /** The item's label. */\n children?: ReactNode;\n /** Leading icon, sized from the menu's `size` (24 on `lg`, 16 on `md`). */\n icon?: BitkitIconComponent;\n /** Style the item as destructive — red label and icon. Use it for delete and similar actions. */\n isDanger?: boolean;\n /** A second, quieter line under the label. Adding it makes the row taller and top-aligns the icon. */\n secondaryText?: ReactNode;\n /**\n * Identifies the item to the menu machine. Omit it for a command item that does its own work in\n * `onClick` — a generated id is used, and typeahead matches the label either way. Pass one when\n * you read `onSelect` on the menu itself and need to tell the items apart.\n */\n value?: string;\n}\n\ninterface BitkitActionMenuItemAsButtonProps extends BitkitActionMenuItemCommonProps {\n href?: undefined;\n isExternal?: undefined;\n rel?: undefined;\n target?: undefined;\n}\n\ninterface BitkitActionMenuItemAsAnchorProps extends BitkitActionMenuItemCommonProps {\n /** Renders the item as an `<a>` instead of a menu button. */\n href: string;\n /**\n * Shorthand for `target=\"_blank\"` plus `rel=\"noreferrer noopener\"`. Also puts an\n * `IconArrowNortheast` at the end of the row — the design system's \"leaves this page\" marker.\n */\n isExternal?: boolean;\n /** Extra `rel` tokens. With `isExternal` the safety tokens are appended to these. */\n rel?: string;\n /** Anchor target. Ignored when `isExternal` is set. */\n target?: string;\n}\n\nexport type BitkitActionMenuItemProps = BitkitActionMenuItemAsButtonProps | BitkitActionMenuItemAsAnchorProps;\n\nconst BitkitActionMenuItem = forwardRef<HTMLElement, BitkitActionMenuItemProps>((props, ref) => {\n const { children, icon: Icon, isDanger, secondaryText } = props;\n const style = useMenuStyles();\n const menuCtx = useContext(BitkitActionMenuContext);\n const iconSize = menuCtx === 'lg' ? '24' : '16';\n const hasHelper = secondaryText ? true : undefined;\n const fallbackValue = useId();\n\n const content = (\n <>\n {Icon && <Icon size={iconSize} />}\n <Box flex=\"1\">\n <Text>{children}</Text>\n {secondaryText && <Text css={style.itemHelper}>{secondaryText}</Text>}\n </Box>\n {props.isExternal && <IconArrowNortheast data-suffix-icon size={iconSize} />}\n </>\n );\n\n if (props.href !== undefined) {\n const {\n children: _children,\n href,\n icon: _icon,\n isDanger: _isDanger,\n isExternal,\n rel,\n secondaryText: _secondaryText,\n target,\n value,\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={isDanger} data-helper={hasHelper} value={value ?? fallbackValue} {...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 {\n children: _children,\n icon: _icon,\n isDanger: _isDanger,\n secondaryText: _secondaryText,\n value,\n ...rest\n } = props;\n return (\n <Menu.Item\n data-danger={isDanger}\n data-helper={hasHelper}\n ref={ref as Ref<HTMLDivElement>}\n value={value ?? fallbackValue}\n {...rest}\n >\n {content}\n </Menu.Item>\n );\n});\nBitkitActionMenuItem.displayName = 'BitkitActionMenu.Item';\n\nexport interface BitkitActionMenuGroupProps extends MenuItemGroupProps {\n /** The group's items. */\n children?: ReactNode;\n /** The group's heading, rendered uppercase with a rule filling the rest of the row. */\n label: ReactNode;\n}\n\nconst BitkitActionMenuGroup = forwardRef<HTMLDivElement, BitkitActionMenuGroupProps>(\n ({ 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 },\n);\nBitkitActionMenuGroup.displayName = 'BitkitActionMenu.Group';\n\nexport type BitkitActionMenuSeparatorProps = MenuSeparatorProps;\n\nconst BitkitActionMenuSeparator = forwardRef<HTMLHRElement, BitkitActionMenuSeparatorProps>((props, ref) => {\n return <Menu.Separator ref={ref} {...props} />;\n});\nBitkitActionMenuSeparator.displayName = 'BitkitActionMenu.Separator';\n\nexport default withSubComponents(BitkitActionMenu, {\n Group: BitkitActionMenuGroup,\n Item: BitkitActionMenuItem,\n Separator: BitkitActionMenuSeparator,\n});\n"],"mappings":";;;;;;;;;;;AAkBA,IAAM,0BAA0B,cAAqC,IAAI;AAsBzE,IAAM,oBAAoB,EAAE,SAAS,UAAU,OAAO,MAAM,GAAG,YAAmC;CAGhG,MAAM,EAAE,gBAAgB,MAAM,cAAc,oBAAoB,KAAK;CAErE,OACE,qBAAC,KAAK,MAAN;EAAiB;EAAM,GAAI;EAA3B,UAAA,CACE,oBAAC,KAAK,SAAN;GAAc,SAAA;GAAS,UAAA;EAAsB,CAAA,GAC7C,oBAAC,QAAD,EAAA,UACE,oBAAC,KAAK,YAAN,EAAA,UACE,oBAAC,wBAAwB,UAAzB;GAAkC,OAAO;GACvC,UAAA,oBAAC,KAAK,SAAN;IAAc,GAAI;IAAiB;GAAuB,CAAA;EAC1B,CAAA,EACnB,CAAA,EACX,CAAA,CACC;;AAEf;AACA,iBAAiB,cAAc;AA0C/B,IAAM,uBAAuB,YAAoD,OAAO,QAAQ;CAC9F,MAAM,EAAE,UAAU,MAAM,MAAM,UAAU,kBAAkB;CAC1D,MAAM,QAAQ,cAAc;CAE5B,MAAM,WADU,WAAW,uBACV,MAAY,OAAO,OAAO;CAC3C,MAAM,YAAY,gBAAgB,OAAO,KAAA;CACzC,MAAM,gBAAgB,MAAM;CAE5B,MAAM,UACJ,qBAAA,YAAA,EAAA,UAAA;EACG,QAAQ,oBAAC,MAAD,EAAM,MAAM,SAAW,CAAA;EAChC,qBAAC,KAAD;GAAK,MAAK;GAAV,UAAA,CACE,oBAAC,MAAD,EAAO,SAAe,CAAA,GACrB,iBAAiB,oBAAC,MAAD;IAAM,KAAK,MAAM;IAAa,UAAA;GAAoB,CAAA,CACjE;;EACJ,MAAM,cAAc,oBAAC,oBAAD;GAAoB,oBAAA;GAAiB,MAAM;EAAW,CAAA;CAC3E,EAAA,CAAA;CAGJ,IAAI,MAAM,SAAS,KAAA,GAAW;EAC5B,MAAM,EACJ,UAAU,WACV,MACA,MAAM,OACN,UAAU,WACV,YACA,KACA,eAAe,gBACf,QACA,OACA,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;GAAU,eAAa;GAAW,OAAO,SAAS;GAAe,GAAI;GACnG,UAAA,oBAAC,KAAD;IAAQ;IAAqC;IAAM,KAAK;IAAc,QAAQ;IAC3E,UAAA;GACA,CAAA;EACM,CAAA;CAEf;CAEA,MAAM,EACJ,UAAU,WACV,MAAM,OACN,UAAU,WACV,eAAe,gBACf,OACA,GAAG,SACD;CACJ,OACE,oBAAC,KAAK,MAAN;EACE,eAAa;EACb,eAAa;EACR;EACL,OAAO,SAAS;EAChB,GAAI;EAEH,UAAA;CACQ,CAAA;AAEf,CAAC;AACD,qBAAqB,cAAc;AASnC,IAAM,wBAAwB,YAC3B,EAAE,OAAO,UAAU,GAAG,SAAS,QAAQ;CACtC,OACE,qBAAC,KAAK,WAAN;EAAqB;EAAK,GAAI;EAA9B,UAAA,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,CACF;AACA,sBAAsB,cAAc;AAIpC,IAAM,4BAA4B,YAA2D,OAAO,QAAQ;CAC1G,OAAO,oBAAC,KAAK,WAAN;EAAqB;EAAK,GAAI;CAAQ,CAAA;AAC/C,CAAC;AACD,0BAA0B,cAAc;AAExC,IAAA,2BAAe,kBAAkB,kBAAkB;CACjD,OAAO;CACP,MAAM;CACN,WAAW;AACb,CAAC"}
@@ -1,6 +1,7 @@
1
1
  import { Dialog } from '@chakra-ui/react/dialog';
2
2
  import { ReactNode } from 'react';
3
- import { DialogDataAttributes, DialogShellProps } from './DialogShell';
3
+ import { BitkitDataAttributes } from '../../utilities/dataAttributes';
4
+ import { DialogShellProps } from './DialogShell';
4
5
  export type BitkitDialogProps = {
5
6
  children?: ReactNode;
6
7
  closable?: boolean;
@@ -22,7 +23,7 @@ export type BitkitDialogProps = {
22
23
  title: ReactNode;
23
24
  trigger?: ReactNode;
24
25
  variant?: 'overflowContent';
25
- } & DialogDataAttributes;
26
+ } & BitkitDataAttributes;
26
27
  declare const _default: {
27
28
  ({ children, closable, footerButtons, footerContent, headerLabel, initialFocusEl, maxHeight, onExitComplete, onOpenChange, open, preventScroll, scrollBehavior, showScrollGradient, size, title, trigger, variant, ...dataAttributes }: BitkitDialogProps): import("react").JSX.Element;
28
29
  displayName: string;
@@ -1 +1 @@
1
- {"version":3,"file":"BitkitDialog.js","names":[],"sources":["../../../lib/components/BitkitDialog/BitkitDialog.tsx"],"sourcesContent":["import { Dialog } from '@chakra-ui/react/dialog';\nimport { type ReactNode } from 'react';\n\nimport { withSubComponents } from '../../utilities/withSubComponents';\nimport DialogInner from './DialogInner';\nimport DialogShell, { type DialogDataAttributes, type DialogShellProps } from './DialogShell';\n\nexport type BitkitDialogProps = {\n children?: ReactNode;\n closable?: boolean;\n footerButtons?: ReactNode;\n footerContent?: ReactNode;\n headerLabel?: string;\n /** Element to focus when the dialog opens, instead of the first focusable one. */\n initialFocusEl?: DialogShellProps['initialFocusEl'];\n maxHeight?: string;\n onExitComplete?: () => void;\n onOpenChange?: (details: { open: boolean }) => void;\n open?: boolean;\n preventScroll?: boolean;\n scrollBehavior?: 'inside' | 'outside';\n showScrollGradient?: boolean;\n size?: 'sm' | 'md' | 'lg' | 'full';\n title: ReactNode;\n trigger?: ReactNode;\n variant?: 'overflowContent';\n} & DialogDataAttributes;\n\nconst BitkitDialog = ({\n children,\n closable = true,\n footerButtons,\n footerContent,\n headerLabel,\n initialFocusEl,\n maxHeight,\n onExitComplete,\n onOpenChange,\n open,\n preventScroll,\n scrollBehavior,\n showScrollGradient,\n size,\n title,\n trigger,\n variant,\n ...dataAttributes\n}: BitkitDialogProps) => (\n <DialogShell\n closable={closable}\n initialFocusEl={initialFocusEl}\n onExitComplete={onExitComplete}\n onOpenChange={onOpenChange}\n open={open}\n preventScroll={preventScroll}\n scrollBehavior={scrollBehavior}\n size={size}\n trigger={trigger}\n variant={variant}\n >\n <Dialog.Content maxHeight={maxHeight} {...dataAttributes}>\n <DialogInner\n closable={closable}\n footerButtons={footerButtons}\n footerContent={footerContent}\n headerLabel={headerLabel}\n scrollBehavior={scrollBehavior}\n showScrollGradient={showScrollGradient}\n title={title}\n variant={variant}\n >\n {children}\n </DialogInner>\n </Dialog.Content>\n </DialogShell>\n);\n\nBitkitDialog.displayName = 'BitkitDialog';\n\nexport default withSubComponents(BitkitDialog, { ActionTrigger: Dialog.ActionTrigger });\n"],"mappings":";;;;;;AA4BA,IAAM,gBAAgB,EACpB,UACA,WAAW,MACX,eACA,eACA,aACA,gBACA,WACA,gBACA,cACA,MACA,eACA,gBACA,oBACA,MACA,OACA,SACA,SACA,GAAG,qBAEH,oBAAC,aAAD;CACY;CACM;CACA;CACF;CACR;CACS;CACC;CACV;CACG;CACA;CAET,UAAA,oBAAC,OAAO,SAAR;EAA2B;EAAW,GAAI;EACxC,UAAA,oBAAC,aAAD;GACY;GACK;GACA;GACF;GACG;GACI;GACb;GACE;GAER;EACU,CAAA;CACC,CAAA;AACL,CAAA;AAGf,aAAa,cAAc;AAE3B,IAAA,uBAAe,kBAAkB,cAAc,EAAE,eAAe,OAAO,cAAc,CAAC"}
1
+ {"version":3,"file":"BitkitDialog.js","names":[],"sources":["../../../lib/components/BitkitDialog/BitkitDialog.tsx"],"sourcesContent":["import { Dialog } from '@chakra-ui/react/dialog';\nimport { type ReactNode } from 'react';\n\nimport { type BitkitDataAttributes } from '../../utilities/dataAttributes';\nimport { withSubComponents } from '../../utilities/withSubComponents';\nimport DialogInner from './DialogInner';\nimport DialogShell, { type DialogShellProps } from './DialogShell';\n\nexport type BitkitDialogProps = {\n children?: ReactNode;\n closable?: boolean;\n footerButtons?: ReactNode;\n footerContent?: ReactNode;\n headerLabel?: string;\n /** Element to focus when the dialog opens, instead of the first focusable one. */\n initialFocusEl?: DialogShellProps['initialFocusEl'];\n maxHeight?: string;\n onExitComplete?: () => void;\n onOpenChange?: (details: { open: boolean }) => void;\n open?: boolean;\n preventScroll?: boolean;\n scrollBehavior?: 'inside' | 'outside';\n showScrollGradient?: boolean;\n size?: 'sm' | 'md' | 'lg' | 'full';\n title: ReactNode;\n trigger?: ReactNode;\n variant?: 'overflowContent';\n // Data attributes are forwarded to the element carrying `role=\"dialog\"`, and nothing else is —\n // style props, `className` and `id` don't pass through.\n} & BitkitDataAttributes;\n\nconst BitkitDialog = ({\n children,\n closable = true,\n footerButtons,\n footerContent,\n headerLabel,\n initialFocusEl,\n maxHeight,\n onExitComplete,\n onOpenChange,\n open,\n preventScroll,\n scrollBehavior,\n showScrollGradient,\n size,\n title,\n trigger,\n variant,\n ...dataAttributes\n}: BitkitDialogProps) => (\n <DialogShell\n closable={closable}\n initialFocusEl={initialFocusEl}\n onExitComplete={onExitComplete}\n onOpenChange={onOpenChange}\n open={open}\n preventScroll={preventScroll}\n scrollBehavior={scrollBehavior}\n size={size}\n trigger={trigger}\n variant={variant}\n >\n <Dialog.Content maxHeight={maxHeight} {...dataAttributes}>\n <DialogInner\n closable={closable}\n footerButtons={footerButtons}\n footerContent={footerContent}\n headerLabel={headerLabel}\n scrollBehavior={scrollBehavior}\n showScrollGradient={showScrollGradient}\n title={title}\n variant={variant}\n >\n {children}\n </DialogInner>\n </Dialog.Content>\n </DialogShell>\n);\n\nBitkitDialog.displayName = 'BitkitDialog';\n\nexport default withSubComponents(BitkitDialog, { ActionTrigger: Dialog.ActionTrigger });\n"],"mappings":";;;;;;AA+BA,IAAM,gBAAgB,EACpB,UACA,WAAW,MACX,eACA,eACA,aACA,gBACA,WACA,gBACA,cACA,MACA,eACA,gBACA,oBACA,MACA,OACA,SACA,SACA,GAAG,qBAEH,oBAAC,aAAD;CACY;CACM;CACA;CACF;CACR;CACS;CACC;CACV;CACG;CACA;CAET,UAAA,oBAAC,OAAO,SAAR;EAA2B;EAAW,GAAI;EACxC,UAAA,oBAAC,aAAD;GACY;GACK;GACA;GACF;GACG;GACI;GACb;GACE;GAER;EACU,CAAA;CACC,CAAA;AACL,CAAA;AAGf,aAAa,cAAc;AAE3B,IAAA,uBAAe,kBAAkB,cAAc,EAAE,eAAe,OAAO,cAAc,CAAC"}
@@ -26,7 +26,7 @@ declare const _default: import('react').ForwardRefExoticComponent<{
26
26
  title: import('react').ReactNode;
27
27
  trigger?: import('react').ReactNode;
28
28
  variant?: "overflowContent";
29
- } & import('./DialogShell').DialogDataAttributes & {
29
+ } & import('../../utilities/dataAttributes').BitkitDataAttributes & {
30
30
  /** Skips the browser's native constraint validation on submit. */
31
31
  noValidate?: boolean;
32
32
  onSubmit?: FormEventHandler<HTMLFormElement>;
@@ -1,7 +1,8 @@
1
1
  import { Dialog } from '@chakra-ui/react/dialog';
2
2
  import { ReactNode } from 'react';
3
+ import { BitkitDataAttributes } from '../../utilities/dataAttributes';
3
4
  import { BitkitStepperDialogStepProps } from './BitkitStepperDialogStep';
4
- import { DialogDataAttributes, DialogShellProps } from './DialogShell';
5
+ import { DialogShellProps } from './DialogShell';
5
6
  export { useStepperDialog } from './StepperContext';
6
7
  export type BitkitStepperDialogProps = {
7
8
  /** `BitkitStepperDialog.Step` children, one per step. */
@@ -35,7 +36,7 @@ export type BitkitStepperDialogProps = {
35
36
  title: ReactNode;
36
37
  trigger?: ReactNode;
37
38
  variant?: 'overflowContent';
38
- } & DialogDataAttributes;
39
+ } & BitkitDataAttributes;
39
40
  declare const _default: {
40
41
  ({ children, closable, defaultStep, initialFocusEl, footerContent, headerLabel, maxHeight, onExitComplete, onOpenChange, onStepChange, open, preventScroll, scrollBehavior, showScrollGradient, size, step: stepProp, title, trigger, variant, ...dataAttributes }: BitkitStepperDialogProps): import("react").JSX.Element;
41
42
  displayName: string;
@@ -1 +1 @@
1
- {"version":3,"file":"BitkitStepperDialog.js","names":[],"sources":["../../../lib/components/BitkitDialog/BitkitStepperDialog.tsx"],"sourcesContent":["import { Dialog } from '@chakra-ui/react/dialog';\nimport { type ReactElement, type ReactNode, useCallback, useMemo, useState } from 'react';\n\nimport { flattenChildren } from '../../utilities/flattenChildren';\nimport { withSubComponents } from '../../utilities/withSubComponents';\nimport BitkitSteps from '../BitkitSteps/BitkitSteps';\nimport BitkitStepperDialogStep, { type BitkitStepperDialogStepProps } from './BitkitStepperDialogStep';\nimport DialogInner from './DialogInner';\nimport DialogShell, { type DialogDataAttributes, type DialogShellProps } from './DialogShell';\nimport { StepperDialogProvider } from './StepperContext';\n\nexport { useStepperDialog } from './StepperContext';\n\nexport type BitkitStepperDialogProps = {\n /** `BitkitStepperDialog.Step` children, one per step. */\n children: ReactNode;\n closable?: boolean;\n /** Initial step when uncontrolled. Resets to this when the dialog closes. */\n defaultStep?: number;\n /** Element to focus when the dialog opens, instead of the first focusable one. */\n initialFocusEl?: DialogShellProps['initialFocusEl'];\n /**\n * Footer content rendered raw. Stepper footers are space-between (Cancel left, Prev/Next right),\n * so build the nav row here with `useStepperDialog()` — there is no `footerButtons` slot, which\n * would force right-alignment.\n */\n footerContent?: ReactNode;\n headerLabel?: string;\n maxHeight?: string;\n onExitComplete?: () => void;\n onOpenChange?: (details: { open: boolean }) => void;\n /** Called whenever the active step changes (controlled or uncontrolled). */\n onStepChange?: (step: number) => void;\n open?: boolean;\n preventScroll?: boolean;\n scrollBehavior?: 'inside' | 'outside';\n showScrollGradient?: boolean;\n size?: 'sm' | 'md' | 'lg' | 'full';\n /** Controlled active step. Omit for uncontrolled (see `defaultStep`). */\n step?: number;\n title: ReactNode;\n trigger?: ReactNode;\n variant?: 'overflowContent';\n} & DialogDataAttributes;\n\n/**\n * A dialog that walks through a sequence of `BitkitStepperDialog.Step` children. It owns the step\n * state, auto-renders the steps header, and shows only the active step's body. Footer navigation is\n * wired by the consumer through the `useStepperDialog()` hook.\n */\nconst BitkitStepperDialog = ({\n children,\n closable = true,\n defaultStep = 0,\n initialFocusEl,\n footerContent,\n headerLabel,\n maxHeight,\n onExitComplete,\n onOpenChange,\n onStepChange,\n open,\n preventScroll,\n scrollBehavior,\n showScrollGradient,\n size,\n step: stepProp,\n title,\n trigger,\n variant,\n ...dataAttributes\n}: BitkitStepperDialogProps) => {\n const [internalStep, setInternalStep] = useState(defaultStep);\n const isControlled = stepProp !== undefined;\n const rawStep = (isControlled ? stepProp : internalStep) ?? 0;\n const steps = flattenChildren(children).filter(\n (child): child is ReactElement<BitkitStepperDialogStepProps> => child.type === BitkitStepperDialogStep,\n );\n const totalSteps = steps.length;\n const step = Math.max(0, Math.min(rawStep, Math.max(0, totalSteps - 1)));\n\n const setStep = useCallback(\n (next: number) => {\n const clamped = Math.max(0, Math.min(next, totalSteps - 1));\n if (!isControlled) setInternalStep(clamped);\n onStepChange?.(clamped);\n },\n [isControlled, onStepChange, totalSteps],\n );\n\n const ctx = useMemo(\n () => ({\n goTo: setStep,\n isFirst: step === 0,\n isLast: step === totalSteps - 1,\n next: () => setStep(step + 1),\n prev: () => setStep(step - 1),\n setStep,\n step,\n totalSteps,\n }),\n [setStep, step, totalSteps],\n );\n\n const handleOpenChange = (details: { open: boolean }) => {\n if (!details.open && !isControlled) setInternalStep(defaultStep);\n onOpenChange?.(details);\n };\n\n const stepsHeader = (\n <BitkitSteps step={step}>\n {steps.map((child, index) => (\n <BitkitSteps.Item key={index} label={child.props.label} />\n ))}\n </BitkitSteps>\n );\n\n return (\n <StepperDialogProvider value={ctx}>\n <DialogShell\n closable={closable}\n initialFocusEl={initialFocusEl}\n onExitComplete={onExitComplete}\n onOpenChange={handleOpenChange}\n open={open}\n preventScroll={preventScroll}\n scrollBehavior={scrollBehavior}\n size={size}\n trigger={trigger}\n variant={variant}\n >\n <Dialog.Content maxHeight={maxHeight} {...dataAttributes}>\n <DialogInner\n closable={closable}\n footerContent={footerContent}\n headerExtra={stepsHeader}\n headerLabel={headerLabel}\n scrollBehavior={scrollBehavior}\n showScrollGradient={showScrollGradient}\n title={title}\n variant={variant}\n >\n {steps[step]}\n </DialogInner>\n </Dialog.Content>\n </DialogShell>\n </StepperDialogProvider>\n );\n};\n\nBitkitStepperDialog.displayName = 'BitkitStepperDialog';\n\nexport default withSubComponents(BitkitStepperDialog, {\n ActionTrigger: Dialog.ActionTrigger,\n Step: BitkitStepperDialogStep,\n});\n"],"mappings":";;;;;;;;;;;;;;;;AAkDA,IAAM,uBAAuB,EAC3B,UACA,WAAW,MACX,cAAc,GACd,gBACA,eACA,aACA,WACA,gBACA,cACA,cACA,MACA,eACA,gBACA,oBACA,MACA,MAAM,UACN,OACA,SACA,SACA,GAAG,qBAC2B;CAC9B,MAAM,CAAC,cAAc,mBAAmB,SAAS,WAAW;CAC5D,MAAM,eAAe,aAAa,KAAA;CAClC,MAAM,WAAW,eAAe,WAAW,iBAAiB;CAC5D,MAAM,QAAQ,gBAAgB,QAAQ,CAAC,CAAC,QACrC,UAA+D,MAAM,SAAS,uBACjF;CACA,MAAM,aAAa,MAAM;CACzB,MAAM,OAAO,KAAK,IAAI,GAAG,KAAK,IAAI,SAAS,KAAK,IAAI,GAAG,aAAa,CAAC,CAAC,CAAC;CAEvE,MAAM,UAAU,aACb,SAAiB;EAChB,MAAM,UAAU,KAAK,IAAI,GAAG,KAAK,IAAI,MAAM,aAAa,CAAC,CAAC;EAC1D,IAAI,CAAC,cAAc,gBAAgB,OAAO;EAC1C,eAAe,OAAO;CACxB,GACA;EAAC;EAAc;EAAc;CAAU,CACzC;CAEA,MAAM,MAAM,eACH;EACL,MAAM;EACN,SAAS,SAAS;EAClB,QAAQ,SAAS,aAAa;EAC9B,YAAY,QAAQ,OAAO,CAAC;EAC5B,YAAY,QAAQ,OAAO,CAAC;EAC5B;EACA;EACA;CACF,IACA;EAAC;EAAS;EAAM;CAAU,CAC5B;CAEA,MAAM,oBAAoB,YAA+B;EACvD,IAAI,CAAC,QAAQ,QAAQ,CAAC,cAAc,gBAAgB,WAAW;EAC/D,eAAe,OAAO;CACxB;CAEA,MAAM,cACJ,oBAAC,qBAAD;EAAmB;EAChB,UAAA,MAAM,KAAK,OAAO,UACjB,oBAAC,oBAAY,MAAb,EAA8B,OAAO,MAAM,MAAM,MAAQ,GAAlC,KAAkC,CAC1D;CACU,CAAA;CAGf,OACE,oBAAC,uBAAD;EAAuB,OAAO;EAC5B,UAAA,oBAAC,aAAD;GACY;GACM;GACA;GAChB,cAAc;GACR;GACS;GACC;GACV;GACG;GACA;GAET,UAAA,oBAAC,OAAO,SAAR;IAA2B;IAAW,GAAI;IACxC,UAAA,oBAAC,aAAD;KACY;KACK;KACf,aAAa;KACA;KACG;KACI;KACb;KACE;KAER,UAAA,MAAM;IACI,CAAA;GACC,CAAA;EACL,CAAA;CACQ,CAAA;AAE3B;AAEA,oBAAoB,cAAc;AAElC,IAAA,8BAAe,kBAAkB,qBAAqB;CACpD,eAAe,OAAO;CACtB,MAAM;AACR,CAAC"}
1
+ {"version":3,"file":"BitkitStepperDialog.js","names":[],"sources":["../../../lib/components/BitkitDialog/BitkitStepperDialog.tsx"],"sourcesContent":["import { Dialog } from '@chakra-ui/react/dialog';\nimport { type ReactElement, type ReactNode, useCallback, useMemo, useState } from 'react';\n\nimport { type BitkitDataAttributes } from '../../utilities/dataAttributes';\nimport { flattenChildren } from '../../utilities/flattenChildren';\nimport { withSubComponents } from '../../utilities/withSubComponents';\nimport BitkitSteps from '../BitkitSteps/BitkitSteps';\nimport BitkitStepperDialogStep, { type BitkitStepperDialogStepProps } from './BitkitStepperDialogStep';\nimport DialogInner from './DialogInner';\nimport DialogShell, { type DialogShellProps } from './DialogShell';\nimport { StepperDialogProvider } from './StepperContext';\n\nexport { useStepperDialog } from './StepperContext';\n\nexport type BitkitStepperDialogProps = {\n /** `BitkitStepperDialog.Step` children, one per step. */\n children: ReactNode;\n closable?: boolean;\n /** Initial step when uncontrolled. Resets to this when the dialog closes. */\n defaultStep?: number;\n /** Element to focus when the dialog opens, instead of the first focusable one. */\n initialFocusEl?: DialogShellProps['initialFocusEl'];\n /**\n * Footer content rendered raw. Stepper footers are space-between (Cancel left, Prev/Next right),\n * so build the nav row here with `useStepperDialog()` — there is no `footerButtons` slot, which\n * would force right-alignment.\n */\n footerContent?: ReactNode;\n headerLabel?: string;\n maxHeight?: string;\n onExitComplete?: () => void;\n onOpenChange?: (details: { open: boolean }) => void;\n /** Called whenever the active step changes (controlled or uncontrolled). */\n onStepChange?: (step: number) => void;\n open?: boolean;\n preventScroll?: boolean;\n scrollBehavior?: 'inside' | 'outside';\n showScrollGradient?: boolean;\n size?: 'sm' | 'md' | 'lg' | 'full';\n /** Controlled active step. Omit for uncontrolled (see `defaultStep`). */\n step?: number;\n title: ReactNode;\n trigger?: ReactNode;\n variant?: 'overflowContent';\n // Data attributes are forwarded to the element carrying `role=\"dialog\"`, and nothing else is —\n // style props, `className` and `id` don't pass through.\n} & BitkitDataAttributes;\n\n/**\n * A dialog that walks through a sequence of `BitkitStepperDialog.Step` children. It owns the step\n * state, auto-renders the steps header, and shows only the active step's body. Footer navigation is\n * wired by the consumer through the `useStepperDialog()` hook.\n */\nconst BitkitStepperDialog = ({\n children,\n closable = true,\n defaultStep = 0,\n initialFocusEl,\n footerContent,\n headerLabel,\n maxHeight,\n onExitComplete,\n onOpenChange,\n onStepChange,\n open,\n preventScroll,\n scrollBehavior,\n showScrollGradient,\n size,\n step: stepProp,\n title,\n trigger,\n variant,\n ...dataAttributes\n}: BitkitStepperDialogProps) => {\n const [internalStep, setInternalStep] = useState(defaultStep);\n const isControlled = stepProp !== undefined;\n const rawStep = (isControlled ? stepProp : internalStep) ?? 0;\n const steps = flattenChildren(children).filter(\n (child): child is ReactElement<BitkitStepperDialogStepProps> => child.type === BitkitStepperDialogStep,\n );\n const totalSteps = steps.length;\n const step = Math.max(0, Math.min(rawStep, Math.max(0, totalSteps - 1)));\n\n const setStep = useCallback(\n (next: number) => {\n const clamped = Math.max(0, Math.min(next, totalSteps - 1));\n if (!isControlled) setInternalStep(clamped);\n onStepChange?.(clamped);\n },\n [isControlled, onStepChange, totalSteps],\n );\n\n const ctx = useMemo(\n () => ({\n goTo: setStep,\n isFirst: step === 0,\n isLast: step === totalSteps - 1,\n next: () => setStep(step + 1),\n prev: () => setStep(step - 1),\n setStep,\n step,\n totalSteps,\n }),\n [setStep, step, totalSteps],\n );\n\n const handleOpenChange = (details: { open: boolean }) => {\n if (!details.open && !isControlled) setInternalStep(defaultStep);\n onOpenChange?.(details);\n };\n\n const stepsHeader = (\n <BitkitSteps step={step}>\n {steps.map((child, index) => (\n <BitkitSteps.Item key={index} label={child.props.label} />\n ))}\n </BitkitSteps>\n );\n\n return (\n <StepperDialogProvider value={ctx}>\n <DialogShell\n closable={closable}\n initialFocusEl={initialFocusEl}\n onExitComplete={onExitComplete}\n onOpenChange={handleOpenChange}\n open={open}\n preventScroll={preventScroll}\n scrollBehavior={scrollBehavior}\n size={size}\n trigger={trigger}\n variant={variant}\n >\n <Dialog.Content maxHeight={maxHeight} {...dataAttributes}>\n <DialogInner\n closable={closable}\n footerContent={footerContent}\n headerExtra={stepsHeader}\n headerLabel={headerLabel}\n scrollBehavior={scrollBehavior}\n showScrollGradient={showScrollGradient}\n title={title}\n variant={variant}\n >\n {steps[step]}\n </DialogInner>\n </Dialog.Content>\n </DialogShell>\n </StepperDialogProvider>\n );\n};\n\nBitkitStepperDialog.displayName = 'BitkitStepperDialog';\n\nexport default withSubComponents(BitkitStepperDialog, {\n ActionTrigger: Dialog.ActionTrigger,\n Step: BitkitStepperDialogStep,\n});\n"],"mappings":";;;;;;;;;;;;;;;;AAqDA,IAAM,uBAAuB,EAC3B,UACA,WAAW,MACX,cAAc,GACd,gBACA,eACA,aACA,WACA,gBACA,cACA,cACA,MACA,eACA,gBACA,oBACA,MACA,MAAM,UACN,OACA,SACA,SACA,GAAG,qBAC2B;CAC9B,MAAM,CAAC,cAAc,mBAAmB,SAAS,WAAW;CAC5D,MAAM,eAAe,aAAa,KAAA;CAClC,MAAM,WAAW,eAAe,WAAW,iBAAiB;CAC5D,MAAM,QAAQ,gBAAgB,QAAQ,CAAC,CAAC,QACrC,UAA+D,MAAM,SAAS,uBACjF;CACA,MAAM,aAAa,MAAM;CACzB,MAAM,OAAO,KAAK,IAAI,GAAG,KAAK,IAAI,SAAS,KAAK,IAAI,GAAG,aAAa,CAAC,CAAC,CAAC;CAEvE,MAAM,UAAU,aACb,SAAiB;EAChB,MAAM,UAAU,KAAK,IAAI,GAAG,KAAK,IAAI,MAAM,aAAa,CAAC,CAAC;EAC1D,IAAI,CAAC,cAAc,gBAAgB,OAAO;EAC1C,eAAe,OAAO;CACxB,GACA;EAAC;EAAc;EAAc;CAAU,CACzC;CAEA,MAAM,MAAM,eACH;EACL,MAAM;EACN,SAAS,SAAS;EAClB,QAAQ,SAAS,aAAa;EAC9B,YAAY,QAAQ,OAAO,CAAC;EAC5B,YAAY,QAAQ,OAAO,CAAC;EAC5B;EACA;EACA;CACF,IACA;EAAC;EAAS;EAAM;CAAU,CAC5B;CAEA,MAAM,oBAAoB,YAA+B;EACvD,IAAI,CAAC,QAAQ,QAAQ,CAAC,cAAc,gBAAgB,WAAW;EAC/D,eAAe,OAAO;CACxB;CAEA,MAAM,cACJ,oBAAC,qBAAD;EAAmB;EAChB,UAAA,MAAM,KAAK,OAAO,UACjB,oBAAC,oBAAY,MAAb,EAA8B,OAAO,MAAM,MAAM,MAAQ,GAAlC,KAAkC,CAC1D;CACU,CAAA;CAGf,OACE,oBAAC,uBAAD;EAAuB,OAAO;EAC5B,UAAA,oBAAC,aAAD;GACY;GACM;GACA;GAChB,cAAc;GACR;GACS;GACC;GACV;GACG;GACA;GAET,UAAA,oBAAC,OAAO,SAAR;IAA2B;IAAW,GAAI;IACxC,UAAA,oBAAC,aAAD;KACY;KACK;KACf,aAAa;KACA;KACG;KACI;KACb;KACE;KAER,UAAA,MAAM;IACI,CAAA;GACC,CAAA;EACL,CAAA;CACQ,CAAA;AAE3B;AAEA,oBAAoB,cAAc;AAElC,IAAA,8BAAe,kBAAkB,qBAAqB;CACpD,eAAe,OAAO;CACtB,MAAM;AACR,CAAC"}
@@ -1,13 +1,5 @@
1
1
  import { Dialog } from '@chakra-ui/react/dialog';
2
2
  import { ComponentProps, ReactNode } from 'react';
3
- /**
4
- * Data attributes every dialog flavour forwards to its content element — the one carrying
5
- * `role="dialog"`. The case this exists for is `data-clarity-unmask`, which opts a region out of
6
- * session replay masking, exactly where support needs to read it.
7
- */
8
- export interface DialogDataAttributes {
9
- [dataAttribute: `data-${string}`]: string | undefined;
10
- }
11
3
  export interface DialogShellProps {
12
4
  /** The `Dialog.Content` element (rendered inside the positioner). */
13
5
  children: ReactNode;
@@ -1 +1 @@
1
- {"version":3,"file":"DialogShell.js","names":[],"sources":["../../../lib/components/BitkitDialog/DialogShell.tsx"],"sourcesContent":["import { Dialog } from '@chakra-ui/react/dialog';\nimport { Portal } from '@chakra-ui/react/portal';\nimport { type ComponentProps, type ReactNode } from 'react';\n\nimport { resolveScrollBehavior } from './DialogBodyContext';\n\n/**\n * Data attributes every dialog flavour forwards to its content element — the one carrying\n * `role=\"dialog\"`. The case this exists for is `data-clarity-unmask`, which opts a region out of\n * session replay masking, exactly where support needs to read it.\n */\nexport interface DialogDataAttributes {\n [dataAttribute: `data-${string}`]: string | undefined;\n}\n\nexport interface DialogShellProps {\n /** The `Dialog.Content` element (rendered inside the positioner). */\n children: ReactNode;\n closable?: boolean;\n /** Element to focus when the dialog opens, instead of the first focusable one. */\n initialFocusEl?: ComponentProps<typeof Dialog.Root>['initialFocusEl'];\n onExitComplete?: () => void;\n onOpenChange?: (details: { open: boolean }) => void;\n open?: boolean;\n preventScroll?: boolean;\n scrollBehavior?: 'inside' | 'outside';\n size?: 'sm' | 'md' | 'lg' | 'full';\n trigger?: ReactNode;\n variant?: 'overflowContent';\n}\n\n/**\n * Shared overlay shell for every Bitkit dialog flavour: `Dialog.Root` + optional trigger + portal +\n * backdrop + positioner. Dismiss policy is derived from `closable` for ESC/close-trigger; outside\n * clicks are always ignored (`closeOnInteractOutside={false}`). Note that `closable` does not reach\n * `ActionTrigger` -- a footer button wired to it closes the dialog either way, so a caller that has\n * to block every route out disables that button itself.\n * The caller passes the `Dialog.Content` (or a `Dialog.Content asChild` wrapper) as children.\n **/\n\nconst DialogShell = ({\n children,\n closable = true,\n initialFocusEl,\n onExitComplete,\n onOpenChange,\n open,\n preventScroll = true,\n scrollBehavior: scrollBehaviorProp,\n size,\n trigger,\n variant,\n}: DialogShellProps) => {\n const scrollBehavior = resolveScrollBehavior(variant, scrollBehaviorProp);\n\n return (\n <Dialog.Root\n closeOnEscape={closable}\n closeOnInteractOutside={false}\n initialFocusEl={initialFocusEl}\n onExitComplete={onExitComplete}\n onOpenChange={onOpenChange}\n open={open}\n preventScroll={preventScroll}\n scrollBehavior={scrollBehavior}\n size={size}\n variant={variant}\n >\n {trigger && <Dialog.Trigger asChild>{trigger}</Dialog.Trigger>}\n <Portal>\n <Dialog.Backdrop />\n <Dialog.Positioner>{children}</Dialog.Positioner>\n </Portal>\n </Dialog.Root>\n );\n};\n\nexport default DialogShell;\n"],"mappings":";;;;;;;;;;;;;AAwCA,IAAM,eAAe,EACnB,UACA,WAAW,MACX,gBACA,gBACA,cACA,MACA,gBAAgB,MAChB,gBAAgB,oBAChB,MACA,SACA,cACsB;CACtB,MAAM,iBAAiB,sBAAsB,SAAS,kBAAkB;CAExE,OACE,qBAAC,OAAO,MAAR;EACE,eAAe;EACf,wBAAwB;EACR;EACA;EACF;EACR;EACS;EACC;EACV;EACG;EAVX,UAAA,CAYG,WAAW,oBAAC,OAAO,SAAR;GAAgB,SAAA;GAAS,UAAA;EAAwB,CAAA,GAC7D,qBAAC,QAAD,EAAA,UAAA,CACE,oBAAC,OAAO,UAAR,CAAkB,CAAA,GAClB,oBAAC,OAAO,YAAR,EAAoB,SAA4B,CAAA,CAC1C,EAAA,CAAA,CACG;;AAEjB"}
1
+ {"version":3,"file":"DialogShell.js","names":[],"sources":["../../../lib/components/BitkitDialog/DialogShell.tsx"],"sourcesContent":["import { Dialog } from '@chakra-ui/react/dialog';\nimport { Portal } from '@chakra-ui/react/portal';\nimport { type ComponentProps, type ReactNode } from 'react';\n\nimport { resolveScrollBehavior } from './DialogBodyContext';\n\nexport interface DialogShellProps {\n /** The `Dialog.Content` element (rendered inside the positioner). */\n children: ReactNode;\n closable?: boolean;\n /** Element to focus when the dialog opens, instead of the first focusable one. */\n initialFocusEl?: ComponentProps<typeof Dialog.Root>['initialFocusEl'];\n onExitComplete?: () => void;\n onOpenChange?: (details: { open: boolean }) => void;\n open?: boolean;\n preventScroll?: boolean;\n scrollBehavior?: 'inside' | 'outside';\n size?: 'sm' | 'md' | 'lg' | 'full';\n trigger?: ReactNode;\n variant?: 'overflowContent';\n}\n\n/**\n * Shared overlay shell for every Bitkit dialog flavour: `Dialog.Root` + optional trigger + portal +\n * backdrop + positioner. Dismiss policy is derived from `closable` for ESC/close-trigger; outside\n * clicks are always ignored (`closeOnInteractOutside={false}`). Note that `closable` does not reach\n * `ActionTrigger` -- a footer button wired to it closes the dialog either way, so a caller that has\n * to block every route out disables that button itself.\n * The caller passes the `Dialog.Content` (or a `Dialog.Content asChild` wrapper) as children.\n **/\n\nconst DialogShell = ({\n children,\n closable = true,\n initialFocusEl,\n onExitComplete,\n onOpenChange,\n open,\n preventScroll = true,\n scrollBehavior: scrollBehaviorProp,\n size,\n trigger,\n variant,\n}: DialogShellProps) => {\n const scrollBehavior = resolveScrollBehavior(variant, scrollBehaviorProp);\n\n return (\n <Dialog.Root\n closeOnEscape={closable}\n closeOnInteractOutside={false}\n initialFocusEl={initialFocusEl}\n onExitComplete={onExitComplete}\n onOpenChange={onOpenChange}\n open={open}\n preventScroll={preventScroll}\n scrollBehavior={scrollBehavior}\n size={size}\n variant={variant}\n >\n {trigger && <Dialog.Trigger asChild>{trigger}</Dialog.Trigger>}\n <Portal>\n <Dialog.Backdrop />\n <Dialog.Positioner>{children}</Dialog.Positioner>\n </Portal>\n </Dialog.Root>\n );\n};\n\nexport default DialogShell;\n"],"mappings":";;;;;;;;;;;;;AA+BA,IAAM,eAAe,EACnB,UACA,WAAW,MACX,gBACA,gBACA,cACA,MACA,gBAAgB,MAChB,gBAAgB,oBAChB,MACA,SACA,cACsB;CACtB,MAAM,iBAAiB,sBAAsB,SAAS,kBAAkB;CAExE,OACE,qBAAC,OAAO,MAAR;EACE,eAAe;EACf,wBAAwB;EACR;EACA;EACF;EACR;EACS;EACC;EACV;EACG;EAVX,UAAA,CAYG,WAAW,oBAAC,OAAO,SAAR;GAAgB,SAAA;GAAS,UAAA;EAAwB,CAAA,GAC7D,qBAAC,QAAD,EAAA,UAAA,CACE,oBAAC,OAAO,UAAR,CAAkB,CAAA,GAClB,oBAAC,OAAO,YAAR,EAAoB,SAA4B,CAAA,CAC1C,EAAA,CAAA,CACG;;AAEjB"}
@@ -1,5 +1,6 @@
1
1
  import { ReactNode } from 'react';
2
2
  import { NotificationVariant } from '../../theme/common/AlertAndToast.common';
3
+ import { BitkitDataAttributes } from '../../utilities/dataAttributes';
3
4
  import { NotificationAction } from '../common/notificationMaps';
4
5
  export type BitkitToastVariant = NotificationVariant;
5
6
  export type BitkitToastProps = {
@@ -15,18 +16,7 @@ export type BitkitToastProps = {
15
16
  timestamp?: string;
16
17
  titleText?: ReactNode;
17
18
  variant: BitkitToastVariant;
18
- } & {
19
- /**
20
- * Data attributes are forwarded to the toast's root element. `createBitkitToast` is a
21
- * function rather than a component, so props can't be spread onto anything directly —
22
- * these travel through the toast store's `meta` and are applied when it renders.
23
- *
24
- * The case this exists for is `data-clarity-unmask`, which opts a region out of session
25
- * replay masking: without it a migrated error toast shows up as blocks in the replay,
26
- * exactly where support needs to read what went wrong.
27
- */
28
- [dataAttribute: `data-${string}`]: string | undefined;
29
- };
19
+ } & BitkitDataAttributes;
30
20
  export declare const toaster: import('@chakra-ui/react').CreateToasterReturn<ReactNode>;
31
21
  declare const createBitkitToast: (props: BitkitToastProps) => string;
32
22
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"BitkitToast.js","names":[],"sources":["../../../lib/components/BitkitToast/BitkitToast.tsx"],"sourcesContent":["import { createToaster } from '@chakra-ui/react/toast';\nimport { type ReactNode } from 'react';\n\nimport { type NotificationVariant } from '../../theme/common/AlertAndToast.common';\nimport { type NotificationAction } from '../common/notificationMaps';\n\nexport type BitkitToastVariant = NotificationVariant;\n\nexport type BitkitToastProps = {\n action?: NotificationAction;\n dismissible?: boolean;\n /**\n * How long the toast stays visible, in milliseconds. Overrides the per-variant\n * default for any variant: 5000ms for `ai`/`info`/`success`/`warning`, `Infinity`\n * for `critical` and `progress`. Pass `Infinity` to make a toast persist.\n */\n duration?: number;\n messageText: ReactNode;\n timestamp?: string;\n titleText?: ReactNode;\n variant: BitkitToastVariant;\n} & {\n /**\n * Data attributes are forwarded to the toast's root element. `createBitkitToast` is a\n * function rather than a component, so props can't be spread onto anything directly —\n * these travel through the toast store's `meta` and are applied when it renders.\n *\n * The case this exists for is `data-clarity-unmask`, which opts a region out of session\n * replay masking: without it a migrated error toast shows up as blocks in the replay,\n * exactly where support needs to read what went wrong.\n */\n [dataAttribute: `data-${string}`]: string | undefined;\n};\n\n// Zag's internal priority table only knows its 5 built-in types and crashes\n// on our custom variants (ai/critical/progress). We replicate Zag's algorithm\n// with our full variant set and compute priority ourselves, so the broken\n// lookup is never reached. Each tuple is [actionable, nonActionable] — mirrors\n// Zag, which ranks actionable toasts higher. Lower number = higher in the stack.\nconst TOAST_PRIORITIES = {\n critical: [1, 2], // ~ Zag \"error\" — most urgent\n warning: [3, 6], // = Zag \"warning\"\n progress: [4, 5], // ~ Zag \"loading\"\n success: [5, 7], // = Zag \"success\"\n ai: [6, 8], // ~ Zag \"info\"\n info: [6, 8], // = Zag \"info\" — least urgent\n} as const satisfies Record<BitkitToastVariant, readonly [number, number]>;\n\n// Same name-collision problem as the priorities above: Zag keys its timeout table\n// by its own type names, so only info/warning/success happen to match ours and the\n// rest silently fall back to its 5000ms DEFAULT. We own the full table instead.\n// `critical` and `progress` persist until dismissed — an error the user must see,\n// and an operation that is still running, should not disappear on a timer.\nconst TOAST_DURATIONS = {\n ai: 5000,\n critical: Infinity,\n info: 5000,\n progress: Infinity,\n success: 5000,\n warning: 5000,\n} as const satisfies Record<BitkitToastVariant, number>;\n\nexport const toaster = createToaster({\n max: 5,\n placement: 'top-end',\n pauseOnPageIdle: true,\n});\n\nconst createBitkitToast = (props: BitkitToastProps) => {\n const { action, dismissible = true, duration, messageText, timestamp, titleText, variant, ...dataAttributes } = props;\n\n const [actionable, nonActionable] = TOAST_PRIORITIES[variant];\n\n return toaster.create({\n closable: dismissible,\n description: messageText,\n duration: duration ?? TOAST_DURATIONS[variant],\n meta: { action, dataAttributes, timestamp },\n priority: action ? actionable : nonActionable,\n title: titleText,\n type: variant,\n });\n};\n\n/**\n * Closes the toast with the given id — the one `createBitkitToast` returns — or every\n * visible toast when called without an id — note that an `undefined` id counts as \"no id\",\n * so guard ids that may not be set yet. Use it to close `duration: Infinity` toasts\n * (`critical`, `progress`) from code once the operation they report on ends, and to clean\n * up toasts between tests. The node is unmounted 200ms after the call — Zag's fixed\n * `removeDelay`, which cuts the exit transition short rather than waiting it out — so in\n * tests, assert its absence with `waitFor` or advance the timers.\n */\nexport const dismissBitkitToast = (id?: string) => toaster.dismiss(id);\n\nexport default createBitkitToast;\n"],"mappings":";;AAuCA,IAAM,mBAAmB;CACvB,UAAU,CAAC,GAAG,CAAC;CACf,SAAS,CAAC,GAAG,CAAC;CACd,UAAU,CAAC,GAAG,CAAC;CACf,SAAS,CAAC,GAAG,CAAC;CACd,IAAI,CAAC,GAAG,CAAC;CACT,MAAM,CAAC,GAAG,CAAC;AACb;AAOA,IAAM,kBAAkB;CACtB,IAAI;CACJ,UAAU;CACV,MAAM;CACN,UAAU;CACV,SAAS;CACT,SAAS;AACX;AAEA,IAAa,UAAU,cAAc;CACnC,KAAK;CACL,WAAW;CACX,iBAAiB;AACnB,CAAC;AAED,IAAM,qBAAqB,UAA4B;CACrD,MAAM,EAAE,QAAQ,cAAc,MAAM,UAAU,aAAa,WAAW,WAAW,SAAS,GAAG,mBAAmB;CAEhH,MAAM,CAAC,YAAY,iBAAiB,iBAAiB;CAErD,OAAO,QAAQ,OAAO;EACpB,UAAU;EACV,aAAa;EACb,UAAU,YAAY,gBAAgB;EACtC,MAAM;GAAE;GAAQ;GAAgB;EAAU;EAC1C,UAAU,SAAS,aAAa;EAChC,OAAO;EACP,MAAM;CACR,CAAC;AACH;;;;;;;;;;AAWA,IAAa,sBAAsB,OAAgB,QAAQ,QAAQ,EAAE"}
1
+ {"version":3,"file":"BitkitToast.js","names":[],"sources":["../../../lib/components/BitkitToast/BitkitToast.tsx"],"sourcesContent":["import { createToaster } from '@chakra-ui/react/toast';\nimport { type ReactNode } from 'react';\n\nimport { type NotificationVariant } from '../../theme/common/AlertAndToast.common';\nimport { type BitkitDataAttributes } from '../../utilities/dataAttributes';\nimport { type NotificationAction } from '../common/notificationMaps';\n\nexport type BitkitToastVariant = NotificationVariant;\n\nexport type BitkitToastProps = {\n action?: NotificationAction;\n dismissible?: boolean;\n /**\n * How long the toast stays visible, in milliseconds. Overrides the per-variant\n * default for any variant: 5000ms for `ai`/`info`/`success`/`warning`, `Infinity`\n * for `critical` and `progress`. Pass `Infinity` to make a toast persist.\n */\n duration?: number;\n messageText: ReactNode;\n timestamp?: string;\n titleText?: ReactNode;\n variant: BitkitToastVariant;\n // Data attributes are forwarded to the toast's root element. `createBitkitToast` is a function\n // rather than a component, so props can't be spread onto anything directly — these travel\n // through the toast store's `meta` and are applied when it renders. The case it exists for is\n // `data-clarity-unmask`: without it a migrated error toast shows up as blocks in session replay,\n // exactly where support needs to read what went wrong.\n} & BitkitDataAttributes;\n\n// Zag's internal priority table only knows its 5 built-in types and crashes\n// on our custom variants (ai/critical/progress). We replicate Zag's algorithm\n// with our full variant set and compute priority ourselves, so the broken\n// lookup is never reached. Each tuple is [actionable, nonActionable] — mirrors\n// Zag, which ranks actionable toasts higher. Lower number = higher in the stack.\nconst TOAST_PRIORITIES = {\n critical: [1, 2], // ~ Zag \"error\" — most urgent\n warning: [3, 6], // = Zag \"warning\"\n progress: [4, 5], // ~ Zag \"loading\"\n success: [5, 7], // = Zag \"success\"\n ai: [6, 8], // ~ Zag \"info\"\n info: [6, 8], // = Zag \"info\" — least urgent\n} as const satisfies Record<BitkitToastVariant, readonly [number, number]>;\n\n// Same name-collision problem as the priorities above: Zag keys its timeout table\n// by its own type names, so only info/warning/success happen to match ours and the\n// rest silently fall back to its 5000ms DEFAULT. We own the full table instead.\n// `critical` and `progress` persist until dismissed — an error the user must see,\n// and an operation that is still running, should not disappear on a timer.\nconst TOAST_DURATIONS = {\n ai: 5000,\n critical: Infinity,\n info: 5000,\n progress: Infinity,\n success: 5000,\n warning: 5000,\n} as const satisfies Record<BitkitToastVariant, number>;\n\nexport const toaster = createToaster({\n max: 5,\n placement: 'top-end',\n pauseOnPageIdle: true,\n});\n\nconst createBitkitToast = (props: BitkitToastProps) => {\n const { action, dismissible = true, duration, messageText, timestamp, titleText, variant, ...dataAttributes } = props;\n\n const [actionable, nonActionable] = TOAST_PRIORITIES[variant];\n\n return toaster.create({\n closable: dismissible,\n description: messageText,\n duration: duration ?? TOAST_DURATIONS[variant],\n meta: { action, dataAttributes, timestamp },\n priority: action ? actionable : nonActionable,\n title: titleText,\n type: variant,\n });\n};\n\n/**\n * Closes the toast with the given id — the one `createBitkitToast` returns — or every\n * visible toast when called without an id — note that an `undefined` id counts as \"no id\",\n * so guard ids that may not be set yet. Use it to close `duration: Infinity` toasts\n * (`critical`, `progress`) from code once the operation they report on ends, and to clean\n * up toasts between tests. The node is unmounted 200ms after the call — Zag's fixed\n * `removeDelay`, which cuts the exit transition short rather than waiting it out — so in\n * tests, assert its absence with `waitFor` or advance the timers.\n */\nexport const dismissBitkitToast = (id?: string) => toaster.dismiss(id);\n\nexport default createBitkitToast;\n"],"mappings":";;AAkCA,IAAM,mBAAmB;CACvB,UAAU,CAAC,GAAG,CAAC;CACf,SAAS,CAAC,GAAG,CAAC;CACd,UAAU,CAAC,GAAG,CAAC;CACf,SAAS,CAAC,GAAG,CAAC;CACd,IAAI,CAAC,GAAG,CAAC;CACT,MAAM,CAAC,GAAG,CAAC;AACb;AAOA,IAAM,kBAAkB;CACtB,IAAI;CACJ,UAAU;CACV,MAAM;CACN,UAAU;CACV,SAAS;CACT,SAAS;AACX;AAEA,IAAa,UAAU,cAAc;CACnC,KAAK;CACL,WAAW;CACX,iBAAiB;AACnB,CAAC;AAED,IAAM,qBAAqB,UAA4B;CACrD,MAAM,EAAE,QAAQ,cAAc,MAAM,UAAU,aAAa,WAAW,WAAW,SAAS,GAAG,mBAAmB;CAEhH,MAAM,CAAC,YAAY,iBAAiB,iBAAiB;CAErD,OAAO,QAAQ,OAAO;EACpB,UAAU;EACV,aAAa;EACb,UAAU,YAAY,gBAAgB;EACtC,MAAM;GAAE;GAAQ;GAAgB;EAAU;EAC1C,UAAU,SAAS,aAAa;EAChC,OAAO;EACP,MAAM;CACR,CAAC;AACH;;;;;;;;;;AAWA,IAAa,sBAAsB,OAAgB,QAAQ,QAAQ,EAAE"}
@@ -46,6 +46,8 @@ var menuSlotRecipe = defineSlotRecipe({
46
46
  boxShadow: "elevation/lg",
47
47
  background: "background/primary",
48
48
  maxHeight: "var(--available-height)",
49
+ overflow: "hidden",
50
+ overflowY: "auto",
49
51
  _open: {
50
52
  animationStyle: "slide-fade-in",
51
53
  animationDuration: "fast"
@@ -91,6 +93,7 @@ var menuSlotRecipe = defineSlotRecipe({
91
93
  "& [data-suffix-icon]": { color: "icon/tertiary" }
92
94
  },
93
95
  itemGroupLabel: {
96
+ "& .separator": { borderColor: "border/minimal" },
94
97
  textStyle: "heading/h6",
95
98
  color: "text/tertiary",
96
99
  paddingTop: "12",
@@ -1 +1 @@
1
- {"version":3,"file":"Menu.recipe.js","names":[],"sources":["../../../lib/theme/slot-recipes/Menu.recipe.ts"],"sourcesContent":["import { menuAnatomy } from '@chakra-ui/react/anatomy';\nimport { defineSlotRecipe, type SystemStyleObject } from '@chakra-ui/react/styled-system';\n\nconst itemActive: SystemStyleObject = {\n background: 'button/secondary/bg-active',\n _icon: {\n color: 'icon/primary',\n },\n};\nconst itemActiveDanger: SystemStyleObject = {\n background: 'button/danger-secondary/bg-active',\n color: 'button/danger-secondary/fg-active',\n _icon: {\n color: 'button/danger-secondary/fg-active',\n },\n};\nconst menuSlotRecipe = defineSlotRecipe({\n className: 'menu',\n slots: [...menuAnatomy.keys(), 'itemHelper'],\n variants: {\n size: {\n lg: {\n item: {\n alignItems: 'center',\n paddingY: '12',\n textStyle: 'body/lg/regular',\n // With a helper line the item aligns to the top of the label and gets tighter padding.\n '&[data-helper]': {\n alignItems: 'flex-start',\n paddingY: '8',\n },\n },\n },\n md: {\n item: {\n alignItems: 'center',\n // The label line (20px) alone is shorter than the designed 40px row.\n minHeight: '40',\n paddingY: '8',\n textStyle: 'body/md/regular',\n '&[data-helper]': {\n _icon: {\n // Optically center the 16px icon against the 20px label line.\n marginTop: '2',\n },\n alignItems: 'flex-start',\n paddingY: '6',\n },\n },\n },\n },\n },\n base: {\n content: {\n // Sit above the legacy v1 full-dialog/drawer layer (zIndex.fullDialog = 1200); the menu\n // portals out, so without this it renders behind a v1 FloatingDrawer. Matches the content-slot\n // z-index convention of the other floating recipes (Popover, Tooltip, Combobox/Select).\n zIndex: 'popover',\n borderRadius: '4',\n paddingY: '8',\n border: '1px solid',\n borderColor: 'border/minimal',\n _focusVisible: { outline: 'none' },\n boxShadow: 'elevation/lg',\n background: 'background/primary',\n maxHeight: 'var(--available-height)',\n _open: {\n animationStyle: 'slide-fade-in',\n animationDuration: 'fast',\n },\n _closed: {\n animationStyle: 'slide-fade-out',\n animationDuration: 'faster',\n },\n },\n itemHelper: {\n textStyle: 'body/sm/regular',\n color: 'text/secondary',\n },\n item: {\n _icon: {\n color: 'icon/secondary',\n _active: {\n color: 'icon/primary',\n },\n },\n cursor: 'pointer',\n display: 'flex',\n gap: '12',\n userSelect: 'none',\n flexDirection: 'row',\n paddingLeft: '16',\n paddingRight: '24',\n _disabled: {\n cursor: 'not-allowed',\n },\n '&[data-danger]': {\n color: 'button/danger-secondary/fg',\n _icon: {\n color: 'button/danger-secondary/fg',\n },\n _active: itemActiveDanger,\n _highlighted: {\n background: 'button/danger-secondary/bg-hover',\n color: 'button/danger-secondary/fg-hover',\n _active: itemActiveDanger,\n _icon: {\n color: 'button/danger-secondary/fg-hover',\n },\n },\n },\n _active: itemActive,\n _highlighted: {\n background: 'button/secondary/bg-hover',\n _active: itemActive,\n },\n // The \"leaves this page\" arrow is quieter than the leading icon, and stays that way in every\n // state — including the destructive one, which overrides `_icon` above.\n '& [data-suffix-icon]': {\n color: 'icon/tertiary',\n },\n },\n itemGroupLabel: {\n textStyle: 'heading/h6',\n color: 'text/tertiary',\n paddingTop: '12',\n paddingLeft: '16',\n paddingRight: '16',\n paddingBottom: '6',\n display: 'flex',\n gap: '8',\n flexDirection: 'row',\n alignItems: 'center',\n },\n separator: {\n color: 'border/minimal',\n marginY: '8',\n },\n },\n defaultVariants: {\n size: 'lg',\n },\n});\n\nexport default menuSlotRecipe;\n"],"mappings":";;;AAGA,IAAM,aAAgC;CACpC,YAAY;CACZ,OAAO,EACL,OAAO,eACT;AACF;AACA,IAAM,mBAAsC;CAC1C,YAAY;CACZ,OAAO;CACP,OAAO,EACL,OAAO,oCACT;AACF;AACA,IAAM,iBAAiB,iBAAiB;CACtC,WAAW;CACX,OAAO,CAAC,GAAG,YAAY,KAAK,GAAG,YAAY;CAC3C,UAAU,EACR,MAAM;EACJ,IAAI,EACF,MAAM;GACJ,YAAY;GACZ,UAAU;GACV,WAAW;GAEX,kBAAkB;IAChB,YAAY;IACZ,UAAU;GACZ;EACF,EACF;EACA,IAAI,EACF,MAAM;GACJ,YAAY;GAEZ,WAAW;GACX,UAAU;GACV,WAAW;GACX,kBAAkB;IAChB,OAAO,EAEL,WAAW,IACb;IACA,YAAY;IACZ,UAAU;GACZ;EACF,EACF;CACF,EACF;CACA,MAAM;EACJ,SAAS;GAIP,QAAQ;GACR,cAAc;GACd,UAAU;GACV,QAAQ;GACR,aAAa;GACb,eAAe,EAAE,SAAS,OAAO;GACjC,WAAW;GACX,YAAY;GACZ,WAAW;GACX,OAAO;IACL,gBAAgB;IAChB,mBAAmB;GACrB;GACA,SAAS;IACP,gBAAgB;IAChB,mBAAmB;GACrB;EACF;EACA,YAAY;GACV,WAAW;GACX,OAAO;EACT;EACA,MAAM;GACJ,OAAO;IACL,OAAO;IACP,SAAS,EACP,OAAO,eACT;GACF;GACA,QAAQ;GACR,SAAS;GACT,KAAK;GACL,YAAY;GACZ,eAAe;GACf,aAAa;GACb,cAAc;GACd,WAAW,EACT,QAAQ,cACV;GACA,kBAAkB;IAChB,OAAO;IACP,OAAO,EACL,OAAO,6BACT;IACA,SAAS;IACT,cAAc;KACZ,YAAY;KACZ,OAAO;KACP,SAAS;KACT,OAAO,EACL,OAAO,mCACT;IACF;GACF;GACA,SAAS;GACT,cAAc;IACZ,YAAY;IACZ,SAAS;GACX;GAGA,wBAAwB,EACtB,OAAO,gBACT;EACF;EACA,gBAAgB;GACd,WAAW;GACX,OAAO;GACP,YAAY;GACZ,aAAa;GACb,cAAc;GACd,eAAe;GACf,SAAS;GACT,KAAK;GACL,eAAe;GACf,YAAY;EACd;EACA,WAAW;GACT,OAAO;GACP,SAAS;EACX;CACF;CACA,iBAAiB,EACf,MAAM,KACR;AACF,CAAC"}
1
+ {"version":3,"file":"Menu.recipe.js","names":[],"sources":["../../../lib/theme/slot-recipes/Menu.recipe.ts"],"sourcesContent":["import { menuAnatomy } from '@chakra-ui/react/anatomy';\nimport { defineSlotRecipe, type SystemStyleObject } from '@chakra-ui/react/styled-system';\n\nconst itemActive: SystemStyleObject = {\n background: 'button/secondary/bg-active',\n _icon: {\n color: 'icon/primary',\n },\n};\nconst itemActiveDanger: SystemStyleObject = {\n background: 'button/danger-secondary/bg-active',\n color: 'button/danger-secondary/fg-active',\n _icon: {\n color: 'button/danger-secondary/fg-active',\n },\n};\nconst menuSlotRecipe = defineSlotRecipe({\n className: 'menu',\n slots: [...menuAnatomy.keys(), 'itemHelper'],\n variants: {\n size: {\n lg: {\n item: {\n alignItems: 'center',\n paddingY: '12',\n textStyle: 'body/lg/regular',\n // With a helper line the item aligns to the top of the label and gets tighter padding.\n '&[data-helper]': {\n alignItems: 'flex-start',\n paddingY: '8',\n },\n },\n },\n md: {\n item: {\n alignItems: 'center',\n // The label line (20px) alone is shorter than the designed 40px row.\n minHeight: '40',\n paddingY: '8',\n textStyle: 'body/md/regular',\n '&[data-helper]': {\n _icon: {\n // Optically center the 16px icon against the 20px label line.\n marginTop: '2',\n },\n alignItems: 'flex-start',\n paddingY: '6',\n },\n },\n },\n },\n },\n base: {\n content: {\n // Sit above the legacy v1 full-dialog/drawer layer (zIndex.fullDialog = 1200); the menu\n // portals out, so without this it renders behind a v1 FloatingDrawer. Matches the content-slot\n // z-index convention of the other floating recipes (Popover, Tooltip, Combobox/Select).\n zIndex: 'popover',\n borderRadius: '4',\n paddingY: '8',\n border: '1px solid',\n borderColor: 'border/minimal',\n _focusVisible: { outline: 'none' },\n boxShadow: 'elevation/lg',\n background: 'background/primary',\n maxHeight: 'var(--available-height)',\n // The cap is useless without these: the positioner sets --available-height from the viewport,\n // and a longer list then spills out of the content box instead of scrolling inside it.\n overflow: 'hidden',\n overflowY: 'auto',\n _open: {\n animationStyle: 'slide-fade-in',\n animationDuration: 'fast',\n },\n _closed: {\n animationStyle: 'slide-fade-out',\n animationDuration: 'faster',\n },\n },\n itemHelper: {\n textStyle: 'body/sm/regular',\n color: 'text/secondary',\n },\n item: {\n _icon: {\n color: 'icon/secondary',\n _active: {\n color: 'icon/primary',\n },\n },\n cursor: 'pointer',\n display: 'flex',\n gap: '12',\n userSelect: 'none',\n flexDirection: 'row',\n paddingLeft: '16',\n paddingRight: '24',\n _disabled: {\n cursor: 'not-allowed',\n },\n '&[data-danger]': {\n color: 'button/danger-secondary/fg',\n _icon: {\n color: 'button/danger-secondary/fg',\n },\n _active: itemActiveDanger,\n _highlighted: {\n background: 'button/danger-secondary/bg-hover',\n color: 'button/danger-secondary/fg-hover',\n _active: itemActiveDanger,\n _icon: {\n color: 'button/danger-secondary/fg-hover',\n },\n },\n },\n _active: itemActive,\n _highlighted: {\n background: 'button/secondary/bg-hover',\n _active: itemActive,\n },\n // The \"leaves this page\" arrow is quieter than the leading icon, and stays that way in every\n // state — including the destructive one, which overrides `_icon` above.\n '& [data-suffix-icon]': {\n color: 'icon/tertiary',\n },\n },\n itemGroupLabel: {\n // The rule after the label is a Chakra Separator, whose recipe base is `border/regular` — a\n // shade darker than the menu's own separator. Match `BitkitActionMenu.Separator`.\n '& .separator': {\n borderColor: 'border/minimal',\n },\n textStyle: 'heading/h6',\n color: 'text/tertiary',\n paddingTop: '12',\n paddingLeft: '16',\n paddingRight: '16',\n paddingBottom: '6',\n display: 'flex',\n gap: '8',\n flexDirection: 'row',\n alignItems: 'center',\n },\n separator: {\n color: 'border/minimal',\n marginY: '8',\n },\n },\n defaultVariants: {\n size: 'lg',\n },\n});\n\nexport default menuSlotRecipe;\n"],"mappings":";;;AAGA,IAAM,aAAgC;CACpC,YAAY;CACZ,OAAO,EACL,OAAO,eACT;AACF;AACA,IAAM,mBAAsC;CAC1C,YAAY;CACZ,OAAO;CACP,OAAO,EACL,OAAO,oCACT;AACF;AACA,IAAM,iBAAiB,iBAAiB;CACtC,WAAW;CACX,OAAO,CAAC,GAAG,YAAY,KAAK,GAAG,YAAY;CAC3C,UAAU,EACR,MAAM;EACJ,IAAI,EACF,MAAM;GACJ,YAAY;GACZ,UAAU;GACV,WAAW;GAEX,kBAAkB;IAChB,YAAY;IACZ,UAAU;GACZ;EACF,EACF;EACA,IAAI,EACF,MAAM;GACJ,YAAY;GAEZ,WAAW;GACX,UAAU;GACV,WAAW;GACX,kBAAkB;IAChB,OAAO,EAEL,WAAW,IACb;IACA,YAAY;IACZ,UAAU;GACZ;EACF,EACF;CACF,EACF;CACA,MAAM;EACJ,SAAS;GAIP,QAAQ;GACR,cAAc;GACd,UAAU;GACV,QAAQ;GACR,aAAa;GACb,eAAe,EAAE,SAAS,OAAO;GACjC,WAAW;GACX,YAAY;GACZ,WAAW;GAGX,UAAU;GACV,WAAW;GACX,OAAO;IACL,gBAAgB;IAChB,mBAAmB;GACrB;GACA,SAAS;IACP,gBAAgB;IAChB,mBAAmB;GACrB;EACF;EACA,YAAY;GACV,WAAW;GACX,OAAO;EACT;EACA,MAAM;GACJ,OAAO;IACL,OAAO;IACP,SAAS,EACP,OAAO,eACT;GACF;GACA,QAAQ;GACR,SAAS;GACT,KAAK;GACL,YAAY;GACZ,eAAe;GACf,aAAa;GACb,cAAc;GACd,WAAW,EACT,QAAQ,cACV;GACA,kBAAkB;IAChB,OAAO;IACP,OAAO,EACL,OAAO,6BACT;IACA,SAAS;IACT,cAAc;KACZ,YAAY;KACZ,OAAO;KACP,SAAS;KACT,OAAO,EACL,OAAO,mCACT;IACF;GACF;GACA,SAAS;GACT,cAAc;IACZ,YAAY;IACZ,SAAS;GACX;GAGA,wBAAwB,EACtB,OAAO,gBACT;EACF;EACA,gBAAgB;GAGd,gBAAgB,EACd,aAAa,iBACf;GACA,WAAW;GACX,OAAO;GACP,YAAY;GACZ,aAAa;GACb,cAAc;GACd,eAAe;GACf,SAAS;GACT,KAAK;GACL,eAAe;GACf,YAAY;EACd;EACA,WAAW;GACT,OAAO;GACP,SAAS;EACX;CACF;CACA,iBAAiB,EACf,MAAM,KACR;AACF,CAAC"}
@@ -39,7 +39,7 @@ var tourSlotRecipe = defineSlotRecipe({
39
39
  display: "flex",
40
40
  flexDirection: "column",
41
41
  gap: "8",
42
- maxHeight: "var(--available-height, 100dvh)",
42
+ maxHeight: "max(var(--available-height, 100dvh), 18rem)",
43
43
  maxWidth: "100%",
44
44
  outline: "none",
45
45
  padding: "16",
@@ -1 +1 @@
1
- {"version":3,"file":"Tour.recipe.js","names":[],"sources":["../../../lib/theme/slot-recipes/Tour.recipe.ts"],"sourcesContent":["// The Tour parts come from Ark UI, so the anatomy comes from there too — Chakra has no `tour`\n// counterpart yet (chakra-ui/chakra-ui#10410 is still open).\nimport { tourAnatomy } from '@ark-ui/react/anatomy';\nimport { defineSlotRecipe } from '@chakra-ui/react/styled-system';\n\nimport { rem } from '../themeUtils';\n\nconst tourSlotRecipe = defineSlotRecipe({\n className: 'tour',\n slots: [...tourAnatomy.keys(), 'actions', 'badge', 'header', 'media', 'titleGroup', 'titleRow'] as const,\n base: {\n backdrop: {\n background: 'utilities/overlay',\n zIndex: 'dialogOverlay',\n _open: {\n animationStyle: 'fade-in',\n animationDuration: 'moderate',\n },\n // No exit animation: Ark sets `hidden` on the backdrop and the content the moment the tour\n // closes, so the node is `display: none` in the same frame and an exit animation can never\n // paint — it only leaves the animation assigned, which flashes the card back in for a frame\n // on the next render. Most visible on steps without a backdrop, where nothing masks it.\n },\n // Sits on the same layer as the backdrop and after it in DOM order, so the ring around the\n // highlighted element paints over the dimmed page.\n spotlight: {\n borderRadius: '4',\n outline: '2px solid',\n outlineColor: 'interactive/highlight',\n zIndex: 'dialogOverlay',\n },\n // Zag positions and layers this one inline, writing\n // `z-index: calc(var(--tour-layer) + var(--tour-z-index))` and expecting us to supply the base.\n // Without it the calc is invalid, the positioner falls back to `auto` — and since it opens its\n // own stacking context (`isolation: isolate`), the card's own z-index can't reach past it, so\n // the whole card ends up under the backdrop and swallows every click. The plain `zIndex` is the\n // fallback for the day Zag stops writing that inline.\n positioner: {\n '--tour-z-index': 'zIndex.dialog',\n zIndex: 'dialog',\n },\n content: {\n background: 'background/primary',\n borderRadius: '8',\n boxShadow: 'elevation/lg',\n display: 'flex',\n flexDirection: 'column',\n gap: '8',\n maxHeight: 'var(--available-height, 100dvh)',\n maxWidth: '100%',\n outline: 'none',\n padding: '16',\n position: 'relative',\n width: rem(360),\n zIndex: 'dialog',\n // Fade only, no scale: Zag puts `--transform-origin` at the arrow tip, so a `scale-in` grows\n // the card away from the highlight — a 360x300 card gains ~15 of height on the way in, which\n // reads as the card repositioning itself rather than appearing.\n _open: {\n animationStyle: 'fade-in',\n animationDuration: 'moderate',\n },\n },\n header: {\n alignItems: 'flex-start',\n display: 'flex',\n gap: '16',\n justifyContent: 'space-between',\n },\n titleGroup: {\n display: 'flex',\n flexDirection: 'column',\n gap: '8',\n },\n // flex-start, not center: the badge is as tall as one line of the title, so it lines up with\n // the first line instead of floating beside the middle of a title that wrapped.\n titleRow: {\n alignItems: 'flex-start',\n display: 'flex',\n gap: '8',\n },\n badge: {\n flexShrink: 0,\n },\n title: {\n color: 'text/primary',\n textStyle: 'heading/h4',\n },\n progressText: {\n color: 'text/secondary',\n textStyle: 'body/sm/regular',\n },\n description: {\n color: 'text/body',\n minHeight: 0,\n overflowY: 'auto',\n textStyle: 'body/md/regular',\n },\n // These two margins stack on the content's own 8 gap, which is how the layout spec builds the\n // spacing: 16 between the description and the visual, and 24 above the footer. The footer gets\n // nothing below it, so the card's own 16 padding is the whole gap under the buttons.\n media: {\n marginBlockStart: '8',\n },\n control: {\n alignItems: 'center',\n display: 'flex',\n gap: '16',\n justifyContent: 'space-between',\n marginBlockStart: '16',\n },\n actions: {\n display: 'flex',\n gap: '8',\n marginInlineStart: 'auto',\n },\n closeTrigger: {\n flexShrink: 0,\n },\n arrow: {\n // Popper draws the arrow as a square rotated 45°, so the visible triangle is `size * √2`\n // wide and `size / √2` tall — 11.3 gives the design's 16×8.\n '--arrow-size': rem(11.3),\n '--arrow-background': 'colors.background/primary',\n // Size and out-of-flow positioning are set here, not only by Popper's inline styles, because\n // the component keeps this element out of Zag's `hidden` (see BitkitTour): Popper derives the\n // card's distance from the anchor as `offset.mainAxis + arrowEl.clientHeight / 2`, read off\n // the DOM. A `display: none` arrow measures 0, which puts the card 6 short of the design's 12\n // on the first pass. `absolute` keeps it from adding its height to the card while it waits\n // for Popper's own inline placement.\n height: 'var(--arrow-size)',\n position: 'absolute',\n width: 'var(--arrow-size)',\n },\n arrowTip: {\n borderColor: 'border/minimal',\n borderInlineStartWidth: '1',\n borderTopWidth: '1',\n },\n },\n});\n\nexport default tourSlotRecipe;\n"],"mappings":";;;;AAOA,IAAM,iBAAiB,iBAAiB;CACtC,WAAW;CACX,OAAO;EAAC,GAAG,YAAY,KAAK;EAAG;EAAW;EAAS;EAAU;EAAS;EAAc;CAAU;CAC9F,MAAM;EACJ,UAAU;GACR,YAAY;GACZ,QAAQ;GACR,OAAO;IACL,gBAAgB;IAChB,mBAAmB;GACrB;EAKF;EAGA,WAAW;GACT,cAAc;GACd,SAAS;GACT,cAAc;GACd,QAAQ;EACV;EAOA,YAAY;GACV,kBAAkB;GAClB,QAAQ;EACV;EACA,SAAS;GACP,YAAY;GACZ,cAAc;GACd,WAAW;GACX,SAAS;GACT,eAAe;GACf,KAAK;GACL,WAAW;GACX,UAAU;GACV,SAAS;GACT,SAAS;GACT,UAAU;GACV,OAAO,IAAI,GAAG;GACd,QAAQ;GAIR,OAAO;IACL,gBAAgB;IAChB,mBAAmB;GACrB;EACF;EACA,QAAQ;GACN,YAAY;GACZ,SAAS;GACT,KAAK;GACL,gBAAgB;EAClB;EACA,YAAY;GACV,SAAS;GACT,eAAe;GACf,KAAK;EACP;EAGA,UAAU;GACR,YAAY;GACZ,SAAS;GACT,KAAK;EACP;EACA,OAAO,EACL,YAAY,EACd;EACA,OAAO;GACL,OAAO;GACP,WAAW;EACb;EACA,cAAc;GACZ,OAAO;GACP,WAAW;EACb;EACA,aAAa;GACX,OAAO;GACP,WAAW;GACX,WAAW;GACX,WAAW;EACb;EAIA,OAAO,EACL,kBAAkB,IACpB;EACA,SAAS;GACP,YAAY;GACZ,SAAS;GACT,KAAK;GACL,gBAAgB;GAChB,kBAAkB;EACpB;EACA,SAAS;GACP,SAAS;GACT,KAAK;GACL,mBAAmB;EACrB;EACA,cAAc,EACZ,YAAY,EACd;EACA,OAAO;GAGL,gBAAgB,IAAI,IAAI;GACxB,sBAAsB;GAOtB,QAAQ;GACR,UAAU;GACV,OAAO;EACT;EACA,UAAU;GACR,aAAa;GACb,wBAAwB;GACxB,gBAAgB;EAClB;CACF;AACF,CAAC"}
1
+ {"version":3,"file":"Tour.recipe.js","names":[],"sources":["../../../lib/theme/slot-recipes/Tour.recipe.ts"],"sourcesContent":["// The Tour parts come from Ark UI, so the anatomy comes from there too — Chakra has no `tour`\n// counterpart yet (chakra-ui/chakra-ui#10410 is still open).\nimport { tourAnatomy } from '@ark-ui/react/anatomy';\nimport { defineSlotRecipe } from '@chakra-ui/react/styled-system';\n\nimport { rem } from '../themeUtils';\n\nconst tourSlotRecipe = defineSlotRecipe({\n className: 'tour',\n slots: [...tourAnatomy.keys(), 'actions', 'badge', 'header', 'media', 'titleGroup', 'titleRow'] as const,\n base: {\n backdrop: {\n background: 'utilities/overlay',\n zIndex: 'dialogOverlay',\n _open: {\n animationStyle: 'fade-in',\n animationDuration: 'moderate',\n },\n // No exit animation: Ark sets `hidden` on the backdrop and the content the moment the tour\n // closes, so the node is `display: none` in the same frame and an exit animation can never\n // paint — it only leaves the animation assigned, which flashes the card back in for a frame\n // on the next render. Most visible on steps without a backdrop, where nothing masks it.\n },\n // Sits on the same layer as the backdrop and after it in DOM order, so the ring around the\n // highlighted element paints over the dimmed page.\n spotlight: {\n borderRadius: '4',\n outline: '2px solid',\n outlineColor: 'interactive/highlight',\n zIndex: 'dialogOverlay',\n },\n // Zag positions and layers this one inline, writing\n // `z-index: calc(var(--tour-layer) + var(--tour-z-index))` and expecting us to supply the base.\n // Without it the calc is invalid, the positioner falls back to `auto` — and since it opens its\n // own stacking context (`isolation: isolate`), the card's own z-index can't reach past it, so\n // the whole card ends up under the backdrop and swallows every click. The plain `zIndex` is the\n // fallback for the day Zag stops writing that inline.\n positioner: {\n '--tour-z-index': 'zIndex.dialog',\n zIndex: 'dialog',\n },\n content: {\n background: 'background/primary',\n borderRadius: '8',\n boxShadow: 'elevation/lg',\n display: 'flex',\n flexDirection: 'column',\n gap: '8',\n // Floored, and the floor is what keeps the card from talking Popper out of flipping. Zag's\n // `size` middleware runs after `flip` and writes `--available-height` from the space on the\n // chosen side; the card is the same node from step to step, so it carries that cap into the\n // next step's first measurement. A step that needs 328 measured 193 — the cap left by a\n // shorter step — decided it fitted below, and never flipped to the side that had 474 free.\n // Below this floor the card stops shrinking, so it overflows instead, which is what `flip`\n // reads to move it.\n maxHeight: 'max(var(--available-height, 100dvh), 18rem)',\n maxWidth: '100%',\n outline: 'none',\n padding: '16',\n position: 'relative',\n width: rem(360),\n zIndex: 'dialog',\n // Fade only, no scale: Zag puts `--transform-origin` at the arrow tip, so a `scale-in` grows\n // the card away from the highlight — a 360x300 card gains ~15 of height on the way in, which\n // reads as the card repositioning itself rather than appearing.\n _open: {\n animationStyle: 'fade-in',\n animationDuration: 'moderate',\n },\n },\n header: {\n alignItems: 'flex-start',\n display: 'flex',\n gap: '16',\n justifyContent: 'space-between',\n },\n titleGroup: {\n display: 'flex',\n flexDirection: 'column',\n gap: '8',\n },\n // flex-start, not center: the badge is as tall as one line of the title, so it lines up with\n // the first line instead of floating beside the middle of a title that wrapped.\n titleRow: {\n alignItems: 'flex-start',\n display: 'flex',\n gap: '8',\n },\n badge: {\n flexShrink: 0,\n },\n title: {\n color: 'text/primary',\n textStyle: 'heading/h4',\n },\n progressText: {\n color: 'text/secondary',\n textStyle: 'body/sm/regular',\n },\n description: {\n color: 'text/body',\n minHeight: 0,\n overflowY: 'auto',\n textStyle: 'body/md/regular',\n },\n // These two margins stack on the content's own 8 gap, which is how the layout spec builds the\n // spacing: 16 between the description and the visual, and 24 above the footer. The footer gets\n // nothing below it, so the card's own 16 padding is the whole gap under the buttons.\n media: {\n marginBlockStart: '8',\n },\n control: {\n alignItems: 'center',\n display: 'flex',\n gap: '16',\n justifyContent: 'space-between',\n marginBlockStart: '16',\n },\n actions: {\n display: 'flex',\n gap: '8',\n marginInlineStart: 'auto',\n },\n closeTrigger: {\n flexShrink: 0,\n },\n arrow: {\n // Popper draws the arrow as a square rotated 45°, so the visible triangle is `size * √2`\n // wide and `size / √2` tall — 11.3 gives the design's 16×8.\n '--arrow-size': rem(11.3),\n '--arrow-background': 'colors.background/primary',\n // Size and out-of-flow positioning are set here, not only by Popper's inline styles, because\n // the component keeps this element out of Zag's `hidden` (see BitkitTour): Popper derives the\n // card's distance from the anchor as `offset.mainAxis + arrowEl.clientHeight / 2`, read off\n // the DOM. A `display: none` arrow measures 0, which puts the card 6 short of the design's 12\n // on the first pass. `absolute` keeps it from adding its height to the card while it waits\n // for Popper's own inline placement.\n height: 'var(--arrow-size)',\n position: 'absolute',\n width: 'var(--arrow-size)',\n },\n arrowTip: {\n borderColor: 'border/minimal',\n borderInlineStartWidth: '1',\n borderTopWidth: '1',\n },\n },\n});\n\nexport default tourSlotRecipe;\n"],"mappings":";;;;AAOA,IAAM,iBAAiB,iBAAiB;CACtC,WAAW;CACX,OAAO;EAAC,GAAG,YAAY,KAAK;EAAG;EAAW;EAAS;EAAU;EAAS;EAAc;CAAU;CAC9F,MAAM;EACJ,UAAU;GACR,YAAY;GACZ,QAAQ;GACR,OAAO;IACL,gBAAgB;IAChB,mBAAmB;GACrB;EAKF;EAGA,WAAW;GACT,cAAc;GACd,SAAS;GACT,cAAc;GACd,QAAQ;EACV;EAOA,YAAY;GACV,kBAAkB;GAClB,QAAQ;EACV;EACA,SAAS;GACP,YAAY;GACZ,cAAc;GACd,WAAW;GACX,SAAS;GACT,eAAe;GACf,KAAK;GAQL,WAAW;GACX,UAAU;GACV,SAAS;GACT,SAAS;GACT,UAAU;GACV,OAAO,IAAI,GAAG;GACd,QAAQ;GAIR,OAAO;IACL,gBAAgB;IAChB,mBAAmB;GACrB;EACF;EACA,QAAQ;GACN,YAAY;GACZ,SAAS;GACT,KAAK;GACL,gBAAgB;EAClB;EACA,YAAY;GACV,SAAS;GACT,eAAe;GACf,KAAK;EACP;EAGA,UAAU;GACR,YAAY;GACZ,SAAS;GACT,KAAK;EACP;EACA,OAAO,EACL,YAAY,EACd;EACA,OAAO;GACL,OAAO;GACP,WAAW;EACb;EACA,cAAc;GACZ,OAAO;GACP,WAAW;EACb;EACA,aAAa;GACX,OAAO;GACP,WAAW;GACX,WAAW;GACX,WAAW;EACb;EAIA,OAAO,EACL,kBAAkB,IACpB;EACA,SAAS;GACP,YAAY;GACZ,SAAS;GACT,KAAK;GACL,gBAAgB;GAChB,kBAAkB;EACpB;EACA,SAAS;GACP,SAAS;GACT,KAAK;GACL,mBAAmB;EACrB;EACA,cAAc,EACZ,YAAY,EACd;EACA,OAAO;GAGL,gBAAgB,IAAI,IAAI;GACxB,sBAAsB;GAOtB,QAAQ;GACR,UAAU;GACV,OAAO;EACT;EACA,UAAU;GACR,aAAa;GACb,wBAAwB;GACxB,gBAAgB;EAClB;CACF;AACF,CAAC"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * `data-*` attributes a component accepts and forwards verbatim to the one element it decides is
3
+ * the right target — never as a general prop passthrough. Mix it into a props type with `&` or
4
+ * `extends`.
5
+ *
6
+ * Components that own their layout (overlays, floating content) don't forward arbitrary props, so
7
+ * without this there is no way to address what they render. The cases it exists for are
8
+ * `data-testid`, and `data-clarity-unmask`, which opts a region out of session replay masking.
9
+ *
10
+ * Say in each component's own docs *which* element receives them — it differs: the dialogs use the
11
+ * element carrying `role="dialog"`, `BitkitActionMenu` the one carrying `role="menu"`.
12
+ */
13
+ export interface BitkitDataAttributes {
14
+ [dataAttribute: `data-${string}`]: string | undefined;
15
+ }
16
+ /**
17
+ * Splits `data-*` attributes out of a props object so they can be sent somewhere other than the
18
+ * rest of the props.
19
+ *
20
+ * Needed when the remaining props go to something that is not a DOM element — a machine's root
21
+ * provider, say. Those drop anything they don't recognise, and silently, because TypeScript does
22
+ * not check hyphenated JSX attributes against a props type. A component whose props all land on one
23
+ * chakra element doesn't need this: a plain `{...rest}` already carries them.
24
+ *
25
+ * @example
26
+ * const { dataAttributes, rest } = splitDataAttributes(props);
27
+ * return (
28
+ * <Menu.Root {...rest}>
29
+ * <Menu.Content {...dataAttributes} />
30
+ * </Menu.Root>
31
+ * );
32
+ */
33
+ export declare const splitDataAttributes: <T extends object>(props: T) => {
34
+ dataAttributes: BitkitDataAttributes;
35
+ rest: Omit<T, `data-${string}`>;
36
+ };
@@ -0,0 +1,30 @@
1
+ //#region lib/utilities/dataAttributes.ts
2
+ /**
3
+ * Splits `data-*` attributes out of a props object so they can be sent somewhere other than the
4
+ * rest of the props.
5
+ *
6
+ * Needed when the remaining props go to something that is not a DOM element — a machine's root
7
+ * provider, say. Those drop anything they don't recognise, and silently, because TypeScript does
8
+ * not check hyphenated JSX attributes against a props type. A component whose props all land on one
9
+ * chakra element doesn't need this: a plain `{...rest}` already carries them.
10
+ *
11
+ * @example
12
+ * const { dataAttributes, rest } = splitDataAttributes(props);
13
+ * return (
14
+ * <Menu.Root {...rest}>
15
+ * <Menu.Content {...dataAttributes} />
16
+ * </Menu.Root>
17
+ * );
18
+ */
19
+ var splitDataAttributes = (props) => {
20
+ const entries = Object.entries(props);
21
+ const isDataAttribute = (key) => key.startsWith("data-");
22
+ return {
23
+ dataAttributes: Object.fromEntries(entries.filter(([key]) => isDataAttribute(key))),
24
+ rest: Object.fromEntries(entries.filter(([key]) => !isDataAttribute(key)))
25
+ };
26
+ };
27
+ //#endregion
28
+ export { splitDataAttributes };
29
+
30
+ //# sourceMappingURL=dataAttributes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dataAttributes.js","names":[],"sources":["../../lib/utilities/dataAttributes.ts"],"sourcesContent":["/**\n * `data-*` attributes a component accepts and forwards verbatim to the one element it decides is\n * the right target — never as a general prop passthrough. Mix it into a props type with `&` or\n * `extends`.\n *\n * Components that own their layout (overlays, floating content) don't forward arbitrary props, so\n * without this there is no way to address what they render. The cases it exists for are\n * `data-testid`, and `data-clarity-unmask`, which opts a region out of session replay masking.\n *\n * Say in each component's own docs *which* element receives them — it differs: the dialogs use the\n * element carrying `role=\"dialog\"`, `BitkitActionMenu` the one carrying `role=\"menu\"`.\n */\nexport interface BitkitDataAttributes {\n [dataAttribute: `data-${string}`]: string | undefined;\n}\n\n/**\n * Splits `data-*` attributes out of a props object so they can be sent somewhere other than the\n * rest of the props.\n *\n * Needed when the remaining props go to something that is not a DOM element — a machine's root\n * provider, say. Those drop anything they don't recognise, and silently, because TypeScript does\n * not check hyphenated JSX attributes against a props type. A component whose props all land on one\n * chakra element doesn't need this: a plain `{...rest}` already carries them.\n *\n * @example\n * const { dataAttributes, rest } = splitDataAttributes(props);\n * return (\n * <Menu.Root {...rest}>\n * <Menu.Content {...dataAttributes} />\n * </Menu.Root>\n * );\n */\nexport const splitDataAttributes = <T extends object>(props: T) => {\n const entries = Object.entries(props);\n const isDataAttribute = (key: string) => key.startsWith('data-');\n\n return {\n dataAttributes: Object.fromEntries(entries.filter(([key]) => isDataAttribute(key))) as BitkitDataAttributes,\n rest: Object.fromEntries(entries.filter(([key]) => !isDataAttribute(key))) as Omit<T, `data-${string}`>,\n };\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAiCA,IAAa,uBAAyC,UAAa;CACjE,MAAM,UAAU,OAAO,QAAQ,KAAK;CACpC,MAAM,mBAAmB,QAAgB,IAAI,WAAW,OAAO;CAE/D,OAAO;EACL,gBAAgB,OAAO,YAAY,QAAQ,QAAQ,CAAC,SAAS,gBAAgB,GAAG,CAAC,CAAC;EAClF,MAAM,OAAO,YAAY,QAAQ,QAAQ,CAAC,SAAS,CAAC,gBAAgB,GAAG,CAAC,CAAC;CAC3E;AACF"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@bitrise/bitkit-v2",
3
3
  "private": false,
4
- "version": "0.3.387",
4
+ "version": "0.3.389",
5
5
  "description": "Bitrise Design System Components built with Chakra UI V3",
6
6
  "keywords": [
7
7
  "react",