{"version":3,"file":"frame.cjs","sources":["../src/frame.ts"],"sourcesContent":["import {\n  Component,\n  createElement,\n  createContext,\n  useContext,\n  useRef,\n  ReactNode,\n} from \"react\";\nimport h from \"@macrostrat/hyper\";\nimport { path } from \"d3-path\";\nimport {\n  ColumnLayoutContext,\n  ColumnLayoutCtx,\n  useColumnLayout,\n} from \"./context\";\nimport { drawZigZagAtConstantHeight } from \"./util\";\n\nlet sequence = 0; // Initialize a sequence counter\nfunction getUniqueIdentifier() {\n  // Generate a unique identifier using a sequential method that is stable across repeated\n  // re-renders. This evolves from a UUID-based approach for SSR (server-side rendering) compatibility.\n  const id = `uuid-${sequence}`;\n  sequence += 1; // Increment the sequence for the next call\n  return id;\n}\n\nclass UUIDComponent<T> extends Component<T> {\n  UUID: string;\n  constructor(props: T) {\n    super(props);\n    this.UUID = getUniqueIdentifier();\n  }\n}\n\nconst UUIDContext = createContext<string | null>(null);\n\nfunction useBasicUUID() {\n  const ref = useRef<string>(getUniqueIdentifier());\n  return ref.current;\n}\n\nconst useUUID = function () {\n  const uuid = useContext(UUIDContext);\n  if (uuid == null) {\n    return useBasicUUID();\n  }\n  return uuid;\n};\n\nfunction UUIDProvider({ children }) {\n  const ref = useRef<string>(getUniqueIdentifier());\n  return h(UUIDContext.Provider, { value: ref.current, children });\n}\n\ninterface FrameProps {\n  id: string;\n  className?: string;\n}\n\nfunction SimpleFrame(props: FrameProps) {\n  const { pixelHeight: height, width } = useContext(ColumnLayoutContext);\n  let { id: frameID, className } = props;\n  if (frameID.startsWith(\"#\")) {\n    frameID = frameID.slice(1);\n  }\n  return h(\"rect\", {\n    id: frameID,\n    x: 0,\n    y: 0,\n    width,\n    height,\n    className,\n  });\n}\n\ninterface GrainsizeFrameProps {\n  id: string;\n  zigZagBottom?: boolean;\n  zigZagTop?: boolean;\n}\n\nfunction GrainsizeFrame(props: GrainsizeFrameProps) {\n  let { id: frameID, zigZagBottom = false, zigZagTop = false } = props;\n\n  const { scale, divisions, grainsizeScale: gs } = useColumnLayout();\n  if (frameID.startsWith(\"#\")) {\n    frameID = frameID.slice(1);\n  }\n  if (divisions.length === 0) {\n    return null;\n  }\n\n  const [bottomOfSection, topOfSection] = scale.domain();\n\n  const topOf = function (d) {\n    let { top } = d;\n    if (top > topOfSection) {\n      top = topOfSection;\n    }\n    return scale(top);\n  };\n  const bottomOf = function (d) {\n    let { bottom } = d;\n    if (bottom < bottomOfSection) {\n      bottom = bottomOfSection;\n    }\n    return scale(bottom);\n  };\n\n  const filteredDivisions = Array.from(divisions).filter(function (d) {\n    if (d.top <= bottomOfSection) {\n      return false;\n    }\n    if (d.bottom > topOfSection) {\n      return false;\n    }\n    return true;\n  });\n\n  let d = path();\n  let currentGrainsize = \"m\";\n  let i = 0;\n  for (const div of filteredDivisions) {\n    if (i === 0) {\n      // First division\n      // start the path at the bottom\n      const y = bottomOf(div);\n      d.moveTo(0, y);\n    }\n    if (div.grainsize != null) {\n      currentGrainsize = div.grainsize;\n    }\n    const x1 = gs(currentGrainsize);\n    if (i === 0 && zigZagBottom) {\n      // Draw zig-zag at bottom\n      drawZigZagAtConstantHeight(d, 0, x1, bottomOf(div));\n    } else {\n      // Draw a normal line\n      d.lineTo(x1, bottomOf(div));\n    }\n\n    d.lineTo(x1, bottomOf(div));\n    d.lineTo(x1, topOf(div));\n\n    if (i === filteredDivisions.length - 1) {\n      // Last division\n      // Draw top\n      if (zigZagTop) {\n        drawZigZagAtConstantHeight(d, x1, 0, topOf(div));\n      } else {\n        d.lineTo(0, topOf(div));\n      }\n    }\n\n    i++;\n  }\n\n  d.closePath();\n\n  return h(\"path\", {\n    id: frameID,\n    key: frameID,\n    d: d.toString(),\n  });\n}\n\nconst ClipPath = function (props) {\n  let { id, children, ...rest } = props;\n  if (id.startsWith(\"#\")) {\n    id = id.slice(1);\n  }\n  return createElement(\"clipPath\", { id, key: id, ...rest }, children);\n};\n\nconst UseFrame = function (props) {\n  const { id: frameID, ...rest } = props;\n  return h(\"use.frame\", {\n    xlinkHref: frameID,\n    fill: \"transparent\",\n    key: \"frame\",\n    ...rest,\n  });\n};\n\nconst prefixID = function (\n  uuid: string,\n  prefixes: string[],\n): Record<string, string> {\n  const res = {};\n  for (let prefix of Array.from(prefixes)) {\n    res[prefix + \"ID\"] = `#${uuid}-${prefix}`;\n  }\n  return res;\n};\n\nexport interface ClipToFrameProps {\n  left: number;\n  shiftY: number;\n  onClick?: () => void;\n  frame?: any;\n  width?: number;\n  className?: string;\n  children?: ReactNode;\n  clip?: boolean;\n}\n\nexport function ClippingFrame(props: ClipToFrameProps) {\n  const {\n    left = 0,\n    shiftY = 0,\n    className,\n    onClick,\n    children,\n    frame = SimpleFrame,\n    clip = true,\n  } = props;\n\n  const uuid = useUUID();\n\n  const { frameID, clipID } = prefixID(uuid, [\"frame\", \"clip\"]);\n\n  let transform = null;\n  if (left != null) {\n    transform = `translate(${left} ${shiftY})`;\n  }\n\n  const frameClassName = \"clip-frame column-clip-frame\";\n\n  let _frame: ReactNode = h(frame, { id: frameID, className: frameClassName });\n  let defs = null;\n  let clipPath = null;\n  if (clip) {\n    defs = h(\"defs\", { key: \"defs\" }, [\n      _frame,\n      h(ClipPath, { id: clipID }, h(UseFrame, { id: frameID })),\n    ]);\n    clipPath = `url(${clipID})`;\n    _frame = h(UseFrame, { id: frameID, className: frameClassName });\n  }\n\n  return h(\"g\", { className, transform, onClick }, [\n    defs,\n    h(\"g.inner\", { clipPath }, children),\n    // Frame must go last\n    _frame,\n  ]);\n}\n\nexport {\n  SimpleFrame,\n  GrainsizeFrame,\n  ClipPath,\n  UUIDComponent,\n  UUIDProvider,\n  useUUID,\n};\n"],"names":["Component","createContext","useRef","useContext","h","ColumnLayoutContext","useColumnLayout","d","path","drawZigZagAtConstantHeight","createElement"],"mappings":"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"}