@kaizen/components 1.42.5 → 1.42.6
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/index.css +4 -4
- package/dist/esm/index.css +4 -4
- package/dist/styles.css +1 -1
- package/package.json +1 -1
- package/src/Tag/_docs/Tag.mdx +8 -1
- package/src/Tag/_docs/Tag.stories.tsx +1 -1
- package/src/TitleBlockZen/TitleBlockZen.module.scss +19 -0
- package/src/TitleBlockZen/_docs/TitleBlockZen.stories.tsx +36 -73
- package/src/TitleBlockZen/subcomponents/NavigationTabs.module.scss +33 -2
- package/src/__future__/Tag/Tag/_docs/Tag-migration-guide.mdx +172 -0
- package/src/__future__/Tag/Tag/_docs/Tag-migration-guide.stories.tsx +328 -0
- package/src/__future__/Tag/Tag/_docs/Tag.mdx +10 -1
package/package.json
CHANGED
package/src/Tag/_docs/Tag.mdx
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Canvas, Controls , Meta } from "@storybook/blocks"
|
|
2
|
+
import { InlineNotification } from "~components/Notification"
|
|
2
3
|
import { ResourceLinks, KAIOInstallation } from "~storybook/components"
|
|
3
4
|
import * as TagStories from "./Tag.stories"
|
|
4
5
|
|
|
@@ -13,6 +14,12 @@ import * as TagStories from "./Tag.stories"
|
|
|
13
14
|
className="!mb-8"
|
|
14
15
|
/>
|
|
15
16
|
|
|
17
|
+
|
|
18
|
+
<InlineNotification type="cautionary" persistent>
|
|
19
|
+
{`This version of the Tag will soon be deprecated and will be removed in the next major release.
|
|
20
|
+
Import Tag from "@kaizen/components/future" for the latest version and veiw our migration guide in the Future folder` }
|
|
21
|
+
</InlineNotification>
|
|
22
|
+
|
|
16
23
|
<KAIOInstallation exportNames="Tag" />
|
|
17
24
|
|
|
18
25
|
## Overview
|
|
@@ -59,7 +66,7 @@ An Avatar can be added in two ways, either by importing the `<Avatar />` compone
|
|
|
59
66
|
<Canvas of={TagStories.ProfileWithAvatarProps} />
|
|
60
67
|
|
|
61
68
|
### Dismissable
|
|
62
|
-
<Canvas of={TagStories.
|
|
69
|
+
<Canvas of={TagStories.Dismissible} />
|
|
63
70
|
|
|
64
71
|
### TruncateWidth
|
|
65
72
|
A pixel width which sets a limit for when the text starts to truncate.
|
|
@@ -550,6 +550,25 @@ $tab-container-height-medium-and-small-collapsed: 0;
|
|
|
550
550
|
text-decoration: underline;
|
|
551
551
|
}
|
|
552
552
|
|
|
553
|
+
&:focus {
|
|
554
|
+
outline: none;
|
|
555
|
+
|
|
556
|
+
&::after {
|
|
557
|
+
$focus-ring-offset: calc(
|
|
558
|
+
(-2 * #{$border-focus-ring-border-width}) - #{$border-focus-ring-border-width}
|
|
559
|
+
);
|
|
560
|
+
|
|
561
|
+
content: "";
|
|
562
|
+
position: absolute;
|
|
563
|
+
background: transparent;
|
|
564
|
+
border-color: $color-blue-200;
|
|
565
|
+
border-radius: 50%;
|
|
566
|
+
border-width: $border-focus-ring-border-width;
|
|
567
|
+
border-style: $border-focus-ring-border-style;
|
|
568
|
+
inset: $focus-ring-offset;
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
|
|
553
572
|
@media only screen and (max-width: $breadcrumb-breakpoint-width) {
|
|
554
573
|
position: relative;
|
|
555
574
|
|
|
@@ -2,6 +2,7 @@ import React from "react"
|
|
|
2
2
|
import { Meta, StoryObj } from "@storybook/react"
|
|
3
3
|
import { assetUrl } from "@kaizen/hosted-assets"
|
|
4
4
|
import { AddIcon, StarOnIcon } from "~components/Icon"
|
|
5
|
+
import { StickerSheet } from "~storybook/components/StickerSheet"
|
|
5
6
|
import { NavigationTab, TitleBlockZen } from "../index"
|
|
6
7
|
|
|
7
8
|
const SECONDARY_ACTIONS = [
|
|
@@ -97,76 +98,38 @@ export const Playground: Story = {
|
|
|
97
98
|
},
|
|
98
99
|
}
|
|
99
100
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
// export const WithDefaultTag: Story = {
|
|
137
|
-
// args: {
|
|
138
|
-
// surveyStatus: { text: "Due July 8, 2030", status: "default" },
|
|
139
|
-
// },
|
|
140
|
-
// }
|
|
141
|
-
|
|
142
|
-
// export const WithMenuButton: Story = {
|
|
143
|
-
// args: {
|
|
144
|
-
// primaryAction: {
|
|
145
|
-
// label: "Menu button",
|
|
146
|
-
// menuItems: [
|
|
147
|
-
// {
|
|
148
|
-
// action: "#",
|
|
149
|
-
// label: "Item 1",
|
|
150
|
-
// },
|
|
151
|
-
// {
|
|
152
|
-
// action: () => alert("Item 2 clicked"),
|
|
153
|
-
// label: "Item 2",
|
|
154
|
-
// },
|
|
155
|
-
// {
|
|
156
|
-
// action: "#",
|
|
157
|
-
// label: "Item 3",
|
|
158
|
-
// },
|
|
159
|
-
// ],
|
|
160
|
-
// },
|
|
161
|
-
// },
|
|
162
|
-
// }
|
|
163
|
-
|
|
164
|
-
// export const Subtitle: Story = {
|
|
165
|
-
// args: {
|
|
166
|
-
// subtitle: (
|
|
167
|
-
// <Text variant="body">
|
|
168
|
-
// This is a <a href="/">link</a>
|
|
169
|
-
// </Text>
|
|
170
|
-
// ),
|
|
171
|
-
// },
|
|
172
|
-
// }
|
|
101
|
+
export const StickerSheetDefault: Story = {
|
|
102
|
+
parameters: {
|
|
103
|
+
docs: {
|
|
104
|
+
canvas: {
|
|
105
|
+
sourceState: "shown",
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
pseudo: {
|
|
109
|
+
hover: [
|
|
110
|
+
'#tab-hover-example [class^="TitleBlockZen-TitleBlockZen-module__navigationTabsList"] li:nth-child(2) a',
|
|
111
|
+
'#Breadcrumbs-hover-example [class^="TitleBlockZen-TitleBlockZen-module__breadcrumb"]',
|
|
112
|
+
],
|
|
113
|
+
focus: [
|
|
114
|
+
'#tab-focus-example [class^="TitleBlockZen-TitleBlockZen-module__navigationTabsList"] li:nth-child(2) a',
|
|
115
|
+
'#Breadcrumbs-focus-example [class^="TitleBlockZen-TitleBlockZen-module__breadcrumb"]',
|
|
116
|
+
],
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
render: args => (
|
|
120
|
+
<StickerSheet>
|
|
121
|
+
<StickerSheet.Row rowTitle="Tab hover">
|
|
122
|
+
<TitleBlockZen {...args} id="tab-hover-example" />
|
|
123
|
+
</StickerSheet.Row>
|
|
124
|
+
<StickerSheet.Row rowTitle="Tab focus">
|
|
125
|
+
<TitleBlockZen {...args} id="tab-focus-example" />
|
|
126
|
+
</StickerSheet.Row>
|
|
127
|
+
<StickerSheet.Row rowTitle="Breadcrumbs hover">
|
|
128
|
+
<TitleBlockZen {...args} id="Breadcrumbs-hover-example" />
|
|
129
|
+
</StickerSheet.Row>
|
|
130
|
+
<StickerSheet.Row rowTitle="Breadcrumbs focus">
|
|
131
|
+
<TitleBlockZen {...args} id="Breadcrumbs-focus-example" />
|
|
132
|
+
</StickerSheet.Row>
|
|
133
|
+
</StickerSheet>
|
|
134
|
+
),
|
|
135
|
+
}
|
|
@@ -59,13 +59,16 @@
|
|
|
59
59
|
margin: 0;
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
|
|
62
|
+
$active-tab-marker-height: 5px;
|
|
63
|
+
|
|
64
|
+
&.active,
|
|
65
|
+
&:focus {
|
|
63
66
|
color: $color-white;
|
|
64
67
|
|
|
65
68
|
&::before {
|
|
66
69
|
content: "";
|
|
67
70
|
display: block;
|
|
68
|
-
height:
|
|
71
|
+
height: $active-tab-marker-height;
|
|
69
72
|
position: absolute;
|
|
70
73
|
top: 0;
|
|
71
74
|
left: 0;
|
|
@@ -82,6 +85,34 @@
|
|
|
82
85
|
}
|
|
83
86
|
}
|
|
84
87
|
}
|
|
88
|
+
|
|
89
|
+
&:focus {
|
|
90
|
+
outline: none;
|
|
91
|
+
|
|
92
|
+
&::before {
|
|
93
|
+
background-color: $color-blue-200;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
&::after {
|
|
97
|
+
$focus-ring-offset: calc((-1 * #{$border-focus-ring-border-width}));
|
|
98
|
+
|
|
99
|
+
content: "";
|
|
100
|
+
position: absolute;
|
|
101
|
+
background: transparent;
|
|
102
|
+
border-color: $color-blue-200;
|
|
103
|
+
border-radius: 0 0 $border-focus-ring-border-radius
|
|
104
|
+
$border-focus-ring-border-radius;
|
|
105
|
+
border-width: $border-focus-ring-border-width;
|
|
106
|
+
border-style: $border-focus-ring-border-style;
|
|
107
|
+
inset: 0 $focus-ring-offset $active-tab-marker-height $focus-ring-offset;
|
|
108
|
+
|
|
109
|
+
@include title-block-medium-and-small {
|
|
110
|
+
border-radius: $border-focus-ring-border-radius
|
|
111
|
+
$border-focus-ring-border-radius 0 0;
|
|
112
|
+
inset: $active-tab-marker-height $focus-ring-offset 0 $focus-ring-offset;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
85
116
|
}
|
|
86
117
|
|
|
87
118
|
.linkAnchor.lightBackground {
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import { Canvas, Meta } from "@storybook/blocks"
|
|
2
|
+
import * as LegacyTagStories from "../../../../Tag/_docs/Tag.stories"
|
|
3
|
+
import * as TagMigrationStories from "./Tag-migration-guide.stories"
|
|
4
|
+
|
|
5
|
+
<Meta of={TagMigrationStories} />
|
|
6
|
+
|
|
7
|
+
# Future Tag migration guide
|
|
8
|
+
|
|
9
|
+
A brief guide on how and why to migrate from Kaizen's current `Tag` to the `future` release.
|
|
10
|
+
|
|
11
|
+
## Why the change?
|
|
12
|
+
|
|
13
|
+
Tag was rebuilt to allow for greater composability as the number of cases for a distinct Tags could not be solved through the use of `variant` without impacting the developer experience for existing users. The flexibility of `Tag` content as `children` also addresses several accessibility issues that the original could not solve intuitively.
|
|
14
|
+
|
|
15
|
+
## Component and API changes at a glance
|
|
16
|
+
|
|
17
|
+
There were a number key changes between current and future `Tag` to achieve the flexibility we were aiming to provide, we've listed these below but also go into further detail in the [migration examples](/docs/components-tag-future-migration-guide--migrationguide#migration-examples).
|
|
18
|
+
|
|
19
|
+
- `variant` prop has been removed
|
|
20
|
+
- This has been superseded by a combination of the `color` and `icon` prop
|
|
21
|
+
- `inline` prop and the default `margin` on all Tags has been removed.
|
|
22
|
+
- This can be directly controlled through `classNameOverride` or a `flex-gap` on the container.
|
|
23
|
+
- `size` has been removed and all tags are the same size.
|
|
24
|
+
- `truncationWidth` has been removed as child content.
|
|
25
|
+
- `dismissible` prop has been removed.
|
|
26
|
+
- A `DismissibleTag` component is now available in its place.
|
|
27
|
+
- `Avatar` and all child content must now be composed by the consumer.
|
|
28
|
+
- This offers a greater degree of flexibility to ensure that the right accessible context can be provided to the end user.
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
## Migration examples
|
|
32
|
+
|
|
33
|
+
The following are example of migrating from previously available props to the composable solution.
|
|
34
|
+
|
|
35
|
+
### Status
|
|
36
|
+
|
|
37
|
+
With the `variant` prop there are four values associated with statuses: `statusLive`, `statusDraft`, `statusClosed`, `statusAction`.
|
|
38
|
+
|
|
39
|
+
For the most part these can all be replaced with the use of the `color` prop, with exception to the `live` status.
|
|
40
|
+
|
|
41
|
+
#### Before
|
|
42
|
+
|
|
43
|
+
<Canvas of={LegacyTagStories.Status} />
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
#### After
|
|
47
|
+
|
|
48
|
+
<Canvas of={TagMigrationStories.StatusMigration} sourceState="shown"/>
|
|
49
|
+
|
|
50
|
+
While the `LiveIcon` is exported from `@kaizen/components` the current `Tag` uses an animated implementation, which is not exported directly from Kaizen. As an interim solution, you can use the following Story's code snippet to create a `LiveIconComponent`. This can then be passed into the future `Tag` as `Children`.
|
|
51
|
+
|
|
52
|
+
<Canvas of={TagMigrationStories.LiveIconComponentStory} sourceState="hidden"/>
|
|
53
|
+
|
|
54
|
+
### Validation
|
|
55
|
+
|
|
56
|
+
Following the same pattern as status, `validationPositive`, `validationInformative`, `validationNegative`, `validationCautionary` can all be replace with the `color` and `icon` prop.
|
|
57
|
+
|
|
58
|
+
Note: because the icons convey meaning, they should have an accessible label that provides context to the `Tag`. A contextual `aria-label` and role of `img` addresses one of the [accessibility issues](https://github.com/cultureamp/kaizen-discourse/issues/102) with the current `Tag`.
|
|
59
|
+
|
|
60
|
+
#### Before
|
|
61
|
+
|
|
62
|
+
<Canvas of={LegacyTagStories.Validation} />
|
|
63
|
+
|
|
64
|
+
#### After
|
|
65
|
+
|
|
66
|
+
<Canvas of={TagMigrationStories.ValidationMigration} sourceState="shown"/>
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
Note: When using the `icon` prop, the icon's color will be determined by the `color` value that has been set. This is to ensure that an accessible contrast ratio is achieved.
|
|
70
|
+
|
|
71
|
+
Any Icons added as a child of future `Tag` will need to set their own colors and ensure the right contrast ratio is achieved.
|
|
72
|
+
|
|
73
|
+
### Sentiment
|
|
74
|
+
|
|
75
|
+
While migration of any `Tag` using, `sentimentPositive`, `sentimentNeutral` or `sentimentNegative` is relatively straight forward using the `color` prop, `sentimentNone` does not align to any Kaizen's [semantic colors](https://cultureamp.atlassian.net/wiki/spaces/DesignSystem/pages/3064857902/Color).
|
|
76
|
+
|
|
77
|
+
#### Before
|
|
78
|
+
|
|
79
|
+
<Canvas of={LegacyTagStories.Sentiments} />
|
|
80
|
+
|
|
81
|
+
#### After
|
|
82
|
+
|
|
83
|
+
<Canvas of={TagMigrationStories.SentimentsMigration} sourceState="shown"/>
|
|
84
|
+
|
|
85
|
+
If required, you could use `classNameOverride` to implement the same UI. It is important that any override of the default styles still meets minimum contrast ratios to ensure the component is accessible.
|
|
86
|
+
|
|
87
|
+
<Canvas of={TagMigrationStories.SentimentNone} />
|
|
88
|
+
|
|
89
|
+
This is also a good time to stop and check if this change is necessary. If there is an opportunity remove older styles that are no longer available, this can help to reduce inconsistencies across the platform. As always, check in with your designer to see if any new option can be used in its place.
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
### Dismissible
|
|
93
|
+
|
|
94
|
+
The `dismissible` prop is no longer available in the future `Tag` component. We have split the dismissible functionality into the [RemovableTag](/docs/components-tag-future-removabletag--docs).
|
|
95
|
+
|
|
96
|
+
This increases the hit box for the dismiss button and makes the `ariaLabel` in the `removeButtonProps` a required prop. This offers a more accessible experience for user and address one of the standing [accessibility issues](https://github.com/cultureamp/kaizen-discourse/issues/101) with the legacy `Tag`.
|
|
97
|
+
|
|
98
|
+
#### Before
|
|
99
|
+
|
|
100
|
+
<Canvas of={LegacyTagStories.Dismissible} />
|
|
101
|
+
|
|
102
|
+
#### After
|
|
103
|
+
|
|
104
|
+
<Canvas of={TagMigrationStories.DismissibleMigration} sourceState="shown"/>
|
|
105
|
+
|
|
106
|
+
Remember that when handling dismiss (or any destructive action), a user's focus should not be lost on the page.
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
### Avatars
|
|
110
|
+
|
|
111
|
+
Avatars are no longer provided directly to the `Tag` as a prop. Instead they will be passed in as children.
|
|
112
|
+
|
|
113
|
+
#### Before
|
|
114
|
+
|
|
115
|
+
<Canvas of={LegacyTagStories.ProfileWithAvatarProps} />
|
|
116
|
+
|
|
117
|
+
#### After
|
|
118
|
+
|
|
119
|
+
<Canvas of={TagMigrationStories.AvatarMigration} sourceState="shown"/>
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
Note: The use of `ps-4` (or `padding-inline-start`) in the `classNameOverride` is to override the default spacing at start of the `Tag`. This will ensure the Avatar can contour the border radius of the `Tag`.
|
|
123
|
+
|
|
124
|
+
#### Dismissible Avatars
|
|
125
|
+
|
|
126
|
+
Following a similar pattern to the above, you can use the `RemovableTag` with an `Avatar` and plain text as its `children` to achieve a dismissible version.
|
|
127
|
+
|
|
128
|
+
<Canvas of={TagMigrationStories.AvatarRemovableMigration} />
|
|
129
|
+
|
|
130
|
+
### Inline
|
|
131
|
+
|
|
132
|
+
Originally the `Tag` was built with the assumption that it would always required spacing at the end. This necessitated the need for the `inline` prop to remove the margin from end when it was not required.
|
|
133
|
+
|
|
134
|
+
In future `Tag` this has been removed so consumers can now control spacing with CSS properties like `gap` or `margin-inline`.
|
|
135
|
+
|
|
136
|
+
#### Before
|
|
137
|
+
|
|
138
|
+
<Canvas of={LegacyTagStories.Inline} />
|
|
139
|
+
|
|
140
|
+
#### After
|
|
141
|
+
|
|
142
|
+
<Canvas of={TagMigrationStories.InlineMigration} sourceState="shown"/>
|
|
143
|
+
|
|
144
|
+
To simplify this example we have avoided DOM elements such as `ul` and `li`. In production, lists should be used if you are rendering a group of `Tag`s.
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
### truncationWidth
|
|
148
|
+
|
|
149
|
+
While the current Tag controls truncation via the `truncationWidth` prop, which set a `max-width` of inner text via inline styles, we have chosen not to adopt this in the future `Tag` as it presents a risk of violating accessibility standards. While truncation can still be achieved in future `Tag` via Tailwind or DOM manipulation, it is important to call out out this as a accessibility concern.
|
|
150
|
+
|
|
151
|
+
#### Before
|
|
152
|
+
|
|
153
|
+
<Canvas of={LegacyTagStories.Truncate} />
|
|
154
|
+
|
|
155
|
+
Where truncation often fails WCAG's success criteria is in [1.4.4](https://www.w3.org/WAI/WCAG21/Techniques/failures/F69) or [1.3.1](https://www.w3.org/WAI/WCAG22/Understanding/info-and-relationships.html). The crux of the issue is that removing content with an ellipsis may lead to a loss of context for visual users. While `aria` labels can support those that use assistive technologies, they are not enough to resolve this issue for sighted users.
|
|
156
|
+
|
|
157
|
+
The recommendation from WCAG is that any truncated content comes with the functionality to visually revealing its full content. This can be accessible either via focus or some form of activation - like an `onClick` to reveal. Based on this, our recommendation is to avoid truncation unless necessary.
|
|
158
|
+
|
|
159
|
+
### Size
|
|
160
|
+
|
|
161
|
+
The two sizes for tag have been remove in favour of a default size in between `medium` and `small`. The `small` specifically was removed due to the reduced hit radius for the dismissible button and poor compatibility with avatars and icon.
|
|
162
|
+
|
|
163
|
+
`classNameOverride` can be leveraged to add padding and modify properties but should be done with caution to reduce inconsistencies in the platform and reduce the risk of accessibility violations.
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
#### Before
|
|
167
|
+
|
|
168
|
+
<Canvas of={LegacyTagStories.Sizes} />
|
|
169
|
+
|
|
170
|
+
#### After
|
|
171
|
+
|
|
172
|
+
<Canvas of={TagMigrationStories.SizesMigration} sourceState="shown"/>
|