@bitrise/bitkit-v2 0.3.388 → 0.3.390-beta.2516

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (26) hide show
  1. package/AGENTS.md +2 -1
  2. package/dist/components/BitkitActionMenu/BitkitActionMenu.d.ts +14 -2
  3. package/dist/components/BitkitActionMenu/BitkitActionMenu.js +13 -5
  4. package/dist/components/BitkitActionMenu/BitkitActionMenu.js.map +1 -1
  5. package/dist/components/BitkitDialog/BitkitDialog.d.ts +3 -2
  6. package/dist/components/BitkitDialog/BitkitDialog.js.map +1 -1
  7. package/dist/components/BitkitDialog/BitkitFormDialog.d.ts +1 -1
  8. package/dist/components/BitkitDialog/BitkitStepperDialog.d.ts +3 -2
  9. package/dist/components/BitkitDialog/BitkitStepperDialog.js.map +1 -1
  10. package/dist/components/BitkitDialog/DialogShell.d.ts +0 -8
  11. package/dist/components/BitkitDialog/DialogShell.js.map +1 -1
  12. package/dist/components/BitkitTable/BitkitLinkedRow.d.ts +1 -6
  13. package/dist/components/BitkitTable/BitkitLinkedRow.js +20 -33
  14. package/dist/components/BitkitTable/BitkitLinkedRow.js.map +1 -1
  15. package/dist/components/BitkitToast/BitkitToast.d.ts +2 -12
  16. package/dist/components/BitkitToast/BitkitToast.js.map +1 -1
  17. package/dist/theme/slot-recipes/Menu.recipe.js +3 -0
  18. package/dist/theme/slot-recipes/Menu.recipe.js.map +1 -1
  19. package/dist/theme/slot-recipes/Table.recipe.d.ts +1 -1
  20. package/dist/theme/slot-recipes/Table.recipe.js +10 -10
  21. package/dist/theme/slot-recipes/Table.recipe.js.map +1 -1
  22. package/dist/theme/slot-recipes/index.d.ts +1 -1
  23. package/dist/utilities/dataAttributes.d.ts +36 -0
  24. package/dist/utilities/dataAttributes.js +30 -0
  25. package/dist/utilities/dataAttributes.js.map +1 -0
  26. package/package.json +1 -1
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,10 +1,5 @@
1
1
  import { Table } from '@chakra-ui/react/table';
2
- export interface BitkitLinkedRowProps extends Omit<Table.RowProps, 'onClick'> {
3
- /** Target of the row link. Passed down to the `BitkitLinkedRow.LinkCell` inside the row. */
4
- href: string;
5
- /** Renders the link with the external-link affordance and opens it in a new tab. */
6
- isExternal?: boolean;
7
- }
2
+ export type BitkitLinkedRowProps = Omit<Table.RowProps, 'onClick'>;
8
3
  export type BitkitLinkedRowLinkCellProps = Table.CellProps;
9
4
  declare const _default: import('react').ForwardRefExoticComponent<BitkitLinkedRowProps & import('react').RefAttributes<HTMLTableRowElement>> & {
10
5
  LinkCell: import('react').ForwardRefExoticComponent<Table.CellProps & import('react').RefAttributes<HTMLTableCellElement>>;
@@ -1,67 +1,54 @@
1
1
  import { withSubComponents } from "../../utilities/withSubComponents.js";
2
- import BitkitLink from "../BitkitLink/BitkitLink.js";
3
2
  import { forwardRef } from "react";
4
3
  import { jsx } from "react/jsx-runtime";
5
- import { createContext as createContext$1 } from "@chakra-ui/react";
6
4
  import { Table, useTableStyles } from "@chakra-ui/react/table";
7
5
  //#region lib/components/BitkitTable/BitkitLinkedRow.tsx
8
- var [ContextProvider, useLinkedRowContext] = createContext$1({
9
- name: "LinkedRowContext",
10
- hookName: "useLinkedRowContext",
11
- providerName: "<BitkitLinkedRow />"
12
- });
13
6
  /**
14
7
  * A table row that navigates as a whole. Exactly one of its cells must be a
15
- * `BitkitLinkedRow.LinkCell` — that cell's content becomes the accessible link text, and its
16
- * stretched pseudo-element makes the entire row the click and focus target.
8
+ * `BitkitLinkedRow.LinkCell` holding the row's link — that link's text becomes the row's accessible
9
+ * name, and its stretched pseudo-element makes the entire row the click and focus target.
17
10
  *
18
11
  * Interactive elements in the other cells (buttons, checkboxes, other links) stay clickable: they
19
12
  * are lifted above the stretched link, so a `BitkitRowActionsCell` works inside a linked row.
20
13
  *
21
14
  * @example
22
15
  * ```tsx
23
- * <BitkitLinkedRow href={`/workflows/${row.id}`}>
24
- * <BitkitLinkedRow.LinkCell>{row.name}</BitkitLinkedRow.LinkCell>
16
+ * <BitkitLinkedRow>
17
+ * <BitkitLinkedRow.LinkCell>
18
+ * <BitkitLink colorVariant="purple" href={`/workflows/${row.id}`}>
19
+ * {row.name}
20
+ * </BitkitLink>
21
+ * </BitkitLinkedRow.LinkCell>
25
22
  * <Table.Cell>{row.status}</Table.Cell>
26
23
  * <BitkitRowActionsCell actions={actions} />
27
24
  * </BitkitLinkedRow>
28
25
  * ```
29
26
  */
30
27
  var BitkitLinkedRow = forwardRef((props, ref) => {
31
- const { children, href, isExternal, ...rest } = props;
28
+ const { children, ...rest } = props;
32
29
  const styles = useTableStyles();
33
- return /* @__PURE__ */ jsx(ContextProvider, {
34
- value: {
35
- href,
36
- isExternal
37
- },
38
- children: /* @__PURE__ */ jsx(Table.Row, {
39
- ref,
40
- css: styles.linkedRow,
41
- ...rest,
42
- children
43
- })
30
+ return /* @__PURE__ */ jsx(Table.Row, {
31
+ ref,
32
+ css: styles.linkedRow,
33
+ ...rest,
34
+ children
44
35
  });
45
36
  });
46
37
  BitkitLinkedRow.displayName = "BitkitLinkedRow";
47
38
  /**
48
- * The cell that carries the row's link. Its children are the accessible link text, so give it the
49
- * cell that names the row. Reads `href` and `isExternal` from the surrounding `BitkitLinkedRow`.
39
+ * The cell that carries the row's link, so give it the cell that names the row. Its content is a
40
+ * single `BitkitLink` with its own `href`, `isExternal`, `colorVariant` and any other link prop —
41
+ * the cell only stretches that link across the row, leaving its styling to the link itself.
50
42
  */
51
43
  var LinkCell = forwardRef((props, ref) => {
52
44
  const { children, ...rest } = props;
53
- const { href, isExternal } = useLinkedRowContext();
54
45
  const styles = useTableStyles();
55
46
  return /* @__PURE__ */ jsx(Table.Cell, {
56
47
  ref,
48
+ css: styles.linkCell,
49
+ "data-link-cell": true,
57
50
  ...rest,
58
- children: /* @__PURE__ */ jsx(BitkitLink, {
59
- css: styles.rowLink,
60
- "data-row-link": true,
61
- href,
62
- isExternal,
63
- children
64
- })
51
+ children
65
52
  });
66
53
  });
67
54
  LinkCell.displayName = "BitkitLinkedRow.LinkCell";
@@ -1 +1 @@
1
- {"version":3,"file":"BitkitLinkedRow.js","names":[],"sources":["../../../lib/components/BitkitTable/BitkitLinkedRow.tsx"],"sourcesContent":["// eslint-disable-next-line no-restricted-imports\nimport { createContext } from '@chakra-ui/react';\nimport { Table, useTableStyles } from '@chakra-ui/react/table';\nimport { forwardRef } from 'react';\n\nimport { withSubComponents } from '../../utilities/withSubComponents';\nimport BitkitLink from '../BitkitLink/BitkitLink';\n\ninterface LinkedRowContext {\n href: string;\n isExternal?: boolean;\n}\n\nconst [ContextProvider, useLinkedRowContext] = createContext<LinkedRowContext>({\n name: 'LinkedRowContext',\n hookName: 'useLinkedRowContext',\n providerName: '<BitkitLinkedRow />',\n});\n\nexport interface BitkitLinkedRowProps extends Omit<Table.RowProps, 'onClick'> {\n /** Target of the row link. Passed down to the `BitkitLinkedRow.LinkCell` inside the row. */\n href: string;\n /** Renders the link with the external-link affordance and opens it in a new tab. */\n isExternal?: boolean;\n}\n\n/**\n * A table row that navigates as a whole. Exactly one of its cells must be a\n * `BitkitLinkedRow.LinkCell` — that cell's content becomes the accessible link text, and its\n * stretched pseudo-element makes the entire row the click and focus target.\n *\n * Interactive elements in the other cells (buttons, checkboxes, other links) stay clickable: they\n * are lifted above the stretched link, so a `BitkitRowActionsCell` works inside a linked row.\n *\n * @example\n * ```tsx\n * <BitkitLinkedRow href={`/workflows/${row.id}`}>\n * <BitkitLinkedRow.LinkCell>{row.name}</BitkitLinkedRow.LinkCell>\n * <Table.Cell>{row.status}</Table.Cell>\n * <BitkitRowActionsCell actions={actions} />\n * </BitkitLinkedRow>\n * ```\n */\nconst BitkitLinkedRow = forwardRef<HTMLTableRowElement, BitkitLinkedRowProps>((props, ref) => {\n const { children, href, isExternal, ...rest } = props;\n const styles = useTableStyles();\n\n return (\n <ContextProvider value={{ href, isExternal }}>\n <Table.Row ref={ref} css={styles.linkedRow} {...rest}>\n {children}\n </Table.Row>\n </ContextProvider>\n );\n});\n\nBitkitLinkedRow.displayName = 'BitkitLinkedRow';\n\nexport type BitkitLinkedRowLinkCellProps = Table.CellProps;\n\n/**\n * The cell that carries the row's link. Its children are the accessible link text, so give it the\n * cell that names the row. Reads `href` and `isExternal` from the surrounding `BitkitLinkedRow`.\n */\nconst LinkCell = forwardRef<HTMLTableCellElement, BitkitLinkedRowLinkCellProps>((props, ref) => {\n const { children, ...rest } = props;\n const { href, isExternal } = useLinkedRowContext();\n const styles = useTableStyles();\n\n return (\n <Table.Cell ref={ref} {...rest}>\n <BitkitLink css={styles.rowLink} data-row-link href={href} isExternal={isExternal}>\n {children}\n </BitkitLink>\n </Table.Cell>\n );\n});\n\nLinkCell.displayName = 'BitkitLinkedRow.LinkCell';\n\nexport default withSubComponents(BitkitLinkedRow, { LinkCell });\n"],"mappings":";;;;;;;AAaA,IAAM,CAAC,iBAAiB,uBAAuB,gBAAgC;CAC7E,MAAM;CACN,UAAU;CACV,cAAc;AAChB,CAAC;;;;;;;;;;;;;;;;;;AA0BD,IAAM,kBAAkB,YAAuD,OAAO,QAAQ;CAC5F,MAAM,EAAE,UAAU,MAAM,YAAY,GAAG,SAAS;CAChD,MAAM,SAAS,eAAe;CAE9B,OACE,oBAAC,iBAAD;EAAiB,OAAO;GAAE;GAAM;EAAW;EACzC,UAAA,oBAAC,MAAM,KAAP;GAAgB;GAAK,KAAK,OAAO;GAAW,GAAI;GAC7C;EACQ,CAAA;CACI,CAAA;AAErB,CAAC;AAED,gBAAgB,cAAc;;;;;AAQ9B,IAAM,WAAW,YAAgE,OAAO,QAAQ;CAC9F,MAAM,EAAE,UAAU,GAAG,SAAS;CAC9B,MAAM,EAAE,MAAM,eAAe,oBAAoB;CACjD,MAAM,SAAS,eAAe;CAE9B,OACE,oBAAC,MAAM,MAAP;EAAiB;EAAK,GAAI;EACxB,UAAA,oBAAC,YAAD;GAAY,KAAK,OAAO;GAAS,iBAAA;GAAoB;GAAkB;GACpE;EACS,CAAA;CACF,CAAA;AAEhB,CAAC;AAED,SAAS,cAAc;AAEvB,IAAA,0BAAe,kBAAkB,iBAAiB,EAAE,SAAS,CAAC"}
1
+ {"version":3,"file":"BitkitLinkedRow.js","names":[],"sources":["../../../lib/components/BitkitTable/BitkitLinkedRow.tsx"],"sourcesContent":["import { Table, useTableStyles } from '@chakra-ui/react/table';\nimport { forwardRef } from 'react';\n\nimport { withSubComponents } from '../../utilities/withSubComponents';\n\nexport type BitkitLinkedRowProps = Omit<Table.RowProps, 'onClick'>;\n\n/**\n * A table row that navigates as a whole. Exactly one of its cells must be a\n * `BitkitLinkedRow.LinkCell` holding the row's link — that link's text becomes the row's accessible\n * name, and its stretched pseudo-element makes the entire row the click and focus target.\n *\n * Interactive elements in the other cells (buttons, checkboxes, other links) stay clickable: they\n * are lifted above the stretched link, so a `BitkitRowActionsCell` works inside a linked row.\n *\n * @example\n * ```tsx\n * <BitkitLinkedRow>\n * <BitkitLinkedRow.LinkCell>\n * <BitkitLink colorVariant=\"purple\" href={`/workflows/${row.id}`}>\n * {row.name}\n * </BitkitLink>\n * </BitkitLinkedRow.LinkCell>\n * <Table.Cell>{row.status}</Table.Cell>\n * <BitkitRowActionsCell actions={actions} />\n * </BitkitLinkedRow>\n * ```\n */\nconst BitkitLinkedRow = forwardRef<HTMLTableRowElement, BitkitLinkedRowProps>((props, ref) => {\n const { children, ...rest } = props;\n const styles = useTableStyles();\n\n return (\n <Table.Row ref={ref} css={styles.linkedRow} {...rest}>\n {children}\n </Table.Row>\n );\n});\n\nBitkitLinkedRow.displayName = 'BitkitLinkedRow';\n\nexport type BitkitLinkedRowLinkCellProps = Table.CellProps;\n\n/**\n * The cell that carries the row's link, so give it the cell that names the row. Its content is a\n * single `BitkitLink` with its own `href`, `isExternal`, `colorVariant` and any other link prop —\n * the cell only stretches that link across the row, leaving its styling to the link itself.\n */\nconst LinkCell = forwardRef<HTMLTableCellElement, BitkitLinkedRowLinkCellProps>((props, ref) => {\n const { children, ...rest } = props;\n const styles = useTableStyles();\n\n return (\n <Table.Cell ref={ref} css={styles.linkCell} data-link-cell {...rest}>\n {children}\n </Table.Cell>\n );\n});\n\nLinkCell.displayName = 'BitkitLinkedRow.LinkCell';\n\nexport default withSubComponents(BitkitLinkedRow, { LinkCell });\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AA4BA,IAAM,kBAAkB,YAAuD,OAAO,QAAQ;CAC5F,MAAM,EAAE,UAAU,GAAG,SAAS;CAC9B,MAAM,SAAS,eAAe;CAE9B,OACE,oBAAC,MAAM,KAAP;EAAgB;EAAK,KAAK,OAAO;EAAW,GAAI;EAC7C;CACQ,CAAA;AAEf,CAAC;AAED,gBAAgB,cAAc;;;;;;AAS9B,IAAM,WAAW,YAAgE,OAAO,QAAQ;CAC9F,MAAM,EAAE,UAAU,GAAG,SAAS;CAC9B,MAAM,SAAS,eAAe;CAE9B,OACE,oBAAC,MAAM,MAAP;EAAiB;EAAK,KAAK,OAAO;EAAU,kBAAA;EAAe,GAAI;EAC5D;CACS,CAAA;AAEhB,CAAC;AAED,SAAS,cAAc;AAEvB,IAAA,0BAAe,kBAAkB,iBAAiB,EAAE,SAAS,CAAC"}
@@ -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"}
@@ -1,4 +1,4 @@
1
- declare const tableSlotRecipe: import('@chakra-ui/react').SlotRecipeDefinition<"body" | "caption" | "footer" | "header" | "cell" | "row" | "root" | "utilityCell" | "bulkActionsGroup" | "bulkActionsButtons" | "definitionTrigger" | "expandedContent" | "expandableRow" | "expandedRow" | "expandCell" | "expandedCell" | "expandTrigger" | "filterControls" | "linkedRow" | "rowLink" | "actionsCell" | "actionsGroup" | "sortColumnHeader" | "sortTrigger" | "columnHeader", {
1
+ declare const tableSlotRecipe: import('@chakra-ui/react').SlotRecipeDefinition<"body" | "caption" | "footer" | "header" | "cell" | "row" | "root" | "utilityCell" | "bulkActionsGroup" | "bulkActionsButtons" | "definitionTrigger" | "expandedContent" | "expandableRow" | "expandedRow" | "expandCell" | "expandedCell" | "expandTrigger" | "filterControls" | "linkedRow" | "linkCell" | "actionsCell" | "actionsGroup" | "sortColumnHeader" | "sortTrigger" | "columnHeader", {
2
2
  variant: {
3
3
  default: {
4
4
  root: {
@@ -20,8 +20,8 @@ var tableSlotRecipe = defineSlotRecipe({
20
20
  "expandedContent",
21
21
  "expandedRow",
22
22
  "filterControls",
23
+ "linkCell",
23
24
  "linkedRow",
24
- "rowLink",
25
25
  "sortColumnHeader",
26
26
  "sortTrigger",
27
27
  "utilityCell"
@@ -117,15 +117,7 @@ var tableSlotRecipe = defineSlotRecipe({
117
117
  gap: "16",
118
118
  width: "full"
119
119
  },
120
- linkedRow: {
121
- position: "relative",
122
- _hover: { backgroundColor: "background/secondary" },
123
- "& :where(a:not([data-row-link]), button, input, label, select)": {
124
- position: "relative",
125
- zIndex: "1"
126
- }
127
- },
128
- rowLink: {
120
+ linkCell: { "& a": {
129
121
  textDecoration: "none",
130
122
  _hover: { textDecoration: "none" },
131
123
  _after: {
@@ -140,6 +132,14 @@ var tableSlotRecipe = defineSlotRecipe({
140
132
  outlineOffset: "calc(var(--focus-ring-width) * -1)"
141
133
  }
142
134
  }
135
+ } },
136
+ linkedRow: {
137
+ position: "relative",
138
+ _hover: { backgroundColor: "background/secondary" },
139
+ "& :where(a:not([data-link-cell] a), button, input, label, select)": {
140
+ position: "relative",
141
+ zIndex: "1"
142
+ }
143
143
  },
144
144
  sortColumnHeader: {
145
145
  paddingBlock: 0,
@@ -1 +1 @@
1
- {"version":3,"file":"Table.recipe.js","names":[],"sources":["../../../lib/theme/slot-recipes/Table.recipe.ts"],"sourcesContent":["import { tableAnatomy } from '@chakra-ui/react/anatomy';\nimport { defineSlotRecipe } from '@chakra-ui/react/styled-system';\n\nimport { rem } from '../themeUtils';\n\n// A control like a checkbox renders as an inline-flex <label>, which sits on the line box's\n// baseline — so the text strut's descender space leaves it a pixel or two above the row's centre.\n// Making it block-level takes the line box out of the equation and lets vertical-align: middle\n// centre it exactly.\nconst controlOnlyCell = {\n '& > :where(label):only-child': {\n display: 'flex',\n },\n};\n\n// A tinted row means \"selected\", and only a Checkbox or a Radio marks it — plus `data-selected` on\n// the row itself, the explicit opt-in for a table that tints on its own terms (a switched-on row,\n// say). Everything else is left alone, which is the narrowing over a bare `input:checked`: a switch\n// renders a hidden input[type=\"checkbox\"] too, so a toggle in a data cell read as a selected row.\n//\n// `[data-part=\"item\"]` is the load-bearing half of the radio branch. Ark's SegmentGroup is Zag's\n// radio-group anatomy renamed, so a segment sits under its own scope — but scope alone would still\n// match `RadioGroup.Root`, which wraps the whole table in the `Selectable` pattern, and with it every\n// checked radio inside. Requiring `item` on the same element pins the match to a single radio.\n//\n// Known gap: BitkitSelectableTag is a `Checkbox.Root` underneath, so one in a data cell tints its\n// row. It has no consumers today; when it gets one, put `data-selectable-tag` on its `Checkbox.Root`\n// and `:not([data-selectable-tag])` on the checkbox branch here.\nconst selectedRow =\n '&:has([data-scope=\"checkbox\"] input:checked), &:has([data-scope=\"radio-group\"][data-part=\"item\"] input:checked), &[data-selected]';\n\nconst tableSlotRecipe = defineSlotRecipe({\n className: 'table',\n slots: [\n ...tableAnatomy.keys(),\n 'actionsCell',\n 'actionsGroup',\n 'bulkActionsGroup',\n 'bulkActionsButtons',\n 'definitionTrigger',\n 'expandCell',\n 'expandTrigger',\n 'expandableRow',\n 'expandedCell',\n 'expandedContent',\n 'expandedRow',\n 'filterControls',\n 'linkedRow',\n 'rowLink',\n 'sortColumnHeader',\n 'sortTrigger',\n 'utilityCell',\n ],\n base: {\n root: {\n fontVariantNumeric: 'lining-nums tabular-nums',\n textAlign: 'start',\n width: 'full',\n },\n caption: {\n captionSide: 'top !important',\n textAlign: 'start',\n '& > * + *': {\n marginBlockStart: '4',\n },\n },\n cell: {\n color: 'text/body',\n textStyle: 'body/md/regular',\n },\n actionsCell: {\n textAlign: 'end',\n whiteSpace: 'nowrap',\n // Shrink-to-fit: a table cell can't go below its content width, so any value under the\n // content's own width collapses the column around the buttons and leaves the rest to\n // the data columns.\n width: '1%',\n },\n actionsGroup: {\n alignItems: 'center',\n display: 'inline-flex',\n gap: '8',\n position: 'relative',\n },\n bulkActionsGroup: {\n alignItems: 'center',\n display: 'flex',\n gap: '12',\n },\n bulkActionsButtons: {\n alignItems: 'center',\n display: 'flex',\n gap: '12',\n marginInlineStart: 'auto',\n },\n // The column header's own `heading/h5` has to survive, so the trigger inherits its type and\n // colour rather than setting them — which is what rules out BitkitDefinitionTooltip in a header,\n // since its recipe always pins a textStyle. The offset is that recipe's own value for 14px type.\n definitionTrigger: {\n color: 'inherit',\n cursor: 'pointer',\n font: 'inherit',\n letterSpacing: 'inherit',\n maxWidth: 'full',\n textDecoration: 'underline dotted',\n textDecorationColor: 'color/neutral/bold',\n textUnderlineOffset: '0.25em',\n _hover: {\n textDecorationColor: 'color/purple/base',\n },\n },\n expandCell: {\n paddingBlock: 0,\n paddingInline: 0,\n verticalAlign: 'middle',\n width: '48',\n },\n // A fixed 32x32 box (per the design), centred in the cell by the cell's own vertical-align.\n // Deriving the size from padding instead leaves it at the mercy of the Collapsible recipe's\n // asymmetric paddingBlockStart, which is what pushed the chevron 2px above the row's centre.\n expandTrigger: {\n alignItems: 'center',\n background: 'none',\n border: 'none',\n cursor: 'pointer',\n display: 'flex',\n height: '32',\n justifyContent: 'center',\n marginInlineStart: '12',\n padding: 0,\n width: '32',\n },\n expandableRow: {\n '& > td': {\n borderBottomWidth: 0,\n },\n },\n expandedCell: {\n height: 0,\n paddingBlock: 0,\n paddingInline: 0,\n },\n expandedContent: {\n borderBlockStartColor: 'border/minimal',\n borderBlockStartStyle: 'solid',\n borderBlockStartWidth: '1',\n marginInlineEnd: '16',\n marginInlineStart: '48',\n paddingBlockEnd: '24',\n paddingBlockStart: '16',\n paddingInlineEnd: '16',\n paddingInlineStart: '12',\n },\n expandedRow: {\n _hover: {\n background: 'none',\n },\n },\n filterControls: {\n alignItems: 'center',\n display: 'flex',\n flexWrap: 'wrap',\n gap: '16',\n width: 'full',\n },\n linkedRow: {\n position: 'relative',\n _hover: {\n backgroundColor: 'background/secondary',\n },\n '& :where(a:not([data-row-link]), button, input, label, select)': {\n position: 'relative',\n zIndex: '1',\n },\n },\n rowLink: {\n textDecoration: 'none',\n // The row's own background change is the hover affordance; the link recipe's hover\n // underline would fire on every row hover, since the stretched pseudo covers the row.\n _hover: {\n textDecoration: 'none',\n },\n _after: {\n content: '\"\"',\n inset: 0,\n position: 'absolute',\n },\n _focusVisible: {\n outline: 'none',\n _after: {\n outline: 'var(--focus-ring-width) var(--focus-ring-style) var(--focus-ring-color)',\n outlineOffset: 'calc(var(--focus-ring-width) * -1)',\n },\n },\n },\n sortColumnHeader: {\n paddingBlock: 0,\n paddingInline: 0,\n },\n sortTrigger: {\n alignItems: 'center',\n appearance: 'none',\n background: 'none',\n border: 'none',\n color: 'inherit',\n cursor: 'pointer',\n display: 'flex',\n font: 'inherit',\n gap: '8',\n height: 'full',\n paddingBlock: '12',\n paddingInline: '16',\n userSelect: 'none',\n width: 'full',\n _focusVisible: {\n outlineOffset: '-3px',\n },\n _hover: {\n backgroundColor: 'background/active',\n },\n },\n utilityCell: {\n height: 'auto',\n paddingBlock: '12',\n paddingInline: '16',\n },\n },\n variants: {\n variant: {\n default: {\n root: {\n borderColor: 'border/regular',\n borderRadius: '4',\n borderStyle: 'solid',\n borderWidth: '1',\n overflow: 'hidden',\n },\n header: {\n '& :where(th)': {\n backgroundColor: 'background/tertiary',\n },\n },\n columnHeader: {\n borderBottomColor: 'border/minimal',\n paddingBlock: '12',\n paddingInline: '16',\n },\n cell: {\n borderBottomColor: 'border/minimal',\n borderTopColor: 'border/minimal',\n paddingInline: '16',\n },\n footer: {\n borderTopColor: 'border/minimal',\n },\n },\n borderless: {\n columnHeader: {\n borderBottomColor: 'border/regular',\n padding: '12',\n },\n cell: {\n borderBottomColor: 'border/regular',\n borderTopColor: 'border/regular',\n paddingInline: '12',\n },\n footer: {\n borderTopColor: 'border/regular',\n },\n },\n card: {\n columnHeader: {\n borderBottomColor: 'border/minimal',\n height: '48',\n padding: '12',\n },\n cell: {\n borderBottomColor: 'border/minimal',\n borderTopColor: 'border/minimal',\n paddingInline: '12',\n },\n row: {\n 'thead &, tbody &': {\n '& > :where(td, th):first-child': {\n paddingInlineStart: '24',\n },\n '& > :where(td, th):last-child': {\n paddingInlineEnd: '24',\n },\n },\n },\n footer: {\n borderTopColor: 'border/minimal',\n },\n },\n },\n size: {\n sm: {\n cell: {\n height: '48',\n },\n },\n md: {\n cell: {\n height: rem(56),\n },\n },\n lg: {\n cell: {\n height: '64',\n },\n },\n },\n // Hovering a row tints it. Usually a reading aid on a long or wide table rather than a hint\n // that the row is clickable, so it says nothing about the row being interactive — turn it off\n // for short, static tables where there is no place to lose.\n rowHover: {\n true: {},\n false: {},\n },\n layout: {\n table: {\n root: {\n borderCollapse: 'separate',\n borderSpacing: '0',\n },\n caption: {\n marginBlockEnd: '24',\n },\n columnHeader: {\n borderBottomStyle: 'solid',\n borderBottomWidth: '1',\n color: 'text/primary',\n fontWeight: 'bold',\n textAlign: 'start',\n textStyle: 'heading/h5',\n verticalAlign: 'middle',\n ...controlOnlyCell,\n },\n cell: {\n borderBottomStyle: 'solid',\n borderBottomWidth: '1',\n verticalAlign: 'middle',\n ...controlOnlyCell,\n // border-collapse: separate ignores borders on tfoot itself (CSS 2.1 §17.6.1),\n // so the body/footer divider has to live on the footer's cells.\n // A footer holds one full-width block (pagination, a \"new item\" action) that brings its\n // own padding and height, so the body cell's 16px inset and fixed row height would\n // double up on it.\n 'tfoot &': {\n borderBottomWidth: 0,\n borderTopStyle: 'solid',\n borderTopWidth: '1',\n height: 'auto',\n paddingBlock: 0,\n paddingInline: 0,\n },\n },\n body: {\n '& :where(tr)': {\n [selectedRow]: {\n backgroundColor: 'background/selected',\n _hover: {\n backgroundColor: 'background/selected',\n },\n },\n },\n '& :where(tr:last-child) td': {\n borderBottomWidth: 0,\n },\n },\n },\n stacked: {\n root: {\n display: 'block',\n },\n caption: {\n display: 'block',\n padding: '16',\n backgroundColor: 'background/secondary',\n borderBottomColor: 'border/minimal',\n borderBottomStyle: 'solid',\n borderBottomWidth: '1',\n },\n header: {\n borderWidth: 0,\n clip: 'rect(0, 0, 0, 0)',\n height: '1',\n margin: '-1px',\n overflow: 'hidden',\n padding: 0,\n position: 'absolute',\n whiteSpace: 'nowrap',\n width: '1',\n },\n body: {\n display: 'block',\n },\n row: {\n borderBottomColor: 'border/minimal',\n borderBottomStyle: 'solid',\n borderBottomWidth: '1',\n display: 'block',\n paddingBlock: '12',\n '&:last-child': {\n borderBottomWidth: 0,\n },\n },\n cell: {\n alignItems: 'center',\n display: 'flex',\n minHeight: '48',\n paddingInline: '16',\n _before: {\n alignSelf: 'center',\n color: 'text/primary',\n content: 'attr(data-label)',\n flexShrink: 0,\n fontWeight: 'semibold',\n marginInlineEnd: '16',\n width: '96',\n },\n 'tfoot &': {\n display: 'block',\n paddingInline: 0,\n _before: {\n content: 'none',\n },\n },\n },\n // display: block takes tfoot out of the table model, so a border on it does render here\n footer: {\n borderTopStyle: 'solid',\n borderTopWidth: '1',\n display: 'block',\n },\n },\n },\n },\n compoundVariants: [\n {\n css: {\n row: {\n borderBottomColor: 'border/regular',\n },\n },\n layout: 'stacked',\n variant: 'borderless',\n },\n // The card gutter and the 12px cell padding are for the wide layout. Stacked rows are blocks\n // whose cells run vertically, so an inline indent on only the first and last one reads as a\n // misalignment — everything goes back to the stacked layout's own 16px.\n {\n css: {\n cell: {\n paddingInline: '16',\n },\n row: {\n 'thead &, tbody &': {\n '& > :where(td, th):first-child': {\n paddingInlineStart: '16',\n },\n '& > :where(td, th):last-child': {\n paddingInlineEnd: '16',\n },\n },\n },\n },\n layout: 'stacked',\n variant: 'card',\n },\n // The `size` variant pins a fixed cell height (48/56/64px), and it is merged after `layout`\n // regardless of declaration order — so only a compound variant can release it. Stacked cells\n // are flex containers whose content (label gutter + a multi-line value) routinely needs more\n // room than the fixed height, and the stacked `cell` keeps `minHeight: 48` as the floor.\n {\n css: {\n cell: {\n height: 'auto',\n },\n },\n layout: 'stacked',\n },\n // Scoped to `layout: table` because that is where the hover lived before: the stacked layout\n // renders rows as blocks and never tinted them.\n {\n css: {\n body: {\n '& :where(tr)': {\n _hover: {\n backgroundColor: 'background/secondary',\n },\n },\n },\n },\n layout: 'table',\n rowHover: true,\n },\n ],\n defaultVariants: {\n layout: 'table',\n rowHover: true,\n size: 'lg',\n variant: 'default',\n },\n});\n\nexport default tableSlotRecipe;\n"],"mappings":"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"}
1
+ {"version":3,"file":"Table.recipe.js","names":[],"sources":["../../../lib/theme/slot-recipes/Table.recipe.ts"],"sourcesContent":["import { tableAnatomy } from '@chakra-ui/react/anatomy';\nimport { defineSlotRecipe } from '@chakra-ui/react/styled-system';\n\nimport { rem } from '../themeUtils';\n\n// A control like a checkbox renders as an inline-flex <label>, which sits on the line box's\n// baseline — so the text strut's descender space leaves it a pixel or two above the row's centre.\n// Making it block-level takes the line box out of the equation and lets vertical-align: middle\n// centre it exactly.\nconst controlOnlyCell = {\n '& > :where(label):only-child': {\n display: 'flex',\n },\n};\n\n// A tinted row means \"selected\", and only a Checkbox or a Radio marks it — plus `data-selected` on\n// the row itself, the explicit opt-in for a table that tints on its own terms (a switched-on row,\n// say). Everything else is left alone, which is the narrowing over a bare `input:checked`: a switch\n// renders a hidden input[type=\"checkbox\"] too, so a toggle in a data cell read as a selected row.\n//\n// `[data-part=\"item\"]` is the load-bearing half of the radio branch. Ark's SegmentGroup is Zag's\n// radio-group anatomy renamed, so a segment sits under its own scope — but scope alone would still\n// match `RadioGroup.Root`, which wraps the whole table in the `Selectable` pattern, and with it every\n// checked radio inside. Requiring `item` on the same element pins the match to a single radio.\n//\n// Known gap: BitkitSelectableTag is a `Checkbox.Root` underneath, so one in a data cell tints its\n// row. It has no consumers today; when it gets one, put `data-selectable-tag` on its `Checkbox.Root`\n// and `:not([data-selectable-tag])` on the checkbox branch here.\nconst selectedRow =\n '&:has([data-scope=\"checkbox\"] input:checked), &:has([data-scope=\"radio-group\"][data-part=\"item\"] input:checked), &[data-selected]';\n\nconst tableSlotRecipe = defineSlotRecipe({\n className: 'table',\n slots: [\n ...tableAnatomy.keys(),\n 'actionsCell',\n 'actionsGroup',\n 'bulkActionsGroup',\n 'bulkActionsButtons',\n 'definitionTrigger',\n 'expandCell',\n 'expandTrigger',\n 'expandableRow',\n 'expandedCell',\n 'expandedContent',\n 'expandedRow',\n 'filterControls',\n 'linkCell',\n 'linkedRow',\n 'sortColumnHeader',\n 'sortTrigger',\n 'utilityCell',\n ],\n base: {\n root: {\n fontVariantNumeric: 'lining-nums tabular-nums',\n textAlign: 'start',\n width: 'full',\n },\n caption: {\n captionSide: 'top !important',\n textAlign: 'start',\n '& > * + *': {\n marginBlockStart: '4',\n },\n },\n cell: {\n color: 'text/body',\n textStyle: 'body/md/regular',\n },\n actionsCell: {\n textAlign: 'end',\n whiteSpace: 'nowrap',\n // Shrink-to-fit: a table cell can't go below its content width, so any value under the\n // content's own width collapses the column around the buttons and leaves the rest to\n // the data columns.\n width: '1%',\n },\n actionsGroup: {\n alignItems: 'center',\n display: 'inline-flex',\n gap: '8',\n position: 'relative',\n },\n bulkActionsGroup: {\n alignItems: 'center',\n display: 'flex',\n gap: '12',\n },\n bulkActionsButtons: {\n alignItems: 'center',\n display: 'flex',\n gap: '12',\n marginInlineStart: 'auto',\n },\n // The column header's own `heading/h5` has to survive, so the trigger inherits its type and\n // colour rather than setting them — which is what rules out BitkitDefinitionTooltip in a header,\n // since its recipe always pins a textStyle. The offset is that recipe's own value for 14px type.\n definitionTrigger: {\n color: 'inherit',\n cursor: 'pointer',\n font: 'inherit',\n letterSpacing: 'inherit',\n maxWidth: 'full',\n textDecoration: 'underline dotted',\n textDecorationColor: 'color/neutral/bold',\n textUnderlineOffset: '0.25em',\n _hover: {\n textDecorationColor: 'color/purple/base',\n },\n },\n expandCell: {\n paddingBlock: 0,\n paddingInline: 0,\n verticalAlign: 'middle',\n width: '48',\n },\n // A fixed 32x32 box (per the design), centred in the cell by the cell's own vertical-align.\n // Deriving the size from padding instead leaves it at the mercy of the Collapsible recipe's\n // asymmetric paddingBlockStart, which is what pushed the chevron 2px above the row's centre.\n expandTrigger: {\n alignItems: 'center',\n background: 'none',\n border: 'none',\n cursor: 'pointer',\n display: 'flex',\n height: '32',\n justifyContent: 'center',\n marginInlineStart: '12',\n padding: 0,\n width: '32',\n },\n expandableRow: {\n '& > td': {\n borderBottomWidth: 0,\n },\n },\n expandedCell: {\n height: 0,\n paddingBlock: 0,\n paddingInline: 0,\n },\n expandedContent: {\n borderBlockStartColor: 'border/minimal',\n borderBlockStartStyle: 'solid',\n borderBlockStartWidth: '1',\n marginInlineEnd: '16',\n marginInlineStart: '48',\n paddingBlockEnd: '24',\n paddingBlockStart: '16',\n paddingInlineEnd: '16',\n paddingInlineStart: '12',\n },\n expandedRow: {\n _hover: {\n background: 'none',\n },\n },\n filterControls: {\n alignItems: 'center',\n display: 'flex',\n flexWrap: 'wrap',\n gap: '16',\n width: 'full',\n },\n linkCell: {\n // The link inside is the row's link: its stretched pseudo covers the whole row, so the row\n // becomes the click and focus target.\n '& a': {\n textDecoration: 'none',\n // The row's own background change is the hover affordance; the link recipe's hover\n // underline would fire on every row hover, since the stretched pseudo covers the row.\n _hover: {\n textDecoration: 'none',\n },\n _after: {\n content: '\"\"',\n inset: 0,\n position: 'absolute',\n },\n _focusVisible: {\n outline: 'none',\n _after: {\n outline: 'var(--focus-ring-width) var(--focus-ring-style) var(--focus-ring-color)',\n outlineOffset: 'calc(var(--focus-ring-width) * -1)',\n },\n },\n },\n },\n linkedRow: {\n position: 'relative',\n _hover: {\n backgroundColor: 'background/secondary',\n },\n '& :where(a:not([data-link-cell] a), button, input, label, select)': {\n position: 'relative',\n zIndex: '1',\n },\n },\n sortColumnHeader: {\n paddingBlock: 0,\n paddingInline: 0,\n },\n sortTrigger: {\n alignItems: 'center',\n appearance: 'none',\n background: 'none',\n border: 'none',\n color: 'inherit',\n cursor: 'pointer',\n display: 'flex',\n font: 'inherit',\n gap: '8',\n height: 'full',\n paddingBlock: '12',\n paddingInline: '16',\n userSelect: 'none',\n width: 'full',\n _focusVisible: {\n outlineOffset: '-3px',\n },\n _hover: {\n backgroundColor: 'background/active',\n },\n },\n utilityCell: {\n height: 'auto',\n paddingBlock: '12',\n paddingInline: '16',\n },\n },\n variants: {\n variant: {\n default: {\n root: {\n borderColor: 'border/regular',\n borderRadius: '4',\n borderStyle: 'solid',\n borderWidth: '1',\n overflow: 'hidden',\n },\n header: {\n '& :where(th)': {\n backgroundColor: 'background/tertiary',\n },\n },\n columnHeader: {\n borderBottomColor: 'border/minimal',\n paddingBlock: '12',\n paddingInline: '16',\n },\n cell: {\n borderBottomColor: 'border/minimal',\n borderTopColor: 'border/minimal',\n paddingInline: '16',\n },\n footer: {\n borderTopColor: 'border/minimal',\n },\n },\n borderless: {\n columnHeader: {\n borderBottomColor: 'border/regular',\n padding: '12',\n },\n cell: {\n borderBottomColor: 'border/regular',\n borderTopColor: 'border/regular',\n paddingInline: '12',\n },\n footer: {\n borderTopColor: 'border/regular',\n },\n },\n card: {\n columnHeader: {\n borderBottomColor: 'border/minimal',\n height: '48',\n padding: '12',\n },\n cell: {\n borderBottomColor: 'border/minimal',\n borderTopColor: 'border/minimal',\n paddingInline: '12',\n },\n row: {\n 'thead &, tbody &': {\n '& > :where(td, th):first-child': {\n paddingInlineStart: '24',\n },\n '& > :where(td, th):last-child': {\n paddingInlineEnd: '24',\n },\n },\n },\n footer: {\n borderTopColor: 'border/minimal',\n },\n },\n },\n size: {\n sm: {\n cell: {\n height: '48',\n },\n },\n md: {\n cell: {\n height: rem(56),\n },\n },\n lg: {\n cell: {\n height: '64',\n },\n },\n },\n // Hovering a row tints it. Usually a reading aid on a long or wide table rather than a hint\n // that the row is clickable, so it says nothing about the row being interactive — turn it off\n // for short, static tables where there is no place to lose.\n rowHover: {\n true: {},\n false: {},\n },\n layout: {\n table: {\n root: {\n borderCollapse: 'separate',\n borderSpacing: '0',\n },\n caption: {\n marginBlockEnd: '24',\n },\n columnHeader: {\n borderBottomStyle: 'solid',\n borderBottomWidth: '1',\n color: 'text/primary',\n fontWeight: 'bold',\n textAlign: 'start',\n textStyle: 'heading/h5',\n verticalAlign: 'middle',\n ...controlOnlyCell,\n },\n cell: {\n borderBottomStyle: 'solid',\n borderBottomWidth: '1',\n verticalAlign: 'middle',\n ...controlOnlyCell,\n // border-collapse: separate ignores borders on tfoot itself (CSS 2.1 §17.6.1),\n // so the body/footer divider has to live on the footer's cells.\n // A footer holds one full-width block (pagination, a \"new item\" action) that brings its\n // own padding and height, so the body cell's 16px inset and fixed row height would\n // double up on it.\n 'tfoot &': {\n borderBottomWidth: 0,\n borderTopStyle: 'solid',\n borderTopWidth: '1',\n height: 'auto',\n paddingBlock: 0,\n paddingInline: 0,\n },\n },\n body: {\n '& :where(tr)': {\n [selectedRow]: {\n backgroundColor: 'background/selected',\n _hover: {\n backgroundColor: 'background/selected',\n },\n },\n },\n '& :where(tr:last-child) td': {\n borderBottomWidth: 0,\n },\n },\n },\n stacked: {\n root: {\n display: 'block',\n },\n caption: {\n display: 'block',\n padding: '16',\n backgroundColor: 'background/secondary',\n borderBottomColor: 'border/minimal',\n borderBottomStyle: 'solid',\n borderBottomWidth: '1',\n },\n header: {\n borderWidth: 0,\n clip: 'rect(0, 0, 0, 0)',\n height: '1',\n margin: '-1px',\n overflow: 'hidden',\n padding: 0,\n position: 'absolute',\n whiteSpace: 'nowrap',\n width: '1',\n },\n body: {\n display: 'block',\n },\n row: {\n borderBottomColor: 'border/minimal',\n borderBottomStyle: 'solid',\n borderBottomWidth: '1',\n display: 'block',\n paddingBlock: '12',\n '&:last-child': {\n borderBottomWidth: 0,\n },\n },\n cell: {\n alignItems: 'center',\n display: 'flex',\n minHeight: '48',\n paddingInline: '16',\n _before: {\n alignSelf: 'center',\n color: 'text/primary',\n content: 'attr(data-label)',\n flexShrink: 0,\n fontWeight: 'semibold',\n marginInlineEnd: '16',\n width: '96',\n },\n 'tfoot &': {\n display: 'block',\n paddingInline: 0,\n _before: {\n content: 'none',\n },\n },\n },\n // display: block takes tfoot out of the table model, so a border on it does render here\n footer: {\n borderTopStyle: 'solid',\n borderTopWidth: '1',\n display: 'block',\n },\n },\n },\n },\n compoundVariants: [\n {\n css: {\n row: {\n borderBottomColor: 'border/regular',\n },\n },\n layout: 'stacked',\n variant: 'borderless',\n },\n // The card gutter and the 12px cell padding are for the wide layout. Stacked rows are blocks\n // whose cells run vertically, so an inline indent on only the first and last one reads as a\n // misalignment — everything goes back to the stacked layout's own 16px.\n {\n css: {\n cell: {\n paddingInline: '16',\n },\n row: {\n 'thead &, tbody &': {\n '& > :where(td, th):first-child': {\n paddingInlineStart: '16',\n },\n '& > :where(td, th):last-child': {\n paddingInlineEnd: '16',\n },\n },\n },\n },\n layout: 'stacked',\n variant: 'card',\n },\n // The `size` variant pins a fixed cell height (48/56/64px), and it is merged after `layout`\n // regardless of declaration order — so only a compound variant can release it. Stacked cells\n // are flex containers whose content (label gutter + a multi-line value) routinely needs more\n // room than the fixed height, and the stacked `cell` keeps `minHeight: 48` as the floor.\n {\n css: {\n cell: {\n height: 'auto',\n },\n },\n layout: 'stacked',\n },\n // Scoped to `layout: table` because that is where the hover lived before: the stacked layout\n // renders rows as blocks and never tinted them.\n {\n css: {\n body: {\n '& :where(tr)': {\n _hover: {\n backgroundColor: 'background/secondary',\n },\n },\n },\n },\n layout: 'table',\n rowHover: true,\n },\n ],\n defaultVariants: {\n layout: 'table',\n rowHover: true,\n size: 'lg',\n variant: 'default',\n },\n});\n\nexport default tableSlotRecipe;\n"],"mappings":"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KACA,WAAW;MACT,SAAS;MACT,eAAe;MACf,SAAS,EACP,SAAS,OACX;KACF;IACF;IAEA,QAAQ;KACN,gBAAgB;KAChB,gBAAgB;KAChB,SAAS;IACX;GACF;EACF;CACF;CACA,kBAAkB;EAChB;GACE,KAAK,EACH,KAAK,EACH,mBAAmB,iBACrB,EACF;GACA,QAAQ;GACR,SAAS;EACX;EAIA;GACE,KAAK;IACH,MAAM,EACJ,eAAe,KACjB;IACA,KAAK,EACH,oBAAoB;KAClB,kCAAkC,EAChC,oBAAoB,KACtB;KACA,iCAAiC,EAC/B,kBAAkB,KACpB;IACF,EACF;GACF;GACA,QAAQ;GACR,SAAS;EACX;EAKA;GACE,KAAK,EACH,MAAM,EACJ,QAAQ,OACV,EACF;GACA,QAAQ;EACV;EAGA;GACE,KAAK,EACH,MAAM,EACJ,gBAAgB,EACd,QAAQ,EACN,iBAAiB,uBACnB,EACF,EACF,EACF;GACA,QAAQ;GACR,UAAU;EACZ;CACF;CACA,iBAAiB;EACf,QAAQ;EACR,UAAU;EACV,MAAM;EACN,SAAS;CACX;AACF,CAAC"}
@@ -2112,7 +2112,7 @@ declare const slotRecipes: {
2112
2112
  };
2113
2113
  };
2114
2114
  }>;
2115
- table: import('@chakra-ui/react').SlotRecipeDefinition<"body" | "caption" | "footer" | "header" | "cell" | "row" | "root" | "utilityCell" | "bulkActionsGroup" | "bulkActionsButtons" | "definitionTrigger" | "expandedContent" | "expandableRow" | "expandedRow" | "expandCell" | "expandedCell" | "expandTrigger" | "filterControls" | "linkedRow" | "rowLink" | "actionsCell" | "actionsGroup" | "sortColumnHeader" | "sortTrigger" | "columnHeader", {
2115
+ table: import('@chakra-ui/react').SlotRecipeDefinition<"body" | "caption" | "footer" | "header" | "cell" | "row" | "root" | "utilityCell" | "bulkActionsGroup" | "bulkActionsButtons" | "definitionTrigger" | "expandedContent" | "expandableRow" | "expandedRow" | "expandCell" | "expandedCell" | "expandTrigger" | "filterControls" | "linkedRow" | "linkCell" | "actionsCell" | "actionsGroup" | "sortColumnHeader" | "sortTrigger" | "columnHeader", {
2116
2116
  variant: {
2117
2117
  default: {
2118
2118
  root: {
@@ -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.388",
4
+ "version": "0.3.390-beta.2516",
5
5
  "description": "Bitrise Design System Components built with Chakra UI V3",
6
6
  "keywords": [
7
7
  "react",