@commercetools/nimbus 0.0.2 → 0.0.3
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/index.d.ts +1412 -0
- package/dist/index.js +11183 -0
- package/dist/index.js.map +1 -0
- package/dist/index.umd.cjs +27 -0
- package/dist/index.umd.cjs.map +1 -0
- package/package.json +63 -39
- package/.storybook/apca-check/index.ts +0 -150
- package/.storybook/main.ts +0 -64
- package/.storybook/preview.tsx +0 -92
- package/.storybook/vitest.setup.ts +0 -13
- package/docs/architecture-decisions/adr-0001-consumer-component-apis.md +0 -177
- package/docs/architecture-decisions/adr-0002-compound-component-extraction.md +0 -82
- package/src/components/accordion/accordion-context.tsx +0 -17
- package/src/components/accordion/accordion.mdx +0 -172
- package/src/components/accordion/accordion.recipe.tsx +0 -98
- package/src/components/accordion/accordion.slots.tsx +0 -39
- package/src/components/accordion/accordion.stories.tsx +0 -188
- package/src/components/accordion/accordion.tsx +0 -16
- package/src/components/accordion/accordion.types.tsx +0 -54
- package/src/components/accordion/components/accordion-content.tsx +0 -28
- package/src/components/accordion/components/accordion-group.tsx +0 -27
- package/src/components/accordion/components/accordion-header.tsx +0 -63
- package/src/components/accordion/components/accordion-item.tsx +0 -87
- package/src/components/accordion/index.ts +0 -2
- package/src/components/alert/alert.mdx +0 -92
- package/src/components/alert/alert.recipe.tsx +0 -65
- package/src/components/alert/alert.slots.tsx +0 -46
- package/src/components/alert/alert.stories.tsx +0 -308
- package/src/components/alert/alert.tsx +0 -18
- package/src/components/alert/alert.types.tsx +0 -70
- package/src/components/alert/components/alert.actions.tsx +0 -27
- package/src/components/alert/components/alert.description.tsx +0 -27
- package/src/components/alert/components/alert.dismiss-button.tsx +0 -41
- package/src/components/alert/components/alert.root.tsx +0 -92
- package/src/components/alert/components/alert.title.tsx +0 -29
- package/src/components/alert/index.ts +0 -2
- package/src/components/avatar/avatar.mdx +0 -80
- package/src/components/avatar/avatar.recipe.tsx +0 -36
- package/src/components/avatar/avatar.slots.tsx +0 -16
- package/src/components/avatar/avatar.stories.tsx +0 -136
- package/src/components/avatar/avatar.tsx +0 -34
- package/src/components/avatar/avatar.types.ts +0 -33
- package/src/components/avatar/index.ts +0 -2
- package/src/components/badge/badge.mdx +0 -91
- package/src/components/badge/badge.recipe.tsx +0 -72
- package/src/components/badge/badge.slots.tsx +0 -8
- package/src/components/badge/badge.stories.tsx +0 -124
- package/src/components/badge/badge.tsx +0 -35
- package/src/components/badge/badge.types.tsx +0 -40
- package/src/components/badge/index.ts +0 -2
- package/src/components/bleed/bleed.tsx +0 -1
- package/src/components/bleed/index.ts +0 -1
- package/src/components/box/box.mdx +0 -115
- package/src/components/box/box.stories.tsx +0 -71
- package/src/components/box/box.tsx +0 -11
- package/src/components/box/index.ts +0 -1
- package/src/components/button/button.mdx +0 -169
- package/src/components/button/button.recipe.ts +0 -185
- package/src/components/button/button.slots.tsx +0 -45
- package/src/components/button/button.stories.tsx +0 -369
- package/src/components/button/button.tsx +0 -37
- package/src/components/button/button.types.ts +0 -14
- package/src/components/button/index.ts +0 -2
- package/src/components/card/card.mdx +0 -92
- package/src/components/card/card.recipe.tsx +0 -71
- package/src/components/card/card.slots.tsx +0 -50
- package/src/components/card/card.stories.tsx +0 -175
- package/src/components/card/card.tsx +0 -9
- package/src/components/card/card.types.ts +0 -22
- package/src/components/card/components/card.content.tsx +0 -29
- package/src/components/card/components/card.header.tsx +0 -28
- package/src/components/card/components/card.root.tsx +0 -62
- package/src/components/card/index.ts +0 -2
- package/src/components/checkbox/checkbox.mdx +0 -78
- package/src/components/checkbox/checkbox.recipe.tsx +0 -116
- package/src/components/checkbox/checkbox.slots.tsx +0 -33
- package/src/components/checkbox/checkbox.stories.tsx +0 -200
- package/src/components/checkbox/checkbox.tsx +0 -77
- package/src/components/checkbox/checkbox.types.tsx +0 -22
- package/src/components/checkbox/index.ts +0 -2
- package/src/components/code/code.mdx +0 -17
- package/src/components/code/code.recipe.ts +0 -63
- package/src/components/code/code.tsx +0 -1
- package/src/components/code/index.ts +0 -1
- package/src/components/dialog/dialog.mdx +0 -20
- package/src/components/dialog/dialog.recipe.ts +0 -254
- package/src/components/dialog/dialog.tsx +0 -61
- package/src/components/dialog/index.ts +0 -1
- package/src/components/em/em.mdx +0 -17
- package/src/components/em/em.tsx +0 -1
- package/src/components/em/index.ts +0 -1
- package/src/components/flex/flex.mdx +0 -41
- package/src/components/flex/flex.tsx +0 -1
- package/src/components/flex/index.ts +0 -1
- package/src/components/grid/grid.mdx +0 -156
- package/src/components/grid/grid.stories.tsx +0 -151
- package/src/components/grid/grid.tsx +0 -29
- package/src/components/grid/index.ts +0 -1
- package/src/components/heading/heading.mdx +0 -23
- package/src/components/heading/heading.recipe.ts +0 -49
- package/src/components/heading/heading.tsx +0 -1
- package/src/components/heading/index.ts +0 -1
- package/src/components/highlight/highlight.mdx +0 -18
- package/src/components/highlight/highlight.tsx +0 -1
- package/src/components/highlight/index.ts +0 -1
- package/src/components/icon-button/icon-button.mdx +0 -98
- package/src/components/icon-button/icon-button.stories.tsx +0 -188
- package/src/components/icon-button/icon-button.tsx +0 -21
- package/src/components/icon-button/icon-button.types.tsx +0 -10
- package/src/components/icon-button/index.ts +0 -2
- package/src/components/index.ts +0 -33
- package/src/components/input/index.ts +0 -1
- package/src/components/input/input.mdx +0 -20
- package/src/components/input/input.recipe.ts +0 -95
- package/src/components/input/input.tsx +0 -1
- package/src/components/input-group/index.ts +0 -1
- package/src/components/input-group/input-group.mdx +0 -20
- package/src/components/input-group/input-group.tsx +0 -44
- package/src/components/kbd/index.ts +0 -1
- package/src/components/kbd/kbd.mdx +0 -18
- package/src/components/kbd/kbd.recipe.ts +0 -57
- package/src/components/kbd/kbd.tsx +0 -1
- package/src/components/link/index.ts +0 -2
- package/src/components/link/link.mdx +0 -77
- package/src/components/link/link.recipe.ts +0 -52
- package/src/components/link/link.slots.tsx +0 -29
- package/src/components/link/link.stories.tsx +0 -204
- package/src/components/link/link.tsx +0 -38
- package/src/components/link/link.types.tsx +0 -26
- package/src/components/list/index.ts +0 -1
- package/src/components/list/list.mdx +0 -18
- package/src/components/list/list.recipe.ts +0 -68
- package/src/components/list/list.tsx +0 -9
- package/src/components/loading-spinner/index.ts +0 -2
- package/src/components/loading-spinner/loading-spinner.mdx +0 -92
- package/src/components/loading-spinner/loading-spinner.recipe.tsx +0 -70
- package/src/components/loading-spinner/loading-spinner.slots.tsx +0 -38
- package/src/components/loading-spinner/loading-spinner.stories.tsx +0 -97
- package/src/components/loading-spinner/loading-spinner.tsx +0 -50
- package/src/components/loading-spinner/loading-spinner.types.tsx +0 -21
- package/src/components/nimbus-provider/color-mode.tsx +0 -32
- package/src/components/nimbus-provider/index.ts +0 -2
- package/src/components/nimbus-provider/nimbus-provider.mdx +0 -21
- package/src/components/nimbus-provider/nimbus-provider.tsx +0 -51
- package/src/components/select/components/select.clear-button.tsx +0 -31
- package/src/components/select/components/select.option-group.tsx +0 -48
- package/src/components/select/components/select.option.tsx +0 -21
- package/src/components/select/components/select.options.tsx +0 -23
- package/src/components/select/components/select.root.tsx +0 -81
- package/src/components/select/index.ts +0 -2
- package/src/components/select/select.mdx +0 -170
- package/src/components/select/select.recipe.tsx +0 -216
- package/src/components/select/select.slots.tsx +0 -58
- package/src/components/select/select.stories.tsx +0 -841
- package/src/components/select/select.tsx +0 -18
- package/src/components/select/select.types.tsx +0 -37
- package/src/components/simple-grid/index.ts +0 -1
- package/src/components/simple-grid/simple-grid.mdx +0 -133
- package/src/components/simple-grid/simple-grid.stories.tsx +0 -143
- package/src/components/simple-grid/simple-grid.tsx +0 -31
- package/src/components/stack/index.ts +0 -1
- package/src/components/stack/stack.mdx +0 -88
- package/src/components/stack/stack.stories.tsx +0 -82
- package/src/components/stack/stack.tsx +0 -15
- package/src/components/table/index.ts +0 -1
- package/src/components/table/table.mdx +0 -23
- package/src/components/table/table.recipe.ts +0 -170
- package/src/components/table/table.tsx +0 -43
- package/src/components/text/index.ts +0 -1
- package/src/components/text/text.mdx +0 -244
- package/src/components/text/text.tsx +0 -23
- package/src/components/text-input/index.ts +0 -2
- package/src/components/text-input/text-input.mdx +0 -118
- package/src/components/text-input/text-input.recipe.tsx +0 -68
- package/src/components/text-input/text-input.slots.tsx +0 -24
- package/src/components/text-input/text-input.stories.tsx +0 -282
- package/src/components/text-input/text-input.tsx +0 -39
- package/src/components/text-input/text-input.types.ts +0 -7
- package/src/components/toggle-button-group/components/toggle-button-group.button.tsx +0 -14
- package/src/components/toggle-button-group/components/toggle-button-group.root.tsx +0 -15
- package/src/components/toggle-button-group/index.ts +0 -2
- package/src/components/toggle-button-group/toggle-button-group.mdx +0 -94
- package/src/components/toggle-button-group/toggle-button-group.recipe.tsx +0 -64
- package/src/components/toggle-button-group/toggle-button-group.slots.tsx +0 -26
- package/src/components/toggle-button-group/toggle-button-group.stories.tsx +0 -311
- package/src/components/toggle-button-group/toggle-button-group.tsx +0 -12
- package/src/components/toggle-button-group/toggle-button-group.types.tsx +0 -62
- package/src/components/tooltip/index.ts +0 -4
- package/src/components/tooltip/make-element-focusable.stories.tsx +0 -56
- package/src/components/tooltip/make-element-focusable.tsx +0 -57
- package/src/components/tooltip/tooltip-trigger.stories.tsx +0 -157
- package/src/components/tooltip/tooltip-trigger.tsx +0 -15
- package/src/components/tooltip/tooltip.mdx +0 -48
- package/src/components/tooltip/tooltip.recipe.ts +0 -26
- package/src/components/tooltip/tooltip.slots.ts +0 -35
- package/src/components/tooltip/tooltip.stories.tsx +0 -139
- package/src/components/tooltip/tooltip.tsx +0 -31
- package/src/components/tooltip/tooltip.types.ts +0 -44
- package/src/components/visually-hidden/index.ts +0 -1
- package/src/components/visually-hidden/visually-hidden.mdx +0 -61
- package/src/components/visually-hidden/visually-hidden.stories.tsx +0 -124
- package/src/components/visually-hidden/visually-hidden.tsx +0 -18
- package/src/docs/accessibility.mdx +0 -21
- package/src/docs/background.mdx +0 -154
- package/src/docs/border.mdx +0 -226
- package/src/docs/changelog.mdx +0 -17
- package/src/docs/components-layout.mdx +0 -22
- package/src/docs/components.mdx +0 -17
- package/src/docs/data-display.mdx +0 -23
- package/src/docs/display.mdx +0 -55
- package/src/docs/effects.mdx +0 -73
- package/src/docs/feedback.mdx +0 -22
- package/src/docs/filters.mdx +0 -268
- package/src/docs/flex-and-grid.mdx +0 -445
- package/src/docs/forms.mdx +0 -22
- package/src/docs/generated/index.mdx +0 -16
- package/src/docs/getting-started.mdx +0 -17
- package/src/docs/home.mdx +0 -56
- package/src/docs/hooks.mdx +0 -16
- package/src/docs/inputs.mdx +0 -21
- package/src/docs/installation.mdx +0 -60
- package/src/docs/interactivity.mdx +0 -278
- package/src/docs/known-issues.mdx +0 -19
- package/src/docs/layout.mdx +0 -301
- package/src/docs/list.mdx +0 -82
- package/src/docs/markdown.mdx +0 -234
- package/src/docs/media.mdx +0 -22
- package/src/docs/naivgation.mdx +0 -22
- package/src/docs/playground.mdx +0 -16
- package/src/docs/rfcs-component-structure-rfcs.mdx +0 -17
- package/src/docs/rfcs-component-structure.mdx +0 -74
- package/src/docs/rfcs-hook-structure.mdx +0 -59
- package/src/docs/sizing.mdx +0 -210
- package/src/docs/spacing.mdx +0 -193
- package/src/docs/style-props-typography.mdx +0 -373
- package/src/docs/style-props.mdx +0 -15
- package/src/docs/svg.mdx +0 -58
- package/src/docs/tables.mdx +0 -95
- package/src/docs/toc.mdx +0 -39
- package/src/docs/tokens/animations.mdx +0 -68
- package/src/docs/tokens/aspect-ratios.mdx +0 -21
- package/src/docs/tokens/blurs.mdx +0 -20
- package/src/docs/tokens/borders.mdx +0 -25
- package/src/docs/tokens/breakpoints.mdx +0 -35
- package/src/docs/tokens/colors.mdx +0 -86
- package/src/docs/tokens/cursors.mdx +0 -21
- package/src/docs/tokens/radii.mdx +0 -23
- package/src/docs/tokens/shadows.mdx +0 -21
- package/src/docs/tokens/sizes.mdx +0 -54
- package/src/docs/tokens/spacing.mdx +0 -35
- package/src/docs/tokens/typography.mdx +0 -61
- package/src/docs/tokens/z-indices.mdx +0 -23
- package/src/docs/tokens-other.mdx +0 -17
- package/src/docs/tokens.mdx +0 -16
- package/src/docs/transforms.mdx +0 -150
- package/src/docs/transitions.mdx +0 -164
- package/src/docs/typography.mdx +0 -17
- package/src/docs/utilities.mdx +0 -17
- package/src/hooks/index.ts +0 -2
- package/src/hooks/use-copy-to-clipboard/use-copy-to-clipboard.mdx +0 -54
- package/src/hooks/use-copy-to-clipboard/use-copy-to-clipboard.ts +0 -1
- package/src/hooks/use-hotkeys/use-hotkeys.mdx +0 -48
- package/src/hooks/use-hotkeys/use-hotkeys.stories.tsx +0 -69
- package/src/hooks/use-hotkeys/use-hotkeys.ts +0 -1
- package/src/index.ts +0 -3
- package/src/test/utils.tsx +0 -20
- package/src/theme/animation-styles.ts +0 -52
- package/src/theme/breakpoints.ts +0 -32
- package/src/theme/global-css.ts +0 -53
- package/src/theme/index.ts +0 -35
- package/src/theme/keyframes.ts +0 -192
- package/src/theme/layer-styles.ts +0 -12
- package/src/theme/recipes/index.ts +0 -21
- package/src/theme/semantic-tokens/colors.ts +0 -55
- package/src/theme/semantic-tokens/index.ts +0 -9
- package/src/theme/semantic-tokens/radii.ts +0 -3
- package/src/theme/semantic-tokens/shadows.ts +0 -4
- package/src/theme/slot-recipes/index.ts +0 -15
- package/src/theme/text-styles.ts +0 -8
- package/src/theme/tokens/animations.ts +0 -4
- package/src/theme/tokens/aspect-ratios.ts +0 -5
- package/src/theme/tokens/blurs.ts +0 -5
- package/src/theme/tokens/borders.ts +0 -4
- package/src/theme/tokens/colors.ts +0 -8
- package/src/theme/tokens/cursor.ts +0 -4
- package/src/theme/tokens/durations.ts +0 -4
- package/src/theme/tokens/easings.ts +0 -4
- package/src/theme/tokens/font-sizes.ts +0 -4
- package/src/theme/tokens/font-weights.ts +0 -4
- package/src/theme/tokens/fonts.ts +0 -4
- package/src/theme/tokens/index.ts +0 -57
- package/src/theme/tokens/letter-spacings.ts +0 -24
- package/src/theme/tokens/line-heights.ts +0 -4
- package/src/theme/tokens/radii.ts +0 -4
- package/src/theme/tokens/sizes.ts +0 -120
- package/src/theme/tokens/spacing.ts +0 -4
- package/src/theme/tokens/z-index.ts +0 -4
- package/src/utils/extractStyleProps.ts +0 -26
- package/src/utils/fixedForwardRef.ts +0 -17
- package/tsconfig.json +0 -38
- package/vite.config.ts +0 -54
- package/vitest.config.ts +0 -50
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import React, { forwardRef, type Key } from "react";
|
|
2
|
-
import { AccordionRoot as AccordionRootSlot } from "../accordion.slots";
|
|
3
|
-
import { useDisclosureGroupState } from "react-stately";
|
|
4
|
-
import { useSlotRecipe } from "@chakra-ui/react";
|
|
5
|
-
import type { DisclosureGroupProps } from "../accordion.types";
|
|
6
|
-
import { DisclosureGroupStateContext } from "../accordion-context";
|
|
7
|
-
|
|
8
|
-
export const AccordionGroup = forwardRef<HTMLDivElement, DisclosureGroupProps>(
|
|
9
|
-
({ children, onExpandedChange, ...props }, forwardedRef) => {
|
|
10
|
-
const state = useDisclosureGroupState({
|
|
11
|
-
...props,
|
|
12
|
-
onExpandedChange: (keys: Set<Key>) => {
|
|
13
|
-
onExpandedChange?.(keys.size > 0);
|
|
14
|
-
},
|
|
15
|
-
});
|
|
16
|
-
const recipe = useSlotRecipe({ key: "accordion" });
|
|
17
|
-
const [recipeProps] = recipe.splitVariantProps(props);
|
|
18
|
-
|
|
19
|
-
return (
|
|
20
|
-
<DisclosureGroupStateContext.Provider value={state}>
|
|
21
|
-
<AccordionRootSlot data-slot="root" ref={forwardedRef} {...recipeProps}>
|
|
22
|
-
{children}
|
|
23
|
-
</AccordionRootSlot>
|
|
24
|
-
</DisclosureGroupStateContext.Provider>
|
|
25
|
-
);
|
|
26
|
-
}
|
|
27
|
-
);
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import React, { forwardRef, useContext } from "react";
|
|
2
|
-
import {
|
|
3
|
-
AccordionTrigger,
|
|
4
|
-
AccordionTitle,
|
|
5
|
-
HeaderRightContent,
|
|
6
|
-
} from "../accordion.slots";
|
|
7
|
-
import { mergeRefs } from "@chakra-ui/react";
|
|
8
|
-
import { Flex } from "@/components";
|
|
9
|
-
import { KeyboardArrowRight } from "@commercetools/nimbus-icons";
|
|
10
|
-
import type { DisclosureGroupProps } from "../accordion.types";
|
|
11
|
-
import { ItemContext } from "../accordion-context";
|
|
12
|
-
|
|
13
|
-
export const AccordionHeader = forwardRef<
|
|
14
|
-
HTMLButtonElement,
|
|
15
|
-
DisclosureGroupProps
|
|
16
|
-
>(({ children }, ref) => {
|
|
17
|
-
const context = useContext(ItemContext);
|
|
18
|
-
if (!context) {
|
|
19
|
-
throw new Error("Accordion.Header must be used within Accordion.Item");
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
// Extract HeaderRightContent if present
|
|
23
|
-
const headerContent = React.Children.toArray(children).reduce<{
|
|
24
|
-
main: React.ReactNode[];
|
|
25
|
-
rightContent: React.ReactNode[];
|
|
26
|
-
}>(
|
|
27
|
-
(acc, child) => {
|
|
28
|
-
if (React.isValidElement(child) && child.type === HeaderRightContent) {
|
|
29
|
-
acc.rightContent.push(child);
|
|
30
|
-
} else {
|
|
31
|
-
acc.main.push(child);
|
|
32
|
-
}
|
|
33
|
-
return acc;
|
|
34
|
-
},
|
|
35
|
-
{ main: [], rightContent: [] }
|
|
36
|
-
);
|
|
37
|
-
|
|
38
|
-
return (
|
|
39
|
-
<Flex
|
|
40
|
-
justifyContent="space-between"
|
|
41
|
-
alignItems="center"
|
|
42
|
-
borderBottom="solid-25"
|
|
43
|
-
borderColor="neutral.4"
|
|
44
|
-
>
|
|
45
|
-
<AccordionTrigger
|
|
46
|
-
ref={mergeRefs(context.triggerRef, ref)}
|
|
47
|
-
{...context.buttonProps}
|
|
48
|
-
data-slot="trigger"
|
|
49
|
-
outline={context.isFocusVisible ? undefined : "none"}
|
|
50
|
-
>
|
|
51
|
-
<KeyboardArrowRight />
|
|
52
|
-
<AccordionTitle data-slot="accordionTitle">
|
|
53
|
-
{headerContent.main}
|
|
54
|
-
</AccordionTitle>
|
|
55
|
-
</AccordionTrigger>
|
|
56
|
-
{headerContent.rightContent.length > 0 && (
|
|
57
|
-
<HeaderRightContent data-slot="headerContentRight">
|
|
58
|
-
{headerContent.rightContent}
|
|
59
|
-
</HeaderRightContent>
|
|
60
|
-
)}
|
|
61
|
-
</Flex>
|
|
62
|
-
);
|
|
63
|
-
});
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
import React, { forwardRef, useContext, useRef } from "react";
|
|
2
|
-
import { AccordionDisclosure } from "../accordion.slots";
|
|
3
|
-
import { useDisclosureState } from "react-stately";
|
|
4
|
-
import {
|
|
5
|
-
useDisclosure,
|
|
6
|
-
mergeProps,
|
|
7
|
-
useButton,
|
|
8
|
-
useFocusRing,
|
|
9
|
-
useId,
|
|
10
|
-
} from "react-aria";
|
|
11
|
-
import type { DisclosureItemProps } from "../accordion.types";
|
|
12
|
-
// Import the contexts from the shared file
|
|
13
|
-
import { ItemContext, DisclosureGroupStateContext } from "../accordion-context";
|
|
14
|
-
|
|
15
|
-
export const AccordionItem = forwardRef<HTMLDivElement, DisclosureItemProps>(
|
|
16
|
-
(
|
|
17
|
-
{ children, id, isDisabled, isExpanded, onExpandedChange, value },
|
|
18
|
-
forwardedRef
|
|
19
|
-
) => {
|
|
20
|
-
const defaultId = useId();
|
|
21
|
-
const itemId = id || defaultId;
|
|
22
|
-
const itemValue = value || itemId;
|
|
23
|
-
|
|
24
|
-
// Get group state from context
|
|
25
|
-
const groupState = useContext(DisclosureGroupStateContext);
|
|
26
|
-
|
|
27
|
-
// Determine if expanded based on group state or prop
|
|
28
|
-
const expanded = groupState
|
|
29
|
-
? groupState.expandedKeys.has(itemValue)
|
|
30
|
-
: isExpanded;
|
|
31
|
-
|
|
32
|
-
// Create disclosure state
|
|
33
|
-
const state = useDisclosureState({
|
|
34
|
-
isExpanded: expanded,
|
|
35
|
-
onExpandedChange: (isExpanded) => {
|
|
36
|
-
if (groupState) {
|
|
37
|
-
groupState.toggleKey(itemValue);
|
|
38
|
-
}
|
|
39
|
-
onExpandedChange?.(isExpanded);
|
|
40
|
-
},
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
// Create refs and get props
|
|
44
|
-
const panelRef = useRef<HTMLDivElement>(null);
|
|
45
|
-
const triggerRef = useRef<HTMLButtonElement>(null);
|
|
46
|
-
const disabled = isDisabled || groupState?.isDisabled || false;
|
|
47
|
-
|
|
48
|
-
const { buttonProps, panelProps } = useDisclosure(
|
|
49
|
-
{
|
|
50
|
-
isExpanded: state.isExpanded,
|
|
51
|
-
isDisabled: disabled,
|
|
52
|
-
},
|
|
53
|
-
state,
|
|
54
|
-
panelRef
|
|
55
|
-
);
|
|
56
|
-
|
|
57
|
-
const { buttonProps: finalButtonProps } = useButton(
|
|
58
|
-
buttonProps,
|
|
59
|
-
triggerRef
|
|
60
|
-
);
|
|
61
|
-
const { focusProps, isFocusVisible } = useFocusRing();
|
|
62
|
-
|
|
63
|
-
// Create context value for Header and Content
|
|
64
|
-
const contextValue = {
|
|
65
|
-
isExpanded: state.isExpanded,
|
|
66
|
-
triggerRef,
|
|
67
|
-
panelRef,
|
|
68
|
-
buttonProps: mergeProps(finalButtonProps, focusProps),
|
|
69
|
-
panelProps,
|
|
70
|
-
isFocusVisible,
|
|
71
|
-
};
|
|
72
|
-
|
|
73
|
-
// Using the imported ItemContext
|
|
74
|
-
return (
|
|
75
|
-
<ItemContext.Provider value={contextValue}>
|
|
76
|
-
<AccordionDisclosure
|
|
77
|
-
data-slot="disclosure"
|
|
78
|
-
data-value={itemValue}
|
|
79
|
-
data-expanded={state.isExpanded}
|
|
80
|
-
ref={forwardedRef}
|
|
81
|
-
>
|
|
82
|
-
{children}
|
|
83
|
-
</AccordionDisclosure>
|
|
84
|
-
</ItemContext.Provider>
|
|
85
|
-
);
|
|
86
|
-
}
|
|
87
|
-
);
|
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
id: Components-Alert
|
|
3
|
-
title: Alert
|
|
4
|
-
description: Provides feedback to the user about the status of an action or system event
|
|
5
|
-
documentState: InitialDraft
|
|
6
|
-
order: 999
|
|
7
|
-
menu:
|
|
8
|
-
- Components
|
|
9
|
-
- Alert
|
|
10
|
-
tags:
|
|
11
|
-
- component
|
|
12
|
-
---
|
|
13
|
-
|
|
14
|
-
# Alert
|
|
15
|
-
|
|
16
|
-
Provides feedback to the user about the status of an action or system event
|
|
17
|
-
|
|
18
|
-
## Basic Usage
|
|
19
|
-
|
|
20
|
-
[Explain the basic usage / usecase of the component].
|
|
21
|
-
|
|
22
|
-
```jsx-live
|
|
23
|
-
const App = () => <Alert>I am Alert!</Alert>
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
### Sizes
|
|
28
|
-
|
|
29
|
-
Available sizes.
|
|
30
|
-
|
|
31
|
-
```jsx-live
|
|
32
|
-
const App = () => {
|
|
33
|
-
|
|
34
|
-
const sizes = ['2xl', 'xl', 'lg', 'md', 'sm', 'xs', '2xs'];
|
|
35
|
-
|
|
36
|
-
return (
|
|
37
|
-
<Stack direction="horizontal" alignItems="center">
|
|
38
|
-
{sizes.map(size => (
|
|
39
|
-
<Alert key={size} size={size}>'{size}' Alert</Alert>
|
|
40
|
-
))}
|
|
41
|
-
</Stack>
|
|
42
|
-
)
|
|
43
|
-
}
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
### Variants
|
|
47
|
-
|
|
48
|
-
Available variants.
|
|
49
|
-
|
|
50
|
-
```jsx-live
|
|
51
|
-
const App = () => {
|
|
52
|
-
|
|
53
|
-
const variants = ['solid', 'subtle', 'outline', 'ghost', 'plain'];
|
|
54
|
-
|
|
55
|
-
return (
|
|
56
|
-
<Stack direction="horizontal">
|
|
57
|
-
{variants.map(variant => (
|
|
58
|
-
<Alert key={variant} variant={variant}>'{variant}' Alert</Alert>
|
|
59
|
-
))}
|
|
60
|
-
</Stack>
|
|
61
|
-
)
|
|
62
|
-
}
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
### Colors
|
|
66
|
-
|
|
67
|
-
[Explain usage with different colors/semantics.]
|
|
68
|
-
|
|
69
|
-
```jsx-live
|
|
70
|
-
const App = () => {
|
|
71
|
-
const variants = ["solid", "subtle", "outline", "ghost", "link", "plain"];
|
|
72
|
-
const colors = ["neutral", "primary", "info", "success", "danger", "error"];
|
|
73
|
-
|
|
74
|
-
return (
|
|
75
|
-
<Stack>
|
|
76
|
-
{colors.map((color) => (
|
|
77
|
-
<Stack key={color} direction="horizontal">
|
|
78
|
-
{variants.map((variant) => (
|
|
79
|
-
<Alert colorPalette={color} key={variant} variant={variant}>
|
|
80
|
-
'{variant}' Alert
|
|
81
|
-
</Alert>
|
|
82
|
-
))}
|
|
83
|
-
</Stack>
|
|
84
|
-
))}
|
|
85
|
-
</Stack>
|
|
86
|
-
);
|
|
87
|
-
};
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
## Props
|
|
91
|
-
|
|
92
|
-
<PropTable id="Alert" />
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
import { defineSlotRecipe } from "@chakra-ui/react";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Recipe configuration for the Alert component.
|
|
5
|
-
* Defines the styling variants and base styles using Chakra UI's recipe system.
|
|
6
|
-
*/
|
|
7
|
-
export const alertRecipe = defineSlotRecipe({
|
|
8
|
-
slots: ["root", "title", "description", "icon", "actions", "dismissButton"],
|
|
9
|
-
// Unique class name prefix for the component
|
|
10
|
-
className: "nimbus-alert",
|
|
11
|
-
|
|
12
|
-
// Base styles applied to all instances of the component
|
|
13
|
-
base: {
|
|
14
|
-
root: {
|
|
15
|
-
display: "inline-flex",
|
|
16
|
-
flexDirection: "row",
|
|
17
|
-
gap: "200",
|
|
18
|
-
width: "100%",
|
|
19
|
-
},
|
|
20
|
-
icon: {
|
|
21
|
-
marginTop: "50",
|
|
22
|
-
"& svg": {
|
|
23
|
-
width: "500",
|
|
24
|
-
height: "500",
|
|
25
|
-
color: "colorPalette.11",
|
|
26
|
-
},
|
|
27
|
-
},
|
|
28
|
-
title: {
|
|
29
|
-
color: "colorPalette.11",
|
|
30
|
-
},
|
|
31
|
-
description: {
|
|
32
|
-
color: "colorPalette.11",
|
|
33
|
-
},
|
|
34
|
-
},
|
|
35
|
-
|
|
36
|
-
variants: {
|
|
37
|
-
tone: {
|
|
38
|
-
critical: {
|
|
39
|
-
root: { colorPalette: "error" },
|
|
40
|
-
},
|
|
41
|
-
info: {
|
|
42
|
-
root: { colorPalette: "info" },
|
|
43
|
-
},
|
|
44
|
-
warning: {
|
|
45
|
-
root: { colorPalette: "amber" },
|
|
46
|
-
},
|
|
47
|
-
positive: {
|
|
48
|
-
root: { colorPalette: "success" },
|
|
49
|
-
},
|
|
50
|
-
},
|
|
51
|
-
|
|
52
|
-
variant: {
|
|
53
|
-
flat: {},
|
|
54
|
-
outlined: {
|
|
55
|
-
root: {
|
|
56
|
-
border: "solid-25",
|
|
57
|
-
borderColor: "colorPalette.5",
|
|
58
|
-
backgroundColor: "colorPalette.2",
|
|
59
|
-
padding: "200",
|
|
60
|
-
borderRadius: "200",
|
|
61
|
-
},
|
|
62
|
-
},
|
|
63
|
-
},
|
|
64
|
-
},
|
|
65
|
-
});
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import { createSlotRecipeContext } from "@chakra-ui/react";
|
|
2
|
-
import { alertRecipe } from "./alert.recipe";
|
|
3
|
-
import type {
|
|
4
|
-
AlertActionsProps,
|
|
5
|
-
AlertDescriptionProps,
|
|
6
|
-
AlertDismissButtonProps,
|
|
7
|
-
AlertIconProps,
|
|
8
|
-
AlertRootProps,
|
|
9
|
-
AlertTitleProps,
|
|
10
|
-
} from "./alert.types";
|
|
11
|
-
|
|
12
|
-
const { withProvider, withContext } = createSlotRecipeContext({
|
|
13
|
-
recipe: alertRecipe,
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
export const AlertRoot = withProvider<HTMLDivElement, AlertRootProps>(
|
|
17
|
-
"div",
|
|
18
|
-
"root"
|
|
19
|
-
);
|
|
20
|
-
|
|
21
|
-
export const AlertTitle = withContext<HTMLDivElement, AlertTitleProps>(
|
|
22
|
-
"div",
|
|
23
|
-
"title"
|
|
24
|
-
);
|
|
25
|
-
|
|
26
|
-
export const AlertDescription = withContext<
|
|
27
|
-
HTMLDivElement,
|
|
28
|
-
AlertDescriptionProps
|
|
29
|
-
>("div", "description");
|
|
30
|
-
|
|
31
|
-
export const AlertIcon = withContext<HTMLDivElement, AlertIconProps>(
|
|
32
|
-
"div",
|
|
33
|
-
"icon"
|
|
34
|
-
);
|
|
35
|
-
|
|
36
|
-
export const AlertActions = withContext<HTMLDivElement, AlertActionsProps>(
|
|
37
|
-
"div",
|
|
38
|
-
"actions"
|
|
39
|
-
);
|
|
40
|
-
|
|
41
|
-
// This is a div wrapper for layout placement - note that we expect it to receive `IconButton` props, but we use a `div`.
|
|
42
|
-
// We then forward the consumer props to the interior `IconButton` component.
|
|
43
|
-
export const AlertDismissButton = withContext<
|
|
44
|
-
HTMLDivElement,
|
|
45
|
-
AlertDismissButtonProps
|
|
46
|
-
>("div", "dismissButton");
|
|
@@ -1,308 +0,0 @@
|
|
|
1
|
-
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
-
import { userEvent, within, expect, fn } from "@storybook/test";
|
|
3
|
-
import { Alert } from "./alert";
|
|
4
|
-
import { Stack } from "./../stack";
|
|
5
|
-
import { Button } from "../button";
|
|
6
|
-
import type { AlertProps } from "./alert.types";
|
|
7
|
-
|
|
8
|
-
const tones: AlertProps["tone"][] = ["critical", "info", "warning", "positive"];
|
|
9
|
-
const variants: AlertProps["variant"][] = ["flat", "outlined"];
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Storybook metadata configuration
|
|
13
|
-
* - title: determines the location in the sidebar
|
|
14
|
-
* - component: references the component being documented
|
|
15
|
-
*/
|
|
16
|
-
const meta: Meta<typeof Alert.Root> = {
|
|
17
|
-
title: "components/Alert",
|
|
18
|
-
component: Alert.Root,
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
export default meta;
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Story type for TypeScript support
|
|
25
|
-
* StoryObj provides type checking for our story configurations
|
|
26
|
-
*/
|
|
27
|
-
type Story = StoryObj<typeof Alert.Root>;
|
|
28
|
-
|
|
29
|
-
// Mock function for dismiss button onPress
|
|
30
|
-
const mockOnDismiss = fn();
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Base story
|
|
34
|
-
* Demonstrates the most basic implementation with all parts.
|
|
35
|
-
* Uses the args pattern for dynamic control panel inputs.
|
|
36
|
-
* Includes interaction tests.
|
|
37
|
-
*/
|
|
38
|
-
export const Base: Story = {
|
|
39
|
-
args: {
|
|
40
|
-
tone: "positive",
|
|
41
|
-
variant: "outlined",
|
|
42
|
-
"data-testid": "base-alert",
|
|
43
|
-
children: (
|
|
44
|
-
<>
|
|
45
|
-
<Alert.Title>Base Alert Title</Alert.Title>
|
|
46
|
-
<Alert.Description>Base Alert Description</Alert.Description>
|
|
47
|
-
<Alert.Actions>
|
|
48
|
-
<Stack direction="row" gap="8px" alignItems="center">
|
|
49
|
-
<Button variant="outline">Action 1</Button>
|
|
50
|
-
<Button variant="outline">Action 2</Button>
|
|
51
|
-
</Stack>
|
|
52
|
-
</Alert.Actions>
|
|
53
|
-
<Alert.DismissButton
|
|
54
|
-
onPress={mockOnDismiss}
|
|
55
|
-
data-testid="dismiss-button"
|
|
56
|
-
/>
|
|
57
|
-
</>
|
|
58
|
-
),
|
|
59
|
-
},
|
|
60
|
-
play: async ({ canvasElement, step }) => {
|
|
61
|
-
const canvas = within(canvasElement);
|
|
62
|
-
const alertRoot = canvas.getByTestId("base-alert");
|
|
63
|
-
const dismissButton = await canvas.findByTestId("dismiss-button");
|
|
64
|
-
// Find the icon inside the button
|
|
65
|
-
const dismissIcon = within(dismissButton).getByRole("img", {
|
|
66
|
-
hidden: true,
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
await step("Renders all parts correctly", async () => {
|
|
70
|
-
await expect(alertRoot).toBeInTheDocument();
|
|
71
|
-
await expect(alertRoot).toHaveAttribute("role", "alert");
|
|
72
|
-
await expect(canvas.getByText("Base Alert Title")).toBeInTheDocument();
|
|
73
|
-
await expect(
|
|
74
|
-
canvas.getByText("Base Alert Description")
|
|
75
|
-
).toBeInTheDocument();
|
|
76
|
-
await expect(canvas.getByText("Action 1")).toBeInTheDocument();
|
|
77
|
-
await expect(canvas.getByText("Action 2")).toBeInTheDocument();
|
|
78
|
-
await expect(dismissButton).toBeInTheDocument();
|
|
79
|
-
await expect(dismissButton).toHaveAttribute("aria-label", "Dismiss"); // Default label from IconButton
|
|
80
|
-
await expect(dismissIcon).toBeInTheDocument(); // Check if the clear icon is rendered
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
await step("Dismiss button is clickable and calls onPress", async () => {
|
|
84
|
-
await userEvent.click(dismissButton);
|
|
85
|
-
await expect(mockOnDismiss).toHaveBeenCalledTimes(1);
|
|
86
|
-
});
|
|
87
|
-
},
|
|
88
|
-
};
|
|
89
|
-
|
|
90
|
-
export const TonesShowcase: Story = {
|
|
91
|
-
name: "Showcase: Tones",
|
|
92
|
-
render: () => (
|
|
93
|
-
<Stack direction="column" gap="400" alignItems="flex-start">
|
|
94
|
-
{tones.map((tone) => (
|
|
95
|
-
<Alert.Root
|
|
96
|
-
key={`alert-${tone as string}`}
|
|
97
|
-
tone={tone}
|
|
98
|
-
variant="outlined"
|
|
99
|
-
>
|
|
100
|
-
<Alert.Title>Alert Title ({tone as string})</Alert.Title>
|
|
101
|
-
<Alert.Description>Alert Description</Alert.Description>
|
|
102
|
-
<Alert.Actions>
|
|
103
|
-
<Stack direction="row" gap="8px" alignItems="center">
|
|
104
|
-
<Button variant="outline">Button</Button>
|
|
105
|
-
</Stack>
|
|
106
|
-
</Alert.Actions>
|
|
107
|
-
<Alert.DismissButton
|
|
108
|
-
onPress={() => alert(`Dismissed ${tone as string}`)}
|
|
109
|
-
/>
|
|
110
|
-
</Alert.Root>
|
|
111
|
-
))}
|
|
112
|
-
</Stack>
|
|
113
|
-
),
|
|
114
|
-
};
|
|
115
|
-
|
|
116
|
-
export const VariantsShowcase: Story = {
|
|
117
|
-
name: "Showcase: Variants",
|
|
118
|
-
render: () => (
|
|
119
|
-
<Stack direction="column" gap="400" alignItems="flex-start">
|
|
120
|
-
{tones.map((tone) => (
|
|
121
|
-
<Stack
|
|
122
|
-
key={`stack-${tone as string}`}
|
|
123
|
-
direction="row"
|
|
124
|
-
gap="400"
|
|
125
|
-
width="100%"
|
|
126
|
-
>
|
|
127
|
-
{variants.map((variant) => (
|
|
128
|
-
<Alert.Root
|
|
129
|
-
key={`alert-${tone as string}-${variant as string}`}
|
|
130
|
-
tone={tone}
|
|
131
|
-
variant={variant}
|
|
132
|
-
>
|
|
133
|
-
<Alert.Title>
|
|
134
|
-
{tone as string} / {variant as string}
|
|
135
|
-
</Alert.Title>
|
|
136
|
-
<Alert.Description>Desc.</Alert.Description>
|
|
137
|
-
<Alert.DismissButton onPress={() => alert("Dismissed")} />
|
|
138
|
-
</Alert.Root>
|
|
139
|
-
))}
|
|
140
|
-
</Stack>
|
|
141
|
-
))}
|
|
142
|
-
</Stack>
|
|
143
|
-
),
|
|
144
|
-
};
|
|
145
|
-
|
|
146
|
-
export const TitleOnly: Story = {
|
|
147
|
-
name: "Composition: Title Only",
|
|
148
|
-
args: {
|
|
149
|
-
tone: "positive",
|
|
150
|
-
variant: "outlined",
|
|
151
|
-
"data-testid": "alert-title-only",
|
|
152
|
-
children: (
|
|
153
|
-
<>
|
|
154
|
-
<Alert.Title>Title Only Alert</Alert.Title>
|
|
155
|
-
{/* Intentionally omit Description, Actions, DismissButton */}
|
|
156
|
-
</>
|
|
157
|
-
),
|
|
158
|
-
},
|
|
159
|
-
play: async ({ canvasElement, step }) => {
|
|
160
|
-
const canvas = within(canvasElement);
|
|
161
|
-
const alert = canvas.getByTestId("alert-title-only");
|
|
162
|
-
|
|
163
|
-
await step("Renders only the title", async () => {
|
|
164
|
-
const title = await within(alert).findByText("Title Only Alert");
|
|
165
|
-
expect(title).toBeInTheDocument();
|
|
166
|
-
});
|
|
167
|
-
|
|
168
|
-
await step("Does not render other parts", async () => {
|
|
169
|
-
await expect(
|
|
170
|
-
within(alert).queryByText(/Description/i)
|
|
171
|
-
).not.toBeInTheDocument();
|
|
172
|
-
await expect(
|
|
173
|
-
within(alert).queryByRole("button") // Check for any button
|
|
174
|
-
).not.toBeInTheDocument();
|
|
175
|
-
});
|
|
176
|
-
},
|
|
177
|
-
};
|
|
178
|
-
|
|
179
|
-
export const DescriptionOnly: Story = {
|
|
180
|
-
name: "Composition: Description Only",
|
|
181
|
-
args: {
|
|
182
|
-
tone: "info",
|
|
183
|
-
variant: "flat",
|
|
184
|
-
"data-testid": "alert-desc-only",
|
|
185
|
-
children: (
|
|
186
|
-
<>
|
|
187
|
-
<Alert.Description>Description Only Alert</Alert.Description>
|
|
188
|
-
{/* Intentionally omit Title, Actions, DismissButton */}
|
|
189
|
-
</>
|
|
190
|
-
),
|
|
191
|
-
},
|
|
192
|
-
play: async ({ canvasElement, step }) => {
|
|
193
|
-
const canvas = within(canvasElement);
|
|
194
|
-
const alert = canvas.getByTestId("alert-desc-only");
|
|
195
|
-
|
|
196
|
-
await step("Renders only the description", async () => {
|
|
197
|
-
const title = await within(alert).findByText("Description Only Alert");
|
|
198
|
-
expect(title).toBeInTheDocument();
|
|
199
|
-
});
|
|
200
|
-
|
|
201
|
-
await step("Does not render other parts", async () => {
|
|
202
|
-
await expect(within(alert).queryByText(/Title/i)).not.toBeInTheDocument();
|
|
203
|
-
await expect(
|
|
204
|
-
within(alert).queryByRole("button") // Check for any button
|
|
205
|
-
).not.toBeInTheDocument();
|
|
206
|
-
});
|
|
207
|
-
},
|
|
208
|
-
};
|
|
209
|
-
|
|
210
|
-
export const TitleAndActions: Story = {
|
|
211
|
-
name: "Composition: Title and Actions",
|
|
212
|
-
args: {
|
|
213
|
-
tone: "warning",
|
|
214
|
-
variant: "outlined",
|
|
215
|
-
"data-testid": "alert-title-actions",
|
|
216
|
-
children: (
|
|
217
|
-
<>
|
|
218
|
-
<Alert.Title>Title and Actions only</Alert.Title>
|
|
219
|
-
<Alert.Actions>
|
|
220
|
-
<Stack direction="row" gap="8px" alignItems="center">
|
|
221
|
-
<Button variant="outline">Action A</Button>
|
|
222
|
-
<Button variant="ghost">Action B</Button>
|
|
223
|
-
</Stack>
|
|
224
|
-
</Alert.Actions>
|
|
225
|
-
{/* Intentionally omit Description, DismissButton */}
|
|
226
|
-
</>
|
|
227
|
-
),
|
|
228
|
-
},
|
|
229
|
-
play: async ({ canvasElement, step }) => {
|
|
230
|
-
const canvas = within(canvasElement);
|
|
231
|
-
const alert = canvas.getByTestId("alert-title-actions");
|
|
232
|
-
|
|
233
|
-
await step("Renders title and action buttons", async () => {
|
|
234
|
-
const title = await within(alert).findByText("Title and Actions only");
|
|
235
|
-
expect(title).toBeInTheDocument();
|
|
236
|
-
|
|
237
|
-
await expect(
|
|
238
|
-
within(alert).getByRole("button", { name: "Action A" })
|
|
239
|
-
).toBeInTheDocument();
|
|
240
|
-
await expect(
|
|
241
|
-
within(alert).getByRole("button", { name: "Action B" })
|
|
242
|
-
).toBeInTheDocument();
|
|
243
|
-
});
|
|
244
|
-
|
|
245
|
-
await step("Does not render description or dismiss button", async () => {
|
|
246
|
-
await expect(
|
|
247
|
-
within(alert).queryByText(/Description/i)
|
|
248
|
-
).not.toBeInTheDocument();
|
|
249
|
-
await expect(
|
|
250
|
-
within(alert).queryByRole("button", { name: /Dismiss/i })
|
|
251
|
-
).not.toBeInTheDocument();
|
|
252
|
-
});
|
|
253
|
-
},
|
|
254
|
-
};
|
|
255
|
-
|
|
256
|
-
const mockDismissNoActions = fn();
|
|
257
|
-
export const NoActions: Story = {
|
|
258
|
-
name: "Composition: Title, Description, Dismiss (No Actions)",
|
|
259
|
-
args: {
|
|
260
|
-
tone: "positive",
|
|
261
|
-
variant: "outlined",
|
|
262
|
-
"data-testid": "alert-no-actions",
|
|
263
|
-
children: (
|
|
264
|
-
<>
|
|
265
|
-
<Alert.Title>Complete Alert (No Actions)</Alert.Title>
|
|
266
|
-
<Alert.Description>
|
|
267
|
-
Title and description are present.
|
|
268
|
-
</Alert.Description>
|
|
269
|
-
{/* Intentionally omit Actions */}
|
|
270
|
-
<Alert.DismissButton
|
|
271
|
-
onPress={mockDismissNoActions}
|
|
272
|
-
data-testid="dismiss-no-actions-button"
|
|
273
|
-
/>
|
|
274
|
-
</>
|
|
275
|
-
),
|
|
276
|
-
},
|
|
277
|
-
play: async ({ canvasElement, step }) => {
|
|
278
|
-
const canvas = within(canvasElement);
|
|
279
|
-
const alert = canvas.getByTestId("alert-no-actions");
|
|
280
|
-
const dismissButton = await within(alert).findByTestId(
|
|
281
|
-
"dismiss-no-actions-button"
|
|
282
|
-
);
|
|
283
|
-
|
|
284
|
-
await step("Renders title, description, and dismiss button", async () => {
|
|
285
|
-
await expect(
|
|
286
|
-
within(alert).getByText("Complete Alert (No Actions)")
|
|
287
|
-
).toBeInTheDocument();
|
|
288
|
-
await expect(
|
|
289
|
-
within(alert).getByText("Title and description are present.")
|
|
290
|
-
).toBeInTheDocument();
|
|
291
|
-
await expect(dismissButton).toBeInTheDocument();
|
|
292
|
-
await expect(dismissButton).toHaveAttribute("aria-label", "Dismiss");
|
|
293
|
-
});
|
|
294
|
-
|
|
295
|
-
await step("Does not render action buttons", async () => {
|
|
296
|
-
// Check specifically for non-dismiss buttons
|
|
297
|
-
const actionButtons = within(alert)
|
|
298
|
-
.queryAllByRole("button")
|
|
299
|
-
.filter((btn) => btn !== dismissButton);
|
|
300
|
-
await expect(actionButtons.length).toBe(0);
|
|
301
|
-
});
|
|
302
|
-
|
|
303
|
-
await step("Dismiss button is clickable and calls onPress", async () => {
|
|
304
|
-
await userEvent.click(dismissButton);
|
|
305
|
-
await expect(mockDismissNoActions).toHaveBeenCalledTimes(1);
|
|
306
|
-
});
|
|
307
|
-
},
|
|
308
|
-
};
|