@kaizen/components 1.68.10 → 1.68.12
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/Tag/Tag.cjs +2 -33
- package/dist/cjs/Tag/Tag.module.scss.cjs +1 -8
- package/dist/cjs/Tag/subcomponents/LiveIcon/LiveIcon.cjs +56 -0
- package/dist/cjs/Tag/subcomponents/LiveIcon/LiveIcon.module.css.cjs +12 -0
- package/dist/cjs/Tile/TileGrid/TileGrid.cjs +19 -2
- package/dist/cjs/__future__/Tabs/constants.cjs +4 -0
- package/dist/cjs/__future__/Tabs/subcomponents/Tab/Tab.cjs +3 -1
- package/dist/cjs/__future__/Tabs/subcomponents/TabList/TabList.cjs +117 -3
- package/dist/cjs/__future__/Tabs/subcomponents/TabList/TabList.module.css.cjs +4 -1
- package/dist/cjs/__utilities__/isRTL/isRTL.cjs +11 -0
- package/dist/esm/Tag/Tag.mjs +2 -33
- package/dist/esm/Tag/Tag.module.scss.mjs +1 -8
- package/dist/esm/Tag/subcomponents/LiveIcon/LiveIcon.mjs +54 -0
- package/dist/esm/Tag/subcomponents/LiveIcon/LiveIcon.module.css.mjs +10 -0
- package/dist/esm/Tile/TileGrid/TileGrid.mjs +19 -2
- package/dist/esm/__future__/Tabs/constants.mjs +2 -0
- package/dist/esm/__future__/Tabs/subcomponents/Tab/Tab.mjs +3 -1
- package/dist/esm/__future__/Tabs/subcomponents/TabList/TabList.mjs +121 -5
- package/dist/esm/__future__/Tabs/subcomponents/TabList/TabList.module.css.mjs +4 -1
- package/dist/esm/__utilities__/isRTL/isRTL.mjs +9 -0
- package/dist/styles.css +155 -87
- package/dist/types/Tag/subcomponents/LiveIcon/LiveIcon.d.ts +4 -0
- package/dist/types/Tag/subcomponents/LiveIcon/index.d.ts +1 -0
- package/dist/types/Tag/subcomponents/index.d.ts +1 -0
- package/dist/types/Tile/TileGrid/TileGrid.d.ts +1 -1
- package/dist/types/__future__/Tabs/constants.d.ts +1 -0
- package/dist/types/__future__/Tabs/subcomponents/TabList/TabList.d.ts +1 -0
- package/dist/types/__utilities__/isRTL/index.d.ts +1 -0
- package/dist/types/__utilities__/isRTL/isRTL.d.ts +5 -0
- package/package.json +3 -3
- package/src/Tag/Tag.module.scss +0 -92
- package/src/Tag/Tag.tsx +2 -37
- package/src/Tag/subcomponents/LiveIcon/LiveIcon.module.css +91 -0
- package/src/Tag/subcomponents/LiveIcon/LiveIcon.tsx +48 -0
- package/src/Tag/subcomponents/LiveIcon/index.ts +1 -0
- package/src/Tag/subcomponents/index.ts +1 -0
- package/src/Tile/TileGrid/TileGrid.module.scss +1 -0
- package/src/Tile/TileGrid/TileGrid.tsx +32 -7
- package/src/Tile/TileGrid/_docs/TileGrid.stickersheet.stories.tsx +40 -0
- package/src/Tile/TileGrid/_docs/TileGrid.stories.tsx +78 -1
- package/src/Workflow/_docs/ProgressStepper.stickersheet.stories.tsx +59 -0
- package/src/Workflow/subcomponents/Footer/components/ProgressStepper/ProgressStepper.module.css +6 -0
- package/src/__future__/Tabs/_docs/Tabs.spec.stories.tsx +118 -0
- package/src/__future__/Tabs/_docs/Tabs.stickersheet.stories.tsx +84 -0
- package/src/__future__/Tabs/_docs/Tabs.stories.tsx +12 -1
- package/src/__future__/Tabs/constants.ts +1 -0
- package/src/__future__/Tabs/subcomponents/Tab/Tab.tsx +1 -1
- package/src/__future__/Tabs/subcomponents/TabList/TabList.module.css +53 -1
- package/src/__future__/Tabs/subcomponents/TabList/TabList.tsx +138 -10
- package/src/__future__/Tag/Tag/_docs/Tag-migration-guide.stories.tsx +24 -64
- package/src/__utilities__/isRTL/index.ts +1 -0
- package/src/__utilities__/isRTL/isRTL.spec.tsx +38 -0
- package/src/__utilities__/isRTL/isRTL.ts +6 -0
|
@@ -1,8 +1,60 @@
|
|
|
1
|
+
.container {
|
|
2
|
+
position: relative;
|
|
3
|
+
}
|
|
4
|
+
|
|
1
5
|
.tabList {
|
|
2
6
|
border-bottom: 1px solid rgba(var(--color-gray-600-rgb), 0.1);
|
|
3
|
-
padding: var(--spacing-
|
|
7
|
+
padding: var(--spacing-6) 0 0;
|
|
8
|
+
width: 100%;
|
|
9
|
+
height: 100%;
|
|
10
|
+
overflow-x: scroll;
|
|
11
|
+
white-space: nowrap;
|
|
12
|
+
scrollbar-width: none;
|
|
13
|
+
scroll-behavior: smooth;
|
|
4
14
|
}
|
|
5
15
|
|
|
6
16
|
.noPadding {
|
|
7
17
|
padding: 0;
|
|
8
18
|
}
|
|
19
|
+
|
|
20
|
+
.leftArrow,
|
|
21
|
+
.rightArrow {
|
|
22
|
+
--icon-size: 24;
|
|
23
|
+
|
|
24
|
+
display: flex;
|
|
25
|
+
align-items: center;
|
|
26
|
+
justify-content: center;
|
|
27
|
+
position: absolute;
|
|
28
|
+
z-index: 10000;
|
|
29
|
+
background: var(--color-white);
|
|
30
|
+
inset-block: 0 1px;
|
|
31
|
+
width: 48px;
|
|
32
|
+
cursor: default;
|
|
33
|
+
user-select: none;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/*
|
|
37
|
+
* Note: we're purposefully using directional properties instead of start/end for positioning and styling related to the carousel arrows
|
|
38
|
+
*/
|
|
39
|
+
.leftArrow {
|
|
40
|
+
left: 0;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.leftArrow,
|
|
44
|
+
.leftArrow:hover {
|
|
45
|
+
border-right: 1px solid rgba(var(--color-gray-600-rgb), 0.1);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.rightArrow {
|
|
49
|
+
right: 0;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.rightArrow,
|
|
53
|
+
.rightArrow:hover {
|
|
54
|
+
border-left: 1px solid rgba(var(--color-gray-600-rgb), 0.1);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.leftArrow:hover,
|
|
58
|
+
.rightArrow:hover {
|
|
59
|
+
background: var(--color-gray-200);
|
|
60
|
+
}
|
|
@@ -1,6 +1,13 @@
|
|
|
1
|
-
import React, { ReactNode } from 'react'
|
|
1
|
+
import React, { ReactNode, useContext, useEffect, useId, useRef, useState } from 'react'
|
|
2
2
|
import classnames from 'classnames'
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
TabList as RACTabList,
|
|
5
|
+
TabListProps as RACTabListProps,
|
|
6
|
+
TabListStateContext,
|
|
7
|
+
} from 'react-aria-components'
|
|
8
|
+
import { Icon } from '~components/__future__/Icon'
|
|
9
|
+
import { isRTL as isRTLCheck } from '~components/__utilities__/isRTL'
|
|
10
|
+
import { SCROLL_AMOUNT } from '../../constants'
|
|
4
11
|
import styles from './TabList.module.css'
|
|
5
12
|
|
|
6
13
|
export type TabListProps = {
|
|
@@ -13,20 +20,141 @@ export type TabListProps = {
|
|
|
13
20
|
*/
|
|
14
21
|
'noPadding'?: boolean
|
|
15
22
|
'children': ReactNode
|
|
23
|
+
'data-testid'?: string
|
|
16
24
|
} & RACTabListProps<HTMLElement>
|
|
17
25
|
|
|
18
26
|
/**
|
|
19
27
|
* Wrapper for the tabs themselves
|
|
20
28
|
*/
|
|
21
29
|
export const TabList = (props: TabListProps): JSX.Element => {
|
|
22
|
-
const {
|
|
30
|
+
const {
|
|
31
|
+
'aria-label': ariaLabel,
|
|
32
|
+
noPadding = false,
|
|
33
|
+
children,
|
|
34
|
+
className,
|
|
35
|
+
'data-testid': testId,
|
|
36
|
+
...restProps
|
|
37
|
+
} = props
|
|
38
|
+
const [isDocumentReady, setIsDocumentReady] = useState<boolean>(false)
|
|
39
|
+
const [leftArrowEnabled, setLeftArrowEnabled] = useState<boolean>(false)
|
|
40
|
+
const [rightArrowEnabled, setRightArrowEnabled] = useState<boolean>(false)
|
|
41
|
+
const tabListRef = useRef<HTMLDivElement | null>(null)
|
|
42
|
+
const tabListId = useId()
|
|
43
|
+
const [isRTL, setIsRTL] = useState<boolean>(false)
|
|
44
|
+
const [containerElement, setContainerElement] = useState<HTMLElement | null>()
|
|
45
|
+
const tabListContext = useContext(TabListStateContext)
|
|
46
|
+
const selectedKey = tabListContext?.selectedKey
|
|
47
|
+
|
|
48
|
+
useEffect(() => {
|
|
49
|
+
if (!isDocumentReady) {
|
|
50
|
+
setIsDocumentReady(true)
|
|
51
|
+
return
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const container = document.getElementById(tabListId)
|
|
55
|
+
setContainerElement(container)
|
|
56
|
+
setIsRTL(container ? isRTLCheck(container) : false)
|
|
57
|
+
}, [isDocumentReady, tabListId])
|
|
58
|
+
|
|
59
|
+
useEffect(() => {
|
|
60
|
+
if (!isDocumentReady) {
|
|
61
|
+
return
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const tabs = containerElement?.querySelectorAll('[data-kz-tab]')
|
|
65
|
+
if (!tabs) {
|
|
66
|
+
return
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const firstTabObserver = new IntersectionObserver(
|
|
70
|
+
(entries) => {
|
|
71
|
+
if (!entries[0].isIntersecting) {
|
|
72
|
+
setLeftArrowEnabled(true)
|
|
73
|
+
return
|
|
74
|
+
}
|
|
75
|
+
setLeftArrowEnabled(false)
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
threshold: 0.75,
|
|
79
|
+
root: containerElement,
|
|
80
|
+
},
|
|
81
|
+
)
|
|
82
|
+
firstTabObserver.observe(isRTL ? tabs[tabs.length - 1] : tabs[0])
|
|
83
|
+
|
|
84
|
+
const lastTabObserver = new IntersectionObserver(
|
|
85
|
+
(entries) => {
|
|
86
|
+
if (!entries[0].isIntersecting) {
|
|
87
|
+
setRightArrowEnabled(true)
|
|
88
|
+
return
|
|
89
|
+
}
|
|
90
|
+
setRightArrowEnabled(false)
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
threshold: 0.75,
|
|
94
|
+
root: containerElement,
|
|
95
|
+
},
|
|
96
|
+
)
|
|
97
|
+
lastTabObserver.observe(isRTL ? tabs[0] : tabs[tabs.length - 1])
|
|
98
|
+
|
|
99
|
+
return () => {
|
|
100
|
+
firstTabObserver.disconnect()
|
|
101
|
+
lastTabObserver.disconnect()
|
|
102
|
+
}
|
|
103
|
+
}, [isDocumentReady, containerElement, isRTL])
|
|
104
|
+
|
|
105
|
+
useEffect(() => {
|
|
106
|
+
if (!isDocumentReady) {
|
|
107
|
+
return
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Scroll selected tab into view
|
|
111
|
+
containerElement
|
|
112
|
+
?.querySelector('[role="tab"][data-selected=true]')
|
|
113
|
+
?.scrollIntoView({ block: 'nearest', inline: 'center' })
|
|
114
|
+
}, [selectedKey, containerElement, isDocumentReady])
|
|
115
|
+
|
|
116
|
+
const handleArrowPress = (direction: 'left' | 'right'): void => {
|
|
117
|
+
if (tabListRef.current) {
|
|
118
|
+
const tabListScrollPos = tabListRef.current.scrollLeft
|
|
119
|
+
const newSpot =
|
|
120
|
+
direction === 'left' ? tabListScrollPos - SCROLL_AMOUNT : tabListScrollPos + SCROLL_AMOUNT
|
|
121
|
+
tabListRef.current.scrollLeft = newSpot
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
23
125
|
return (
|
|
24
|
-
<
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
126
|
+
<div className={styles.container} id={tabListId}>
|
|
127
|
+
{leftArrowEnabled && (
|
|
128
|
+
// making a conscious decision to use <div onClick> over <button> here, because:
|
|
129
|
+
// - <button> would add pointless noise for a screen reader user
|
|
130
|
+
// - keyboard only user can toggle through tabs with left/right arrow keys already
|
|
131
|
+
// eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions
|
|
132
|
+
<div
|
|
133
|
+
onClick={() => handleArrowPress('left')}
|
|
134
|
+
className={styles.leftArrow}
|
|
135
|
+
data-testid={testId ? `${testId}-kz-tablist-left-arrow` : undefined}
|
|
136
|
+
>
|
|
137
|
+
<Icon name="chevron_left" isPresentational />
|
|
138
|
+
</div>
|
|
139
|
+
)}
|
|
140
|
+
<RACTabList
|
|
141
|
+
aria-label={ariaLabel}
|
|
142
|
+
ref={tabListRef}
|
|
143
|
+
className={classnames(styles.tabList, className, noPadding && styles.noPadding)}
|
|
144
|
+
{...restProps}
|
|
145
|
+
>
|
|
146
|
+
{children}
|
|
147
|
+
</RACTabList>
|
|
148
|
+
{rightArrowEnabled && (
|
|
149
|
+
// eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions
|
|
150
|
+
<div
|
|
151
|
+
onClick={() => handleArrowPress('right')}
|
|
152
|
+
className={styles.rightArrow}
|
|
153
|
+
data-testid={testId ? `${testId}-kz-tablist-right-arrow` : undefined}
|
|
154
|
+
>
|
|
155
|
+
<Icon name="chevron_right" isPresentational />
|
|
156
|
+
</div>
|
|
157
|
+
)}
|
|
158
|
+
</div>
|
|
31
159
|
)
|
|
32
160
|
}
|
|
@@ -2,8 +2,7 @@ import React from 'react'
|
|
|
2
2
|
import { Meta, StoryObj } from '@storybook/react'
|
|
3
3
|
import { fn } from '@storybook/test'
|
|
4
4
|
import { Avatar } from '~components/Avatar'
|
|
5
|
-
import { LiveIcon } from '~components/
|
|
6
|
-
import styles from '~components/Tag/Tag.module.scss'
|
|
5
|
+
import { LiveIcon } from '~components/Tag/subcomponents'
|
|
7
6
|
import { Icon } from '~components/__future__/Icon'
|
|
8
7
|
import { Tag, RemovableTag } from '../..'
|
|
9
8
|
|
|
@@ -23,8 +22,16 @@ const meta = {
|
|
|
23
22
|
} satisfies Meta<typeof Tag>
|
|
24
23
|
|
|
25
24
|
export default meta
|
|
25
|
+
type Story = StoryObj<typeof meta>
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
export const LiveIconComponentStory: Story = {
|
|
28
|
+
render: () => <LiveIcon />,
|
|
29
|
+
parameters: {
|
|
30
|
+
docs: {
|
|
31
|
+
source: {
|
|
32
|
+
type: 'dynamic',
|
|
33
|
+
code: `
|
|
34
|
+
// component with styled with CSS modules
|
|
28
35
|
const LiveIconComponent = (): JSX.Element => (
|
|
29
36
|
<span className={styles.liveIcon}>
|
|
30
37
|
<LiveIcon
|
|
@@ -61,68 +68,21 @@ const LiveIconComponent = (): JSX.Element => (
|
|
|
61
68
|
/>
|
|
62
69
|
</span>
|
|
63
70
|
)
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
docs: {
|
|
69
|
-
source: {
|
|
70
|
-
type: 'dynamic',
|
|
71
|
-
code: `
|
|
72
|
-
// component with styled with CSS modules
|
|
73
|
-
const LiveIconComponent = (): JSX.Element => (
|
|
74
|
-
<span className={styles.liveIcon}>
|
|
75
|
-
<LiveIcon
|
|
76
|
-
role="presentation"
|
|
77
|
-
classNameOverride={styles.liveIcon_base}
|
|
78
|
-
width="16"
|
|
79
|
-
height="16"
|
|
80
|
-
viewBox="0 0 16 16"
|
|
81
|
-
fill="none"
|
|
82
|
-
/>
|
|
83
|
-
<LiveIcon
|
|
84
|
-
role="presentation"
|
|
85
|
-
classNameOverride={styles.liveIcon_1}
|
|
86
|
-
width="16"
|
|
87
|
-
height="16"
|
|
88
|
-
viewBox="0 0 16 16"
|
|
89
|
-
fill="none"
|
|
90
|
-
/>
|
|
91
|
-
<LiveIcon
|
|
92
|
-
role="presentation"
|
|
93
|
-
classNameOverride={styles.liveIcon_2}
|
|
94
|
-
width="16"
|
|
95
|
-
height="16"
|
|
96
|
-
viewBox="0 0 16 16"
|
|
97
|
-
fill="none"
|
|
98
|
-
/>
|
|
99
|
-
<LiveIcon
|
|
100
|
-
role="presentation"
|
|
101
|
-
classNameOverride={styles.liveIcon_3}
|
|
102
|
-
width="16"
|
|
103
|
-
height="16"
|
|
104
|
-
viewBox="0 0 16 16"
|
|
105
|
-
fill="none"
|
|
106
|
-
/>
|
|
107
|
-
</span>
|
|
108
|
-
)
|
|
109
|
-
|
|
110
|
-
// Minified SCSS from the stylesheet
|
|
111
|
-
<style>
|
|
112
|
-
.liveIcon_2,.liveIcon_3{animation-duration:3s;animation-iteration-count:3;animation-delay:1s}.liveIcon{display:inline-block;position:relative;width:20px;height:20px;color:$color-green-500}.liveIcon_1,.liveIcon_2,.liveIcon_3{display:block;position:absolute;top:0;left:$0;width:100%;height:100%;overflow:hidden}.liveIcon_base{opacity:30%;display:block}.liveIcon_1{clip-path:circle(16%)}.liveIcon_2{clip-path:circle(32%);animation-name:pulse-inner}.liveIcon_3{clip-path:circle(50%);animation-name:pulse-outer}@keyframes pulse-inner{0%,25%{opacity:0%}100%,50%,75%{opacity:100%}}@keyframes pulse-outer{0%,25%,50%{opacity:0%}100%,75%{opacity:100%}}
|
|
113
|
-
</style>
|
|
114
|
-
`,
|
|
71
|
+
// Minified SCSS from the stylesheet
|
|
72
|
+
<style>
|
|
73
|
+
.liveIcon_2,.liveIcon_3{animation-duration:3s;animation-iteration-count:3;animation-delay:1s}.liveIcon{display:inline-block;position:relative;width:20px;height:20px;color:$color-green-500}.liveIcon_1,.liveIcon_2,.liveIcon_3{display:block;position:absolute;top:0;left:$0;width:100%;height:100%;overflow:hidden}.liveIcon_base{opacity:30%;display:block}.liveIcon_1{clip-path:circle(16%)}.liveIcon_2{clip-path:circle(32%);animation-name:pulse-inner}.liveIcon_3{clip-path:circle(50%);animation-name:pulse-outer}@keyframes pulse-inner{0%,25%{opacity:0%}100%,50%,75%{opacity:100%}}@keyframes pulse-outer{0%,25%,50%{opacity:0%}100%,75%{opacity:100%}}
|
|
74
|
+
</style>`,
|
|
115
75
|
},
|
|
116
76
|
},
|
|
117
77
|
},
|
|
118
78
|
}
|
|
119
79
|
|
|
120
|
-
export const StatusMigration:
|
|
80
|
+
export const StatusMigration: Story = {
|
|
121
81
|
render: () => (
|
|
122
82
|
<>
|
|
123
83
|
<Tag classNameOverride="gap-4" color="green">
|
|
124
84
|
<span>Tag</span>
|
|
125
|
-
<
|
|
85
|
+
<LiveIcon />
|
|
126
86
|
</Tag>
|
|
127
87
|
<Tag color="blue">Tag</Tag>
|
|
128
88
|
<Tag color="red">Tag</Tag>
|
|
@@ -138,7 +98,7 @@ export const StatusMigration: StoryObj = {
|
|
|
138
98
|
],
|
|
139
99
|
}
|
|
140
100
|
|
|
141
|
-
export const ValidationMigration:
|
|
101
|
+
export const ValidationMigration: Story = {
|
|
142
102
|
render: () => (
|
|
143
103
|
<>
|
|
144
104
|
<Tag color="green" icon={<Icon name="check_circle" isFilled alt="Success," />}>
|
|
@@ -164,7 +124,7 @@ export const ValidationMigration: StoryObj = {
|
|
|
164
124
|
],
|
|
165
125
|
}
|
|
166
126
|
|
|
167
|
-
export const SentimentsMigration:
|
|
127
|
+
export const SentimentsMigration: Story = {
|
|
168
128
|
render: () => (
|
|
169
129
|
<>
|
|
170
130
|
<Tag color="green">Tag</Tag>
|
|
@@ -184,7 +144,7 @@ export const SentimentsMigration: StoryObj = {
|
|
|
184
144
|
],
|
|
185
145
|
}
|
|
186
146
|
|
|
187
|
-
export const SentimentNone:
|
|
147
|
+
export const SentimentNone: Story = {
|
|
188
148
|
render: () => (
|
|
189
149
|
<Tag color="gray" classNameOverride="bg-white border-default-color border-solid border">
|
|
190
150
|
Tag
|
|
@@ -192,7 +152,7 @@ export const SentimentNone: StoryObj = {
|
|
|
192
152
|
),
|
|
193
153
|
}
|
|
194
154
|
|
|
195
|
-
export const DismissibleMigration:
|
|
155
|
+
export const DismissibleMigration: Story = {
|
|
196
156
|
render: () => (
|
|
197
157
|
<RemovableTag
|
|
198
158
|
removeButtonProps={{
|
|
@@ -205,7 +165,7 @@ export const DismissibleMigration: StoryObj = {
|
|
|
205
165
|
),
|
|
206
166
|
}
|
|
207
167
|
|
|
208
|
-
export const AvatarMigration:
|
|
168
|
+
export const AvatarMigration: Story = {
|
|
209
169
|
render: () => (
|
|
210
170
|
<>
|
|
211
171
|
<Tag classNameOverride="ps-4">
|
|
@@ -241,7 +201,7 @@ export const AvatarMigration: StoryObj = {
|
|
|
241
201
|
],
|
|
242
202
|
}
|
|
243
203
|
|
|
244
|
-
export const AvatarRemovableMigration:
|
|
204
|
+
export const AvatarRemovableMigration: Story = {
|
|
245
205
|
render: () => (
|
|
246
206
|
<>
|
|
247
207
|
<RemovableTag
|
|
@@ -295,7 +255,7 @@ export const AvatarRemovableMigration: StoryObj = {
|
|
|
295
255
|
],
|
|
296
256
|
}
|
|
297
257
|
|
|
298
|
-
export const InlineMigration:
|
|
258
|
+
export const InlineMigration: Story = {
|
|
299
259
|
render: () => (
|
|
300
260
|
<div className="flex gap-12">
|
|
301
261
|
<Tag>Tag</Tag>
|
|
@@ -305,4 +265,4 @@ export const InlineMigration: StoryObj = {
|
|
|
305
265
|
),
|
|
306
266
|
}
|
|
307
267
|
|
|
308
|
-
export const SizesMigration:
|
|
268
|
+
export const SizesMigration: Story = {}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './isRTL'
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { render, screen } from '@testing-library/react'
|
|
3
|
+
import { isRTL } from './isRTL'
|
|
4
|
+
|
|
5
|
+
describe('isRTL', () => {
|
|
6
|
+
it('returns false when no element with dir found', () => {
|
|
7
|
+
const Example = (): JSX.Element => <button type="button">Test</button>
|
|
8
|
+
render(<Example />)
|
|
9
|
+
const button = screen.getByRole('button')
|
|
10
|
+
expect(isRTL(button)).toBe(false)
|
|
11
|
+
})
|
|
12
|
+
|
|
13
|
+
it('returns false when greater parent is dir=rtl, but closer parent is dir=ltr', () => {
|
|
14
|
+
const Example = (): JSX.Element => (
|
|
15
|
+
<div dir="rtl">
|
|
16
|
+
<div dir="ltr">
|
|
17
|
+
<button type="button">Test</button>
|
|
18
|
+
</div>
|
|
19
|
+
</div>
|
|
20
|
+
)
|
|
21
|
+
render(<Example />)
|
|
22
|
+
const button = screen.getByRole('button')
|
|
23
|
+
expect(isRTL(button)).toBe(false)
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
it('returns true when greater parent is dir=ltr, but closer parent is dir=rtl', () => {
|
|
27
|
+
const Example = (): JSX.Element => (
|
|
28
|
+
<div dir="ltr">
|
|
29
|
+
<div dir="rtl">
|
|
30
|
+
<button type="button">Test</button>
|
|
31
|
+
</div>
|
|
32
|
+
</div>
|
|
33
|
+
)
|
|
34
|
+
render(<Example />)
|
|
35
|
+
const button = screen.getByRole('button')
|
|
36
|
+
expect(isRTL(button)).toBe(true)
|
|
37
|
+
})
|
|
38
|
+
})
|