Advertisement
crutch12

Sut Widgets

Nov 27th, 2022 (edited)
1,130
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import React from 'react';
  2.  
  3. // Context
  4. // - хранит состояние сворачивания (expanded)
  5. // - хранит dom узел, в который будут рендерится виджеты (widgetsRef)
  6. const WidgetsContext = React.createContext(/* ... */)
  7.  
  8. // Provider
  9. const WidgetsProvider = ({ widgets, children }) => {
  10.     const [expanded, setExpanded] = React.useState(false) // мб сохранять в localStorage
  11.     const widgetsRef = React.useRef(null)
  12.  
  13.     return <WidgetsContext.Provider value={{ expanded, setExpanded, widgetsRef }}>
  14.         {children}
  15.     </WidgetsContext.Provider>
  16. }
  17.  
  18. // Пример инициализации в приложении
  19. const _app = () => {
  20.     <WidgetsProvider>
  21.         {children}
  22.     </WidgetsProvider>
  23. }
  24.  
  25. // Пример компонента, который
  26. // - сворачивается/разворачивается (через WidgetsContext)
  27. // - отображает dom узел для вывода виджетов (в т.ч. свёрнутых)
  28. // - предоставляет dom узел для будущего createPortal
  29. const WidgetsBar = () => {
  30.     // используем expanded и setExpanded
  31.     // выставляем widgetsRef
  32.     const { expanded, setExpanded, widgetsRef } = React.useContext(WidgetsContext)
  33.  
  34.     return (<div>
  35.         <button onClick={() => setExpanded(v => !v)}>Свернуть/развернуть</button>
  36.         {/* DOM узел, куда компонент Widgets будет рисовать свой контент */}
  37.         <div ref={widgetsRef} />
  38.     </div>)
  39. }
  40.  
  41. // Пример компонента одного виджета
  42. const Widget = ({ title, children, loading }) => <div />
  43.  
  44. // Пример подключения sidebar'а в Layout
  45. const Layout = () => {
  46.     <>
  47.         <div>{children}</div>
  48.         {/* Находится справа */}
  49.         <WidgetsBar />
  50.     </>
  51. }
  52.  
  53. // Пример компонента, через который виджеты пробрасываются в WidgetsBar (через createPotal)
  54. const Widgets = ({ widgets, children }) => {
  55.     // рисуем развёрнутые/свернётые виджеты (в зависимости от expanded)
  56.     // рисуем <Widget key=... />, если не передана children функция
  57.     // в expanded: false рисуем просто квадратики
  58.  
  59.     // пример
  60.     const result = <>{widgets.map(widget => children ? children(widget) : <Widget {...widget}>{widget.render()}</Widget> )}</>
  61.  
  62.    
  63.     // через WidgetsContext достаём dom узел (widgetsRef), в который нужно запихнуть результат
  64.     // передаём результат в createPortal через widgetsRef
  65.  
  66.     // пример
  67.     return createPortal(result, widgetsRef.current)
  68. }
  69.  
  70. // Пример использовния
  71. const Page = () => {
  72.     const widgets = [
  73.         {
  74.             id: 'w1',
  75.             title: 'Виджет 1',
  76.             loading: false,
  77.             render: () => <div></div>
  78.         },
  79.         {
  80.             id: 'w2',
  81.             title: 'Виджет 2',
  82.             loading: true,
  83.             render: () => <div></div>
  84.         }
  85.     ]
  86.  
  87.     return (<>
  88.         Контент страницы
  89.  
  90.         {/* Базовый пример */}
  91.         <Widgets widgets={widgets} />
  92.  
  93.         {/* Пример с кастомизацией */}
  94.         <Widgets widgets={widgets}>
  95.             {/* Функция отрисовки каждого виджета */}
  96.             {({ title, loading, render }) => <Widget
  97.                 title={title}
  98.                 loading={loading}>
  99.                     {render()}
  100.             </Widget>}
  101.         </Widgets>
  102.     </>)
  103. }
  104.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement