EnterpriseNav.tsx 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. import * as React from 'react';
  2. import { Block, HeaderBlock, SideNavSettings } from '../types';
  3. import { Icon } from './ui/Icon';
  4. const getFontFamilyValue = (font: SideNavSettings['fontFamily']) => {
  5. switch (font) {
  6. case 'serif': return 'serif';
  7. case 'mono': return 'monospace';
  8. case 'sans': default: return 'sans-serif';
  9. }
  10. }
  11. var EnterpriseNav: React.FC<{ blocks: Block[]; deviceView: 'pc' | 'mobile'; scrollContainerRef: React.RefObject<HTMLDivElement>, settings: SideNavSettings }> = function(props) {
  12. var blocks = props.blocks, deviceView = props.deviceView, scrollContainerRef = props.scrollContainerRef, settings = props.settings;
  13. var isNavOpenState = React.useState(false);
  14. var isNavOpen = isNavOpenState[0];
  15. var setIsNavOpen = isNavOpenState[1];
  16. var headers = blocks.filter(function(b) { return b.type === 'header'; }) as HeaderBlock[];
  17. var handleScrollTo = function(blockId: string) {
  18. if (scrollContainerRef.current) {
  19. var element = scrollContainerRef.current.querySelector('#block-' + blockId);
  20. if (element) {
  21. element.scrollIntoView({ behavior: 'smooth', block: 'start' });
  22. }
  23. }
  24. setIsNavOpen(false);
  25. };
  26. var handleBackToTop = function() {
  27. if (scrollContainerRef.current) {
  28. scrollContainerRef.current.scrollTo({ top: 0, behavior: 'smooth' });
  29. }
  30. setIsNavOpen(false);
  31. };
  32. var navLinks = [
  33. React.createElement(
  34. "button",
  35. {
  36. key: "back-to-top",
  37. onClick: handleBackToTop,
  38. className: "block w-full text-left p-2 rounded-md transition-colors font-semibold",
  39. style: { color: settings.textColor },
  40. onMouseOver: (e: any) => { e.currentTarget.style.backgroundColor = settings.hoverBackgroundColor; e.currentTarget.style.color = settings.hoverTextColor; },
  41. onMouseOut: (e: any) => { e.currentTarget.style.backgroundColor = 'transparent'; e.currentTarget.style.color = settings.textColor; },
  42. } as any,
  43. "↑ Back to Top"
  44. )
  45. ].concat(headers.map(function (header) {
  46. return React.createElement(
  47. "button",
  48. {
  49. key: header.id,
  50. onClick: function () { return handleScrollTo(header.id); },
  51. className: "block w-full text-left p-2 rounded-md transition-colors",
  52. style: { color: settings.textColor },
  53. onMouseOver: (e: any) => { e.currentTarget.style.backgroundColor = settings.hoverBackgroundColor; e.currentTarget.style.color = settings.hoverTextColor; },
  54. onMouseOut: (e: any) => { e.currentTarget.style.backgroundColor = 'transparent'; e.currentTarget.style.color = settings.textColor; },
  55. } as any,
  56. header.text
  57. );
  58. }));
  59. var navElement = React.createElement("nav", { className: "space-y-2" }, ...navLinks);
  60. if (deviceView === 'pc') {
  61. var navBackgroundStyle = settings.navBackgroundStyle || 'compact';
  62. var asideStyle: React.CSSProperties = {
  63. fontFamily: getFontFamilyValue(settings.fontFamily),
  64. fontSize: settings.fontSize,
  65. };
  66. var asideClasses = "p-4";
  67. if (navBackgroundStyle === 'compact') {
  68. asideClasses += ' rounded-lg';
  69. asideStyle.backgroundColor = settings.backgroundColor;
  70. }
  71. return React.createElement("aside", {
  72. className: asideClasses,
  73. style: asideStyle
  74. }, navElement);
  75. }
  76. var mobileNavContent = React.createElement("div", { className: "p-4" }, navElement);
  77. return React.createElement(React.Fragment, null,
  78. React.createElement("button", { onClick: function() { return setIsNavOpen(true); }, className: "absolute top-4 left-4 z-30 p-2 bg-black/50 rounded-full" } as any,
  79. React.createElement(Icon, { className: "h-6 w-6 text-white", children: React.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M4 6h16M4 12h16M4 18h16" }) })
  80. ),
  81. isNavOpen && React.createElement("div", { className: "absolute inset-0 bg-black/50 z-40", onClick: function() { return setIsNavOpen(false); } } as any),
  82. React.createElement("div", { className: "absolute top-0 left-0 h-full w-64 bg-white dark:bg-gray-800 shadow-lg z-50 transition-transform duration-300 " + (isNavOpen ? "translate-x-0" : "-translate-x-full") } as any, mobileNavContent)
  83. );
  84. };
  85. export default EnterpriseNav;