{"version":3,"sources":["../../src/utils/composeComponent.ts"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport type { JSXElement, RefAttributes } from '@fluentui/react-utilities';\n\n/**\n * Hook creating the state of a component from its props and ref.\n */\nexport type StateHook<Props, State, RefType> = (props: Props, ref: React.Ref<RefType>) => State;\n\n/**\n * Hook mapping the state of a component to the context values its render function passes down.\n */\nexport type ContextValuesHook<State, ContextValues> = (state: State) => ContextValues;\n\n/**\n * Function rendering a component from its state.\n */\nexport type RenderFn<State, Result extends JSXElement | null = JSXElement | null> = (state: State) => Result;\n\n/**\n * Function rendering a component from its state and the context values returned by its `ContextValuesHook`.\n */\nexport type RenderWithContextValuesFn<State, ContextValues, Result extends JSXElement | null = JSXElement | null> = (\n  state: State,\n  contextValues: ContextValues,\n) => Result;\n\ntype ComposeComponentFnArgs<State, ContextValues, UseState> =\n  | [useState: UseState, render: RenderFn<State>]\n  | [\n      useState: UseState,\n      useGetContextValues: ContextValuesHook<State, ContextValues>,\n      render: RenderWithContextValuesFn<State, ContextValues>,\n    ];\n\ntype ForwardRefComponent<Props, RefType> = React.ForwardRefExoticComponent<\n  React.PropsWithoutRef<Props> & RefAttributes<RefType>\n>;\n\ntype Component<Props, Result extends JSXElement | null> = {\n  (props: Props): Result;\n  displayName: string;\n};\n\n/**\n * Composes a headless component from its state hook and render function, optionally deriving context values\n * before rendering.\n *\n * Every headless component has the same shape: `state = useX(props, ref)`,\n * `contextValues = useXContextValues(state)` and `renderX(state, contextValues)`. Sharing the `forwardRef` wrapper\n * keeps that boilerplate out of each component, which adds up across the whole library.\n *\n * Supports `useState, render` and `useState, useGetContextValues, render` after the display name.\n * The component function is picked once, when the component is composed, based on the number of arguments.\n * A component therefore always calls the same hooks in the same order.\n *\n * Arguments are positional on purpose: an options object would repeat its property names in every component, and\n * minifiers don't mangle property names.\n *\n * ```ts\n * export const Foo: ForwardRefComponent<FooProps> = composeComponent(\n *   'Foo',\n *   useFoo,\n *   useFooContextValues,\n *   renderFoo,\n * );\n * ```\n *\n * Components annotate the call as pure (the `__PURE__` annotation comment), so that unused components can be\n * tree-shaken by bundlers that don't honor `sideEffects: false`.\n *\n * @param displayName - display name of the component, always set so it is available in production as well\n * @param useState - state hook of the component\n * @param render - render function of the component. It receives the context values as the second argument when\n * `useGetContextValues` is provided.\n *\n * @internal\n */\nexport function composeComponent<Props, State, RefType>(\n  displayName: string,\n  useState: StateHook<Props, State, RefType>,\n  render: RenderFn<State>,\n): ForwardRefComponent<Props, RefType>;\nexport function composeComponent<Props, State, RefType, ContextValues>(\n  displayName: string,\n  useState: StateHook<Props, State, RefType>,\n  useGetContextValues: ContextValuesHook<State, ContextValues>,\n  render: RenderWithContextValuesFn<State, ContextValues>,\n): ForwardRefComponent<Props, RefType>;\nexport function composeComponent<Props, State, RefType, ContextValues>(\n  displayName: string,\n  ...args: ComposeComponentFnArgs<State, ContextValues, StateHook<React.PropsWithoutRef<Props>, State, RefType>>\n): ForwardRefComponent<Props, RefType> {\n  const Component = React.forwardRef<RefType, Props>(createRender(...args));\n\n  Component.displayName = displayName;\n\n  return Component;\n}\n\n/**\n * Composes a plain function component using the same pipelines as {@link composeComponent}, without a\n * `forwardRef` wrapper. The state hook accepts props only, and the result does not add a ref prop.\n *\n * Pass the display name and state hook, then an optional context hook, with the renderer last.\n * Annotate calls as pure for tree-shaking.\n *\n * @internal\n */\nexport function composeComponentWithoutRef<Props, State, Result extends JSXElement | null>(\n  displayName: string,\n  useState: (props: Props) => State,\n  render: RenderFn<State, Result>,\n): Component<Props, Result>;\nexport function composeComponentWithoutRef<Props, State, ContextValues, Result extends JSXElement | null>(\n  displayName: string,\n  useState: (props: Props) => State,\n  useGetContextValues: ContextValuesHook<State, ContextValues>,\n  render: RenderWithContextValuesFn<State, ContextValues, Result>,\n): Component<Props, Result>;\nexport function composeComponentWithoutRef<Props, State, ContextValues>(\n  displayName: string,\n  ...args: ComposeComponentFnArgs<State, ContextValues, (props: Props) => State>\n): Component<Props, JSXElement | null> {\n  const Component = createRender<Props, State, never, ContextValues>(...args) as Component<Props, JSXElement | null>;\n\n  Component.displayName = displayName;\n\n  return Component;\n}\n\n/**\n * Creates a render function for a composed component based on the provided hooks and renderer.\n * Handles state, optional context values, and render functions.\n */\nfunction createRender<Props, State, RefType, ContextValues>(\n  ...args: ComposeComponentFnArgs<State, ContextValues, StateHook<Props, State, RefType>>\n): (props: Props, ref: React.Ref<RefType>) => JSXElement | null {\n  if (args.length === 2) {\n    const [useState, render] = args;\n\n    return (...params) => render(useState(...params));\n  } else {\n    const [useState, useGetContextValues, render] = args;\n\n    return (...params) => {\n      const state = useState(...params);\n      return render(state, useGetContextValues(state));\n    };\n  }\n}\n"],"names":["composeComponent","composeComponentWithoutRef","displayName","args","Component","React","forwardRef","createRender","length","useState","render","params","useGetContextValues","state"],"mappings":"AAAA;;;;;;;;;;;;QA0FgBA;eAAAA;;QA+BAC;eAAAA;;;;iEAvHO;AAwFhB,SAASD,iBACdE,WAAmB,EACnB,GAAGC,IAA2G;IAE9G,MAAMC,YAAYC,OAAMC,UAAU,CAAiBC,gBAAgBJ;IAEnEC,UAAUF,WAAW,GAAGA;IAExB,OAAOE;AACT;AAsBO,SAASH,2BACdC,WAAmB,EACnB,GAAGC,IAA2E;IAE9E,MAAMC,YAAYG,gBAAoDJ;IAEtEC,UAAUF,WAAW,GAAGA;IAExB,OAAOE;AACT;AAEA;;;CAGC,GACD,SAASG,aACP,GAAGJ,IAAoF;IAEvF,IAAIA,KAAKK,MAAM,KAAK,GAAG;QACrB,MAAM,CAACC,UAAUC,OAAO,GAAGP;QAE3B,OAAO,CAAC,GAAGQ,SAAWD,OAAOD,YAAYE;IAC3C,OAAO;QACL,MAAM,CAACF,UAAUG,qBAAqBF,OAAO,GAAGP;QAEhD,OAAO,CAAC,GAAGQ;YACT,MAAME,QAAQJ,YAAYE;YAC1B,OAAOD,OAAOG,OAAOD,oBAAoBC;QAC3C;IACF;AACF"}