@bitrise/bitkit-v2 0.3.427 → 0.3.428
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/BitkitCollapsible/BitkitCollapsible.js +3 -3
- package/dist/components/BitkitCollapsible/BitkitCollapsible.js.map +1 -1
- package/dist/components/BitkitDataWidget/BitkitDataWidget.js +2 -2
- package/dist/components/BitkitDataWidget/BitkitDataWidget.js.map +1 -1
- package/dist/components/BitkitDraggableCard/BitkitDraggableCard.js +2 -2
- package/dist/components/BitkitDraggableCard/BitkitDraggableCard.js.map +1 -1
- package/dist/components/BitkitGroupHeading/BitkitGroupHeading.js +2 -2
- package/dist/components/BitkitGroupHeading/BitkitGroupHeading.js.map +1 -1
- package/dist/components/BitkitInlineLoading/BitkitInlineLoading.js +2 -2
- package/dist/components/BitkitInlineLoading/BitkitInlineLoading.js.map +1 -1
- package/dist/components/BitkitMarkdown/BitkitMarkdown.js +2 -2
- package/dist/components/BitkitMarkdown/BitkitMarkdown.js.map +1 -1
- package/dist/components/BitkitMarkdownCard/BitkitMarkdownCard.js +2 -2
- package/dist/components/BitkitMarkdownCard/BitkitMarkdownCard.js.map +1 -1
- package/dist/components/BitkitMultiselect/BitkitMultiselect.js +3 -2
- package/dist/components/BitkitMultiselect/BitkitMultiselect.js.map +1 -1
- package/dist/components/BitkitNoteCard/BitkitNoteCard.js +2 -2
- package/dist/components/BitkitNoteCard/BitkitNoteCard.js.map +1 -1
- package/dist/components/BitkitNumberInput/BitkitNumberInput.js +2 -2
- package/dist/components/BitkitNumberInput/BitkitNumberInput.js.map +1 -1
- package/dist/components/BitkitOverflowContent/BitkitOverflowContent.js +2 -2
- package/dist/components/BitkitOverflowContent/BitkitOverflowContent.js.map +1 -1
- package/dist/components/BitkitPageFooter/BitkitPageFooter.js +2 -2
- package/dist/components/BitkitPageFooter/BitkitPageFooter.js.map +1 -1
- package/dist/components/BitkitPageHeader/BitkitPageHeader.js +2 -2
- package/dist/components/BitkitPageHeader/BitkitPageHeader.js.map +1 -1
- package/dist/components/BitkitPageSidebar/BitkitPageSidebar.js +13 -12
- package/dist/components/BitkitPageSidebar/BitkitPageSidebar.js.map +1 -1
- package/dist/components/BitkitPagination/BitkitPagination.js +2 -2
- package/dist/components/BitkitPagination/BitkitPagination.js.map +1 -1
- package/dist/components/BitkitPaginationLoadMore/BitkitPaginationLoadMore.js +2 -2
- package/dist/components/BitkitPaginationLoadMore/BitkitPaginationLoadMore.js.map +1 -1
- package/dist/components/BitkitRibbon/BitkitRibbon.js +2 -2
- package/dist/components/BitkitRibbon/BitkitRibbon.js.map +1 -1
- package/dist/components/BitkitSectionHeading/BitkitSectionHeading.js +2 -2
- package/dist/components/BitkitSectionHeading/BitkitSectionHeading.js.map +1 -1
- package/dist/components/BitkitSelectMenu/SelectMenuShell.js +3 -2
- package/dist/components/BitkitSelectMenu/SelectMenuShell.js.map +1 -1
- package/dist/components/BitkitSettingsCard/BitkitSettingsCard.js +7 -6
- package/dist/components/BitkitSettingsCard/BitkitSettingsCard.js.map +1 -1
- package/dist/components/BitkitStepsCard/BitkitStepsCard.js +8 -8
- package/dist/components/BitkitStepsCard/BitkitStepsCard.js.map +1 -1
- package/dist/components/BitkitTable/BitkitLinkedRow.js +4 -4
- package/dist/components/BitkitTable/BitkitLinkedRow.js.map +1 -1
- package/dist/components/BitkitTable/BitkitRowActionsCell.js +2 -2
- package/dist/components/BitkitTable/BitkitRowActionsCell.js.map +1 -1
- package/dist/components/BitkitTable/BitkitSortableColumnHeader.js +2 -2
- package/dist/components/BitkitTable/BitkitSortableColumnHeader.js.map +1 -1
- package/dist/components/BitkitTableCard/BitkitTableCard.js +2 -2
- package/dist/components/BitkitTableCard/BitkitTableCard.js.map +1 -1
- package/dist/components/BitkitTabs/BitkitTabs.js +2 -2
- package/dist/components/BitkitTabs/BitkitTabs.js.map +1 -1
- package/dist/components/BitkitTextInput/BitkitTextInput.js +2 -2
- package/dist/components/BitkitTextInput/BitkitTextInput.js.map +1 -1
- package/package.json +1 -1
|
@@ -10,24 +10,24 @@ var useSettingsCardStyles = () => {
|
|
|
10
10
|
return useSlotRecipe({ key: "settingsCard" })();
|
|
11
11
|
};
|
|
12
12
|
var BitkitSettingsCard = forwardRef((props, ref) => {
|
|
13
|
-
const { children, ...rest } = props;
|
|
13
|
+
const { children, css, ...rest } = props;
|
|
14
14
|
const styles = useSettingsCardStyles();
|
|
15
15
|
return /* @__PURE__ */ jsx(Card.Root, {
|
|
16
16
|
ref,
|
|
17
17
|
elevation: false,
|
|
18
18
|
paddingSize: "md",
|
|
19
|
-
css: styles.root,
|
|
19
|
+
css: [styles.root, css],
|
|
20
20
|
...rest,
|
|
21
21
|
children
|
|
22
22
|
});
|
|
23
23
|
});
|
|
24
24
|
BitkitSettingsCard.displayName = "BitkitSettingsCard";
|
|
25
25
|
var Content = forwardRef((props, ref) => {
|
|
26
|
-
const { actions, children, ...rest } = props;
|
|
26
|
+
const { actions, children, css, ...rest } = props;
|
|
27
27
|
const styles = useSettingsCardStyles();
|
|
28
28
|
return /* @__PURE__ */ jsxs(Card.Body, {
|
|
29
29
|
ref,
|
|
30
|
-
css: styles.content,
|
|
30
|
+
css: [styles.content, css],
|
|
31
31
|
...rest,
|
|
32
32
|
children: [/* @__PURE__ */ jsx(Box, {
|
|
33
33
|
css: styles.contentBody,
|
|
@@ -69,11 +69,12 @@ var Status = forwardRef((props, ref) => {
|
|
|
69
69
|
});
|
|
70
70
|
Status.displayName = "BitkitSettingsCard.Status";
|
|
71
71
|
var Footer = forwardRef((props, ref) => {
|
|
72
|
+
const { css, ...rest } = props;
|
|
72
73
|
const styles = useSettingsCardStyles();
|
|
73
74
|
return /* @__PURE__ */ jsx(Card.Footer, {
|
|
74
75
|
ref,
|
|
75
|
-
css: styles.footer,
|
|
76
|
-
...
|
|
76
|
+
css: [styles.footer, css],
|
|
77
|
+
...rest
|
|
77
78
|
});
|
|
78
79
|
});
|
|
79
80
|
Footer.displayName = "BitkitSettingsCard.Footer";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BitkitSettingsCard.js","names":[],"sources":["../../../lib/components/BitkitSettingsCard/BitkitSettingsCard.tsx"],"sourcesContent":["import { Box, type BoxProps } from '@chakra-ui/react/box';\nimport { Card, type CardBodyProps, type CardFooterProps, type CardRootProps } from '@chakra-ui/react/card';\nimport { useSlotRecipe } from '@chakra-ui/react/styled-system';\nimport { Text } from '@chakra-ui/react/text';\nimport { forwardRef, type ReactNode } from 'react';\n\nimport { type BitkitIconComponent } from '../../icons';\nimport { withSubComponents } from '../../utilities/withSubComponents';\n\nconst useSettingsCardStyles = () => {\n const recipe = useSlotRecipe({ key: 'settingsCard' });\n return recipe();\n};\n\n// --- Root ---\n\nexport interface BitkitSettingsCardProps extends Omit<CardRootProps, 'children'> {\n children: ReactNode;\n}\n\nconst BitkitSettingsCard = forwardRef<HTMLDivElement, BitkitSettingsCardProps>((props, ref) => {\n const { children, ...rest } = props;\n const styles = useSettingsCardStyles();\n\n return (\n <Card.Root ref={ref} elevation={false} paddingSize=\"md\" css={styles.root} {...rest}>\n {children}\n </Card.Root>\n );\n});\n\nBitkitSettingsCard.displayName = 'BitkitSettingsCard';\n\n// --- Content ---\n\nexport interface BitkitSettingsCardContentProps extends Omit<CardBodyProps, 'children'> {\n actions?: ReactNode;\n children: ReactNode;\n}\n\nconst Content = forwardRef<HTMLDivElement, BitkitSettingsCardContentProps>((props, ref) => {\n const { actions, children, ...rest } = props;\n const styles = useSettingsCardStyles();\n\n return (\n <Card.Body ref={ref} css={styles.content} {...rest}>\n <Box css={styles.contentBody}>{children}</Box>\n {actions && <Box css={styles.contentActions}>{actions}</Box>}\n </Card.Body>\n );\n});\n\nContent.displayName = 'BitkitSettingsCard.Content';\n\n// --- Status ---\n\nexport interface BitkitSettingsCardStatusProps extends Omit<BoxProps, 'children' | 'colorPalette'> {\n description?: string;\n helperText?: ReactNode;\n icon: BitkitIconComponent;\n iconColor?: string;\n statusText: string;\n}\n\nconst Status = forwardRef<HTMLDivElement, BitkitSettingsCardStatusProps>((props, ref) => {\n const { description, helperText, icon: Icon, iconColor, statusText, ...rest } = props;\n const styles = useSettingsCardStyles();\n\n return (\n <Box ref={ref} role=\"status\" {...rest}>\n <Box css={styles.statusRow}>\n <Icon color={iconColor} css={styles.statusIcon} size=\"16\" />\n <Box>\n <Text as=\"strong\" css={styles.statusText}>\n {statusText}\n </Text>\n {description && (\n <Text as=\"p\" css={styles.statusDescription}>\n {description}\n </Text>\n )}\n </Box>\n </Box>\n {helperText && <Text css={styles.statusHelperText}>{helperText}</Text>}\n </Box>\n );\n});\n\nStatus.displayName = 'BitkitSettingsCard.Status';\n\n// --- Footer ---\n\nconst Footer = forwardRef<HTMLDivElement, CardFooterProps>((props, ref) => {\n const styles = useSettingsCardStyles();\n return <Card.Footer ref={ref} css={styles.footer} {...
|
|
1
|
+
{"version":3,"file":"BitkitSettingsCard.js","names":[],"sources":["../../../lib/components/BitkitSettingsCard/BitkitSettingsCard.tsx"],"sourcesContent":["import { Box, type BoxProps } from '@chakra-ui/react/box';\nimport { Card, type CardBodyProps, type CardFooterProps, type CardRootProps } from '@chakra-ui/react/card';\nimport { useSlotRecipe } from '@chakra-ui/react/styled-system';\nimport { Text } from '@chakra-ui/react/text';\nimport { forwardRef, type ReactNode } from 'react';\n\nimport { type BitkitIconComponent } from '../../icons';\nimport { withSubComponents } from '../../utilities/withSubComponents';\n\nconst useSettingsCardStyles = () => {\n const recipe = useSlotRecipe({ key: 'settingsCard' });\n return recipe();\n};\n\n// --- Root ---\n\nexport interface BitkitSettingsCardProps extends Omit<CardRootProps, 'children'> {\n children: ReactNode;\n}\n\nconst BitkitSettingsCard = forwardRef<HTMLDivElement, BitkitSettingsCardProps>((props, ref) => {\n const { children, css, ...rest } = props;\n const styles = useSettingsCardStyles();\n\n return (\n <Card.Root ref={ref} elevation={false} paddingSize=\"md\" css={[styles.root, css]} {...rest}>\n {children}\n </Card.Root>\n );\n});\n\nBitkitSettingsCard.displayName = 'BitkitSettingsCard';\n\n// --- Content ---\n\nexport interface BitkitSettingsCardContentProps extends Omit<CardBodyProps, 'children'> {\n actions?: ReactNode;\n children: ReactNode;\n}\n\nconst Content = forwardRef<HTMLDivElement, BitkitSettingsCardContentProps>((props, ref) => {\n const { actions, children, css, ...rest } = props;\n const styles = useSettingsCardStyles();\n\n return (\n <Card.Body ref={ref} css={[styles.content, css]} {...rest}>\n <Box css={styles.contentBody}>{children}</Box>\n {actions && <Box css={styles.contentActions}>{actions}</Box>}\n </Card.Body>\n );\n});\n\nContent.displayName = 'BitkitSettingsCard.Content';\n\n// --- Status ---\n\nexport interface BitkitSettingsCardStatusProps extends Omit<BoxProps, 'children' | 'colorPalette'> {\n description?: string;\n helperText?: ReactNode;\n icon: BitkitIconComponent;\n iconColor?: string;\n statusText: string;\n}\n\nconst Status = forwardRef<HTMLDivElement, BitkitSettingsCardStatusProps>((props, ref) => {\n const { description, helperText, icon: Icon, iconColor, statusText, ...rest } = props;\n const styles = useSettingsCardStyles();\n\n return (\n <Box ref={ref} role=\"status\" {...rest}>\n <Box css={styles.statusRow}>\n <Icon color={iconColor} css={styles.statusIcon} size=\"16\" />\n <Box>\n <Text as=\"strong\" css={styles.statusText}>\n {statusText}\n </Text>\n {description && (\n <Text as=\"p\" css={styles.statusDescription}>\n {description}\n </Text>\n )}\n </Box>\n </Box>\n {helperText && <Text css={styles.statusHelperText}>{helperText}</Text>}\n </Box>\n );\n});\n\nStatus.displayName = 'BitkitSettingsCard.Status';\n\n// --- Footer ---\n\nconst Footer = forwardRef<HTMLDivElement, CardFooterProps>((props, ref) => {\n const { css, ...rest } = props;\n const styles = useSettingsCardStyles();\n return <Card.Footer ref={ref} css={[styles.footer, css]} {...rest} />;\n});\n\nFooter.displayName = 'BitkitSettingsCard.Footer';\n\n// --- Compound export ---\n\nexport default withSubComponents(BitkitSettingsCard, {\n Content,\n Footer,\n Status,\n});\n"],"mappings":";;;;;;;;AASA,IAAM,8BAA8B;CAElC,OADe,cAAc,EAAE,KAAK,eAAe,CAC5C,CAAA,CAAO;AAChB;AAQA,IAAM,qBAAqB,YAAqD,OAAO,QAAQ;CAC7F,MAAM,EAAE,UAAU,KAAK,GAAG,SAAS;CACnC,MAAM,SAAS,sBAAsB;CAErC,OACE,oBAAC,KAAK,MAAN;EAAgB;EAAK,WAAW;EAAO,aAAY;EAAK,KAAK,CAAC,OAAO,MAAM,GAAG;EAAG,GAAI;EAClF;CACQ,CAAA;AAEf,CAAC;AAED,mBAAmB,cAAc;AASjC,IAAM,UAAU,YAA4D,OAAO,QAAQ;CACzF,MAAM,EAAE,SAAS,UAAU,KAAK,GAAG,SAAS;CAC5C,MAAM,SAAS,sBAAsB;CAErC,OACE,qBAAC,KAAK,MAAN;EAAgB;EAAK,KAAK,CAAC,OAAO,SAAS,GAAG;EAAG,GAAI;EAArD,UAAA,CACE,oBAAC,KAAD;GAAK,KAAK,OAAO;GAAc;EAAc,CAAA,GAC5C,WAAW,oBAAC,KAAD;GAAK,KAAK,OAAO;GAAiB,UAAA;EAAa,CAAA,CAClD;;AAEf,CAAC;AAED,QAAQ,cAAc;AAYtB,IAAM,SAAS,YAA2D,OAAO,QAAQ;CACvF,MAAM,EAAE,aAAa,YAAY,MAAM,MAAM,WAAW,YAAY,GAAG,SAAS;CAChF,MAAM,SAAS,sBAAsB;CAErC,OACE,qBAAC,KAAD;EAAU;EAAK,MAAK;EAAS,GAAI;EAAjC,UAAA,CACE,qBAAC,KAAD;GAAK,KAAK,OAAO;GAAjB,UAAA,CACE,oBAAC,MAAD;IAAM,OAAO;IAAW,KAAK,OAAO;IAAY,MAAK;GAAM,CAAA,GAC3D,qBAAC,KAAD,EAAA,UAAA,CACE,oBAAC,MAAD;IAAM,IAAG;IAAS,KAAK,OAAO;IAC3B,UAAA;GACG,CAAA,GACL,eACC,oBAAC,MAAD;IAAM,IAAG;IAAI,KAAK,OAAO;IACtB,UAAA;GACG,CAAA,CAEL,EAAA,CAAA,CACF;EACJ,CAAA,GAAA,cAAc,oBAAC,MAAD;GAAM,KAAK,OAAO;GAAmB,UAAA;EAAiB,CAAA,CAClE;;AAET,CAAC;AAED,OAAO,cAAc;AAIrB,IAAM,SAAS,YAA6C,OAAO,QAAQ;CACzE,MAAM,EAAE,KAAK,GAAG,SAAS;CACzB,MAAM,SAAS,sBAAsB;CACrC,OAAO,oBAAC,KAAK,QAAN;EAAkB;EAAK,KAAK,CAAC,OAAO,QAAQ,GAAG;EAAG,GAAI;CAAO,CAAA;AACtE,CAAC;AAED,OAAO,cAAc;AAIrB,IAAA,6BAAe,kBAAkB,oBAAoB;CACnD;CACA;CACA;AACF,CAAC"}
|
|
@@ -10,13 +10,13 @@ var useStepsCardStyles = () => {
|
|
|
10
10
|
return useSlotRecipe({ key: "stepsCard" })();
|
|
11
11
|
};
|
|
12
12
|
var BitkitStepsCard = forwardRef((props, ref) => {
|
|
13
|
-
const { children, step, ...rest } = props;
|
|
13
|
+
const { children, css, step, ...rest } = props;
|
|
14
14
|
const styles = useStepsCardStyles();
|
|
15
15
|
return /* @__PURE__ */ jsx(StepCardProvider, {
|
|
16
16
|
value: { step },
|
|
17
17
|
children: /* @__PURE__ */ jsx(Card.Root, {
|
|
18
18
|
ref,
|
|
19
|
-
css: styles.root,
|
|
19
|
+
css: [styles.root, css],
|
|
20
20
|
unstyled: true,
|
|
21
21
|
...rest,
|
|
22
22
|
children
|
|
@@ -25,22 +25,22 @@ var BitkitStepsCard = forwardRef((props, ref) => {
|
|
|
25
25
|
});
|
|
26
26
|
BitkitStepsCard.displayName = "BitkitStepsCard";
|
|
27
27
|
var BitkitStepsCardHeader = forwardRef((props, ref) => {
|
|
28
|
-
const { children, ...rest } = props;
|
|
28
|
+
const { children, css, ...rest } = props;
|
|
29
29
|
const styles = useStepsCardStyles();
|
|
30
30
|
return /* @__PURE__ */ jsx(Card.Header, {
|
|
31
31
|
ref,
|
|
32
|
-
css: styles.header,
|
|
32
|
+
css: [styles.header, css],
|
|
33
33
|
...rest,
|
|
34
34
|
children
|
|
35
35
|
});
|
|
36
36
|
});
|
|
37
37
|
BitkitStepsCardHeader.displayName = "BitkitStepsCardHeader";
|
|
38
38
|
var BitkitStepsCardBody = forwardRef((props, ref) => {
|
|
39
|
-
const { children, ...rest } = props;
|
|
39
|
+
const { children, css, ...rest } = props;
|
|
40
40
|
const styles = useStepsCardStyles();
|
|
41
41
|
return /* @__PURE__ */ jsx(Card.Body, {
|
|
42
42
|
ref,
|
|
43
|
-
css: styles.body,
|
|
43
|
+
css: [styles.body, css],
|
|
44
44
|
...rest,
|
|
45
45
|
children: Children.map(children, (child, index) => {
|
|
46
46
|
if (isValidElement(child)) return cloneElement(child, { _index: index });
|
|
@@ -70,11 +70,11 @@ var BitkitStepsCardStep = (props) => {
|
|
|
70
70
|
};
|
|
71
71
|
BitkitStepsCardStep.displayName = "BitkitStepsCardStep";
|
|
72
72
|
var BitkitStepsCardFooter = forwardRef((props, ref) => {
|
|
73
|
-
const { children, ...rest } = props;
|
|
73
|
+
const { children, css, ...rest } = props;
|
|
74
74
|
const styles = useStepsCardStyles();
|
|
75
75
|
return /* @__PURE__ */ jsx(Card.Footer, {
|
|
76
76
|
ref,
|
|
77
|
-
css: styles.footer,
|
|
77
|
+
css: [styles.footer, css],
|
|
78
78
|
...rest,
|
|
79
79
|
children
|
|
80
80
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BitkitStepsCard.js","names":[],"sources":["../../../lib/components/BitkitStepsCard/BitkitStepsCard.tsx"],"sourcesContent":["import { Box } from '@chakra-ui/react/box';\nimport {\n Card,\n type CardBodyProps,\n type CardFooterProps,\n type CardHeaderProps,\n type CardRootProps,\n} from '@chakra-ui/react/card';\nimport { useSlotRecipe } from '@chakra-ui/react/styled-system';\nimport { Children, cloneElement, forwardRef, isValidElement, type ReactElement, type ReactNode } from 'react';\n\nimport { withSubComponents } from '../../utilities/withSubComponents';\nimport { StepCardProvider, useStepCardContext } from './StepCardContext';\n\nconst useStepsCardStyles = () => {\n const recipe = useSlotRecipe({ key: 'stepsCard' });\n return recipe();\n};\n\nexport interface BitkitStepsCardProps extends Omit<CardRootProps, 'children' | 'title'> {\n children: ReactNode;\n step: number;\n}\n\nconst BitkitStepsCard = forwardRef<HTMLDivElement, BitkitStepsCardProps>((props, ref) => {\n const { children, step, ...rest } = props;\n const styles = useStepsCardStyles();\n\n return (\n <StepCardProvider value={{ step }}>\n <Card.Root ref={ref} css={styles.root} unstyled {...rest}>\n {children}\n </Card.Root>\n </StepCardProvider>\n );\n});\n\nBitkitStepsCard.displayName = 'BitkitStepsCard';\n\nexport interface BitkitStepsCardHeaderProps extends Omit<CardHeaderProps, 'children'> {\n children: ReactNode;\n}\n\nconst BitkitStepsCardHeader = forwardRef<HTMLDivElement, BitkitStepsCardHeaderProps>((props, ref) => {\n const { children, ...rest } = props;\n const styles = useStepsCardStyles();\n\n return (\n <Card.Header ref={ref} css={styles.header} {...rest}>\n {children}\n </Card.Header>\n );\n});\n\nBitkitStepsCardHeader.displayName = 'BitkitStepsCardHeader';\n\nexport interface BitkitStepsCardBodyProps extends Omit<CardBodyProps, 'children'> {\n children: ReactNode;\n}\n\nconst BitkitStepsCardBody = forwardRef<HTMLDivElement, BitkitStepsCardBodyProps>((props, ref) => {\n const { children, ...rest } = props;\n const styles = useStepsCardStyles();\n\n return (\n <Card.Body ref={ref} css={styles.body} {...rest}>\n {Children.map(children, (child, index) => {\n if (isValidElement(child)) {\n return cloneElement(child as ReactElement<{ _index?: number }>, { _index: index });\n }\n return child;\n })}\n </Card.Body>\n );\n});\n\nBitkitStepsCardBody.displayName = 'BitkitStepsCardBody';\n\nconst hasContent = (node: ReactNode) => node !== null && node !== undefined && node !== '';\n\nexport interface BitkitStepsCardStepProps {\n children?: ReactNode;\n description?: ReactNode;\n title?: ReactNode;\n}\n\ninterface BitkitStepsCardStepInternalProps extends BitkitStepsCardStepProps {\n _index?: number;\n}\n\nconst BitkitStepsCardStep = (props: BitkitStepsCardStepProps) => {\n const { _index = 0, children, description, title } = props as BitkitStepsCardStepInternalProps;\n const { step } = useStepCardContext() ?? { step: 0 };\n const styles = useStepsCardStyles();\n\n if (_index !== step) return null;\n\n const showTitle = hasContent(title);\n const showDescription = hasContent(description);\n\n return (\n <>\n {(showTitle || showDescription) && (\n <Box css={styles.titleGroup}>\n {showTitle && <Card.Title css={styles.title}>{title}</Card.Title>}\n {showDescription && <Card.Description css={styles.description}>{description}</Card.Description>}\n </Box>\n )}\n {children}\n </>\n );\n};\n\nBitkitStepsCardStep.displayName = 'BitkitStepsCardStep';\n\nexport interface BitkitStepsCardFooterProps extends Omit<CardFooterProps, 'children'> {\n children: ReactNode;\n}\n\nconst BitkitStepsCardFooter = forwardRef<HTMLDivElement, BitkitStepsCardFooterProps>((props, ref) => {\n const { children, ...rest } = props;\n const styles = useStepsCardStyles();\n\n return (\n <Card.Footer ref={ref} css={styles.footer} {...rest}>\n {children}\n </Card.Footer>\n );\n});\n\nBitkitStepsCardFooter.displayName = 'BitkitStepsCardFooter';\n\nexport default withSubComponents(BitkitStepsCard, {\n Body: BitkitStepsCardBody,\n Footer: BitkitStepsCardFooter,\n Header: BitkitStepsCardHeader,\n Step: BitkitStepsCardStep,\n});\n"],"mappings":";;;;;;;;AAcA,IAAM,2BAA2B;CAE/B,OADe,cAAc,EAAE,KAAK,YAAY,CACzC,CAAA,CAAO;AAChB;AAOA,IAAM,kBAAkB,YAAkD,OAAO,QAAQ;CACvF,MAAM,EAAE,UAAU,MAAM,GAAG,SAAS;
|
|
1
|
+
{"version":3,"file":"BitkitStepsCard.js","names":[],"sources":["../../../lib/components/BitkitStepsCard/BitkitStepsCard.tsx"],"sourcesContent":["import { Box } from '@chakra-ui/react/box';\nimport {\n Card,\n type CardBodyProps,\n type CardFooterProps,\n type CardHeaderProps,\n type CardRootProps,\n} from '@chakra-ui/react/card';\nimport { useSlotRecipe } from '@chakra-ui/react/styled-system';\nimport { Children, cloneElement, forwardRef, isValidElement, type ReactElement, type ReactNode } from 'react';\n\nimport { withSubComponents } from '../../utilities/withSubComponents';\nimport { StepCardProvider, useStepCardContext } from './StepCardContext';\n\nconst useStepsCardStyles = () => {\n const recipe = useSlotRecipe({ key: 'stepsCard' });\n return recipe();\n};\n\nexport interface BitkitStepsCardProps extends Omit<CardRootProps, 'children' | 'title'> {\n children: ReactNode;\n step: number;\n}\n\nconst BitkitStepsCard = forwardRef<HTMLDivElement, BitkitStepsCardProps>((props, ref) => {\n const { children, css, step, ...rest } = props;\n const styles = useStepsCardStyles();\n\n return (\n <StepCardProvider value={{ step }}>\n <Card.Root ref={ref} css={[styles.root, css]} unstyled {...rest}>\n {children}\n </Card.Root>\n </StepCardProvider>\n );\n});\n\nBitkitStepsCard.displayName = 'BitkitStepsCard';\n\nexport interface BitkitStepsCardHeaderProps extends Omit<CardHeaderProps, 'children'> {\n children: ReactNode;\n}\n\nconst BitkitStepsCardHeader = forwardRef<HTMLDivElement, BitkitStepsCardHeaderProps>((props, ref) => {\n const { children, css, ...rest } = props;\n const styles = useStepsCardStyles();\n\n return (\n <Card.Header ref={ref} css={[styles.header, css]} {...rest}>\n {children}\n </Card.Header>\n );\n});\n\nBitkitStepsCardHeader.displayName = 'BitkitStepsCardHeader';\n\nexport interface BitkitStepsCardBodyProps extends Omit<CardBodyProps, 'children'> {\n children: ReactNode;\n}\n\nconst BitkitStepsCardBody = forwardRef<HTMLDivElement, BitkitStepsCardBodyProps>((props, ref) => {\n const { children, css, ...rest } = props;\n const styles = useStepsCardStyles();\n\n return (\n <Card.Body ref={ref} css={[styles.body, css]} {...rest}>\n {Children.map(children, (child, index) => {\n if (isValidElement(child)) {\n return cloneElement(child as ReactElement<{ _index?: number }>, { _index: index });\n }\n return child;\n })}\n </Card.Body>\n );\n});\n\nBitkitStepsCardBody.displayName = 'BitkitStepsCardBody';\n\nconst hasContent = (node: ReactNode) => node !== null && node !== undefined && node !== '';\n\nexport interface BitkitStepsCardStepProps {\n children?: ReactNode;\n description?: ReactNode;\n title?: ReactNode;\n}\n\ninterface BitkitStepsCardStepInternalProps extends BitkitStepsCardStepProps {\n _index?: number;\n}\n\nconst BitkitStepsCardStep = (props: BitkitStepsCardStepProps) => {\n const { _index = 0, children, description, title } = props as BitkitStepsCardStepInternalProps;\n const { step } = useStepCardContext() ?? { step: 0 };\n const styles = useStepsCardStyles();\n\n if (_index !== step) return null;\n\n const showTitle = hasContent(title);\n const showDescription = hasContent(description);\n\n return (\n <>\n {(showTitle || showDescription) && (\n <Box css={styles.titleGroup}>\n {showTitle && <Card.Title css={styles.title}>{title}</Card.Title>}\n {showDescription && <Card.Description css={styles.description}>{description}</Card.Description>}\n </Box>\n )}\n {children}\n </>\n );\n};\n\nBitkitStepsCardStep.displayName = 'BitkitStepsCardStep';\n\nexport interface BitkitStepsCardFooterProps extends Omit<CardFooterProps, 'children'> {\n children: ReactNode;\n}\n\nconst BitkitStepsCardFooter = forwardRef<HTMLDivElement, BitkitStepsCardFooterProps>((props, ref) => {\n const { children, css, ...rest } = props;\n const styles = useStepsCardStyles();\n\n return (\n <Card.Footer ref={ref} css={[styles.footer, css]} {...rest}>\n {children}\n </Card.Footer>\n );\n});\n\nBitkitStepsCardFooter.displayName = 'BitkitStepsCardFooter';\n\nexport default withSubComponents(BitkitStepsCard, {\n Body: BitkitStepsCardBody,\n Footer: BitkitStepsCardFooter,\n Header: BitkitStepsCardHeader,\n Step: BitkitStepsCardStep,\n});\n"],"mappings":";;;;;;;;AAcA,IAAM,2BAA2B;CAE/B,OADe,cAAc,EAAE,KAAK,YAAY,CACzC,CAAA,CAAO;AAChB;AAOA,IAAM,kBAAkB,YAAkD,OAAO,QAAQ;CACvF,MAAM,EAAE,UAAU,KAAK,MAAM,GAAG,SAAS;CACzC,MAAM,SAAS,mBAAmB;CAElC,OACE,oBAAC,kBAAD;EAAkB,OAAO,EAAE,KAAK;EAC9B,UAAA,oBAAC,KAAK,MAAN;GAAgB;GAAK,KAAK,CAAC,OAAO,MAAM,GAAG;GAAG,UAAA;GAAS,GAAI;GACxD;EACQ,CAAA;CACK,CAAA;AAEtB,CAAC;AAED,gBAAgB,cAAc;AAM9B,IAAM,wBAAwB,YAAwD,OAAO,QAAQ;CACnG,MAAM,EAAE,UAAU,KAAK,GAAG,SAAS;CACnC,MAAM,SAAS,mBAAmB;CAElC,OACE,oBAAC,KAAK,QAAN;EAAkB;EAAK,KAAK,CAAC,OAAO,QAAQ,GAAG;EAAG,GAAI;EACnD;CACU,CAAA;AAEjB,CAAC;AAED,sBAAsB,cAAc;AAMpC,IAAM,sBAAsB,YAAsD,OAAO,QAAQ;CAC/F,MAAM,EAAE,UAAU,KAAK,GAAG,SAAS;CACnC,MAAM,SAAS,mBAAmB;CAElC,OACE,oBAAC,KAAK,MAAN;EAAgB;EAAK,KAAK,CAAC,OAAO,MAAM,GAAG;EAAG,GAAI;EAC/C,UAAA,SAAS,IAAI,WAAW,OAAO,UAAU;GACxC,IAAI,eAAe,KAAK,GACtB,OAAO,aAAa,OAA4C,EAAE,QAAQ,MAAM,CAAC;GAEnF,OAAO;EACT,CAAC;CACQ,CAAA;AAEf,CAAC;AAED,oBAAoB,cAAc;AAElC,IAAM,cAAc,SAAoB,SAAS,QAAQ,SAAS,KAAA,KAAa,SAAS;AAYxF,IAAM,uBAAuB,UAAoC;CAC/D,MAAM,EAAE,SAAS,GAAG,UAAU,aAAa,UAAU;CACrD,MAAM,EAAE,SAAS,mBAAmB,KAAK,EAAE,MAAM,EAAE;CACnD,MAAM,SAAS,mBAAmB;CAElC,IAAI,WAAW,MAAM,OAAO;CAE5B,MAAM,YAAY,WAAW,KAAK;CAClC,MAAM,kBAAkB,WAAW,WAAW;CAE9C,OACE,qBAAA,YAAA,EAAA,UAAA,EACI,aAAa,oBACb,qBAAC,KAAD;EAAK,KAAK,OAAO;EAAjB,UAAA,CACG,aAAa,oBAAC,KAAK,OAAN;GAAY,KAAK,OAAO;GAAQ,UAAA;EAAkB,CAAA,GAC/D,mBAAmB,oBAAC,KAAK,aAAN;GAAkB,KAAK,OAAO;GAAc,UAAA;EAA8B,CAAA,CAC3F;CAEN,CAAA,GAAA,QACD,EAAA,CAAA;AAEN;AAEA,oBAAoB,cAAc;AAMlC,IAAM,wBAAwB,YAAwD,OAAO,QAAQ;CACnG,MAAM,EAAE,UAAU,KAAK,GAAG,SAAS;CACnC,MAAM,SAAS,mBAAmB;CAElC,OACE,oBAAC,KAAK,QAAN;EAAkB;EAAK,KAAK,CAAC,OAAO,QAAQ,GAAG;EAAG,GAAI;EACnD;CACU,CAAA;AAEjB,CAAC;AAED,sBAAsB,cAAc;AAEpC,IAAA,0BAAe,kBAAkB,iBAAiB;CAChD,MAAM;CACN,QAAQ;CACR,QAAQ;CACR,MAAM;AACR,CAAC"}
|
|
@@ -28,11 +28,11 @@ import { Table, useTableStyles } from "@chakra-ui/react/table";
|
|
|
28
28
|
* ```
|
|
29
29
|
*/
|
|
30
30
|
var BitkitLinkedRow = forwardRef((props, ref) => {
|
|
31
|
-
const { children, ...rest } = props;
|
|
31
|
+
const { children, css, ...rest } = props;
|
|
32
32
|
const styles = useTableStyles();
|
|
33
33
|
return /* @__PURE__ */ jsx(Table.Row, {
|
|
34
34
|
ref,
|
|
35
|
-
css: styles.linkedRow,
|
|
35
|
+
css: [styles.linkedRow, css],
|
|
36
36
|
...rest,
|
|
37
37
|
children
|
|
38
38
|
});
|
|
@@ -43,11 +43,11 @@ BitkitLinkedRow.displayName = "BitkitTable.LinkedRow";
|
|
|
43
43
|
* stretches its link across the row, leaving the styling to the link itself.
|
|
44
44
|
*/
|
|
45
45
|
var LinkCell = forwardRef((props, ref) => {
|
|
46
|
-
const { children, ...rest } = props;
|
|
46
|
+
const { children, css, ...rest } = props;
|
|
47
47
|
const styles = useTableStyles();
|
|
48
48
|
return /* @__PURE__ */ jsx(Table.Cell, {
|
|
49
49
|
ref,
|
|
50
|
-
css: styles.linkCell,
|
|
50
|
+
css: [styles.linkCell, css],
|
|
51
51
|
"data-link-cell": true,
|
|
52
52
|
...rest,
|
|
53
53
|
children
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BitkitLinkedRow.js","names":[],"sources":["../../../lib/components/BitkitTable/BitkitLinkedRow.tsx"],"sourcesContent":["import { Table, useTableStyles } from '@chakra-ui/react/table';\nimport { forwardRef, type ReactElement } from 'react';\n\nimport { withSubComponents } from '../../utilities/withSubComponents';\nimport { type BitkitLinkProps } from '../BitkitLink/BitkitLink';\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 * `BitkitTable.LinkedRow.LinkCell` holding the row's link — that link's text becomes the row's\n * accessible 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 `BitkitTable.RowActionsCell` works inside a linked row.\n *\n * Neither requirement is enforced: a row without a `LinkCell`, or one whose link has no `href`,\n * still renders with the linked-row styling — hover affordance included — and navigates nowhere.\n *\n * @example\n * ```tsx\n * <BitkitTable.LinkedRow>\n * <BitkitTable.LinkedRow.LinkCell>\n * <BitkitLink colorVariant=\"purple\" href={`/workflows/${row.id}`}>\n * {row.name}\n * </BitkitLink>\n * </BitkitTable.LinkedRow.LinkCell>\n * <BitkitTable.Cell>{row.status}</BitkitTable.Cell>\n * <BitkitTable.RowActionsCell actions={actions} />\n * </BitkitTable.LinkedRow>\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 = 'BitkitTable.LinkedRow';\n\nexport interface BitkitLinkedRowLinkCellProps extends Omit<Table.CellProps, 'children'> {\n /**\n * The row's link: a single `BitkitLink` with its own `href`, `isExternal`, `colorVariant` and any\n * other link prop. The type only rules out bare text and multiple children — a non-link element,\n * or a `BitkitLink` without an `href`, type-checks as well and leaves the row looking linked\n * while navigating nowhere. Anything else the cell should show (an icon, a `VisuallyHidden` name)\n * goes inside the link.\n */\n children: ReactElement<BitkitLinkProps>;\n}\n\n/**\n * The cell that carries the row's link, so give it the cell that names the row. The cell only\n * stretches its link across the row, leaving the 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 = 'BitkitTable.LinkedRow.LinkCell';\n\nexport default withSubComponents(BitkitLinkedRow, { LinkCell });\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgCA,IAAM,kBAAkB,YAAuD,OAAO,QAAQ;CAC5F,MAAM,EAAE,UAAU,GAAG,SAAS;
|
|
1
|
+
{"version":3,"file":"BitkitLinkedRow.js","names":[],"sources":["../../../lib/components/BitkitTable/BitkitLinkedRow.tsx"],"sourcesContent":["import { Table, useTableStyles } from '@chakra-ui/react/table';\nimport { forwardRef, type ReactElement } from 'react';\n\nimport { withSubComponents } from '../../utilities/withSubComponents';\nimport { type BitkitLinkProps } from '../BitkitLink/BitkitLink';\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 * `BitkitTable.LinkedRow.LinkCell` holding the row's link — that link's text becomes the row's\n * accessible 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 `BitkitTable.RowActionsCell` works inside a linked row.\n *\n * Neither requirement is enforced: a row without a `LinkCell`, or one whose link has no `href`,\n * still renders with the linked-row styling — hover affordance included — and navigates nowhere.\n *\n * @example\n * ```tsx\n * <BitkitTable.LinkedRow>\n * <BitkitTable.LinkedRow.LinkCell>\n * <BitkitLink colorVariant=\"purple\" href={`/workflows/${row.id}`}>\n * {row.name}\n * </BitkitLink>\n * </BitkitTable.LinkedRow.LinkCell>\n * <BitkitTable.Cell>{row.status}</BitkitTable.Cell>\n * <BitkitTable.RowActionsCell actions={actions} />\n * </BitkitTable.LinkedRow>\n * ```\n */\nconst BitkitLinkedRow = forwardRef<HTMLTableRowElement, BitkitLinkedRowProps>((props, ref) => {\n const { children, css, ...rest } = props;\n const styles = useTableStyles();\n\n return (\n <Table.Row ref={ref} css={[styles.linkedRow, css]} {...rest}>\n {children}\n </Table.Row>\n );\n});\n\nBitkitLinkedRow.displayName = 'BitkitTable.LinkedRow';\n\nexport interface BitkitLinkedRowLinkCellProps extends Omit<Table.CellProps, 'children'> {\n /**\n * The row's link: a single `BitkitLink` with its own `href`, `isExternal`, `colorVariant` and any\n * other link prop. The type only rules out bare text and multiple children — a non-link element,\n * or a `BitkitLink` without an `href`, type-checks as well and leaves the row looking linked\n * while navigating nowhere. Anything else the cell should show (an icon, a `VisuallyHidden` name)\n * goes inside the link.\n */\n children: ReactElement<BitkitLinkProps>;\n}\n\n/**\n * The cell that carries the row's link, so give it the cell that names the row. The cell only\n * stretches its link across the row, leaving the styling to the link itself.\n */\nconst LinkCell = forwardRef<HTMLTableCellElement, BitkitLinkedRowLinkCellProps>((props, ref) => {\n const { children, css, ...rest } = props;\n const styles = useTableStyles();\n\n return (\n <Table.Cell ref={ref} css={[styles.linkCell, css]} data-link-cell {...rest}>\n {children}\n </Table.Cell>\n );\n});\n\nLinkCell.displayName = 'BitkitTable.LinkedRow.LinkCell';\n\nexport default withSubComponents(BitkitLinkedRow, { LinkCell });\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgCA,IAAM,kBAAkB,YAAuD,OAAO,QAAQ;CAC5F,MAAM,EAAE,UAAU,KAAK,GAAG,SAAS;CACnC,MAAM,SAAS,eAAe;CAE9B,OACE,oBAAC,MAAM,KAAP;EAAgB;EAAK,KAAK,CAAC,OAAO,WAAW,GAAG;EAAG,GAAI;EACpD;CACQ,CAAA;AAEf,CAAC;AAED,gBAAgB,cAAc;;;;;AAiB9B,IAAM,WAAW,YAAgE,OAAO,QAAQ;CAC9F,MAAM,EAAE,UAAU,KAAK,GAAG,SAAS;CACnC,MAAM,SAAS,eAAe;CAE9B,OACE,oBAAC,MAAM,MAAP;EAAiB;EAAK,KAAK,CAAC,OAAO,UAAU,GAAG;EAAG,kBAAA;EAAe,GAAI;EACnE;CACS,CAAA;AAEhB,CAAC;AAED,SAAS,cAAc;AAEvB,IAAA,0BAAe,kBAAkB,iBAAiB,EAAE,SAAS,CAAC"}
|
|
@@ -63,12 +63,12 @@ var MenuAction = ({ action }) => {
|
|
|
63
63
|
* ```
|
|
64
64
|
*/
|
|
65
65
|
var BitkitRowActionsCell = forwardRef((props, ref) => {
|
|
66
|
-
const { actions, menuLabel = "More actions", ...rest } = props;
|
|
66
|
+
const { actions, css, menuLabel = "More actions", ...rest } = props;
|
|
67
67
|
const styles = useTableStyles();
|
|
68
68
|
const isPending = actions.some((action) => action.state === "skeleton");
|
|
69
69
|
return /* @__PURE__ */ jsx(Table.Cell, {
|
|
70
70
|
ref,
|
|
71
|
-
css: styles.actionsCell,
|
|
71
|
+
css: [styles.actionsCell, css],
|
|
72
72
|
...rest,
|
|
73
73
|
children: /* @__PURE__ */ jsx(Box, {
|
|
74
74
|
css: styles.actionsGroup,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BitkitRowActionsCell.js","names":[],"sources":["../../../lib/components/BitkitTable/BitkitRowActionsCell.tsx"],"sourcesContent":["import { Box } from '@chakra-ui/react/box';\nimport { Table, useTableStyles } from '@chakra-ui/react/table';\nimport { forwardRef, type MouseEvent } from 'react';\n\nimport { type BitkitIconComponent } from '../../icons';\nimport IconMoreVertical from '../../icons/IconMoreVertical';\nimport BitkitActionMenu from '../BitkitActionMenu/BitkitActionMenu';\nimport BitkitControlButton from '../BitkitControlButton/BitkitControlButton';\n\n/** One row action, rendered either as an inline control button or as an action menu item. */\nexport interface BitkitRowAction {\n /** Renders the action in the danger color set. */\n danger?: boolean;\n /** Makes the action a link instead of a button. */\n href?: string;\n icon: BitkitIconComponent;\n /** Only with `href`: opens the link in a new tab and adds the external-link affordance. */\n isExternal?: boolean;\n /** Accessible name of the inline button, and the visible text of the menu item. Must be unique\n * within `actions`, since it keys the list. */\n label: string;\n onClick?: (event: MouseEvent<HTMLElement>) => void;\n /**\n * `disabled` makes this one action inert. `skeleton` marks it as in flight: an inline action\n * shimmers in place, and in the collapsed menu the trigger shimmers instead — the state belongs\n * to the row, and the items sit behind a closed menu. Menu items are inert under either state.\n */\n state?: 'disabled' | 'skeleton';\n}\n\nexport interface BitkitRowActionsCellProps extends Omit<Table.CellProps, 'children' | 'onClick'> {\n /** Up to two actions render as inline icon buttons; three or more collapse into an action menu. */\n actions: BitkitRowAction[];\n /** Accessible name of the action menu trigger, used from the third action on. Default: `More actions` */\n menuLabel?: string;\n}\n\nconst MAX_INLINE_ACTIONS = 2;\n\nconst InlineAction = ({ action }: { action: BitkitRowAction }) => {\n if (action.href !== undefined) {\n return (\n <BitkitControlButton\n href={action.href}\n icon={action.icon}\n isDanger={action.danger}\n isExternal={action.isExternal}\n label={action.label}\n onClick={action.onClick}\n state={action.state}\n />\n );\n }\n\n return (\n <BitkitControlButton\n icon={action.icon}\n isDanger={action.danger}\n label={action.label}\n onClick={action.onClick}\n state={action.state}\n />\n );\n};\n\nconst MenuAction = ({ action }: { action: BitkitRowAction }) => {\n if (action.href !== undefined) {\n return (\n <BitkitActionMenu.Item\n disabled={action.state !== undefined}\n href={action.href}\n icon={action.icon}\n isDanger={action.danger}\n isExternal={action.isExternal}\n onClick={action.onClick}\n value={action.label}\n >\n {action.label}\n </BitkitActionMenu.Item>\n );\n }\n\n return (\n <BitkitActionMenu.Item\n disabled={action.state !== undefined}\n icon={action.icon}\n isDanger={action.danger}\n onClick={action.onClick}\n value={action.label}\n >\n {action.label}\n </BitkitActionMenu.Item>\n );\n};\n\n/**\n * The trailing cell of a table row, holding its actions. The column shrinks to fit the buttons.\n *\n * Up to two actions render as inline icon buttons; from the third on they collapse into a single\n * action menu, so the column width stays predictable. Clicks are kept inside the cell, so the\n * actions work in a `BitkitTable.LinkedRow` without triggering the row link.\n *\n * @example\n * ```tsx\n * <BitkitTable.RowActionsCell\n * actions={[\n * { icon: IconPencil, label: 'Edit', onClick: onEdit },\n * { danger: true, icon: IconMinusCircle, label: 'Remove', onClick: onRemove },\n * ]}\n * />\n * ```\n */\nconst BitkitRowActionsCell = forwardRef<HTMLTableCellElement, BitkitRowActionsCellProps>((props, ref) => {\n const { actions, menuLabel = 'More actions', ...rest } = props;\n const styles = useTableStyles();\n const isPending = actions.some((action) => action.state === 'skeleton');\n\n return (\n <Table.Cell ref={ref} css={styles.actionsCell} {...rest}>\n <Box css={styles.actionsGroup} onClick={(event) => event.stopPropagation()}>\n {actions.length <= MAX_INLINE_ACTIONS ? (\n actions.map((action) => <InlineAction key={action.label} action={action} />)\n ) : (\n <BitkitActionMenu\n size=\"md\"\n trigger={\n <BitkitControlButton\n icon={IconMoreVertical}\n label={menuLabel}\n state={isPending ? 'skeleton' : undefined}\n />\n }\n >\n {actions.map((action) => (\n <MenuAction key={action.label} action={action} />\n ))}\n </BitkitActionMenu>\n )}\n </Box>\n </Table.Cell>\n );\n});\n\nBitkitRowActionsCell.displayName = 'BitkitTable.RowActionsCell';\n\nexport default BitkitRowActionsCell;\n"],"mappings":";;;;;;;;AAqCA,IAAM,qBAAqB;AAE3B,IAAM,gBAAgB,EAAE,aAA0C;CAChE,IAAI,OAAO,SAAS,KAAA,GAClB,OACE,oBAAC,qBAAD;EACE,MAAM,OAAO;EACb,MAAM,OAAO;EACb,UAAU,OAAO;EACjB,YAAY,OAAO;EACnB,OAAO,OAAO;EACd,SAAS,OAAO;EAChB,OAAO,OAAO;CACf,CAAA;CAIL,OACE,oBAAC,qBAAD;EACE,MAAM,OAAO;EACb,UAAU,OAAO;EACjB,OAAO,OAAO;EACd,SAAS,OAAO;EAChB,OAAO,OAAO;CACf,CAAA;AAEL;AAEA,IAAM,cAAc,EAAE,aAA0C;CAC9D,IAAI,OAAO,SAAS,KAAA,GAClB,OACE,oBAAC,yBAAiB,MAAlB;EACE,UAAU,OAAO,UAAU,KAAA;EAC3B,MAAM,OAAO;EACb,MAAM,OAAO;EACb,UAAU,OAAO;EACjB,YAAY,OAAO;EACnB,SAAS,OAAO;EAChB,OAAO,OAAO;EAEb,UAAA,OAAO;CACa,CAAA;CAI3B,OACE,oBAAC,yBAAiB,MAAlB;EACE,UAAU,OAAO,UAAU,KAAA;EAC3B,MAAM,OAAO;EACb,UAAU,OAAO;EACjB,SAAS,OAAO;EAChB,OAAO,OAAO;EAEb,UAAA,OAAO;CACa,CAAA;AAE3B;;;;;;;;;;;;;;;;;;AAmBA,IAAM,uBAAuB,YAA6D,OAAO,QAAQ;CACvG,MAAM,EAAE,SAAS,YAAY,gBAAgB,GAAG,SAAS;
|
|
1
|
+
{"version":3,"file":"BitkitRowActionsCell.js","names":[],"sources":["../../../lib/components/BitkitTable/BitkitRowActionsCell.tsx"],"sourcesContent":["import { Box } from '@chakra-ui/react/box';\nimport { Table, useTableStyles } from '@chakra-ui/react/table';\nimport { forwardRef, type MouseEvent } from 'react';\n\nimport { type BitkitIconComponent } from '../../icons';\nimport IconMoreVertical from '../../icons/IconMoreVertical';\nimport BitkitActionMenu from '../BitkitActionMenu/BitkitActionMenu';\nimport BitkitControlButton from '../BitkitControlButton/BitkitControlButton';\n\n/** One row action, rendered either as an inline control button or as an action menu item. */\nexport interface BitkitRowAction {\n /** Renders the action in the danger color set. */\n danger?: boolean;\n /** Makes the action a link instead of a button. */\n href?: string;\n icon: BitkitIconComponent;\n /** Only with `href`: opens the link in a new tab and adds the external-link affordance. */\n isExternal?: boolean;\n /** Accessible name of the inline button, and the visible text of the menu item. Must be unique\n * within `actions`, since it keys the list. */\n label: string;\n onClick?: (event: MouseEvent<HTMLElement>) => void;\n /**\n * `disabled` makes this one action inert. `skeleton` marks it as in flight: an inline action\n * shimmers in place, and in the collapsed menu the trigger shimmers instead — the state belongs\n * to the row, and the items sit behind a closed menu. Menu items are inert under either state.\n */\n state?: 'disabled' | 'skeleton';\n}\n\nexport interface BitkitRowActionsCellProps extends Omit<Table.CellProps, 'children' | 'onClick'> {\n /** Up to two actions render as inline icon buttons; three or more collapse into an action menu. */\n actions: BitkitRowAction[];\n /** Accessible name of the action menu trigger, used from the third action on. Default: `More actions` */\n menuLabel?: string;\n}\n\nconst MAX_INLINE_ACTIONS = 2;\n\nconst InlineAction = ({ action }: { action: BitkitRowAction }) => {\n if (action.href !== undefined) {\n return (\n <BitkitControlButton\n href={action.href}\n icon={action.icon}\n isDanger={action.danger}\n isExternal={action.isExternal}\n label={action.label}\n onClick={action.onClick}\n state={action.state}\n />\n );\n }\n\n return (\n <BitkitControlButton\n icon={action.icon}\n isDanger={action.danger}\n label={action.label}\n onClick={action.onClick}\n state={action.state}\n />\n );\n};\n\nconst MenuAction = ({ action }: { action: BitkitRowAction }) => {\n if (action.href !== undefined) {\n return (\n <BitkitActionMenu.Item\n disabled={action.state !== undefined}\n href={action.href}\n icon={action.icon}\n isDanger={action.danger}\n isExternal={action.isExternal}\n onClick={action.onClick}\n value={action.label}\n >\n {action.label}\n </BitkitActionMenu.Item>\n );\n }\n\n return (\n <BitkitActionMenu.Item\n disabled={action.state !== undefined}\n icon={action.icon}\n isDanger={action.danger}\n onClick={action.onClick}\n value={action.label}\n >\n {action.label}\n </BitkitActionMenu.Item>\n );\n};\n\n/**\n * The trailing cell of a table row, holding its actions. The column shrinks to fit the buttons.\n *\n * Up to two actions render as inline icon buttons; from the third on they collapse into a single\n * action menu, so the column width stays predictable. Clicks are kept inside the cell, so the\n * actions work in a `BitkitTable.LinkedRow` without triggering the row link.\n *\n * @example\n * ```tsx\n * <BitkitTable.RowActionsCell\n * actions={[\n * { icon: IconPencil, label: 'Edit', onClick: onEdit },\n * { danger: true, icon: IconMinusCircle, label: 'Remove', onClick: onRemove },\n * ]}\n * />\n * ```\n */\nconst BitkitRowActionsCell = forwardRef<HTMLTableCellElement, BitkitRowActionsCellProps>((props, ref) => {\n const { actions, css, menuLabel = 'More actions', ...rest } = props;\n const styles = useTableStyles();\n const isPending = actions.some((action) => action.state === 'skeleton');\n\n return (\n <Table.Cell ref={ref} css={[styles.actionsCell, css]} {...rest}>\n <Box css={styles.actionsGroup} onClick={(event) => event.stopPropagation()}>\n {actions.length <= MAX_INLINE_ACTIONS ? (\n actions.map((action) => <InlineAction key={action.label} action={action} />)\n ) : (\n <BitkitActionMenu\n size=\"md\"\n trigger={\n <BitkitControlButton\n icon={IconMoreVertical}\n label={menuLabel}\n state={isPending ? 'skeleton' : undefined}\n />\n }\n >\n {actions.map((action) => (\n <MenuAction key={action.label} action={action} />\n ))}\n </BitkitActionMenu>\n )}\n </Box>\n </Table.Cell>\n );\n});\n\nBitkitRowActionsCell.displayName = 'BitkitTable.RowActionsCell';\n\nexport default BitkitRowActionsCell;\n"],"mappings":";;;;;;;;AAqCA,IAAM,qBAAqB;AAE3B,IAAM,gBAAgB,EAAE,aAA0C;CAChE,IAAI,OAAO,SAAS,KAAA,GAClB,OACE,oBAAC,qBAAD;EACE,MAAM,OAAO;EACb,MAAM,OAAO;EACb,UAAU,OAAO;EACjB,YAAY,OAAO;EACnB,OAAO,OAAO;EACd,SAAS,OAAO;EAChB,OAAO,OAAO;CACf,CAAA;CAIL,OACE,oBAAC,qBAAD;EACE,MAAM,OAAO;EACb,UAAU,OAAO;EACjB,OAAO,OAAO;EACd,SAAS,OAAO;EAChB,OAAO,OAAO;CACf,CAAA;AAEL;AAEA,IAAM,cAAc,EAAE,aAA0C;CAC9D,IAAI,OAAO,SAAS,KAAA,GAClB,OACE,oBAAC,yBAAiB,MAAlB;EACE,UAAU,OAAO,UAAU,KAAA;EAC3B,MAAM,OAAO;EACb,MAAM,OAAO;EACb,UAAU,OAAO;EACjB,YAAY,OAAO;EACnB,SAAS,OAAO;EAChB,OAAO,OAAO;EAEb,UAAA,OAAO;CACa,CAAA;CAI3B,OACE,oBAAC,yBAAiB,MAAlB;EACE,UAAU,OAAO,UAAU,KAAA;EAC3B,MAAM,OAAO;EACb,UAAU,OAAO;EACjB,SAAS,OAAO;EAChB,OAAO,OAAO;EAEb,UAAA,OAAO;CACa,CAAA;AAE3B;;;;;;;;;;;;;;;;;;AAmBA,IAAM,uBAAuB,YAA6D,OAAO,QAAQ;CACvG,MAAM,EAAE,SAAS,KAAK,YAAY,gBAAgB,GAAG,SAAS;CAC9D,MAAM,SAAS,eAAe;CAC9B,MAAM,YAAY,QAAQ,MAAM,WAAW,OAAO,UAAU,UAAU;CAEtE,OACE,oBAAC,MAAM,MAAP;EAAiB;EAAK,KAAK,CAAC,OAAO,aAAa,GAAG;EAAG,GAAI;EACxD,UAAA,oBAAC,KAAD;GAAK,KAAK,OAAO;GAAc,UAAU,UAAU,MAAM,gBAAgB;GACtE,UAAA,QAAQ,UAAU,qBACjB,QAAQ,KAAK,WAAW,oBAAC,cAAD,EAAyC,OAAS,GAA/B,OAAO,KAAwB,CAAC,IAE3E,oBAAC,0BAAD;IACE,MAAK;IACL,SACE,oBAAC,qBAAD;KACE,MAAM;KACN,OAAO;KACP,OAAO,YAAY,aAAa,KAAA;IACjC,CAAA;IAGF,UAAA,QAAQ,KAAK,WACZ,oBAAC,YAAD,EAAuC,OAAS,GAA/B,OAAO,KAAwB,CACjD;GACe,CAAA;EAEjB,CAAA;CACK,CAAA;AAEhB,CAAC;AAED,qBAAqB,cAAc"}
|
|
@@ -35,14 +35,14 @@ var SortIcon = forwardRef((props, ref) => {
|
|
|
35
35
|
});
|
|
36
36
|
});
|
|
37
37
|
SortIcon.displayName = "SortIcon";
|
|
38
|
-
var BitkitSortableColumnHeader = forwardRef(({ children, direction, onSort, textAlign, ...rest }, ref) => {
|
|
38
|
+
var BitkitSortableColumnHeader = forwardRef(({ children, css, direction, onSort, textAlign, ...rest }, ref) => {
|
|
39
39
|
const styles = useTableStyles();
|
|
40
40
|
const isEndAligned = textAlign === "end";
|
|
41
41
|
const sortIcon = /* @__PURE__ */ jsx(SortIcon, { direction });
|
|
42
42
|
return /* @__PURE__ */ jsx(Table.ColumnHeader, {
|
|
43
43
|
ref,
|
|
44
44
|
"aria-sort": direction === "none" ? void 0 : direction,
|
|
45
|
-
css: styles.sortColumnHeader,
|
|
45
|
+
css: [styles.sortColumnHeader, css],
|
|
46
46
|
...rest,
|
|
47
47
|
children: /* @__PURE__ */ jsx(chakra.button, {
|
|
48
48
|
css: styles.sortTrigger,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BitkitSortableColumnHeader.js","names":[],"sources":["../../../lib/components/BitkitTable/BitkitSortableColumnHeader.tsx"],"sourcesContent":["import { Icon, type IconProps } from '@chakra-ui/react/icon';\nimport { chakra } from '@chakra-ui/react/styled-system';\nimport { Table, useTableStyles } from '@chakra-ui/react/table';\nimport { forwardRef, type Ref } from 'react';\n\ntype SortDirection = 'ascending' | 'descending' | 'none';\n\nexport interface BitkitSortableColumnHeaderProps extends Omit<Table.ColumnHeaderProps, 'aria-sort' | 'onClick'> {\n direction: SortDirection;\n onSort: () => void;\n}\n\nconst SortIcon = forwardRef((props: IconProps & { direction: SortDirection }, ref: Ref<SVGSVGElement>) => {\n const { direction, ...rest } = props;\n const upFill = direction === 'ascending' ? 'currentColor' : 'var(--sort-icon-inactive)';\n const downFill = direction === 'descending' ? 'currentColor' : 'var(--sort-icon-inactive)';\n\n return (\n <Icon\n ref={ref}\n asChild\n css={{\n '--sort-icon-inactive': 'colors.icon/disabled',\n color: 'icon/primary',\n display: 'inline-block',\n verticalAlign: 'middle',\n }}\n {...rest}\n >\n <svg fill=\"none\" height=\"24\" viewBox=\"0 0 24 24\" width=\"24\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M11.617 4.461 7.684 9.18c-.271.326-.04.82.384.82h7.865c.424 0 .655-.494.384-.82l-3.933-4.719a.5.5 0 0 0-.767 0Z\"\n fill={upFill}\n />\n <path\n d=\"M12.384 19.539l3.933-4.719c.27-.326.04-.82-.384-.82H8.068c-.424 0-.655.494-.384.82l3.933 4.719a.5.5 0 0 0 .767 0Z\"\n fill={downFill}\n />\n </svg>\n </Icon>\n );\n});\n\nSortIcon.displayName = 'SortIcon';\n\nconst BitkitSortableColumnHeader = forwardRef<HTMLTableCellElement, BitkitSortableColumnHeaderProps>(\n ({ children, direction, onSort, textAlign, ...rest }, ref) => {\n const styles = useTableStyles();\n const isEndAligned = textAlign === 'end';\n const sortIcon = <SortIcon direction={direction} />;\n\n return (\n <Table.ColumnHeader\n ref={ref}\n aria-sort={direction === 'none' ? undefined : direction}\n css={styles.sortColumnHeader}\n {...rest}\n >\n {/* chakra.button: no named primitive attaches a recipe slot to a bare trigger button */}\n <chakra.button\n css={styles.sortTrigger}\n justifyContent={isEndAligned ? 'flex-end' : undefined}\n onClick={onSort}\n type=\"button\"\n >\n {isEndAligned ? (\n <>\n {sortIcon} {children}\n </>\n ) : (\n <>\n {children} {sortIcon}\n </>\n )}\n </chakra.button>\n </Table.ColumnHeader>\n );\n },\n);\n\nBitkitSortableColumnHeader.displayName = 'BitkitTable.SortableColumnHeader';\n\nexport default BitkitSortableColumnHeader;\n"],"mappings":";;;;;;AAYA,IAAM,WAAW,YAAY,OAAiD,QAA4B;CACxG,MAAM,EAAE,WAAW,GAAG,SAAS;CAC/B,MAAM,SAAS,cAAc,cAAc,iBAAiB;CAC5D,MAAM,WAAW,cAAc,eAAe,iBAAiB;CAE/D,OACE,oBAAC,MAAD;EACO;EACL,SAAA;EACA,KAAK;GACH,wBAAwB;GACxB,OAAO;GACP,SAAS;GACT,eAAe;EACjB;EACA,GAAI;EAEJ,UAAA,qBAAC,OAAD;GAAK,MAAK;GAAO,QAAO;GAAK,SAAQ;GAAY,OAAM;GAAK,OAAM;GAAlE,UAAA,CACE,oBAAC,QAAD;IACE,GAAE;IACF,MAAM;GACP,CAAA,GACD,oBAAC,QAAD;IACE,GAAE;IACF,MAAM;GACP,CAAA,CACE;;CACD,CAAA;AAEV,CAAC;AAED,SAAS,cAAc;AAEvB,IAAM,6BAA6B,YAChC,EAAE,UAAU,WAAW,QAAQ,WAAW,GAAG,QAAQ,QAAQ;
|
|
1
|
+
{"version":3,"file":"BitkitSortableColumnHeader.js","names":[],"sources":["../../../lib/components/BitkitTable/BitkitSortableColumnHeader.tsx"],"sourcesContent":["import { Icon, type IconProps } from '@chakra-ui/react/icon';\nimport { chakra } from '@chakra-ui/react/styled-system';\nimport { Table, useTableStyles } from '@chakra-ui/react/table';\nimport { forwardRef, type Ref } from 'react';\n\ntype SortDirection = 'ascending' | 'descending' | 'none';\n\nexport interface BitkitSortableColumnHeaderProps extends Omit<Table.ColumnHeaderProps, 'aria-sort' | 'onClick'> {\n direction: SortDirection;\n onSort: () => void;\n}\n\nconst SortIcon = forwardRef((props: IconProps & { direction: SortDirection }, ref: Ref<SVGSVGElement>) => {\n const { direction, ...rest } = props;\n const upFill = direction === 'ascending' ? 'currentColor' : 'var(--sort-icon-inactive)';\n const downFill = direction === 'descending' ? 'currentColor' : 'var(--sort-icon-inactive)';\n\n return (\n <Icon\n ref={ref}\n asChild\n css={{\n '--sort-icon-inactive': 'colors.icon/disabled',\n color: 'icon/primary',\n display: 'inline-block',\n verticalAlign: 'middle',\n }}\n {...rest}\n >\n <svg fill=\"none\" height=\"24\" viewBox=\"0 0 24 24\" width=\"24\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M11.617 4.461 7.684 9.18c-.271.326-.04.82.384.82h7.865c.424 0 .655-.494.384-.82l-3.933-4.719a.5.5 0 0 0-.767 0Z\"\n fill={upFill}\n />\n <path\n d=\"M12.384 19.539l3.933-4.719c.27-.326.04-.82-.384-.82H8.068c-.424 0-.655.494-.384.82l3.933 4.719a.5.5 0 0 0 .767 0Z\"\n fill={downFill}\n />\n </svg>\n </Icon>\n );\n});\n\nSortIcon.displayName = 'SortIcon';\n\nconst BitkitSortableColumnHeader = forwardRef<HTMLTableCellElement, BitkitSortableColumnHeaderProps>(\n ({ children, css, direction, onSort, textAlign, ...rest }, ref) => {\n const styles = useTableStyles();\n const isEndAligned = textAlign === 'end';\n const sortIcon = <SortIcon direction={direction} />;\n\n return (\n <Table.ColumnHeader\n ref={ref}\n aria-sort={direction === 'none' ? undefined : direction}\n css={[styles.sortColumnHeader, css]}\n {...rest}\n >\n {/* chakra.button: no named primitive attaches a recipe slot to a bare trigger button */}\n <chakra.button\n css={styles.sortTrigger}\n justifyContent={isEndAligned ? 'flex-end' : undefined}\n onClick={onSort}\n type=\"button\"\n >\n {isEndAligned ? (\n <>\n {sortIcon} {children}\n </>\n ) : (\n <>\n {children} {sortIcon}\n </>\n )}\n </chakra.button>\n </Table.ColumnHeader>\n );\n },\n);\n\nBitkitSortableColumnHeader.displayName = 'BitkitTable.SortableColumnHeader';\n\nexport default BitkitSortableColumnHeader;\n"],"mappings":";;;;;;AAYA,IAAM,WAAW,YAAY,OAAiD,QAA4B;CACxG,MAAM,EAAE,WAAW,GAAG,SAAS;CAC/B,MAAM,SAAS,cAAc,cAAc,iBAAiB;CAC5D,MAAM,WAAW,cAAc,eAAe,iBAAiB;CAE/D,OACE,oBAAC,MAAD;EACO;EACL,SAAA;EACA,KAAK;GACH,wBAAwB;GACxB,OAAO;GACP,SAAS;GACT,eAAe;EACjB;EACA,GAAI;EAEJ,UAAA,qBAAC,OAAD;GAAK,MAAK;GAAO,QAAO;GAAK,SAAQ;GAAY,OAAM;GAAK,OAAM;GAAlE,UAAA,CACE,oBAAC,QAAD;IACE,GAAE;IACF,MAAM;GACP,CAAA,GACD,oBAAC,QAAD;IACE,GAAE;IACF,MAAM;GACP,CAAA,CACE;;CACD,CAAA;AAEV,CAAC;AAED,SAAS,cAAc;AAEvB,IAAM,6BAA6B,YAChC,EAAE,UAAU,KAAK,WAAW,QAAQ,WAAW,GAAG,QAAQ,QAAQ;CACjE,MAAM,SAAS,eAAe;CAC9B,MAAM,eAAe,cAAc;CACnC,MAAM,WAAW,oBAAC,UAAD,EAAqB,UAAY,CAAA;CAElD,OACE,oBAAC,MAAM,cAAP;EACO;EACL,aAAW,cAAc,SAAS,KAAA,IAAY;EAC9C,KAAK,CAAC,OAAO,kBAAkB,GAAG;EAClC,GAAI;EAGJ,UAAA,oBAAC,OAAO,QAAR;GACE,KAAK,OAAO;GACZ,gBAAgB,eAAe,aAAa,KAAA;GAC5C,SAAS;GACT,MAAK;GAEJ,UAAA,eACC,qBAAA,YAAA,EAAA,UAAA;IACG;IAAS;IAAE;GACZ,EAAA,CAAA,IAEF,qBAAA,YAAA,EAAA,UAAA;IACG;IAAS;IAAE;GACZ,EAAA,CAAA;EAES,CAAA;CACG,CAAA;AAExB,CACF;AAEA,2BAA2B,cAAc"}
|
|
@@ -5,11 +5,11 @@ import { jsx, jsxs } from "react/jsx-runtime";
|
|
|
5
5
|
import { Card } from "@chakra-ui/react/card";
|
|
6
6
|
//#region lib/components/BitkitTableCard/BitkitTableCard.tsx
|
|
7
7
|
var BitkitTableCard = forwardRef((props, ref) => {
|
|
8
|
-
const { action, children, secondaryText, titleText, ...rest } = props;
|
|
8
|
+
const { action, children, css, secondaryText, titleText, ...rest } = props;
|
|
9
9
|
const styles = useSlotRecipe({ key: "tableCard" })();
|
|
10
10
|
return /* @__PURE__ */ jsxs(Card.Root, {
|
|
11
11
|
ref,
|
|
12
|
-
css: styles.root,
|
|
12
|
+
css: [styles.root, css],
|
|
13
13
|
elevation: false,
|
|
14
14
|
...rest,
|
|
15
15
|
children: [/* @__PURE__ */ jsx(Card.Header, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BitkitTableCard.js","names":[],"sources":["../../../lib/components/BitkitTableCard/BitkitTableCard.tsx"],"sourcesContent":["import { Box } from '@chakra-ui/react/box';\nimport { Card, type CardRootProps } from '@chakra-ui/react/card';\nimport { useSlotRecipe } from '@chakra-ui/react/styled-system';\nimport { forwardRef, type ReactNode } from 'react';\n\nexport interface BitkitTableCardProps extends Omit<CardRootProps, 'children'> {\n /** Trailing action in the header, e.g. a `BitkitButton`. Omit it and the header is title-only. */\n action?: ReactNode;\n /** The table filling the card. Use `<BitkitTable.Root variant=\"card\">` so it matches the card's frame. */\n children: ReactNode;\n /** Quieter second line under the title. */\n secondaryText?: ReactNode;\n /** The card's heading. Named like `BitkitAlert`'s so the native `title` attribute stays free. */\n titleText: ReactNode;\n}\n\nconst BitkitTableCard = forwardRef<HTMLDivElement, BitkitTableCardProps>((props, ref) => {\n const { action, children, secondaryText, titleText, ...rest } = props;\n\n const recipe = useSlotRecipe({ key: 'tableCard' });\n const styles = recipe();\n\n return (\n <Card.Root ref={ref} css={styles.root} elevation={false} {...rest}>\n <Card.Header css={styles.header}>\n <Box css={styles.contentBlock}>\n <Box css={styles.titleBlock}>\n <Card.Title css={styles.title}>{titleText}</Card.Title>\n {secondaryText && <Card.Description css={styles.description}>{secondaryText}</Card.Description>}\n </Box>\n {action}\n </Box>\n </Card.Header>\n <Card.Body css={styles.body}>{children}</Card.Body>\n </Card.Root>\n );\n});\n\nBitkitTableCard.displayName = 'BitkitTableCard';\n\nexport default BitkitTableCard;\n"],"mappings":";;;;;;AAgBA,IAAM,kBAAkB,YAAkD,OAAO,QAAQ;CACvF,MAAM,EAAE,QAAQ,UAAU,eAAe,WAAW,GAAG,SAAS;
|
|
1
|
+
{"version":3,"file":"BitkitTableCard.js","names":[],"sources":["../../../lib/components/BitkitTableCard/BitkitTableCard.tsx"],"sourcesContent":["import { Box } from '@chakra-ui/react/box';\nimport { Card, type CardRootProps } from '@chakra-ui/react/card';\nimport { useSlotRecipe } from '@chakra-ui/react/styled-system';\nimport { forwardRef, type ReactNode } from 'react';\n\nexport interface BitkitTableCardProps extends Omit<CardRootProps, 'children'> {\n /** Trailing action in the header, e.g. a `BitkitButton`. Omit it and the header is title-only. */\n action?: ReactNode;\n /** The table filling the card. Use `<BitkitTable.Root variant=\"card\">` so it matches the card's frame. */\n children: ReactNode;\n /** Quieter second line under the title. */\n secondaryText?: ReactNode;\n /** The card's heading. Named like `BitkitAlert`'s so the native `title` attribute stays free. */\n titleText: ReactNode;\n}\n\nconst BitkitTableCard = forwardRef<HTMLDivElement, BitkitTableCardProps>((props, ref) => {\n const { action, children, css, secondaryText, titleText, ...rest } = props;\n\n const recipe = useSlotRecipe({ key: 'tableCard' });\n const styles = recipe();\n\n return (\n <Card.Root ref={ref} css={[styles.root, css]} elevation={false} {...rest}>\n <Card.Header css={styles.header}>\n <Box css={styles.contentBlock}>\n <Box css={styles.titleBlock}>\n <Card.Title css={styles.title}>{titleText}</Card.Title>\n {secondaryText && <Card.Description css={styles.description}>{secondaryText}</Card.Description>}\n </Box>\n {action}\n </Box>\n </Card.Header>\n <Card.Body css={styles.body}>{children}</Card.Body>\n </Card.Root>\n );\n});\n\nBitkitTableCard.displayName = 'BitkitTableCard';\n\nexport default BitkitTableCard;\n"],"mappings":";;;;;;AAgBA,IAAM,kBAAkB,YAAkD,OAAO,QAAQ;CACvF,MAAM,EAAE,QAAQ,UAAU,KAAK,eAAe,WAAW,GAAG,SAAS;CAGrE,MAAM,SADS,cAAc,EAAE,KAAK,YAAY,CACjC,CAAA,CAAO;CAEtB,OACE,qBAAC,KAAK,MAAN;EAAgB;EAAK,KAAK,CAAC,OAAO,MAAM,GAAG;EAAG,WAAW;EAAO,GAAI;EAApE,UAAA,CACE,oBAAC,KAAK,QAAN;GAAa,KAAK,OAAO;GACvB,UAAA,qBAAC,KAAD;IAAK,KAAK,OAAO;IAAjB,UAAA,CACE,qBAAC,KAAD;KAAK,KAAK,OAAO;KAAjB,UAAA,CACE,oBAAC,KAAK,OAAN;MAAY,KAAK,OAAO;MAAQ,UAAA;KAAsB,CAAA,GACrD,iBAAiB,oBAAC,KAAK,aAAN;MAAkB,KAAK,OAAO;MAAc,UAAA;KAAgC,CAAA,CAC3F;IACJ,CAAA,GAAA,MACE;;EACM,CAAA,GACb,oBAAC,KAAK,MAAN;GAAW,KAAK,OAAO;GAAO;EAAoB,CAAA,CACzC;;AAEf,CAAC;AAED,gBAAgB,cAAc"}
|
|
@@ -165,7 +165,7 @@ var AddButton = forwardRef((props, ref) => {
|
|
|
165
165
|
});
|
|
166
166
|
AddButton.displayName = "BitkitTabs.AddButton";
|
|
167
167
|
var List = forwardRef((props, ref) => {
|
|
168
|
-
const { children, id, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledby, ...rest } = props;
|
|
168
|
+
const { children, css, id, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledby, ...rest } = props;
|
|
169
169
|
const { variant = "line" } = useRootPropsContext();
|
|
170
170
|
const api = useTabsContext();
|
|
171
171
|
const styles = useTabsStyles();
|
|
@@ -247,7 +247,7 @@ var List = forwardRef((props, ref) => {
|
|
|
247
247
|
const hiddenItems = visible ? items.filter((_, i) => !visible.has(i)) : [];
|
|
248
248
|
return /* @__PURE__ */ jsxs(Box, {
|
|
249
249
|
ref: setListRef,
|
|
250
|
-
css: styles.list,
|
|
250
|
+
css: [styles.list, css],
|
|
251
251
|
...rest,
|
|
252
252
|
children: [
|
|
253
253
|
/* @__PURE__ */ jsx(Tabs.List, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BitkitTabs.js","names":[],"sources":["../../../lib/components/BitkitTabs/BitkitTabs.tsx"],"sourcesContent":["// eslint-disable-next-line no-restricted-imports\nimport { createContext, mergeRefs, useSafeLayoutEffect } from '@chakra-ui/react';\nimport { Box } from '@chakra-ui/react/box';\nimport { Menu } from '@chakra-ui/react/menu';\nimport { Portal } from '@chakra-ui/react/portal';\nimport { chakra, useRecipe } from '@chakra-ui/react/styled-system';\nimport { Tabs, useTabsContext, useTabsStyles } from '@chakra-ui/react/tabs';\nimport { Text } from '@chakra-ui/react/text';\nimport {\n cloneElement,\n forwardRef,\n type KeyboardEvent,\n type MouseEvent,\n type ReactElement,\n type ReactNode,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\n\nimport { type BitkitIconComponent, IconCross, IconPlus } from '../../icons';\nimport { flattenChildren } from '../../utilities/flattenChildren';\nimport BitkitControlButton, { type BitkitControlButtonProps } from '../BitkitControlButton/BitkitControlButton';\n\n/**\n * Root props. `onValueChange` is re-declared with a concrete `{ value }` arg so the callback\n * parameter is inferred at the call site: the base `Tabs.RootProps` intersection breaks\n * contextual typing, which otherwise leaves consumers' `({ value }) => …` flagged as an\n * implicit `any` under `noImplicitAny`.\n */\nexport type BitkitTabsRootProps = Omit<Tabs.RootProps, 'onValueChange'> & {\n onValueChange?: (details: { value: string }) => void;\n};\n\nexport const [RootPropsProvider, useRootPropsContext] = createContext<BitkitTabsRootProps>({\n name: 'RootPropsContext',\n hookName: 'useRootPropsContext',\n providerName: '<RootProps />',\n});\n\nconst Root = forwardRef<HTMLDivElement, BitkitTabsRootProps>((props, ref) => {\n return (\n <RootPropsProvider value={props}>\n <Tabs.Root ref={ref} {...props} />\n </RootPropsProvider>\n );\n});\n\n/** Status-dot colors for the `canvas` variant. */\nexport type BitkitTabsStatusColor = 'neutral' | 'purple' | 'red' | 'yellow';\n\nconst STATUS_COLOR_TOKEN: Record<BitkitTabsStatusColor, string> = {\n neutral: 'color/neutral/muted',\n purple: 'interactive/bold',\n red: 'color/red/base',\n yellow: 'color/yellow/bold',\n};\n\ntype TriggerProps = Tabs.TriggerProps & {\n badge?: ReactNode;\n children?: string;\n icon?: BitkitIconComponent;\n /** `canvas` variant only — when provided, a close button reveals on hover and calls this handler when clicked. */\n onClose?: () => void;\n secondaryText?: ReactNode;\n /** `canvas` variant only — shows a status indicator dot. When hovered (and `onClose` is set), the close button replaces it. */\n statusColor?: BitkitTabsStatusColor;\n};\n\nRoot.displayName = 'BitkitTabs.Root';\n\nconst Trigger = forwardRef<HTMLButtonElement, TriggerProps>((props, ref) => {\n const { badge, children, className, icon: Icon, onClose, onKeyDown, secondaryText, statusColor, ...rest } = props;\n // Mirror the recipe's defaultVariant so an unset `variant` renders the line layout (not the\n // contained one) — otherwise an undefined variant would fall through to the contained branch.\n const { variant = 'line' } = useRootPropsContext();\n const closeButtonRecipe = useRecipe({ key: 'closeButton' });\n\n // Close button and status dot are exclusive to the canvas variant.\n const isCanvas = variant === 'canvas';\n const closable = isCanvas && !!onClose && !rest.disabled;\n const hasStatus = isCanvas && !!statusColor && !rest.disabled;\n const showTrailing = closable || hasStatus;\n const mergedClassName = showTrailing ? (className ? `group ${className}` : 'group') : className;\n // The close button is always visible when there is no status dot; when the dot is shown it is\n // revealed on hover/focus instead (replacing the dot).\n const revealCloseOnInteraction = closable && hasStatus;\n const revealOnInteraction = { opacity: 1, pointerEvents: 'auto' } as const;\n\n const handleCloseClick = (event: MouseEvent<HTMLSpanElement>) => {\n event.stopPropagation();\n event.preventDefault();\n onClose?.();\n };\n\n // The close control is not in the tab order; keyboard users close the focused tab with Delete/Backspace.\n const handleTriggerKeyDown = (event: KeyboardEvent<HTMLButtonElement>) => {\n if (closable && (event.key === 'Delete' || event.key === 'Backspace')) {\n event.preventDefault();\n // Move focus to a sibling tab before removal so keyboard navigation can continue.\n const trigger = event.currentTarget;\n // Skip overflowed (`hidden`) tabs — they aren't focusable.\n const triggers = [\n ...(trigger.closest('[role=\"tablist\"]')?.querySelectorAll<HTMLElement>('[role=\"tab\"]:not([hidden])') ?? []),\n ];\n const index = triggers.indexOf(trigger);\n (triggers[index + 1] ?? triggers[index - 1])?.focus();\n onClose?.();\n }\n onKeyDown?.(event);\n };\n\n const trailing = showTrailing ? (\n <chakra.span\n position=\"relative\"\n display=\"flex\"\n alignItems=\"center\"\n justifyContent=\"center\"\n boxSize=\"24\"\n flexShrink={0}\n >\n {hasStatus && statusColor && (\n <chakra.span\n position=\"absolute\"\n inset={0}\n display=\"flex\"\n alignItems=\"center\"\n justifyContent=\"center\"\n pointerEvents=\"none\"\n transition=\"opacity 0.1s\"\n _groupHover={closable ? { opacity: 0 } : undefined}\n _groupFocusWithin={closable ? { opacity: 0 } : undefined}\n >\n <chakra.span boxSize=\"8\" borderRadius=\"full\" backgroundColor={STATUS_COLOR_TOKEN[statusColor]} />\n </chakra.span>\n )}\n {closable && (\n <chakra.span\n aria-hidden\n tabIndex={-1}\n onClick={handleCloseClick}\n css={closeButtonRecipe({ size: 'xs' })}\n position=\"absolute\"\n inset={0}\n color=\"icon/primary\"\n opacity={revealCloseOnInteraction ? 0 : 1}\n pointerEvents={revealCloseOnInteraction ? 'none' : 'auto'}\n transition=\"opacity 0.1s\"\n _groupHover={revealCloseOnInteraction ? revealOnInteraction : undefined}\n _groupFocusWithin={revealCloseOnInteraction ? revealOnInteraction : undefined}\n >\n <IconCross size=\"16\" />\n </chakra.span>\n )}\n </chakra.span>\n ) : null;\n\n return (\n <Tabs.Trigger\n ref={ref}\n {...rest}\n className={mergedClassName}\n gap={isCanvas ? '4' : showTrailing ? '12' : undefined}\n onKeyDown={handleTriggerKeyDown}\n paddingInlineEnd={isCanvas ? (showTrailing ? '8' : undefined) : showTrailing ? '12' : undefined}\n paddingInlineStart={isCanvas && Icon ? '8' : undefined}\n >\n {isCanvas ? (\n <>\n <Box display=\"flex\" alignItems=\"center\" gap=\"8\">\n {Icon && <Icon size=\"16\" />}\n {children}\n </Box>\n {trailing}\n </>\n ) : variant === 'line' ? (\n <>\n <Box display=\"flex\" alignItems=\"center\" gap=\"8\">\n {Icon && <Icon size=\"24\" />}\n {children}\n {badge}\n </Box>\n {trailing}\n </>\n ) : (\n <>\n <Box display=\"flex\" gap=\"16\">\n {children}\n {badge}\n {Icon && <Icon size=\"24\" />}\n </Box>\n {!!secondaryText && (\n <Text as=\"span\" textStyle=\"body/md/regular\" color={rest.disabled ? 'text/on-disabled' : 'text/secondary'}>\n {secondaryText}\n </Text>\n )}\n {trailing}\n </>\n )}\n </Tabs.Trigger>\n );\n});\n\nTrigger.displayName = 'BitkitTabs.Trigger';\n\ntype TabItem = ReactElement<TriggerProps>;\n\n// Returns the set of visible tab indices for the overflow, always keeping the selected tab\n// visible: if it would overflow, it takes the last visible slot.\nconst getVisibleIndices = (total: number, count: number, selectedIndex: number) => {\n const visible = new Set<number>();\n for (let i = 0; i < count; i += 1) visible.add(i);\n if (selectedIndex >= 0 && selectedIndex < total && !visible.has(selectedIndex)) {\n visible.delete(count - 1);\n visible.add(selectedIndex);\n }\n return visible;\n};\n\nexport type BitkitTabsAddButtonProps = Omit<\n Extract<BitkitControlButtonProps, { href?: undefined }>,\n 'icon' | 'label' | 'size'\n> & {\n /** Accessible label / tooltip for the add button. */\n label?: string;\n};\n\n// \"+\" button to add a tab. Place it as a child of `List`; it always renders at the end of the row\n// (after the overflow menu). A compact `xxs` control button (16px icon, 4px padding) per the design.\nconst AddButton = forwardRef<HTMLButtonElement, BitkitTabsAddButtonProps>((props, ref) => {\n const { label = 'Add tab', ...rest } = props;\n return <BitkitControlButton ref={ref} icon={IconPlus} label={label} size=\"xxs\" {...rest} />;\n});\n\nAddButton.displayName = 'BitkitTabs.AddButton';\n\n// Overflow-aware List (all variants): measures the tabs and collapses the overflowing ones into a\n// \"N more…\" menu. The more-button look comes from the variant's `moreTrigger` recipe slot.\nconst List = forwardRef<HTMLDivElement, Tabs.ListProps>((props, ref) => {\n // Semantic/labelling attributes belong on the actual tablist, not the visual wrapper.\n const { children, id, 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledby, ...rest } = props;\n const { variant = 'line' } = useRootPropsContext();\n const api = useTabsContext();\n const styles = useTabsStyles();\n\n // Split children: tab triggers participate in overflow; the optional add button always renders last.\n const allChildren = flattenChildren(children);\n const addButton = allChildren.find((child) => child.type === AddButton) ?? null;\n // Only Trigger elements are measured/overflowed; anything else (fragments, stray nodes) is ignored.\n const items = allChildren.filter((child) => child.type === Trigger) as TabItem[];\n // Re-measure whenever the tab set OR any width-affecting input changes — the variant, each tab's\n // value/label, icon/status/close/disabled state, and badge/secondaryText content (best-effort\n // string form, so width-changing text like \"3 errors\" → \"12 errors\" invalidates the cache).\n const measureKey =\n variant +\n items\n .map((item) => {\n const p = item.props;\n return [\n p.value,\n String(p.children),\n p.icon ? 'i' : '',\n p.badge ? String(p.badge) : '',\n p.secondaryText ? String(p.secondaryText) : '',\n p.statusColor ?? '',\n p.onClose ? 'c' : '',\n p.disabled ? 'd' : '',\n ].join(':');\n })\n .join('|');\n const selectedIndex = items.findIndex((item) => item.props.value === api.value);\n // Conservative width reservations: the more button (wider for the lg/semibold variants) and the\n // always-visible add button.\n const moreReserve = variant === 'canvas' ? 100 : 140;\n const addReserve = addButton ? 48 : 0;\n\n const listRef = useRef<HTMLDivElement | null>(null);\n const widthsRef = useRef<number[]>([]);\n // Horizontal padding of the list, cached during the measure pass so the resize hot path doesn't\n // call getComputedStyle on every tick.\n const paddingRef = useRef(0);\n // `measuredKey` is state (not a ref) so finishing the measure pass always re-renders and flips\n // `measuring` off — even when recompute keeps the same visibleCount (which would skip a re-render).\n const [measuredKey, setMeasuredKey] = useState<string | null>(null);\n const [visibleCount, setVisibleCount] = useState(items.length);\n\n const setListRef = useMemo(() => mergeRefs(listRef, ref), [ref]);\n\n const recompute = useCallback(() => {\n const el = listRef.current;\n const widths = widthsRef.current;\n if (!el || !widths.length) return;\n const available = el.clientWidth - paddingRef.current - addReserve;\n const totalWidth = widths.reduce((sum, w) => sum + w, 0);\n if (totalWidth <= available) {\n setVisibleCount(widths.length);\n return;\n }\n let used = moreReserve;\n let count = 0;\n for (let i = 0; i < widths.length; i += 1) {\n if (used + widths[i] > available) break;\n used += widths[i];\n count += 1;\n }\n setVisibleCount(Math.max(count, 1));\n }, [addReserve, moreReserve]);\n\n // Measure once per width-affecting change (all tabs are rendered visible during this pass).\n // Isomorphic layout effect: avoids the SSR \"useLayoutEffect does nothing on the server\" warning.\n const measuring = measuredKey !== measureKey;\n useSafeLayoutEffect(() => {\n const el = listRef.current;\n if (!el) return;\n if (measuredKey !== measureKey) {\n const tabEls = el.querySelectorAll<HTMLElement>('[data-tab-trigger]');\n widthsRef.current = Array.from(tabEls, (node) => node.offsetWidth);\n const cs = getComputedStyle(el);\n paddingRef.current = parseFloat(cs.paddingLeft) + parseFloat(cs.paddingRight);\n setMeasuredKey(measureKey);\n }\n recompute();\n }, [measureKey, measuredKey, recompute]);\n\n useEffect(() => {\n const el = listRef.current;\n if (!el || typeof ResizeObserver === 'undefined') return;\n // Coalesce resize bursts into one recompute per frame to avoid a read/write layout storm.\n let raf = 0;\n const observer = new ResizeObserver(() => {\n cancelAnimationFrame(raf);\n raf = requestAnimationFrame(recompute);\n });\n observer.observe(el);\n return () => {\n cancelAnimationFrame(raf);\n observer.disconnect();\n };\n }, [recompute]);\n\n const showAll = measuring || visibleCount >= items.length;\n const visible = showAll ? null : getVisibleIndices(items.length, visibleCount, selectedIndex);\n const hiddenItems = visible ? items.filter((_, i) => !visible.has(i)) : [];\n\n return (\n // The visual row carries the list styling (background, baseline border, leading padding) and is\n // measured for overflow. The tablist itself only wraps the tabs (`display: contents` keeps the\n // flex layout intact), so the more/add controls stay outside `role=\"tablist\"` per the ARIA spec.\n <Box ref={setListRef} css={styles.list} {...rest}>\n <Tabs.List display=\"contents\" id={id} aria-label={ariaLabel} aria-labelledby={ariaLabelledby}>\n {items.map((item, i) =>\n cloneElement(item, {\n key: item.props.value,\n 'data-tab-trigger': '',\n hidden: visible ? !visible.has(i) : undefined,\n } as Partial<TriggerProps>),\n )}\n </Tabs.List>\n {hiddenItems.length > 0 && (\n <Menu.Root size=\"md\" positioning={{ gutter: 0, shift: -4 }}>\n <Menu.Trigger asChild>\n <chakra.button type=\"button\" css={styles.moreTrigger}>\n {hiddenItems.length} more…\n </chakra.button>\n </Menu.Trigger>\n <Portal>\n <Menu.Positioner>\n <Menu.Content>\n {hiddenItems.map((item) => (\n <Menu.Item\n key={item.props.value}\n value={item.props.value}\n disabled={item.props.disabled}\n onSelect={() => api.setValue(item.props.value)}\n alignItems=\"center\"\n >\n <Text flex=\"1\" color={item.props.disabled ? 'text/on-disabled' : 'inherit'}>\n {item.props.children}\n </Text>\n {variant === 'canvas' && item.props.statusColor && (\n <chakra.span\n boxSize=\"8\"\n borderRadius=\"full\"\n flexShrink={0}\n backgroundColor={STATUS_COLOR_TOKEN[item.props.statusColor]}\n />\n )}\n </Menu.Item>\n ))}\n </Menu.Content>\n </Menu.Positioner>\n </Portal>\n </Menu.Root>\n )}\n {addButton && (\n <Box display=\"flex\" alignItems=\"center\" flexShrink={0} paddingInline=\"8\">\n {addButton}\n </Box>\n )}\n </Box>\n );\n});\n\nList.displayName = 'BitkitTabs.List';\n\nconst BitkitTabs: Omit<typeof Tabs, 'Root' | 'Trigger' | 'List'> & {\n AddButton: typeof AddButton;\n List: typeof List;\n Root: typeof Root;\n Trigger: typeof Trigger;\n} = {\n ...Tabs,\n AddButton,\n List,\n Root,\n Trigger,\n};\n\nBitkitTabs.Content.displayName = 'BitkitTabs.Content';\nBitkitTabs.ContentGroup.displayName = 'BitkitTabs.ContentGroup';\nBitkitTabs.Root.displayName = 'BitkitTabs.Root';\n\nexport default BitkitTabs;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"BitkitTabs.js","names":[],"sources":["../../../lib/components/BitkitTabs/BitkitTabs.tsx"],"sourcesContent":["// eslint-disable-next-line no-restricted-imports\nimport { createContext, mergeRefs, useSafeLayoutEffect } from '@chakra-ui/react';\nimport { Box } from '@chakra-ui/react/box';\nimport { Menu } from '@chakra-ui/react/menu';\nimport { Portal } from '@chakra-ui/react/portal';\nimport { chakra, useRecipe } from '@chakra-ui/react/styled-system';\nimport { Tabs, useTabsContext, useTabsStyles } from '@chakra-ui/react/tabs';\nimport { Text } from '@chakra-ui/react/text';\nimport {\n cloneElement,\n forwardRef,\n type KeyboardEvent,\n type MouseEvent,\n type ReactElement,\n type ReactNode,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\n\nimport { type BitkitIconComponent, IconCross, IconPlus } from '../../icons';\nimport { flattenChildren } from '../../utilities/flattenChildren';\nimport BitkitControlButton, { type BitkitControlButtonProps } from '../BitkitControlButton/BitkitControlButton';\n\n/**\n * Root props. `onValueChange` is re-declared with a concrete `{ value }` arg so the callback\n * parameter is inferred at the call site: the base `Tabs.RootProps` intersection breaks\n * contextual typing, which otherwise leaves consumers' `({ value }) => …` flagged as an\n * implicit `any` under `noImplicitAny`.\n */\nexport type BitkitTabsRootProps = Omit<Tabs.RootProps, 'onValueChange'> & {\n onValueChange?: (details: { value: string }) => void;\n};\n\nexport const [RootPropsProvider, useRootPropsContext] = createContext<BitkitTabsRootProps>({\n name: 'RootPropsContext',\n hookName: 'useRootPropsContext',\n providerName: '<RootProps />',\n});\n\nconst Root = forwardRef<HTMLDivElement, BitkitTabsRootProps>((props, ref) => {\n return (\n <RootPropsProvider value={props}>\n <Tabs.Root ref={ref} {...props} />\n </RootPropsProvider>\n );\n});\n\n/** Status-dot colors for the `canvas` variant. */\nexport type BitkitTabsStatusColor = 'neutral' | 'purple' | 'red' | 'yellow';\n\nconst STATUS_COLOR_TOKEN: Record<BitkitTabsStatusColor, string> = {\n neutral: 'color/neutral/muted',\n purple: 'interactive/bold',\n red: 'color/red/base',\n yellow: 'color/yellow/bold',\n};\n\ntype TriggerProps = Tabs.TriggerProps & {\n badge?: ReactNode;\n children?: string;\n icon?: BitkitIconComponent;\n /** `canvas` variant only — when provided, a close button reveals on hover and calls this handler when clicked. */\n onClose?: () => void;\n secondaryText?: ReactNode;\n /** `canvas` variant only — shows a status indicator dot. When hovered (and `onClose` is set), the close button replaces it. */\n statusColor?: BitkitTabsStatusColor;\n};\n\nRoot.displayName = 'BitkitTabs.Root';\n\nconst Trigger = forwardRef<HTMLButtonElement, TriggerProps>((props, ref) => {\n const { badge, children, className, icon: Icon, onClose, onKeyDown, secondaryText, statusColor, ...rest } = props;\n // Mirror the recipe's defaultVariant so an unset `variant` renders the line layout (not the\n // contained one) — otherwise an undefined variant would fall through to the contained branch.\n const { variant = 'line' } = useRootPropsContext();\n const closeButtonRecipe = useRecipe({ key: 'closeButton' });\n\n // Close button and status dot are exclusive to the canvas variant.\n const isCanvas = variant === 'canvas';\n const closable = isCanvas && !!onClose && !rest.disabled;\n const hasStatus = isCanvas && !!statusColor && !rest.disabled;\n const showTrailing = closable || hasStatus;\n const mergedClassName = showTrailing ? (className ? `group ${className}` : 'group') : className;\n // The close button is always visible when there is no status dot; when the dot is shown it is\n // revealed on hover/focus instead (replacing the dot).\n const revealCloseOnInteraction = closable && hasStatus;\n const revealOnInteraction = { opacity: 1, pointerEvents: 'auto' } as const;\n\n const handleCloseClick = (event: MouseEvent<HTMLSpanElement>) => {\n event.stopPropagation();\n event.preventDefault();\n onClose?.();\n };\n\n // The close control is not in the tab order; keyboard users close the focused tab with Delete/Backspace.\n const handleTriggerKeyDown = (event: KeyboardEvent<HTMLButtonElement>) => {\n if (closable && (event.key === 'Delete' || event.key === 'Backspace')) {\n event.preventDefault();\n // Move focus to a sibling tab before removal so keyboard navigation can continue.\n const trigger = event.currentTarget;\n // Skip overflowed (`hidden`) tabs — they aren't focusable.\n const triggers = [\n ...(trigger.closest('[role=\"tablist\"]')?.querySelectorAll<HTMLElement>('[role=\"tab\"]:not([hidden])') ?? []),\n ];\n const index = triggers.indexOf(trigger);\n (triggers[index + 1] ?? triggers[index - 1])?.focus();\n onClose?.();\n }\n onKeyDown?.(event);\n };\n\n const trailing = showTrailing ? (\n <chakra.span\n position=\"relative\"\n display=\"flex\"\n alignItems=\"center\"\n justifyContent=\"center\"\n boxSize=\"24\"\n flexShrink={0}\n >\n {hasStatus && statusColor && (\n <chakra.span\n position=\"absolute\"\n inset={0}\n display=\"flex\"\n alignItems=\"center\"\n justifyContent=\"center\"\n pointerEvents=\"none\"\n transition=\"opacity 0.1s\"\n _groupHover={closable ? { opacity: 0 } : undefined}\n _groupFocusWithin={closable ? { opacity: 0 } : undefined}\n >\n <chakra.span boxSize=\"8\" borderRadius=\"full\" backgroundColor={STATUS_COLOR_TOKEN[statusColor]} />\n </chakra.span>\n )}\n {closable && (\n <chakra.span\n aria-hidden\n tabIndex={-1}\n onClick={handleCloseClick}\n css={closeButtonRecipe({ size: 'xs' })}\n position=\"absolute\"\n inset={0}\n color=\"icon/primary\"\n opacity={revealCloseOnInteraction ? 0 : 1}\n pointerEvents={revealCloseOnInteraction ? 'none' : 'auto'}\n transition=\"opacity 0.1s\"\n _groupHover={revealCloseOnInteraction ? revealOnInteraction : undefined}\n _groupFocusWithin={revealCloseOnInteraction ? revealOnInteraction : undefined}\n >\n <IconCross size=\"16\" />\n </chakra.span>\n )}\n </chakra.span>\n ) : null;\n\n return (\n <Tabs.Trigger\n ref={ref}\n {...rest}\n className={mergedClassName}\n gap={isCanvas ? '4' : showTrailing ? '12' : undefined}\n onKeyDown={handleTriggerKeyDown}\n paddingInlineEnd={isCanvas ? (showTrailing ? '8' : undefined) : showTrailing ? '12' : undefined}\n paddingInlineStart={isCanvas && Icon ? '8' : undefined}\n >\n {isCanvas ? (\n <>\n <Box display=\"flex\" alignItems=\"center\" gap=\"8\">\n {Icon && <Icon size=\"16\" />}\n {children}\n </Box>\n {trailing}\n </>\n ) : variant === 'line' ? (\n <>\n <Box display=\"flex\" alignItems=\"center\" gap=\"8\">\n {Icon && <Icon size=\"24\" />}\n {children}\n {badge}\n </Box>\n {trailing}\n </>\n ) : (\n <>\n <Box display=\"flex\" gap=\"16\">\n {children}\n {badge}\n {Icon && <Icon size=\"24\" />}\n </Box>\n {!!secondaryText && (\n <Text as=\"span\" textStyle=\"body/md/regular\" color={rest.disabled ? 'text/on-disabled' : 'text/secondary'}>\n {secondaryText}\n </Text>\n )}\n {trailing}\n </>\n )}\n </Tabs.Trigger>\n );\n});\n\nTrigger.displayName = 'BitkitTabs.Trigger';\n\ntype TabItem = ReactElement<TriggerProps>;\n\n// Returns the set of visible tab indices for the overflow, always keeping the selected tab\n// visible: if it would overflow, it takes the last visible slot.\nconst getVisibleIndices = (total: number, count: number, selectedIndex: number) => {\n const visible = new Set<number>();\n for (let i = 0; i < count; i += 1) visible.add(i);\n if (selectedIndex >= 0 && selectedIndex < total && !visible.has(selectedIndex)) {\n visible.delete(count - 1);\n visible.add(selectedIndex);\n }\n return visible;\n};\n\nexport type BitkitTabsAddButtonProps = Omit<\n Extract<BitkitControlButtonProps, { href?: undefined }>,\n 'icon' | 'label' | 'size'\n> & {\n /** Accessible label / tooltip for the add button. */\n label?: string;\n};\n\n// \"+\" button to add a tab. Place it as a child of `List`; it always renders at the end of the row\n// (after the overflow menu). A compact `xxs` control button (16px icon, 4px padding) per the design.\nconst AddButton = forwardRef<HTMLButtonElement, BitkitTabsAddButtonProps>((props, ref) => {\n const { label = 'Add tab', ...rest } = props;\n return <BitkitControlButton ref={ref} icon={IconPlus} label={label} size=\"xxs\" {...rest} />;\n});\n\nAddButton.displayName = 'BitkitTabs.AddButton';\n\n// Overflow-aware List (all variants): measures the tabs and collapses the overflowing ones into a\n// \"N more…\" menu. The more-button look comes from the variant's `moreTrigger` recipe slot.\nconst List = forwardRef<HTMLDivElement, Tabs.ListProps>((props, ref) => {\n // Semantic/labelling attributes belong on the actual tablist, not the visual wrapper.\n const { children, css, id, 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledby, ...rest } = props;\n const { variant = 'line' } = useRootPropsContext();\n const api = useTabsContext();\n const styles = useTabsStyles();\n\n // Split children: tab triggers participate in overflow; the optional add button always renders last.\n const allChildren = flattenChildren(children);\n const addButton = allChildren.find((child) => child.type === AddButton) ?? null;\n // Only Trigger elements are measured/overflowed; anything else (fragments, stray nodes) is ignored.\n const items = allChildren.filter((child) => child.type === Trigger) as TabItem[];\n // Re-measure whenever the tab set OR any width-affecting input changes — the variant, each tab's\n // value/label, icon/status/close/disabled state, and badge/secondaryText content (best-effort\n // string form, so width-changing text like \"3 errors\" → \"12 errors\" invalidates the cache).\n const measureKey =\n variant +\n items\n .map((item) => {\n const p = item.props;\n return [\n p.value,\n String(p.children),\n p.icon ? 'i' : '',\n p.badge ? String(p.badge) : '',\n p.secondaryText ? String(p.secondaryText) : '',\n p.statusColor ?? '',\n p.onClose ? 'c' : '',\n p.disabled ? 'd' : '',\n ].join(':');\n })\n .join('|');\n const selectedIndex = items.findIndex((item) => item.props.value === api.value);\n // Conservative width reservations: the more button (wider for the lg/semibold variants) and the\n // always-visible add button.\n const moreReserve = variant === 'canvas' ? 100 : 140;\n const addReserve = addButton ? 48 : 0;\n\n const listRef = useRef<HTMLDivElement | null>(null);\n const widthsRef = useRef<number[]>([]);\n // Horizontal padding of the list, cached during the measure pass so the resize hot path doesn't\n // call getComputedStyle on every tick.\n const paddingRef = useRef(0);\n // `measuredKey` is state (not a ref) so finishing the measure pass always re-renders and flips\n // `measuring` off — even when recompute keeps the same visibleCount (which would skip a re-render).\n const [measuredKey, setMeasuredKey] = useState<string | null>(null);\n const [visibleCount, setVisibleCount] = useState(items.length);\n\n const setListRef = useMemo(() => mergeRefs(listRef, ref), [ref]);\n\n const recompute = useCallback(() => {\n const el = listRef.current;\n const widths = widthsRef.current;\n if (!el || !widths.length) return;\n const available = el.clientWidth - paddingRef.current - addReserve;\n const totalWidth = widths.reduce((sum, w) => sum + w, 0);\n if (totalWidth <= available) {\n setVisibleCount(widths.length);\n return;\n }\n let used = moreReserve;\n let count = 0;\n for (let i = 0; i < widths.length; i += 1) {\n if (used + widths[i] > available) break;\n used += widths[i];\n count += 1;\n }\n setVisibleCount(Math.max(count, 1));\n }, [addReserve, moreReserve]);\n\n // Measure once per width-affecting change (all tabs are rendered visible during this pass).\n // Isomorphic layout effect: avoids the SSR \"useLayoutEffect does nothing on the server\" warning.\n const measuring = measuredKey !== measureKey;\n useSafeLayoutEffect(() => {\n const el = listRef.current;\n if (!el) return;\n if (measuredKey !== measureKey) {\n const tabEls = el.querySelectorAll<HTMLElement>('[data-tab-trigger]');\n widthsRef.current = Array.from(tabEls, (node) => node.offsetWidth);\n const cs = getComputedStyle(el);\n paddingRef.current = parseFloat(cs.paddingLeft) + parseFloat(cs.paddingRight);\n setMeasuredKey(measureKey);\n }\n recompute();\n }, [measureKey, measuredKey, recompute]);\n\n useEffect(() => {\n const el = listRef.current;\n if (!el || typeof ResizeObserver === 'undefined') return;\n // Coalesce resize bursts into one recompute per frame to avoid a read/write layout storm.\n let raf = 0;\n const observer = new ResizeObserver(() => {\n cancelAnimationFrame(raf);\n raf = requestAnimationFrame(recompute);\n });\n observer.observe(el);\n return () => {\n cancelAnimationFrame(raf);\n observer.disconnect();\n };\n }, [recompute]);\n\n const showAll = measuring || visibleCount >= items.length;\n const visible = showAll ? null : getVisibleIndices(items.length, visibleCount, selectedIndex);\n const hiddenItems = visible ? items.filter((_, i) => !visible.has(i)) : [];\n\n return (\n // The visual row carries the list styling (background, baseline border, leading padding) and is\n // measured for overflow. The tablist itself only wraps the tabs (`display: contents` keeps the\n // flex layout intact), so the more/add controls stay outside `role=\"tablist\"` per the ARIA spec.\n <Box ref={setListRef} css={[styles.list, css]} {...rest}>\n <Tabs.List display=\"contents\" id={id} aria-label={ariaLabel} aria-labelledby={ariaLabelledby}>\n {items.map((item, i) =>\n cloneElement(item, {\n key: item.props.value,\n 'data-tab-trigger': '',\n hidden: visible ? !visible.has(i) : undefined,\n } as Partial<TriggerProps>),\n )}\n </Tabs.List>\n {hiddenItems.length > 0 && (\n <Menu.Root size=\"md\" positioning={{ gutter: 0, shift: -4 }}>\n <Menu.Trigger asChild>\n <chakra.button type=\"button\" css={styles.moreTrigger}>\n {hiddenItems.length} more…\n </chakra.button>\n </Menu.Trigger>\n <Portal>\n <Menu.Positioner>\n <Menu.Content>\n {hiddenItems.map((item) => (\n <Menu.Item\n key={item.props.value}\n value={item.props.value}\n disabled={item.props.disabled}\n onSelect={() => api.setValue(item.props.value)}\n alignItems=\"center\"\n >\n <Text flex=\"1\" color={item.props.disabled ? 'text/on-disabled' : 'inherit'}>\n {item.props.children}\n </Text>\n {variant === 'canvas' && item.props.statusColor && (\n <chakra.span\n boxSize=\"8\"\n borderRadius=\"full\"\n flexShrink={0}\n backgroundColor={STATUS_COLOR_TOKEN[item.props.statusColor]}\n />\n )}\n </Menu.Item>\n ))}\n </Menu.Content>\n </Menu.Positioner>\n </Portal>\n </Menu.Root>\n )}\n {addButton && (\n <Box display=\"flex\" alignItems=\"center\" flexShrink={0} paddingInline=\"8\">\n {addButton}\n </Box>\n )}\n </Box>\n );\n});\n\nList.displayName = 'BitkitTabs.List';\n\nconst BitkitTabs: Omit<typeof Tabs, 'Root' | 'Trigger' | 'List'> & {\n AddButton: typeof AddButton;\n List: typeof List;\n Root: typeof Root;\n Trigger: typeof Trigger;\n} = {\n ...Tabs,\n AddButton,\n List,\n Root,\n Trigger,\n};\n\nBitkitTabs.Content.displayName = 'BitkitTabs.Content';\nBitkitTabs.ContentGroup.displayName = 'BitkitTabs.ContentGroup';\nBitkitTabs.Root.displayName = 'BitkitTabs.Root';\n\nexport default BitkitTabs;\n"],"mappings":"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"}
|
|
@@ -28,7 +28,7 @@ var BitkitTextInput = forwardRef((props, ref) => {
|
|
|
28
28
|
size: iconSize
|
|
29
29
|
});
|
|
30
30
|
else if (hasWarning) statusIcon = /* @__PURE__ */ jsx(IconWarningYellow, { size: iconSize });
|
|
31
|
-
const { onChange: inputOnChange, value: inputValue, ...restInputProps } = inputProps ?? {};
|
|
31
|
+
const { css: inputCss, onChange: inputOnChange, value: inputValue, ...restInputProps } = inputProps ?? {};
|
|
32
32
|
const resolvedValue = inputValue ?? value;
|
|
33
33
|
const nativeOnChange = inputOnChange ?? onChange;
|
|
34
34
|
const handleChange = onValueChange || nativeOnChange ? (event) => {
|
|
@@ -69,7 +69,7 @@ var BitkitTextInput = forwardRef((props, ref) => {
|
|
|
69
69
|
children: startElement
|
|
70
70
|
}),
|
|
71
71
|
/* @__PURE__ */ jsx(Input, {
|
|
72
|
-
css: styles.input,
|
|
72
|
+
css: [styles.input, inputCss],
|
|
73
73
|
maxLength,
|
|
74
74
|
onChange: handleChange,
|
|
75
75
|
placeholder,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BitkitTextInput.js","names":[],"sources":["../../../lib/components/BitkitTextInput/BitkitTextInput.tsx"],"sourcesContent":["import { Box } from '@chakra-ui/react/box';\nimport { Group } from '@chakra-ui/react/group';\nimport { Input, type InputProps } from '@chakra-ui/react/input';\nimport { InputAddon, type InputAddonProps } from '@chakra-ui/react/input-addon';\nimport { useSlotRecipe } from '@chakra-ui/react/styled-system';\nimport { type ChangeEventHandler, forwardRef, type ReactNode } from 'react';\n\nimport { IconErrorCircleFilled, IconWarningYellow } from '../../icons';\nimport BitkitField, { type BitkitFieldProps } from '../BitkitField/BitkitField';\n\nexport interface BitkitTextInputProps extends Omit<BitkitFieldProps, 'children' | 'onChange' | 'state' | 'value'> {\n /**\n * Show a live character counter (`length/maxLength`) next to the label. Requires `maxLength` and a\n * known `value`.\n */\n counter?: boolean;\n /** Content attached to the trailing edge, outside the input border (e.g. a unit label or button). */\n endAddon?: ReactNode;\n /** Props forwarded to the trailing `InputAddon` wrapper. */\n endAddonProps?: InputAddonProps;\n /** Inline content rendered inside the input, at the trailing edge (e.g. an icon or reveal button). */\n endElement?: ReactNode;\n /**\n * Escape hatch for the underlying Chakra `Input` — extra native attributes or a spread\n * `{...register()}`. On conflict, values here win over the top-level `value`/`onChange`.\n */\n inputProps?: InputProps;\n /** Maximum number of characters accepted; also feeds the optional `counter`. */\n maxLength?: HTMLInputElement['maxLength'];\n /**\n * Native change event — the same handler you could put on `inputProps`, promoted to the top level.\n * Reach for `onValueChange` when you only need the value. If both this and `inputProps.onChange` are\n * set, `inputProps.onChange` wins (it's the same event, so they shouldn't both be set).\n */\n onChange?: ChangeEventHandler<HTMLInputElement>;\n /** Convenience change handler that receives the value directly, without `event.target.value`. */\n onValueChange?: (value: string) => void;\n /** Placeholder text shown while the field is empty. */\n placeholder?: string;\n /** Field size — controls height and typography. */\n size?: 'md' | 'lg';\n /** Content attached to the leading edge, outside the input border (e.g. a unit label or button). */\n startAddon?: ReactNode;\n /** Props forwarded to the leading `InputAddon` wrapper. */\n startAddonProps?: InputAddonProps;\n /** Inline content rendered inside the input, at the leading edge (e.g. an icon). */\n startElement?: ReactNode;\n /**\n * Field state. `error`/`warning` are also implied by `errorText`/`warningText`; `disabled` and\n * `readOnly` gate interaction.\n */\n state?: 'disabled' | 'error' | 'readOnly' | 'warning';\n /**\n * Controlled value. Pair with `onValueChange` or `onChange`. Can also be supplied via `inputProps`,\n * which wins on conflict.\n */\n value?: string;\n}\n\n/**\n * A single-line text field wrapping the native `<input>`, with a label and helper/error/warning\n * text. Reflect the value with `value` + `onValueChange` (or the native `onChange`); `inputProps` is\n * the escape hatch for any other native attribute. `startAddon`/`endAddon` sit outside the border,\n * `startElement`/`endElement` inline inside it, and `counter` pairs with `maxLength`.\n */\nconst BitkitTextInput = forwardRef<HTMLDivElement, BitkitTextInputProps>((props, ref) => {\n const {\n counter,\n endAddon,\n endAddonProps,\n endElement,\n inputProps,\n maxLength,\n onChange,\n onValueChange,\n placeholder,\n size = 'lg',\n startAddon,\n startAddonProps,\n startElement,\n state,\n value,\n ...rest\n } = props;\n\n const recipe = useSlotRecipe({ key: 'textInput' });\n const styles = recipe({ size });\n\n const iconSize = size === 'md' ? '16' : '24';\n const addonSize = size === 'md' ? 'md' : 'lg';\n\n const hasWarning = state === 'warning' || !!rest.warningText;\n const isInvalid = state === 'error' || !!rest.errorText;\n\n let statusIcon: ReactNode = null;\n if (isInvalid) {\n statusIcon = <IconErrorCircleFilled color=\"icon/negative\" size={iconSize} />;\n } else if (hasWarning) {\n statusIcon = <IconWarningYellow size={iconSize} />;\n }\n\n // `value` / `onChange` may come in at the top level or via `inputProps` — the object wins on\n // conflict (natural for a spread `{...register()}`). `onValueChange` always fires with the value.\n const { onChange: inputOnChange, value: inputValue, ...restInputProps } = inputProps ?? {};\n const resolvedValue = inputValue ?? value;\n const nativeOnChange = inputOnChange ?? onChange;\n const handleChange: ChangeEventHandler<HTMLInputElement> | undefined =\n onValueChange || nativeOnChange\n ? (event) => {\n onValueChange?.(event.target.value);\n nativeOnChange?.(event);\n }\n : undefined;\n\n const counterText =\n counter && maxLength && resolvedValue !== undefined ? `${resolvedValue.toString().length}/${maxLength}` : undefined;\n\n const stateAttrs = {\n 'data-disabled': state === 'disabled' ? '' : undefined,\n 'data-invalid': isInvalid ? '' : undefined,\n 'data-readonly': state === 'readOnly' ? '' : undefined,\n };\n\n return (\n <BitkitField counterText={counterText} ref={ref} state={state} {...rest}>\n <Group attached width=\"100%\">\n {startAddon != null && (\n <InputAddon position=\"start\" size={addonSize} {...stateAttrs} {...startAddonProps}>\n {startAddon}\n </InputAddon>\n )}\n <Box css={styles.field} data-has-end-element={endElement != null ? '' : undefined} flex=\"1\" {...stateAttrs}>\n {startElement != null && (\n <Box css={styles.element} {...stateAttrs}>\n {startElement}\n </Box>\n )}\n <Input\n css={styles.input}\n maxLength={maxLength}\n onChange={handleChange}\n placeholder={placeholder}\n value={resolvedValue}\n {...restInputProps}\n unstyled\n />\n {statusIcon != null && (\n <Box css={styles.element} {...stateAttrs}>\n {statusIcon}\n </Box>\n )}\n {endElement != null && (\n <Box css={styles.element} {...stateAttrs}>\n {endElement}\n </Box>\n )}\n </Box>\n {endAddon != null && (\n <InputAddon position=\"end\" size={addonSize} {...stateAttrs} {...endAddonProps}>\n {endAddon}\n </InputAddon>\n )}\n </Group>\n </BitkitField>\n );\n});\n\nBitkitTextInput.displayName = 'BitkitTextInput';\n\nexport default BitkitTextInput;\n"],"mappings":";;;;;;;;;;;;;;;;;AAiEA,IAAM,kBAAkB,YAAkD,OAAO,QAAQ;CACvF,MAAM,EACJ,SACA,UACA,eACA,YACA,YACA,WACA,UACA,eACA,aACA,OAAO,MACP,YACA,iBACA,cACA,OACA,OACA,GAAG,SACD;CAGJ,MAAM,SADS,cAAc,EAAE,KAAK,YAAY,CACjC,CAAA,CAAO,EAAE,KAAK,CAAC;CAE9B,MAAM,WAAW,SAAS,OAAO,OAAO;CACxC,MAAM,YAAY,SAAS,OAAO,OAAO;CAEzC,MAAM,aAAa,UAAU,aAAa,CAAC,CAAC,KAAK;CACjD,MAAM,YAAY,UAAU,WAAW,CAAC,CAAC,KAAK;CAE9C,IAAI,aAAwB;CAC5B,IAAI,WACF,aAAa,oBAAC,uBAAD;EAAuB,OAAM;EAAgB,MAAM;CAAW,CAAA;MACtE,IAAI,YACT,aAAa,oBAAC,mBAAD,EAAmB,MAAM,SAAW,CAAA;CAKnD,MAAM,EAAE,UAAU,eAAe,OAAO,YAAY,GAAG,mBAAmB,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"BitkitTextInput.js","names":[],"sources":["../../../lib/components/BitkitTextInput/BitkitTextInput.tsx"],"sourcesContent":["import { Box } from '@chakra-ui/react/box';\nimport { Group } from '@chakra-ui/react/group';\nimport { Input, type InputProps } from '@chakra-ui/react/input';\nimport { InputAddon, type InputAddonProps } from '@chakra-ui/react/input-addon';\nimport { useSlotRecipe } from '@chakra-ui/react/styled-system';\nimport { type ChangeEventHandler, forwardRef, type ReactNode } from 'react';\n\nimport { IconErrorCircleFilled, IconWarningYellow } from '../../icons';\nimport BitkitField, { type BitkitFieldProps } from '../BitkitField/BitkitField';\n\nexport interface BitkitTextInputProps extends Omit<BitkitFieldProps, 'children' | 'onChange' | 'state' | 'value'> {\n /**\n * Show a live character counter (`length/maxLength`) next to the label. Requires `maxLength` and a\n * known `value`.\n */\n counter?: boolean;\n /** Content attached to the trailing edge, outside the input border (e.g. a unit label or button). */\n endAddon?: ReactNode;\n /** Props forwarded to the trailing `InputAddon` wrapper. */\n endAddonProps?: InputAddonProps;\n /** Inline content rendered inside the input, at the trailing edge (e.g. an icon or reveal button). */\n endElement?: ReactNode;\n /**\n * Escape hatch for the underlying Chakra `Input` — extra native attributes or a spread\n * `{...register()}`. On conflict, values here win over the top-level `value`/`onChange`.\n */\n inputProps?: InputProps;\n /** Maximum number of characters accepted; also feeds the optional `counter`. */\n maxLength?: HTMLInputElement['maxLength'];\n /**\n * Native change event — the same handler you could put on `inputProps`, promoted to the top level.\n * Reach for `onValueChange` when you only need the value. If both this and `inputProps.onChange` are\n * set, `inputProps.onChange` wins (it's the same event, so they shouldn't both be set).\n */\n onChange?: ChangeEventHandler<HTMLInputElement>;\n /** Convenience change handler that receives the value directly, without `event.target.value`. */\n onValueChange?: (value: string) => void;\n /** Placeholder text shown while the field is empty. */\n placeholder?: string;\n /** Field size — controls height and typography. */\n size?: 'md' | 'lg';\n /** Content attached to the leading edge, outside the input border (e.g. a unit label or button). */\n startAddon?: ReactNode;\n /** Props forwarded to the leading `InputAddon` wrapper. */\n startAddonProps?: InputAddonProps;\n /** Inline content rendered inside the input, at the leading edge (e.g. an icon). */\n startElement?: ReactNode;\n /**\n * Field state. `error`/`warning` are also implied by `errorText`/`warningText`; `disabled` and\n * `readOnly` gate interaction.\n */\n state?: 'disabled' | 'error' | 'readOnly' | 'warning';\n /**\n * Controlled value. Pair with `onValueChange` or `onChange`. Can also be supplied via `inputProps`,\n * which wins on conflict.\n */\n value?: string;\n}\n\n/**\n * A single-line text field wrapping the native `<input>`, with a label and helper/error/warning\n * text. Reflect the value with `value` + `onValueChange` (or the native `onChange`); `inputProps` is\n * the escape hatch for any other native attribute. `startAddon`/`endAddon` sit outside the border,\n * `startElement`/`endElement` inline inside it, and `counter` pairs with `maxLength`.\n */\nconst BitkitTextInput = forwardRef<HTMLDivElement, BitkitTextInputProps>((props, ref) => {\n const {\n counter,\n endAddon,\n endAddonProps,\n endElement,\n inputProps,\n maxLength,\n onChange,\n onValueChange,\n placeholder,\n size = 'lg',\n startAddon,\n startAddonProps,\n startElement,\n state,\n value,\n ...rest\n } = props;\n\n const recipe = useSlotRecipe({ key: 'textInput' });\n const styles = recipe({ size });\n\n const iconSize = size === 'md' ? '16' : '24';\n const addonSize = size === 'md' ? 'md' : 'lg';\n\n const hasWarning = state === 'warning' || !!rest.warningText;\n const isInvalid = state === 'error' || !!rest.errorText;\n\n let statusIcon: ReactNode = null;\n if (isInvalid) {\n statusIcon = <IconErrorCircleFilled color=\"icon/negative\" size={iconSize} />;\n } else if (hasWarning) {\n statusIcon = <IconWarningYellow size={iconSize} />;\n }\n\n // `value` / `onChange` may come in at the top level or via `inputProps` — the object wins on\n // conflict (natural for a spread `{...register()}`). `onValueChange` always fires with the value.\n const { css: inputCss, onChange: inputOnChange, value: inputValue, ...restInputProps } = inputProps ?? {};\n const resolvedValue = inputValue ?? value;\n const nativeOnChange = inputOnChange ?? onChange;\n const handleChange: ChangeEventHandler<HTMLInputElement> | undefined =\n onValueChange || nativeOnChange\n ? (event) => {\n onValueChange?.(event.target.value);\n nativeOnChange?.(event);\n }\n : undefined;\n\n const counterText =\n counter && maxLength && resolvedValue !== undefined ? `${resolvedValue.toString().length}/${maxLength}` : undefined;\n\n const stateAttrs = {\n 'data-disabled': state === 'disabled' ? '' : undefined,\n 'data-invalid': isInvalid ? '' : undefined,\n 'data-readonly': state === 'readOnly' ? '' : undefined,\n };\n\n return (\n <BitkitField counterText={counterText} ref={ref} state={state} {...rest}>\n <Group attached width=\"100%\">\n {startAddon != null && (\n <InputAddon position=\"start\" size={addonSize} {...stateAttrs} {...startAddonProps}>\n {startAddon}\n </InputAddon>\n )}\n <Box css={styles.field} data-has-end-element={endElement != null ? '' : undefined} flex=\"1\" {...stateAttrs}>\n {startElement != null && (\n <Box css={styles.element} {...stateAttrs}>\n {startElement}\n </Box>\n )}\n <Input\n css={[styles.input, inputCss]}\n maxLength={maxLength}\n onChange={handleChange}\n placeholder={placeholder}\n value={resolvedValue}\n {...restInputProps}\n unstyled\n />\n {statusIcon != null && (\n <Box css={styles.element} {...stateAttrs}>\n {statusIcon}\n </Box>\n )}\n {endElement != null && (\n <Box css={styles.element} {...stateAttrs}>\n {endElement}\n </Box>\n )}\n </Box>\n {endAddon != null && (\n <InputAddon position=\"end\" size={addonSize} {...stateAttrs} {...endAddonProps}>\n {endAddon}\n </InputAddon>\n )}\n </Group>\n </BitkitField>\n );\n});\n\nBitkitTextInput.displayName = 'BitkitTextInput';\n\nexport default BitkitTextInput;\n"],"mappings":";;;;;;;;;;;;;;;;;AAiEA,IAAM,kBAAkB,YAAkD,OAAO,QAAQ;CACvF,MAAM,EACJ,SACA,UACA,eACA,YACA,YACA,WACA,UACA,eACA,aACA,OAAO,MACP,YACA,iBACA,cACA,OACA,OACA,GAAG,SACD;CAGJ,MAAM,SADS,cAAc,EAAE,KAAK,YAAY,CACjC,CAAA,CAAO,EAAE,KAAK,CAAC;CAE9B,MAAM,WAAW,SAAS,OAAO,OAAO;CACxC,MAAM,YAAY,SAAS,OAAO,OAAO;CAEzC,MAAM,aAAa,UAAU,aAAa,CAAC,CAAC,KAAK;CACjD,MAAM,YAAY,UAAU,WAAW,CAAC,CAAC,KAAK;CAE9C,IAAI,aAAwB;CAC5B,IAAI,WACF,aAAa,oBAAC,uBAAD;EAAuB,OAAM;EAAgB,MAAM;CAAW,CAAA;MACtE,IAAI,YACT,aAAa,oBAAC,mBAAD,EAAmB,MAAM,SAAW,CAAA;CAKnD,MAAM,EAAE,KAAK,UAAU,UAAU,eAAe,OAAO,YAAY,GAAG,mBAAmB,cAAc,CAAC;CACxG,MAAM,gBAAgB,cAAc;CACpC,MAAM,iBAAiB,iBAAiB;CACxC,MAAM,eACJ,iBAAiB,kBACZ,UAAU;EACT,gBAAgB,MAAM,OAAO,KAAK;EAClC,iBAAiB,KAAK;CACxB,IACA,KAAA;CAEN,MAAM,cACJ,WAAW,aAAa,kBAAkB,KAAA,IAAY,GAAG,cAAc,SAAS,CAAC,CAAC,OAAO,GAAG,cAAc,KAAA;CAE5G,MAAM,aAAa;EACjB,iBAAiB,UAAU,aAAa,KAAK,KAAA;EAC7C,gBAAgB,YAAY,KAAK,KAAA;EACjC,iBAAiB,UAAU,aAAa,KAAK,KAAA;CAC/C;CAEA,OACE,oBAAC,aAAD;EAA0B;EAAkB;EAAY;EAAO,GAAI;EACjE,UAAA,qBAAC,OAAD;GAAO,UAAA;GAAS,OAAM;GAAtB,UAAA;IACG,cAAc,QACb,oBAAC,YAAD;KAAY,UAAS;KAAQ,MAAM;KAAW,GAAI;KAAY,GAAI;KAC/D,UAAA;IACS,CAAA;IAEd,qBAAC,KAAD;KAAK,KAAK,OAAO;KAAO,wBAAsB,cAAc,OAAO,KAAK,KAAA;KAAW,MAAK;KAAI,GAAI;KAAhG,UAAA;MACG,gBAAgB,QACf,oBAAC,KAAD;OAAK,KAAK,OAAO;OAAS,GAAI;OAC3B,UAAA;MACE,CAAA;MAEP,oBAAC,OAAD;OACE,KAAK,CAAC,OAAO,OAAO,QAAQ;OACjB;OACX,UAAU;OACG;OACb,OAAO;OACP,GAAI;OACJ,UAAA;MACD,CAAA;MACA,cAAc,QACb,oBAAC,KAAD;OAAK,KAAK,OAAO;OAAS,GAAI;OAC3B,UAAA;MACE,CAAA;MAEN,cAAc,QACb,oBAAC,KAAD;OAAK,KAAK,OAAO;OAAS,GAAI;OAC3B,UAAA;MACE,CAAA;KAEJ;;IACJ,YAAY,QACX,oBAAC,YAAD;KAAY,UAAS;KAAM,MAAM;KAAW,GAAI;KAAY,GAAI;KAC7D,UAAA;IACS,CAAA;GAET;;CACI,CAAA;AAEjB,CAAC;AAED,gBAAgB,cAAc"}
|