@kaizen/components 1.68.3 → 1.68.5
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/Filter/FilterBar/context/FilterBarContext.cjs +13 -3
- package/dist/cjs/Filter/FilterBar/context/reducer/filterBarStateReducer.cjs +1 -1
- package/dist/cjs/Filter/FilterBar/context/reducer/setupFilterBarState.cjs +4 -0
- package/dist/cjs/Filter/FilterBar/context/utils/updateDependentFilters.cjs +1 -1
- package/dist/cjs/Filter/FilterBar/subcomponents/ClearAllButton/ClearAllButton.cjs +7 -2
- package/dist/cjs/Filter/FilterBar/subcomponents/ClearAllButton/ClearAllButton.module.scss.cjs +2 -1
- package/dist/cjs/Filter/FilterDateRangePicker/subcomponents/FilterDateRangePickerField/FilterDateRangePickerField.cjs +3 -0
- package/dist/cjs/Tile/subcomponents/GenericTile/GenericTile.cjs +23 -2
- package/dist/esm/Filter/FilterBar/context/FilterBarContext.mjs +13 -3
- package/dist/esm/Filter/FilterBar/context/reducer/filterBarStateReducer.mjs +1 -1
- package/dist/esm/Filter/FilterBar/context/reducer/setupFilterBarState.mjs +4 -0
- package/dist/esm/Filter/FilterBar/context/utils/updateDependentFilters.mjs +1 -1
- package/dist/esm/Filter/FilterBar/subcomponents/ClearAllButton/ClearAllButton.mjs +6 -2
- package/dist/esm/Filter/FilterBar/subcomponents/ClearAllButton/ClearAllButton.module.scss.mjs +2 -1
- package/dist/esm/Filter/FilterDateRangePicker/subcomponents/FilterDateRangePickerField/FilterDateRangePickerField.mjs +3 -0
- package/dist/esm/Tile/subcomponents/GenericTile/GenericTile.mjs +24 -3
- package/dist/styles.css +77 -73
- package/dist/types/Filter/FilterBar/context/FilterBarContext.d.ts +1 -0
- package/dist/types/Filter/FilterBar/context/types.d.ts +1 -0
- package/locales/ar.json +8 -0
- package/locales/bg.json +8 -0
- package/locales/cs.json +8 -0
- package/locales/cy.json +8 -0
- package/locales/da.json +8 -0
- package/locales/de.json +8 -0
- package/locales/el.json +8 -0
- package/locales/en-GB.json +8 -0
- package/locales/es-419.json +8 -0
- package/locales/es.json +8 -0
- package/locales/et.json +8 -0
- package/locales/fi.json +8 -0
- package/locales/fr-CA.json +8 -0
- package/locales/fr.json +8 -0
- package/locales/he.json +8 -0
- package/locales/hi.json +8 -0
- package/locales/ht.json +8 -0
- package/locales/hu.json +8 -0
- package/locales/id.json +8 -0
- package/locales/it.json +8 -0
- package/locales/ja.json +8 -0
- package/locales/km-KH.json +8 -0
- package/locales/ko.json +8 -0
- package/locales/lt.json +8 -0
- package/locales/lv.json +8 -0
- package/locales/mi.json +8 -0
- package/locales/ms.json +8 -0
- package/locales/nb.json +8 -0
- package/locales/nl.json +8 -0
- package/locales/pl.json +8 -0
- package/locales/pt-BR.json +8 -0
- package/locales/pt.json +8 -0
- package/locales/ro.json +8 -0
- package/locales/ru.json +8 -0
- package/locales/si-LK.json +8 -0
- package/locales/sk.json +8 -0
- package/locales/sr.json +8 -0
- package/locales/sv.json +8 -0
- package/locales/th.json +8 -0
- package/locales/tl.json +8 -0
- package/locales/tr.json +8 -0
- package/locales/uk.json +8 -0
- package/locales/vi.json +8 -0
- package/locales/zh-TW.json +8 -0
- package/locales/zh.json +8 -0
- package/package.json +1 -1
- package/src/Filter/FilterBar/FilterBar.spec.tsx +0 -64
- package/src/Filter/FilterBar/_docs/FilterBar.spec.stories.tsx +249 -0
- package/src/Filter/FilterBar/_docs/FilterBar.stickersheet.stories.tsx +1 -1
- package/src/Filter/FilterBar/_docs/FilterBar.stories.tsx +1 -1
- package/src/Filter/FilterBar/context/FilterBarContext.tsx +17 -5
- package/src/Filter/FilterBar/context/reducer/filterBarStateReducer.spec.ts +3 -0
- package/src/Filter/FilterBar/context/reducer/filterBarStateReducer.ts +1 -1
- package/src/Filter/FilterBar/context/reducer/setupFilterBarState.spec.tsx +40 -0
- package/src/Filter/FilterBar/context/reducer/setupFilterBarState.ts +5 -0
- package/src/Filter/FilterBar/context/reducer/updateSingleFilter.spec.ts +2 -0
- package/src/Filter/FilterBar/context/reducer/updateValues.spec.ts +5 -0
- package/src/Filter/FilterBar/context/types.ts +1 -0
- package/src/Filter/FilterBar/context/utils/checkShouldUpdateValues.spec.ts +1 -0
- package/src/Filter/FilterBar/context/utils/getInactiveFilters.spec.ts +2 -0
- package/src/Filter/FilterBar/context/utils/getIsUsableWhenArgs.spec.ts +1 -0
- package/src/Filter/FilterBar/context/utils/updateDependentFilters.spec.ts +8 -0
- package/src/Filter/FilterBar/context/utils/updateDependentFilters.ts +1 -1
- package/src/Filter/FilterBar/subcomponents/ClearAllButton/ClearAllButton.module.scss +4 -0
- package/src/Filter/FilterBar/subcomponents/ClearAllButton/ClearAllButton.tsx +5 -2
- package/src/Filter/FilterDateRangePicker/subcomponents/FilterDateRangePickerField/FilterDateRangePickerField.tsx +4 -0
- package/src/Tile/TileGrid/_docs/TileGrid.stories.tsx +41 -8
- package/src/Tile/subcomponents/GenericTile/GenericTile.spec.stories.tsx +58 -0
- package/src/Tile/subcomponents/GenericTile/GenericTile.tsx +24 -1
|
@@ -38,6 +38,7 @@ describe("updateDependentFilters()", () => {
|
|
|
38
38
|
values: { flavour: "jasmine" },
|
|
39
39
|
dependentFilterIds: new Set(),
|
|
40
40
|
hasUpdatedValues: false,
|
|
41
|
+
hasRemovableFilter: false,
|
|
41
42
|
} satisfies FilterBarState<Values>
|
|
42
43
|
|
|
43
44
|
const newState = updateDependentFilters<Values>(state)
|
|
@@ -53,6 +54,7 @@ describe("updateDependentFilters()", () => {
|
|
|
53
54
|
values: { flavour: "jasmine" },
|
|
54
55
|
dependentFilterIds: new Set<keyof Values>(["sugarLevel"]),
|
|
55
56
|
hasUpdatedValues: false,
|
|
57
|
+
hasRemovableFilter: false,
|
|
56
58
|
} satisfies FilterBarState<Values>
|
|
57
59
|
|
|
58
60
|
const newState = updateDependentFilters<Values>(state)
|
|
@@ -77,6 +79,7 @@ describe("updateDependentFilters()", () => {
|
|
|
77
79
|
values: { flavour: "jasmine" },
|
|
78
80
|
dependentFilterIds: new Set<keyof Values>(["sugarLevel"]),
|
|
79
81
|
hasUpdatedValues: false,
|
|
82
|
+
hasRemovableFilter: false,
|
|
80
83
|
} satisfies FilterBarState<Values>
|
|
81
84
|
|
|
82
85
|
updateDependentFilters<Values>(state)
|
|
@@ -98,6 +101,7 @@ describe("updateDependentFilters()", () => {
|
|
|
98
101
|
values: { flavour: "jasmine" },
|
|
99
102
|
dependentFilterIds: new Set<keyof Values>(["sugarLevel"]),
|
|
100
103
|
hasUpdatedValues: false,
|
|
104
|
+
hasRemovableFilter: false,
|
|
101
105
|
} satisfies FilterBarState<Values>
|
|
102
106
|
|
|
103
107
|
const newState = updateDependentFilters<Values>(state)
|
|
@@ -117,6 +121,7 @@ describe("updateDependentFilters()", () => {
|
|
|
117
121
|
values: { flavour: "jasmine" },
|
|
118
122
|
dependentFilterIds: new Set<keyof Values>(["sugarLevel"]),
|
|
119
123
|
hasUpdatedValues: false,
|
|
124
|
+
hasRemovableFilter: false,
|
|
120
125
|
} satisfies FilterBarState<Values>
|
|
121
126
|
|
|
122
127
|
const newState = updateDependentFilters<Values>(state)
|
|
@@ -139,6 +144,7 @@ describe("updateDependentFilters()", () => {
|
|
|
139
144
|
values: { flavour: "jasmine", sugarLevel: 50 },
|
|
140
145
|
dependentFilterIds: new Set<keyof Values>(["sugarLevel"]),
|
|
141
146
|
hasUpdatedValues: false,
|
|
147
|
+
hasRemovableFilter: false,
|
|
142
148
|
} satisfies FilterBarState<Values>
|
|
143
149
|
|
|
144
150
|
const newState = updateDependentFilters<Values>(state)
|
|
@@ -161,6 +167,7 @@ describe("updateDependentFilters()", () => {
|
|
|
161
167
|
values: { flavour: "jasmine" },
|
|
162
168
|
dependentFilterIds: new Set<keyof Values>(["sugarLevel"]),
|
|
163
169
|
hasUpdatedValues: false,
|
|
170
|
+
hasRemovableFilter: false,
|
|
164
171
|
} satisfies FilterBarState<Values>
|
|
165
172
|
|
|
166
173
|
const newState = updateDependentFilters<Values>(state)
|
|
@@ -176,6 +183,7 @@ describe("updateDependentFilters()", () => {
|
|
|
176
183
|
values: { sugarLevel: 50 },
|
|
177
184
|
dependentFilterIds: new Set<keyof Values>(["sugarLevel"]),
|
|
178
185
|
hasUpdatedValues: false,
|
|
186
|
+
hasRemovableFilter: false,
|
|
179
187
|
} satisfies FilterBarState<Values>
|
|
180
188
|
|
|
181
189
|
const newState = updateDependentFilters<Values>(state)
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React from "react"
|
|
2
2
|
import { useIntl } from "@cultureamp/i18n-react-intl"
|
|
3
|
+
import classnames from "classnames"
|
|
3
4
|
import { Button } from "~components/__actions__/v2"
|
|
4
5
|
import { useFilterBarContext } from "../../context/FilterBarContext"
|
|
5
6
|
import styles from "./ClearAllButton.module.scss"
|
|
@@ -19,13 +20,15 @@ export const ClearAllButton = (): JSX.Element => {
|
|
|
19
20
|
description: "Button aria-label to clear all values within the filter bar",
|
|
20
21
|
})
|
|
21
22
|
|
|
22
|
-
const { clearAllFilters } = useFilterBarContext()
|
|
23
|
+
const { clearAllFilters, isClearable } = useFilterBarContext()
|
|
23
24
|
|
|
24
25
|
return (
|
|
25
26
|
<Button
|
|
26
27
|
label={clearButtonLabel}
|
|
27
28
|
aria-label={clearButtonAriaLabel}
|
|
28
|
-
classNameOverride={styles.clearAllButton
|
|
29
|
+
classNameOverride={classnames(styles.clearAllButton, {
|
|
30
|
+
[styles.hidden]: !isClearable,
|
|
31
|
+
})}
|
|
29
32
|
secondary
|
|
30
33
|
onClick={clearAllFilters}
|
|
31
34
|
/>
|
|
@@ -259,6 +259,10 @@ export const FilterDateRangePickerField = ({
|
|
|
259
259
|
return
|
|
260
260
|
}
|
|
261
261
|
|
|
262
|
+
if (state.inputStartValue === "" && state.inputEndValue === "") {
|
|
263
|
+
return
|
|
264
|
+
}
|
|
265
|
+
|
|
262
266
|
const newStartDate = validateStartDate(
|
|
263
267
|
selectedRange?.from,
|
|
264
268
|
state.inputStartValue
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React from "react"
|
|
2
2
|
import { Meta, StoryObj } from "@storybook/react"
|
|
3
|
+
import { expect, waitFor, within } from "@storybook/test"
|
|
3
4
|
import { InformationTile } from "~components/Tile"
|
|
4
5
|
import { TileGrid } from "../index"
|
|
5
6
|
|
|
@@ -10,21 +11,21 @@ const meta = {
|
|
|
10
11
|
children: (
|
|
11
12
|
<>
|
|
12
13
|
<InformationTile
|
|
13
|
-
title="Title"
|
|
14
|
+
title="Title A"
|
|
14
15
|
metadata="Side A"
|
|
15
|
-
information="Side
|
|
16
|
+
information="Side A - Back"
|
|
16
17
|
footer={<>Footer</>}
|
|
17
18
|
/>
|
|
18
19
|
<InformationTile
|
|
19
|
-
title="Title"
|
|
20
|
-
metadata="Side
|
|
21
|
-
information="Side B"
|
|
20
|
+
title="Title B"
|
|
21
|
+
metadata="Side B"
|
|
22
|
+
information="Side B - Back"
|
|
22
23
|
footer={<>Footer</>}
|
|
23
24
|
/>
|
|
24
25
|
<InformationTile
|
|
25
|
-
title="Title"
|
|
26
|
-
metadata="Side
|
|
27
|
-
information="Side
|
|
26
|
+
title="Title C"
|
|
27
|
+
metadata="Side C"
|
|
28
|
+
information="Side C - Back"
|
|
28
29
|
footer={<>Footer</>}
|
|
29
30
|
/>
|
|
30
31
|
</>
|
|
@@ -45,3 +46,35 @@ export const Playground: Story = {
|
|
|
45
46
|
},
|
|
46
47
|
},
|
|
47
48
|
}
|
|
49
|
+
|
|
50
|
+
// Test for multiple tiles, flipping one doesn't flip others
|
|
51
|
+
export const FlipOneNotOthers: Story = {
|
|
52
|
+
play: async ({ canvasElement, step }) => {
|
|
53
|
+
const canvas = within(canvasElement)
|
|
54
|
+
|
|
55
|
+
await step("initial render complete", async () => {
|
|
56
|
+
await waitFor(() => {
|
|
57
|
+
canvas.getByRole("button", {
|
|
58
|
+
name: "View more information: Title A",
|
|
59
|
+
})
|
|
60
|
+
})
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
await step("Can focus to button", async () => {
|
|
64
|
+
await waitFor(() => {
|
|
65
|
+
const buttonWithInfoLabel = canvas.getByRole("button", {
|
|
66
|
+
name: "View more information: Title A",
|
|
67
|
+
})
|
|
68
|
+
buttonWithInfoLabel.click()
|
|
69
|
+
})
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
await step("Check other tiles", async () => {
|
|
73
|
+
await waitFor(() => {
|
|
74
|
+
expect(canvas.getByText("Side A - Back")).toBeInTheDocument()
|
|
75
|
+
expect(canvas.getByText("Title B")).toBeInTheDocument()
|
|
76
|
+
expect(canvas.getByText("Title C")).toBeInTheDocument()
|
|
77
|
+
})
|
|
78
|
+
})
|
|
79
|
+
},
|
|
80
|
+
}
|
|
@@ -87,3 +87,61 @@ export const InfoButtonLabel: Story = {
|
|
|
87
87
|
})
|
|
88
88
|
},
|
|
89
89
|
}
|
|
90
|
+
|
|
91
|
+
export const DoesNotStealFocusOnInitialRender: Story = {
|
|
92
|
+
play: async ({ canvasElement, step }) => {
|
|
93
|
+
const canvas = within(canvasElement)
|
|
94
|
+
|
|
95
|
+
await step("initial render complete", async () => {
|
|
96
|
+
await waitFor(() => {
|
|
97
|
+
canvas.getByRole("button", {
|
|
98
|
+
name: "View more information: Title",
|
|
99
|
+
})
|
|
100
|
+
})
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
await step("Can focus to button", async () => {
|
|
104
|
+
await waitFor(() => {
|
|
105
|
+
const buttonWithInfoLabel = canvas.getByRole("button", {
|
|
106
|
+
name: "View more information: Title",
|
|
107
|
+
})
|
|
108
|
+
expect(buttonWithInfoLabel).not.toHaveFocus()
|
|
109
|
+
})
|
|
110
|
+
})
|
|
111
|
+
},
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export const FocusOnFlip: Story = {
|
|
115
|
+
play: async ({ canvasElement, step }) => {
|
|
116
|
+
const canvas = within(canvasElement)
|
|
117
|
+
const buttonWithInfoLabel = await canvas.findByRole("button", {
|
|
118
|
+
name: "View more information: Title",
|
|
119
|
+
})
|
|
120
|
+
|
|
121
|
+
await step("initial render complete", async () => {
|
|
122
|
+
expect(buttonWithInfoLabel).toBeInTheDocument()
|
|
123
|
+
})
|
|
124
|
+
|
|
125
|
+
await step("Can focus to button", async () => {
|
|
126
|
+
await waitFor(() => {
|
|
127
|
+
buttonWithInfoLabel.click()
|
|
128
|
+
})
|
|
129
|
+
})
|
|
130
|
+
|
|
131
|
+
const returnButton = canvas.getByRole("button", {
|
|
132
|
+
name: "Hide information: Title",
|
|
133
|
+
})
|
|
134
|
+
|
|
135
|
+
await step("Can click on info button again", async () => {
|
|
136
|
+
await waitFor(() => {
|
|
137
|
+
returnButton.click()
|
|
138
|
+
})
|
|
139
|
+
})
|
|
140
|
+
|
|
141
|
+
await step("Info button has focus again", async () => {
|
|
142
|
+
await waitFor(() => {
|
|
143
|
+
expect(buttonWithInfoLabel).toHaveFocus()
|
|
144
|
+
})
|
|
145
|
+
})
|
|
146
|
+
},
|
|
147
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { HTMLAttributes, useState } from "react"
|
|
1
|
+
import React, { HTMLAttributes, useState, useRef, useEffect } from "react"
|
|
2
2
|
import { useIntl } from "@cultureamp/i18n-react-intl"
|
|
3
3
|
import classnames from "classnames"
|
|
4
4
|
import { AllowedHeadingTags, Heading } from "~components/Heading"
|
|
@@ -57,7 +57,28 @@ export const GenericTile = ({
|
|
|
57
57
|
...restProps
|
|
58
58
|
}: GenericTileProps): JSX.Element => {
|
|
59
59
|
const [isFlipped, setIsFlipped] = useState<boolean>(false)
|
|
60
|
+
const [isDocumentReady, setIsDocumentReady] = useState<boolean>(false)
|
|
61
|
+
|
|
60
62
|
const { formatMessage } = useIntl()
|
|
63
|
+
const infoButtonRef = useRef<HTMLButtonElement>(null)
|
|
64
|
+
const infoButtonReturnRef = useRef<HTMLButtonElement>(null)
|
|
65
|
+
|
|
66
|
+
useEffect(() => {
|
|
67
|
+
setIsDocumentReady(true)
|
|
68
|
+
}, [])
|
|
69
|
+
|
|
70
|
+
useEffect(() => {
|
|
71
|
+
if (!isDocumentReady) {
|
|
72
|
+
setIsDocumentReady(true)
|
|
73
|
+
return
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (isFlipped) {
|
|
77
|
+
infoButtonReturnRef.current!.focus()
|
|
78
|
+
} else {
|
|
79
|
+
infoButtonRef.current!.focus()
|
|
80
|
+
}
|
|
81
|
+
}, [isFlipped])
|
|
61
82
|
|
|
62
83
|
const translatedInfoLabel = formatMessage({
|
|
63
84
|
id: "kzGenericTile.infoButtonLabel",
|
|
@@ -97,6 +118,7 @@ export const GenericTile = ({
|
|
|
97
118
|
onClick={(): void => setIsFlipped(true)}
|
|
98
119
|
disabled={isFlipped}
|
|
99
120
|
aria-hidden={isFlipped}
|
|
121
|
+
ref={infoButtonRef}
|
|
100
122
|
/>
|
|
101
123
|
</div>
|
|
102
124
|
)}
|
|
@@ -162,6 +184,7 @@ export const GenericTile = ({
|
|
|
162
184
|
onClick={(): void => setIsFlipped(false)}
|
|
163
185
|
disabled={!isFlipped}
|
|
164
186
|
aria-hidden={!isFlipped}
|
|
187
|
+
ref={infoButtonReturnRef}
|
|
165
188
|
/>
|
|
166
189
|
</div>
|
|
167
190
|
<div className={styles.information}>
|