Layout scaffolding for Web apps.
Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.
 
 
 

173 wiersze
5.2 KiB

  1. // TODO figure out how to refactor left sidebar with menu widget
  2. import * as React from 'react';
  3. import {LayoutArgs, layouts, Span} from '@tesseract-design/viewfinder-base';
  4. type BaseMenuItem = {
  5. label: React.ReactNode,
  6. icon: React.ReactNode,
  7. url: unknown,
  8. }
  9. export type MenuItem = BaseMenuItem & {
  10. id: string,
  11. secondary?: boolean,
  12. }
  13. export type LeftSidebarWithMenuBaseProps = Omit<React.HTMLProps<HTMLDivElement>, 'span'> & {
  14. span?: Span,
  15. items?: MenuItem[],
  16. linkComponent?: React.ElementType,
  17. moreLinkComponent?: React.ElementType,
  18. moreLinkItem?: BaseMenuItem,
  19. moreItemsOpen?: boolean,
  20. open?: boolean,
  21. }
  22. export const LeftSidebarWithMenuBase = React.forwardRef<HTMLDivElement, LeftSidebarWithMenuBaseProps>(({
  23. children,
  24. span = Span.WIDE,
  25. open = false,
  26. items: sidebarMenuItems = [],
  27. linkComponent: LinkComponent = 'a',
  28. moreLinkComponent: MoreLinkComponent = LinkComponent,
  29. moreLinkItem,
  30. moreItemsOpen = false,
  31. ...etcProps
  32. }, ref) => {
  33. const args: LayoutArgs = {
  34. span,
  35. mainSidebarOpen: open,
  36. auxiliaryItemsShown: moreItemsOpen,
  37. };
  38. const primarySidebarMenuItems = sidebarMenuItems.filter(s => !s.secondary)
  39. const secondarySidebarMenuItems = sidebarMenuItems.filter(s => s.secondary)
  40. const visibleSecondarySidebarMenuItems = secondarySidebarMenuItems.slice(0, 1)
  41. const moreSecondarySidebarMenuItems = secondarySidebarMenuItems.slice(1)
  42. const visiblePrimarySidebarMenuItems = (
  43. visibleSecondarySidebarMenuItems.length === 1
  44. ? primarySidebarMenuItems.slice(0, 3)
  45. : primarySidebarMenuItems.slice(0, 4)
  46. )
  47. const morePrimarySidebarMenuItems = (
  48. visibleSecondarySidebarMenuItems.length === 1
  49. ? primarySidebarMenuItems.slice(3)
  50. : primarySidebarMenuItems.slice(4)
  51. )
  52. const hasMoreSidebarMenuItems = (
  53. morePrimarySidebarMenuItems.length > 0
  54. || moreSecondarySidebarMenuItems.length > 0
  55. )
  56. return (
  57. <div
  58. className={layouts.LeftSidebarWithMenu.SidebarBase()}
  59. {...etcProps}
  60. ref={ref}
  61. >
  62. <div
  63. className={layouts.LeftSidebarWithMenu.SidebarMenu()}
  64. >
  65. <div>
  66. <div
  67. className={layouts.LeftSidebarWithMenu.SidebarMenuSize()}
  68. >
  69. <div
  70. className={layouts.LeftSidebarWithMenu.SidebarMenuGroup()}
  71. >
  72. {visiblePrimarySidebarMenuItems.map(({ id, ...item }) => (
  73. <span
  74. className={layouts.LeftSidebarWithMenu.SidebarMenuItem()}
  75. key={id}
  76. >
  77. <LinkComponent
  78. {...item}
  79. />
  80. </span>
  81. ))}
  82. </div>
  83. <div
  84. className={layouts.LeftSidebarWithMenu.MoreItems(args)}
  85. >
  86. <div
  87. className={layouts.LeftSidebarWithMenu.MoreItemsScroll()}
  88. >
  89. <div
  90. className={layouts.LeftSidebarWithMenu.MorePrimarySidebarMenuGroup()}
  91. >
  92. {morePrimarySidebarMenuItems.map(({ id, ...item }) => (
  93. <span
  94. className={layouts.LeftSidebarWithMenu.MoreSidebarMenuItem()}
  95. key={id}
  96. >
  97. <MoreLinkComponent
  98. {...item}
  99. />
  100. </span>
  101. ))}
  102. </div>
  103. <div
  104. className={layouts.LeftSidebarWithMenu.MoreSecondarySidebarMenuGroup()}
  105. >
  106. {moreSecondarySidebarMenuItems.map(({ id, ...item }) => (
  107. <span
  108. className={layouts.LeftSidebarWithMenu.MoreSidebarMenuItem()}
  109. key={id}
  110. >
  111. <MoreLinkComponent
  112. {...item}
  113. />
  114. </span>
  115. ))}
  116. </div>
  117. </div>
  118. </div>
  119. {hasMoreSidebarMenuItems && (
  120. <span
  121. className={layouts.LeftSidebarWithMenu.MoreToggleSidebarMenuItem()}
  122. >
  123. <span
  124. className={layouts.LeftSidebarWithMenu.SidebarMenuItem()}
  125. >
  126. <LinkComponent
  127. {...moreLinkItem}
  128. />
  129. </span>
  130. </span>
  131. )}
  132. {visibleSecondarySidebarMenuItems.length > 0 && (
  133. <div
  134. className={layouts.LeftSidebarWithMenu.SidebarMenuGroup()}
  135. >
  136. {visibleSecondarySidebarMenuItems.map(({ id, ...item }) => (
  137. <span
  138. className={layouts.LeftSidebarWithMenu.SidebarMenuItem()}
  139. key={id}
  140. >
  141. <LinkComponent
  142. {...item}
  143. />
  144. </span>
  145. ))}
  146. </div>
  147. )}
  148. </div>
  149. </div>
  150. </div>
  151. {children && (
  152. <div
  153. className={layouts.LeftSidebarWithMenu.SidebarMain(args)}
  154. >
  155. <div
  156. className={layouts.LeftSidebarWithMenu.SidebarMainOverflow()}
  157. >
  158. {children}
  159. </div>
  160. </div>
  161. )}
  162. </div>
  163. )
  164. });