@transferwise/components 0.0.0-experimental-47052c9 → 0.0.0-experimental-b2b287d
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/build/Snackbar/Snackbar.js +178 -102
- package/build/Snackbar/Snackbar.js.map +1 -1
- package/build/Snackbar/Snackbar.messages.js +14 -0
- package/build/Snackbar/Snackbar.messages.js.map +1 -0
- package/build/Snackbar/Snackbar.messages.mjs +10 -0
- package/build/Snackbar/Snackbar.messages.mjs.map +1 -0
- package/build/Snackbar/Snackbar.mjs +180 -101
- package/build/Snackbar/Snackbar.mjs.map +1 -1
- package/build/Snackbar/SnackbarContext.js.map +1 -1
- package/build/Snackbar/SnackbarContext.mjs.map +1 -1
- package/build/Snackbar/SnackbarPortal.js +12 -0
- package/build/Snackbar/SnackbarPortal.js.map +1 -0
- package/build/Snackbar/SnackbarPortal.mjs +8 -0
- package/build/Snackbar/SnackbarPortal.mjs.map +1 -0
- package/build/Snackbar/SnackbarProvider.js +24 -28
- package/build/Snackbar/SnackbarProvider.js.map +1 -1
- package/build/Snackbar/SnackbarProvider.mjs +25 -29
- package/build/Snackbar/SnackbarProvider.mjs.map +1 -1
- package/build/Snackbar/constants.js +17 -0
- package/build/Snackbar/constants.js.map +1 -0
- package/build/Snackbar/constants.mjs +11 -0
- package/build/Snackbar/constants.mjs.map +1 -0
- package/build/Snackbar/useSnackbarAutoDismiss.js +66 -0
- package/build/Snackbar/useSnackbarAutoDismiss.js.map +1 -0
- package/build/Snackbar/useSnackbarAutoDismiss.mjs +62 -0
- package/build/Snackbar/useSnackbarAutoDismiss.mjs.map +1 -0
- package/build/Snackbar/useSnackbarManager.js +153 -0
- package/build/Snackbar/useSnackbarManager.js.map +1 -0
- package/build/Snackbar/useSnackbarManager.mjs +149 -0
- package/build/Snackbar/useSnackbarManager.mjs.map +1 -0
- package/build/Snackbar/useSnackbarSwipeDismiss.js +135 -0
- package/build/Snackbar/useSnackbarSwipeDismiss.js.map +1 -0
- package/build/Snackbar/useSnackbarSwipeDismiss.mjs +131 -0
- package/build/Snackbar/useSnackbarSwipeDismiss.mjs.map +1 -0
- package/build/i18n/en.json +1 -0
- package/build/i18n/en.json.js +1 -0
- package/build/i18n/en.json.js.map +1 -1
- package/build/i18n/en.json.mjs +1 -0
- package/build/i18n/en.json.mjs.map +1 -1
- package/build/index.js +0 -4
- package/build/index.js.map +1 -1
- package/build/index.mjs +0 -2
- package/build/index.mjs.map +1 -1
- package/build/main.css +116 -245
- package/build/styles/Snackbar/Snackbar.css +117 -54
- package/build/styles/main.css +116 -245
- package/build/types/Snackbar/Snackbar.d.ts +55 -9
- package/build/types/Snackbar/Snackbar.d.ts.map +1 -1
- package/build/types/Snackbar/Snackbar.messages.d.ts +9 -0
- package/build/types/Snackbar/Snackbar.messages.d.ts.map +1 -0
- package/build/types/Snackbar/Snackbar.types.d.ts +12 -0
- package/build/types/Snackbar/Snackbar.types.d.ts.map +1 -0
- package/build/types/Snackbar/SnackbarContext.d.ts +2 -2
- package/build/types/Snackbar/SnackbarContext.d.ts.map +1 -1
- package/build/types/Snackbar/SnackbarPortal.d.ts +4 -0
- package/build/types/Snackbar/SnackbarPortal.d.ts.map +1 -0
- package/build/types/Snackbar/SnackbarProvider.d.ts +7 -0
- package/build/types/Snackbar/SnackbarProvider.d.ts.map +1 -1
- package/build/types/Snackbar/constants.d.ts +9 -0
- package/build/types/Snackbar/constants.d.ts.map +1 -0
- package/build/types/Snackbar/index.d.ts +1 -1
- package/build/types/Snackbar/index.d.ts.map +1 -1
- package/build/types/Snackbar/useSnackbar.d.ts +1 -1
- package/build/types/Snackbar/useSnackbar.d.ts.map +1 -1
- package/build/types/Snackbar/useSnackbarAutoDismiss.d.ts +13 -0
- package/build/types/Snackbar/useSnackbarAutoDismiss.d.ts.map +1 -0
- package/build/types/Snackbar/useSnackbarManager.d.ts +20 -0
- package/build/types/Snackbar/useSnackbarManager.d.ts.map +1 -0
- package/build/types/Snackbar/useSnackbarSwipeDismiss.d.ts +22 -0
- package/build/types/Snackbar/useSnackbarSwipeDismiss.d.ts.map +1 -0
- package/build/types/index.d.ts +1 -5
- package/build/types/index.d.ts.map +1 -1
- package/build/types/test-utils/index.d.ts +2 -0
- package/build/types/test-utils/index.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/FlowNavigation/_stories/FlowNavigation.CriticalBanner.docs.mdx +66 -0
- package/src/Prompt/CriticalBanner/_stories/CriticalBanner.story.tsx +2 -0
- package/src/Snackbar/Snackbar.css +117 -54
- package/src/Snackbar/Snackbar.less +139 -60
- package/src/Snackbar/Snackbar.messages.ts +9 -0
- package/src/Snackbar/Snackbar.test.tsx +989 -119
- package/src/Snackbar/Snackbar.tsx +208 -93
- package/src/Snackbar/Snackbar.types.ts +17 -0
- package/src/Snackbar/SnackbarContext.ts +2 -2
- package/src/Snackbar/SnackbarPortal.tsx +8 -0
- package/src/Snackbar/SnackbarProvider.test.tsx +783 -0
- package/src/Snackbar/SnackbarProvider.tsx +27 -19
- package/src/Snackbar/_stories/Snackbar.accessibility.docs.mdx +58 -0
- package/src/Snackbar/_stories/Snackbar.rtl.test.story.tsx +16 -8
- package/src/Snackbar/_stories/Snackbar.story.tsx +388 -61
- package/src/Snackbar/_stories/Snackbar.test.story.tsx +171 -47
- package/src/Snackbar/constants.ts +10 -0
- package/src/Snackbar/index.ts +1 -1
- package/src/Snackbar/useSnackbarAutoDismiss.ts +74 -0
- package/src/Snackbar/useSnackbarManager.ts +169 -0
- package/src/Snackbar/useSnackbarSwipeDismiss.ts +169 -0
- package/src/i18n/en.json +1 -0
- package/src/index.ts +1 -14
- package/src/main.css +116 -245
- package/src/main.less +0 -2
- package/build/CardContainer/CardContainer.js +0 -34
- package/build/CardContainer/CardContainer.js.map +0 -1
- package/build/CardContainer/CardContainer.mjs +0 -30
- package/build/CardContainer/CardContainer.mjs.map +0 -1
- package/build/CardWidget/CardWidget.js +0 -98
- package/build/CardWidget/CardWidget.js.map +0 -1
- package/build/CardWidget/CardWidget.mjs +0 -94
- package/build/CardWidget/CardWidget.mjs.map +0 -1
- package/build/CardWidget/CardWidgetAction.js +0 -73
- package/build/CardWidget/CardWidgetAction.js.map +0 -1
- package/build/CardWidget/CardWidgetAction.mjs +0 -68
- package/build/CardWidget/CardWidgetAction.mjs.map +0 -1
- package/build/styles/CardContainer/CardContainer.css +0 -108
- package/build/styles/CardWidget/CardWidget.css +0 -84
- package/build/types/CardContainer/CardContainer.d.ts +0 -8
- package/build/types/CardContainer/CardContainer.d.ts.map +0 -1
- package/build/types/CardContainer/CardContainer.types.d.ts +0 -53
- package/build/types/CardContainer/CardContainer.types.d.ts.map +0 -1
- package/build/types/CardContainer/_stories/helpers.d.ts +0 -3
- package/build/types/CardContainer/_stories/helpers.d.ts.map +0 -1
- package/build/types/CardContainer/index.d.ts +0 -3
- package/build/types/CardContainer/index.d.ts.map +0 -1
- package/build/types/CardWidget/CardWidget.d.ts +0 -10
- package/build/types/CardWidget/CardWidget.d.ts.map +0 -1
- package/build/types/CardWidget/CardWidget.types.d.ts +0 -55
- package/build/types/CardWidget/CardWidget.types.d.ts.map +0 -1
- package/build/types/CardWidget/CardWidgetAction.d.ts +0 -54
- package/build/types/CardWidget/CardWidgetAction.d.ts.map +0 -1
- package/build/types/CardWidget/index.d.ts +0 -4
- package/build/types/CardWidget/index.d.ts.map +0 -1
- package/src/CardContainer/CardContainer.css +0 -108
- package/src/CardContainer/CardContainer.less +0 -171
- package/src/CardContainer/CardContainer.test.tsx +0 -150
- package/src/CardContainer/CardContainer.tsx +0 -51
- package/src/CardContainer/CardContainer.types.ts +0 -60
- package/src/CardContainer/_stories/CardContainer.story.tsx +0 -167
- package/src/CardContainer/_stories/CardContainer.test.story.tsx +0 -103
- package/src/CardContainer/_stories/helpers.tsx +0 -50
- package/src/CardContainer/index.ts +0 -6
- package/src/CardWidget/CardWidget.css +0 -84
- package/src/CardWidget/CardWidget.less +0 -110
- package/src/CardWidget/CardWidget.test.tsx +0 -222
- package/src/CardWidget/CardWidget.tsx +0 -83
- package/src/CardWidget/CardWidget.types.ts +0 -63
- package/src/CardWidget/CardWidgetAction.tsx +0 -128
- package/src/CardWidget/_stories/CardWidget.story.tsx +0 -238
- package/src/CardWidget/_stories/CardWidget.test.story.tsx +0 -350
- package/src/CardWidget/index.ts +0 -3
- package/src/Prompt/CriticalBanner/_stories/CriticalBanner.docs.mdx +0 -122
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import type { HTMLAttributes, ReactNode } from 'react';
|
|
2
|
-
/**
|
|
3
|
-
* Highlights the card, matching `ListItem`'s `spotlight`.
|
|
4
|
-
*
|
|
5
|
-
* - `active` — live content the user can act on. Raised, with a soft shadow and a hairline border.
|
|
6
|
-
* - `inactive` — a feature the user has not set up yet. Recessed, with a dashed stroke.
|
|
7
|
-
*
|
|
8
|
-
* Without a spotlight the card is flat, with a solid stroke, for content that is present but not
|
|
9
|
-
* actionable.
|
|
10
|
-
*/
|
|
11
|
-
export type CardContainerSpotlight = 'active' | 'inactive';
|
|
12
|
-
/**
|
|
13
|
-
* - `md` — 8px, and 16px from the `md` breakpoint up.
|
|
14
|
-
* - `none` — content runs to the card's edges.
|
|
15
|
-
*/
|
|
16
|
-
export type CardContainerPadding = 'md' | 'none';
|
|
17
|
-
export interface CardContainerProps extends HTMLAttributes<HTMLElement> {
|
|
18
|
-
/**
|
|
19
|
-
* Highlights the card as live content (`active`) or as a feature not set up yet (`inactive`).
|
|
20
|
-
* Leave unset for a flat card.
|
|
21
|
-
* @default undefined
|
|
22
|
-
*/
|
|
23
|
-
spotlight?: CardContainerSpotlight;
|
|
24
|
-
/**
|
|
25
|
-
* Space between the card's edge and its content. `none` lets content such as images or charts
|
|
26
|
-
* run to the card's edges, clipped to its rounded corners. Anything clipped at the edges
|
|
27
|
-
* includes focus rings, so use `none` for non-interactive content, and keep lists on `md`.
|
|
28
|
-
* @default 'md'
|
|
29
|
-
*/
|
|
30
|
-
padding?: CardContainerPadding;
|
|
31
|
-
/**
|
|
32
|
-
* Content, stacked with no gap.
|
|
33
|
-
* @default undefined
|
|
34
|
-
*/
|
|
35
|
-
children?: ReactNode;
|
|
36
|
-
/**
|
|
37
|
-
* Element rendered as the root.
|
|
38
|
-
* @default 'section'
|
|
39
|
-
*/
|
|
40
|
-
as?: 'section' | 'div' | 'article';
|
|
41
|
-
/**
|
|
42
|
-
* Shows the card as hovered or pressed while a direct child link (with an `href`) or enabled
|
|
43
|
-
* button is, such as a link that fills the card, and as hovered while that child has keyboard
|
|
44
|
-
* focus. The rest of the card,
|
|
45
|
-
* and controls nested deeper, don't trigger the states, so the card is only shown as something
|
|
46
|
-
* to act on where it can be clicked.
|
|
47
|
-
* @default false
|
|
48
|
-
*/
|
|
49
|
-
interactive?: boolean;
|
|
50
|
-
className?: string;
|
|
51
|
-
'data-testid'?: string;
|
|
52
|
-
}
|
|
53
|
-
//# sourceMappingURL=CardContainer.types.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"CardContainer.types.d.ts","sourceRoot":"","sources":["../../../src/CardContainer/CardContainer.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvD;;;;;;;;GAQG;AACH,MAAM,MAAM,sBAAsB,GAAG,QAAQ,GAAG,UAAU,CAAC;AAE3D;;;GAGG;AACH,MAAM,MAAM,oBAAoB,GAAG,IAAI,GAAG,MAAM,CAAC;AAEjD,MAAM,WAAW,kBAAmB,SAAQ,cAAc,CAAC,WAAW,CAAC;IACrE;;;;OAIG;IACH,SAAS,CAAC,EAAE,sBAAsB,CAAC;IAEnC;;;;;OAKG;IACH,OAAO,CAAC,EAAE,oBAAoB,CAAC;IAE/B;;;OAGG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;IAErB;;;OAGG;IACH,EAAE,CAAC,EAAE,SAAS,GAAG,KAAK,GAAG,SAAS,CAAC;IAEnC;;;;;;;OAOG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../../src/CardContainer/_stories/helpers.tsx"],"names":[],"mappings":"AAMA,eAAO,MAAM,aAAa,mCAKzB,CAAC;AAEF,eAAO,MAAM,SAAS,mCAoCrB,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/CardContainer/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC1C,YAAY,EACV,kBAAkB,EAClB,sBAAsB,EACtB,oBAAoB,GACrB,MAAM,uBAAuB,CAAC"}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import type { CardWidgetProps } from './CardWidget.types';
|
|
2
|
-
/**
|
|
3
|
-
* A `CardContainer` with an optional header — a title, a title link and up to two actions — above
|
|
4
|
-
* its content. The card shows as hovered or pressed while the title link is, and as hovered while
|
|
5
|
-
* the link has keyboard focus. Hovering or pressing the rest of the card, or its actions, leaves it
|
|
6
|
-
* at rest.
|
|
7
|
-
*/
|
|
8
|
-
declare const CardWidget: import("react").ForwardRefExoticComponent<CardWidgetProps & import("react").RefAttributes<HTMLElement>>;
|
|
9
|
-
export default CardWidget;
|
|
10
|
-
//# sourceMappingURL=CardWidget.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"CardWidget.d.ts","sourceRoot":"","sources":["../../../src/CardWidget/CardWidget.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAoB,eAAe,EAAE,MAAM,oBAAoB,CAAC;AA6C5E;;;;;GAKG;AACH,QAAA,MAAM,UAAU,yGAmBf,CAAC;AAIF,eAAe,UAAU,CAAC"}
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import type { ReactNode } from 'react';
|
|
2
|
-
import type { Heading } from '../common';
|
|
3
|
-
import type { CardContainerProps } from '../CardContainer';
|
|
4
|
-
import type { LinkProps } from '../Link';
|
|
5
|
-
import type { CardWidgetActionButton } from './CardWidgetAction';
|
|
6
|
-
/**
|
|
7
|
-
* Props passed to the [Link](https://storybook.wise.design/?path=/docs/typography-link--docs)
|
|
8
|
-
* that the title is rendered as. A trailing chevron is rendered automatically, so do not put one
|
|
9
|
-
* in `title`.
|
|
10
|
-
*/
|
|
11
|
-
export type CardWidgetTitleAction = Pick<LinkProps, 'href' | 'target' | 'onClick'>;
|
|
12
|
-
export interface CardWidgetHeader {
|
|
13
|
-
/** The widget's title. */
|
|
14
|
-
title: ReactNode;
|
|
15
|
-
/**
|
|
16
|
-
* Heading element rendered for the title.
|
|
17
|
-
* @default 'h3'
|
|
18
|
-
*/
|
|
19
|
-
as?: Heading;
|
|
20
|
-
/**
|
|
21
|
-
* Makes the title a link with a trailing chevron.
|
|
22
|
-
* @default undefined
|
|
23
|
-
*/
|
|
24
|
-
titleAction?: CardWidgetTitleAction;
|
|
25
|
-
/**
|
|
26
|
-
* A `CardWidgetActionButton` object (with a `label` or an `icon`) renders a small button,
|
|
27
|
-
* anchored to the inline end. Any other node is rendered as given.
|
|
28
|
-
* @default undefined
|
|
29
|
-
*/
|
|
30
|
-
action?: CardWidgetActionButton | ReactNode;
|
|
31
|
-
/**
|
|
32
|
-
* Second action, at a lower emphasis, rendered before `action`. Two is the maximum, to keep
|
|
33
|
-
* the title legible. Takes the same values as `action`, and keeps its lower emphasis when used
|
|
34
|
-
* on its own.
|
|
35
|
-
* @default undefined
|
|
36
|
-
*/
|
|
37
|
-
actionSecondary?: CardWidgetActionButton | ReactNode;
|
|
38
|
-
}
|
|
39
|
-
/**
|
|
40
|
-
* The widget always has the card's default padding, so its header and content line up, and its
|
|
41
|
-
* states always follow its title link.
|
|
42
|
-
*/
|
|
43
|
-
export interface CardWidgetProps extends Omit<CardContainerProps, 'padding' | 'interactive'> {
|
|
44
|
-
/**
|
|
45
|
-
* The widget's header: a title, optionally a link, and up to two actions.
|
|
46
|
-
* @default undefined
|
|
47
|
-
*/
|
|
48
|
-
header?: CardWidgetHeader;
|
|
49
|
-
/**
|
|
50
|
-
* The widget's content, rendered under the header.
|
|
51
|
-
* @default undefined
|
|
52
|
-
*/
|
|
53
|
-
children?: ReactNode;
|
|
54
|
-
}
|
|
55
|
-
//# sourceMappingURL=CardWidget.types.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"CardWidget.types.d.ts","sourceRoot":"","sources":["../../../src/CardWidget/CardWidget.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAEjE;;;;GAIG;AACH,MAAM,MAAM,qBAAqB,GAAG,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS,CAAC,CAAC;AAEnF,MAAM,WAAW,gBAAgB;IAC/B,0BAA0B;IAC1B,KAAK,EAAE,SAAS,CAAC;IAEjB;;;OAGG;IACH,EAAE,CAAC,EAAE,OAAO,CAAC;IAEb;;;OAGG;IACH,WAAW,CAAC,EAAE,qBAAqB,CAAC;IAEpC;;;;OAIG;IACH,MAAM,CAAC,EAAE,sBAAsB,GAAG,SAAS,CAAC;IAE5C;;;;;OAKG;IACH,eAAe,CAAC,EAAE,sBAAsB,GAAG,SAAS,CAAC;CACtD;AAED;;;GAGG;AACH,MAAM,WAAW,eAAgB,SAAQ,IAAI,CAAC,kBAAkB,EAAE,SAAS,GAAG,aAAa,CAAC;IAC1F;;;OAGG;IACH,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAE1B;;;OAGG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB"}
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import { type MouseEventHandler, type ReactNode } from 'react';
|
|
2
|
-
import type { ButtonProps } from '../Button/Button.types';
|
|
3
|
-
/** The action slot a `CardWidgetActionButton` was passed to, which is what determines its emphasis. */
|
|
4
|
-
export type CardWidgetActionSlot = 'action' | 'actionSecondary';
|
|
5
|
-
type CardWidgetActionButtonBase = Pick<ButtonProps, 'href' | 'target' | 'disabled'> & {
|
|
6
|
-
/**
|
|
7
|
-
* `HTMLElement` rather than a narrower target, because an action is a `button` or an `a`
|
|
8
|
-
* depending on whether `href` is set.
|
|
9
|
-
* @default undefined
|
|
10
|
-
*/
|
|
11
|
-
onClick?: MouseEventHandler<HTMLElement>;
|
|
12
|
-
/**
|
|
13
|
-
* Rendered after `label`, or as the only content of an unlabelled action.
|
|
14
|
-
* Size it yourself — 16px is expected in both cases.
|
|
15
|
-
* @default undefined
|
|
16
|
-
*/
|
|
17
|
-
icon?: ReactNode;
|
|
18
|
-
'data-testid'?: string;
|
|
19
|
-
};
|
|
20
|
-
/** An action with a visible label, rendered as a small button. */
|
|
21
|
-
type CardWidgetLabelledActionButton = CardWidgetActionButtonBase & {
|
|
22
|
-
/** Non-rendering values are excluded, so an unlabelled action has to meet the icon-only rules. */
|
|
23
|
-
label: Exclude<ButtonProps['children'], null | undefined | boolean>;
|
|
24
|
-
/** @default undefined */
|
|
25
|
-
'aria-label'?: string;
|
|
26
|
-
};
|
|
27
|
-
/**
|
|
28
|
-
* An action with no visible label, rendered as a 32px icon button. The icon is
|
|
29
|
-
* the only thing on screen and `aria-label` is the only accessible name, so
|
|
30
|
-
* both are required.
|
|
31
|
-
*/
|
|
32
|
-
type CardWidgetIconActionButton = CardWidgetActionButtonBase & {
|
|
33
|
-
label?: never;
|
|
34
|
-
icon: ReactNode;
|
|
35
|
-
'aria-label': string;
|
|
36
|
-
};
|
|
37
|
-
/**
|
|
38
|
-
* An action the `CardWidget` header renders as a button. With a `label` it is a small `Button`; without
|
|
39
|
-
* one, a 32px `IconButton`, which requires both an `icon` and an `aria-label`. Emphasis is not
|
|
40
|
-
* part of the object — it comes from the slot the action is passed to.
|
|
41
|
-
*/
|
|
42
|
-
export type CardWidgetActionButton = CardWidgetLabelledActionButton | CardWidgetIconActionButton;
|
|
43
|
-
/**
|
|
44
|
-
* Tells a `CardWidgetActionButton` object apart from any other node passed to an action slot.
|
|
45
|
-
* Every button action has a `label` or an `icon`, which no React element, portal or array does.
|
|
46
|
-
*/
|
|
47
|
-
export declare const isCardWidgetActionButton: (value: unknown) => value is CardWidgetActionButton;
|
|
48
|
-
/** Renders a `CardWidgetActionButton` at the emphasis of the slot it was passed to. */
|
|
49
|
-
declare const CardWidgetAction: ({ action: { label, icon, "aria-label": ariaLabel, "data-testid": dataTestId, href, target, onClick, disabled, }, slot, }: {
|
|
50
|
-
action: CardWidgetActionButton;
|
|
51
|
-
slot: CardWidgetActionSlot;
|
|
52
|
-
}) => import("react").JSX.Element;
|
|
53
|
-
export default CardWidgetAction;
|
|
54
|
-
//# sourceMappingURL=CardWidgetAction.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"CardWidgetAction.d.ts","sourceRoot":"","sources":["../../../src/CardWidget/CardWidgetAction.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAkB,KAAK,iBAAiB,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAG/E,OAAO,KAAK,EAAkB,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAG1E,uGAAuG;AACvG,MAAM,MAAM,oBAAoB,GAAG,QAAQ,GAAG,iBAAiB,CAAC;AAEhE,KAAK,0BAA0B,GAAG,IAAI,CAAC,WAAW,EAAE,MAAM,GAAG,QAAQ,GAAG,UAAU,CAAC,GAAG;IACpF;;;;OAIG;IACH,OAAO,CAAC,EAAE,iBAAiB,CAAC,WAAW,CAAC,CAAC;IAEzC;;;;OAIG;IACH,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,kEAAkE;AAClE,KAAK,8BAA8B,GAAG,0BAA0B,GAAG;IACjE,kGAAkG;IAClG,KAAK,EAAE,OAAO,CAAC,WAAW,CAAC,UAAU,CAAC,EAAE,IAAI,GAAG,SAAS,GAAG,OAAO,CAAC,CAAC;IACpE,yBAAyB;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF;;;;GAIG;AACH,KAAK,0BAA0B,GAAG,0BAA0B,GAAG;IAC7D,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,IAAI,EAAE,SAAS,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,sBAAsB,GAAG,8BAA8B,GAAG,0BAA0B,CAAC;AAYjG;;;GAGG;AACH,eAAO,MAAM,wBAAwB,GAAI,OAAO,OAAO,KAAG,KAAK,IAAI,sBAK5B,CAAC;AAExC,uFAAuF;AACvF,QAAA,MAAM,gBAAgB,GAA6B,0HAYhD;IACD,MAAM,EAAE,sBAAsB,CAAC;IAC/B,IAAI,EAAE,oBAAoB,CAAC;CAC5B,gCAoCA,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/CardWidget/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AACnG,YAAY,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
.wds-card-container {
|
|
2
|
-
--CardContainer-shadow: var(--CardContainer-theme-shadow, none);
|
|
3
|
-
--CardContainer-background-color: var(--color-background-screen);
|
|
4
|
-
--CardContainer-border-color: var(--color-border-neutral);
|
|
5
|
-
--CardContainer-border-radius: var(--radius-large);
|
|
6
|
-
--CardContainer-padding-block: var(--size-8);
|
|
7
|
-
--CardContainer-padding-inline: var(--size-8);
|
|
8
|
-
background-color: var(--CardContainer-background-color);
|
|
9
|
-
border: 1px solid var(--CardContainer-border-color);
|
|
10
|
-
border-radius: var(--CardContainer-border-radius);
|
|
11
|
-
box-sizing: border-box;
|
|
12
|
-
display: flex;
|
|
13
|
-
flex-direction: column;
|
|
14
|
-
padding-block: var(--CardContainer-padding-block);
|
|
15
|
-
padding-inline: var(--CardContainer-padding-inline);
|
|
16
|
-
inline-size: 100%;
|
|
17
|
-
}
|
|
18
|
-
@media (min-width: 840px) {
|
|
19
|
-
.wds-card-container {
|
|
20
|
-
--CardContainer-padding-block: var(--size-16);
|
|
21
|
-
--CardContainer-padding-inline: var(--size-16);
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
.wds-card-container--padding-none {
|
|
25
|
-
--CardContainer-padding-block: 0px;
|
|
26
|
-
--CardContainer-padding-inline: 0px;
|
|
27
|
-
overflow: clip;
|
|
28
|
-
}
|
|
29
|
-
.wds-card-container--active {
|
|
30
|
-
--CardContainer-background-color: var(--color-background-elevated);
|
|
31
|
-
--CardContainer-border-color: color-mix(in srgb, var(--color-border-neutral) 25%, transparent);
|
|
32
|
-
box-shadow: var(--CardContainer-shadow);
|
|
33
|
-
}
|
|
34
|
-
.wds-card-container--inactive {
|
|
35
|
-
--CardContainer-background-color: color-mix(in srgb, var(--color-background-neutral) 25%, transparent);
|
|
36
|
-
border-width: 0;
|
|
37
|
-
padding-block: calc(var(--CardContainer-padding-block) + 1px);
|
|
38
|
-
padding-inline: calc(var(--CardContainer-padding-inline) + 1px);
|
|
39
|
-
position: relative;
|
|
40
|
-
}
|
|
41
|
-
.wds-card-container--interactive:has(
|
|
42
|
-
> a[href]:hover,
|
|
43
|
-
> button:enabled:hover,
|
|
44
|
-
> a[href]:focus-visible,
|
|
45
|
-
> button:enabled:focus-visible
|
|
46
|
-
).wds-card-container--active {
|
|
47
|
-
--CardContainer-border-color: color-mix(in srgb, var(--color-border-neutral) 75%, transparent);
|
|
48
|
-
}
|
|
49
|
-
.wds-card-container--interactive:has(
|
|
50
|
-
> a[href]:hover,
|
|
51
|
-
> button:enabled:hover,
|
|
52
|
-
> a[href]:focus-visible,
|
|
53
|
-
> button:enabled:focus-visible
|
|
54
|
-
).wds-card-container--inactive {
|
|
55
|
-
--CardContainer-background-color: color-mix(in srgb, var(--color-background-neutral-hover) 25%, transparent);
|
|
56
|
-
}
|
|
57
|
-
.wds-card-container--interactive:has(> a[href]:active, > button:enabled:active).wds-card-container--active {
|
|
58
|
-
--CardContainer-border-color: var(--color-border-neutral);
|
|
59
|
-
}
|
|
60
|
-
.wds-card-container--interactive:has(> a[href]:active, > button:enabled:active).wds-card-container--inactive {
|
|
61
|
-
--CardContainer-background-color: color-mix(in srgb, var(--color-background-neutral-active) 25%, transparent);
|
|
62
|
-
}
|
|
63
|
-
.wds-card-container__border {
|
|
64
|
-
container-type: size;
|
|
65
|
-
inset: 0;
|
|
66
|
-
pointer-events: none;
|
|
67
|
-
position: absolute;
|
|
68
|
-
}
|
|
69
|
-
.wds-card-container__border svg {
|
|
70
|
-
display: block;
|
|
71
|
-
block-size: 100%;
|
|
72
|
-
inline-size: 100%;
|
|
73
|
-
}
|
|
74
|
-
.wds-card-container__border rect {
|
|
75
|
-
--CardContainer-border-dash-size: calc(var(--size-12) * 0.5);
|
|
76
|
-
--CardContainer-border-stroke-radius: calc(min(var(--CardContainer-border-radius), 50cqh, 50cqw) - 0.5px);
|
|
77
|
-
fill: none;
|
|
78
|
-
block-size: calc(100% - 1px);
|
|
79
|
-
rx: var(--CardContainer-border-stroke-radius);
|
|
80
|
-
ry: var(--CardContainer-border-stroke-radius);
|
|
81
|
-
stroke: var(--color-border-neutral);
|
|
82
|
-
stroke-dasharray: var(--CardContainer-border-dash-size) var(--CardContainer-border-dash-size);
|
|
83
|
-
inline-size: calc(100% - 1px);
|
|
84
|
-
x: 0.5px;
|
|
85
|
-
y: 0.5px;
|
|
86
|
-
}
|
|
87
|
-
/**
|
|
88
|
-
* The active spotlight's resting shadow, only designed for the light themes. Set on every theme
|
|
89
|
-
* root, as a nested ThemeProvider renders its own, so a card follows its nearest theme: a dark or
|
|
90
|
-
* green provider inside a light one turns the shadow off.
|
|
91
|
-
*
|
|
92
|
-
* There is no shadow or elevation token in @transferwise/neptune-tokens, so the value is
|
|
93
|
-
* component-scoped for now, the way PromoCard scopes `--Card-box-shadow`. It is the "Card Active
|
|
94
|
-
* shadow" effect style from Figma: `#0e0f0c` at 4%, kept literal so it doesn't drift with a
|
|
95
|
-
* theme's tokens. Collapses to a token reference once one is minted.
|
|
96
|
-
*/
|
|
97
|
-
.np-theme-personal {
|
|
98
|
-
--CardContainer-theme-shadow: 0 2px 12px rgba(14, 15, 12, 0.04), 0 2px 32px rgba(14, 15, 12, 0.04);
|
|
99
|
-
}
|
|
100
|
-
.np-theme-personal.np-theme-personal--dark,
|
|
101
|
-
.np-theme-personal.np-theme-personal--bright-green,
|
|
102
|
-
.np-theme-personal.np-theme-personal--forest-green,
|
|
103
|
-
.np-theme-personal.np-theme-business--dark,
|
|
104
|
-
.np-theme-personal.np-theme-business--bright-green,
|
|
105
|
-
.np-theme-personal.np-theme-business--forest-green,
|
|
106
|
-
.np-theme-personal.np-theme-platform--forest-green {
|
|
107
|
-
--CardContainer-theme-shadow: none;
|
|
108
|
-
}
|
|
@@ -1,171 +0,0 @@
|
|
|
1
|
-
// The hover and pressed states, as mixins so CardWidget can apply them to the card when only its
|
|
2
|
-
// title is hovered or pressed. Applied to the card's root.
|
|
3
|
-
.wds-card-container-hover-state() {
|
|
4
|
-
// The active spotlight keeps its resting shadow, and its hairline border strengthens.
|
|
5
|
-
&.wds-card-container--active {
|
|
6
|
-
--CardContainer-border-color: color-mix(in srgb, var(--color-border-neutral) 75%, transparent);
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
// The inactive spotlight's fill takes its hover value, at the same 25% strength as at rest.
|
|
10
|
-
&.wds-card-container--inactive {
|
|
11
|
-
--CardContainer-background-color: color-mix(
|
|
12
|
-
in srgb,
|
|
13
|
-
var(--color-background-neutral-hover) 25%,
|
|
14
|
-
transparent
|
|
15
|
-
);
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
.wds-card-container-pressed-state() {
|
|
20
|
-
// The active spotlight keeps its resting shadow, and its border is at full strength.
|
|
21
|
-
&.wds-card-container--active {
|
|
22
|
-
--CardContainer-border-color: var(--color-border-neutral);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
// The inactive spotlight's fill takes its pressed value, at the same 25% strength as at rest.
|
|
26
|
-
&.wds-card-container--inactive {
|
|
27
|
-
--CardContainer-background-color: color-mix(
|
|
28
|
-
in srgb,
|
|
29
|
-
var(--color-background-neutral-active) 25%,
|
|
30
|
-
transparent
|
|
31
|
-
);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
.wds-card-container {
|
|
36
|
-
// Resolved at the nearest theme root, below.
|
|
37
|
-
--CardContainer-shadow: var(--CardContainer-theme-shadow, none);
|
|
38
|
-
--CardContainer-background-color: var(--color-background-screen);
|
|
39
|
-
--CardContainer-border-color: var(--color-border-neutral);
|
|
40
|
-
--CardContainer-border-radius: var(--radius-large);
|
|
41
|
-
--CardContainer-padding-block: var(--size-8);
|
|
42
|
-
--CardContainer-padding-inline: var(--size-8);
|
|
43
|
-
|
|
44
|
-
background-color: var(--CardContainer-background-color);
|
|
45
|
-
border: 1px solid var(--CardContainer-border-color);
|
|
46
|
-
border-radius: var(--CardContainer-border-radius);
|
|
47
|
-
box-sizing: border-box;
|
|
48
|
-
display: flex;
|
|
49
|
-
flex-direction: column;
|
|
50
|
-
padding: var(--CardContainer-padding-block) var(--CardContainer-padding-inline);
|
|
51
|
-
width: 100%;
|
|
52
|
-
|
|
53
|
-
@media (--screen-md) {
|
|
54
|
-
--CardContainer-padding-block: var(--size-16);
|
|
55
|
-
--CardContainer-padding-inline: var(--size-16);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
// Set through the padding variables, so the `inactive` spotlight's padding still composes.
|
|
59
|
-
// Length zeroes, as the inactive spotlight adds `1px` to these in `calc()`, which a unitless `0`
|
|
60
|
-
// would invalidate.
|
|
61
|
-
&--padding-none {
|
|
62
|
-
--CardContainer-padding-block: 0px;
|
|
63
|
-
--CardContainer-padding-inline: 0px;
|
|
64
|
-
|
|
65
|
-
// Full-bleed content has to follow the card's rounded corners. `overflow` leaves the card's
|
|
66
|
-
// own shadow alone, which `clip-path` would cut off.
|
|
67
|
-
overflow: clip;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
&--active {
|
|
71
|
-
--CardContainer-background-color: var(--color-background-elevated);
|
|
72
|
-
// The raised surface's shadow already separates it, so its border is a softer hairline.
|
|
73
|
-
--CardContainer-border-color: color-mix(in srgb, var(--color-border-neutral) 25%, transparent);
|
|
74
|
-
|
|
75
|
-
box-shadow: var(--CardContainer-shadow);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
&--inactive {
|
|
79
|
-
--CardContainer-background-color: color-mix(
|
|
80
|
-
in srgb,
|
|
81
|
-
var(--color-background-neutral) 25%,
|
|
82
|
-
transparent
|
|
83
|
-
);
|
|
84
|
-
|
|
85
|
-
// The dashed stroke is drawn inside the card instead of on a border, so the stroke isn't
|
|
86
|
-
// clipped with `padding="none"`. The padding takes the border's 1px, so content stays put.
|
|
87
|
-
border-width: 0;
|
|
88
|
-
padding: calc(var(--CardContainer-padding-block) + 1px)
|
|
89
|
-
calc(var(--CardContainer-padding-inline) + 1px);
|
|
90
|
-
position: relative;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
// An `interactive` card follows its direct child link or button, such as a link that fills the
|
|
94
|
-
// card, so it only looks clickable where it can be clicked. Keyboard focus on the child shows the
|
|
95
|
-
// hover state too. A card without a spotlight has no hover or pressed state.
|
|
96
|
-
&--interactive:has(
|
|
97
|
-
> a[href]:hover,
|
|
98
|
-
> button:enabled:hover,
|
|
99
|
-
> a[href]:focus-visible,
|
|
100
|
-
> button:enabled:focus-visible
|
|
101
|
-
) {
|
|
102
|
-
.wds-card-container-hover-state();
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
// Pressed state, while the same direct child is pressed. After the hover rule, so pressed wins
|
|
106
|
-
// while the pointer is down.
|
|
107
|
-
&--interactive:has(> a[href]:active, > button:enabled:active) {
|
|
108
|
-
.wds-card-container-pressed-state();
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
// Same treatment as ListItem's inactive spotlight: CSS `dashed` borders have a browser-chosen
|
|
112
|
-
// dash length, so the 6px/6px dashes are an SVG stroke along the card's edge.
|
|
113
|
-
&__border {
|
|
114
|
-
// A size container, so the stroke's corner radius can be capped by the card's height. An SVG
|
|
115
|
-
// `rect` clamps `rx` and `ry` separately, which turns the corners of a card shorter than twice
|
|
116
|
-
// the radius into ellipses, where `border-radius` keeps them round.
|
|
117
|
-
container-type: size;
|
|
118
|
-
inset: 0;
|
|
119
|
-
pointer-events: none;
|
|
120
|
-
position: absolute;
|
|
121
|
-
|
|
122
|
-
svg {
|
|
123
|
-
display: block;
|
|
124
|
-
height: 100%;
|
|
125
|
-
width: 100%;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
rect {
|
|
129
|
-
--CardContainer-border-dash-size: calc(var(--size-12) * 0.5);
|
|
130
|
-
--CardContainer-border-stroke-radius: calc(
|
|
131
|
-
min(var(--CardContainer-border-radius), 50cqh, 50cqw) - 0.5px
|
|
132
|
-
);
|
|
133
|
-
|
|
134
|
-
fill: none;
|
|
135
|
-
height: calc(100% - 1px);
|
|
136
|
-
rx: var(--CardContainer-border-stroke-radius);
|
|
137
|
-
ry: var(--CardContainer-border-stroke-radius);
|
|
138
|
-
stroke: var(--color-border-neutral);
|
|
139
|
-
stroke-dasharray: var(--CardContainer-border-dash-size) var(--CardContainer-border-dash-size);
|
|
140
|
-
width: calc(100% - 1px);
|
|
141
|
-
x: 0.5px;
|
|
142
|
-
y: 0.5px;
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
/**
|
|
148
|
-
* The active spotlight's resting shadow, only designed for the light themes. Set on every theme
|
|
149
|
-
* root, as a nested ThemeProvider renders its own, so a card follows its nearest theme: a dark or
|
|
150
|
-
* green provider inside a light one turns the shadow off.
|
|
151
|
-
*
|
|
152
|
-
* There is no shadow or elevation token in @transferwise/neptune-tokens, so the value is
|
|
153
|
-
* component-scoped for now, the way PromoCard scopes `--Card-box-shadow`. It is the "Card Active
|
|
154
|
-
* shadow" effect style from Figma: `#0e0f0c` at 4%, kept literal so it doesn't drift with a
|
|
155
|
-
* theme's tokens. Collapses to a token reference once one is minted.
|
|
156
|
-
*/
|
|
157
|
-
.np-theme-personal {
|
|
158
|
-
--CardContainer-theme-shadow: 0 2px 12px rgb(14 15 12 / 4%), 0 2px 32px rgb(14 15 12 / 4%);
|
|
159
|
-
|
|
160
|
-
&:is(
|
|
161
|
-
.np-theme-personal--dark,
|
|
162
|
-
.np-theme-personal--bright-green,
|
|
163
|
-
.np-theme-personal--forest-green,
|
|
164
|
-
.np-theme-business--dark,
|
|
165
|
-
.np-theme-business--bright-green,
|
|
166
|
-
.np-theme-business--forest-green,
|
|
167
|
-
.np-theme-platform--forest-green
|
|
168
|
-
) {
|
|
169
|
-
--CardContainer-theme-shadow: none;
|
|
170
|
-
}
|
|
171
|
-
}
|
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
import { render, screen, userEvent } from '../test-utils';
|
|
2
|
-
import CardContainer from './CardContainer';
|
|
3
|
-
import type { CardContainerSpotlight } from './CardContainer.types';
|
|
4
|
-
|
|
5
|
-
describe('CardContainer', () => {
|
|
6
|
-
const content = 'Container content';
|
|
7
|
-
|
|
8
|
-
describe('rendering', () => {
|
|
9
|
-
it('renders children', () => {
|
|
10
|
-
render(<CardContainer>{content}</CardContainer>);
|
|
11
|
-
expect(screen.getByText(content)).toBeInTheDocument();
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
it('renders as a section by default', () => {
|
|
15
|
-
render(<CardContainer data-testid="container">{content}</CardContainer>);
|
|
16
|
-
expect(screen.getByTestId('container').tagName).toBe('SECTION');
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
it.each(['div', 'article'] as const)('renders as %s when as is provided', (as) => {
|
|
20
|
-
render(
|
|
21
|
-
<CardContainer as={as} data-testid="container">
|
|
22
|
-
{content}
|
|
23
|
-
</CardContainer>,
|
|
24
|
-
);
|
|
25
|
-
expect(screen.getByTestId('container').tagName).toBe(as.toUpperCase());
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
it('applies className to the root element', () => {
|
|
29
|
-
render(
|
|
30
|
-
<CardContainer className="custom-class" data-testid="container">
|
|
31
|
-
{content}
|
|
32
|
-
</CardContainer>,
|
|
33
|
-
);
|
|
34
|
-
expect(screen.getByTestId('container')).toHaveClass('wds-card-container', 'custom-class');
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
it('spreads unknown props onto the root element', () => {
|
|
38
|
-
render(
|
|
39
|
-
<CardContainer aria-label="Cards" data-testid="container">
|
|
40
|
-
{content}
|
|
41
|
-
</CardContainer>,
|
|
42
|
-
);
|
|
43
|
-
expect(screen.getByTestId('container')).toHaveAttribute('aria-label', 'Cards');
|
|
44
|
-
});
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
describe('padding', () => {
|
|
48
|
-
it('has no padding modifier by default', () => {
|
|
49
|
-
render(<CardContainer data-testid="container">{content}</CardContainer>);
|
|
50
|
-
expect(screen.getByTestId('container')).not.toHaveClass('wds-card-container--padding-none');
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
it('renders the padding-none modifier', () => {
|
|
54
|
-
render(
|
|
55
|
-
<CardContainer padding="none" data-testid="container">
|
|
56
|
-
{content}
|
|
57
|
-
</CardContainer>,
|
|
58
|
-
);
|
|
59
|
-
expect(screen.getByTestId('container')).toHaveClass('wds-card-container--padding-none');
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
it('keeps the dashed border for the inactive spotlight without padding', () => {
|
|
63
|
-
render(
|
|
64
|
-
<CardContainer padding="none" spotlight="inactive" data-testid="container">
|
|
65
|
-
{content}
|
|
66
|
-
</CardContainer>,
|
|
67
|
-
);
|
|
68
|
-
expect(
|
|
69
|
-
screen.getByTestId('container').querySelector('.wds-card-container__border'),
|
|
70
|
-
).toBeInTheDocument();
|
|
71
|
-
});
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
describe('spotlight', () => {
|
|
75
|
-
it('has no spotlight modifier by default', () => {
|
|
76
|
-
render(<CardContainer data-testid="container">{content}</CardContainer>);
|
|
77
|
-
const root = screen.getByTestId('container');
|
|
78
|
-
expect(root).not.toHaveClass('wds-card-container--active');
|
|
79
|
-
expect(root).not.toHaveClass('wds-card-container--inactive');
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
it.each<CardContainerSpotlight>(['active', 'inactive'])(
|
|
83
|
-
'renders the %s spotlight modifier',
|
|
84
|
-
(spotlight) => {
|
|
85
|
-
render(
|
|
86
|
-
<CardContainer spotlight={spotlight} data-testid="container">
|
|
87
|
-
{content}
|
|
88
|
-
</CardContainer>,
|
|
89
|
-
);
|
|
90
|
-
expect(screen.getByTestId('container')).toHaveClass(`wds-card-container--${spotlight}`);
|
|
91
|
-
},
|
|
92
|
-
);
|
|
93
|
-
|
|
94
|
-
it('draws a decorative dashed border for the inactive spotlight', () => {
|
|
95
|
-
render(
|
|
96
|
-
<CardContainer spotlight="inactive" data-testid="container">
|
|
97
|
-
{content}
|
|
98
|
-
</CardContainer>,
|
|
99
|
-
);
|
|
100
|
-
expect(
|
|
101
|
-
screen.getByTestId('container').querySelector('.wds-card-container__border'),
|
|
102
|
-
).toHaveAttribute('aria-hidden', 'true');
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
it.each<CardContainerSpotlight | undefined>(['active', undefined])(
|
|
106
|
-
'draws no dashed border for spotlight %s',
|
|
107
|
-
(spotlight) => {
|
|
108
|
-
render(
|
|
109
|
-
<CardContainer spotlight={spotlight} data-testid="container">
|
|
110
|
-
{content}
|
|
111
|
-
</CardContainer>,
|
|
112
|
-
);
|
|
113
|
-
const root = screen.getByTestId('container');
|
|
114
|
-
expect(root.querySelector('.wds-card-container__border')).not.toBeInTheDocument();
|
|
115
|
-
},
|
|
116
|
-
);
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
describe('interactive', () => {
|
|
120
|
-
it('is not interactive by default', () => {
|
|
121
|
-
render(<CardContainer data-testid="container">{content}</CardContainer>);
|
|
122
|
-
expect(screen.getByTestId('container')).not.toHaveClass('wds-card-container--interactive');
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
it('adds the interactive modifier without changing the element', () => {
|
|
126
|
-
render(
|
|
127
|
-
<CardContainer interactive data-testid="container">
|
|
128
|
-
<a href="/cards">{content}</a>
|
|
129
|
-
</CardContainer>,
|
|
130
|
-
);
|
|
131
|
-
const root = screen.getByTestId('container');
|
|
132
|
-
expect(root.tagName).toBe('SECTION');
|
|
133
|
-
expect(root).toHaveClass('wds-card-container--interactive');
|
|
134
|
-
expect(root).not.toHaveAttribute('interactive');
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
it('spreads onClick onto the root element as a plain handler', async () => {
|
|
138
|
-
const onClick = jest.fn();
|
|
139
|
-
render(
|
|
140
|
-
<CardContainer data-testid="container" onClick={onClick}>
|
|
141
|
-
{content}
|
|
142
|
-
</CardContainer>,
|
|
143
|
-
);
|
|
144
|
-
const root = screen.getByTestId('container');
|
|
145
|
-
expect(root.tagName).toBe('SECTION');
|
|
146
|
-
await userEvent.click(root);
|
|
147
|
-
expect(onClick).toHaveBeenCalledTimes(1);
|
|
148
|
-
});
|
|
149
|
-
});
|
|
150
|
-
});
|