LayoutBuilder.ts 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. import React from 'react';
  2. export interface LayoutRendererComponentProps<T extends string> {
  3. slots: Partial<Record<T, React.ReactNode | null>>;
  4. refs: Record<T, (i: any) => void>;
  5. width: number;
  6. height: number;
  7. }
  8. export type LayoutRendererComponent<T extends string> = React.ComponentType<LayoutRendererComponentProps<T>>;
  9. // Fluent API for defining and rendering layout
  10. export class LayoutBuilder<T extends string> {
  11. private layout: Partial<Record<T, React.ReactNode | null>> = {};
  12. constructor(
  13. private renderer: LayoutRendererComponent<T>,
  14. private refsMap: Record<T, (i: any) => void>,
  15. private width: number,
  16. private height: number
  17. ) {}
  18. getLayout() {
  19. return this.layout;
  20. }
  21. addSlot(id: T, node: React.ReactNode) {
  22. this.layout[id] = node;
  23. return this;
  24. }
  25. clearSlot(id: T) {
  26. if (this.layout[id] && this.refsMap[id]) {
  27. delete this.layout[id];
  28. this.refsMap[id](null);
  29. }
  30. return this;
  31. }
  32. render() {
  33. if (!this.layout) {
  34. return null;
  35. }
  36. return React.createElement(this.renderer, {
  37. slots: this.layout,
  38. refs: this.refsMap,
  39. width: this.width,
  40. height: this.height,
  41. });
  42. }
  43. }