@servicetitan/navigation 13.1.3 → 13.2.0-canary.270.41c771f.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.
@@ -24,7 +24,7 @@
24
24
  .header {
25
25
  --nav-top-content-height: 32px;
26
26
 
27
- height: var(--nav-offset-top);
27
+ height: var(--nav-top-height);
28
28
  display: flex;
29
29
  justify-content: space-between;
30
30
 
@@ -86,8 +86,8 @@
86
86
 
87
87
  .nav-drawer-backdrop {
88
88
  position: fixed;
89
- height: 100vh;
90
- width: 100vw;
89
+ height: 100%;
90
+ width: 100%;
91
91
  top: 0;
92
92
  left: 0;
93
93
  z-index: 991;
@@ -1 +1 @@
1
- {"version":3,"file":"titan-layout-default.stories.d.ts","sourceRoot":"","sources":["../../../src/components/titan-layout/titan-layout-default.stories.tsx"],"names":[],"mappings":"AAkBA,OAAO,EACH,iBAAiB,EAIpB,MAAM,yBAAyB,CAAC;;;;;;;;AASjC,wBAWE;AAgSF,eAAO,MAAM,aAAa,GAAI,MAAM,iBAAiB,4CASpD,CAAC;AAEF,eAAO,MAAM,aAAa,GAAI,MAAM,iBAAiB,4CAMpD,CAAC;AAEF,eAAO,MAAM,aAAa,GAAI,MAAM,iBAAiB,4CAQpD,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAI,MAAM,iBAAiB,4CAcvD,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,MAAM,iBAAiB,4CAyBrD,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAI,MAAM,iBAAiB,4CA0BxD,CAAC;AAEF,eAAO,MAAM,sBAAsB,GAAI,MAAM,iBAAiB,4CA0B7D,CAAC"}
1
+ {"version":3,"file":"titan-layout-default.stories.d.ts","sourceRoot":"","sources":["../../../src/components/titan-layout/titan-layout-default.stories.tsx"],"names":[],"mappings":"AAkBA,OAAO,EACH,iBAAiB,EAIpB,MAAM,yBAAyB,CAAC;;;;;;;;AASjC,wBAWE;AAmSF,eAAO,MAAM,aAAa,GAAI,MAAM,iBAAiB,4CASpD,CAAC;AAEF,eAAO,MAAM,aAAa,GAAI,MAAM,iBAAiB,4CAMpD,CAAC;AAEF,eAAO,MAAM,aAAa,GAAI,MAAM,iBAAiB,4CAQpD,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAI,MAAM,iBAAiB,4CAcvD,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,MAAM,iBAAiB,4CAyBrD,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAI,MAAM,iBAAiB,4CA0BxD,CAAC;AAEF,eAAO,MAAM,sBAAsB,GAAI,MAAM,iBAAiB,4CA0B7D,CAAC"}
@@ -26,6 +26,8 @@ export type TitanLayoutProps = Omit<ComponentPropsWithoutRef<'div'>, 'children'
26
26
  onStateChange?: (state: TitanLayoutState) => void;
27
27
  /** content header content */
28
28
  header?: ReactElement;
29
+ /** content header fixed (stocky to top) content */
30
+ headerFixed?: ReactElement;
29
31
  /** layout header content (center) */
30
32
  top?: ReactElement;
31
33
  /** top links for side navigation */
@@ -56,7 +58,7 @@ export type TitanLayoutProps = Omit<ComponentPropsWithoutRef<'div'>, 'children'
56
58
  */
57
59
  minContentWidth?: number;
58
60
  };
59
- declare function TitanLayoutComponent({ appearance, navVariant, id, children, contentOnly, navigationComponent, header, top, profile, state, logo, onStateChange, navigationMainItems, navigationOverflowItems, extraLinks, extraLinksTop, extraText, minContentWidth, sideTop, }: TitanLayoutProps): import("react/jsx-runtime").JSX.Element;
61
+ declare function TitanLayoutComponent({ appearance, navVariant, id, children, contentOnly, navigationComponent, header, headerFixed, top, profile, state, logo, onStateChange, navigationMainItems, navigationOverflowItems, extraLinks, extraLinksTop, extraText, minContentWidth, sideTop, }: TitanLayoutProps): import("react/jsx-runtime").JSX.Element;
60
62
  export declare const TitanLayout: typeof TitanLayoutComponent & {
61
63
  Link: FC<import("./interface").TitanLayoutLinkProps>;
62
64
  Trigger: FC<import("./interface").TitanLayoutTriggerProps>;
@@ -1 +1 @@
1
- {"version":3,"file":"titan-layout.d.ts","sourceRoot":"","sources":["../../../src/components/titan-layout/titan-layout.tsx"],"names":[],"mappings":"AACA,OAAO,EAEH,wBAAwB,EACxB,EAAE,EAGF,YAAY,EACZ,SAAS,EAMZ,MAAM,OAAO,CAAC;AACf,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAA2B,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AAEhG,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAS/C,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAOrD,MAAM,MAAM,gBAAgB,GAAG,IAAI,CAAC,wBAAwB,CAAC,KAAK,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,GAAG;IACzF,wBAAwB;IACxB,UAAU,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;IAE5C,kDAAkD;IAClD,UAAU,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IAE5B,uBAAuB;IACvB,QAAQ,CAAC,EAAE,SAAS,CAAC;IAErB,kDAAkD;IAClD,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB,oCAAoC;IACpC,mBAAmB,CAAC,EAAE,EAAE,CAAC,qBAAqB,CAAC,CAAC;IAEhD,qCAAqC;IACrC,mBAAmB,CAAC,EAAE,kBAAkB,EAAE,CAAC;IAE3C,sEAAsE;IACtE,uBAAuB,CAAC,EAAE,kBAAkB,EAAE,CAAC;IAE/C,iBAAiB;IACjB,IAAI,CAAC,EAAE,oBAAoB,CAAC;IAE5B,mBAAmB;IACnB,KAAK,CAAC,EAAE,gBAAgB,CAAC;IACzB,kCAAkC;IAClC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAElD,6BAA6B;IAC7B,MAAM,CAAC,EAAE,YAAY,CAAC;IAEtB,qCAAqC;IACrC,GAAG,CAAC,EAAE,YAAY,CAAC;IAEnB,oCAAoC;IACpC,OAAO,CAAC,EAAE,YAAY,EAAE,CAAC;IAEzB;;;OAGG;IACH,OAAO,CAAC,EAAE,YAAY,CAAC;IAEvB;;;OAGG;IACH,UAAU,CAAC,EAAE,YAAY,CAAC;IAE1B;;;OAGG;IACH,aAAa,CAAC,EAAE,YAAY,CAAC;IAE7B;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAyBF,iBAAS,oBAAoB,CAAC,EAC1B,UAAqB,EACrB,UAAmB,EACnB,EAAE,EACF,QAAQ,EACR,WAAW,EACX,mBAAmB,EACnB,MAAM,EACN,GAAG,EACH,OAAO,EACP,KAAK,EACL,IAAI,EACJ,aAAa,EACb,mBAAmB,EACnB,uBAAuB,EACvB,UAAU,EACV,aAAa,EACb,SAAS,EACT,eAAe,EACf,OAAO,GACV,EAAE,gBAAgB,2CAgRlB;AAyFD,eAAO,MAAM,WAAW;;;CAGtB,CAAC"}
1
+ {"version":3,"file":"titan-layout.d.ts","sourceRoot":"","sources":["../../../src/components/titan-layout/titan-layout.tsx"],"names":[],"mappings":"AACA,OAAO,EAEH,wBAAwB,EACxB,EAAE,EAGF,YAAY,EACZ,SAAS,EAMZ,MAAM,OAAO,CAAC;AACf,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAA2B,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AAEhG,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAS/C,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAOrD,MAAM,MAAM,gBAAgB,GAAG,IAAI,CAAC,wBAAwB,CAAC,KAAK,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,GAAG;IACzF,wBAAwB;IACxB,UAAU,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;IAE5C,kDAAkD;IAClD,UAAU,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IAE5B,uBAAuB;IACvB,QAAQ,CAAC,EAAE,SAAS,CAAC;IAErB,kDAAkD;IAClD,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB,oCAAoC;IACpC,mBAAmB,CAAC,EAAE,EAAE,CAAC,qBAAqB,CAAC,CAAC;IAEhD,qCAAqC;IACrC,mBAAmB,CAAC,EAAE,kBAAkB,EAAE,CAAC;IAE3C,sEAAsE;IACtE,uBAAuB,CAAC,EAAE,kBAAkB,EAAE,CAAC;IAE/C,iBAAiB;IACjB,IAAI,CAAC,EAAE,oBAAoB,CAAC;IAE5B,mBAAmB;IACnB,KAAK,CAAC,EAAE,gBAAgB,CAAC;IACzB,kCAAkC;IAClC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAElD,6BAA6B;IAC7B,MAAM,CAAC,EAAE,YAAY,CAAC;IAEtB,mDAAmD;IACnD,WAAW,CAAC,EAAE,YAAY,CAAC;IAE3B,qCAAqC;IACrC,GAAG,CAAC,EAAE,YAAY,CAAC;IAEnB,oCAAoC;IACpC,OAAO,CAAC,EAAE,YAAY,EAAE,CAAC;IAEzB;;;OAGG;IACH,OAAO,CAAC,EAAE,YAAY,CAAC;IAEvB;;;OAGG;IACH,UAAU,CAAC,EAAE,YAAY,CAAC;IAE1B;;;OAGG;IACH,aAAa,CAAC,EAAE,YAAY,CAAC;IAE7B;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AA8DF,iBAAS,oBAAoB,CAAC,EAC1B,UAAqB,EACrB,UAAmB,EACnB,EAAE,EACF,QAAQ,EACR,WAAW,EACX,mBAAmB,EACnB,MAAM,EACN,WAAW,EACX,GAAG,EACH,OAAO,EACP,KAAK,EACL,IAAI,EACJ,aAAa,EACb,mBAAmB,EACnB,uBAAuB,EACvB,UAAU,EACV,aAAa,EACb,SAAS,EACT,eAAe,EACf,OAAO,GACV,EAAE,gBAAgB,2CAqRlB;AA2FD,eAAO,MAAM,WAAW;;;CAGtB,CAAC"}
@@ -32,7 +32,34 @@ const useAppearance = (appearance)=>useMemo(()=>{
32
32
  }, [
33
33
  appearance
34
34
  ]);
35
- function TitanLayoutComponent({ appearance = 'anvil2', navVariant = 'left', id, children, contentOnly, navigationComponent, header, top, profile, state, logo, onStateChange, navigationMainItems, navigationOverflowItems, extraLinks, extraLinksTop, extraText, minContentWidth, sideTop }) {
35
+ var TopNavVariant = /*#__PURE__*/ function(TopNavVariant) {
36
+ TopNavVariant["None"] = "none";
37
+ TopNavVariant["Tiny"] = "tiny";
38
+ TopNavVariant["Dark"] = "dark";
39
+ TopNavVariant["DarkStacked"] = "stacked";
40
+ TopNavVariant["Mobile"] = "mobile";
41
+ return TopNavVariant;
42
+ }(TopNavVariant || {});
43
+ const topBarHeights = {
44
+ ["none"]: 0,
45
+ ["tiny"]: 48,
46
+ ["dark"]: 48,
47
+ ["stacked"]: 80,
48
+ ["mobile"]: 72
49
+ };
50
+ const useTopNavVariant = (hasTopBar, isMobile, isLeftNav, hasTopCenterContent)=>{
51
+ if (!hasTopBar) {
52
+ return "none";
53
+ }
54
+ if (isMobile) {
55
+ return "mobile";
56
+ }
57
+ if (isLeftNav) {
58
+ return "tiny";
59
+ }
60
+ return hasTopCenterContent ? "stacked" : "dark";
61
+ };
62
+ function TitanLayoutComponent({ appearance = 'anvil2', navVariant = 'left', id, children, contentOnly, navigationComponent, header, headerFixed, top, profile, state, logo, onStateChange, navigationMainItems, navigationOverflowItems, extraLinks, extraLinksTop, extraText, minContentWidth, sideTop }) {
36
63
  const breakpoint = useTitanBreakpoint();
37
64
  const context = useMemo(()=>({
38
65
  NavigationComponent: navigationComponent !== null && navigationComponent !== void 0 ? navigationComponent : DefaultNavLinkComponent,
@@ -46,15 +73,11 @@ function TitanLayoutComponent({ appearance = 'anvil2', navVariant = 'left', id,
46
73
  const view = useAppearance(appearance);
47
74
  const [mobileDrawerOpened, setMobileDrawerOpened] = useState(false);
48
75
  const { hasNotifications, NotificationsContextProvider } = useNotificationsState();
49
- const [offsetTopStyles, setOffsetTopStyles] = useState({});
50
- const updateIndicatorsHeight = useCallback((offset)=>{
51
- setOffsetTopStyles({
52
- '--content-offset-top': `calc(var(--nav-offset-top) + ${offset}px)`
53
- });
54
- }, []);
76
+ const [headerHeight] = useState(0);
77
+ const [headerFixedHeight, setHeaderFixedHeight] = useState(0);
55
78
  const isMobile = breakpoint.isMobile;
56
79
  const hasSideBar = !contentOnly && (navVariant === 'left' || navVariant === 'top' && isMobile) && (!!(navigationMainItems === null || navigationMainItems === void 0 ? void 0 : navigationMainItems.length) || !!(sideTop === null || sideTop === void 0 ? void 0 : sideTop.length));
57
- const hasTopBar = !contentOnly;
80
+ const topBarVariant = useTopNavVariant(!contentOnly, isMobile, navVariant === 'left', !!top);
58
81
  useEffect(()=>{
59
82
  if (view.isAnvil1) {
60
83
  const bodyClassName = 'of-hidden-i';
@@ -155,17 +178,22 @@ function TitanLayoutComponent({ appearance = 'anvil2', navVariant = 'left', id,
155
178
  minContentWidth,
156
179
  breakpoint.width
157
180
  ]);
158
- const contentStyles = useMemo(()=>{
159
- if (view.isAnvil2 || view.isLegacy) {
160
- return offsetTopStyles;
161
- }
181
+ const layoutStyles = useMemo(()=>{
182
+ var _topBarHeights_topBarVariant;
183
+ const topHeight = (_topBarHeights_topBarVariant = topBarHeights[topBarVariant]) !== null && _topBarHeights_topBarVariant !== void 0 ? _topBarHeights_topBarVariant : 0;
184
+ return {
185
+ '--nav-top-height': `${topHeight}px`,
186
+ '--nav-offset-top': `${topHeight + headerFixedHeight}px`,
187
+ '--content-offset-top': `${topHeight + headerFixedHeight + headerHeight}px`
188
+ };
162
189
  }, [
163
- view,
164
- offsetTopStyles
190
+ topBarVariant,
191
+ headerFixedHeight,
192
+ headerHeight
165
193
  ]);
166
194
  const layoutClass = view.isLegacy ? Styles.layoutLegacy : view.isAnvil1 ? Styles.layoutAnvil1 : Styles.layoutAnvil2;
167
195
  const burgerProps = useMemo(()=>{
168
- if (!hasTopBar) {
196
+ if (topBarVariant === "none") {
169
197
  return undefined;
170
198
  }
171
199
  if (isMobile) {
@@ -187,7 +215,7 @@ function TitanLayoutComponent({ appearance = 'anvil2', navVariant = 'left', id,
187
215
  return undefined;
188
216
  }, [
189
217
  isMobile,
190
- hasTopBar,
218
+ topBarVariant,
191
219
  navVariant,
192
220
  state === null || state === void 0 ? void 0 : state.navCollapsed,
193
221
  onBurgerClick,
@@ -200,16 +228,16 @@ function TitanLayoutComponent({ appearance = 'anvil2', navVariant = 'left', id,
200
228
  value: "unset",
201
229
  children: /*#__PURE__*/ _jsxs("div", {
202
230
  id: id,
203
- className: classNames(Styles.layout, isMobile ? Styles.layoutMobile : Styles.layoutDesktop, hasTopBar && (navVariant === 'left' || !top ? Styles.layoutTopLight : Styles.layoutTopNav), {
231
+ className: classNames(Styles.layout, !isMobile && Styles.layoutDesktop, {
204
232
  [Styles.layoutNavSlim]: !isMobile && hasSideBar && (state === null || state === void 0 ? void 0 : state.navCollapsed),
205
233
  [Styles.layoutNavWide]: !isMobile && hasSideBar && !(state === null || state === void 0 ? void 0 : state.navCollapsed)
206
234
  }, layoutClass),
207
- style: contentStyles,
235
+ style: layoutStyles,
208
236
  children: [
209
- view.isSequent && /*#__PURE__*/ _jsx("div", {
237
+ /*#__PURE__*/ _jsx("div", {
210
238
  className: Styles.topPlaceholder
211
239
  }),
212
- hasTopBar && (navVariant === 'left' ? /*#__PURE__*/ _jsx(LayoutHeader, {
240
+ topBarVariant === "tiny" ? /*#__PURE__*/ _jsx(LayoutHeader, {
213
241
  className: Styles.top,
214
242
  variant: "light",
215
243
  logo: logo,
@@ -224,7 +252,7 @@ function TitanLayoutComponent({ appearance = 'anvil2', navVariant = 'left', id,
224
252
  }),
225
253
  isMobile: isMobile,
226
254
  burger: burgerProps
227
- }) : /*#__PURE__*/ _jsx(LayoutHeaderDark, {
255
+ }) : topBarVariant !== "none" ? /*#__PURE__*/ _jsx(LayoutHeaderDark, {
228
256
  className: Styles.top,
229
257
  logo: logo,
230
258
  profile: isMobile ? undefined : profile,
@@ -240,7 +268,7 @@ function TitanLayoutComponent({ appearance = 'anvil2', navVariant = 'left', id,
240
268
  burger: burgerProps,
241
269
  navigationMainItems: navigationMainItems,
242
270
  navigationOverflowItems: navigationOverflowItems
243
- })),
271
+ }) : null,
244
272
  hasSideBar && /*#__PURE__*/ _jsx(NotificationsContextProvider, {
245
273
  children: /*#__PURE__*/ _jsx(LayoutSidebar, {
246
274
  className: Styles.side,
@@ -271,8 +299,15 @@ function TitanLayoutComponent({ appearance = 'anvil2', navVariant = 'left', id,
271
299
  }) : undefined
272
300
  })
273
301
  }),
274
- view.isSequent && /*#__PURE__*/ _jsx(TitanLayoutHeaderObserved, {
275
- heightChange: updateIndicatorsHeight,
302
+ !!headerFixed && /*#__PURE__*/ _jsx(TitanLayoutHeaderObserved, {
303
+ heightChange: setHeaderFixedHeight,
304
+ className: Styles.contentFixedHeader,
305
+ "data-cy": "layout-content-fixed-header",
306
+ children: headerFixed
307
+ }),
308
+ !!header && view.isSequent && /*#__PURE__*/ _jsx("div", {
309
+ className: Styles.contentHeader,
310
+ "data-cy": "layout-content-header",
276
311
  children: header
277
312
  }),
278
313
  view.isAnvil1 ? /*#__PURE__*/ _jsx(LayoutContentAnvil1, {
@@ -288,7 +323,7 @@ function TitanLayoutComponent({ appearance = 'anvil2', navVariant = 'left', id,
288
323
  })
289
324
  });
290
325
  }
291
- const TitanLayoutHeaderObserved = ({ children, heightChange })=>{
326
+ const TitanLayoutHeaderObserved = ({ children, heightChange, ...rest })=>{
292
327
  const ref = useRef(null);
293
328
  useEffect(()=>{
294
329
  if (ref.current) {
@@ -314,9 +349,8 @@ const TitanLayoutHeaderObserved = ({ children, heightChange })=>{
314
349
  heightChange
315
350
  ]);
316
351
  return /*#__PURE__*/ _jsx("div", {
352
+ ...rest,
317
353
  ref: ref,
318
- className: Styles.contentHeader,
319
- "data-cy": "layout-content-header",
320
354
  children: children
321
355
  });
322
356
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/titan-layout/titan-layout.tsx"],"sourcesContent":["import classNames from 'classnames';\nimport {\n CSSProperties,\n ComponentPropsWithoutRef,\n FC,\n Fragment,\n MouseEvent,\n ReactElement,\n ReactNode,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { NavigationItemData } from '../../utils/navigation';\nimport { DefaultNavLinkComponent, NavLinkComponentProps } from '../../utils/navigation-context';\nimport { useTitanBreakpoint } from '../../utils/use-breakpoint';\nimport { TitanLayoutState } from './interface';\nimport {\n LayoutContext,\n LayoutPlacementContext,\n TitanLayoutContextType,\n TitanLayoutSidebarContextType,\n} from './layout-context';\nimport { LayoutHeader, LayoutHeaderProps } from './layout-header';\nimport { LayoutHeaderDark } from './layout-header-dark';\nimport { TitanLayoutLogoProps } from './layout-logo';\nimport { LayoutSidebar } from './layout-sidebar';\nimport { InternalSideNavigationTrigger } from './layout-sidebar-links-internal';\nimport { useNotificationsState } from './notifications-context';\nimport { TitanLayoutLink, TitanLayoutTrigger } from './titan-layout-links';\nimport * as Styles from './titan-layout.module.less';\n\nexport type TitanLayoutProps = Omit<ComponentPropsWithoutRef<'div'>, 'children' | 'style'> & {\n /** layout appearance */\n appearance?: 'legacy' | 'anvil1' | 'anvil2';\n\n /** layout navigation variant (left by default) */\n navVariant?: 'left' | 'top';\n\n /** layout's content */\n children?: ReactNode;\n\n /** show only content without side and top bars */\n contentOnly?: boolean;\n\n /** component used for navigation */\n navigationComponent?: FC<NavLinkComponentProps>;\n\n /** data for main navigation links */\n navigationMainItems?: NavigationItemData[];\n\n /** data for overflow navigation links (used only with top variant) */\n navigationOverflowItems?: NavigationItemData[];\n\n /** logo props */\n logo?: TitanLayoutLogoProps;\n\n /** layout state */\n state?: TitanLayoutState;\n /** layout state change handler */\n onStateChange?: (state: TitanLayoutState) => void;\n\n /** content header content */\n header?: ReactElement;\n\n /** layout header content (center) */\n top?: ReactElement;\n\n /** top links for side navigation */\n sideTop?: ReactElement[];\n\n /**\n * profile element for layout\n * @see ProfileDropdown\n */\n profile?: ReactElement;\n\n /**\n * extra links for layout header\n * shown in side nav footer on mobile\n */\n extraLinks?: ReactElement;\n\n /**\n * fixed extra links for layout header\n * shown in header on mobile as well\n */\n extraLinksTop?: ReactElement;\n\n /**\n * text shown in layout's header\n * shown in side nav footer on mobile\n */\n extraText?: string;\n\n /**\n * minimal width set for content area\n * used for pages that aren't adopted to mobile\n */\n minContentWidth?: number;\n};\n\nconst defaultSidebarContext: TitanLayoutSidebarContextType = {\n styles: {\n popoverContent: {\n '--background-color-strong': '#24323C',\n 'color': 'var(--color-white)',\n } as CSSProperties,\n },\n};\n\nconst useAppearance = (appearance: TitanLayoutProps['appearance']) =>\n useMemo(() => {\n const isLegacy = appearance === 'legacy';\n const isAnvil1 = appearance === 'anvil1';\n const isAnvil2 = appearance === 'anvil2';\n\n return {\n isLegacy,\n isAnvil1,\n isAnvil2,\n isSequent: isLegacy || isAnvil2,\n };\n }, [appearance]);\n\nfunction TitanLayoutComponent({\n appearance = 'anvil2',\n navVariant = 'left',\n id,\n children,\n contentOnly,\n navigationComponent,\n header,\n top,\n profile,\n state,\n logo,\n onStateChange,\n navigationMainItems,\n navigationOverflowItems,\n extraLinks,\n extraLinksTop,\n extraText,\n minContentWidth,\n sideTop,\n}: TitanLayoutProps) {\n const breakpoint = useTitanBreakpoint();\n const context: TitanLayoutContextType = useMemo(\n () => ({\n NavigationComponent: navigationComponent ?? DefaultNavLinkComponent,\n breakpoint,\n isTitanLayout: true,\n sidebar: defaultSidebarContext,\n }),\n [navigationComponent, breakpoint]\n );\n const view = useAppearance(appearance);\n const [mobileDrawerOpened, setMobileDrawerOpened] = useState(false);\n const { hasNotifications, NotificationsContextProvider } = useNotificationsState();\n const [offsetTopStyles, setOffsetTopStyles] = useState<object>({});\n const updateIndicatorsHeight = useCallback((offset: number) => {\n setOffsetTopStyles({\n '--content-offset-top': `calc(var(--nav-offset-top) + ${offset}px)`,\n });\n }, []);\n\n const isMobile = breakpoint.isMobile;\n const hasSideBar =\n !contentOnly &&\n (navVariant === 'left' || (navVariant === 'top' && isMobile)) &&\n (!!navigationMainItems?.length || !!sideTop?.length);\n const hasTopBar = !contentOnly;\n\n useEffect(() => {\n if (view.isAnvil1) {\n const bodyClassName = 'of-hidden-i';\n document.body.classList.add(bodyClassName);\n return () => document.body.classList.remove(bodyClassName);\n }\n }, [view.isAnvil1]);\n\n const onBurgerClick = useCallback(\n (e: MouseEvent<never>) => {\n if (isMobile) {\n setMobileDrawerOpened(true);\n } else {\n onStateChange?.({ navCollapsed: !state?.navCollapsed });\n }\n\n e.stopPropagation();\n },\n [isMobile, state?.navCollapsed, onStateChange]\n );\n\n const onBarExpandChange = useCallback(\n (expanded: boolean) => {\n if (isMobile) {\n setMobileDrawerOpened(false);\n } else {\n onStateChange?.({ navCollapsed: !expanded });\n }\n },\n [onStateChange, isMobile]\n );\n const onSubmenuExpandChange = useCallback(\n (id: string, expanded: boolean, force: boolean) => {\n onStateChange?.({\n navCollapsed: state?.navCollapsed ?? false,\n submenusExpanded: [\n ...(force ? [] : (state?.submenusExpanded ?? []).filter(i => i !== id)),\n ...(expanded ? [id] : []),\n ],\n });\n },\n [state, onStateChange]\n );\n const sidebarNavItems = useMemo(() => {\n if (!hasSideBar) {\n return undefined;\n }\n\n if (navVariant === 'left') {\n return navigationMainItems;\n }\n\n return [...(navigationMainItems ?? []), ...(navigationOverflowItems ?? [])];\n }, [hasSideBar, navigationMainItems, navigationOverflowItems, navVariant]);\n\n const hasMenuNotifications = useMemo(() => {\n try {\n return (\n sidebarNavItems?.some(item => {\n if (item.counter || item.tag?.value) {\n return true;\n } else if (item.submenu) {\n return item.submenu.groups.some(group =>\n group.links.some(link => !!link.counter || !!link.tag?.value)\n );\n }\n return false;\n }) ?? false\n );\n } catch {\n return false;\n }\n }, [sidebarNavItems]);\n\n const limitContentWidth = useMemo(() => {\n if (view.isAnvil2 || !minContentWidth) {\n return undefined;\n }\n\n if (breakpoint.width < minContentWidth) {\n return minContentWidth;\n }\n }, [view, minContentWidth, breakpoint.width]);\n\n const contentStyles = useMemo(() => {\n if (view.isAnvil2 || view.isLegacy) {\n return offsetTopStyles;\n }\n }, [view, offsetTopStyles]);\n\n const layoutClass = view.isLegacy\n ? Styles.layoutLegacy\n : view.isAnvil1\n ? Styles.layoutAnvil1\n : Styles.layoutAnvil2;\n\n const burgerProps: LayoutHeaderProps['burger'] = useMemo(() => {\n if (!hasTopBar) {\n return undefined;\n }\n\n if (isMobile) {\n return {\n onClick: onBurgerClick,\n tag: { value: hasNotifications || hasMenuNotifications },\n };\n }\n\n if (navVariant === 'left') {\n return {\n 'onClick': onBurgerClick,\n 'tooltip': state?.navCollapsed ? 'Expand' : 'Collapse',\n 'data-pendo': 'navigation-left-options',\n 'data-cy': 'navigation-left-options',\n };\n }\n\n return undefined;\n }, [\n isMobile,\n hasTopBar,\n navVariant,\n state?.navCollapsed,\n onBurgerClick,\n hasNotifications,\n hasMenuNotifications,\n ]);\n\n return (\n <LayoutContext.Provider value={context}>\n <LayoutPlacementContext.Provider value=\"unset\">\n <div\n id={id}\n className={classNames(\n Styles.layout,\n isMobile ? Styles.layoutMobile : Styles.layoutDesktop,\n hasTopBar &&\n (navVariant === 'left' || !top\n ? Styles.layoutTopLight\n : Styles.layoutTopNav),\n {\n [Styles.layoutNavSlim]: !isMobile && hasSideBar && state?.navCollapsed,\n [Styles.layoutNavWide]: !isMobile && hasSideBar && !state?.navCollapsed,\n },\n layoutClass\n )}\n style={contentStyles}\n >\n {view.isSequent && <div className={Styles.topPlaceholder} />}\n {hasTopBar &&\n (navVariant === 'left' ? (\n <LayoutHeader\n className={Styles.top}\n variant=\"light\"\n logo={logo}\n profile={isMobile ? undefined : profile}\n center={top}\n rightText={isMobile ? undefined : extraText}\n right={\n <Fragment>\n {extraLinksTop}\n {!isMobile && extraLinks}\n </Fragment>\n }\n isMobile={isMobile}\n burger={burgerProps}\n />\n ) : (\n <LayoutHeaderDark\n className={Styles.top}\n logo={logo}\n profile={isMobile ? undefined : profile}\n center={top}\n rightText={isMobile ? undefined : extraText}\n right={\n <Fragment>\n {extraLinksTop}\n {!isMobile && extraLinks}\n </Fragment>\n }\n isMobile={isMobile}\n burger={burgerProps}\n navigationMainItems={navigationMainItems}\n navigationOverflowItems={navigationOverflowItems}\n />\n ))}\n\n {hasSideBar && (\n <NotificationsContextProvider>\n <LayoutSidebar\n className={Styles.side}\n mobile={breakpoint.isMobile}\n barExpanded={!state?.navCollapsed}\n onBarExpandChange={onBarExpandChange}\n submenusExpanded={state?.submenusExpanded}\n onSubmenuExpandChange={onSubmenuExpandChange}\n drawerOpened={mobileDrawerOpened}\n onDrawerOpenChange={setMobileDrawerOpened}\n top={sideTop}\n mainItems={sidebarNavItems}\n navigationComponent={context.NavigationComponent}\n bottom={\n isMobile ? (\n <Fragment>\n {profile}\n {extraLinks}\n {!!extraText && (\n <InternalSideNavigationTrigger\n id=\"--extra-text\"\n title={extraText}\n isActive={undefined}\n icon={undefined}\n iconActive={undefined}\n tag={undefined}\n className={undefined}\n />\n )}\n </Fragment>\n ) : undefined\n }\n />\n </NotificationsContextProvider>\n )}\n\n {view.isSequent && (\n <TitanLayoutHeaderObserved heightChange={updateIndicatorsHeight}>\n {header}\n </TitanLayoutHeaderObserved>\n )}\n {view.isAnvil1 ? (\n <LayoutContentAnvil1 header={header} minWidth={limitContentWidth}>\n {children}\n </LayoutContentAnvil1>\n ) : view.isLegacy ? (\n <LayoutContentLegacy minWidth={limitContentWidth}>\n {children}\n </LayoutContentLegacy>\n ) : (\n children\n )}\n </div>\n </LayoutPlacementContext.Provider>\n </LayoutContext.Provider>\n );\n}\n\nconst TitanLayoutHeaderObserved: FC<{\n children: ReactNode;\n heightChange?(value: number): void;\n}> = ({ children, heightChange }) => {\n const ref = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (ref.current) {\n const updatePosition = () => {\n if (ref.current && heightChange) {\n const pos = ref.current.getBoundingClientRect();\n heightChange(pos.height);\n }\n };\n\n const observer = new ResizeObserver(updatePosition);\n observer.observe(ref.current);\n\n updatePosition();\n return () => observer.disconnect();\n }\n }, [heightChange]);\n\n useEffect(() => {\n return () => {\n heightChange?.(0);\n };\n }, [heightChange]);\n return (\n <div ref={ref} className={Styles.contentHeader} data-cy=\"layout-content-header\">\n {children}\n </div>\n );\n};\nconst TitanLayoutHeader: FC<{ children: ReactNode }> = ({ children }) => {\n return (\n <div className={Styles.contentHeader} data-cy=\"layout-content-header\">\n {children}\n </div>\n );\n};\n\nconst LayoutContentAnvil1: FC<{\n children: ReactNode;\n header?: ReactNode;\n minWidth?: number;\n}> = ({ children, header, minWidth }) => {\n const innerContentStyles: CSSProperties = useMemo(\n () => ({\n ...(minWidth ? { minWidth: `${minWidth}px`, overflowX: 'auto' } : {}),\n }),\n [minWidth]\n );\n\n return (\n <Fragment>\n <TitanLayoutHeader>{header}</TitanLayoutHeader>\n <div\n className={classNames(Styles.content, { 'of-x-auto-i': !!minWidth })}\n data-cy=\"layout-content\"\n >\n <div\n className=\"position-relative d-f flex-grow-1 flex-basis-0 of-hidden\"\n style={innerContentStyles}\n >\n {children}\n </div>\n </div>\n </Fragment>\n );\n};\n\nconst LayoutContentLegacy: FC<{\n children: ReactNode;\n minWidth: number | undefined;\n}> = ({ children, minWidth }) => {\n const innerContentStyles: CSSProperties = useMemo(\n () => ({\n position: 'relative',\n minWidth: `${minWidth}px`,\n }),\n [minWidth]\n );\n\n return <div style={minWidth ? innerContentStyles : undefined}>{children}</div>;\n};\n\nexport const TitanLayout = Object.assign(TitanLayoutComponent, {\n Link: TitanLayoutLink,\n Trigger: TitanLayoutTrigger,\n});\n"],"names":["classNames","Fragment","useCallback","useEffect","useMemo","useRef","useState","DefaultNavLinkComponent","useTitanBreakpoint","LayoutContext","LayoutPlacementContext","LayoutHeader","LayoutHeaderDark","LayoutSidebar","InternalSideNavigationTrigger","useNotificationsState","TitanLayoutLink","TitanLayoutTrigger","Styles","defaultSidebarContext","styles","popoverContent","useAppearance","appearance","isLegacy","isAnvil1","isAnvil2","isSequent","TitanLayoutComponent","navVariant","id","children","contentOnly","navigationComponent","header","top","profile","state","logo","onStateChange","navigationMainItems","navigationOverflowItems","extraLinks","extraLinksTop","extraText","minContentWidth","sideTop","breakpoint","context","NavigationComponent","isTitanLayout","sidebar","view","mobileDrawerOpened","setMobileDrawerOpened","hasNotifications","NotificationsContextProvider","offsetTopStyles","setOffsetTopStyles","updateIndicatorsHeight","offset","isMobile","hasSideBar","length","hasTopBar","bodyClassName","document","body","classList","add","remove","onBurgerClick","e","navCollapsed","stopPropagation","onBarExpandChange","expanded","onSubmenuExpandChange","force","submenusExpanded","filter","i","sidebarNavItems","undefined","hasMenuNotifications","some","item","counter","tag","value","submenu","groups","group","links","link","limitContentWidth","width","contentStyles","layoutClass","layoutLegacy","layoutAnvil1","layoutAnvil2","burgerProps","onClick","Provider","div","className","layout","layoutMobile","layoutDesktop","layoutTopLight","layoutTopNav","layoutNavSlim","layoutNavWide","style","topPlaceholder","variant","center","rightText","right","burger","side","mobile","barExpanded","drawerOpened","onDrawerOpenChange","mainItems","bottom","title","isActive","icon","iconActive","TitanLayoutHeaderObserved","heightChange","LayoutContentAnvil1","minWidth","LayoutContentLegacy","ref","current","updatePosition","pos","getBoundingClientRect","height","observer","ResizeObserver","observe","disconnect","contentHeader","data-cy","TitanLayoutHeader","innerContentStyles","overflowX","content","position","TitanLayout","Object","assign","Link","Trigger"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/components/titan-layout/titan-layout.tsx"],"sourcesContent":["import classNames from 'classnames';\nimport {\n CSSProperties,\n ComponentPropsWithoutRef,\n FC,\n Fragment,\n MouseEvent,\n ReactElement,\n ReactNode,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { NavigationItemData } from '../../utils/navigation';\nimport { DefaultNavLinkComponent, NavLinkComponentProps } from '../../utils/navigation-context';\nimport { useTitanBreakpoint } from '../../utils/use-breakpoint';\nimport { TitanLayoutState } from './interface';\nimport {\n LayoutContext,\n LayoutPlacementContext,\n TitanLayoutContextType,\n TitanLayoutSidebarContextType,\n} from './layout-context';\nimport { LayoutHeader, LayoutHeaderProps } from './layout-header';\nimport { LayoutHeaderDark } from './layout-header-dark';\nimport { TitanLayoutLogoProps } from './layout-logo';\nimport { LayoutSidebar } from './layout-sidebar';\nimport { InternalSideNavigationTrigger } from './layout-sidebar-links-internal';\nimport { useNotificationsState } from './notifications-context';\nimport { TitanLayoutLink, TitanLayoutTrigger } from './titan-layout-links';\nimport * as Styles from './titan-layout.module.less';\n\nexport type TitanLayoutProps = Omit<ComponentPropsWithoutRef<'div'>, 'children' | 'style'> & {\n /** layout appearance */\n appearance?: 'legacy' | 'anvil1' | 'anvil2';\n\n /** layout navigation variant (left by default) */\n navVariant?: 'left' | 'top';\n\n /** layout's content */\n children?: ReactNode;\n\n /** show only content without side and top bars */\n contentOnly?: boolean;\n\n /** component used for navigation */\n navigationComponent?: FC<NavLinkComponentProps>;\n\n /** data for main navigation links */\n navigationMainItems?: NavigationItemData[];\n\n /** data for overflow navigation links (used only with top variant) */\n navigationOverflowItems?: NavigationItemData[];\n\n /** logo props */\n logo?: TitanLayoutLogoProps;\n\n /** layout state */\n state?: TitanLayoutState;\n /** layout state change handler */\n onStateChange?: (state: TitanLayoutState) => void;\n\n /** content header content */\n header?: ReactElement;\n\n /** content header fixed (stocky to top) content */\n headerFixed?: ReactElement;\n\n /** layout header content (center) */\n top?: ReactElement;\n\n /** top links for side navigation */\n sideTop?: ReactElement[];\n\n /**\n * profile element for layout\n * @see ProfileDropdown\n */\n profile?: ReactElement;\n\n /**\n * extra links for layout header\n * shown in side nav footer on mobile\n */\n extraLinks?: ReactElement;\n\n /**\n * fixed extra links for layout header\n * shown in header on mobile as well\n */\n extraLinksTop?: ReactElement;\n\n /**\n * text shown in layout's header\n * shown in side nav footer on mobile\n */\n extraText?: string;\n\n /**\n * minimal width set for content area\n * used for pages that aren't adopted to mobile\n */\n minContentWidth?: number;\n};\n\nconst defaultSidebarContext: TitanLayoutSidebarContextType = {\n styles: {\n popoverContent: {\n '--background-color-strong': '#24323C',\n 'color': 'var(--color-white)',\n } as CSSProperties,\n },\n};\n\nconst useAppearance = (appearance: TitanLayoutProps['appearance']) =>\n useMemo(() => {\n const isLegacy = appearance === 'legacy';\n const isAnvil1 = appearance === 'anvil1';\n const isAnvil2 = appearance === 'anvil2';\n\n return {\n isLegacy,\n isAnvil1,\n isAnvil2,\n isSequent: isLegacy || isAnvil2,\n };\n }, [appearance]);\n\nenum TopNavVariant {\n None = 'none',\n Tiny = 'tiny',\n Dark = 'dark',\n DarkStacked = 'stacked',\n Mobile = 'mobile',\n}\n\nconst topBarHeights: Record<TopNavVariant, number> = {\n [TopNavVariant.None]: 0,\n [TopNavVariant.Tiny]: 48,\n [TopNavVariant.Dark]: 48,\n [TopNavVariant.DarkStacked]: 80,\n [TopNavVariant.Mobile]: 72,\n};\n\nconst useTopNavVariant = (\n hasTopBar: boolean,\n isMobile: boolean,\n isLeftNav: boolean,\n hasTopCenterContent: boolean\n) => {\n if (!hasTopBar) {\n return TopNavVariant.None;\n }\n\n if (isMobile) {\n return TopNavVariant.Mobile;\n }\n\n if (isLeftNav) {\n return TopNavVariant.Tiny;\n }\n\n return hasTopCenterContent ? TopNavVariant.DarkStacked : TopNavVariant.Dark;\n};\n\nfunction TitanLayoutComponent({\n appearance = 'anvil2',\n navVariant = 'left',\n id,\n children,\n contentOnly,\n navigationComponent,\n header,\n headerFixed,\n top,\n profile,\n state,\n logo,\n onStateChange,\n navigationMainItems,\n navigationOverflowItems,\n extraLinks,\n extraLinksTop,\n extraText,\n minContentWidth,\n sideTop,\n}: TitanLayoutProps) {\n const breakpoint = useTitanBreakpoint();\n const context: TitanLayoutContextType = useMemo(\n () => ({\n NavigationComponent: navigationComponent ?? DefaultNavLinkComponent,\n breakpoint,\n isTitanLayout: true,\n sidebar: defaultSidebarContext,\n }),\n [navigationComponent, breakpoint]\n );\n const view = useAppearance(appearance);\n const [mobileDrawerOpened, setMobileDrawerOpened] = useState(false);\n const { hasNotifications, NotificationsContextProvider } = useNotificationsState();\n const [headerHeight] = useState(0);\n const [headerFixedHeight, setHeaderFixedHeight] = useState(0);\n\n const isMobile = breakpoint.isMobile;\n const hasSideBar =\n !contentOnly &&\n (navVariant === 'left' || (navVariant === 'top' && isMobile)) &&\n (!!navigationMainItems?.length || !!sideTop?.length);\n const topBarVariant = useTopNavVariant(!contentOnly, isMobile, navVariant === 'left', !!top);\n\n useEffect(() => {\n if (view.isAnvil1) {\n const bodyClassName = 'of-hidden-i';\n document.body.classList.add(bodyClassName);\n return () => document.body.classList.remove(bodyClassName);\n }\n }, [view.isAnvil1]);\n\n const onBurgerClick = useCallback(\n (e: MouseEvent<never>) => {\n if (isMobile) {\n setMobileDrawerOpened(true);\n } else {\n onStateChange?.({ navCollapsed: !state?.navCollapsed });\n }\n\n e.stopPropagation();\n },\n [isMobile, state?.navCollapsed, onStateChange]\n );\n\n const onBarExpandChange = useCallback(\n (expanded: boolean) => {\n if (isMobile) {\n setMobileDrawerOpened(false);\n } else {\n onStateChange?.({ navCollapsed: !expanded });\n }\n },\n [onStateChange, isMobile]\n );\n const onSubmenuExpandChange = useCallback(\n (id: string, expanded: boolean, force: boolean) => {\n onStateChange?.({\n navCollapsed: state?.navCollapsed ?? false,\n submenusExpanded: [\n ...(force ? [] : (state?.submenusExpanded ?? []).filter(i => i !== id)),\n ...(expanded ? [id] : []),\n ],\n });\n },\n [state, onStateChange]\n );\n const sidebarNavItems = useMemo(() => {\n if (!hasSideBar) {\n return undefined;\n }\n\n if (navVariant === 'left') {\n return navigationMainItems;\n }\n\n return [...(navigationMainItems ?? []), ...(navigationOverflowItems ?? [])];\n }, [hasSideBar, navigationMainItems, navigationOverflowItems, navVariant]);\n\n const hasMenuNotifications = useMemo(() => {\n try {\n return (\n sidebarNavItems?.some(item => {\n if (item.counter || item.tag?.value) {\n return true;\n } else if (item.submenu) {\n return item.submenu.groups.some(group =>\n group.links.some(link => !!link.counter || !!link.tag?.value)\n );\n }\n return false;\n }) ?? false\n );\n } catch {\n return false;\n }\n }, [sidebarNavItems]);\n\n const limitContentWidth = useMemo(() => {\n if (view.isAnvil2 || !minContentWidth) {\n return undefined;\n }\n\n if (breakpoint.width < minContentWidth) {\n return minContentWidth;\n }\n }, [view, minContentWidth, breakpoint.width]);\n\n const layoutStyles = useMemo(() => {\n const topHeight = topBarHeights[topBarVariant] ?? 0;\n\n return {\n '--nav-top-height': `${topHeight}px`,\n '--nav-offset-top': `${topHeight + headerFixedHeight}px`,\n '--content-offset-top': `${topHeight + headerFixedHeight + headerHeight}px`,\n } as CSSProperties;\n }, [topBarVariant, headerFixedHeight, headerHeight]);\n\n const layoutClass = view.isLegacy\n ? Styles.layoutLegacy\n : view.isAnvil1\n ? Styles.layoutAnvil1\n : Styles.layoutAnvil2;\n\n const burgerProps: LayoutHeaderProps['burger'] = useMemo(() => {\n if (topBarVariant === TopNavVariant.None) {\n return undefined;\n }\n\n if (isMobile) {\n return {\n onClick: onBurgerClick,\n tag: { value: hasNotifications || hasMenuNotifications },\n };\n }\n\n if (navVariant === 'left') {\n return {\n 'onClick': onBurgerClick,\n 'tooltip': state?.navCollapsed ? 'Expand' : 'Collapse',\n 'data-pendo': 'navigation-left-options',\n 'data-cy': 'navigation-left-options',\n };\n }\n\n return undefined;\n }, [\n isMobile,\n topBarVariant,\n navVariant,\n state?.navCollapsed,\n onBurgerClick,\n hasNotifications,\n hasMenuNotifications,\n ]);\n\n return (\n <LayoutContext.Provider value={context}>\n <LayoutPlacementContext.Provider value=\"unset\">\n <div\n id={id}\n className={classNames(\n Styles.layout,\n !isMobile && Styles.layoutDesktop,\n {\n [Styles.layoutNavSlim]: !isMobile && hasSideBar && state?.navCollapsed,\n [Styles.layoutNavWide]: !isMobile && hasSideBar && !state?.navCollapsed,\n },\n layoutClass\n )}\n style={layoutStyles}\n >\n <div className={Styles.topPlaceholder} />\n {topBarVariant === TopNavVariant.Tiny ? (\n <LayoutHeader\n className={Styles.top}\n variant=\"light\"\n logo={logo}\n profile={isMobile ? undefined : profile}\n center={top}\n rightText={isMobile ? undefined : extraText}\n right={\n <Fragment>\n {extraLinksTop}\n {!isMobile && extraLinks}\n </Fragment>\n }\n isMobile={isMobile}\n burger={burgerProps}\n />\n ) : topBarVariant !== TopNavVariant.None ? (\n <LayoutHeaderDark\n className={Styles.top}\n logo={logo}\n profile={isMobile ? undefined : profile}\n center={top}\n rightText={isMobile ? undefined : extraText}\n right={\n <Fragment>\n {extraLinksTop}\n {!isMobile && extraLinks}\n </Fragment>\n }\n isMobile={isMobile}\n burger={burgerProps}\n navigationMainItems={navigationMainItems}\n navigationOverflowItems={navigationOverflowItems}\n />\n ) : null}\n\n {hasSideBar && (\n <NotificationsContextProvider>\n <LayoutSidebar\n className={Styles.side}\n mobile={breakpoint.isMobile}\n barExpanded={!state?.navCollapsed}\n onBarExpandChange={onBarExpandChange}\n submenusExpanded={state?.submenusExpanded}\n onSubmenuExpandChange={onSubmenuExpandChange}\n drawerOpened={mobileDrawerOpened}\n onDrawerOpenChange={setMobileDrawerOpened}\n top={sideTop}\n mainItems={sidebarNavItems}\n navigationComponent={context.NavigationComponent}\n bottom={\n isMobile ? (\n <Fragment>\n {profile}\n {extraLinks}\n {!!extraText && (\n <InternalSideNavigationTrigger\n id=\"--extra-text\"\n title={extraText}\n isActive={undefined}\n icon={undefined}\n iconActive={undefined}\n tag={undefined}\n className={undefined}\n />\n )}\n </Fragment>\n ) : undefined\n }\n />\n </NotificationsContextProvider>\n )}\n\n {!!headerFixed && (\n <TitanLayoutHeaderObserved\n heightChange={setHeaderFixedHeight}\n className={Styles.contentFixedHeader}\n data-cy=\"layout-content-fixed-header\"\n >\n {headerFixed}\n </TitanLayoutHeaderObserved>\n )}\n\n {!!header && view.isSequent && (\n <div className={Styles.contentHeader} data-cy=\"layout-content-header\">\n {header}\n </div>\n )}\n {view.isAnvil1 ? (\n <LayoutContentAnvil1 header={header} minWidth={limitContentWidth}>\n {children}\n </LayoutContentAnvil1>\n ) : view.isLegacy ? (\n <LayoutContentLegacy minWidth={limitContentWidth}>\n {children}\n </LayoutContentLegacy>\n ) : (\n children\n )}\n </div>\n </LayoutPlacementContext.Provider>\n </LayoutContext.Provider>\n );\n}\n\nconst TitanLayoutHeaderObserved: FC<{\n 'children': ReactNode;\n 'className'?: string;\n 'data-cy'?: string;\n heightChange?(value: number): void;\n}> = ({ children, heightChange, ...rest }) => {\n const ref = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (ref.current) {\n const updatePosition = () => {\n if (ref.current && heightChange) {\n const pos = ref.current.getBoundingClientRect();\n heightChange(pos.height);\n }\n };\n\n const observer = new ResizeObserver(updatePosition);\n observer.observe(ref.current);\n\n updatePosition();\n return () => observer.disconnect();\n }\n }, [heightChange]);\n\n useEffect(() => {\n return () => {\n heightChange?.(0);\n };\n }, [heightChange]);\n return (\n <div {...rest} ref={ref}>\n {children}\n </div>\n );\n};\nconst TitanLayoutHeader: FC<{ children: ReactNode }> = ({ children }) => {\n return (\n <div className={Styles.contentHeader} data-cy=\"layout-content-header\">\n {children}\n </div>\n );\n};\n\nconst LayoutContentAnvil1: FC<{\n children: ReactNode;\n header?: ReactNode;\n minWidth?: number;\n}> = ({ children, header, minWidth }) => {\n const innerContentStyles: CSSProperties = useMemo(\n () => ({\n ...(minWidth ? { minWidth: `${minWidth}px`, overflowX: 'auto' } : {}),\n }),\n [minWidth]\n );\n\n return (\n <Fragment>\n <TitanLayoutHeader>{header}</TitanLayoutHeader>\n <div\n className={classNames(Styles.content, { 'of-x-auto-i': !!minWidth })}\n data-cy=\"layout-content\"\n >\n <div\n className=\"position-relative d-f flex-grow-1 flex-basis-0 of-hidden\"\n style={innerContentStyles}\n >\n {children}\n </div>\n </div>\n </Fragment>\n );\n};\n\nconst LayoutContentLegacy: FC<{\n children: ReactNode;\n minWidth: number | undefined;\n}> = ({ children, minWidth }) => {\n const innerContentStyles: CSSProperties = useMemo(\n () => ({\n position: 'relative',\n minWidth: `${minWidth}px`,\n }),\n [minWidth]\n );\n\n return <div style={minWidth ? innerContentStyles : undefined}>{children}</div>;\n};\n\nexport const TitanLayout = Object.assign(TitanLayoutComponent, {\n Link: TitanLayoutLink,\n Trigger: TitanLayoutTrigger,\n});\n"],"names":["classNames","Fragment","useCallback","useEffect","useMemo","useRef","useState","DefaultNavLinkComponent","useTitanBreakpoint","LayoutContext","LayoutPlacementContext","LayoutHeader","LayoutHeaderDark","LayoutSidebar","InternalSideNavigationTrigger","useNotificationsState","TitanLayoutLink","TitanLayoutTrigger","Styles","defaultSidebarContext","styles","popoverContent","useAppearance","appearance","isLegacy","isAnvil1","isAnvil2","isSequent","TopNavVariant","topBarHeights","useTopNavVariant","hasTopBar","isMobile","isLeftNav","hasTopCenterContent","TitanLayoutComponent","navVariant","id","children","contentOnly","navigationComponent","header","headerFixed","top","profile","state","logo","onStateChange","navigationMainItems","navigationOverflowItems","extraLinks","extraLinksTop","extraText","minContentWidth","sideTop","breakpoint","context","NavigationComponent","isTitanLayout","sidebar","view","mobileDrawerOpened","setMobileDrawerOpened","hasNotifications","NotificationsContextProvider","headerHeight","headerFixedHeight","setHeaderFixedHeight","hasSideBar","length","topBarVariant","bodyClassName","document","body","classList","add","remove","onBurgerClick","e","navCollapsed","stopPropagation","onBarExpandChange","expanded","onSubmenuExpandChange","force","submenusExpanded","filter","i","sidebarNavItems","undefined","hasMenuNotifications","some","item","counter","tag","value","submenu","groups","group","links","link","limitContentWidth","width","layoutStyles","topHeight","layoutClass","layoutLegacy","layoutAnvil1","layoutAnvil2","burgerProps","onClick","Provider","div","className","layout","layoutDesktop","layoutNavSlim","layoutNavWide","style","topPlaceholder","variant","center","rightText","right","burger","side","mobile","barExpanded","drawerOpened","onDrawerOpenChange","mainItems","bottom","title","isActive","icon","iconActive","TitanLayoutHeaderObserved","heightChange","contentFixedHeader","data-cy","contentHeader","LayoutContentAnvil1","minWidth","LayoutContentLegacy","rest","ref","current","updatePosition","pos","getBoundingClientRect","height","observer","ResizeObserver","observe","disconnect","TitanLayoutHeader","innerContentStyles","overflowX","content","position","TitanLayout","Object","assign","Link","Trigger"],"mappings":"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"}
@@ -9,8 +9,7 @@
9
9
  @bg-color-active: rgba(120, 187, 250, 0.2);
10
10
 
11
11
  .layout-anvil1 {
12
- height: calc(100vh - var(--nav-offset-top));
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-offset-top);
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,20 @@
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
 
103
91
  @media print {
104
92
  .layout {
93
+ --nav-top-height: 0px !important;
94
+ --nav-offset-top: 0px !important;
105
95
  --nav-offset-left: 0px !important;
106
96
  --nav-offset-right: 0px !important;
107
97
 
@@ -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;
@@ -1,6 +1,7 @@
1
1
  import { TitanLayoutProps } from '../components/titan-layout';
2
2
  export interface LayoutContentArgs {
3
3
  header: boolean;
4
+ headerFixed: boolean;
4
5
  sideTop: boolean;
5
6
  extraText: boolean;
6
7
  search: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"titan-layout.d.ts","sourceRoot":"","sources":["../../src/test/titan-layout.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAE9D,MAAM,WAAW,iBAAiB;IAC9B,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,OAAO,CAAC;IAChB,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;IACrB,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;IAClB,aAAa,EAAE,OAAO,CAAC;CAC1B;AAED,eAAO,MAAM,cAAc,QAAO,iBAUhC,CAAC;AAGH,eAAO,MAAM,sBAAsB,GAAI,OAAO,OAAO,CAAC,gBAAgB,CAAC,MAAM,OAAO,GAAG,4CAItF,CAAC;AACF,eAAO,MAAM,qBAAqB,iCAAwC,CAAC"}
1
+ {"version":3,"file":"titan-layout.d.ts","sourceRoot":"","sources":["../../src/test/titan-layout.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAE9D,MAAM,WAAW,iBAAiB;IAC9B,MAAM,EAAE,OAAO,CAAC;IAChB,WAAW,EAAE,OAAO,CAAC;IACrB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,OAAO,CAAC;IAChB,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;IACrB,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;IAClB,aAAa,EAAE,OAAO,CAAC;CAC1B;AAED,eAAO,MAAM,cAAc,QAAO,iBAWhC,CAAC;AAGH,eAAO,MAAM,sBAAsB,GAAI,OAAO,OAAO,CAAC,gBAAgB,CAAC,MAAM,OAAO,GAAG,4CAItF,CAAC;AACF,eAAO,MAAM,qBAAqB,iCAAwC,CAAC"}
@@ -2,6 +2,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { createContext, useContext } from 'react';
3
3
  export const getDefaultArgs = ()=>({
4
4
  header: true,
5
+ headerFixed: true,
5
6
  sideTop: true,
6
7
  extraText: true,
7
8
  search: true,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/test/titan-layout.tsx"],"sourcesContent":["import { createContext, useContext } from 'react';\nimport { TitanLayoutProps } from '../components/titan-layout';\n\nexport interface LayoutContentArgs {\n header: boolean;\n sideTop: boolean;\n extraText: boolean;\n search: boolean;\n longContent: boolean;\n wideContent: boolean;\n minWidth: boolean;\n emptyNav: boolean;\n overflowItems: boolean;\n}\n\nexport const getDefaultArgs = (): LayoutContentArgs => ({\n header: true,\n sideTop: true,\n extraText: true,\n search: true,\n longContent: true,\n wideContent: false,\n minWidth: false,\n emptyNav: false,\n overflowItems: true,\n});\n\nconst DefaultPropsContext = createContext<Partial<TitanLayoutProps>>({});\nexport const withDefaultLayoutProps = (props: Partial<TitanLayoutProps>) => (Story: any) => (\n <DefaultPropsContext.Provider value={props}>\n <Story />\n </DefaultPropsContext.Provider>\n);\nexport const useDefaultLayoutProps = () => useContext(DefaultPropsContext);\n"],"names":["createContext","useContext","getDefaultArgs","header","sideTop","extraText","search","longContent","wideContent","minWidth","emptyNav","overflowItems","DefaultPropsContext","withDefaultLayoutProps","props","Story","Provider","value","useDefaultLayoutProps"],"mappings":";AAAA,SAASA,aAAa,EAAEC,UAAU,QAAQ,QAAQ;AAelD,OAAO,MAAMC,iBAAiB,IAA0B,CAAA;QACpDC,QAAQ;QACRC,SAAS;QACTC,WAAW;QACXC,QAAQ;QACRC,aAAa;QACbC,aAAa;QACbC,UAAU;QACVC,UAAU;QACVC,eAAe;IACnB,CAAA,EAAG;AAEH,MAAMC,oCAAsBZ,cAAyC,CAAC;AACtE,OAAO,MAAMa,yBAAyB,CAACC,QAAqC,CAACC,sBACzE,KAACH,oBAAoBI,QAAQ;YAACC,OAAOH;sBACjC,cAAA,KAACC;WAEP;AACF,OAAO,MAAMG,wBAAwB,IAAMjB,WAAWW,qBAAqB"}
1
+ {"version":3,"sources":["../../src/test/titan-layout.tsx"],"sourcesContent":["import { createContext, useContext } from 'react';\nimport { TitanLayoutProps } from '../components/titan-layout';\n\nexport interface LayoutContentArgs {\n header: boolean;\n headerFixed: boolean;\n sideTop: boolean;\n extraText: boolean;\n search: boolean;\n longContent: boolean;\n wideContent: boolean;\n minWidth: boolean;\n emptyNav: boolean;\n overflowItems: boolean;\n}\n\nexport const getDefaultArgs = (): LayoutContentArgs => ({\n header: true,\n headerFixed: true,\n sideTop: true,\n extraText: true,\n search: true,\n longContent: true,\n wideContent: false,\n minWidth: false,\n emptyNav: false,\n overflowItems: true,\n});\n\nconst DefaultPropsContext = createContext<Partial<TitanLayoutProps>>({});\nexport const withDefaultLayoutProps = (props: Partial<TitanLayoutProps>) => (Story: any) => (\n <DefaultPropsContext.Provider value={props}>\n <Story />\n </DefaultPropsContext.Provider>\n);\nexport const useDefaultLayoutProps = () => useContext(DefaultPropsContext);\n"],"names":["createContext","useContext","getDefaultArgs","header","headerFixed","sideTop","extraText","search","longContent","wideContent","minWidth","emptyNav","overflowItems","DefaultPropsContext","withDefaultLayoutProps","props","Story","Provider","value","useDefaultLayoutProps"],"mappings":";AAAA,SAASA,aAAa,EAAEC,UAAU,QAAQ,QAAQ;AAgBlD,OAAO,MAAMC,iBAAiB,IAA0B,CAAA;QACpDC,QAAQ;QACRC,aAAa;QACbC,SAAS;QACTC,WAAW;QACXC,QAAQ;QACRC,aAAa;QACbC,aAAa;QACbC,UAAU;QACVC,UAAU;QACVC,eAAe;IACnB,CAAA,EAAG;AAEH,MAAMC,oCAAsBb,cAAyC,CAAC;AACtE,OAAO,MAAMc,yBAAyB,CAACC,QAAqC,CAACC,sBACzE,KAACH,oBAAoBI,QAAQ;YAACC,OAAOH;sBACjC,cAAA,KAACC;WAEP;AACF,OAAO,MAAMG,wBAAwB,IAAMlB,WAAWY,qBAAqB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@servicetitan/navigation",
3
- "version": "13.1.3",
3
+ "version": "13.2.0-canary.270.41c771f.0",
4
4
  "description": "Navigation components",
5
5
  "repository": {
6
6
  "type": "git",
@@ -42,5 +42,5 @@
42
42
  "less": true,
43
43
  "webpack": false
44
44
  },
45
- "gitHead": "cd08e467dfda5ea17418691ad361a858f3163e17"
45
+ "gitHead": "41c771f48874df63f3b15dd35343ba2fc15d578f"
46
46
  }
@@ -24,7 +24,7 @@
24
24
  .header {
25
25
  --nav-top-content-height: 32px;
26
26
 
27
- height: var(--nav-offset-top);
27
+ height: var(--nav-top-height);
28
28
  display: flex;
29
29
  justify-content: space-between;
30
30
 
@@ -86,8 +86,8 @@
86
86
 
87
87
  .nav-drawer-backdrop {
88
88
  position: fixed;
89
- height: 100vh;
90
- width: 100vw;
89
+ height: 100%;
90
+ width: 100%;
91
91
  top: 0;
92
92
  left: 0;
93
93
  z-index: 991;
@@ -176,7 +176,6 @@ const ContentHeader = () => {
176
176
 
177
177
  return (
178
178
  <Fragment>
179
- <Announcement title="Some info" status="info" />
180
179
  <Announcement title="Some warning" status="warning" />
181
180
  <div
182
181
  className="d-f justify-content-center align-items-center bg-purple-100-i"
@@ -192,6 +191,9 @@ const ContentHeader = () => {
192
191
  </Fragment>
193
192
  );
194
193
  };
194
+ const ContentHeaderFixed = () => {
195
+ return <Announcement title="Some info" status="info" />;
196
+ };
195
197
  const SearchBar = () => (
196
198
  <TextField size="small" placeholder="Search" className="w-100-i m-x-half-i" />
197
199
  );
@@ -210,6 +212,7 @@ const useLayoutProps = (args: LayoutContentArgs): TitanLayoutProps => {
210
212
  profile,
211
213
  top: args.search ? <SearchBar /> : undefined,
212
214
  header: args.header ? <ContentHeader /> : undefined,
215
+ headerFixed: args.headerFixed ? <ContentHeaderFixed /> : undefined,
213
216
 
214
217
  logo: { title: true },
215
218
 
@@ -9,8 +9,7 @@
9
9
  @bg-color-active: rgba(120, 187, 250, 0.2);
10
10
 
11
11
  .layout-anvil1 {
12
- height: calc(100vh - var(--nav-offset-top));
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-offset-top);
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,20 @@
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
 
103
91
  @media print {
104
92
  .layout {
93
+ --nav-top-height: 0px !important;
94
+ --nav-offset-top: 0px !important;
105
95
  --nav-offset-left: 0px !important;
106
96
  --nav-offset-right: 0px !important;
107
97
 
@@ -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 [offsetTopStyles, setOffsetTopStyles] = useState<object>({});
163
- const updateIndicatorsHeight = useCallback((offset: number) => {
164
- setOffsetTopStyles({
165
- '--content-offset-top': `calc(var(--nav-offset-top) + ${offset}px)`,
166
- });
167
- }, []);
203
+ const [headerHeight] = 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 hasTopBar = !contentOnly;
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 contentStyles = useMemo(() => {
261
- if (view.isAnvil2 || view.isLegacy) {
262
- return offsetTopStyles;
263
- }
264
- }, [view, offsetTopStyles]);
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 (!hasTopBar) {
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
- hasTopBar,
337
+ topBarVariant,
297
338
  navVariant,
298
339
  state?.navCollapsed,
299
340
  onBurgerClick,
@@ -308,57 +349,52 @@ function TitanLayoutComponent({
308
349
  id={id}
309
350
  className={classNames(
310
351
  Styles.layout,
311
- isMobile ? Styles.layoutMobile : Styles.layoutDesktop,
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={contentStyles}
359
+ style={layoutStyles}
323
360
  >
324
- {view.isSequent && <div className={Styles.topPlaceholder} />}
325
- {hasTopBar &&
326
- (navVariant === 'left' ? (
327
- <LayoutHeader
328
- className={Styles.top}
329
- variant="light"
330
- logo={logo}
331
- profile={isMobile ? undefined : profile}
332
- center={top}
333
- rightText={isMobile ? undefined : extraText}
334
- right={
335
- <Fragment>
336
- {extraLinksTop}
337
- {!isMobile && extraLinks}
338
- </Fragment>
339
- }
340
- isMobile={isMobile}
341
- burger={burgerProps}
342
- />
343
- ) : (
344
- <LayoutHeaderDark
345
- className={Styles.top}
346
- logo={logo}
347
- profile={isMobile ? undefined : profile}
348
- center={top}
349
- rightText={isMobile ? undefined : extraText}
350
- right={
351
- <Fragment>
352
- {extraLinksTop}
353
- {!isMobile && extraLinks}
354
- </Fragment>
355
- }
356
- isMobile={isMobile}
357
- burger={burgerProps}
358
- navigationMainItems={navigationMainItems}
359
- navigationOverflowItems={navigationOverflowItems}
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>
@@ -397,11 +433,21 @@ function TitanLayoutComponent({
397
433
  </NotificationsContextProvider>
398
434
  )}
399
435
 
400
- {view.isSequent && (
401
- <TitanLayoutHeaderObserved heightChange={updateIndicatorsHeight}>
402
- {header}
436
+ {!!headerFixed && (
437
+ <TitanLayoutHeaderObserved
438
+ heightChange={setHeaderFixedHeight}
439
+ className={Styles.contentFixedHeader}
440
+ data-cy="layout-content-fixed-header"
441
+ >
442
+ {headerFixed}
403
443
  </TitanLayoutHeaderObserved>
404
444
  )}
445
+
446
+ {!!header && view.isSequent && (
447
+ <div className={Styles.contentHeader} data-cy="layout-content-header">
448
+ {header}
449
+ </div>
450
+ )}
405
451
  {view.isAnvil1 ? (
406
452
  <LayoutContentAnvil1 header={header} minWidth={limitContentWidth}>
407
453
  {children}
@@ -420,9 +466,11 @@ function TitanLayoutComponent({
420
466
  }
421
467
 
422
468
  const TitanLayoutHeaderObserved: FC<{
423
- children: ReactNode;
469
+ 'children': ReactNode;
470
+ 'className'?: string;
471
+ 'data-cy'?: string;
424
472
  heightChange?(value: number): void;
425
- }> = ({ children, heightChange }) => {
473
+ }> = ({ children, heightChange, ...rest }) => {
426
474
  const ref = useRef<HTMLDivElement>(null);
427
475
 
428
476
  useEffect(() => {
@@ -448,7 +496,7 @@ const TitanLayoutHeaderObserved: FC<{
448
496
  };
449
497
  }, [heightChange]);
450
498
  return (
451
- <div ref={ref} className={Styles.contentHeader} data-cy="layout-content-header">
499
+ <div {...rest} ref={ref}>
452
500
  {children}
453
501
  </div>
454
502
  );
@@ -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,