@kaizen/components 2.5.0 → 3.0.0
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/cjs/src/Button/Button.cjs +2 -4
- package/dist/cjs/src/GuidanceBlock/GuidanceBlock.cjs +16 -82
- package/dist/cjs/src/GuidanceBlock/GuidanceBlock.module.css.cjs +0 -1
- package/dist/cjs/src/LinkButton/LinkButton.cjs +2 -4
- package/dist/cjs/src/Modal/ConfirmationModal/ConfirmationModal.cjs +3 -2
- package/dist/cjs/src/Modal/ContextModal/ContextModal.cjs +0 -1
- package/dist/cjs/src/Modal/GenericModal/GenericModal.cjs +2 -2
- package/dist/cjs/src/Modal/GenericModal/subcomponents/ModalFooter/ModalFooter.cjs +3 -6
- package/dist/cjs/src/Select/Select.cjs +14 -15
- package/dist/cjs/src/Select/Select.module.scss.cjs +0 -1
- package/dist/cjs/src/SingleSelect/SingleSelect.cjs +12 -19
- package/dist/cjs/src/SingleSelect/subcomponents/SelectToggle/SelectToggle.cjs +3 -5
- package/dist/cjs/src/SingleSelect/subcomponents/SelectToggle/SelectToggle.module.scss.cjs +0 -1
- package/dist/cjs/src/TimeField/TimeField.cjs +2 -3
- package/dist/esm/src/Button/Button.mjs +2 -4
- package/dist/esm/src/GuidanceBlock/GuidanceBlock.mjs +18 -84
- package/dist/esm/src/GuidanceBlock/GuidanceBlock.module.css.mjs +0 -1
- package/dist/esm/src/LinkButton/LinkButton.mjs +2 -4
- package/dist/esm/src/Modal/ConfirmationModal/ConfirmationModal.mjs +3 -2
- package/dist/esm/src/Modal/ContextModal/ContextModal.mjs +0 -1
- package/dist/esm/src/Modal/GenericModal/GenericModal.mjs +2 -2
- package/dist/esm/src/Modal/GenericModal/subcomponents/ModalFooter/ModalFooter.mjs +3 -6
- package/dist/esm/src/Select/Select.mjs +14 -15
- package/dist/esm/src/Select/Select.module.scss.mjs +0 -1
- package/dist/esm/src/SingleSelect/SingleSelect.mjs +12 -19
- package/dist/esm/src/SingleSelect/subcomponents/SelectToggle/SelectToggle.mjs +3 -5
- package/dist/esm/src/SingleSelect/subcomponents/SelectToggle/SelectToggle.module.scss.mjs +0 -1
- package/dist/esm/src/TimeField/TimeField.mjs +2 -3
- package/dist/styles.css +0 -94
- package/dist/types/Button/Button.d.ts +0 -5
- package/dist/types/Calendar/CalendarRange/CalendarRange.d.ts +2 -1
- package/dist/types/Calendar/CalendarSingle/CalendarSingle.d.ts +2 -1
- package/dist/types/Calendar/types.d.ts +1 -0
- package/dist/types/GuidanceBlock/GuidanceBlock.d.ts +1 -26
- package/dist/types/Input/Input/Input.d.ts +1 -6
- package/dist/types/Modal/GenericModal/subcomponents/ModalFooter/ModalFooter.d.ts +1 -5
- package/dist/types/Select/Select.d.ts +3 -13
- package/dist/types/SingleSelect/SingleSelect.d.ts +2 -24
- package/dist/types/SingleSelect/subcomponents/SelectToggle/SelectToggle.d.ts +2 -12
- package/dist/types/TextArea/TextArea.d.ts +1 -6
- package/dist/types/TimeField/TimeField.d.ts +1 -1
- package/package.json +1 -2
- package/src/Button/Button.tsx +1 -8
- package/src/Button/_docs/Button--api-specification.mdx +0 -1
- package/src/Calendar/CalendarRange/CalendarRange.tsx +4 -1
- package/src/Calendar/CalendarSingle/CalendarSingle.tsx +4 -1
- package/src/Calendar/types.ts +18 -0
- package/src/GuidanceBlock/GuidanceBlock.module.css +0 -8
- package/src/GuidanceBlock/GuidanceBlock.spec.tsx +1 -26
- package/src/GuidanceBlock/GuidanceBlock.tsx +2 -112
- package/src/GuidanceBlock/_docs/GuidanceBlock.stories.tsx +0 -90
- package/src/Input/Input/Input.module.scss +0 -31
- package/src/Input/Input/Input.tsx +1 -6
- package/src/LinkButton/LinkButton.tsx +1 -3
- package/src/LinkButton/_docs/LinkButton--api-specification.mdx +0 -1
- package/src/Modal/ConfirmationModal/ConfirmationModal.tsx +7 -6
- package/src/Modal/ContextModal/ContextModal.tsx +0 -1
- package/src/Modal/GenericModal/GenericModal.tsx +3 -4
- package/src/Modal/GenericModal/subcomponents/ModalFooter/ModalFooter.tsx +2 -8
- package/src/Select/Select.module.scss +0 -16
- package/src/Select/Select.tsx +16 -19
- package/src/SingleSelect/SingleSelect.tsx +1 -14
- package/src/SingleSelect/_docs/SingleSelect.stories.tsx +5 -2
- package/src/SingleSelect/subcomponents/SelectToggle/SelectToggle.module.scss +0 -8
- package/src/SingleSelect/subcomponents/SelectToggle/SelectToggle.tsx +2 -9
- package/src/TextArea/TextArea.tsx +1 -6
- package/src/TimeField/TimeField.tsx +2 -9
- package/dist/cjs/src/Modal/util/console.cjs +0 -16
- package/dist/esm/src/Modal/util/console.mjs +0 -13
- package/dist/types/Modal/util/console.d.ts +0 -5
- package/dist/types/utils/useResizeObserver.d.ts +0 -22
- package/src/Modal/util/console.ts +0 -13
- package/src/utils/useResizeObserver.ts +0 -73
|
@@ -24,12 +24,7 @@ export type SelectProps = {
|
|
|
24
24
|
* @default false
|
|
25
25
|
*/
|
|
26
26
|
fullWidth?: boolean;
|
|
27
|
-
|
|
28
|
-
* @deprecated Use of placeholder text goes against our a11y standards.
|
|
29
|
-
* Use the `labelText` prop to provide a concise name, and the `description` prop for any help text.
|
|
30
|
-
*/
|
|
31
|
-
placeholder?: string;
|
|
32
|
-
} & ReactSelectProps<any, boolean>;
|
|
27
|
+
} & Omit<ReactSelectProps<any, boolean>, 'placeholder'>;
|
|
33
28
|
/**
|
|
34
29
|
* {@link https://cultureamp.atlassian.net/wiki/spaces/DesignSystem/pages/3081896474/Select Guidance} |
|
|
35
30
|
* {@link https://cultureamp.design/?path=/docs/components-select--docs Storybook}
|
|
@@ -57,13 +52,8 @@ export declare const Select: React.ForwardRefExoticComponent<{
|
|
|
57
52
|
* @default false
|
|
58
53
|
*/
|
|
59
54
|
fullWidth?: boolean;
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
* Use the `labelText` prop to provide a concise name, and the `description` prop for any help text.
|
|
63
|
-
*/
|
|
64
|
-
placeholder?: string;
|
|
65
|
-
} & Omit<import("react-select/dist/declarations/src/Select").PublicBaseSelectProps<any, boolean, import("react-select").GroupBase<any>>, "onChange" | "value" | "inputValue" | "onInputChange" | "menuIsOpen" | "onMenuOpen" | "onMenuClose"> & Partial<import("react-select/dist/declarations/src/Select").PublicBaseSelectProps<any, boolean, import("react-select").GroupBase<any>>> & import("react-select/dist/declarations/src/useStateManager").StateManagerAdditionalProps<any> & React.RefAttributes<any>>;
|
|
66
|
-
interface AsyncProps extends ReactAsyncSelectProps<any, boolean, any>, ReactSelectProps<any, boolean, any> {
|
|
55
|
+
} & Omit<ReactSelectProps<any, boolean>, "placeholder"> & React.RefAttributes<any>>;
|
|
56
|
+
interface AsyncProps extends Omit<ReactAsyncSelectProps<any, boolean, any>, 'placeholder'>, Omit<ReactSelectProps<any, boolean, any>, 'placeholder'> {
|
|
67
57
|
}
|
|
68
58
|
export declare const AsyncSelect: React.ForwardRefExoticComponent<AsyncProps & React.RefAttributes<any>>;
|
|
69
59
|
export {};
|
|
@@ -46,22 +46,17 @@ export type SingleSelectProps<Option extends SingleSelectOption = SingleSelectOp
|
|
|
46
46
|
* Creates a portal for the Popover to the matching element id
|
|
47
47
|
*/
|
|
48
48
|
portalContainerId?: string;
|
|
49
|
-
/**
|
|
50
|
-
* @deprecated Use of placeholder text goes against our a11y standards.
|
|
51
|
-
* Use the `labelText` prop to provide a concise name, and the `description` prop for any help text.
|
|
52
|
-
*/
|
|
53
|
-
placeholder?: string;
|
|
54
49
|
/**
|
|
55
50
|
* Handler that is called when the selection changes.
|
|
56
51
|
*/
|
|
57
52
|
onSelectionChange?: (key: Key) => void;
|
|
58
|
-
} & OverrideClassName<Omit<AriaSelectProps<Option>, OmittedAriaSelectProps>>;
|
|
53
|
+
} & OverrideClassName<Omit<AriaSelectProps<Option>, OmittedAriaSelectProps | 'placeholder'>>;
|
|
59
54
|
/**
|
|
60
55
|
* {@link https://cultureamp.atlassian.net/wiki/spaces/DesignSystem/pages/3081896474/Select Guidance} |
|
|
61
56
|
* {@link https://cultureamp.design/?path=/docs/components-select--docs Storybook}
|
|
62
57
|
*/
|
|
63
58
|
export declare const SingleSelect: {
|
|
64
|
-
<Option extends SingleSelectOption = SingleSelectOption>({ label, items, id: propsId, trigger, children, status, validationMessage, isReversed, isRequired, isFullWidth, classNameOverride, selectedKey, description,
|
|
59
|
+
<Option extends SingleSelectOption = SingleSelectOption>({ label, items, id: propsId, trigger, children, status, validationMessage, isReversed, isRequired, isFullWidth, classNameOverride, selectedKey, description, isDisabled, onSelectionChange, portalContainerId, ...restProps }: SingleSelectProps<Option>): JSX.Element;
|
|
65
60
|
displayName: string;
|
|
66
61
|
Section: {
|
|
67
62
|
<Option extends SingleSelectOption = SingleSelectOption>({ section, }: import("./subcomponents").ListBoxSectionProps<Option>): JSX.Element;
|
|
@@ -79,22 +74,5 @@ export declare const SingleSelect: {
|
|
|
79
74
|
<Option extends SingleSelectOption = SingleSelectOption>({ item, }: import("./subcomponents").ListItemProps<Option>): JSX.Element;
|
|
80
75
|
displayName: string;
|
|
81
76
|
};
|
|
82
|
-
TriggerButton: React.ForwardRefExoticComponent<{
|
|
83
|
-
label: React.ReactNode;
|
|
84
|
-
labelProps: import("@react-types/shared").DOMAttributes<import("@react-types/shared").FocusableElement>;
|
|
85
|
-
value: React.ReactNode;
|
|
86
|
-
valueProps: import("@react-types/shared").DOMAttributes<import("@react-types/shared").FocusableElement>;
|
|
87
|
-
isOpen?: boolean;
|
|
88
|
-
placeholder?: string;
|
|
89
|
-
status?: "error" | "caution";
|
|
90
|
-
isDisabled?: boolean;
|
|
91
|
-
isReversed?: boolean;
|
|
92
|
-
} & Omit<React.HTMLAttributes<HTMLButtonElement>, "className"> & {
|
|
93
|
-
classNameOverride?: string;
|
|
94
|
-
} & React.RefAttributes<HTMLButtonElement>>;
|
|
95
|
-
ListBox: {
|
|
96
|
-
<Option extends SingleSelectOption>({ children, menuProps, classNameOverride, ...restProps }: import("./subcomponents").SingleListBoxProps<Option>): JSX.Element;
|
|
97
|
-
displayName: string;
|
|
98
|
-
};
|
|
99
77
|
};
|
|
100
78
|
export {};
|
|
@@ -8,17 +8,12 @@ export type SelectToggleProps = {
|
|
|
8
8
|
/** Props for the element representing the selected value. */
|
|
9
9
|
valueProps: DOMAttributes<FocusableElement>;
|
|
10
10
|
isOpen?: boolean;
|
|
11
|
-
/**
|
|
12
|
-
* @deprecated Use of placeholder text goes against our a11y standards.
|
|
13
|
-
* Use the `labelText` prop to provide a concise name, and the `description` prop for any help text.
|
|
14
|
-
*/
|
|
15
|
-
placeholder?: string;
|
|
16
11
|
/** Updates the styling of the validation. */
|
|
17
12
|
status?: 'error' | 'caution';
|
|
18
13
|
isDisabled?: boolean;
|
|
19
14
|
/** Use the `reversed` styles. */
|
|
20
15
|
isReversed?: boolean;
|
|
21
|
-
} & OverrideClassName<HTMLAttributes<HTMLButtonElement>>;
|
|
16
|
+
} & OverrideClassName<Omit<HTMLAttributes<HTMLButtonElement>, 'placeholder'>>;
|
|
22
17
|
export declare const SelectToggle: React.ForwardRefExoticComponent<{
|
|
23
18
|
label: React.ReactNode;
|
|
24
19
|
labelProps: DOMAttributes<FocusableElement>;
|
|
@@ -26,16 +21,11 @@ export declare const SelectToggle: React.ForwardRefExoticComponent<{
|
|
|
26
21
|
/** Props for the element representing the selected value. */
|
|
27
22
|
valueProps: DOMAttributes<FocusableElement>;
|
|
28
23
|
isOpen?: boolean;
|
|
29
|
-
/**
|
|
30
|
-
* @deprecated Use of placeholder text goes against our a11y standards.
|
|
31
|
-
* Use the `labelText` prop to provide a concise name, and the `description` prop for any help text.
|
|
32
|
-
*/
|
|
33
|
-
placeholder?: string;
|
|
34
24
|
/** Updates the styling of the validation. */
|
|
35
25
|
status?: "error" | "caution";
|
|
36
26
|
isDisabled?: boolean;
|
|
37
27
|
/** Use the `reversed` styles. */
|
|
38
28
|
isReversed?: boolean;
|
|
39
|
-
} & Omit<React.HTMLAttributes<HTMLButtonElement>, "className"> & {
|
|
29
|
+
} & Omit<Omit<React.HTMLAttributes<HTMLButtonElement>, "placeholder">, "className"> & {
|
|
40
30
|
classNameOverride?: string;
|
|
41
31
|
} & React.RefAttributes<HTMLButtonElement>>;
|
|
@@ -9,12 +9,7 @@ export type TextAreaProps = {
|
|
|
9
9
|
*/
|
|
10
10
|
autogrow?: boolean;
|
|
11
11
|
reversed?: boolean;
|
|
12
|
-
|
|
13
|
-
* @deprecated Use of placeholder text goes against our a11y standards.
|
|
14
|
-
* Use the `labelText` prop to provide a concise name, and the `description` prop for any help text.
|
|
15
|
-
*/
|
|
16
|
-
placeholder?: string;
|
|
17
|
-
} & OverrideClassName<TextareaHTMLAttributes<HTMLTextAreaElement>>;
|
|
12
|
+
} & OverrideClassName<Omit<TextareaHTMLAttributes<HTMLTextAreaElement>, 'placeholder'>>;
|
|
18
13
|
export declare const TextArea: {
|
|
19
14
|
({ textAreaRef: propsTextAreaRef, status, autogrow, reversed, rows, defaultValue, value, disabled, onChange: propsOnChange, ...restProps }: TextAreaProps): JSX.Element;
|
|
20
15
|
displayName: string;
|
|
@@ -2,7 +2,7 @@ import React from 'react';
|
|
|
2
2
|
import { type TimeFieldStateOptions } from '@react-stately/datepicker';
|
|
3
3
|
import { type OverrideClassName } from "../types/OverrideClassName";
|
|
4
4
|
import { type StatusType, type ValueType } from './types';
|
|
5
|
-
type OmittedTimeFieldProps = 'errorMessage' | '
|
|
5
|
+
type OmittedTimeFieldProps = 'errorMessage' | 'value' | 'onChange' | 'label' | 'hideTimeZone';
|
|
6
6
|
export type TimeFieldProps = {
|
|
7
7
|
id?: string;
|
|
8
8
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kaizen/components",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "Kaizen component library",
|
|
5
5
|
"author": "Geoffrey Chong <geoff.chong@cultureamp.com>",
|
|
6
6
|
"homepage": "https://cultureamp.design",
|
|
@@ -122,7 +122,6 @@
|
|
|
122
122
|
"react-popper": "^2.3.0",
|
|
123
123
|
"react-select": "^5.10.2",
|
|
124
124
|
"react-textfit": "^1.1.1",
|
|
125
|
-
"resize-observer-polyfill": "^1.5.1",
|
|
126
125
|
"use-debounce": "^10.0.6",
|
|
127
126
|
"uuid": "^13.0.0"
|
|
128
127
|
},
|
package/src/Button/Button.tsx
CHANGED
|
@@ -22,11 +22,6 @@ export type ButtonUIProps = {
|
|
|
22
22
|
iconPosition?: 'start' | 'end'
|
|
23
23
|
/** Controls if the button inherits width from its parent. @default "false" */
|
|
24
24
|
isFullWidth?: boolean
|
|
25
|
-
/**
|
|
26
|
-
* Controls the reversed style of Button
|
|
27
|
-
* @deprecated Use the ReversedColors Provider instead. This is here to support gradual migration to the ReversedColors Provider and will take precedence if a value is provided. {@link https://cultureamp.design/?path=/docs/actions-button-button-next-api-specification--docs#variants}
|
|
28
|
-
*/
|
|
29
|
-
isReversed?: boolean
|
|
30
25
|
}
|
|
31
26
|
|
|
32
27
|
export type ButtonProps = ButtonUIProps &
|
|
@@ -51,13 +46,11 @@ export const Button = forwardRef(
|
|
|
51
46
|
isPending,
|
|
52
47
|
hasHiddenPendingLabel: propsHasHiddenPendingLabel = false,
|
|
53
48
|
pendingLabel,
|
|
54
|
-
isReversed,
|
|
55
49
|
...restProps
|
|
56
50
|
}: ButtonProps,
|
|
57
51
|
ref: React.ForwardedRef<HTMLButtonElement>,
|
|
58
52
|
) => {
|
|
59
|
-
const
|
|
60
|
-
const isReversedVariant = isReversed ?? shouldUseReverse
|
|
53
|
+
const isReversedVariant = useReversedColors()
|
|
61
54
|
const pendingProps: PendingButtonProps = isPending
|
|
62
55
|
? {
|
|
63
56
|
isPending,
|
|
@@ -4,6 +4,7 @@ import { DayPicker, type PropsBase, type PropsRange } from 'react-day-picker'
|
|
|
4
4
|
import { Icon } from '~components/Icon'
|
|
5
5
|
import { type OverrideClassName } from '~components/types/OverrideClassName'
|
|
6
6
|
import { baseCalendarClassNames } from '../baseCalendarClassNames'
|
|
7
|
+
import { type DeprecatedReactDayPickerProps } from '../types'
|
|
7
8
|
import { isInvalidDate } from '../utils'
|
|
8
9
|
import styles from './CalendarRange.module.scss'
|
|
9
10
|
|
|
@@ -13,7 +14,9 @@ export type CalendarRangeProps = {
|
|
|
13
14
|
id?: string
|
|
14
15
|
onMount?: (calendarElement: CalendarRangeElement) => void
|
|
15
16
|
hasDivider?: boolean
|
|
16
|
-
} & OverrideClassName<
|
|
17
|
+
} & OverrideClassName<
|
|
18
|
+
Omit<PropsRange & Omit<PropsBase, 'mode'>, 'mode' | DeprecatedReactDayPickerProps>
|
|
19
|
+
>
|
|
17
20
|
|
|
18
21
|
export const CalendarRange = ({
|
|
19
22
|
id,
|
|
@@ -4,6 +4,7 @@ import { DayPicker, type PropsBase, type PropsSingle } from 'react-day-picker'
|
|
|
4
4
|
import { Icon } from '~components/Icon'
|
|
5
5
|
import { type OverrideClassName } from '~components/types/OverrideClassName'
|
|
6
6
|
import { baseCalendarClassNames } from '../baseCalendarClassNames'
|
|
7
|
+
import { type DeprecatedReactDayPickerProps } from '../types'
|
|
7
8
|
import { isInvalidDate, isValidWeekStartsOn } from '../utils'
|
|
8
9
|
import styles from './CalendarSingle.module.scss'
|
|
9
10
|
|
|
@@ -14,7 +15,9 @@ export type CalendarSingleProps = {
|
|
|
14
15
|
onMount?: (calendarElement: CalendarSingleElement) => void
|
|
15
16
|
/** Exposes the react-day-picker component prop. Please be aware, consumers using this will have to guarentee functions as expected */
|
|
16
17
|
components?: PropsBase['components']
|
|
17
|
-
} & OverrideClassName<
|
|
18
|
+
} & OverrideClassName<
|
|
19
|
+
Omit<PropsSingle & Omit<PropsBase, 'mode'>, 'mode' | DeprecatedReactDayPickerProps>
|
|
20
|
+
>
|
|
18
21
|
|
|
19
22
|
export const CalendarSingle = ({
|
|
20
23
|
id,
|
package/src/Calendar/types.ts
CHANGED
|
@@ -5,6 +5,24 @@ export type { DateInterval, DateRange }
|
|
|
5
5
|
|
|
6
6
|
export type DisabledDays = DayPickerProps['disabled']
|
|
7
7
|
|
|
8
|
+
export type DeprecatedReactDayPickerProps =
|
|
9
|
+
| 'fromDate'
|
|
10
|
+
| 'fromMonth'
|
|
11
|
+
| 'fromYear'
|
|
12
|
+
| 'toDate'
|
|
13
|
+
| 'toMonth'
|
|
14
|
+
| 'toYear'
|
|
15
|
+
| 'initialFocus'
|
|
16
|
+
| 'onDayKeyUp'
|
|
17
|
+
| 'onDayKeyPress'
|
|
18
|
+
| 'onDayPointerEnter'
|
|
19
|
+
| 'onDayPointerLeave'
|
|
20
|
+
| 'onDayTouchCancel'
|
|
21
|
+
| 'onDayTouchEnd'
|
|
22
|
+
| 'onDayTouchMove'
|
|
23
|
+
| 'onDayTouchStart'
|
|
24
|
+
| 'onWeekNumberClick'
|
|
25
|
+
|
|
8
26
|
export type DisabledDayMatchers = {
|
|
9
27
|
/**
|
|
10
28
|
* Accepts an array of singluar dates and disables them.
|
|
@@ -18,9 +18,6 @@
|
|
|
18
18
|
box-shadow: var(--shadow-small-box-shadow);
|
|
19
19
|
position: relative;
|
|
20
20
|
top: -1px;
|
|
21
|
-
transition:
|
|
22
|
-
opacity var(--animation-duration-slow) ease,
|
|
23
|
-
margin-top var(--animation-duration-fast) var(--animation-duration-slow) ease;
|
|
24
21
|
color: var(--color-purple-800);
|
|
25
22
|
|
|
26
23
|
@media (width >= 1024px) {
|
|
@@ -130,11 +127,6 @@
|
|
|
130
127
|
}
|
|
131
128
|
}
|
|
132
129
|
|
|
133
|
-
.hidden {
|
|
134
|
-
opacity: 0;
|
|
135
|
-
margin-bottom: 0;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
130
|
.headingWrapper {
|
|
139
131
|
margin-bottom: var(--spacing-24);
|
|
140
132
|
}
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
|
-
import { cleanup, render
|
|
3
|
-
import userEvent from '@testing-library/user-event'
|
|
2
|
+
import { cleanup, render } from '@testing-library/react'
|
|
4
3
|
import { vi } from 'vitest'
|
|
5
4
|
import { Informative } from '~components/Illustration'
|
|
6
5
|
import { GuidanceBlock } from './GuidanceBlock'
|
|
7
|
-
const user = userEvent.setup()
|
|
8
6
|
|
|
9
7
|
window.matchMedia = vi.fn().mockImplementation(() => ({
|
|
10
8
|
matches: false,
|
|
@@ -17,29 +15,6 @@ window.matchMedia = vi.fn().mockImplementation(() => ({
|
|
|
17
15
|
describe('GuidanceBlock', () => {
|
|
18
16
|
afterEach(cleanup)
|
|
19
17
|
|
|
20
|
-
it('calls the action function when action button is clicked', async () => {
|
|
21
|
-
const onAction = vi.fn()
|
|
22
|
-
const { container } = render(
|
|
23
|
-
<GuidanceBlock
|
|
24
|
-
illustration={<Informative alt="" />}
|
|
25
|
-
text={{
|
|
26
|
-
title: 'This is the call to action title',
|
|
27
|
-
description:
|
|
28
|
-
'Mussum Ipsum, cacilds vidis litro abertis. Suco de cevadiss, é um leite divinis.',
|
|
29
|
-
}}
|
|
30
|
-
actions={{
|
|
31
|
-
primary: { label: 'Action!', onClick: onAction },
|
|
32
|
-
}}
|
|
33
|
-
/>,
|
|
34
|
-
)
|
|
35
|
-
const actionButton = container.querySelector('button')
|
|
36
|
-
if (actionButton) await user.click(actionButton)
|
|
37
|
-
|
|
38
|
-
await waitFor(() => {
|
|
39
|
-
expect(onAction).toHaveBeenCalledTimes(1)
|
|
40
|
-
})
|
|
41
|
-
})
|
|
42
|
-
|
|
43
18
|
it('has a default title tag of h3', () => {
|
|
44
19
|
const { getByRole } = render(
|
|
45
20
|
<GuidanceBlock
|
|
@@ -1,36 +1,18 @@
|
|
|
1
|
-
import React
|
|
1
|
+
import React from 'react'
|
|
2
2
|
import classNames from 'classnames'
|
|
3
|
-
import { Button as V1Button, type ButtonProps as V1ButtonProps } from '~components/ButtonV1'
|
|
4
3
|
import { Heading, type HeadingProps } from '~components/Heading'
|
|
5
|
-
import { Icon } from '~components/Icon'
|
|
6
4
|
import { type SceneProps, type SpotProps } from '~components/Illustration'
|
|
7
5
|
import { Text } from '~components/Text'
|
|
8
|
-
import { Tooltip, type TooltipProps } from '~components/TooltipV1'
|
|
9
6
|
import { useMediaQueries } from '~components/utils/useMediaQueries'
|
|
10
7
|
import { type VariantType } from './types'
|
|
11
8
|
import styles from './GuidanceBlock.module.css'
|
|
12
9
|
|
|
13
|
-
export type ActionProps = V1ButtonProps & {
|
|
14
|
-
'tooltip'?: TooltipProps
|
|
15
|
-
'aria-label'?: string
|
|
16
|
-
'aria-labelledby'?: string
|
|
17
|
-
'aria-describedby'?: string
|
|
18
|
-
}
|
|
19
|
-
|
|
20
10
|
type LayoutType = 'default' | 'inline' | 'stacked'
|
|
21
11
|
|
|
22
12
|
type IllustrationType = 'spot' | 'scene'
|
|
23
13
|
|
|
24
14
|
type TextAlignment = 'center' | 'left'
|
|
25
15
|
|
|
26
|
-
type GuidanceBlockActions = {
|
|
27
|
-
primary: ActionProps
|
|
28
|
-
secondary?: ActionProps
|
|
29
|
-
dismiss?: {
|
|
30
|
-
onClick: () => void
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
16
|
type BaseGuidanceBlockProps = {
|
|
35
17
|
layout?: LayoutType
|
|
36
18
|
illustration: React.ReactElement<SpotProps | SceneProps>
|
|
@@ -39,15 +21,9 @@ type BaseGuidanceBlockProps = {
|
|
|
39
21
|
*/
|
|
40
22
|
illustrationType?: IllustrationType
|
|
41
23
|
smallScreenTextAlignment?: TextAlignment
|
|
42
|
-
/** @deprecated use the `actionsSlot` prop with Button/next instead */
|
|
43
|
-
actions?: GuidanceBlockActions
|
|
44
24
|
/** A slot for the primary and secondary action. It is recommended to use the {@link https://cultureamp.design/?path=/docs/components-button-button-next-api-specification--docs | Button} or {@link https://cultureamp.design/?path=/docs/components-linkbutton-usage-guidelines--docs | LinkButton} wrapped in fragment. */
|
|
45
25
|
actionsSlot?: React.ReactNode
|
|
46
|
-
/** @deprecated this is no longer a used feature and is only the deprecated `actions` prop, ie: {secondary: { label: "Dismiss action" }}` */
|
|
47
|
-
secondaryDismiss?: boolean
|
|
48
26
|
variant?: VariantType
|
|
49
|
-
/** @deprecated use the `actionsSlot` and pass the icon into the JSX elements */
|
|
50
|
-
withActionButtonArrow?: boolean
|
|
51
27
|
noMaxWidth?: boolean
|
|
52
28
|
}
|
|
53
29
|
|
|
@@ -65,19 +41,6 @@ type GuidanceBlockPropsWithContent = {
|
|
|
65
41
|
|
|
66
42
|
export type GuidanceBlockProps = GuidanceBlockWithText | GuidanceBlockPropsWithContent
|
|
67
43
|
|
|
68
|
-
export type GuidanceBlockState = {
|
|
69
|
-
hidden: boolean
|
|
70
|
-
removed: boolean
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
type WithTooltipProps = {
|
|
74
|
-
children: React.ReactNode
|
|
75
|
-
tooltipProps?: TooltipProps
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
const WithTooltip = ({ tooltipProps, children }: WithTooltipProps): JSX.Element =>
|
|
79
|
-
tooltipProps ? <Tooltip {...tooltipProps}>{children}</Tooltip> : <>{children}</>
|
|
80
|
-
|
|
81
44
|
/**
|
|
82
45
|
* {@link https://cultureamp.atlassian.net/wiki/spaces/DesignSystem/pages/3082093807/Guidance+Block Guidance} |
|
|
83
46
|
* {@link https://cultureamp.design/?path=/docs/components-guidanceblock--docs Storybook}
|
|
@@ -85,63 +48,26 @@ const WithTooltip = ({ tooltipProps, children }: WithTooltipProps): JSX.Element
|
|
|
85
48
|
export const GuidanceBlock = ({
|
|
86
49
|
layout = 'default',
|
|
87
50
|
variant = 'default',
|
|
88
|
-
withActionButtonArrow = true,
|
|
89
51
|
noMaxWidth = false,
|
|
90
52
|
illustrationType = 'spot',
|
|
91
53
|
smallScreenTextAlignment = 'center',
|
|
92
|
-
actions,
|
|
93
54
|
illustration,
|
|
94
|
-
secondaryDismiss,
|
|
95
55
|
actionsSlot,
|
|
96
56
|
...restProps
|
|
97
57
|
}: GuidanceBlockProps): JSX.Element => {
|
|
98
|
-
const [hidden, setHidden] = useState<boolean>(false)
|
|
99
|
-
const [removed, setRemoved] = useState<boolean>(false)
|
|
100
58
|
const { queries } = useMediaQueries()
|
|
101
59
|
|
|
102
|
-
const containerRef = React.createRef<HTMLDivElement>()
|
|
103
|
-
|
|
104
|
-
const handleDismissBanner = (): void => {
|
|
105
|
-
setHidden(true)
|
|
106
|
-
actions?.dismiss?.onClick()
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
const onTransitionEnd = (e: React.TransitionEvent<HTMLDivElement>): void => {
|
|
110
|
-
// Be careful: this assumes the final CSS property to be animated is "margin-top".
|
|
111
|
-
if (hidden && e.propertyName === 'margin-top') {
|
|
112
|
-
setRemoved(true)
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
const marginTop = (): string => {
|
|
117
|
-
if (hidden && containerRef.current) {
|
|
118
|
-
return -containerRef.current.clientHeight + 'px'
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
return '0'
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
if (removed) {
|
|
125
|
-
return <></>
|
|
126
|
-
}
|
|
127
|
-
|
|
128
60
|
return (
|
|
129
61
|
<div
|
|
130
62
|
className={classNames(
|
|
131
63
|
styles.banner,
|
|
132
64
|
variant && styles[variant],
|
|
133
65
|
layout && styles[layout],
|
|
134
|
-
hidden && styles.hidden,
|
|
135
66
|
queries.isSmall && styles.centerContent,
|
|
136
67
|
noMaxWidth && styles.noMaxWidth,
|
|
137
68
|
illustrationType === 'scene' && styles.hasSceneIllustration,
|
|
138
69
|
smallScreenTextAlignment === 'left' && styles.smallScreenTextAlignment,
|
|
139
70
|
)}
|
|
140
|
-
style={{
|
|
141
|
-
marginTop: marginTop(),
|
|
142
|
-
}}
|
|
143
|
-
ref={containerRef}
|
|
144
|
-
onTransitionEnd={onTransitionEnd}
|
|
145
71
|
>
|
|
146
72
|
<div className={styles.illustrationWrapper}>
|
|
147
73
|
<div className={styles.illustration}>
|
|
@@ -166,43 +92,7 @@ export const GuidanceBlock = ({
|
|
|
166
92
|
</>
|
|
167
93
|
)}
|
|
168
94
|
</div>
|
|
169
|
-
{
|
|
170
|
-
<div className={styles.buttonContainer}>
|
|
171
|
-
{actions?.primary && (
|
|
172
|
-
<>
|
|
173
|
-
<WithTooltip tooltipProps={actions.primary.tooltip}>
|
|
174
|
-
<V1Button
|
|
175
|
-
icon={
|
|
176
|
-
withActionButtonArrow ? (
|
|
177
|
-
<Icon name="arrow_forward" isPresentational shouldMirrorInRTL />
|
|
178
|
-
) : undefined
|
|
179
|
-
}
|
|
180
|
-
iconPosition="end"
|
|
181
|
-
{...actions.primary}
|
|
182
|
-
fullWidth={queries.isSmall}
|
|
183
|
-
/>
|
|
184
|
-
</WithTooltip>
|
|
185
|
-
{actions?.secondary && (
|
|
186
|
-
<WithTooltip tooltipProps={actions.secondary.tooltip}>
|
|
187
|
-
<div className={styles.secondaryAction}>
|
|
188
|
-
<V1Button
|
|
189
|
-
secondary
|
|
190
|
-
{...actions.secondary}
|
|
191
|
-
onClick={
|
|
192
|
-
secondaryDismiss
|
|
193
|
-
? (): void => handleDismissBanner()
|
|
194
|
-
: actions?.secondary?.onClick
|
|
195
|
-
}
|
|
196
|
-
fullWidth={queries.isSmall}
|
|
197
|
-
/>
|
|
198
|
-
</div>
|
|
199
|
-
</WithTooltip>
|
|
200
|
-
)}
|
|
201
|
-
</>
|
|
202
|
-
)}
|
|
203
|
-
{!actions && actionsSlot && actionsSlot}
|
|
204
|
-
</div>
|
|
205
|
-
) : null}
|
|
95
|
+
{actionsSlot && <div className={styles.buttonContainer}>{actionsSlot}</div>}
|
|
206
96
|
</div>
|
|
207
97
|
</div>
|
|
208
98
|
)
|
|
@@ -39,9 +39,6 @@ const meta = {
|
|
|
39
39
|
illustration: <Informative alt="" />,
|
|
40
40
|
},
|
|
41
41
|
argTypes: {
|
|
42
|
-
actions: {
|
|
43
|
-
control: false,
|
|
44
|
-
},
|
|
45
42
|
illustrationType: {
|
|
46
43
|
description:
|
|
47
44
|
'Sets the how the width and aspect ratio will respond to the Illustration passed in.',
|
|
@@ -138,42 +135,6 @@ export const Playground: Story = {
|
|
|
138
135
|
},
|
|
139
136
|
}
|
|
140
137
|
|
|
141
|
-
export const Actions: Story = {
|
|
142
|
-
args: {
|
|
143
|
-
content: <ContentComponent />,
|
|
144
|
-
actions: {
|
|
145
|
-
primary: {
|
|
146
|
-
label: 'Label',
|
|
147
|
-
onClick: () => alert('tada: 🎉'),
|
|
148
|
-
},
|
|
149
|
-
secondary: {
|
|
150
|
-
label: 'Label',
|
|
151
|
-
href: '#',
|
|
152
|
-
},
|
|
153
|
-
},
|
|
154
|
-
},
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
export const Tooltip: Story = {
|
|
158
|
-
args: {
|
|
159
|
-
content: <ContentComponent />,
|
|
160
|
-
actions: {
|
|
161
|
-
primary: {
|
|
162
|
-
label: 'Label',
|
|
163
|
-
onClick: () => alert('tada: 🎉'),
|
|
164
|
-
tooltip: {
|
|
165
|
-
text: 'Opens in a new tab',
|
|
166
|
-
mood: 'cautionary',
|
|
167
|
-
},
|
|
168
|
-
},
|
|
169
|
-
secondary: {
|
|
170
|
-
label: 'Label',
|
|
171
|
-
href: '#',
|
|
172
|
-
},
|
|
173
|
-
},
|
|
174
|
-
},
|
|
175
|
-
}
|
|
176
|
-
|
|
177
138
|
export const CustomContent: Story = {
|
|
178
139
|
args: {
|
|
179
140
|
content: <ContentComponent />,
|
|
@@ -214,57 +175,6 @@ export const Variants: Story = {
|
|
|
214
175
|
},
|
|
215
176
|
}
|
|
216
177
|
|
|
217
|
-
export const ActionsVsActionsSlot: Story = {
|
|
218
|
-
args: {
|
|
219
|
-
layout: 'default',
|
|
220
|
-
illustration: <Informative alt="" />,
|
|
221
|
-
content: <ContentComponent />,
|
|
222
|
-
actions: {
|
|
223
|
-
dismiss: {
|
|
224
|
-
onClick: () => {
|
|
225
|
-
alert('Dismissed')
|
|
226
|
-
},
|
|
227
|
-
},
|
|
228
|
-
primary: {
|
|
229
|
-
label: 'Label',
|
|
230
|
-
onClick: () => alert('tada: 🎉'),
|
|
231
|
-
},
|
|
232
|
-
secondary: {
|
|
233
|
-
label: 'Label',
|
|
234
|
-
href: '#',
|
|
235
|
-
},
|
|
236
|
-
},
|
|
237
|
-
secondaryDismiss: true,
|
|
238
|
-
},
|
|
239
|
-
render: (args) => (
|
|
240
|
-
<div className="flex flex-col gap-16">
|
|
241
|
-
<GuidanceBlock
|
|
242
|
-
layout="default"
|
|
243
|
-
illustration={<Informative alt="" />}
|
|
244
|
-
content={<ContentComponent />}
|
|
245
|
-
actions={args.actions}
|
|
246
|
-
secondaryDismiss
|
|
247
|
-
/>
|
|
248
|
-
<GuidanceBlock
|
|
249
|
-
layout="default"
|
|
250
|
-
illustration={<Informative alt="" />}
|
|
251
|
-
content={<ContentComponent />}
|
|
252
|
-
secondaryDismiss={true}
|
|
253
|
-
actionsSlot={
|
|
254
|
-
<>
|
|
255
|
-
<Button size="large" onPress={() => alert('tada: 🎉')} slot="primary">
|
|
256
|
-
Label
|
|
257
|
-
</Button>
|
|
258
|
-
<Button variant="tertiary" size="large" onPress={() => alert('tada: 🎉')}>
|
|
259
|
-
Label
|
|
260
|
-
</Button>
|
|
261
|
-
</>
|
|
262
|
-
}
|
|
263
|
-
/>
|
|
264
|
-
</div>
|
|
265
|
-
),
|
|
266
|
-
}
|
|
267
|
-
|
|
268
178
|
export const ActionsSlot: Story = {
|
|
269
179
|
args: {
|
|
270
180
|
layout: 'default',
|