@okta/odyssey-react-mui 1.9.12 → 1.9.13
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/CHANGELOG.md +4 -0
- package/dist/Badge.js +33 -32
- package/dist/Badge.js.map +1 -1
- package/dist/Tabs.js +54 -10
- package/dist/Tabs.js.map +1 -1
- package/dist/src/Badge.d.ts.map +1 -1
- package/dist/src/Tabs.d.ts +5 -1
- package/dist/src/Tabs.d.ts.map +1 -1
- package/dist/theme/components.js +1 -1
- package/dist/theme/components.js.map +1 -1
- package/dist/tsconfig.production.tsbuildinfo +1 -1
- package/package.json +3 -3
- package/src/Badge.tsx +33 -29
- package/src/Tabs.tsx +85 -17
- package/src/theme/components.tsx +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@okta/odyssey-react-mui",
|
|
3
|
-
"version": "1.9.
|
|
3
|
+
"version": "1.9.13",
|
|
4
4
|
"description": "React MUI components for Odyssey, Okta's design system",
|
|
5
5
|
"author": "Okta, Inc.",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"@mui/system": "^5.14.9",
|
|
52
52
|
"@mui/utils": "^5.11.2",
|
|
53
53
|
"@mui/x-date-pickers": "^5.0.15",
|
|
54
|
-
"@okta/odyssey-design-tokens": "1.9.
|
|
54
|
+
"@okta/odyssey-design-tokens": "1.9.13",
|
|
55
55
|
"date-fns": "^2.30.0",
|
|
56
56
|
"i18next": "^23.5.1",
|
|
57
57
|
"material-react-table": "^2.0.2",
|
|
@@ -63,5 +63,5 @@
|
|
|
63
63
|
"react": ">=17 <19",
|
|
64
64
|
"react-dom": ">=17 <19"
|
|
65
65
|
},
|
|
66
|
-
"gitHead": "
|
|
66
|
+
"gitHead": "747861bf33f9c65b901782e306c16b0ccf26a942"
|
|
67
67
|
}
|
package/src/Badge.tsx
CHANGED
|
@@ -51,20 +51,17 @@ const Badge = ({
|
|
|
51
51
|
}: BadgeProps) => {
|
|
52
52
|
const odysseyDesignTokens = useOdysseyDesignTokens();
|
|
53
53
|
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
: badgeContent;
|
|
64
|
-
const contentIsLongerThanOneChar = formattedContent?.toString()?.length > 1;
|
|
54
|
+
const renderBadge = useMemo(() => {
|
|
55
|
+
const greaterThanZeroContentMax = badgeContentMax > 0 ? badgeContentMax : 1;
|
|
56
|
+
const threeDigitLimitedMax =
|
|
57
|
+
greaterThanZeroContentMax > 999 ? 999 : greaterThanZeroContentMax;
|
|
58
|
+
const isOverContentMax = badgeContent > threeDigitLimitedMax;
|
|
59
|
+
const overContentMaxMessage = `${greaterThanZeroContentMax}+`;
|
|
60
|
+
const formattedContent = isOverContentMax
|
|
61
|
+
? overContentMaxMessage
|
|
62
|
+
: badgeContent.toString();
|
|
65
63
|
|
|
66
|
-
|
|
67
|
-
() => ({
|
|
64
|
+
const badgeStyles: CSSProperties = {
|
|
68
65
|
display: "inline-flex",
|
|
69
66
|
alignItems: "center",
|
|
70
67
|
justifyContent: "center",
|
|
@@ -72,31 +69,38 @@ const Badge = ({
|
|
|
72
69
|
height: `calc(${odysseyDesignTokens.Spacing4} + ${odysseyDesignTokens.Spacing1})`,
|
|
73
70
|
minHeight: `calc(${odysseyDesignTokens.Spacing4} + ${odysseyDesignTokens.Spacing1})`,
|
|
74
71
|
// 6px horizontal padding per design requirements
|
|
75
|
-
padding:
|
|
72
|
+
padding: "0 6px",
|
|
76
73
|
backgroundColor: badgeTypeColors(odysseyDesignTokens)[type].background,
|
|
77
74
|
color: badgeTypeColors(odysseyDesignTokens)[type].font,
|
|
78
|
-
borderRadius:
|
|
79
|
-
|
|
80
|
-
|
|
75
|
+
borderRadius:
|
|
76
|
+
formattedContent.length > 1
|
|
77
|
+
? `${odysseyDesignTokens.BorderRadiusOuter}`
|
|
78
|
+
: "50%",
|
|
81
79
|
fontSize: `${odysseyDesignTokens.TypographyScale0}`,
|
|
82
80
|
fontFamily: `${odysseyDesignTokens.TypographyFamilyMono}`,
|
|
83
81
|
fontWeight: `${odysseyDesignTokens.TypographyWeightBodyBold}`,
|
|
84
82
|
lineHeight: 1,
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
83
|
+
transitionDuration: `${odysseyDesignTokens.TransitionDurationMain}`,
|
|
84
|
+
transitionProperty: `background-color, color`,
|
|
85
|
+
};
|
|
88
86
|
|
|
89
|
-
|
|
87
|
+
const hasNotificationCount = badgeContent && badgeContent > 0;
|
|
90
88
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
89
|
+
return hasNotificationCount ? (
|
|
90
|
+
<Box sx={badgeStyles} data-se={testId} translate={translate}>
|
|
91
|
+
{formattedContent}
|
|
92
|
+
</Box>
|
|
93
|
+
) : null;
|
|
94
|
+
}, [
|
|
95
|
+
badgeContent,
|
|
96
|
+
badgeContentMax,
|
|
97
|
+
odysseyDesignTokens,
|
|
98
|
+
testId,
|
|
99
|
+
translate,
|
|
100
|
+
type,
|
|
101
|
+
]);
|
|
94
102
|
|
|
95
|
-
return
|
|
96
|
-
<Box sx={badgeStyles} data-se={testId} translate={translate}>
|
|
97
|
-
{formattedContent}
|
|
98
|
-
</Box>
|
|
99
|
-
);
|
|
103
|
+
return renderBadge;
|
|
100
104
|
};
|
|
101
105
|
|
|
102
106
|
const MemoizedBadge = memo(Badge);
|
package/src/Tabs.tsx
CHANGED
|
@@ -10,13 +10,6 @@
|
|
|
10
10
|
* See the License for the specific language governing permissions and limitations under the License.
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
import {
|
|
14
|
-
TabContext as MuiTabContext,
|
|
15
|
-
TabList as MuiTabList,
|
|
16
|
-
TabListProps as MuiTabListProps,
|
|
17
|
-
TabPanel as MuiTabPanel,
|
|
18
|
-
} from "@mui/lab";
|
|
19
|
-
import { Tab as MuiTab } from "@mui/material";
|
|
20
13
|
import {
|
|
21
14
|
ReactElement,
|
|
22
15
|
ReactNode,
|
|
@@ -25,7 +18,18 @@ import {
|
|
|
25
18
|
useEffect,
|
|
26
19
|
useState,
|
|
27
20
|
} from "react";
|
|
21
|
+
import {
|
|
22
|
+
TabContext as MuiTabContext,
|
|
23
|
+
TabList as MuiTabList,
|
|
24
|
+
TabListProps as MuiTabListProps,
|
|
25
|
+
TabPanel as MuiTabPanel,
|
|
26
|
+
} from "@mui/lab";
|
|
27
|
+
import { Tab as MuiTab } from "@mui/material";
|
|
28
|
+
|
|
29
|
+
import { useOdysseyDesignTokens } from "./OdysseyDesignTokensContext";
|
|
30
|
+
import { Badge, BadgeProps } from "./Badge";
|
|
28
31
|
import { AllowedProps } from "./AllowedProps";
|
|
32
|
+
import { Box } from "./Box";
|
|
29
33
|
|
|
30
34
|
export type TabItemProps = {
|
|
31
35
|
/**
|
|
@@ -48,6 +52,9 @@ export type TabItemProps = {
|
|
|
48
52
|
* The value associated with the TabItem
|
|
49
53
|
*/
|
|
50
54
|
value?: string;
|
|
55
|
+
} & {
|
|
56
|
+
notificationCount?: BadgeProps["badgeContent"];
|
|
57
|
+
notificationCountMax?: BadgeProps["badgeContentMax"];
|
|
51
58
|
} & AllowedProps;
|
|
52
59
|
|
|
53
60
|
export type TabsProps = {
|
|
@@ -74,6 +81,42 @@ export type TabsProps = {
|
|
|
74
81
|
onChange?: MuiTabListProps["onChange"];
|
|
75
82
|
};
|
|
76
83
|
|
|
84
|
+
const TabLabel = ({
|
|
85
|
+
label,
|
|
86
|
+
notificationCount,
|
|
87
|
+
notificationCountMax,
|
|
88
|
+
tabState,
|
|
89
|
+
value,
|
|
90
|
+
}: Pick<
|
|
91
|
+
TabItemProps,
|
|
92
|
+
"label" | "notificationCount" | "notificationCountMax" | "value"
|
|
93
|
+
> & {
|
|
94
|
+
tabState: string;
|
|
95
|
+
}) => {
|
|
96
|
+
const odysseyDesignTokens = useOdysseyDesignTokens();
|
|
97
|
+
|
|
98
|
+
return (
|
|
99
|
+
<>
|
|
100
|
+
{label}
|
|
101
|
+
{notificationCount !== undefined && notificationCount > 0 && (
|
|
102
|
+
<Box
|
|
103
|
+
sx={{
|
|
104
|
+
marginInlineStart: notificationCount
|
|
105
|
+
? odysseyDesignTokens.Spacing2
|
|
106
|
+
: 0,
|
|
107
|
+
}}
|
|
108
|
+
>
|
|
109
|
+
<Badge
|
|
110
|
+
badgeContent={notificationCount}
|
|
111
|
+
badgeContentMax={notificationCountMax}
|
|
112
|
+
type={value === tabState ? "attention" : "default"}
|
|
113
|
+
/>
|
|
114
|
+
</Box>
|
|
115
|
+
)}
|
|
116
|
+
</>
|
|
117
|
+
);
|
|
118
|
+
};
|
|
119
|
+
|
|
77
120
|
const Tabs = ({
|
|
78
121
|
ariaLabel,
|
|
79
122
|
initialValue,
|
|
@@ -97,19 +140,44 @@ const Tabs = ({
|
|
|
97
140
|
}
|
|
98
141
|
}, [value]);
|
|
99
142
|
|
|
143
|
+
const renderTab = useCallback(
|
|
144
|
+
(tab, index) => {
|
|
145
|
+
const {
|
|
146
|
+
testId,
|
|
147
|
+
isDisabled,
|
|
148
|
+
label,
|
|
149
|
+
startIcon,
|
|
150
|
+
value,
|
|
151
|
+
notificationCount,
|
|
152
|
+
notificationCountMax,
|
|
153
|
+
} = tab;
|
|
154
|
+
|
|
155
|
+
return (
|
|
156
|
+
<MuiTab
|
|
157
|
+
data-se={testId}
|
|
158
|
+
disabled={isDisabled}
|
|
159
|
+
icon={startIcon}
|
|
160
|
+
label={
|
|
161
|
+
<TabLabel
|
|
162
|
+
label={label}
|
|
163
|
+
notificationCount={notificationCount}
|
|
164
|
+
notificationCountMax={notificationCountMax}
|
|
165
|
+
tabState={tabState}
|
|
166
|
+
value={value}
|
|
167
|
+
/>
|
|
168
|
+
}
|
|
169
|
+
value={value ? value : index.toString()}
|
|
170
|
+
key={value ? value : index.toString()}
|
|
171
|
+
/>
|
|
172
|
+
);
|
|
173
|
+
},
|
|
174
|
+
[tabState]
|
|
175
|
+
);
|
|
176
|
+
|
|
100
177
|
return (
|
|
101
178
|
<MuiTabContext value={tabState}>
|
|
102
179
|
<MuiTabList onChange={onChange} aria-label={ariaLabel}>
|
|
103
|
-
{tabs.map((tab, index) => (
|
|
104
|
-
<MuiTab
|
|
105
|
-
data-se={tab.testId}
|
|
106
|
-
disabled={tab.isDisabled}
|
|
107
|
-
icon={tab.startIcon}
|
|
108
|
-
label={tab.label}
|
|
109
|
-
value={tab.value ? tab.value : index.toString()}
|
|
110
|
-
key={tab.value ? tab.value : index.toString()}
|
|
111
|
-
/>
|
|
112
|
-
))}
|
|
180
|
+
{tabs.map((tab, index) => renderTab(tab, index))}
|
|
113
181
|
</MuiTabList>
|
|
114
182
|
{tabs.map((tab, index) => (
|
|
115
183
|
<MuiTabPanel
|
package/src/theme/components.tsx
CHANGED
|
@@ -2208,7 +2208,7 @@ export const components = ({
|
|
|
2208
2208
|
root: ({ ownerState }) => ({
|
|
2209
2209
|
maxWidth: `calc(${odysseyTokens.TypographyLineLengthMax} / 2)`,
|
|
2210
2210
|
minWidth: "unset",
|
|
2211
|
-
minHeight:
|
|
2211
|
+
minHeight: odysseyTokens.Spacing9,
|
|
2212
2212
|
padding: `${odysseyTokens.Spacing4} ${odysseyTokens.Spacing1}`,
|
|
2213
2213
|
fontSize: odysseyTokens.TypographySizeHeading6,
|
|
2214
2214
|
fontFamily: odysseyTokens.TypographyFamilyHeading,
|