@servicetitan/navigation 13.1.4 → 13.2.0-canary.270.b4a066f.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/titan-layout/layout-context.js +1 -0
- package/dist/components/titan-layout/layout-context.js.map +1 -1
- package/dist/components/titan-layout/layout-header.module.less +1 -1
- package/dist/components/titan-layout/layout-sidebar.d.ts +1 -0
- package/dist/components/titan-layout/layout-sidebar.d.ts.map +1 -1
- package/dist/components/titan-layout/layout-sidebar.js +5 -4
- package/dist/components/titan-layout/layout-sidebar.js.map +1 -1
- package/dist/components/titan-layout/titan-layout-default.stories.d.ts.map +1 -1
- package/dist/components/titan-layout/titan-layout.d.ts +3 -1
- package/dist/components/titan-layout/titan-layout.d.ts.map +1 -1
- package/dist/components/titan-layout/titan-layout.js +66 -28
- package/dist/components/titan-layout/titan-layout.js.map +1 -1
- package/dist/components/titan-layout/titan-layout.module.less +24 -25
- package/dist/components/titan-layout/titan-layout.module.less.d.ts +1 -3
- package/dist/test/data.d.ts +3 -0
- package/dist/test/data.d.ts.map +1 -1
- package/dist/test/data.js +40 -1
- package/dist/test/data.js.map +1 -1
- package/dist/test/titan-layout.d.ts +1 -0
- package/dist/test/titan-layout.d.ts.map +1 -1
- package/dist/test/titan-layout.js +1 -0
- package/dist/test/titan-layout.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 +2 -0
- package/dist/utils/use-breakpoint.js.map +1 -1
- package/package.json +3 -3
- package/src/components/titan-layout/layout-context.tsx +1 -1
- package/src/components/titan-layout/layout-header.module.less +1 -1
- package/src/components/titan-layout/layout-sidebar.tsx +13 -2
- package/src/components/titan-layout/titan-layout-default.stories.tsx +19 -21
- package/src/components/titan-layout/titan-layout.module.less +24 -25
- package/src/components/titan-layout/titan-layout.module.less.d.ts +1 -3
- package/src/components/titan-layout/titan-layout.tsx +118 -64
- package/src/test/data.tsx +37 -1
- package/src/test/titan-layout.tsx +2 -0
- package/src/utils/use-breakpoint.ts +4 -0
|
@@ -9,8 +9,7 @@
|
|
|
9
9
|
@bg-color-active: rgba(120, 187, 250, 0.2);
|
|
10
10
|
|
|
11
11
|
.layout-anvil1 {
|
|
12
|
-
height:
|
|
13
|
-
margin-top: var(--nav-offset-top);
|
|
12
|
+
height: 100vh;
|
|
14
13
|
|
|
15
14
|
display: flex;
|
|
16
15
|
flex-direction: column;
|
|
@@ -30,20 +29,12 @@
|
|
|
30
29
|
}
|
|
31
30
|
}
|
|
32
31
|
|
|
33
|
-
.layout-anvil2 {
|
|
34
|
-
.content-header {
|
|
35
|
-
position: sticky;
|
|
36
|
-
top: var(--nav-offset-top);
|
|
37
|
-
z-index: 989;
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
32
|
.layout-desktop {
|
|
42
33
|
padding-left: var(--nav-offset-left);
|
|
43
34
|
|
|
44
35
|
.side {
|
|
45
36
|
position: fixed;
|
|
46
|
-
top: var(--nav-
|
|
37
|
+
top: var(--nav-top-height);
|
|
47
38
|
bottom: 0;
|
|
48
39
|
left: 0;
|
|
49
40
|
right: 0;
|
|
@@ -52,31 +43,20 @@
|
|
|
52
43
|
}
|
|
53
44
|
|
|
54
45
|
.layout-legacy,
|
|
55
|
-
.layout-anvil2
|
|
46
|
+
.layout-anvil2,
|
|
47
|
+
.layout-anvil1 {
|
|
56
48
|
.top-placeholder {
|
|
57
49
|
height: var(--nav-offset-top);
|
|
58
50
|
}
|
|
59
51
|
}
|
|
60
52
|
|
|
61
53
|
.layout {
|
|
54
|
+
--nav-top-height: 0px;
|
|
62
55
|
--nav-offset-top: 0px;
|
|
63
56
|
--nav-offset-left: 0px;
|
|
64
57
|
--content-offset-top: var(--nav-offset-top);
|
|
65
58
|
--offset: var(--content-offset-top);
|
|
66
59
|
|
|
67
|
-
&.layout-desktop.layout-top-light {
|
|
68
|
-
--nav-offset-top: 48px;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
&.layout-desktop.layout-top-nav {
|
|
72
|
-
--nav-offset-top: 80px;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
&.layout-mobile.layout-top-light,
|
|
76
|
-
&.layout-mobile.layout-top-nav {
|
|
77
|
-
--nav-offset-top: 72px;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
60
|
&.layout-desktop.layout-nav-slim {
|
|
81
61
|
--nav-offset-left: 64px;
|
|
82
62
|
}
|
|
@@ -98,10 +78,29 @@
|
|
|
98
78
|
left: 0;
|
|
99
79
|
right: 0;
|
|
100
80
|
}
|
|
81
|
+
|
|
82
|
+
.content-fixed-header {
|
|
83
|
+
position: fixed;
|
|
84
|
+
top: var(--nav-top-height);
|
|
85
|
+
left: var(--nav-offset-left);
|
|
86
|
+
right: 0;
|
|
87
|
+
z-index: 801;
|
|
88
|
+
}
|
|
101
89
|
}
|
|
102
90
|
|
|
91
|
+
/* anvil2 doesn't support scrollable header s above the Page content */
|
|
92
|
+
/* so making them sticky as well */
|
|
93
|
+
.layout-anvil2 {
|
|
94
|
+
.content-header {
|
|
95
|
+
position: sticky;
|
|
96
|
+
top: var(--nav-offset-top);
|
|
97
|
+
z-index: 800;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
103
100
|
@media print {
|
|
104
101
|
.layout {
|
|
102
|
+
--nav-top-height: 0px !important;
|
|
103
|
+
--nav-offset-top: 0px !important;
|
|
105
104
|
--nav-offset-left: 0px !important;
|
|
106
105
|
--nav-offset-right: 0px !important;
|
|
107
106
|
|
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
export const __esModule: true;
|
|
2
2
|
export const content: string;
|
|
3
|
+
export const contentFixedHeader: string;
|
|
3
4
|
export const contentHeader: string;
|
|
4
5
|
export const layout: string;
|
|
5
6
|
export const layoutAnvil1: string;
|
|
6
7
|
export const layoutAnvil2: string;
|
|
7
8
|
export const layoutDesktop: string;
|
|
8
9
|
export const layoutLegacy: string;
|
|
9
|
-
export const layoutMobile: string;
|
|
10
10
|
export const layoutNavSlim: string;
|
|
11
11
|
export const layoutNavWide: string;
|
|
12
|
-
export const layoutTopLight: string;
|
|
13
|
-
export const layoutTopNav: string;
|
|
14
12
|
export const side: string;
|
|
15
13
|
export const top: string;
|
|
16
14
|
export const topPlaceholder: string;
|
|
@@ -65,6 +65,9 @@ export type TitanLayoutProps = Omit<ComponentPropsWithoutRef<'div'>, 'children'
|
|
|
65
65
|
/** content header content */
|
|
66
66
|
header?: ReactElement;
|
|
67
67
|
|
|
68
|
+
/** content header fixed (stocky to top) content */
|
|
69
|
+
headerFixed?: ReactElement;
|
|
70
|
+
|
|
68
71
|
/** layout header content (center) */
|
|
69
72
|
top?: ReactElement;
|
|
70
73
|
|
|
@@ -125,6 +128,43 @@ const useAppearance = (appearance: TitanLayoutProps['appearance']) =>
|
|
|
125
128
|
};
|
|
126
129
|
}, [appearance]);
|
|
127
130
|
|
|
131
|
+
enum TopNavVariant {
|
|
132
|
+
None = 'none',
|
|
133
|
+
Tiny = 'tiny',
|
|
134
|
+
Dark = 'dark',
|
|
135
|
+
DarkStacked = 'stacked',
|
|
136
|
+
Mobile = 'mobile',
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const topBarHeights: Record<TopNavVariant, number> = {
|
|
140
|
+
[TopNavVariant.None]: 0,
|
|
141
|
+
[TopNavVariant.Tiny]: 48,
|
|
142
|
+
[TopNavVariant.Dark]: 48,
|
|
143
|
+
[TopNavVariant.DarkStacked]: 80,
|
|
144
|
+
[TopNavVariant.Mobile]: 72,
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
const useTopNavVariant = (
|
|
148
|
+
hasTopBar: boolean,
|
|
149
|
+
isMobile: boolean,
|
|
150
|
+
isLeftNav: boolean,
|
|
151
|
+
hasTopCenterContent: boolean
|
|
152
|
+
) => {
|
|
153
|
+
if (!hasTopBar) {
|
|
154
|
+
return TopNavVariant.None;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
if (isMobile) {
|
|
158
|
+
return TopNavVariant.Mobile;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
if (isLeftNav) {
|
|
162
|
+
return TopNavVariant.Tiny;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
return hasTopCenterContent ? TopNavVariant.DarkStacked : TopNavVariant.Dark;
|
|
166
|
+
};
|
|
167
|
+
|
|
128
168
|
function TitanLayoutComponent({
|
|
129
169
|
appearance = 'anvil2',
|
|
130
170
|
navVariant = 'left',
|
|
@@ -133,6 +173,7 @@ function TitanLayoutComponent({
|
|
|
133
173
|
contentOnly,
|
|
134
174
|
navigationComponent,
|
|
135
175
|
header,
|
|
176
|
+
headerFixed,
|
|
136
177
|
top,
|
|
137
178
|
profile,
|
|
138
179
|
state,
|
|
@@ -159,19 +200,15 @@ function TitanLayoutComponent({
|
|
|
159
200
|
const view = useAppearance(appearance);
|
|
160
201
|
const [mobileDrawerOpened, setMobileDrawerOpened] = useState(false);
|
|
161
202
|
const { hasNotifications, NotificationsContextProvider } = useNotificationsState();
|
|
162
|
-
const [
|
|
163
|
-
const
|
|
164
|
-
setOffsetTopStyles({
|
|
165
|
-
'--content-offset-top': `calc(var(--nav-offset-top) + ${offset}px)`,
|
|
166
|
-
});
|
|
167
|
-
}, []);
|
|
203
|
+
const [headerHeight, setHeaderHeight] = useState(0);
|
|
204
|
+
const [headerFixedHeight, setHeaderFixedHeight] = useState(0);
|
|
168
205
|
|
|
169
206
|
const isMobile = breakpoint.isMobile;
|
|
170
207
|
const hasSideBar =
|
|
171
208
|
!contentOnly &&
|
|
172
209
|
(navVariant === 'left' || (navVariant === 'top' && isMobile)) &&
|
|
173
210
|
(!!navigationMainItems?.length || !!sideTop?.length);
|
|
174
|
-
const
|
|
211
|
+
const topBarVariant = useTopNavVariant(!contentOnly, isMobile, navVariant === 'left', !!top);
|
|
175
212
|
|
|
176
213
|
useEffect(() => {
|
|
177
214
|
if (view.isAnvil1) {
|
|
@@ -257,11 +294,15 @@ function TitanLayoutComponent({
|
|
|
257
294
|
}
|
|
258
295
|
}, [view, minContentWidth, breakpoint.width]);
|
|
259
296
|
|
|
260
|
-
const
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
297
|
+
const layoutStyles = useMemo(() => {
|
|
298
|
+
const topHeight = topBarHeights[topBarVariant] ?? 0;
|
|
299
|
+
|
|
300
|
+
return {
|
|
301
|
+
'--nav-top-height': `${topHeight}px`,
|
|
302
|
+
'--nav-offset-top': `${topHeight + headerFixedHeight}px`,
|
|
303
|
+
'--content-offset-top': `${topHeight + headerFixedHeight + headerHeight}px`,
|
|
304
|
+
} as CSSProperties;
|
|
305
|
+
}, [topBarVariant, headerFixedHeight, headerHeight]);
|
|
265
306
|
|
|
266
307
|
const layoutClass = view.isLegacy
|
|
267
308
|
? Styles.layoutLegacy
|
|
@@ -270,7 +311,7 @@ function TitanLayoutComponent({
|
|
|
270
311
|
: Styles.layoutAnvil2;
|
|
271
312
|
|
|
272
313
|
const burgerProps: LayoutHeaderProps['burger'] = useMemo(() => {
|
|
273
|
-
if (
|
|
314
|
+
if (topBarVariant === TopNavVariant.None) {
|
|
274
315
|
return undefined;
|
|
275
316
|
}
|
|
276
317
|
|
|
@@ -293,7 +334,7 @@ function TitanLayoutComponent({
|
|
|
293
334
|
return undefined;
|
|
294
335
|
}, [
|
|
295
336
|
isMobile,
|
|
296
|
-
|
|
337
|
+
topBarVariant,
|
|
297
338
|
navVariant,
|
|
298
339
|
state?.navCollapsed,
|
|
299
340
|
onBurgerClick,
|
|
@@ -308,63 +349,59 @@ function TitanLayoutComponent({
|
|
|
308
349
|
id={id}
|
|
309
350
|
className={classNames(
|
|
310
351
|
Styles.layout,
|
|
311
|
-
isMobile
|
|
312
|
-
hasTopBar &&
|
|
313
|
-
(navVariant === 'left' || !top
|
|
314
|
-
? Styles.layoutTopLight
|
|
315
|
-
: Styles.layoutTopNav),
|
|
352
|
+
!isMobile && Styles.layoutDesktop,
|
|
316
353
|
{
|
|
317
354
|
[Styles.layoutNavSlim]: !isMobile && hasSideBar && state?.navCollapsed,
|
|
318
355
|
[Styles.layoutNavWide]: !isMobile && hasSideBar && !state?.navCollapsed,
|
|
319
356
|
},
|
|
320
357
|
layoutClass
|
|
321
358
|
)}
|
|
322
|
-
style={
|
|
359
|
+
style={layoutStyles}
|
|
323
360
|
>
|
|
324
|
-
|
|
325
|
-
{
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
))}
|
|
361
|
+
<div className={Styles.topPlaceholder} />
|
|
362
|
+
{topBarVariant === TopNavVariant.Tiny ? (
|
|
363
|
+
<LayoutHeader
|
|
364
|
+
className={Styles.top}
|
|
365
|
+
variant="light"
|
|
366
|
+
logo={logo}
|
|
367
|
+
profile={isMobile ? undefined : profile}
|
|
368
|
+
center={top}
|
|
369
|
+
rightText={isMobile ? undefined : extraText}
|
|
370
|
+
right={
|
|
371
|
+
<Fragment>
|
|
372
|
+
{extraLinksTop}
|
|
373
|
+
{!isMobile && extraLinks}
|
|
374
|
+
</Fragment>
|
|
375
|
+
}
|
|
376
|
+
isMobile={isMobile}
|
|
377
|
+
burger={burgerProps}
|
|
378
|
+
/>
|
|
379
|
+
) : topBarVariant !== TopNavVariant.None ? (
|
|
380
|
+
<LayoutHeaderDark
|
|
381
|
+
className={Styles.top}
|
|
382
|
+
logo={logo}
|
|
383
|
+
profile={isMobile ? undefined : profile}
|
|
384
|
+
center={top}
|
|
385
|
+
rightText={isMobile ? undefined : extraText}
|
|
386
|
+
right={
|
|
387
|
+
<Fragment>
|
|
388
|
+
{extraLinksTop}
|
|
389
|
+
{!isMobile && extraLinks}
|
|
390
|
+
</Fragment>
|
|
391
|
+
}
|
|
392
|
+
isMobile={isMobile}
|
|
393
|
+
burger={burgerProps}
|
|
394
|
+
navigationMainItems={navigationMainItems}
|
|
395
|
+
navigationOverflowItems={navigationOverflowItems}
|
|
396
|
+
/>
|
|
397
|
+
) : null}
|
|
362
398
|
|
|
363
399
|
{hasSideBar && (
|
|
364
400
|
<NotificationsContextProvider>
|
|
365
401
|
<LayoutSidebar
|
|
366
402
|
className={Styles.side}
|
|
367
403
|
mobile={breakpoint.isMobile}
|
|
404
|
+
touchDevice={breakpoint.isTouchDevice}
|
|
368
405
|
barExpanded={!state?.navCollapsed}
|
|
369
406
|
onBarExpandChange={onBarExpandChange}
|
|
370
407
|
submenusExpanded={state?.submenusExpanded}
|
|
@@ -397,11 +434,26 @@ function TitanLayoutComponent({
|
|
|
397
434
|
</NotificationsContextProvider>
|
|
398
435
|
)}
|
|
399
436
|
|
|
400
|
-
{
|
|
401
|
-
<TitanLayoutHeaderObserved
|
|
402
|
-
{
|
|
437
|
+
{!!headerFixed && (
|
|
438
|
+
<TitanLayoutHeaderObserved
|
|
439
|
+
heightChange={setHeaderFixedHeight}
|
|
440
|
+
className={Styles.contentFixedHeader}
|
|
441
|
+
data-cy="layout-content-fixed-header"
|
|
442
|
+
>
|
|
443
|
+
{headerFixed}
|
|
403
444
|
</TitanLayoutHeaderObserved>
|
|
404
445
|
)}
|
|
446
|
+
|
|
447
|
+
{!!header && view.isSequent && (
|
|
448
|
+
<div className={Styles.contentHeader}>
|
|
449
|
+
<TitanLayoutHeaderObserved
|
|
450
|
+
heightChange={setHeaderHeight}
|
|
451
|
+
data-cy="layout-content-header"
|
|
452
|
+
>
|
|
453
|
+
{header}
|
|
454
|
+
</TitanLayoutHeaderObserved>
|
|
455
|
+
</div>
|
|
456
|
+
)}
|
|
405
457
|
{view.isAnvil1 ? (
|
|
406
458
|
<LayoutContentAnvil1 header={header} minWidth={limitContentWidth}>
|
|
407
459
|
{children}
|
|
@@ -420,9 +472,11 @@ function TitanLayoutComponent({
|
|
|
420
472
|
}
|
|
421
473
|
|
|
422
474
|
const TitanLayoutHeaderObserved: FC<{
|
|
423
|
-
children: ReactNode;
|
|
475
|
+
'children': ReactNode;
|
|
476
|
+
'className'?: string;
|
|
477
|
+
'data-cy'?: string;
|
|
424
478
|
heightChange?(value: number): void;
|
|
425
|
-
}> = ({ children, heightChange }) => {
|
|
479
|
+
}> = ({ children, heightChange, ...rest }) => {
|
|
426
480
|
const ref = useRef<HTMLDivElement>(null);
|
|
427
481
|
|
|
428
482
|
useEffect(() => {
|
|
@@ -448,7 +502,7 @@ const TitanLayoutHeaderObserved: FC<{
|
|
|
448
502
|
};
|
|
449
503
|
}, [heightChange]);
|
|
450
504
|
return (
|
|
451
|
-
<div
|
|
505
|
+
<div {...rest} ref={ref}>
|
|
452
506
|
{children}
|
|
453
507
|
</div>
|
|
454
508
|
);
|
package/src/test/data.tsx
CHANGED
|
@@ -33,7 +33,7 @@ import SvgTasks from '@servicetitan/anvil2/assets/icons/st/gnav_tasks_inactive.s
|
|
|
33
33
|
import { BodyText, Popover } from '@servicetitan/design-system';
|
|
34
34
|
|
|
35
35
|
import classNames from 'classnames';
|
|
36
|
-
import { FC, Fragment, forwardRef, useState } from 'react';
|
|
36
|
+
import { FC, Fragment, forwardRef, useLayoutEffect, useRef, useState } from 'react';
|
|
37
37
|
// needed only for storybook and added in root dependencies
|
|
38
38
|
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
39
39
|
import { MemoryRouter, Redirect, Switch, useHistory, useLocation } from 'react-router-dom';
|
|
@@ -78,6 +78,42 @@ export const LocationInfo: FC<{ className?: string }> = ({ className }) => {
|
|
|
78
78
|
return <BodyText className={className}>current location - {location.pathname}</BodyText>;
|
|
79
79
|
};
|
|
80
80
|
|
|
81
|
+
export const CssInfo: FC<{ className?: string }> = ({ className }) => {
|
|
82
|
+
const ref = useRef<HTMLDivElement>(null);
|
|
83
|
+
const [info, setInfo] = useState({ 'offset': '', 'nav-offset-top': '' });
|
|
84
|
+
|
|
85
|
+
useLayoutEffect(() => {
|
|
86
|
+
const interval = setInterval(() => {
|
|
87
|
+
const el = ref.current;
|
|
88
|
+
|
|
89
|
+
if (!el) {
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// eslint-disable-next-line no-restricted-globals
|
|
94
|
+
const st = getComputedStyle(el);
|
|
95
|
+
|
|
96
|
+
setInfo({
|
|
97
|
+
'offset': st.getPropertyValue('--offset'),
|
|
98
|
+
'nav-offset-top': st.getPropertyValue('--nav-offset-top'),
|
|
99
|
+
});
|
|
100
|
+
}, 100);
|
|
101
|
+
|
|
102
|
+
return () => clearInterval(interval);
|
|
103
|
+
}, []);
|
|
104
|
+
|
|
105
|
+
return (
|
|
106
|
+
<div className={className} ref={ref}>
|
|
107
|
+
<p>CSS variables:</p>
|
|
108
|
+
{Object.entries(info).map(([key, value]) => (
|
|
109
|
+
<p key={key}>
|
|
110
|
+
--{key} - {value}
|
|
111
|
+
</p>
|
|
112
|
+
))}
|
|
113
|
+
</div>
|
|
114
|
+
);
|
|
115
|
+
};
|
|
116
|
+
|
|
81
117
|
export const withMemoryRouter = (Story: any) => (
|
|
82
118
|
<MemoryRouter>
|
|
83
119
|
<Story />
|
|
@@ -3,6 +3,7 @@ import { TitanLayoutProps } from '../components/titan-layout';
|
|
|
3
3
|
|
|
4
4
|
export interface LayoutContentArgs {
|
|
5
5
|
header: boolean;
|
|
6
|
+
headerFixed: boolean;
|
|
6
7
|
sideTop: boolean;
|
|
7
8
|
extraText: boolean;
|
|
8
9
|
search: boolean;
|
|
@@ -15,6 +16,7 @@ export interface LayoutContentArgs {
|
|
|
15
16
|
|
|
16
17
|
export const getDefaultArgs = (): LayoutContentArgs => ({
|
|
17
18
|
header: true,
|
|
19
|
+
headerFixed: true,
|
|
18
20
|
sideTop: true,
|
|
19
21
|
extraText: true,
|
|
20
22
|
search: true,
|
|
@@ -4,9 +4,12 @@ import { useMemo } from 'react';
|
|
|
4
4
|
export interface TitanBreakpoint {
|
|
5
5
|
name: BreakpointReturnProps['name'];
|
|
6
6
|
isMobile: boolean;
|
|
7
|
+
isTouchDevice: boolean;
|
|
7
8
|
width: number;
|
|
8
9
|
}
|
|
9
10
|
|
|
11
|
+
const isTouchDevice = () => window.matchMedia('(any-pointer: coarse)').matches;
|
|
12
|
+
|
|
10
13
|
export const useTitanBreakpoint = (): TitanBreakpoint => {
|
|
11
14
|
const breakpoint = useBreakpoint();
|
|
12
15
|
|
|
@@ -14,6 +17,7 @@ export const useTitanBreakpoint = (): TitanBreakpoint => {
|
|
|
14
17
|
() => ({
|
|
15
18
|
name: breakpoint?.name ?? 'xl',
|
|
16
19
|
isMobile: breakpoint ? breakpoint.innerWidth < 768 : false,
|
|
20
|
+
isTouchDevice: isTouchDevice(),
|
|
17
21
|
width: breakpoint?.innerWidth ?? 0,
|
|
18
22
|
}),
|
|
19
23
|
[breakpoint]
|