{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "dependencies": [],
  "description": "APG progressbar. Determinate (value + max) or indeterminate (omit value). role=progressbar with aria-valuemin/max/now. Zero interaction JS — server-safe when value is a prop. Indicator fill via structural inline size.",
  "files": [
    {
      "content": "/**\n * heidi-ui Progress — APG progressbar. Zero interaction JS (server-safe).\n * Determinate: pass `value` (and optional `max`, default 100).\n * Indeterminate: omit `value`. Requires `label` for the accessible name.\n */\n\nimport {\n  type ComponentPropsWithoutRef,\n  type CSSProperties,\n  type ReactNode,\n  type Ref\n} from \"react\";\nimport {\n  renderHeidiElement,\n  type HeidiIntrinsicHostProps\n} from \"../_internal/render-element\";\nimport { PROGRESS_CLASSES } from \"./progress.classes.generated\";\n\nexport type ProgressState = \"complete\" | \"indeterminate\" | \"loading\";\n\nfunction progressState(\n  value: number | undefined,\n  max: number\n): ProgressState {\n  if (value === undefined || !Number.isFinite(value)) {\n    return \"indeterminate\";\n  }\n\n  if (value >= max) {\n    return \"complete\";\n  }\n  return \"loading\";\n}\n\nfunction clampPercent(value: number, max: number): number {\n  if (max <= 0) {\n    return 0;\n  }\n  return Math.min(100, Math.max(0, (value / max) * 100));\n}\n\n/**\n * The ANNOUNCED value, clamped into the range it is announced against.\n *\n * ponytail: `percent` was clamped for the rendered bar while `aria-valuenow`\n * passed `value` raw, so `value={150} max={100}` drew a full bar and announced\n * \"150\" against `aria-valuemax=\"100\"` — the bar and the screen reader\n * disagreed, and the pair was self-contradictory on its own terms. Audit P12.\n * `max <= 0` keeps its existing meaning: `progressState` already resolves that\n * class of input (a zero-item task is \"complete\", not a perpetual 0%), so this\n * only pins the number, never the state.\n */\nfunction clampAnnouncedValue(value: number, max: number): number {\n  if (max <= 0) {\n    return 0;\n  }\n  return Math.min(max, Math.max(0, value));\n}\n\nexport type ProgressRootState = {\n  max: number;\n  state: ProgressState;\n  value: number | undefined;\n};\n\ntype ProgressRootNativeProps = Omit<\n  ComponentPropsWithoutRef<\"div\">,\n  | \"aria-label\"\n  | \"aria-valuemax\"\n  | \"aria-valuemin\"\n  | \"aria-valuenow\"\n  | \"children\"\n  | \"className\"\n  | \"ref\"\n  | \"role\"\n  | \"style\"\n>;\n\nexport type ProgressRootProps = HeidiIntrinsicHostProps<\n  ProgressRootState,\n  \"div\"\n> &\n  ProgressRootNativeProps & {\n    children?: ReactNode;\n    /** Accessible name for the progressbar (aria-label). Required. */\n    label: string;\n    max?: number;\n    ref?: Ref<HTMLDivElement>;\n    /** Omit for indeterminate. */\n    value?: number;\n  };\n\nexport function ProgressRoot({\n  children,\n  className,\n  label,\n  max = 100,\n  ref,\n  render,\n  style,\n  value,\n  ...nativeProps\n}: ProgressRootProps) {\n  // ponytail: Progress deliberately does NOT use _internal/range's\n  // normalizeRange (unlike Meter, whose adoption was equivalence-verified).\n  // Rebasing a degenerate max onto a synthetic 0-100 span inverts the honest\n  // states: `max=0, value=0` is a finished zero-item task (\"complete\"), but\n  // rebased to max=100 it reads as a perpetual 0% \"loading\"; `value=Infinity`\n  // likewise flipped \"complete\" → \"indeterminate\". Raw comparisons below are\n  // the pre-adoption behavior for every input class.\n  /*\n   * ponytail: a NON-FINITE max falls back to the documented default of 100; it\n   * does not make the component indeterminate. The lab story\n   * `progress--invalid` specifies exactly this — `max={NaN} value={50}` must\n   * render `aria-valuemax=\"100\"`, `aria-valuenow=\"50\"`, \"loading\", 50% — so a\n   * bad `max` prop degrades to the default scale rather than poisoning a bar\n   * that still has a perfectly good value.\n   *\n   * I got this wrong first: the earlier P12 follow-up made a non-finite max\n   * indeterminate, which is defensible in isolation and contradicted a\n   * specification that already existed in `static-controls.ts`. The lesson is\n   * the cheaper one — look for the spec before choosing the semantics.\n   *\n   * `Number.isFinite`, NOT `max > 0`: `max={0}` with `value={0}` is a finished\n   * zero-item task and must stay \"complete\", which the note above documents.\n   */\n  const resolvedMax = Number.isFinite(max) ? max : 100;\n  const state = progressState(value, resolvedMax);\n  const percent =\n    value === undefined ? undefined : clampPercent(value, resolvedMax);\n\n  return renderHeidiElement({\n    className: PROGRESS_CLASSES.root,\n    dataPart: \"progress-root\",\n    element: \"div\",\n    props: {\n      ...nativeProps,\n      \"aria-label\": label,\n      \"aria-valuemax\": state === \"indeterminate\" ? undefined : resolvedMax,\n      \"aria-valuemin\": state === \"indeterminate\" ? undefined : 0,\n      \"aria-valuenow\":\n        state === \"indeterminate\" || value === undefined\n          ? undefined\n          : clampAnnouncedValue(value, resolvedMax),\n      children: children ?? (\n        <ProgressIndicator\n          percent={percent}\n          state={state}\n        />\n      ),\n      \"data-state\": state,\n      ref,\n      role: \"progressbar\"\n    },\n    renderProps: { className, render, style },\n    state: { max, state, value }\n  });\n}\n\nexport type ProgressIndicatorState = { state: ProgressState };\n\ntype ProgressIndicatorNativeProps = Omit<\n  ComponentPropsWithoutRef<\"div\">,\n  \"children\" | \"className\" | \"ref\" | \"style\"\n>;\n\nexport type ProgressIndicatorProps = HeidiIntrinsicHostProps<\n  ProgressIndicatorState,\n  \"div\"\n> &\n  ProgressIndicatorNativeProps & {\n    children?: ReactNode;\n    /** @internal used by ProgressRoot default child */\n    percent?: number;\n    ref?: Ref<HTMLDivElement>;\n    /** @internal used by ProgressRoot default child */\n    state?: ProgressState;\n  };\n\nexport function ProgressIndicator({\n  children,\n  className,\n  percent,\n  ref,\n  render,\n  state = \"indeterminate\",\n  style,\n  ...nativeProps\n}: ProgressIndicatorProps) {\n  const structuralStyle: CSSProperties | undefined =\n    state === \"loading\" && percent !== undefined\n      ? { inlineSize: `${percent}%` }\n      : undefined;\n\n  return renderHeidiElement({\n    className: PROGRESS_CLASSES.indicator,\n    dataPart: \"progress-indicator\",\n    element: \"div\",\n    props: {\n      ...nativeProps,\n      children,\n      \"data-state\": state,\n      ref\n    },\n    renderProps: { className, render, style },\n    state: { state },\n    structuralStyle\n  });\n}\n\nexport const Progress = {\n  Indicator: ProgressIndicator,\n  Root: ProgressRoot\n} as const;\n",
      "path": "packages/heidi-ui/src/progress/progress.tsx",
      "target": "components/ui/heidi/progress/progress.tsx",
      "type": "registry:ui"
    },
    {
      "content": "/*\n * heidi-ui progress — STRUCTURAL CSS only. No --hui-*.\n */\n\n@layer heidi-ui-base {\n  .hui-progress-root {\n    block-size: 0.5rem;\n    display: block;\n    inline-size: 100%;\n    overflow: hidden;\n    position: relative;\n  }\n\n  .hui-progress-indicator {\n    block-size: 100%;\n    inline-size: 0;\n  }\n\n  .hui-progress-indicator[data-state=\"indeterminate\"] {\n    inline-size: 40%;\n  }\n\n  .hui-progress-indicator[data-state=\"loading\"] {\n    /* Width comes from structural inline style (percent of value/max). */\n    inline-size: 0;\n  }\n\n  .hui-progress-indicator[data-state=\"complete\"] {\n    inline-size: 100%;\n  }\n}\n",
      "path": "packages/heidi-ui/src/progress/progress.base.css",
      "target": "components/ui/heidi/progress/progress.base.css",
      "type": "registry:ui"
    },
    {
      "content": "/*\n * heidi-ui progress — VISUAL theme (opt-in). Consumes --hui-*.\n */\n\n@layer heidi-ui {\n  .hui-progress-root {\n    background: var(--hui-color-border-default);\n    border-radius: var(--hui-radius-md);\n  }\n\n  .hui-progress-indicator {\n    background: var(--hui-color-brand-primary);\n    border-radius: inherit;\n    transition-duration: var(--hui-duration-fast);\n    transition-property: inline-size;\n    transition-timing-function: var(--hui-ease-out);\n  }\n\n  .hui-progress-indicator[data-state=\"indeterminate\"] {\n    animation: hui-progress-indeterminate 1.2s var(--hui-ease-out) infinite;\n  }\n\n  @media (prefers-reduced-motion: reduce) {\n    .hui-progress-indicator {\n      animation: none;\n      transition-duration: 0s;\n    }\n\n    .hui-progress-indicator[data-state=\"indeterminate\"] {\n      animation: none;\n      transform: none;\n    }\n  }\n\n  @media (forced-colors: active) {\n    .hui-progress-root {\n      background: Canvas;\n      border: var(--hui-border-width) solid CanvasText;\n      box-sizing: border-box;\n      forced-color-adjust: none;\n    }\n\n    .hui-progress-indicator {\n      background: Highlight;\n    }\n  }\n}\n\n@keyframes hui-progress-indeterminate {\n  0% {\n    transform: translateX(-100%);\n  }\n  100% {\n    transform: translateX(250%);\n  }\n}\n",
      "path": "packages/heidi-ui/src/progress/progress.theme.css",
      "target": "components/ui/heidi/progress/progress.theme.css",
      "type": "registry:ui"
    },
    {
      "content": "/*\n * heidi-ui progress — aggregator.\n */\n\n@import \"./progress.base.css\";\n@import \"../../../../styles/heidi-ui-adapter.css\";\n@import \"./progress.theme.css\";\n",
      "path": "packages/heidi-ui/src/progress/progress.css",
      "target": "components/ui/heidi/progress/progress.css",
      "type": "registry:ui"
    },
    {
      "content": "/** GENERATED from packages/heidi-ui/src/progress/progress.base.css + packages/heidi-ui/src/progress/progress.theme.css — do not edit by hand.\n * Rebuild: `bun run hui:build`. Freshness: `bun run contracts:check`. */\nexport const PROGRESS_CLASSES = {\n  indicator: \"hui-progress-indicator\",\n  root: \"hui-progress-root\",\n} as const;\n",
      "path": "packages/heidi-ui/src/progress/progress.classes.generated.ts",
      "target": "components/ui/heidi/progress/progress.classes.generated.ts",
      "type": "registry:ui"
    },
    {
      "content": "/** GENERATED from progress.anatomy.json + progress.base.css + progress.theme.css — do not edit by hand.\n * Rebuild: `bun run hui:build`. Freshness: `bun run contracts:check`. */\n\nexport type ProgressState = \"complete\" | \"indeterminate\" | \"loading\";\n\nexport const PROGRESS_ANATOMY = {\n  \"component\": \"progress\",\n  \"description\": \"APG progressbar. Determinate (value + max) or indeterminate (omit value). role=progressbar with aria-valuemin/max/now. Zero interaction JS — server-safe when value is a prop. Indicator fill via structural inline size.\",\n  \"schemaVersion\": 2,\n  \"parts\": {\n    \"indicator\": {\n      \"aria\": {\n        \"owns\": [],\n        \"role\": null\n      },\n      \"class\": \"hui-progress-indicator\",\n      \"css\": {\n        \"structural\": [\n          \"block-size\",\n          \"inline-size\"\n        ]\n      },\n      \"dataPart\": \"progress-indicator\",\n      \"description\": \"Fill bar; width set structurally from value/max (or full when indeterminate).\",\n      \"element\": \"div\",\n      \"nativeProps\": true,\n      \"props\": [\n        \"className\",\n        \"ref\",\n        \"render\",\n        \"style\"\n      ],\n      \"pseudoStates\": [],\n      \"states\": {\n        \"data-state\": [\n          \"complete\",\n          \"indeterminate\",\n          \"loading\"\n        ]\n      }\n    },\n    \"root\": {\n      \"aria\": {\n        \"owns\": [\n          \"aria-label\",\n          \"aria-valuemax\",\n          \"aria-valuemin\",\n          \"aria-valuenow\"\n        ],\n        \"role\": \"progressbar\"\n      },\n      \"class\": \"hui-progress-root\",\n      \"css\": {\n        \"structural\": [\n          \"block-size\",\n          \"display\",\n          \"inline-size\",\n          \"overflow\",\n          \"position\"\n        ]\n      },\n      \"dataPart\": \"progress-root\",\n      \"description\": \"The progressbar track; requires an accessible name via label.\",\n      \"element\": \"div\",\n      \"nativeProps\": true,\n      \"props\": [\n        \"className\",\n        \"label\",\n        \"max\",\n        \"ref\",\n        \"render\",\n        \"style\",\n        \"value\"\n      ],\n      \"pseudoStates\": [],\n      \"states\": {\n        \"data-state\": [\n          \"complete\",\n          \"indeterminate\",\n          \"loading\"\n        ]\n      }\n    }\n  },\n  \"rootProps\": [\n    \"label\",\n    \"max\",\n    \"value\"\n  ],\n  \"tokens\": [\n    \"--hui-border-width\",\n    \"--hui-color-border-default\",\n    \"--hui-color-brand-primary\",\n    \"--hui-duration-fast\",\n    \"--hui-ease-out\",\n    \"--hui-radius-md\"\n  ]\n} as const;\n",
      "path": "packages/heidi-ui/src/progress/progress.anatomy.generated.ts",
      "target": "components/ui/heidi/progress/progress.anatomy.generated.ts",
      "type": "registry:ui"
    },
    {
      "content": "{\n  \"component\": \"progress\",\n  \"description\": \"APG progressbar. Determinate (value + max) or indeterminate (omit value). role=progressbar with aria-valuemin/max/now. Zero interaction JS — server-safe when value is a prop. Indicator fill via structural inline size.\",\n  \"schemaVersion\": 2,\n  \"parts\": {\n    \"indicator\": {\n      \"aria\": {\n        \"owns\": [],\n        \"role\": null\n      },\n      \"class\": \"hui-progress-indicator\",\n      \"css\": {\n        \"structural\": [\"block-size\", \"inline-size\"]\n      },\n      \"dataPart\": \"progress-indicator\",\n      \"description\": \"Fill bar; width set structurally from value/max (or full when indeterminate).\",\n      \"element\": \"div\",\n      \"nativeProps\": true,\n      \"props\": [\"className\", \"ref\", \"render\", \"style\"],\n      \"pseudoStates\": [],\n      \"states\": {\n        \"data-state\": [\"complete\", \"indeterminate\", \"loading\"]\n      }\n    },\n    \"root\": {\n      \"aria\": {\n        \"owns\": [\"aria-label\", \"aria-valuemax\", \"aria-valuemin\", \"aria-valuenow\"],\n        \"role\": \"progressbar\"\n      },\n      \"class\": \"hui-progress-root\",\n      \"css\": {\n        \"structural\": [\"block-size\", \"display\", \"inline-size\", \"overflow\", \"position\"]\n      },\n      \"dataPart\": \"progress-root\",\n      \"description\": \"The progressbar track; requires an accessible name via label.\",\n      \"element\": \"div\",\n      \"nativeProps\": true,\n      \"props\": [\"className\", \"label\", \"max\", \"ref\", \"render\", \"style\", \"value\"],\n      \"pseudoStates\": [],\n      \"states\": {\n        \"data-state\": [\"complete\", \"indeterminate\", \"loading\"]\n      }\n    }\n  },\n  \"rootProps\": [\"label\", \"max\", \"value\"]\n}\n",
      "path": "packages/heidi-ui/src/progress/progress.anatomy.json",
      "target": "components/ui/heidi/progress/progress.anatomy.json",
      "type": "registry:ui"
    },
    {
      "content": "/**\n * Shared host rendering for heidi-ui parts — Base-UI-shaped composition\n * (docs/HEIDI-UI-HEADLESS.md § 4 / HEIDI-UI.md § 4.5):\n *   - className / style as value or (state) => value\n *   - render as ReactElement or (props, state) => ReactElement\n *   - ref forwarding\n *   - data-hui-part always set (stable unstyled hook)\n *\n * Structural inline styles (e.g. anchorName) are merged last so a consumer\n * style override cannot drop platform wiring.\n */\n\nimport {\n  cloneElement,\n  createElement,\n  isValidElement,\n  type CSSProperties,\n  type ComponentPropsWithRef,\n  type HTMLAttributes,\n  type ReactElement,\n  type ReactNode,\n  type Ref,\n  type RefCallback\n} from \"react\";\n\nexport type HeidiClassName<State> = string | ((state: State) => string | undefined) | undefined;\n\nexport type HeidiStyle<State> =\n  | CSSProperties\n  | ((state: State) => CSSProperties | undefined)\n  | undefined;\n\nexport type HeidiRenderFn<State, Props> = (\n  props: Props,\n  state: State\n) => ReactElement;\n\nexport type HeidiRender<State, Props> =\n  | ReactElement\n  | HeidiRenderFn<State, Props>\n  | undefined;\n\ntype DefaultRenderProps = HTMLAttributes<HTMLElement> & { ref?: Ref<HTMLElement> };\n\nexport type HeidiHostProps<\n  State,\n  RenderProps extends object = DefaultRenderProps\n> = {\n  className?: HeidiClassName<State>;\n  render?: HeidiRender<State, RenderProps>;\n  style?: HeidiStyle<State>;\n};\n\nexport type HeidiIntrinsicHostProps<\n  State,\n  Tag extends keyof HTMLElementTagNameMap\n> = HeidiHostProps<State, ComponentPropsWithRef<Tag>>;\n\nfunction resolveClassName<State>(\n  className: HeidiClassName<State>,\n  state: State\n): string | undefined {\n  return typeof className === \"function\" ? className(state) : className;\n}\n\nfunction resolveStyle<State>(style: HeidiStyle<State>, state: State): CSSProperties | undefined {\n  return typeof style === \"function\" ? style(state) : style;\n}\n\nfunction mergeClassNames(...parts: Array<string | undefined>): string | undefined {\n  const merged = parts.filter(Boolean).join(\" \");\n  return merged.length > 0 ? merged : undefined;\n}\n\n/**\n * Compose a consumer event with library behavior. Consumers run first and may\n * cancel the component behavior with `event.preventDefault()`. Heidi keeps\n * this native-event convention intentionally: it avoids a second branded event\n * API while still making async/controlled actions vetoable.\n */\nexport function composeHeidiEventHandlers<Event extends { defaultPrevented: boolean }>(\n  consumer: ((event: Event) => void) | undefined,\n  library: (event: Event) => void\n): (event: Event) => void {\n  return (event) => {\n    consumer?.(event);\n    if (!event.defaultPrevented) {\n      library(event);\n    }\n  };\n}\n\n/** React 19-safe ref fan-out, including callback-ref cleanup functions. */\nexport function mergeHeidiRefs<Element>(\n  ...inputRefs: Array<Ref<Element> | undefined>\n): Ref<Element> | undefined {\n  const refs = Array.from(\n    new Set(\n      inputRefs.filter(\n        (ref): ref is Exclude<Ref<Element>, null> => ref != null\n      )\n    )\n  );\n  if (refs.length === 0) {\n    return undefined;\n  }\n  if (refs.length === 1) {\n    return refs[0];\n  }\n\n  let cache = mergedRefCache;\n  for (const ref of refs) {\n    const key = ref as object;\n    let child = cache.children.get(key);\n    if (!child) {\n      child = { children: new WeakMap() };\n      cache.children.set(key, child);\n    }\n    cache = child;\n  }\n  if (cache.callback) {\n    return cache.callback as RefCallback<Element>;\n  }\n\n  const callback: RefCallback<Element> = (node) => {\n    const cleanups: Array<() => void> = [];\n    for (const ref of refs) {\n      if (typeof ref === \"function\") {\n        const cleanup = ref(node);\n        if (node !== null) {\n          cleanups.push(typeof cleanup === \"function\" ? cleanup : () => ref(null));\n        }\n      } else if (ref) {\n        ref.current = node;\n        if (node !== null) {\n          cleanups.push(() => {\n            ref.current = null;\n          });\n        }\n      }\n    }\n    return cleanups.length > 0\n      ? () => {\n          for (const cleanup of cleanups) {\n            cleanup();\n          }\n        }\n      : undefined;\n  };\n  cache.callback = callback as RefCallback<unknown>;\n  return callback;\n}\n\ntype MergedRefCache = {\n  callback?: RefCallback<unknown>;\n  children: WeakMap<object, MergedRefCache>;\n};\n\nconst mergedRefCache: MergedRefCache = { children: new WeakMap() };\n\ntype UnknownHandler = (...args: never[]) => unknown;\n\nfunction isEventHandler(key: string, value: unknown): value is UnknownHandler {\n  return /^on[A-Z]/.test(key) && typeof value === \"function\";\n}\n\nfunction defaultPrevented(args: unknown[]): boolean {\n  const event = args[0];\n  return (\n    typeof event === \"object\" &&\n    event !== null &&\n    \"defaultPrevented\" in event &&\n    event.defaultPrevented === true\n  );\n}\n\nfunction composeUnknownHandlers(\n  consumer: UnknownHandler,\n  library: UnknownHandler\n): UnknownHandler {\n  if (consumer === library) {\n    return library;\n  }\n  return ((...args: unknown[]) => {\n    (consumer as (...handlerArgs: unknown[]) => unknown)(...args);\n    if (!defaultPrevented(args)) {\n      (library as (...handlerArgs: unknown[]) => unknown)(...args);\n    }\n  }) as UnknownHandler;\n}\n\n/** Library-owned host props — permissive so button `type`, `data-*`, `popover`, etc. type-check. */\nexport type HeidiElementProps<Tag extends keyof HTMLElementTagNameMap> = Record<\n  string,\n  unknown\n> & {\n  children?: ReactNode;\n  className?: string;\n  ref?: Ref<HTMLElementTagNameMap[Tag]>;\n  style?: CSSProperties;\n};\n\ntype RenderElementParams<\n  State,\n  Tag extends keyof HTMLElementTagNameMap,\n  RenderProps extends object = DefaultRenderProps\n> = {\n  /** Default class from the generated hui-* map (theme/base target). */\n  className?: string;\n  /** Stable machine hook — always emitted. */\n  dataPart: string;\n  /** Intrinsic tag when `render` is omitted. */\n  element: Tag;\n  /** Props the library owns (aria, ids, handlers, popover, …). */\n  props: HeidiElementProps<Tag>;\n  /** Optional consumer composition props. */\n  renderProps?: HeidiHostProps<State, RenderProps>;\n  /** Typed state passed to functional className/style/render. */\n  state: State;\n  /** Structural inline styles that must survive consumer style merges. */\n  structuralStyle?: CSSProperties;\n  /**\n   * Render-element handlers to remove instead of composing. This is reserved\n   * for states such as a focusable disabled composite item where the public\n   * contract requires press handlers to be completely inert.\n   */\n  suppressRenderedHandlers?: readonly string[];\n};\n\n/**\n * Render a heidi-ui host element with optional Base-shaped composition.\n */\nexport function renderHeidiElement<\n  State,\n  Tag extends keyof HTMLElementTagNameMap,\n  RenderProps extends object = DefaultRenderProps\n>(\n  params: RenderElementParams<State, Tag, RenderProps>\n): ReactElement {\n  const {\n    className,\n    dataPart,\n    element,\n    props,\n    renderProps,\n    state,\n    structuralStyle,\n    suppressRenderedHandlers\n  } = params;\n  const consumerClass = resolveClassName(renderProps?.className, state);\n  const consumerStyle = resolveStyle(renderProps?.style, state);\n  const mergedStyle: CSSProperties | undefined =\n    props.style || consumerStyle || structuralStyle\n      ? { ...props.style, ...consumerStyle, ...structuralStyle }\n      : undefined;\n\n  const outProps: HTMLAttributes<HTMLElement> & {\n    \"data-hui-part\": string;\n    ref?: Ref<HTMLElement>;\n  } = {\n    ...(props as HTMLAttributes<HTMLElement> & { ref?: Ref<HTMLElement> }),\n    className: mergeClassNames(consumerClass, className),\n    \"data-hui-part\": dataPart,\n    style: mergedStyle\n  };\n\n  const render = renderProps?.render;\n  if (typeof render === \"function\") {\n    // Post-merge the returned element as well. This deliberately makes the\n    // stable data hook, owned semantics, refs, and internal handlers survive\n    // even when a render function forgets to spread one of the supplied props.\n    return mergeRenderedElement(\n      render(outProps as unknown as RenderProps, state),\n      outProps,\n      dataPart,\n      structuralStyle,\n      suppressRenderedHandlers\n    );\n  }\n  if (isValidElement(render)) {\n    return mergeRenderedElement(\n      render,\n      outProps,\n      dataPart,\n      structuralStyle,\n      suppressRenderedHandlers\n    );\n  }\n\n  return createElement(element, outProps as never, props.children);\n}\n\ntype RenderedProps = Record<string, unknown> & {\n  children?: ReactNode;\n  className?: string;\n  ref?: Ref<HTMLElement>;\n  style?: CSSProperties;\n};\n\nfunction mergeRenderedElement(\n  element: ReactElement,\n  libraryProps: HTMLAttributes<HTMLElement> & {\n    \"data-hui-part\": string;\n    ref?: Ref<HTMLElement>;\n  },\n  dataPart: string,\n  structuralStyle: CSSProperties | undefined,\n  suppressRenderedHandlers: readonly string[] | undefined\n): ReactElement {\n  const rendered = element as ReactElement<RenderedProps>;\n  const renderedProps = rendered.props;\n  const renderedClass =\n    renderedProps.className === libraryProps.className\n      ? undefined\n      : renderedProps.className;\n  const merged: RenderedProps = {\n    ...renderedProps,\n    ...libraryProps,\n    className: mergeClassNames(renderedClass, libraryProps.className),\n    \"data-hui-part\": dataPart,\n    ref: mergeHeidiRefs(libraryProps.ref, renderedProps.ref),\n    style: {\n      ...libraryProps.style,\n      ...renderedProps.style,\n      ...structuralStyle\n    }\n  };\n\n  if (Object.prototype.hasOwnProperty.call(renderedProps, \"children\")) {\n    merged.children = renderedProps.children;\n  }\n\n  const suppressedHandlers = suppressRenderedHandlers\n    ? new Set(suppressRenderedHandlers)\n    : null;\n  for (const key of new Set([...Object.keys(renderedProps), ...Object.keys(libraryProps)])) {\n    const consumer = renderedProps[key];\n    const library = (libraryProps as unknown as Record<string, unknown>)[key];\n    if (suppressedHandlers?.has(key)) {\n      merged[key] = library;\n      continue;\n    }\n    if (isEventHandler(key, consumer) && isEventHandler(key, library)) {\n      merged[key] = composeUnknownHandlers(consumer, library);\n    }\n  }\n\n  return cloneElement(rendered, merged as never);\n}\n",
      "path": "packages/heidi-ui/src/_internal/render-element.ts",
      "target": "components/ui/heidi/_internal/render-element.ts",
      "type": "registry:ui"
    }
  ],
  "name": "progress",
  "registryDependencies": [
    "@heidi-ui/heidi-tokens"
  ],
  "title": "Progress",
  "type": "registry:ui"
}
