@servicetitan/navigation 11.0.0-canary.237.f2d512b.0 → 11.0.0-canary.237.f834dab.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/components/badge-tag.d.ts +1 -1
- package/dist/components/badge-tag.d.ts.map +1 -1
- package/dist/components/header-navigation/header-navigation-stacked.stories.js +1 -1
- package/dist/components/header-navigation/header-navigation-stacked.stories.js.map +1 -1
- package/dist/components/header-navigation/header-navigation.stories.js +1 -1
- package/dist/components/header-navigation/header-navigation.stories.js.map +1 -1
- package/dist/components/left-navigation/header-navigation-tiny.stories.js +2 -2
- package/dist/components/left-navigation/header-navigation-tiny.stories.js.map +1 -1
- package/dist/components/logo/logo-titan-text.d.ts +1 -1
- package/dist/components/logo/logo-titan-text.d.ts.map +1 -1
- package/dist/components/profile-dropdown/profile-dropdown.d.ts +12 -7
- package/dist/components/profile-dropdown/profile-dropdown.d.ts.map +1 -1
- package/dist/components/profile-dropdown/profile-dropdown.js +5 -4
- package/dist/components/profile-dropdown/profile-dropdown.js.map +1 -1
- package/dist/components/profile-dropdown/profile-dropdown.module.less +3 -0
- package/dist/components/titan-layout/layout-context.js +1 -1
- package/dist/components/titan-layout/layout-context.js.map +1 -1
- package/dist/components/titan-layout/layout-header.d.ts +2 -0
- package/dist/components/titan-layout/layout-header.d.ts.map +1 -1
- package/dist/components/titan-layout/layout-header.js +3 -4
- package/dist/components/titan-layout/layout-header.js.map +1 -1
- package/dist/components/titan-layout/layout-header.module.less +60 -21
- package/dist/components/titan-layout/layout-logo.d.ts.map +1 -1
- package/dist/components/titan-layout/layout-logo.js +2 -1
- package/dist/components/titan-layout/layout-logo.js.map +1 -1
- package/dist/components/titan-layout/layout-profile.d.ts.map +1 -1
- package/dist/components/titan-layout/layout-profile.js +37 -9
- package/dist/components/titan-layout/layout-profile.js.map +1 -1
- package/dist/components/titan-layout/layout-profile.stories.d.ts.map +1 -1
- package/dist/components/titan-layout/layout-profile.stories.js +1 -1
- package/dist/components/titan-layout/layout-profile.stories.js.map +1 -1
- package/dist/components/titan-layout/layout-sidebar-links-internal.d.ts +2 -2
- package/dist/components/titan-layout/layout-sidebar-links-internal.d.ts.map +1 -1
- package/dist/components/titan-layout/layout-sidebar-links-internal.js +4 -4
- package/dist/components/titan-layout/layout-sidebar-links-internal.js.map +1 -1
- package/dist/components/titan-layout/layout-sidebar-links.d.ts.map +1 -1
- package/dist/components/titan-layout/layout-sidebar-links.js +12 -5
- package/dist/components/titan-layout/layout-sidebar-links.js.map +1 -1
- package/dist/components/titan-layout/layout-sidebar.d.ts +2 -0
- package/dist/components/titan-layout/layout-sidebar.d.ts.map +1 -1
- package/dist/components/titan-layout/layout-sidebar.js +6 -4
- package/dist/components/titan-layout/layout-sidebar.js.map +1 -1
- package/dist/components/titan-layout/layout-sidebar.module.less +29 -6
- package/dist/components/titan-layout/notifications-context.d.ts +13 -0
- package/dist/components/titan-layout/notifications-context.d.ts.map +1 -0
- package/dist/components/titan-layout/notifications-context.js +23 -0
- package/dist/components/titan-layout/notifications-context.js.map +1 -0
- package/dist/components/titan-layout/titan-layout.d.ts +10 -6
- package/dist/components/titan-layout/titan-layout.d.ts.map +1 -1
- package/dist/components/titan-layout/titan-layout.js +104 -21
- package/dist/components/titan-layout/titan-layout.js.map +1 -1
- package/dist/components/titan-layout/titan-layout.module.less +50 -20
- package/dist/components/titan-layout/titan-layout.stories.d.ts +15 -11
- package/dist/components/titan-layout/titan-layout.stories.d.ts.map +1 -1
- package/dist/components/titan-layout/titan-layout.stories.js +35 -14
- package/dist/components/titan-layout/titan-layout.stories.js.map +1 -1
- package/dist/test/data.d.ts +4 -1
- package/dist/test/data.d.ts.map +1 -1
- package/dist/test/data.js +2 -3
- package/dist/test/data.js.map +1 -1
- package/dist/utils/use-breakpoint.d.ts +1 -0
- package/dist/utils/use-breakpoint.d.ts.map +1 -1
- package/dist/utils/use-breakpoint.js +3 -2
- package/dist/utils/use-breakpoint.js.map +1 -1
- package/package.json +2 -2
- package/src/components/badge-tag.tsx +1 -1
- package/src/components/header-navigation/header-navigation-stacked.stories.tsx +1 -1
- package/src/components/header-navigation/header-navigation.stories.tsx +1 -1
- package/src/components/left-navigation/header-navigation-tiny.stories.tsx +2 -2
- package/src/components/logo/logo-titan-text.tsx +1 -1
- package/src/components/profile-dropdown/profile-dropdown.module.less +3 -0
- package/src/components/profile-dropdown/profile-dropdown.tsx +23 -6
- package/src/components/titan-layout/layout-context.tsx +1 -1
- package/src/components/titan-layout/layout-header.module.less +60 -21
- package/src/components/titan-layout/layout-header.module.less.d.ts +2 -0
- package/src/components/titan-layout/layout-header.tsx +12 -5
- package/src/components/titan-layout/layout-logo.tsx +13 -6
- package/src/components/titan-layout/layout-profile.stories.tsx +10 -1
- package/src/components/titan-layout/layout-profile.tsx +88 -26
- package/src/components/titan-layout/layout-sidebar-links-internal.tsx +18 -5
- package/src/components/titan-layout/layout-sidebar-links.tsx +21 -5
- package/src/components/titan-layout/layout-sidebar.module.less +29 -6
- package/src/components/titan-layout/layout-sidebar.module.less.d.ts +1 -0
- package/src/components/titan-layout/layout-sidebar.tsx +14 -5
- package/src/components/titan-layout/notifications-context.tsx +44 -0
- package/src/components/titan-layout/titan-layout.module.less +50 -20
- package/src/components/titan-layout/titan-layout.module.less.d.ts +3 -0
- package/src/components/titan-layout/titan-layout.stories.tsx +167 -19
- package/src/components/titan-layout/titan-layout.tsx +265 -76
- package/src/test/data.tsx +2 -3
- package/src/utils/use-breakpoint.ts +3 -1
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
useCallback,
|
|
12
12
|
useEffect,
|
|
13
13
|
useMemo,
|
|
14
|
+
useRef,
|
|
14
15
|
useState,
|
|
15
16
|
} from 'react';
|
|
16
17
|
import { NavigationItemData } from '../../utils/navigation';
|
|
@@ -28,33 +29,38 @@ import { TitanLayoutLogo, TitanLayoutLogoProps } from './layout-logo';
|
|
|
28
29
|
import { LayoutSidebar } from './layout-sidebar';
|
|
29
30
|
import { TitanLayoutSidebarLink, TitanLayoutSidebarTrigger } from './layout-sidebar-links';
|
|
30
31
|
import { InternalSideNavigationTrigger } from './layout-sidebar-links-internal';
|
|
32
|
+
import { useNotificationsState } from './notifications-context';
|
|
31
33
|
import * as Styles from './titan-layout.module.less';
|
|
32
34
|
|
|
33
35
|
type TitanLayoutChild = ReactElement<TitanLayoutContentProps> | ReactElement<TitanLayoutLogoProps>;
|
|
34
36
|
|
|
35
37
|
export type TitanLayoutProps = Omit<ComponentPropsWithoutRef<'div'>, 'children' | 'style'> & {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
+
/** layout appearance */
|
|
38
39
|
appearance?: 'legacy' | 'anvil1' | 'anvil2';
|
|
39
40
|
|
|
41
|
+
/** layout's content */
|
|
42
|
+
children?: TitanLayoutChild | TitanLayoutChild[];
|
|
43
|
+
|
|
44
|
+
/** show only content without side and top bars */
|
|
45
|
+
contentOnly?: boolean;
|
|
46
|
+
|
|
40
47
|
/** component used for navigation */
|
|
41
48
|
navigationComponent?: FC<NavLinkComponentProps>;
|
|
42
49
|
|
|
43
50
|
/** data for main navigation links */
|
|
44
51
|
navigationMainItems?: NavigationItemData[];
|
|
45
52
|
|
|
46
|
-
/** layout's content */
|
|
47
|
-
children?: TitanLayoutChild | TitanLayoutChild[];
|
|
48
|
-
|
|
49
53
|
state?: TitanLayoutState;
|
|
50
54
|
onStateChange?: (state: TitanLayoutState) => void;
|
|
51
55
|
|
|
52
56
|
header?: ReactElement;
|
|
57
|
+
top?: ReactElement;
|
|
58
|
+
sideTop?: ReactElement[];
|
|
53
59
|
profile?: ReactElement;
|
|
54
60
|
extraLinks?: ReactElement;
|
|
55
61
|
extraLinksTop?: ReactElement;
|
|
56
62
|
extraText?: string;
|
|
57
|
-
|
|
63
|
+
minContentWidth?: number;
|
|
58
64
|
};
|
|
59
65
|
|
|
60
66
|
const defaultSidebarContext: TitanLayoutSidebarContextType = {
|
|
@@ -113,8 +119,10 @@ const TitanLayoutComponent: FC<TitanLayoutProps> = ({
|
|
|
113
119
|
appearance = 'anvil2',
|
|
114
120
|
id,
|
|
115
121
|
children,
|
|
122
|
+
contentOnly,
|
|
116
123
|
navigationComponent,
|
|
117
124
|
header,
|
|
125
|
+
top,
|
|
118
126
|
profile,
|
|
119
127
|
state,
|
|
120
128
|
onStateChange,
|
|
@@ -122,10 +130,10 @@ const TitanLayoutComponent: FC<TitanLayoutProps> = ({
|
|
|
122
130
|
extraLinks,
|
|
123
131
|
extraLinksTop,
|
|
124
132
|
extraText,
|
|
125
|
-
|
|
133
|
+
minContentWidth,
|
|
134
|
+
sideTop,
|
|
126
135
|
}) => {
|
|
127
136
|
const breakpoint = useTitanBreakpoint();
|
|
128
|
-
const isMobile = breakpoint.isMobile;
|
|
129
137
|
const context: TitanLayoutContextType = useMemo(
|
|
130
138
|
() => ({
|
|
131
139
|
NavigationComponent: navigationComponent ?? DefaultNavLinkComponent,
|
|
@@ -138,21 +146,23 @@ const TitanLayoutComponent: FC<TitanLayoutProps> = ({
|
|
|
138
146
|
const variant = useVariant(appearance);
|
|
139
147
|
const [mobileDrawerOpened, setMobileDrawerOpened] = useState(false);
|
|
140
148
|
const { content, logo } = useLayoutChildren(children);
|
|
149
|
+
const { hasNotifications, NotificationsContextProvider } = useNotificationsState();
|
|
150
|
+
const [anvil2Styles, setAnvil2Styles] = useState<object>({});
|
|
151
|
+
const updateIndicatorsHeight = useCallback((offset: number) => {
|
|
152
|
+
setAnvil2Styles({ '--offset': `calc(var(--nav-offset-top) + ${offset}px)` });
|
|
153
|
+
}, []);
|
|
154
|
+
|
|
155
|
+
const isMobile = breakpoint.isMobile;
|
|
156
|
+
const hasSideBar = !contentOnly && (!!navigationMainItems?.length || !!sideTop?.length);
|
|
157
|
+
const hasTopBar = !contentOnly;
|
|
141
158
|
|
|
142
159
|
useEffect(() => {
|
|
143
|
-
if (
|
|
144
|
-
|
|
145
|
-
|
|
160
|
+
if (variant.isAnvil1) {
|
|
161
|
+
const bodyClassName = 'of-hidden-i';
|
|
162
|
+
document.body.classList.add(bodyClassName);
|
|
163
|
+
return () => document.body.classList.remove(bodyClassName);
|
|
146
164
|
}
|
|
147
|
-
|
|
148
|
-
const listener = () => {
|
|
149
|
-
setMobileDrawerOpened(false);
|
|
150
|
-
};
|
|
151
|
-
|
|
152
|
-
document.addEventListener('click', listener);
|
|
153
|
-
|
|
154
|
-
return () => document.removeEventListener('click', listener);
|
|
155
|
-
}, [isMobile]);
|
|
165
|
+
}, [variant.isAnvil1]);
|
|
156
166
|
|
|
157
167
|
const onBurgerClick = useCallback((e: MouseEvent) => {
|
|
158
168
|
setMobileDrawerOpened(true);
|
|
@@ -178,8 +188,48 @@ const TitanLayoutComponent: FC<TitanLayoutProps> = ({
|
|
|
178
188
|
},
|
|
179
189
|
[state, onStateChange]
|
|
180
190
|
);
|
|
191
|
+
const hasMenuNotifications = useMemo(() => {
|
|
192
|
+
try {
|
|
193
|
+
return (
|
|
194
|
+
navigationMainItems?.some(item => {
|
|
195
|
+
if (item.counter || item.tag?.value) {
|
|
196
|
+
return true;
|
|
197
|
+
} else if (item.submenu) {
|
|
198
|
+
return item.submenu.groups.some(group =>
|
|
199
|
+
group.links.some(link => !!link.counter || !!link.tag?.value)
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
return false;
|
|
203
|
+
}) ?? false
|
|
204
|
+
);
|
|
205
|
+
} catch {
|
|
206
|
+
return false;
|
|
207
|
+
}
|
|
208
|
+
}, [navigationMainItems]);
|
|
209
|
+
|
|
210
|
+
const limitContentWidth = useMemo(() => {
|
|
211
|
+
if (variant.isAnvil2 || !minContentWidth) {
|
|
212
|
+
return undefined;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
if (breakpoint.width < minContentWidth) {
|
|
216
|
+
return minContentWidth;
|
|
217
|
+
}
|
|
218
|
+
}, [variant, minContentWidth, breakpoint.width]);
|
|
219
|
+
|
|
220
|
+
const contentStyles = useMemo(() => {
|
|
221
|
+
if (variant.isAnvil2) {
|
|
222
|
+
return anvil2Styles;
|
|
223
|
+
}
|
|
181
224
|
|
|
182
|
-
|
|
225
|
+
if (variant.isLegacy && limitContentWidth) {
|
|
226
|
+
return {
|
|
227
|
+
display: 'flex',
|
|
228
|
+
flexDirection: 'column',
|
|
229
|
+
minHeight: '100vh',
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
}, [variant, anvil2Styles, limitContentWidth]);
|
|
183
233
|
|
|
184
234
|
const layoutClass = variant.isLegacy
|
|
185
235
|
? Styles.layoutLegacy
|
|
@@ -194,79 +244,218 @@ const TitanLayoutComponent: FC<TitanLayoutProps> = ({
|
|
|
194
244
|
id={id}
|
|
195
245
|
className={classNames(
|
|
196
246
|
Styles.layout,
|
|
197
|
-
isMobile
|
|
198
|
-
|
|
199
|
-
:
|
|
200
|
-
|
|
201
|
-
|
|
247
|
+
isMobile ? Styles.layoutMobile : Styles.layoutDesktop,
|
|
248
|
+
{
|
|
249
|
+
[Styles.layoutTop]: hasTopBar,
|
|
250
|
+
[Styles.layoutNavSlim]: !isMobile && hasSideBar && state?.navCollapsed,
|
|
251
|
+
[Styles.layoutNavWide]: !isMobile && hasSideBar && !state?.navCollapsed,
|
|
252
|
+
},
|
|
202
253
|
layoutClass
|
|
203
254
|
)}
|
|
204
|
-
style={
|
|
255
|
+
style={contentStyles}
|
|
205
256
|
>
|
|
206
257
|
{variant.isSequent && <div className={Styles.topPlaceholder} />}
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
{extraLinksTop}
|
|
216
|
-
{!isMobile && extraLinks}
|
|
217
|
-
</Fragment>
|
|
218
|
-
}
|
|
219
|
-
onBurgerClick={onBurgerClick}
|
|
220
|
-
/>
|
|
221
|
-
|
|
222
|
-
<LayoutSidebar
|
|
223
|
-
className={Styles.side}
|
|
224
|
-
mobile={breakpoint.isMobile}
|
|
225
|
-
barExpanded={isMobile ? mobileDrawerOpened : !state?.navCollapsed}
|
|
226
|
-
submenuExpanded={state?.submenuExpanded}
|
|
227
|
-
onBarExpandChange={onBarExpandChange}
|
|
228
|
-
onSubmenuExpandChange={onSubmenuExpandChange}
|
|
229
|
-
top={sidebarTop}
|
|
230
|
-
mainItems={navigationMainItems}
|
|
231
|
-
navigationComponent={context.NavigationComponent}
|
|
232
|
-
bottom={
|
|
233
|
-
isMobile ? (
|
|
258
|
+
{hasTopBar && (
|
|
259
|
+
<LayoutHeader
|
|
260
|
+
className={Styles.top}
|
|
261
|
+
logo={logo}
|
|
262
|
+
profile={isMobile ? undefined : profile}
|
|
263
|
+
center={top}
|
|
264
|
+
rightText={isMobile ? undefined : extraText}
|
|
265
|
+
right={
|
|
234
266
|
<Fragment>
|
|
235
|
-
{
|
|
236
|
-
{extraLinks}
|
|
237
|
-
{!!extraText && (
|
|
238
|
-
<InternalSideNavigationTrigger
|
|
239
|
-
id="__extra_text"
|
|
240
|
-
title={extraText}
|
|
241
|
-
submenuExpanded={undefined}
|
|
242
|
-
dataPrefix="navigation-extra-text"
|
|
243
|
-
tag={undefined}
|
|
244
|
-
icon={undefined}
|
|
245
|
-
iconActive={undefined}
|
|
246
|
-
/>
|
|
247
|
-
)}
|
|
267
|
+
{extraLinksTop}
|
|
268
|
+
{!isMobile && extraLinks}
|
|
248
269
|
</Fragment>
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
270
|
+
}
|
|
271
|
+
isMobile={isMobile}
|
|
272
|
+
hasNotifications={hasNotifications || hasMenuNotifications}
|
|
273
|
+
onBurgerClick={onBurgerClick}
|
|
274
|
+
/>
|
|
275
|
+
)}
|
|
252
276
|
|
|
253
|
-
{
|
|
277
|
+
{hasSideBar && (
|
|
278
|
+
<NotificationsContextProvider>
|
|
279
|
+
<LayoutSidebar
|
|
280
|
+
className={Styles.side}
|
|
281
|
+
mobile={breakpoint.isMobile}
|
|
282
|
+
barExpanded={!state?.navCollapsed}
|
|
283
|
+
onBarExpandChange={onBarExpandChange}
|
|
284
|
+
submenuExpanded={state?.submenuExpanded}
|
|
285
|
+
onSubmenuExpandChange={onSubmenuExpandChange}
|
|
286
|
+
drawerOpened={mobileDrawerOpened}
|
|
287
|
+
onDrawerOpenChange={setMobileDrawerOpened}
|
|
288
|
+
top={sideTop}
|
|
289
|
+
mainItems={navigationMainItems}
|
|
290
|
+
navigationComponent={context.NavigationComponent}
|
|
291
|
+
bottom={
|
|
292
|
+
isMobile ? (
|
|
293
|
+
<Fragment>
|
|
294
|
+
{profile}
|
|
295
|
+
{extraLinks}
|
|
296
|
+
{!!extraText && (
|
|
297
|
+
<InternalSideNavigationTrigger
|
|
298
|
+
id="__extra_text"
|
|
299
|
+
title={extraText}
|
|
300
|
+
submenuExpanded={undefined}
|
|
301
|
+
dataPrefix="navigation-extra-text"
|
|
302
|
+
tag={undefined}
|
|
303
|
+
icon={undefined}
|
|
304
|
+
iconActive={undefined}
|
|
305
|
+
/>
|
|
306
|
+
)}
|
|
307
|
+
</Fragment>
|
|
308
|
+
) : undefined
|
|
309
|
+
}
|
|
310
|
+
/>
|
|
311
|
+
</NotificationsContextProvider>
|
|
312
|
+
)}
|
|
313
|
+
|
|
314
|
+
{variant.isAnvil1 ? (
|
|
315
|
+
<LayoutContentAnvil1 header={header} minWidth={limitContentWidth}>
|
|
316
|
+
{content}
|
|
317
|
+
</LayoutContentAnvil1>
|
|
318
|
+
) : variant.isLegacy ? (
|
|
319
|
+
<LayoutContentLegacy header={header} minWidth={limitContentWidth}>
|
|
320
|
+
{content}
|
|
321
|
+
</LayoutContentLegacy>
|
|
322
|
+
) : (
|
|
323
|
+
<LayoutContentAnvil2
|
|
324
|
+
header={header}
|
|
325
|
+
onHeaderHeightChange={updateIndicatorsHeight}
|
|
326
|
+
>
|
|
327
|
+
{content}
|
|
328
|
+
</LayoutContentAnvil2>
|
|
329
|
+
)}
|
|
254
330
|
</div>
|
|
255
331
|
</LayoutPlacementContext.Provider>
|
|
256
332
|
</LayoutContext.Provider>
|
|
257
333
|
);
|
|
258
334
|
};
|
|
259
335
|
|
|
336
|
+
const TitanLayoutHeaderObserved: FC<{
|
|
337
|
+
children: ReactNode;
|
|
338
|
+
heightChange?(value: number): void;
|
|
339
|
+
}> = ({ children, heightChange }) => {
|
|
340
|
+
const ref = useRef<HTMLDivElement>(null);
|
|
341
|
+
|
|
342
|
+
useEffect(() => {
|
|
343
|
+
if (ref.current) {
|
|
344
|
+
const updatePosition = () => {
|
|
345
|
+
if (ref.current && heightChange) {
|
|
346
|
+
const pos = ref.current.getBoundingClientRect();
|
|
347
|
+
heightChange(pos.height);
|
|
348
|
+
}
|
|
349
|
+
};
|
|
350
|
+
|
|
351
|
+
const observer = new ResizeObserver(updatePosition);
|
|
352
|
+
observer.observe(ref.current);
|
|
353
|
+
|
|
354
|
+
updatePosition();
|
|
355
|
+
return () => observer.disconnect();
|
|
356
|
+
}
|
|
357
|
+
}, [heightChange]);
|
|
358
|
+
|
|
359
|
+
useEffect(() => {
|
|
360
|
+
return () => {
|
|
361
|
+
heightChange?.(0);
|
|
362
|
+
};
|
|
363
|
+
}, [heightChange]);
|
|
364
|
+
return (
|
|
365
|
+
<div ref={ref} className={Styles.contentHeader} data-cy="layout-content-header">
|
|
366
|
+
{children}
|
|
367
|
+
</div>
|
|
368
|
+
);
|
|
369
|
+
};
|
|
370
|
+
const TitanLayoutHeader: FC<{ children: ReactNode }> = ({ children }) => {
|
|
371
|
+
return (
|
|
372
|
+
<div className={Styles.contentHeader} data-cy="layout-content-header">
|
|
373
|
+
{children}
|
|
374
|
+
</div>
|
|
375
|
+
);
|
|
376
|
+
};
|
|
377
|
+
|
|
260
378
|
export interface TitanLayoutContentProps {
|
|
261
379
|
children: ReactNode;
|
|
262
380
|
}
|
|
263
|
-
const TitanLayoutContent: FC<TitanLayoutContentProps> = ({ children }) =>
|
|
264
|
-
|
|
265
|
-
|
|
381
|
+
const TitanLayoutContent: FC<TitanLayoutContentProps> = ({ children }) => children;
|
|
382
|
+
|
|
383
|
+
const LayoutContentAnvil2: FC<{
|
|
384
|
+
children: ReactNode;
|
|
385
|
+
header?: ReactNode;
|
|
386
|
+
onHeaderHeightChange?: (height: number) => void;
|
|
387
|
+
}> = ({ children, header, onHeaderHeightChange }) => {
|
|
388
|
+
return (
|
|
389
|
+
<Fragment>
|
|
390
|
+
<TitanLayoutHeaderObserved heightChange={onHeaderHeightChange}>
|
|
391
|
+
{header}
|
|
392
|
+
</TitanLayoutHeaderObserved>
|
|
393
|
+
{children}
|
|
394
|
+
</Fragment>
|
|
395
|
+
);
|
|
396
|
+
};
|
|
397
|
+
|
|
398
|
+
const LayoutContentAnvil1: FC<{
|
|
399
|
+
children: ReactNode;
|
|
400
|
+
header?: ReactNode;
|
|
401
|
+
minWidth?: number;
|
|
402
|
+
}> = ({ children, header, minWidth }) => {
|
|
403
|
+
const innerContentStyles: CSSProperties = useMemo(
|
|
404
|
+
() => ({
|
|
405
|
+
...(minWidth ? { minWidth: `${minWidth}px` } : {}),
|
|
406
|
+
}),
|
|
407
|
+
[minWidth]
|
|
408
|
+
);
|
|
409
|
+
|
|
410
|
+
return (
|
|
411
|
+
<Fragment>
|
|
412
|
+
<TitanLayoutHeader>{header}</TitanLayoutHeader>
|
|
413
|
+
<div
|
|
414
|
+
className={classNames(Styles.content, { 'of-x-auto': !!minWidth })}
|
|
415
|
+
data-cy="layout-content"
|
|
416
|
+
>
|
|
417
|
+
<div
|
|
418
|
+
className="position-relative d-f flex-grow-1 flex-basis-0 of-hidden"
|
|
419
|
+
style={innerContentStyles}
|
|
420
|
+
>
|
|
421
|
+
{children}
|
|
422
|
+
</div>
|
|
423
|
+
</div>
|
|
424
|
+
</Fragment>
|
|
425
|
+
);
|
|
426
|
+
};
|
|
427
|
+
|
|
428
|
+
const LayoutContentLegacy: FC<{
|
|
429
|
+
children: ReactNode;
|
|
430
|
+
header?: ReactNode;
|
|
431
|
+
minWidth: number | undefined;
|
|
432
|
+
}> = ({ children, header, minWidth }) => {
|
|
433
|
+
const innerContentStyles: CSSProperties = useMemo(
|
|
434
|
+
() => ({
|
|
435
|
+
position: 'relative',
|
|
436
|
+
minWidth: `${minWidth}px`,
|
|
437
|
+
}),
|
|
438
|
+
[minWidth]
|
|
439
|
+
);
|
|
440
|
+
|
|
441
|
+
return (
|
|
442
|
+
<Fragment>
|
|
443
|
+
<TitanLayoutHeader>{header}</TitanLayoutHeader>
|
|
444
|
+
|
|
445
|
+
{minWidth ? (
|
|
446
|
+
<div className="of-x-auto flex-basis-0 flex-grow-1">
|
|
447
|
+
<div style={innerContentStyles}>{children}</div>
|
|
448
|
+
</div>
|
|
449
|
+
) : (
|
|
450
|
+
children
|
|
451
|
+
)}
|
|
452
|
+
</Fragment>
|
|
453
|
+
);
|
|
454
|
+
};
|
|
266
455
|
|
|
267
456
|
export const TitanLayout = Object.assign(TitanLayoutComponent, {
|
|
268
457
|
Content: TitanLayoutContent,
|
|
269
458
|
Logo: TitanLayoutLogo,
|
|
270
|
-
|
|
271
|
-
|
|
459
|
+
Link: TitanLayoutSidebarLink,
|
|
460
|
+
Trigger: TitanLayoutSidebarTrigger,
|
|
272
461
|
});
|
package/src/test/data.tsx
CHANGED
|
@@ -66,7 +66,6 @@ export const NavLinkMock = forwardRef<any, NavLinkComponentProps>(
|
|
|
66
66
|
{...rest}
|
|
67
67
|
onClick={e => {
|
|
68
68
|
e.preventDefault();
|
|
69
|
-
e.stopPropagation();
|
|
70
69
|
|
|
71
70
|
if (!to.startsWith('http')) {
|
|
72
71
|
history.replace(to);
|
|
@@ -82,10 +81,10 @@ export const NavLinkMock = forwardRef<any, NavLinkComponentProps>(
|
|
|
82
81
|
}
|
|
83
82
|
);
|
|
84
83
|
|
|
85
|
-
export const LocationInfo = () => {
|
|
84
|
+
export const LocationInfo: FC<{ className?: string }> = ({ className }) => {
|
|
86
85
|
const location = useLocation();
|
|
87
86
|
|
|
88
|
-
return <BodyText>current location - {location.pathname}</BodyText>;
|
|
87
|
+
return <BodyText className={className}>current location - {location.pathname}</BodyText>;
|
|
89
88
|
};
|
|
90
89
|
|
|
91
90
|
const LocationProvider: FC<{ children: any }> = ({ children }) => {
|
|
@@ -4,6 +4,7 @@ import { useMemo } from 'react';
|
|
|
4
4
|
export interface TitanBreakpoint {
|
|
5
5
|
name: BreakpointReturnProps['name'];
|
|
6
6
|
isMobile: boolean;
|
|
7
|
+
width: number;
|
|
7
8
|
}
|
|
8
9
|
|
|
9
10
|
export const useTitanBreakpoint = (): TitanBreakpoint => {
|
|
@@ -12,7 +13,8 @@ export const useTitanBreakpoint = (): TitanBreakpoint => {
|
|
|
12
13
|
return useMemo(
|
|
13
14
|
() => ({
|
|
14
15
|
name: breakpoint?.name ?? 'xl',
|
|
15
|
-
isMobile: breakpoint ? breakpoint.innerWidth
|
|
16
|
+
isMobile: breakpoint ? breakpoint.innerWidth < 768 : false,
|
|
17
|
+
width: breakpoint?.innerWidth ?? 0,
|
|
16
18
|
}),
|
|
17
19
|
[breakpoint]
|
|
18
20
|
);
|