@bitrise/bitkit-v2 0.3.357 → 0.3.359-beta.2314

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.
@@ -1,6 +1,6 @@
1
1
  import { Checkbox } from '@chakra-ui/react/checkbox';
2
2
  import { DataAttr } from '@chakra-ui/react/styled-system';
3
- import { InputHTMLAttributes, ReactNode } from 'react';
3
+ import { InputHTMLAttributes, ReactElement, ReactNode, Ref } from 'react';
4
4
  type BitkitCheckboxBaseProps = {
5
5
  /** Props forwarded to the underlying `<input>` (e.g. `data-testid`). */
6
6
  inputProps?: InputHTMLAttributes<HTMLInputElement> & DataAttr;
@@ -12,13 +12,20 @@ type BitkitCheckboxBaseProps = {
12
12
  * select-all header — an `aria-label`, which is applied to the hidden input instead of being
13
13
  * rendered.
14
14
  */
15
- export type BitkitCheckboxProps = BitkitCheckboxBaseProps & ({
15
+ export type BitkitCheckboxProps<T extends NonNullable<ReactNode> = NonNullable<ReactNode>> = BitkitCheckboxBaseProps & ({
16
16
  helperText?: ReactNode;
17
- labelText: NonNullable<ReactNode>;
17
+ /**
18
+ * The visible label, which is where the checkbox gets its accessible name from. It has to be
19
+ * non-empty — an empty string is a compile error. When the layout has no room for a visible
20
+ * label, pass `aria-label` instead of an empty `labelText`.
21
+ */
22
+ labelText: T extends '' ? never : T;
18
23
  } | {
19
24
  'aria-label': string;
20
25
  helperText?: never;
21
26
  labelText?: null;
22
27
  });
23
- declare const BitkitCheckbox: import('react').ForwardRefExoticComponent<BitkitCheckboxProps & import('react').RefAttributes<HTMLInputElement>>;
24
- export default BitkitCheckbox;
28
+ declare const _default: <T extends NonNullable<ReactNode>>(props: BitkitCheckboxProps<T> & {
29
+ ref?: Ref<HTMLInputElement>;
30
+ }) => ReactElement;
31
+ export default _default;
@@ -1,12 +1,12 @@
1
1
  import IconCheck from "../../icons/IconCheck.js";
2
2
  import IconMinus from "../../icons/IconMinus.js";
3
+ import { isEmptyNode } from "../../utilities/isEmptyNode.js";
3
4
  import { forwardRef } from "react";
4
5
  import { jsx, jsxs } from "react/jsx-runtime";
5
6
  import { Text } from "@chakra-ui/react/text";
6
7
  import { Skeleton } from "@chakra-ui/react/skeleton";
7
8
  import { Checkbox } from "@chakra-ui/react/checkbox";
8
9
  //#region lib/components/BitkitCheckbox/BitkitCheckbox.tsx
9
- var isEmptyNode = (node) => node == null || node === "" || typeof node === "boolean";
10
10
  var BitkitCheckbox = forwardRef((props, ref) => {
11
11
  const { "aria-label": ariaLabel, helperText, inputProps, labelText, state, ...rest } = props;
12
12
  const hasHelperText = !isEmptyNode(helperText);
@@ -1 +1 @@
1
- {"version":3,"file":"BitkitCheckbox.js","names":[],"sources":["../../../lib/components/BitkitCheckbox/BitkitCheckbox.tsx"],"sourcesContent":["import { Checkbox } from '@chakra-ui/react/checkbox';\nimport { Skeleton } from '@chakra-ui/react/skeleton';\nimport { type DataAttr } from '@chakra-ui/react/styled-system';\nimport { Text } from '@chakra-ui/react/text';\nimport { forwardRef, type InputHTMLAttributes, type ReactNode } from 'react';\n\nimport { IconCheck, IconMinus } from '../../icons';\n\ntype BitkitCheckboxBaseProps = {\n /** Props forwarded to the underlying `<input>` (e.g. `data-testid`). */\n inputProps?: InputHTMLAttributes<HTMLInputElement> & DataAttr;\n state?: 'disabled' | 'readOnly' | 'skeleton';\n} & Omit<Checkbox.RootProps, 'disabled' | 'readOnly'>;\n\n/**\n * A checkbox has to end up with an accessible name, and it takes that name from its label. So either\n * pass a visible `labelText`, or — for a checkbox in a layout with no room for one, like a table\n * select-all header — an `aria-label`, which is applied to the hidden input instead of being\n * rendered.\n */\nexport type BitkitCheckboxProps = BitkitCheckboxBaseProps &\n (\n | {\n helperText?: ReactNode;\n labelText: NonNullable<ReactNode>;\n }\n | { 'aria-label': string; helperText?: never; labelText?: null }\n );\n\nconst isEmptyNode = (node: ReactNode) => node == null || node === '' || typeof node === 'boolean';\n\nconst BitkitCheckbox = forwardRef<HTMLInputElement, BitkitCheckboxProps>((props, ref) => {\n const { 'aria-label': ariaLabel, helperText, inputProps, labelText, state, ...rest } = props;\n const hasHelperText = !isEmptyNode(helperText);\n const hasLabel = !isEmptyNode(labelText) || hasHelperText;\n\n // Skeleton has to set disabled to be inert: the Skeleton wrapper's own pointer-events: none never\n // stopped a click, it only moved the target to the <label>, which activates the control. The cursor\n // style prop then keeps the arrow plain — style props land outside @layer recipes, where the\n // recipe's _disabled: { cursor: 'not-allowed' } sits.\n return (\n <Checkbox.Root\n cursor={state === 'skeleton' ? 'default' : undefined}\n disabled={state === 'disabled' || state === 'skeleton'}\n readOnly={state === 'readOnly'}\n {...rest}\n >\n <Checkbox.HiddenInput aria-label={ariaLabel} ref={ref} {...inputProps} />\n <Skeleton loading={state === 'skeleton'}>\n <Checkbox.Control>{rest.checked === 'indeterminate' ? <IconMinus /> : <IconCheck />}</Checkbox.Control>\n </Skeleton>\n {hasLabel && (\n <Skeleton loading={state === 'skeleton'}>\n <Checkbox.Label as=\"div\">\n {labelText}\n {hasHelperText && (\n <Text color=\"text/helper\" textStyle=\"comp/input/helperText\">\n {helperText}\n </Text>\n )}\n </Checkbox.Label>\n </Skeleton>\n )}\n </Checkbox.Root>\n );\n});\n\nBitkitCheckbox.displayName = 'BitkitCheckbox';\n\nexport default BitkitCheckbox;\n"],"mappings":";;;;;;;;AA6BA,IAAM,eAAe,SAAoB,QAAQ,QAAQ,SAAS,MAAM,OAAO,SAAS;AAExF,IAAM,iBAAiB,YAAmD,OAAO,QAAQ;CACvF,MAAM,EAAE,cAAc,WAAW,YAAY,YAAY,WAAW,OAAO,GAAG,SAAS;CACvF,MAAM,gBAAgB,CAAC,YAAY,UAAU;CAC7C,MAAM,WAAW,CAAC,YAAY,SAAS,KAAK;CAM5C,OACE,qBAAC,SAAS,MAAV;EACE,QAAQ,UAAU,aAAa,YAAY,KAAA;EAC3C,UAAU,UAAU,cAAc,UAAU;EAC5C,UAAU,UAAU;EACpB,GAAI;EAJN,UAAA;GAME,oBAAC,SAAS,aAAV;IAAsB,cAAY;IAAgB;IAAK,GAAI;GAAa,CAAA;GACxE,oBAAC,UAAD;IAAU,SAAS,UAAU;IAC3B,UAAA,oBAAC,SAAS,SAAV,EAAA,UAAmB,KAAK,YAAY,kBAAkB,oBAAC,WAAD,CAAY,CAAA,IAAI,oBAAC,WAAD,CAAY,CAAA,EAAoB,CAAA;GAC9F,CAAA;GACT,YACC,oBAAC,UAAD;IAAU,SAAS,UAAU;IAC3B,UAAA,qBAAC,SAAS,OAAV;KAAgB,IAAG;KAAnB,UAAA,CACG,WACA,iBACC,oBAAC,MAAD;MAAM,OAAM;MAAc,WAAU;MACjC,UAAA;KACG,CAAA,CAEM;;GACR,CAAA;EAEC;;AAEnB,CAAC;AAED,eAAe,cAAc"}
1
+ {"version":3,"file":"BitkitCheckbox.js","names":[],"sources":["../../../lib/components/BitkitCheckbox/BitkitCheckbox.tsx"],"sourcesContent":["import { Checkbox } from '@chakra-ui/react/checkbox';\nimport { Skeleton } from '@chakra-ui/react/skeleton';\nimport { type DataAttr } from '@chakra-ui/react/styled-system';\nimport { Text } from '@chakra-ui/react/text';\nimport { forwardRef, type InputHTMLAttributes, type ReactElement, type ReactNode, type Ref } from 'react';\n\nimport { IconCheck, IconMinus } from '../../icons';\nimport { isEmptyNode } from '../../utilities/isEmptyNode';\n\ntype BitkitCheckboxBaseProps = {\n /** Props forwarded to the underlying `<input>` (e.g. `data-testid`). */\n inputProps?: InputHTMLAttributes<HTMLInputElement> & DataAttr;\n state?: 'disabled' | 'readOnly' | 'skeleton';\n} & Omit<Checkbox.RootProps, 'disabled' | 'readOnly'>;\n\n/**\n * A checkbox has to end up with an accessible name, and it takes that name from its label. So either\n * pass a visible `labelText`, or — for a checkbox in a layout with no room for one, like a table\n * select-all header — an `aria-label`, which is applied to the hidden input instead of being\n * rendered.\n */\nexport type BitkitCheckboxProps<T extends NonNullable<ReactNode> = NonNullable<ReactNode>> = BitkitCheckboxBaseProps &\n (\n | {\n helperText?: ReactNode;\n /**\n * The visible label, which is where the checkbox gets its accessible name from. It has to be\n * non-empty — an empty string is a compile error. When the layout has no room for a visible\n * label, pass `aria-label` instead of an empty `labelText`.\n */\n labelText: T extends '' ? never : T;\n }\n | { 'aria-label': string; helperText?: never; labelText?: null }\n );\n\nconst BitkitCheckbox = forwardRef<HTMLInputElement, BitkitCheckboxProps>((props, ref) => {\n const { 'aria-label': ariaLabel, helperText, inputProps, labelText, state, ...rest } = props;\n const hasHelperText = !isEmptyNode(helperText);\n const hasLabel = !isEmptyNode(labelText) || hasHelperText;\n\n // Skeleton has to set disabled to be inert: the Skeleton wrapper's own pointer-events: none never\n // stopped a click, it only moved the target to the <label>, which activates the control. The cursor\n // style prop then keeps the arrow plain — style props land outside @layer recipes, where the\n // recipe's _disabled: { cursor: 'not-allowed' } sits.\n return (\n <Checkbox.Root\n cursor={state === 'skeleton' ? 'default' : undefined}\n disabled={state === 'disabled' || state === 'skeleton'}\n readOnly={state === 'readOnly'}\n {...rest}\n >\n <Checkbox.HiddenInput aria-label={ariaLabel} ref={ref} {...inputProps} />\n <Skeleton loading={state === 'skeleton'}>\n <Checkbox.Control>{rest.checked === 'indeterminate' ? <IconMinus /> : <IconCheck />}</Checkbox.Control>\n </Skeleton>\n {hasLabel && (\n <Skeleton loading={state === 'skeleton'}>\n <Checkbox.Label as=\"div\">\n {labelText}\n {hasHelperText && (\n <Text color=\"text/helper\" textStyle=\"comp/input/helperText\">\n {helperText}\n </Text>\n )}\n </Checkbox.Label>\n </Skeleton>\n )}\n </Checkbox.Root>\n );\n});\n\nBitkitCheckbox.displayName = 'BitkitCheckbox';\n\n// The generic is what makes `labelText=\"\"` a compile error: `Exclude` cannot narrow `string` to\n// \"non-empty string\", but a conditional type on an inferred literal can. The cast carries the\n// generic through the call site, which `forwardRef`'s own signature would erase.\nexport default BitkitCheckbox as <T extends NonNullable<ReactNode>>(\n props: BitkitCheckboxProps<T> & { ref?: Ref<HTMLInputElement> },\n) => ReactElement;\n"],"mappings":";;;;;;;;;AAmCA,IAAM,iBAAiB,YAAmD,OAAO,QAAQ;CACvF,MAAM,EAAE,cAAc,WAAW,YAAY,YAAY,WAAW,OAAO,GAAG,SAAS;CACvF,MAAM,gBAAgB,CAAC,YAAY,UAAU;CAC7C,MAAM,WAAW,CAAC,YAAY,SAAS,KAAK;CAM5C,OACE,qBAAC,SAAS,MAAV;EACE,QAAQ,UAAU,aAAa,YAAY,KAAA;EAC3C,UAAU,UAAU,cAAc,UAAU;EAC5C,UAAU,UAAU;EACpB,GAAI;EAJN,UAAA;GAME,oBAAC,SAAS,aAAV;IAAsB,cAAY;IAAgB;IAAK,GAAI;GAAa,CAAA;GACxE,oBAAC,UAAD;IAAU,SAAS,UAAU;IAC3B,UAAA,oBAAC,SAAS,SAAV,EAAA,UAAmB,KAAK,YAAY,kBAAkB,oBAAC,WAAD,CAAY,CAAA,IAAI,oBAAC,WAAD,CAAY,CAAA,EAAoB,CAAA;GAC9F,CAAA;GACT,YACC,oBAAC,UAAD;IAAU,SAAS,UAAU;IAC3B,UAAA,qBAAC,SAAS,OAAV;KAAgB,IAAG;KAAnB,UAAA,CACG,WACA,iBACC,oBAAC,MAAD;MAAM,OAAM;MAAc,WAAU;MACjC,UAAA;KACG,CAAA,CAEM;;GACR,CAAA;EAEC;;AAEnB,CAAC;AAED,eAAe,cAAc"}
@@ -1,6 +1,6 @@
1
1
  import { RadioGroup } from '@chakra-ui/react/radio-group';
2
2
  import { DataAttr } from '@chakra-ui/react/styled-system';
3
- import { InputHTMLAttributes, ReactNode } from 'react';
3
+ import { InputHTMLAttributes, ReactElement, ReactNode, Ref } from 'react';
4
4
  /**
5
5
  * Passthrough attributes for the radio `<input>`. The RadioGroup machine owns the behavioral / state
6
6
  * attributes (`checked`, `value`, `name`, `type`, `disabled`, `onChange`, …), so they're excluded —
@@ -8,18 +8,30 @@ import { InputHTMLAttributes, ReactNode } from 'react';
8
8
  * things like `data-testid`.
9
9
  */
10
10
  type RadioInputProps = Omit<InputHTMLAttributes<HTMLInputElement>, 'checked' | 'defaultChecked' | 'defaultValue' | 'disabled' | 'name' | 'onChange' | 'type' | 'value'> & DataAttr;
11
- export type BitkitRadioProps = {
11
+ type BitkitRadioBaseProps = {
12
12
  badge?: 'off' | 'on';
13
- helperText?: ReactNode;
14
13
  inputProps?: RadioInputProps;
15
- labelText: ReactNode;
16
14
  state?: 'disabled' | 'skeleton';
17
15
  } & Omit<RadioGroup.ItemProps, 'disabled'>;
18
- declare const BitkitRadio: import('react').ForwardRefExoticComponent<{
19
- badge?: "off" | "on";
16
+ /**
17
+ * A radio has to end up with an accessible name, and it takes that name from its label. So either
18
+ * pass a visible `labelText`, or — for a radio in a layout with no room for one, like a table row
19
+ * selector — an `aria-label`, which is applied to the hidden input instead of being rendered.
20
+ */
21
+ export type BitkitRadioProps<T extends NonNullable<ReactNode> = NonNullable<ReactNode>> = BitkitRadioBaseProps & ({
20
22
  helperText?: ReactNode;
21
- inputProps?: RadioInputProps;
22
- labelText: ReactNode;
23
- state?: "disabled" | "skeleton";
24
- } & Omit<RadioGroup.ItemProps, "disabled"> & import('react').RefAttributes<HTMLInputElement>>;
25
- export default BitkitRadio;
23
+ /**
24
+ * The visible label, which is where the radio gets its accessible name from. It has to be
25
+ * non-empty — an empty string is a compile error. When the layout has no room for a visible
26
+ * label, pass `aria-label` instead of an empty `labelText`.
27
+ */
28
+ labelText: T extends '' ? never : T;
29
+ } | {
30
+ 'aria-label': string;
31
+ helperText?: never;
32
+ labelText?: null;
33
+ });
34
+ declare const _default: <T extends NonNullable<ReactNode>>(props: BitkitRadioProps<T> & {
35
+ ref?: Ref<HTMLInputElement>;
36
+ }) => ReactElement;
37
+ export default _default;
@@ -1,4 +1,5 @@
1
1
  import BitkitBadge from "../BitkitBadge/BitkitBadge.js";
2
+ import { isEmptyNode } from "../../utilities/isEmptyNode.js";
2
3
  import { forwardRef } from "react";
3
4
  import { jsx, jsxs } from "react/jsx-runtime";
4
5
  import { Text } from "@chakra-ui/react/text";
@@ -6,14 +7,17 @@ import { Skeleton } from "@chakra-ui/react/skeleton";
6
7
  import { RadioGroup, useRadioGroupStyles } from "@chakra-ui/react/radio-group";
7
8
  //#region lib/components/BitkitRadio/BitkitRadio.tsx
8
9
  var BitkitRadio = forwardRef((props, ref) => {
9
- const { badge, helperText, inputProps, labelText, state, ...rest } = props;
10
+ const { "aria-label": ariaLabel, badge, helperText, inputProps, labelText, state, ...rest } = props;
10
11
  const styles = useRadioGroupStyles();
12
+ const hasHelperText = !isEmptyNode(helperText);
13
+ const hasLabel = !isEmptyNode(labelText) || hasHelperText;
11
14
  return /* @__PURE__ */ jsxs(RadioGroup.Item, {
12
15
  cursor: state === "skeleton" ? "default" : void 0,
13
16
  disabled: state === "disabled" || state === "skeleton",
14
17
  ...rest,
15
18
  children: [
16
19
  /* @__PURE__ */ jsx(RadioGroup.ItemHiddenInput, {
20
+ "aria-label": ariaLabel,
17
21
  ref,
18
22
  ...inputProps
19
23
  }),
@@ -30,11 +34,11 @@ var BitkitRadio = forwardRef((props, ref) => {
30
34
  children: badge
31
35
  })
32
36
  }),
33
- /* @__PURE__ */ jsx(Skeleton, {
37
+ hasLabel && /* @__PURE__ */ jsx(Skeleton, {
34
38
  loading: state === "skeleton",
35
39
  children: /* @__PURE__ */ jsxs(RadioGroup.ItemText, {
36
40
  as: "div",
37
- children: [labelText, !!helperText && /* @__PURE__ */ jsx(Text, {
41
+ children: [labelText, hasHelperText && /* @__PURE__ */ jsx(Text, {
38
42
  color: state === "disabled" ? "text/disabled" : "text/helper",
39
43
  textStyle: "comp/input/helperText",
40
44
  children: helperText
@@ -1 +1 @@
1
- {"version":3,"file":"BitkitRadio.js","names":[],"sources":["../../../lib/components/BitkitRadio/BitkitRadio.tsx"],"sourcesContent":["import { RadioGroup, useRadioGroupStyles } from '@chakra-ui/react/radio-group';\nimport { Skeleton } from '@chakra-ui/react/skeleton';\nimport { type DataAttr } from '@chakra-ui/react/styled-system';\nimport { Text } from '@chakra-ui/react/text';\nimport { forwardRef, type InputHTMLAttributes, type ReactNode } from 'react';\n\nimport BitkitBadge from '../BitkitBadge/BitkitBadge';\n\n/**\n * Passthrough attributes for the radio `<input>`. The RadioGroup machine owns the behavioral / state\n * attributes (`checked`, `value`, `name`, `type`, `disabled`, `onChange`, …), so they're excluded —\n * setting them here would let the input drift out of sync with its `RadioGroup.Item`. Keep it to\n * things like `data-testid`.\n */\ntype RadioInputProps = Omit<\n InputHTMLAttributes<HTMLInputElement>,\n 'checked' | 'defaultChecked' | 'defaultValue' | 'disabled' | 'name' | 'onChange' | 'type' | 'value'\n> &\n DataAttr;\n\nexport type BitkitRadioProps = {\n badge?: 'off' | 'on';\n helperText?: ReactNode;\n inputProps?: RadioInputProps;\n labelText: ReactNode;\n state?: 'disabled' | 'skeleton';\n} & Omit<RadioGroup.ItemProps, 'disabled'>;\n\nconst BitkitRadio = forwardRef<HTMLInputElement, BitkitRadioProps>((props, ref) => {\n const { badge, helperText, inputProps, labelText, state, ...rest } = props;\n const styles = useRadioGroupStyles();\n\n // Skeleton has to set disabled to be inert: the Skeleton wrapper's own pointer-events: none never\n // stopped a click, it only moved the target to the <label>, which activates the control. The cursor\n // style prop then keeps the arrow plain — style props land outside @layer recipes, where the\n // recipe's _disabled: { cursor: 'not-allowed' } sits.\n return (\n <RadioGroup.Item\n cursor={state === 'skeleton' ? 'default' : undefined}\n disabled={state === 'disabled' || state === 'skeleton'}\n {...rest}\n >\n <RadioGroup.ItemHiddenInput ref={ref} {...inputProps} />\n <Skeleton borderRadius=\"50%\" loading={state === 'skeleton'}>\n <RadioGroup.ItemIndicator />\n </Skeleton>\n {!!badge && (\n <Skeleton loading={state === 'skeleton'}>\n <BitkitBadge colorVariant={badge === 'on' ? 'green' : 'neutral'} css={styles.badge}>\n {badge}\n </BitkitBadge>\n </Skeleton>\n )}\n <Skeleton loading={state === 'skeleton'}>\n <RadioGroup.ItemText as=\"div\">\n {labelText}\n {!!helperText && (\n <Text color={state === 'disabled' ? 'text/disabled' : 'text/helper'} textStyle=\"comp/input/helperText\">\n {helperText}\n </Text>\n )}\n </RadioGroup.ItemText>\n </Skeleton>\n </RadioGroup.Item>\n );\n});\n\nBitkitRadio.displayName = 'BitkitRadio';\n\nexport default BitkitRadio;\n"],"mappings":";;;;;;;AA4BA,IAAM,cAAc,YAAgD,OAAO,QAAQ;CACjF,MAAM,EAAE,OAAO,YAAY,YAAY,WAAW,OAAO,GAAG,SAAS;CACrE,MAAM,SAAS,oBAAoB;CAMnC,OACE,qBAAC,WAAW,MAAZ;EACE,QAAQ,UAAU,aAAa,YAAY,KAAA;EAC3C,UAAU,UAAU,cAAc,UAAU;EAC5C,GAAI;EAHN,UAAA;GAKE,oBAAC,WAAW,iBAAZ;IAAiC;IAAK,GAAI;GAAa,CAAA;GACvD,oBAAC,UAAD;IAAU,cAAa;IAAM,SAAS,UAAU;IAC9C,UAAA,oBAAC,WAAW,eAAZ,CAA2B,CAAA;GACnB,CAAA;GACT,CAAC,CAAC,SACD,oBAAC,UAAD;IAAU,SAAS,UAAU;IAC3B,UAAA,oBAAC,aAAD;KAAa,cAAc,UAAU,OAAO,UAAU;KAAW,KAAK,OAAO;KAC1E,UAAA;IACU,CAAA;GACL,CAAA;GAEZ,oBAAC,UAAD;IAAU,SAAS,UAAU;IAC3B,UAAA,qBAAC,WAAW,UAAZ;KAAqB,IAAG;KAAxB,UAAA,CACG,WACA,CAAC,CAAC,cACD,oBAAC,MAAD;MAAM,OAAO,UAAU,aAAa,kBAAkB;MAAe,WAAU;MAC5E,UAAA;KACG,CAAA,CAEW;;GACb,CAAA;EACK;;AAErB,CAAC;AAED,YAAY,cAAc"}
1
+ {"version":3,"file":"BitkitRadio.js","names":[],"sources":["../../../lib/components/BitkitRadio/BitkitRadio.tsx"],"sourcesContent":["import { RadioGroup, useRadioGroupStyles } from '@chakra-ui/react/radio-group';\nimport { Skeleton } from '@chakra-ui/react/skeleton';\nimport { type DataAttr } from '@chakra-ui/react/styled-system';\nimport { Text } from '@chakra-ui/react/text';\nimport { forwardRef, type InputHTMLAttributes, type ReactElement, type ReactNode, type Ref } from 'react';\n\nimport { isEmptyNode } from '../../utilities/isEmptyNode';\nimport BitkitBadge from '../BitkitBadge/BitkitBadge';\n\n/**\n * Passthrough attributes for the radio `<input>`. The RadioGroup machine owns the behavioral / state\n * attributes (`checked`, `value`, `name`, `type`, `disabled`, `onChange`, …), so they're excluded —\n * setting them here would let the input drift out of sync with its `RadioGroup.Item`. Keep it to\n * things like `data-testid`.\n */\ntype RadioInputProps = Omit<\n InputHTMLAttributes<HTMLInputElement>,\n 'checked' | 'defaultChecked' | 'defaultValue' | 'disabled' | 'name' | 'onChange' | 'type' | 'value'\n> &\n DataAttr;\n\ntype BitkitRadioBaseProps = {\n badge?: 'off' | 'on';\n inputProps?: RadioInputProps;\n state?: 'disabled' | 'skeleton';\n} & Omit<RadioGroup.ItemProps, 'disabled'>;\n\n/**\n * A radio has to end up with an accessible name, and it takes that name from its label. So either\n * pass a visible `labelText`, or — for a radio in a layout with no room for one, like a table row\n * selector — an `aria-label`, which is applied to the hidden input instead of being rendered.\n */\nexport type BitkitRadioProps<T extends NonNullable<ReactNode> = NonNullable<ReactNode>> = BitkitRadioBaseProps &\n (\n | {\n helperText?: ReactNode;\n /**\n * The visible label, which is where the radio gets its accessible name from. It has to be\n * non-empty — an empty string is a compile error. When the layout has no room for a visible\n * label, pass `aria-label` instead of an empty `labelText`.\n */\n labelText: T extends '' ? never : T;\n }\n | { 'aria-label': string; helperText?: never; labelText?: null }\n );\n\nconst BitkitRadio = forwardRef<HTMLInputElement, BitkitRadioProps>((props, ref) => {\n const { 'aria-label': ariaLabel, badge, helperText, inputProps, labelText, state, ...rest } = props;\n const styles = useRadioGroupStyles();\n const hasHelperText = !isEmptyNode(helperText);\n const hasLabel = !isEmptyNode(labelText) || hasHelperText;\n\n // Skeleton has to set disabled to be inert: the Skeleton wrapper's own pointer-events: none never\n // stopped a click, it only moved the target to the <label>, which activates the control. The cursor\n // style prop then keeps the arrow plain — style props land outside @layer recipes, where the\n // recipe's _disabled: { cursor: 'not-allowed' } sits.\n return (\n <RadioGroup.Item\n cursor={state === 'skeleton' ? 'default' : undefined}\n disabled={state === 'disabled' || state === 'skeleton'}\n {...rest}\n >\n <RadioGroup.ItemHiddenInput aria-label={ariaLabel} ref={ref} {...inputProps} />\n <Skeleton borderRadius=\"50%\" loading={state === 'skeleton'}>\n <RadioGroup.ItemIndicator />\n </Skeleton>\n {!!badge && (\n <Skeleton loading={state === 'skeleton'}>\n <BitkitBadge colorVariant={badge === 'on' ? 'green' : 'neutral'} css={styles.badge}>\n {badge}\n </BitkitBadge>\n </Skeleton>\n )}\n {hasLabel && (\n <Skeleton loading={state === 'skeleton'}>\n <RadioGroup.ItemText as=\"div\">\n {labelText}\n {hasHelperText && (\n <Text color={state === 'disabled' ? 'text/disabled' : 'text/helper'} textStyle=\"comp/input/helperText\">\n {helperText}\n </Text>\n )}\n </RadioGroup.ItemText>\n </Skeleton>\n )}\n </RadioGroup.Item>\n );\n});\n\nBitkitRadio.displayName = 'BitkitRadio';\n\n// The generic is what makes `labelText=\"\"` a compile error: `Exclude` cannot narrow `string` to\n// \"non-empty string\", but a conditional type on an inferred literal can. The cast carries the\n// generic through the call site, which `forwardRef`'s own signature would erase.\nexport default BitkitRadio as <T extends NonNullable<ReactNode>>(\n props: BitkitRadioProps<T> & { ref?: Ref<HTMLInputElement> },\n) => ReactElement;\n"],"mappings":";;;;;;;;AA8CA,IAAM,cAAc,YAAgD,OAAO,QAAQ;CACjF,MAAM,EAAE,cAAc,WAAW,OAAO,YAAY,YAAY,WAAW,OAAO,GAAG,SAAS;CAC9F,MAAM,SAAS,oBAAoB;CACnC,MAAM,gBAAgB,CAAC,YAAY,UAAU;CAC7C,MAAM,WAAW,CAAC,YAAY,SAAS,KAAK;CAM5C,OACE,qBAAC,WAAW,MAAZ;EACE,QAAQ,UAAU,aAAa,YAAY,KAAA;EAC3C,UAAU,UAAU,cAAc,UAAU;EAC5C,GAAI;EAHN,UAAA;GAKE,oBAAC,WAAW,iBAAZ;IAA4B,cAAY;IAAgB;IAAK,GAAI;GAAa,CAAA;GAC9E,oBAAC,UAAD;IAAU,cAAa;IAAM,SAAS,UAAU;IAC9C,UAAA,oBAAC,WAAW,eAAZ,CAA2B,CAAA;GACnB,CAAA;GACT,CAAC,CAAC,SACD,oBAAC,UAAD;IAAU,SAAS,UAAU;IAC3B,UAAA,oBAAC,aAAD;KAAa,cAAc,UAAU,OAAO,UAAU;KAAW,KAAK,OAAO;KAC1E,UAAA;IACU,CAAA;GACL,CAAA;GAEX,YACC,oBAAC,UAAD;IAAU,SAAS,UAAU;IAC3B,UAAA,qBAAC,WAAW,UAAZ;KAAqB,IAAG;KAAxB,UAAA,CACG,WACA,iBACC,oBAAC,MAAD;MAAM,OAAO,UAAU,aAAa,kBAAkB;MAAe,WAAU;MAC5E,UAAA;KACG,CAAA,CAEW;;GACb,CAAA;EAEG;;AAErB,CAAC;AAED,YAAY,cAAc"}
@@ -17,6 +17,8 @@ export type BitkitTourSecondaryAction = {
17
17
  action?: never;
18
18
  /** Renders the action as a link out. */
19
19
  href: string;
20
+ /** Opens the link in a new tab, with the matching `rel`. */
21
+ isExternal?: boolean;
20
22
  label: string;
21
23
  };
22
24
  /**
@@ -67,6 +67,7 @@ var SecondaryAction = ({ secondaryAction }) => {
67
67
  const { action, href, label } = secondaryAction;
68
68
  if (href !== void 0) return /* @__PURE__ */ jsx(BitkitButton, {
69
69
  href,
70
+ isExternal: secondaryAction.isExternal,
70
71
  size: "sm",
71
72
  variant: "tertiary",
72
73
  children: label
@@ -99,6 +100,19 @@ var BitkitTour = ({ tour }) => {
99
100
  const styles = useSlotRecipe({ key: "tour" })();
100
101
  const step = tour.step;
101
102
  const actions = step?.actions ?? [];
103
+ const { open } = tour;
104
+ const contentId = tour.getContentProps().id;
105
+ useEffect(() => {
106
+ if (!open || contentId === void 0) return;
107
+ const contentEl = document.getElementById(contentId);
108
+ if (!contentEl) return;
109
+ const takeFocus = () => {
110
+ contentEl.removeEventListener("focusin", takeFocus);
111
+ contentEl.focus();
112
+ };
113
+ contentEl.addEventListener("focusin", takeFocus);
114
+ return () => contentEl.removeEventListener("focusin", takeFocus);
115
+ }, [contentId, open]);
102
116
  return /* @__PURE__ */ jsx(Tour.Root, {
103
117
  unmountOnExit: true,
104
118
  tour,
@@ -1 +1 @@
1
- {"version":3,"file":"BitkitTour.js","names":[],"sources":["../../../lib/components/BitkitTour/BitkitTour.tsx"],"sourcesContent":["import {\n Tour as ArkTour,\n type TourStepDetails,\n useTour,\n type UseTourProps,\n type UseTourReturn,\n} from '@ark-ui/react/tour';\nimport { Box } from '@chakra-ui/react/box';\nimport { Portal } from '@chakra-ui/react/portal';\nimport { chakra, useSlotRecipe } from '@chakra-ui/react/styled-system';\nimport { type ReactNode, useCallback, useEffect } from 'react';\n\nimport BitkitButton from '../BitkitButton/BitkitButton';\nimport BitkitCloseButton from '../BitkitCloseButton/BitkitCloseButton';\n\ntype BitkitTourStepAction = NonNullable<TourStepDetails['actions']>[number];\n\n/**\n * The link-style action in the footer, e.g. `Skip tour` or `Learn more`. It either drives the tour\n * (`action`) or leaves the page (`href`) — the union makes passing both, or neither, a type error.\n */\nexport type BitkitTourSecondaryAction =\n | {\n /**\n * A tour action — `'skip'`, `'dismiss'`, `'next'`, `'prev'`, or a function that receives the\n * action map (`{ next, prev, dismiss, skip, goto }`) to do something else first.\n */\n action: NonNullable<BitkitTourStepAction['action']>;\n href?: never;\n label: string;\n }\n | {\n action?: never;\n /** Renders the action as a link out. */\n href: string;\n label: string;\n };\n\n/**\n * A single step of the tour. On top of Ark's step details it carries the three Bitkit slots —\n * `badge`, `content` and `secondaryAction`. Zag spreads the whole step object when it normalises\n * it, so these reach `tour.step` untouched. (Zag also offers a `meta` bag for this; flat fields\n * read better at the call site, at the cost of a name clash if Zag ever adds one of these.)\n *\n * Ark's step `type` is not part of this: every step is a card anchored to an element, so the hook\n * sets it. `target` is required for the same reason — Zag turns a step without one into a centred\n * dialog, which is a presentation this component doesn't have.\n */\nexport type BitkitTourStep = Omit<TourStepDetails, 'type'> & {\n /**\n * Rendered next to the title — a `BitkitBadge` in practice, e.g. `BETA` or `NEW`. Nothing about\n * the badge is fixed here beyond its placement: the element itself comes from the caller.\n */\n badge?: ReactNode;\n /** Rendered between the description and the footer — an image, a video, a table, anything. */\n content?: ReactNode;\n secondaryAction?: BitkitTourSecondaryAction;\n /** The element the step points at. */\n target: NonNullable<TourStepDetails['target']>;\n};\n\nexport interface BitkitTourOptions extends Omit<UseTourProps, 'closeOnInteractOutside' | 'onStepsChange' | 'steps'> {\n /** Refined so the callback reports the Bitkit slots too, like the rest of the api does. */\n onStepsChange?: (details: { steps: BitkitTourStep[] }) => void;\n /**\n * Drives the tour from a value the caller already has — it starts when this turns true and closes\n * when it turns false. Omit it to drive the tour with `start()` and `dismiss()` instead.\n */\n open?: boolean;\n steps: BitkitTourStep[];\n}\n/** The tour api returned by `useBitkitTour` — pass it around to control the tour from anywhere. */\nexport type BitkitTourInstance = Omit<UseTourReturn, 'addStep' | 'setSteps' | 'step' | 'updateStep'> & {\n addStep: (step: BitkitTourStep) => void;\n setSteps: (steps: BitkitTourStep[]) => void;\n /** The current step, with the Bitkit slots (`badge`, `content`, `secondaryAction`) still typed on it. */\n step: BitkitTourStep | null;\n /** Closes the tour, the same way its close button does. */\n dismiss: () => void;\n updateStep: (id: string, stepOverrides: Partial<BitkitTourStep>) => void;\n};\nexport type BitkitTourProps = {\n /** The tour instance returned by `useBitkitTour`. Start it with `tour.start()`. */\n tour: BitkitTourInstance;\n};\n\n/**\n * Creates the tour instance that drives `BitkitTour`. Takes the steps plus the tour-level options\n * (`onStepChange`, `onStatusChange`, `closeOnEscape`, `preventInteraction`, `translations`, …) and\n * returns the api used to control it: `start()`, `next()`, `prev()`, `setStep()`, `step`,\n * `stepIndex`, `totalSteps`. Closing on a click outside isn't among them — see below.\n */\nexport const useBitkitTour = (options: BitkitTourOptions): BitkitTourInstance => {\n const tour = useTour({\n // The highlight sits 8 around the target, and the card 12 from the highlight — the 8 the arrow\n // takes plus the 4 gap the design asks for. Both are measured from the highlight, since Zag\n // grows the anchor rect by `spotlightOffset` before positioning. `offset.mainAxis` replaces\n // Zag's own gutter, and Popper adds half the arrow's box on top of it: 6 + 5.65 ≈ the 12.\n spotlightOffset: { x: 8, y: 8 },\n // 4 is also Zag's current default, but the design asks for it and a third-party default is not\n // ours to rely on — the z-index contract already moved under us once between two minors.\n spotlightRadius: 4,\n ...options,\n // Not part of the options, and set after the spread so it can't be turned back on: a tour is a\n // guided flow with its own ways out — the close button, `Skip tour`, `Done` — and Zag would\n // otherwise end it on any click outside the card, losing the whole thing to a stray click on\n // the dimmed page. Escape is a deliberate keystroke rather than a stray click, so it keeps\n // closing the tour by default — and unlike this one, `closeOnEscape` stays in the options for\n // callers who want it off.\n closeOnInteractOutside: false,\n // Same reason as the cast on `Tour.Root` below: our step type isn't a supertype of Ark's, so a\n // callback taking ours doesn't match the signature Ark declares. The payload is Ark's.\n onStepsChange: options.onStepsChange as UseTourProps['onStepsChange'],\n // Zag's default is `close tour`, and this one is visible rather than screen-reader only: the\n // close button shows its own aria-label in a tooltip. The rest of Zag's translations\n // (`nextStep`, `prevStep`, `skip`) stay as they are — those only ever reach assistive tech.\n translations: { close: 'Close tour', ...options.translations },\n // `type` last: there is one presentation, so it isn't the caller's to pick.\n steps: options.steps.map((step) => ({ offset: { mainAxis: 6 }, ...step, type: 'tooltip' as const })),\n });\n\n // Zag's api can start a tour but not stop one. Its close trigger's click handler *is* the\n // machine's dismiss, so this borrows that instead of reaching into the machine. The cast says\n // what the handler is rather than manufacturing an event for it: `actionMap.dismiss` takes none.\n const dismiss = useCallback(() => {\n const closeTriggerClick = tour.getCloseTriggerProps().onClick as (() => void) | undefined;\n\n closeTriggerClick?.();\n }, [tour]);\n\n const { open } = options;\n useEffect(() => {\n if (open === undefined || open === tour.open) {\n return;\n }\n\n if (open) {\n tour.start();\n } else {\n dismiss();\n }\n // `tour` is a new object on every render, so the machine's own `open` is the dependency that\n // matters here.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [dismiss, open, tour.open]);\n\n return { ...tour, dismiss, step: tour.step as BitkitTourStep | null };\n};\n\n// The Ark parts aren't Chakra components, so they're wrapped with the `chakra()` factory to accept\n// `css`. They're deliberately NOT wrapped with `asChild`: each Ark part falls back to the current\n// step's content (title, description, progress text, action label) only when it renders its own\n// children, and `asChild` would replace those children with the wrapper element.\nconst TourBackdrop = chakra(ArkTour.Backdrop);\nconst TourSpotlight = chakra(ArkTour.Spotlight);\nconst TourPositioner = chakra(ArkTour.Positioner);\nconst TourContent = chakra(ArkTour.Content);\nconst TourArrow = chakra(ArkTour.Arrow);\nconst TourArrowTip = chakra(ArkTour.ArrowTip);\nconst TourTitle = chakra(ArkTour.Title);\nconst TourDescription = chakra(ArkTour.Description);\nconst TourControl = chakra(ArkTour.Control);\nconst TourProgressText = chakra(ArkTour.ProgressText);\n\nconst SecondaryAction = ({ secondaryAction }: { secondaryAction: BitkitTourSecondaryAction }) => {\n const { action, href, label } = secondaryAction;\n\n if (href !== undefined) {\n return (\n <BitkitButton href={href} size=\"sm\" variant=\"tertiary\">\n {label}\n </BitkitButton>\n );\n }\n\n if (!action) return null;\n\n return (\n <ArkTour.ActionTrigger asChild action={{ action, label }} aria-label={label}>\n <BitkitButton size=\"sm\" variant=\"tertiary\">\n {label}\n </BitkitButton>\n </ArkTour.ActionTrigger>\n );\n};\n\n/**\n * A guided product tour: a step card anchored to an element on the page, with a spotlight cut out\n * of the dimmed backdrop around that element.\n *\n * The steps and the tour behaviour live on the instance — create it with `useBitkitTour` and render\n * `BitkitTour` once, anywhere in the tree. Each step declares its own action buttons; the last one\n * is rendered as the primary button. A single-step tour drops the `1 of n` label, which is what\n * turns the card into the single-feature presentation.\n */\nconst BitkitTour = ({ tour }: BitkitTourProps) => {\n const recipe = useSlotRecipe({ key: 'tour' });\n const styles = recipe();\n const step = tour.step;\n const actions = step?.actions ?? [];\n\n return (\n // `unmountOnExit` isn't only tidiness: Ark's backdrop applies `hidden: !tour.step?.backdrop`\n // after merging the presence props, which overrides the presence's own `hidden` — and since the\n // step is kept after the tour closes, the dimming would stay on screen for good. Unmounting on\n // exit takes the node out before that can happen.\n // The cast is the price of refining `step` and the step-mutating methods on the instance: our\n // step type isn't a supertype of Ark's, so the methods no longer match its api signature. The\n // object is Ark's api — only the types are ours.\n <ArkTour.Root unmountOnExit tour={tour as UseTourReturn}>\n <Portal>\n <TourBackdrop css={styles.backdrop} />\n <TourSpotlight css={styles.spotlight} />\n <TourPositioner css={styles.positioner}>\n <TourContent css={styles.content}>\n {/* `hidden={false}` overrides Zag, which hides the arrow until the card has been\n positioned — while Popper computes that position from the arrow's `clientHeight`, so\n a hidden arrow measures 0 and the card lands 6 short of the design's 12, then drops\n by that 6 as soon as anything recomputes. Nothing shows in the meantime: until it is\n positioned the card itself sits off-screen at `-100vh`. */}\n <TourArrow css={styles.arrow} hidden={false}>\n <TourArrowTip css={styles.arrowTip} />\n </TourArrow>\n <Box css={styles.header}>\n <Box css={styles.titleGroup}>\n {tour.totalSteps > 1 ? <TourProgressText css={styles.progressText} /> : null}\n <Box css={styles.titleRow}>\n <TourTitle css={styles.title} />\n {step?.badge ? <Box css={styles.badge}>{step.badge}</Box> : null}\n </Box>\n </Box>\n <ArkTour.CloseTrigger asChild>\n <BitkitCloseButton css={styles.closeTrigger} size=\"xs\" />\n </ArkTour.CloseTrigger>\n </Box>\n <TourDescription css={styles.description} />\n {step?.content ? <Box css={styles.media}>{step.content}</Box> : null}\n <TourControl css={styles.control}>\n {step?.secondaryAction ? <SecondaryAction secondaryAction={step.secondaryAction} /> : null}\n <Box css={styles.actions}>\n {actions.map((action, index) => (\n // Zag labels the trigger from its own translations (`close tour`, `next step`),\n // which would override the visible text as the accessible name — and put two\n // `Close tour` buttons on a card whose dismiss action reads `Got it`.\n <ArkTour.ActionTrigger key={action.label} asChild action={action} aria-label={action.label}>\n <BitkitButton size=\"sm\" variant={index === actions.length - 1 ? 'primary' : 'secondary'}>\n {action.label}\n </BitkitButton>\n </ArkTour.ActionTrigger>\n ))}\n </Box>\n </TourControl>\n </TourContent>\n </TourPositioner>\n </Portal>\n </ArkTour.Root>\n );\n};\n\nBitkitTour.displayName = 'BitkitTour';\n\nexport default BitkitTour;\n"],"mappings":"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"}
1
+ {"version":3,"file":"BitkitTour.js","names":[],"sources":["../../../lib/components/BitkitTour/BitkitTour.tsx"],"sourcesContent":["import {\n Tour as ArkTour,\n type TourStepDetails,\n useTour,\n type UseTourProps,\n type UseTourReturn,\n} from '@ark-ui/react/tour';\nimport { Box } from '@chakra-ui/react/box';\nimport { Portal } from '@chakra-ui/react/portal';\nimport { chakra, useSlotRecipe } from '@chakra-ui/react/styled-system';\nimport { type ReactNode, useCallback, useEffect } from 'react';\n\nimport BitkitButton from '../BitkitButton/BitkitButton';\nimport BitkitCloseButton from '../BitkitCloseButton/BitkitCloseButton';\n\ntype BitkitTourStepAction = NonNullable<TourStepDetails['actions']>[number];\n\n/**\n * The link-style action in the footer, e.g. `Skip tour` or `Learn more`. It either drives the tour\n * (`action`) or leaves the page (`href`) — the union makes passing both, or neither, a type error.\n */\nexport type BitkitTourSecondaryAction =\n | {\n /**\n * A tour action — `'skip'`, `'dismiss'`, `'next'`, `'prev'`, or a function that receives the\n * action map (`{ next, prev, dismiss, skip, goto }`) to do something else first.\n */\n action: NonNullable<BitkitTourStepAction['action']>;\n href?: never;\n label: string;\n }\n | {\n action?: never;\n /** Renders the action as a link out. */\n href: string;\n /** Opens the link in a new tab, with the matching `rel`. */\n isExternal?: boolean;\n label: string;\n };\n\n/**\n * A single step of the tour. On top of Ark's step details it carries the three Bitkit slots —\n * `badge`, `content` and `secondaryAction`. Zag spreads the whole step object when it normalises\n * it, so these reach `tour.step` untouched. (Zag also offers a `meta` bag for this; flat fields\n * read better at the call site, at the cost of a name clash if Zag ever adds one of these.)\n *\n * Ark's step `type` is not part of this: every step is a card anchored to an element, so the hook\n * sets it. `target` is required for the same reason — Zag turns a step without one into a centred\n * dialog, which is a presentation this component doesn't have.\n */\nexport type BitkitTourStep = Omit<TourStepDetails, 'type'> & {\n /**\n * Rendered next to the title — a `BitkitBadge` in practice, e.g. `BETA` or `NEW`. Nothing about\n * the badge is fixed here beyond its placement: the element itself comes from the caller.\n */\n badge?: ReactNode;\n /** Rendered between the description and the footer — an image, a video, a table, anything. */\n content?: ReactNode;\n secondaryAction?: BitkitTourSecondaryAction;\n /** The element the step points at. */\n target: NonNullable<TourStepDetails['target']>;\n};\n\nexport interface BitkitTourOptions extends Omit<UseTourProps, 'closeOnInteractOutside' | 'onStepsChange' | 'steps'> {\n /** Refined so the callback reports the Bitkit slots too, like the rest of the api does. */\n onStepsChange?: (details: { steps: BitkitTourStep[] }) => void;\n /**\n * Drives the tour from a value the caller already has — it starts when this turns true and closes\n * when it turns false. Omit it to drive the tour with `start()` and `dismiss()` instead.\n */\n open?: boolean;\n steps: BitkitTourStep[];\n}\n/** The tour api returned by `useBitkitTour` — pass it around to control the tour from anywhere. */\nexport type BitkitTourInstance = Omit<UseTourReturn, 'addStep' | 'setSteps' | 'step' | 'updateStep'> & {\n addStep: (step: BitkitTourStep) => void;\n setSteps: (steps: BitkitTourStep[]) => void;\n /** The current step, with the Bitkit slots (`badge`, `content`, `secondaryAction`) still typed on it. */\n step: BitkitTourStep | null;\n /** Closes the tour, the same way its close button does. */\n dismiss: () => void;\n updateStep: (id: string, stepOverrides: Partial<BitkitTourStep>) => void;\n};\nexport type BitkitTourProps = {\n /** The tour instance returned by `useBitkitTour`. Start it with `tour.start()`. */\n tour: BitkitTourInstance;\n};\n\n/**\n * Creates the tour instance that drives `BitkitTour`. Takes the steps plus the tour-level options\n * (`onStepChange`, `onStatusChange`, `closeOnEscape`, `preventInteraction`, `translations`, …) and\n * returns the api used to control it: `start()`, `next()`, `prev()`, `setStep()`, `step`,\n * `stepIndex`, `totalSteps`. Closing on a click outside isn't among them — see below.\n */\nexport const useBitkitTour = (options: BitkitTourOptions): BitkitTourInstance => {\n const tour = useTour({\n // The highlight sits 8 around the target, and the card 12 from the highlight — the 8 the arrow\n // takes plus the 4 gap the design asks for. Both are measured from the highlight, since Zag\n // grows the anchor rect by `spotlightOffset` before positioning. `offset.mainAxis` replaces\n // Zag's own gutter, and Popper adds half the arrow's box on top of it: 6 + 5.65 ≈ the 12.\n spotlightOffset: { x: 8, y: 8 },\n // 4 is also Zag's current default, but the design asks for it and a third-party default is not\n // ours to rely on — the z-index contract already moved under us once between two minors.\n spotlightRadius: 4,\n ...options,\n // Not part of the options, and set after the spread so it can't be turned back on: a tour is a\n // guided flow with its own ways out — the close button, `Skip tour`, `Done` — and Zag would\n // otherwise end it on any click outside the card, losing the whole thing to a stray click on\n // the dimmed page. Escape is a deliberate keystroke rather than a stray click, so it keeps\n // closing the tour by default — and unlike this one, `closeOnEscape` stays in the options for\n // callers who want it off.\n closeOnInteractOutside: false,\n // Same reason as the cast on `Tour.Root` below: our step type isn't a supertype of Ark's, so a\n // callback taking ours doesn't match the signature Ark declares. The payload is Ark's.\n onStepsChange: options.onStepsChange as UseTourProps['onStepsChange'],\n // Zag's default is `close tour`, and this one is visible rather than screen-reader only: the\n // close button shows its own aria-label in a tooltip. The rest of Zag's translations\n // (`nextStep`, `prevStep`, `skip`) stay as they are — those only ever reach assistive tech.\n translations: { close: 'Close tour', ...options.translations },\n // `type` last: there is one presentation, so it isn't the caller's to pick.\n steps: options.steps.map((step) => ({ offset: { mainAxis: 6 }, ...step, type: 'tooltip' as const })),\n });\n\n // Zag's api can start a tour but not stop one. Its close trigger's click handler *is* the\n // machine's dismiss, so this borrows that instead of reaching into the machine. The cast says\n // what the handler is rather than manufacturing an event for it: `actionMap.dismiss` takes none.\n const dismiss = useCallback(() => {\n const closeTriggerClick = tour.getCloseTriggerProps().onClick as (() => void) | undefined;\n\n closeTriggerClick?.();\n }, [tour]);\n\n const { open } = options;\n useEffect(() => {\n if (open === undefined || open === tour.open) {\n return;\n }\n\n if (open) {\n tour.start();\n } else {\n dismiss();\n }\n // `tour` is a new object on every render, so the machine's own `open` is the dependency that\n // matters here.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [dismiss, open, tour.open]);\n\n return { ...tour, dismiss, step: tour.step as BitkitTourStep | null };\n};\n\n// The Ark parts aren't Chakra components, so they're wrapped with the `chakra()` factory to accept\n// `css`. They're deliberately NOT wrapped with `asChild`: each Ark part falls back to the current\n// step's content (title, description, progress text, action label) only when it renders its own\n// children, and `asChild` would replace those children with the wrapper element.\nconst TourBackdrop = chakra(ArkTour.Backdrop);\nconst TourSpotlight = chakra(ArkTour.Spotlight);\nconst TourPositioner = chakra(ArkTour.Positioner);\nconst TourContent = chakra(ArkTour.Content);\nconst TourArrow = chakra(ArkTour.Arrow);\nconst TourArrowTip = chakra(ArkTour.ArrowTip);\nconst TourTitle = chakra(ArkTour.Title);\nconst TourDescription = chakra(ArkTour.Description);\nconst TourControl = chakra(ArkTour.Control);\nconst TourProgressText = chakra(ArkTour.ProgressText);\n\nconst SecondaryAction = ({ secondaryAction }: { secondaryAction: BitkitTourSecondaryAction }) => {\n const { action, href, label } = secondaryAction;\n\n if (href !== undefined) {\n return (\n <BitkitButton href={href} isExternal={secondaryAction.isExternal} size=\"sm\" variant=\"tertiary\">\n {label}\n </BitkitButton>\n );\n }\n\n if (!action) return null;\n\n return (\n <ArkTour.ActionTrigger asChild action={{ action, label }} aria-label={label}>\n <BitkitButton size=\"sm\" variant=\"tertiary\">\n {label}\n </BitkitButton>\n </ArkTour.ActionTrigger>\n );\n};\n\n/**\n * A guided product tour: a step card anchored to an element on the page, with a spotlight cut out\n * of the dimmed backdrop around that element.\n *\n * The steps and the tour behaviour live on the instance — create it with `useBitkitTour` and render\n * `BitkitTour` once, anywhere in the tree. Each step declares its own action buttons; the last one\n * is rendered as the primary button. A single-step tour drops the `1 of n` label, which is what\n * turns the card into the single-feature presentation.\n */\nconst BitkitTour = ({ tour }: BitkitTourProps) => {\n const recipe = useSlotRecipe({ key: 'tour' });\n const styles = recipe();\n const step = tour.step;\n const actions = step?.actions ?? [];\n\n // Zag traps focus with fixed options, so it lands on the card's first tabbable — the close button,\n // which means a screen reader opens the tour on `Close tour` instead of on what the step says. The\n // card is what should take it: Zag gives the content `role=\"alertdialog\"`, `tabIndex: -1` and the\n // `aria-labelledby`/`aria-describedby` pair exactly so it can be focused and read out. Measured\n // alternatives that don't work: making the card tabbable (the trap picks a descendant either way)\n // and a ref (it doesn't survive the `chakra()`-wrapped Ark part). This corrects the trap's choice\n // instead of trying to beat it — the trap activates asynchronously too, and racing it with a frame\n // loses whenever the first paint is slow. The listener takes the first focus that lands anywhere\n // in the card, moves it to the card itself and then steps out of the way, so everything after it\n // (Tab, the buttons, a click) behaves normally. It arms on open and not per step, so stepping on\n // keeps the focus on the button that did it, rather than pulling the next keystroke back to the\n // card. The lookup goes through the machine's own content id, so two mounted tours can't reach\n // each other's card.\n //\n // The tour machine is the one Zag component that can't be told where to put focus: `dialog` takes\n // an `initialFocusEl` and hands it to the same trap, and even defaults an `alertdialog` to its\n // close trigger deliberately. Once the tour has that prop too, this effect goes away.\n const { open } = tour;\n const contentId = tour.getContentProps().id;\n useEffect(() => {\n if (!open || contentId === undefined) {\n return undefined;\n }\n\n const contentEl = document.getElementById(contentId);\n if (!contentEl) {\n return undefined;\n }\n\n const takeFocus = () => {\n contentEl.removeEventListener('focusin', takeFocus);\n contentEl.focus();\n };\n\n contentEl.addEventListener('focusin', takeFocus);\n\n return () => contentEl.removeEventListener('focusin', takeFocus);\n }, [contentId, open]);\n\n return (\n // `unmountOnExit` isn't only tidiness: Ark's backdrop applies `hidden: !tour.step?.backdrop`\n // after merging the presence props, which overrides the presence's own `hidden` — and since the\n // step is kept after the tour closes, the dimming would stay on screen for good. Unmounting on\n // exit takes the node out before that can happen.\n // The cast is the price of refining `step` and the step-mutating methods on the instance: our\n // step type isn't a supertype of Ark's, so the methods no longer match its api signature. The\n // object is Ark's api — only the types are ours.\n <ArkTour.Root unmountOnExit tour={tour as UseTourReturn}>\n <Portal>\n <TourBackdrop css={styles.backdrop} />\n <TourSpotlight css={styles.spotlight} />\n <TourPositioner css={styles.positioner}>\n <TourContent css={styles.content}>\n {/* `hidden={false}` overrides Zag, which hides the arrow until the card has been\n positioned — while Popper computes that position from the arrow's `clientHeight`, so\n a hidden arrow measures 0 and the card lands 6 short of the design's 12, then drops\n by that 6 as soon as anything recomputes. Nothing shows in the meantime: until it is\n positioned the card itself sits off-screen at `-100vh`. */}\n <TourArrow css={styles.arrow} hidden={false}>\n <TourArrowTip css={styles.arrowTip} />\n </TourArrow>\n <Box css={styles.header}>\n <Box css={styles.titleGroup}>\n {tour.totalSteps > 1 ? <TourProgressText css={styles.progressText} /> : null}\n <Box css={styles.titleRow}>\n <TourTitle css={styles.title} />\n {step?.badge ? <Box css={styles.badge}>{step.badge}</Box> : null}\n </Box>\n </Box>\n <ArkTour.CloseTrigger asChild>\n <BitkitCloseButton css={styles.closeTrigger} size=\"xs\" />\n </ArkTour.CloseTrigger>\n </Box>\n <TourDescription css={styles.description} />\n {step?.content ? <Box css={styles.media}>{step.content}</Box> : null}\n <TourControl css={styles.control}>\n {step?.secondaryAction ? <SecondaryAction secondaryAction={step.secondaryAction} /> : null}\n <Box css={styles.actions}>\n {actions.map((action, index) => (\n // Zag labels the trigger from its own translations (`close tour`, `next step`),\n // which would override the visible text as the accessible name — and put two\n // `Close tour` buttons on a card whose dismiss action reads `Got it`.\n <ArkTour.ActionTrigger key={action.label} asChild action={action} aria-label={action.label}>\n <BitkitButton size=\"sm\" variant={index === actions.length - 1 ? 'primary' : 'secondary'}>\n {action.label}\n </BitkitButton>\n </ArkTour.ActionTrigger>\n ))}\n </Box>\n </TourControl>\n </TourContent>\n </TourPositioner>\n </Portal>\n </ArkTour.Root>\n );\n};\n\nBitkitTour.displayName = 'BitkitTour';\n\nexport default BitkitTour;\n"],"mappings":"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"}
@@ -56,7 +56,6 @@ export { default as BitkitProgressBar, type BitkitProgressBarProps, type BitkitP
56
56
  export { default as BitkitPromoBanner, type BitkitPromoBannerProps } from './BitkitPromoBanner/BitkitPromoBanner';
57
57
  export { default as BitkitRadio, type BitkitRadioProps } from './BitkitRadio/BitkitRadio';
58
58
  export { default as BitkitRadioGroup, type BitkitRadioGroupProps } from './BitkitRadioGroup/BitkitRadioGroup';
59
- export { default as BitkitRadioItem, type BitkitRadioItemProps } from './BitkitRadioItem/BitkitRadioItem';
60
59
  export { default as BitkitRibbon, type BitkitRibbonProps } from './BitkitRibbon/BitkitRibbon';
61
60
  export { default as BitkitSearchInput, type BitkitSearchInputProps } from './BitkitSearchInput/BitkitSearchInput';
62
61
  export { default as BitkitSectionHeading, type BitkitSectionHeadingProps, } from './BitkitSectionHeading/BitkitSectionHeading';
package/dist/main.js CHANGED
@@ -346,7 +346,6 @@ import BitkitProgressBar from "./components/BitkitProgressBar/BitkitProgressBar.
346
346
  import BitkitPromoBanner from "./components/BitkitPromoBanner/BitkitPromoBanner.js";
347
347
  import BitkitRadio from "./components/BitkitRadio/BitkitRadio.js";
348
348
  import BitkitRadioGroup from "./components/BitkitRadioGroup/BitkitRadioGroup.js";
349
- import BitkitRadioItem from "./components/BitkitRadioItem/BitkitRadioItem.js";
350
349
  import BitkitRibbon from "./components/BitkitRibbon/BitkitRibbon.js";
351
350
  import BitkitTextInput from "./components/BitkitTextInput/BitkitTextInput.js";
352
351
  import BitkitSearchInput from "./components/BitkitSearchInput/BitkitSearchInput.js";
@@ -374,4 +373,4 @@ import BitkitTreeView, { createTreeCollection } from "./components/BitkitTreeVie
374
373
  import useResponsive, { ResponsiveProvider } from "./hooks/useResponsive.js";
375
374
  import bitkitTheme from "./theme/index.js";
376
375
  import Provider from "./providers/BitkitProvider.js";
377
- export { BitkitAccordion, BitkitActionBar, BitkitActionMenu, BitkitAlert, BitkitAvatar, BitkitBadge, BitkitBreadcrumb, BitkitButton, BitkitCalendar, BitkitCheckbox, BitkitCheckboxGroup, BitkitCloseButton, BitkitCodeSnippet, BitkitCollapsible, BitkitColorButton, BitkitCombobox_default as BitkitCombobox, BitkitControlButton, BitkitDataWidget, BitkitDatePicker, BitkitDefinitionTooltip, BitkitDialog_default as BitkitDialog, BitkitDraggableCard, BitkitDrawer, BitkitEmptyState, BitkitExpandableCard, BitkitExpandableRow, BitkitField, BitkitFileInput, BitkitFormDialog_default as BitkitFormDialog, BitkitGroupHeading, BitkitHeading, BitkitIconButton, BitkitInlineLoading, BitkitLabel, BitkitLabelTooltip, BitkitLabeledData, BitkitLightbox, BitkitLink, BitkitLinkButton, BitkitList_default as BitkitList, BitkitMarkdown, BitkitMarkdownCard, BitkitMultiselect_default as BitkitMultiselect, BitkitMultiselectMenu, BitkitNativeSelect, BitkitNoteCard, BitkitNumberInput, BitkitOverflowContent, BitkitOverflowTooltip, BitkitPageFooter_default as BitkitPageFooter, BitkitPagination, BitkitPaginationLoadMore, BitkitPopover, BitkitProgressBar, BitkitPromoBanner, Provider as BitkitProvider, BitkitRadio, BitkitRadioGroup, BitkitRadioItem, BitkitRibbon, BitkitSearchInput, BitkitSectionHeading, BitkitSegmentedControl_default as BitkitSegmentedControl, BitkitSelect_default as BitkitSelect, BitkitSelectMenu, BitkitSelectMenuAction, BitkitSelectableTag_default as BitkitSelectableTag, BitkitSettingsCard_default as BitkitSettingsCard, BitkitSidebar_default as BitkitSidebar, BitkitSkeletonGroup, BitkitSortableColumnHeader, BitkitSpinner, BitkitSplitButton_default as BitkitSplitButton, BitkitStat, BitkitStepperDialog_default as BitkitStepperDialog, BitkitSteps_default as BitkitSteps, BitkitStepsCard_default as BitkitStepsCard, BitkitSwitch, BitkitTabs, BitkitTag, BitkitTagsInput, BitkitTextArea, BitkitTextInput, BitkitToggleButton, BitkitTooltip, BitkitTour, BitkitTreeView, IconAbortCircle, IconAbortCircleFilled, IconAddons, IconAgent, IconAnchor, IconAndroid, IconApp, IconAppSettings, IconAppStore, IconAppStoreColor, IconApple, IconArchive, IconArchiveDelete, IconArchiveRestore, IconArrowBackAndDown, IconArrowBackAndUp, IconArrowDown, IconArrowForwardAndDown, IconArrowForwardAndUp, IconArrowLeft, IconArrowNortheast, IconArrowNorthwest, IconArrowRight, IconArrowUp, IconArrowsHorizontal, IconArrowsVertical, IconAutomation, IconAws, IconAwsColor, IconBadge3RdParty, IconBadgeBitrise, IconBadgeUpgrade, IconBadgeVersionOk, IconBazel, IconBell, IconBitbot, IconBitbotError, IconBitbucket, IconBitbucketColor, IconBitbucketNeutral, IconBitbucketWhite, IconBlockCircle, IconBook, IconBoxArrowDown, IconBoxDot, IconBoxLinesOverflow, IconBoxLinesWrap, IconBranch, IconBrowserstackColor, IconBug, IconBuild, IconBuildCache, IconBuildCacheFilled, IconBuildEnvSetup, IconBuildHub, IconBuildHubFilled, IconCalendar, IconChangePlan, IconChat, IconCheck, IconCheckCircle, IconCheckCircleFilled, IconChevronDown, IconChevronLeft, IconChevronRight, IconChevronUp, IconCi, IconCiFilled, IconCircle, IconCircleDashed, IconCircleHalfFilled, IconClaude, IconClaudeColor, IconClock, IconCode, IconCodePush, IconCodeSigning, IconCoffee, IconCommit, IconConfigure, IconConnectedAccounts, IconContainer, IconCopy, IconCordova, IconCpu, IconCreditcard, IconCredits, IconCross, IconCrossCircle, IconCrossCircleFilled, IconCrown, IconCycle, IconDashboard, IconDashboardFilled, IconDeployment, IconDetails, IconDoc, IconDollar, IconDot, IconDotnet, IconDotnetColor, IconDotnetText, IconDotnetTextColor, IconDoubleCircle, IconDownload, IconDragHandle, IconEc2Ami, IconEnterprise, IconErrorCircle, IconErrorCircleFilled, IconExpand, IconExtraBuildCapacity, IconEye, IconEyeSlash, IconFastlane, IconFileDoc, IconFilePdf, IconFilePlist, IconFileYml, IconFileZip, IconFilter, IconFlag, IconFlutter, IconFolder, IconFullscreen, IconFullscreenExit, IconGauge, IconGit, IconGithub, IconGitlab, IconGitlabColor, IconGitlabWhite, IconGlobe, IconGo, IconGoogleColor, IconGooglePlay, IconGooglePlayColor, IconGradle, IconGroup, IconHashtag, IconHeadset, IconHeart, IconHistory, IconHourglass, IconImage, IconInfoCircle, IconInfoCircleFilled, IconInsights, IconInsightsFilled, IconInstall, IconInteraction, IconInvoice, IconIonic, IconJapanese, IconJava, IconJavaColor, IconJavaDuke, IconJavaDukeColor, IconKey, IconKotlin, IconKotlinColor, IconKotlinWhite, IconLaptop, IconLaunchdarkly, IconLegacyApp, IconLightbulb, IconLink, IconLinux, IconLock, IconLockOpen, IconLogin, IconLogout, IconMacos, IconMagicWand, IconMagnifier, IconMail, IconMedal, IconMemory, IconMenuGrid, IconMenuHamburger, IconMessage, IconMessageAlert, IconMessageQuestion, IconMicrophone, IconMinus, IconMinusCircle, IconMinusCircleFilled, IconMobile, IconMobileLandscape, IconMonitorChart, IconMoreHorizontal, IconMoreVertical, IconNews, IconNextjs, IconNodejs, IconOpenInNew, IconOther, IconOutsideContributor, IconOverview, IconPause, IconPencil, IconPeople, IconPercent, IconPerson, IconPersonWithDesk, IconPlay, IconPlus, IconPlusCircle, IconPlusCircleFilled, IconPower, IconProject, IconProjectSettings, IconPull, IconPush, IconPuzzle, IconPython, IconPythonColor, IconQuestionCircle, IconQuestionCircleFilled, IconReact, IconRefresh, IconRegex, IconRelease, IconReleaseFilled, IconRemoteAccess, IconReplace, IconResponsiveness, IconReviewerApproved, IconReviewerAssigned, IconReviewerRejected, IconRuby, IconRubyColor, IconSave, IconSecurityShield, IconSettings, IconSettingsFilled, IconShuffle, IconSiren, IconSkip, IconSkipCircle, IconSkipCircleFilled, IconSlack, IconSlackColor, IconSparkle, IconSparkleFilled, IconSpinnerOnDisabled, IconSpinnerPurple, IconSpinnerPurpleDouble, IconSpinnerWhite, IconStability, IconStack, IconStar, IconStep, IconStop, IconStopwatch, IconTag, IconTasks, IconTeams, IconTeamsColor, IconTemplateCode, IconTerminal, IconTestQuarantine, IconThemeDarkToggle, IconThumbDown, IconThumbUp, IconTools, IconTrash, IconTrigger, IconUbuntu, IconUbuntuColor, IconUnity3D, IconUpload, IconValidateShield, IconVideo, IconWarning, IconWarningYellow, IconWebUi, IconWebhooks, IconWorkflow, IconWorkflowFlow, IconXTwitter, IconXamarin, IconXcode, ResponsiveProvider, bitkitIcon, bitkitTheme as bitriseTheme, createBitkitToast, createTreeCollection, dismissBitkitToast, rem, useBitkitTour, useResponsive, useStepperDialog };
376
+ export { BitkitAccordion, BitkitActionBar, BitkitActionMenu, BitkitAlert, BitkitAvatar, BitkitBadge, BitkitBreadcrumb, BitkitButton, BitkitCalendar, BitkitCheckbox, BitkitCheckboxGroup, BitkitCloseButton, BitkitCodeSnippet, BitkitCollapsible, BitkitColorButton, BitkitCombobox_default as BitkitCombobox, BitkitControlButton, BitkitDataWidget, BitkitDatePicker, BitkitDefinitionTooltip, BitkitDialog_default as BitkitDialog, BitkitDraggableCard, BitkitDrawer, BitkitEmptyState, BitkitExpandableCard, BitkitExpandableRow, BitkitField, BitkitFileInput, BitkitFormDialog_default as BitkitFormDialog, BitkitGroupHeading, BitkitHeading, BitkitIconButton, BitkitInlineLoading, BitkitLabel, BitkitLabelTooltip, BitkitLabeledData, BitkitLightbox, BitkitLink, BitkitLinkButton, BitkitList_default as BitkitList, BitkitMarkdown, BitkitMarkdownCard, BitkitMultiselect_default as BitkitMultiselect, BitkitMultiselectMenu, BitkitNativeSelect, BitkitNoteCard, BitkitNumberInput, BitkitOverflowContent, BitkitOverflowTooltip, BitkitPageFooter_default as BitkitPageFooter, BitkitPagination, BitkitPaginationLoadMore, BitkitPopover, BitkitProgressBar, BitkitPromoBanner, Provider as BitkitProvider, BitkitRadio, BitkitRadioGroup, BitkitRibbon, BitkitSearchInput, BitkitSectionHeading, BitkitSegmentedControl_default as BitkitSegmentedControl, BitkitSelect_default as BitkitSelect, BitkitSelectMenu, BitkitSelectMenuAction, BitkitSelectableTag_default as BitkitSelectableTag, BitkitSettingsCard_default as BitkitSettingsCard, BitkitSidebar_default as BitkitSidebar, BitkitSkeletonGroup, BitkitSortableColumnHeader, BitkitSpinner, BitkitSplitButton_default as BitkitSplitButton, BitkitStat, BitkitStepperDialog_default as BitkitStepperDialog, BitkitSteps_default as BitkitSteps, BitkitStepsCard_default as BitkitStepsCard, BitkitSwitch, BitkitTabs, BitkitTag, BitkitTagsInput, BitkitTextArea, BitkitTextInput, BitkitToggleButton, BitkitTooltip, BitkitTour, BitkitTreeView, IconAbortCircle, IconAbortCircleFilled, IconAddons, IconAgent, IconAnchor, IconAndroid, IconApp, IconAppSettings, IconAppStore, IconAppStoreColor, IconApple, IconArchive, IconArchiveDelete, IconArchiveRestore, IconArrowBackAndDown, IconArrowBackAndUp, IconArrowDown, IconArrowForwardAndDown, IconArrowForwardAndUp, IconArrowLeft, IconArrowNortheast, IconArrowNorthwest, IconArrowRight, IconArrowUp, IconArrowsHorizontal, IconArrowsVertical, IconAutomation, IconAws, IconAwsColor, IconBadge3RdParty, IconBadgeBitrise, IconBadgeUpgrade, IconBadgeVersionOk, IconBazel, IconBell, IconBitbot, IconBitbotError, IconBitbucket, IconBitbucketColor, IconBitbucketNeutral, IconBitbucketWhite, IconBlockCircle, IconBook, IconBoxArrowDown, IconBoxDot, IconBoxLinesOverflow, IconBoxLinesWrap, IconBranch, IconBrowserstackColor, IconBug, IconBuild, IconBuildCache, IconBuildCacheFilled, IconBuildEnvSetup, IconBuildHub, IconBuildHubFilled, IconCalendar, IconChangePlan, IconChat, IconCheck, IconCheckCircle, IconCheckCircleFilled, IconChevronDown, IconChevronLeft, IconChevronRight, IconChevronUp, IconCi, IconCiFilled, IconCircle, IconCircleDashed, IconCircleHalfFilled, IconClaude, IconClaudeColor, IconClock, IconCode, IconCodePush, IconCodeSigning, IconCoffee, IconCommit, IconConfigure, IconConnectedAccounts, IconContainer, IconCopy, IconCordova, IconCpu, IconCreditcard, IconCredits, IconCross, IconCrossCircle, IconCrossCircleFilled, IconCrown, IconCycle, IconDashboard, IconDashboardFilled, IconDeployment, IconDetails, IconDoc, IconDollar, IconDot, IconDotnet, IconDotnetColor, IconDotnetText, IconDotnetTextColor, IconDoubleCircle, IconDownload, IconDragHandle, IconEc2Ami, IconEnterprise, IconErrorCircle, IconErrorCircleFilled, IconExpand, IconExtraBuildCapacity, IconEye, IconEyeSlash, IconFastlane, IconFileDoc, IconFilePdf, IconFilePlist, IconFileYml, IconFileZip, IconFilter, IconFlag, IconFlutter, IconFolder, IconFullscreen, IconFullscreenExit, IconGauge, IconGit, IconGithub, IconGitlab, IconGitlabColor, IconGitlabWhite, IconGlobe, IconGo, IconGoogleColor, IconGooglePlay, IconGooglePlayColor, IconGradle, IconGroup, IconHashtag, IconHeadset, IconHeart, IconHistory, IconHourglass, IconImage, IconInfoCircle, IconInfoCircleFilled, IconInsights, IconInsightsFilled, IconInstall, IconInteraction, IconInvoice, IconIonic, IconJapanese, IconJava, IconJavaColor, IconJavaDuke, IconJavaDukeColor, IconKey, IconKotlin, IconKotlinColor, IconKotlinWhite, IconLaptop, IconLaunchdarkly, IconLegacyApp, IconLightbulb, IconLink, IconLinux, IconLock, IconLockOpen, IconLogin, IconLogout, IconMacos, IconMagicWand, IconMagnifier, IconMail, IconMedal, IconMemory, IconMenuGrid, IconMenuHamburger, IconMessage, IconMessageAlert, IconMessageQuestion, IconMicrophone, IconMinus, IconMinusCircle, IconMinusCircleFilled, IconMobile, IconMobileLandscape, IconMonitorChart, IconMoreHorizontal, IconMoreVertical, IconNews, IconNextjs, IconNodejs, IconOpenInNew, IconOther, IconOutsideContributor, IconOverview, IconPause, IconPencil, IconPeople, IconPercent, IconPerson, IconPersonWithDesk, IconPlay, IconPlus, IconPlusCircle, IconPlusCircleFilled, IconPower, IconProject, IconProjectSettings, IconPull, IconPush, IconPuzzle, IconPython, IconPythonColor, IconQuestionCircle, IconQuestionCircleFilled, IconReact, IconRefresh, IconRegex, IconRelease, IconReleaseFilled, IconRemoteAccess, IconReplace, IconResponsiveness, IconReviewerApproved, IconReviewerAssigned, IconReviewerRejected, IconRuby, IconRubyColor, IconSave, IconSecurityShield, IconSettings, IconSettingsFilled, IconShuffle, IconSiren, IconSkip, IconSkipCircle, IconSkipCircleFilled, IconSlack, IconSlackColor, IconSparkle, IconSparkleFilled, IconSpinnerOnDisabled, IconSpinnerPurple, IconSpinnerPurpleDouble, IconSpinnerWhite, IconStability, IconStack, IconStar, IconStep, IconStop, IconStopwatch, IconTag, IconTasks, IconTeams, IconTeamsColor, IconTemplateCode, IconTerminal, IconTestQuarantine, IconThemeDarkToggle, IconThumbDown, IconThumbUp, IconTools, IconTrash, IconTrigger, IconUbuntu, IconUbuntuColor, IconUnity3D, IconUpload, IconValidateShield, IconVideo, IconWarning, IconWarningYellow, IconWebUi, IconWebhooks, IconWorkflow, IconWorkflowFlow, IconXTwitter, IconXamarin, IconXcode, ResponsiveProvider, bitkitIcon, bitkitTheme as bitriseTheme, createBitkitToast, createTreeCollection, dismissBitkitToast, rem, useBitkitTour, useResponsive, useStepperDialog };
@@ -0,0 +1,6 @@
1
+ import { ReactNode } from 'react';
2
+ /**
3
+ * True for nodes that render nothing (`null`, `undefined`, `''`, booleans, or an array of those) —
4
+ * so an "empty" slot can be left out of the DOM instead of rendering a wrapper that only adds gap.
5
+ */
6
+ export declare const isEmptyNode: (node: ReactNode) => boolean;
@@ -0,0 +1,10 @@
1
+ //#region lib/utilities/isEmptyNode.ts
2
+ /**
3
+ * True for nodes that render nothing (`null`, `undefined`, `''`, booleans, or an array of those) —
4
+ * so an "empty" slot can be left out of the DOM instead of rendering a wrapper that only adds gap.
5
+ */
6
+ var isEmptyNode = (node) => node == null || node === "" || typeof node === "boolean" || Array.isArray(node) && node.every(isEmptyNode);
7
+ //#endregion
8
+ export { isEmptyNode };
9
+
10
+ //# sourceMappingURL=isEmptyNode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"isEmptyNode.js","names":[],"sources":["../../lib/utilities/isEmptyNode.ts"],"sourcesContent":["import { type ReactNode } from 'react';\n\n/**\n * True for nodes that render nothing (`null`, `undefined`, `''`, booleans, or an array of those) —\n * so an \"empty\" slot can be left out of the DOM instead of rendering a wrapper that only adds gap.\n */\nexport const isEmptyNode = (node: ReactNode): boolean =>\n node == null || node === '' || typeof node === 'boolean' || (Array.isArray(node) && node.every(isEmptyNode));\n"],"mappings":";;;;;AAMA,IAAa,eAAe,SAC1B,QAAQ,QAAQ,SAAS,MAAM,OAAO,SAAS,aAAc,MAAM,QAAQ,IAAI,KAAK,KAAK,MAAM,WAAW"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@bitrise/bitkit-v2",
3
3
  "private": false,
4
- "version": "0.3.357",
4
+ "version": "0.3.359-beta.2314",
5
5
  "description": "Bitrise Design System Components built with Chakra UI V3",
6
6
  "keywords": [
7
7
  "react",
@@ -1,30 +0,0 @@
1
- import { RadioGroup } from '@chakra-ui/react/radio-group';
2
- import { DataAttr } from '@chakra-ui/react/styled-system';
3
- import { InputHTMLAttributes } from 'react';
4
- /**
5
- * Passthrough attributes for the radio `<input>`. The RadioGroup machine owns the behavioral / state
6
- * attributes (`checked`, `value`, `name`, `type`, `disabled`, `onChange`, …), so they're excluded —
7
- * setting them here would let the input drift out of sync with its `RadioGroup.Item`. Keep it to
8
- * things like `data-testid`.
9
- */
10
- type RadioInputProps = Omit<InputHTMLAttributes<HTMLInputElement>, 'checked' | 'defaultChecked' | 'defaultValue' | 'disabled' | 'name' | 'onChange' | 'type' | 'value'> & DataAttr;
11
- export interface BitkitRadioItemProps extends Omit<RadioGroup.ItemProps, 'children' | 'disabled'> {
12
- /** Props forwarded to the underlying radio `<input>` (e.g. `data-testid`). */
13
- inputProps?: RadioInputProps;
14
- /**
15
- * Accessible name for the radio. Not rendered — this is an icon-only control — so it's required to
16
- * keep the radio from ending up with an empty accessible name.
17
- */
18
- label: string;
19
- state?: 'disabled';
20
- }
21
- /**
22
- * An icon-only radio: the styled indicator without any label chrome. Use it to place radios inside a
23
- * custom layout — table cells, a shared CSS grid, a virtualized list — where BitkitRadioGroup's
24
- * fieldset wrapper doesn't fit. Compose it under a Chakra `RadioGroup.Root` (kept layout-neutral with
25
- * `css` / `asChild`): the grouping semantics come from that root and the Bitkit visual from the
26
- * theme, while `label` supplies the required accessible name. Reach for BitkitRadio instead whenever
27
- * a visible label fits.
28
- */
29
- declare const BitkitRadioItem: import('react').ForwardRefExoticComponent<BitkitRadioItemProps & import('react').RefAttributes<HTMLInputElement>>;
30
- export default BitkitRadioItem;
@@ -1,29 +0,0 @@
1
- import { forwardRef } from "react";
2
- import { jsx, jsxs } from "react/jsx-runtime";
3
- import { RadioGroup } from "@chakra-ui/react/radio-group";
4
- //#region lib/components/BitkitRadioItem/BitkitRadioItem.tsx
5
- /**
6
- * An icon-only radio: the styled indicator without any label chrome. Use it to place radios inside a
7
- * custom layout — table cells, a shared CSS grid, a virtualized list — where BitkitRadioGroup's
8
- * fieldset wrapper doesn't fit. Compose it under a Chakra `RadioGroup.Root` (kept layout-neutral with
9
- * `css` / `asChild`): the grouping semantics come from that root and the Bitkit visual from the
10
- * theme, while `label` supplies the required accessible name. Reach for BitkitRadio instead whenever
11
- * a visible label fits.
12
- */
13
- var BitkitRadioItem = forwardRef((props, ref) => {
14
- const { inputProps, label, state, ...rest } = props;
15
- return /* @__PURE__ */ jsxs(RadioGroup.Item, {
16
- disabled: state === "disabled",
17
- ...rest,
18
- children: [/* @__PURE__ */ jsx(RadioGroup.ItemHiddenInput, {
19
- ref,
20
- ...inputProps,
21
- "aria-label": label
22
- }), /* @__PURE__ */ jsx(RadioGroup.ItemIndicator, {})]
23
- });
24
- });
25
- BitkitRadioItem.displayName = "BitkitRadioItem";
26
- //#endregion
27
- export { BitkitRadioItem as default };
28
-
29
- //# sourceMappingURL=BitkitRadioItem.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"BitkitRadioItem.js","names":[],"sources":["../../../lib/components/BitkitRadioItem/BitkitRadioItem.tsx"],"sourcesContent":["import { RadioGroup } from '@chakra-ui/react/radio-group';\nimport { type DataAttr } from '@chakra-ui/react/styled-system';\nimport { forwardRef, type InputHTMLAttributes } from 'react';\n\n/**\n * Passthrough attributes for the radio `<input>`. The RadioGroup machine owns the behavioral / state\n * attributes (`checked`, `value`, `name`, `type`, `disabled`, `onChange`, …), so they're excluded —\n * setting them here would let the input drift out of sync with its `RadioGroup.Item`. Keep it to\n * things like `data-testid`.\n */\ntype RadioInputProps = Omit<\n InputHTMLAttributes<HTMLInputElement>,\n 'checked' | 'defaultChecked' | 'defaultValue' | 'disabled' | 'name' | 'onChange' | 'type' | 'value'\n> &\n DataAttr;\n\nexport interface BitkitRadioItemProps extends Omit<RadioGroup.ItemProps, 'children' | 'disabled'> {\n /** Props forwarded to the underlying radio `<input>` (e.g. `data-testid`). */\n inputProps?: RadioInputProps;\n /**\n * Accessible name for the radio. Not rendered — this is an icon-only control — so it's required to\n * keep the radio from ending up with an empty accessible name.\n */\n label: string;\n state?: 'disabled';\n}\n\n/**\n * An icon-only radio: the styled indicator without any label chrome. Use it to place radios inside a\n * custom layout — table cells, a shared CSS grid, a virtualized list — where BitkitRadioGroup's\n * fieldset wrapper doesn't fit. Compose it under a Chakra `RadioGroup.Root` (kept layout-neutral with\n * `css` / `asChild`): the grouping semantics come from that root and the Bitkit visual from the\n * theme, while `label` supplies the required accessible name. Reach for BitkitRadio instead whenever\n * a visible label fits.\n */\nconst BitkitRadioItem = forwardRef<HTMLInputElement, BitkitRadioItemProps>((props, ref) => {\n const { inputProps, label, state, ...rest } = props;\n\n return (\n <RadioGroup.Item disabled={state === 'disabled'} {...rest}>\n <RadioGroup.ItemHiddenInput ref={ref} {...inputProps} aria-label={label} />\n <RadioGroup.ItemIndicator />\n </RadioGroup.Item>\n );\n});\n\nBitkitRadioItem.displayName = 'BitkitRadioItem';\n\nexport default BitkitRadioItem;\n"],"mappings":";;;;;;;;;;;;AAmCA,IAAM,kBAAkB,YAAoD,OAAO,QAAQ;CACzF,MAAM,EAAE,YAAY,OAAO,OAAO,GAAG,SAAS;CAE9C,OACE,qBAAC,WAAW,MAAZ;EAAiB,UAAU,UAAU;EAAY,GAAI;EAArD,UAAA,CACE,oBAAC,WAAW,iBAAZ;GAAiC;GAAK,GAAI;GAAY,cAAY;EAAQ,CAAA,GAC1E,oBAAC,WAAW,eAAZ,CAA2B,CAAA,CACZ;;AAErB,CAAC;AAED,gBAAgB,cAAc"}