@acronis-platform/ui-react 0.57.1 → 0.60.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (170) hide show
  1. package/dist/components/ui/area-chart/area-chart.js +177 -0
  2. package/dist/components/ui/area-chart/area-chart.js.map +1 -0
  3. package/dist/components/ui/bar-chart/bar-chart.js +184 -78
  4. package/dist/components/ui/bar-chart/bar-chart.js.map +1 -1
  5. package/dist/components/ui/button-icon-input/button-icon-input.js +36 -0
  6. package/dist/components/ui/button-icon-input/button-icon-input.js.map +1 -0
  7. package/dist/components/ui/button-menu/button-menu.js +1 -1
  8. package/dist/components/ui/button-menu/button-menu.js.map +1 -1
  9. package/dist/components/ui/calendar/calendar.js +17 -15
  10. package/dist/components/ui/calendar/calendar.js.map +1 -1
  11. package/dist/components/ui/card-filter/card-filter.js +40 -27
  12. package/dist/components/ui/card-filter/card-filter.js.map +1 -1
  13. package/dist/components/ui/carousel-dialog/carousel-dialog.js +87 -0
  14. package/dist/components/ui/carousel-dialog/carousel-dialog.js.map +1 -0
  15. package/dist/components/ui/category-bar/category-bar.js +126 -0
  16. package/dist/components/ui/category-bar/category-bar.js.map +1 -0
  17. package/dist/components/ui/chart/chart-format.js +40 -0
  18. package/dist/components/ui/chart/chart-format.js.map +1 -0
  19. package/dist/components/ui/chart/chart.js.map +1 -1
  20. package/dist/components/ui/chart-state/chart-state.js +42 -0
  21. package/dist/components/ui/chart-state/chart-state.js.map +1 -0
  22. package/dist/components/ui/chip/chip.js +13 -13
  23. package/dist/components/ui/chip/chip.js.map +1 -1
  24. package/dist/components/ui/composed-chart/composed-chart.js +135 -0
  25. package/dist/components/ui/composed-chart/composed-chart.js.map +1 -0
  26. package/dist/components/ui/confidence-cone/confidence-cone.js +223 -0
  27. package/dist/components/ui/confidence-cone/confidence-cone.js.map +1 -0
  28. package/dist/components/ui/date-range-picker/date-range-picker.js +21 -21
  29. package/dist/components/ui/date-range-picker/date-range-picker.js.map +1 -1
  30. package/dist/components/ui/dialog/dialog.js +248 -76
  31. package/dist/components/ui/dialog/dialog.js.map +1 -1
  32. package/dist/components/ui/dialog-footer-carousel/dialog-footer-carousel.js +57 -0
  33. package/dist/components/ui/dialog-footer-carousel/dialog-footer-carousel.js.map +1 -0
  34. package/dist/components/ui/dialog-footer-default/dialog-footer-default.js +26 -0
  35. package/dist/components/ui/dialog-footer-default/dialog-footer-default.js.map +1 -0
  36. package/dist/components/ui/dialog-welcome/dialog-welcome.js +272 -0
  37. package/dist/components/ui/dialog-welcome/dialog-welcome.js.map +1 -0
  38. package/dist/components/ui/dropdown-menu/dropdown-menu.js +21 -21
  39. package/dist/components/ui/dropdown-menu/dropdown-menu.js.map +1 -1
  40. package/dist/components/ui/filter-search/filter-search.js +91 -90
  41. package/dist/components/ui/filter-search/filter-search.js.map +1 -1
  42. package/dist/components/ui/funnel-chart/funnel-chart.js +87 -0
  43. package/dist/components/ui/funnel-chart/funnel-chart.js.map +1 -0
  44. package/dist/components/ui/histogram/histogram.js +136 -0
  45. package/dist/components/ui/histogram/histogram.js.map +1 -0
  46. package/dist/components/ui/input/input.js.map +1 -1
  47. package/dist/components/ui/input-otp/input-otp.js +104 -0
  48. package/dist/components/ui/input-otp/input-otp.js.map +1 -0
  49. package/dist/components/ui/input-password/input-password.js +120 -0
  50. package/dist/components/ui/input-password/input-password.js.map +1 -0
  51. package/dist/components/ui/input-text/input-text.js +9 -9
  52. package/dist/components/ui/input-text/input-text.js.map +1 -1
  53. package/dist/components/ui/line-chart/line-chart.js +234 -0
  54. package/dist/components/ui/line-chart/line-chart.js.map +1 -0
  55. package/dist/components/ui/link/link.js +5 -5
  56. package/dist/components/ui/link/link.js.map +1 -1
  57. package/dist/components/ui/loading/loading.js +79 -0
  58. package/dist/components/ui/loading/loading.js.map +1 -0
  59. package/dist/components/ui/meter/meter.js +93 -0
  60. package/dist/components/ui/meter/meter.js.map +1 -0
  61. package/dist/components/ui/metric/metric.js +185 -0
  62. package/dist/components/ui/metric/metric.js.map +1 -0
  63. package/dist/components/ui/pie-chart/pie-chart.js +113 -0
  64. package/dist/components/ui/pie-chart/pie-chart.js.map +1 -0
  65. package/dist/components/ui/popover/popover.js +57 -27
  66. package/dist/components/ui/popover/popover.js.map +1 -1
  67. package/dist/components/ui/radar-chart/radar-chart.js +74 -0
  68. package/dist/components/ui/radar-chart/radar-chart.js.map +1 -0
  69. package/dist/components/ui/radial-bar-chart/radial-bar-chart.js +69 -0
  70. package/dist/components/ui/radial-bar-chart/radial-bar-chart.js.map +1 -0
  71. package/dist/components/ui/sankey-chart/sankey-chart.js +192 -0
  72. package/dist/components/ui/sankey-chart/sankey-chart.js.map +1 -0
  73. package/dist/components/ui/scatter-chart/scatter-chart.js +130 -0
  74. package/dist/components/ui/scatter-chart/scatter-chart.js.map +1 -0
  75. package/dist/components/ui/search/search.js +16 -16
  76. package/dist/components/ui/search/search.js.map +1 -1
  77. package/dist/components/ui/sheet/sheet-details.js +16 -16
  78. package/dist/components/ui/sheet/sheet-details.js.map +1 -1
  79. package/dist/components/ui/spinner/spinner.js.map +1 -1
  80. package/dist/components/ui/timeline/timeline.js +175 -0
  81. package/dist/components/ui/timeline/timeline.js.map +1 -0
  82. package/dist/components/ui/toolbar/toolbar.js +82 -92
  83. package/dist/components/ui/toolbar/toolbar.js.map +1 -1
  84. package/dist/components/ui/treemap/treemap.js +83 -0
  85. package/dist/components/ui/treemap/treemap.js.map +1 -0
  86. package/dist/components/ui/trend-indicator/trend-indicator.js +97 -0
  87. package/dist/components/ui/trend-indicator/trend-indicator.js.map +1 -0
  88. package/dist/index.js +461 -400
  89. package/dist/index.js.map +1 -1
  90. package/dist/lib/breakpoints.js +9 -6
  91. package/dist/lib/breakpoints.js.map +1 -1
  92. package/dist/node_modules/.pnpm/embla-carousel-react@8.6.0_react@19.2.6/node_modules/embla-carousel-react/esm/embla-carousel-react.esm.js +25 -0
  93. package/dist/node_modules/.pnpm/embla-carousel-react@8.6.0_react@19.2.6/node_modules/embla-carousel-react/esm/embla-carousel-react.esm.js.map +1 -0
  94. package/dist/node_modules/.pnpm/embla-carousel-reactive-utils@8.6.0_embla-carousel@8.6.0/node_modules/embla-carousel-reactive-utils/esm/embla-carousel-reactive-utils.esm.js +36 -0
  95. package/dist/node_modules/.pnpm/embla-carousel-reactive-utils@8.6.0_embla-carousel@8.6.0/node_modules/embla-carousel-reactive-utils/esm/embla-carousel-reactive-utils.esm.js.map +1 -0
  96. package/dist/node_modules/.pnpm/embla-carousel@8.6.0/node_modules/embla-carousel/esm/embla-carousel.esm.js +1205 -0
  97. package/dist/node_modules/.pnpm/embla-carousel@8.6.0/node_modules/embla-carousel/esm/embla-carousel.esm.js.map +1 -0
  98. package/dist/react.js +461 -400
  99. package/dist/react.js.map +1 -1
  100. package/dist/src/components/ui/area-chart/area-chart.d.ts +34 -0
  101. package/dist/src/components/ui/area-chart/index.d.ts +1 -0
  102. package/dist/src/components/ui/avatar/avatar.d.ts +1 -1
  103. package/dist/src/components/ui/bar-chart/bar-chart.d.ts +30 -5
  104. package/dist/src/components/ui/bar-chart/index.d.ts +1 -1
  105. package/dist/src/components/ui/button-icon-input/button-icon-input.d.ts +21 -0
  106. package/dist/src/components/ui/button-icon-input/index.d.ts +1 -0
  107. package/dist/src/components/ui/card-filter/card-filter.d.ts +5 -0
  108. package/dist/src/components/ui/carousel-dialog/carousel-dialog.d.ts +28 -0
  109. package/dist/src/components/ui/carousel-dialog/index.d.ts +1 -0
  110. package/dist/src/components/ui/category-bar/category-bar.d.ts +51 -0
  111. package/dist/src/components/ui/category-bar/index.d.ts +1 -0
  112. package/dist/src/components/ui/chart/__tests__/chart-format.test.d.ts +1 -0
  113. package/dist/src/components/ui/chart/chart-format.d.ts +111 -0
  114. package/dist/src/components/ui/chart/chart.d.ts +2 -0
  115. package/dist/src/components/ui/chart/index.d.ts +3 -1
  116. package/dist/src/components/ui/chart-state/chart-state.d.ts +11 -0
  117. package/dist/src/components/ui/chart-state/index.d.ts +1 -0
  118. package/dist/src/components/ui/composed-chart/composed-chart.d.ts +33 -0
  119. package/dist/src/components/ui/composed-chart/index.d.ts +1 -0
  120. package/dist/src/components/ui/confidence-cone/confidence-cone.d.ts +62 -0
  121. package/dist/src/components/ui/confidence-cone/index.d.ts +1 -0
  122. package/dist/src/components/ui/dialog/dialog.d.ts +105 -9
  123. package/dist/src/components/ui/dialog/dialog.docs.d.ts +82 -5
  124. package/dist/src/components/ui/dialog/index.d.ts +1 -1
  125. package/dist/src/components/ui/dialog-footer-carousel/dialog-footer-carousel.d.ts +9 -0
  126. package/dist/src/components/ui/dialog-footer-carousel/index.d.ts +1 -0
  127. package/dist/src/components/ui/dialog-footer-default/dialog-footer-default.d.ts +11 -0
  128. package/dist/src/components/ui/dialog-footer-default/index.d.ts +1 -0
  129. package/dist/src/components/ui/dialog-welcome/dialog-welcome.d.ts +54 -0
  130. package/dist/src/components/ui/dialog-welcome/dialog-welcome.docs.d.ts +55 -0
  131. package/dist/src/components/ui/dialog-welcome/index.d.ts +1 -0
  132. package/dist/src/components/ui/filter-search/filter-search.d.ts +1 -1
  133. package/dist/src/components/ui/funnel-chart/funnel-chart.d.ts +39 -0
  134. package/dist/src/components/ui/funnel-chart/index.d.ts +1 -0
  135. package/dist/src/components/ui/histogram/histogram.d.ts +40 -0
  136. package/dist/src/components/ui/histogram/index.d.ts +1 -0
  137. package/dist/src/components/ui/input-otp/index.d.ts +1 -0
  138. package/dist/src/components/ui/input-otp/input-otp.d.ts +23 -0
  139. package/dist/src/components/ui/input-password/index.d.ts +1 -0
  140. package/dist/src/components/ui/input-password/input-password.d.ts +21 -0
  141. package/dist/src/components/ui/line-chart/index.d.ts +1 -0
  142. package/dist/src/components/ui/line-chart/line-chart.d.ts +68 -0
  143. package/dist/src/components/ui/loading/index.d.ts +1 -0
  144. package/dist/src/components/ui/loading/loading.d.ts +13 -0
  145. package/dist/src/components/ui/meter/index.d.ts +1 -0
  146. package/dist/src/components/ui/meter/meter.d.ts +25 -0
  147. package/dist/src/components/ui/metric/index.d.ts +1 -0
  148. package/dist/src/components/ui/metric/metric.d.ts +37 -0
  149. package/dist/src/components/ui/pie-chart/index.d.ts +1 -0
  150. package/dist/src/components/ui/pie-chart/pie-chart.d.ts +54 -0
  151. package/dist/src/components/ui/popover/index.d.ts +1 -1
  152. package/dist/src/components/ui/popover/popover.d.ts +13 -1
  153. package/dist/src/components/ui/radar-chart/index.d.ts +1 -0
  154. package/dist/src/components/ui/radar-chart/radar-chart.d.ts +40 -0
  155. package/dist/src/components/ui/radial-bar-chart/index.d.ts +1 -0
  156. package/dist/src/components/ui/radial-bar-chart/radial-bar-chart.d.ts +45 -0
  157. package/dist/src/components/ui/sankey-chart/index.d.ts +2 -0
  158. package/dist/src/components/ui/sankey-chart/sankey-chart.d.ts +69 -0
  159. package/dist/src/components/ui/scatter-chart/index.d.ts +1 -0
  160. package/dist/src/components/ui/scatter-chart/scatter-chart.d.ts +35 -0
  161. package/dist/src/components/ui/stack/stack.d.ts +1 -1
  162. package/dist/src/components/ui/timeline/index.d.ts +1 -0
  163. package/dist/src/components/ui/timeline/timeline.d.ts +41 -0
  164. package/dist/src/components/ui/treemap/index.d.ts +1 -0
  165. package/dist/src/components/ui/treemap/treemap.d.ts +44 -0
  166. package/dist/src/components/ui/trend-indicator/index.d.ts +1 -0
  167. package/dist/src/components/ui/trend-indicator/trend-indicator.d.ts +32 -0
  168. package/dist/src/index.d.ts +27 -2
  169. package/dist/ui-react.css +1 -1
  170. package/package.json +5 -4
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sankey-chart.js","sources":["../../../../src/components/ui/sankey-chart/sankey-chart.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { Sankey as RechartsSankey, Rectangle } from 'recharts';\n\nimport { cn } from '@/lib/utils';\nimport {\n ChartContainer,\n ChartStyle,\n ChartTooltip,\n type ChartConfig,\n} from '../chart';\n\n// A typed recharts composition over the shared `Chart` primitives — a flow\n// diagram where link width is proportional to the value flowing between nodes.\n// Like Treemap/Funnel it's a single recharts element (`<Sankey>`) themed through\n// custom `node` / `link` renderers (recharts' defaults paint one flat grey and\n// carry no token hooks). No CVA variant: a Sankey's expressiveness is the\n// nodes/links graph + geometry (plain props), not a visual \"mode\".\n//\n// Node `name`s are the color keys: each must match a `config` entry, so they\n// must be CSS-safe (they become part of a `--color-<name>` custom property).\n// The human-readable text comes from `config[name].label`.\n\n/** A node in the flow — `name` is its color/config key (CSS-safe, unique). */\nexport interface SankeyChartNode {\n name: string;\n}\n\n/** A directed flow between two nodes, referenced by their index in `nodes`. */\nexport interface SankeyChartLink {\n /** Index of the source node in `data.nodes`. */\n source: number;\n /** Index of the target node in `data.nodes`. */\n target: number;\n /** Flow magnitude — drives the link's width. */\n value: number;\n /**\n * Ribbon color (any CSS color, e.g. a `var(--ui-*)` token), rendered at **full\n * opacity** so it matches its node bar. Omit to use the target node's color at\n * 35% (the default tinted ribbon).\n */\n color?: string;\n}\n\nexport interface SankeyChartProps\n extends Omit<React.ComponentProps<'div'>, 'children'> {\n /** The graph: `nodes` (color keys) + `links` (source/target indices + value). */\n data: {\n nodes: ReadonlyArray<SankeyChartNode>;\n links: ReadonlyArray<SankeyChartLink>;\n };\n /**\n * Per-node map of `label` / `color`, keyed by the node's `name` (imported from\n * the shared `Chart` primitives). Turned into `--color-<name>` custom\n * properties. Colors are caller-supplied — reference an existing semantic\n * `--ui-*` token; there is no chart palette tier yet.\n */\n config: ChartConfig;\n /** Vertical gap between nodes in the same column. */\n nodePadding?: number;\n /** Thickness of each node bar. */\n nodeWidth?: number;\n /** Curviness of the links (0 = straight, 1 = fully curved). */\n linkCurvature?: number;\n /**\n * Sort nodes vertically to minimize link crossings (recharts' relaxation).\n * Defaults to `false` — nodes render in the order given by `data.nodes` within\n * each column, which keeps curated flows tidy; set `true` to auto-order.\n */\n sort?: boolean;\n /** Render each node's label (from `config[name].label`) beside its bar. */\n showLabels?: boolean;\n /** Render a legend (color dot + label + value + % per node) below the chart. */\n showLegend?: boolean;\n /** Show a hover tooltip on nodes and links (dot + `source → target` + value). */\n showTooltip?: boolean;\n /**\n * Replace the default tooltip. Pass a configured `ChartTooltipContent`\n * (imported from this library) — e.g. with a `formatter` / `labelFormatter` —\n * to customize formatting without composing recharts yourself. Ignored when\n * `showTooltip` is false.\n */\n tooltipContent?: React.ComponentProps<typeof ChartTooltip>['content'];\n}\n\n// recharts injects these into the `node` / `link` render functions but doesn't\n// export their prop types from the package root, so we type the fields we use\n// (structurally compatible with recharts' internal NodeProps / LinkProps).\ninterface SankeyNodeShapeProps {\n x: number;\n y: number;\n width: number;\n height: number;\n index: number;\n payload: { name: string; value: number };\n}\n\ninterface SankeyLinkShapeProps {\n sourceX: number;\n targetX: number;\n sourceY: number;\n targetY: number;\n sourceControlX: number;\n targetControlX: number;\n linkWidth: number;\n // recharts spreads the original link onto `payload` (then overrides\n // source/target with node objects), so a custom `color` survives here.\n payload: {\n source: { name: string };\n target: { name: string };\n value: number;\n color?: string;\n };\n}\n\n// Node bar: a rect filled from `--color-<name>`, with the config label placed on\n// whichever side keeps it inside the plot — to the right for nodes that have\n// outgoing links (sources), to the left for terminal nodes (sinks).\nfunction makeNodeRenderer(\n config: ChartConfig,\n sourceIndices: ReadonlySet<number>,\n showLabels: boolean\n) {\n return function SankeyNodeShape({\n x,\n y,\n width,\n height,\n index,\n payload,\n }: SankeyNodeShapeProps) {\n const name = String(payload.name);\n const label = config[name]?.label ?? name;\n const isSource = sourceIndices.has(index);\n return (\n <g>\n <Rectangle\n x={x}\n y={y}\n width={width}\n height={height}\n fill={`var(--color-${name})`}\n radius={2}\n />\n {showLabels && (\n <text\n x={isSource ? x + width + 6 : x - 6}\n y={y + height / 2}\n textAnchor={isSource ? 'start' : 'end'}\n dominantBaseline=\"middle\"\n className=\"fill-foreground text-xs\"\n >\n {label}\n </text>\n )}\n </g>\n );\n };\n}\n\n// Link ribbon: a bezier stroked at 35% opacity in the link's own `color` if\n// given (recharts preserves custom link fields on the render `payload`), else\n// the **target** node's color (so a flow reads as \"where it goes\"). Drawn as a\n// stroke, not a fill, so the ribbon width comes from `linkWidth`.\nfunction SankeyLinkShape({\n sourceX,\n targetX,\n sourceY,\n targetY,\n sourceControlX,\n targetControlX,\n linkWidth,\n payload,\n}: SankeyLinkShapeProps) {\n const targetName = String(payload.target.name);\n const stroke = payload.color ?? `var(--color-${targetName})`;\n return (\n <path\n d={`M${sourceX},${sourceY}C${sourceControlX},${sourceY} ${targetControlX},${targetY} ${targetX},${targetY}`}\n fill=\"none\"\n stroke={stroke}\n strokeWidth={Math.max(1, linkWidth)}\n // An explicit per-link color is the caller's exact choice — render it at\n // full opacity (so it matches its node bar); the default target-tint is\n // dimmed to 35% so ribbons don't overwhelm the nodes.\n strokeOpacity={payload.color ? 1 : 0.35}\n />\n );\n}\n\n// Default tooltip: recharts' Sankey payload carries no config color, and labels\n// a hovered link \"source - target\" using the node keys (a node is a single key).\n// Parse that name to a color dot (the target node's color) + the mapped config\n// labels joined with an arrow + the value — driven by `config`, so it's reliable\n// where the shared ChartTooltipContent can't resolve the Sankey payload.\n//\n// Exported (module-only, not from the package barrel) so its branches can be\n// unit-tested directly: recharts can't lay out a Sankey in happy-dom, and its\n// hover tooltip has no statically-open form the component exposes, so rendering\n// `<SankeyChart>` never reaches this code.\nexport function makeSankeyTooltip(\n config: ChartConfig,\n links: ReadonlyArray<SankeyChartLink>,\n nodes: ReadonlyArray<SankeyChartNode>\n) {\n const labelFor = (key: string): React.ReactNode => config[key]?.label ?? key;\n // Resolve each link's dot color by its \"source - target\" name (which is the\n // tooltip item's name): the link's own color if set, else the target's, via\n // the `--color-<name>` bridge so a per-theme config resolves too.\n const styleByName = new Map<string, { color: string; opacity: number }>();\n for (const link of links) {\n const source = nodes[link.source]?.name ?? '';\n const target = nodes[link.target]?.name ?? '';\n // Mirror the ribbon: an explicit color renders full-opacity; the default\n // target tint renders at 35%.\n styleByName.set(source + ' - ' + target, {\n color: link.color ?? `var(--color-${target})`,\n opacity: link.color ? 1 : 0.35,\n });\n }\n\n return function SankeyTooltipContent({\n active,\n payload,\n }: {\n active?: boolean;\n payload?: ReadonlyArray<{\n name?: string | number;\n value?: number | string | ReadonlyArray<number | string>;\n }>;\n }) {\n if (!active || !payload?.length) return null;\n const item = payload[0];\n const parts = String(item?.name ?? '').split(' - ');\n const targetKey = parts[parts.length - 1];\n const linkStyle = styleByName.get(String(item?.name ?? ''));\n const dotColor = linkStyle?.color ?? `var(--color-${targetKey})`;\n const dotOpacity = linkStyle?.opacity ?? 1;\n const value = item?.value;\n return (\n <div className=\"flex items-center gap-2 rounded-[var(--ui-tooltip-container-border-radius)] border border-border bg-background px-[var(--ui-tooltip-container-padding-x)] py-[var(--ui-tooltip-container-padding-y)] text-xs text-foreground shadow-md\">\n <span\n className=\"h-2.5 w-2.5 shrink-0 rounded-[2px]\"\n style={{ backgroundColor: dotColor, opacity: dotOpacity }}\n />\n <span className=\"text-muted-foreground\">\n {/* A config label can be any ReactNode, so the arrow-joined label is\n built as nodes rather than stringified. */}\n {parts.map((key, index) => (\n <React.Fragment key={`${key}-${index}`}>\n {index > 0 && ' → '}\n {labelFor(key)}\n </React.Fragment>\n ))}\n </span>\n {value != null && (\n <span className=\"ms-2 font-medium tabular-nums\">\n {formatTooltipValue(value)}\n </span>\n )}\n </div>\n );\n };\n}\n\n// recharts types a tooltip item's value as a scalar *or* a range tuple; a plain\n// `String()` would print \"1,2\" for the tuple, so format each part and join.\nfunction formatTooltipValue(\n value: number | string | ReadonlyArray<number | string>\n): string {\n if (Array.isArray(value)) {\n return value.map((part) => formatTooltipValue(part)).join(' – ');\n }\n return typeof value === 'number'\n ? value.toLocaleString()\n : String(value as string);\n}\n\nconst SankeyChart = React.forwardRef<HTMLDivElement, SankeyChartProps>(\n (\n {\n className,\n config,\n data,\n nodePadding = 24,\n nodeWidth = 12,\n linkCurvature = 0.5,\n sort = false,\n showLabels = true,\n showLegend = false,\n showTooltip = true,\n tooltipContent,\n ...props\n },\n ref\n ) => {\n const uniqueId = React.useId();\n const chartId = `chart-${uniqueId.replace(/:/g, '')}`;\n\n // Node indices that appear as a link `source` have outgoing flow — used by\n // the node renderer to place the label on the readable side.\n const sourceIndices = React.useMemo(\n () => new Set(data.links.map((link) => link.source)),\n [data.links]\n );\n\n const nodeRenderer = React.useMemo(\n () => makeNodeRenderer(config, sourceIndices, showLabels),\n [config, sourceIndices, showLabels]\n );\n\n const defaultTooltip = React.useMemo(\n () => makeSankeyTooltip(config, data.links, data.nodes),\n [config, data.links, data.nodes]\n );\n\n // Per-node value (incoming flow, or outgoing for a source with no incoming)\n // and its share of the largest node — drives the legend's count + %.\n const nodeStats = React.useMemo(() => {\n const incoming = new Map<number, number>();\n const outgoing = new Map<number, number>();\n for (const link of data.links) {\n outgoing.set(link.source, (outgoing.get(link.source) ?? 0) + link.value);\n incoming.set(link.target, (incoming.get(link.target) ?? 0) + link.value);\n }\n const values = data.nodes.map(\n (_, i) => incoming.get(i) ?? outgoing.get(i) ?? 0\n );\n const total = values.length ? Math.max(...values) : 0;\n return data.nodes.map((node, i) => ({\n name: node.name,\n value: values[i],\n pct: total > 0 ? Math.round((values[i] / total) * 100) : 0,\n }));\n }, [data]);\n\n return (\n <div\n ref={ref}\n // The legend sits outside `ChartContainer`, so the root carries its own\n // `--color-<name>` scope for it (the plot and the recharts-portaled\n // tooltip resolve theirs from ChartContainer's).\n data-chart={chartId}\n className={cn('flex flex-col', className)}\n {...props}\n >\n <ChartStyle id={chartId} config={config} />\n <ChartContainer config={config} className=\"min-h-0 flex-1\">\n <RechartsSankey\n data={data as { nodes: SankeyChartNode[]; links: SankeyChartLink[] }}\n node={nodeRenderer}\n link={SankeyLinkShape}\n nodePadding={nodePadding}\n nodeWidth={nodeWidth}\n linkCurvature={linkCurvature}\n sort={sort}\n // recharts defaults to `justify`, which right-aligns sink nodes to\n // the last column — so a terminal node like \"No certification\" would\n // jump to the far right instead of staying at its real depth. `left`\n // positions every node by its distance from the source, keeping the\n // flow's columns intact.\n align=\"left\"\n // Node labels never extend past the plot's right edge: a node in the\n // last column has no outgoing links, so its label is drawn to the\n // LEFT of its bar (see the node renderer). Only a small gutter is\n // needed here — a wide reserve would just shrink the diagram.\n margin={{ top: 8, right: 24, bottom: 8, left: 24 }}\n >\n {showTooltip && (\n <ChartTooltip content={tooltipContent ?? defaultTooltip} />\n )}\n </RechartsSankey>\n </ChartContainer>\n {showLegend && (\n <div className=\"mt-3 grid grid-cols-2 gap-x-6 gap-y-1.5 text-xs\">\n {nodeStats.map(({ name, value, pct }) => (\n <div key={name} className=\"flex items-center gap-2\">\n <span\n className=\"size-2.5 shrink-0 rounded-full\"\n style={{ backgroundColor: `var(--color-${name})` }}\n />\n <span className=\"truncate text-muted-foreground\">\n {config[name]?.label ?? name}\n </span>\n <span className=\"ms-auto font-semibold tabular-nums\">\n {value.toLocaleString()}\n </span>\n <span className=\"w-9 shrink-0 text-end tabular-nums text-muted-foreground\">\n {pct}%\n </span>\n </div>\n ))}\n </div>\n )}\n </div>\n );\n }\n);\nSankeyChart.displayName = 'SankeyChart';\n\nexport { SankeyChart };\n"],"names":["makeNodeRenderer","config","sourceIndices","showLabels","x","y","width","height","index","payload","name","label","_a","isSource","jsx","Rectangle","SankeyLinkShape","sourceX","targetX","sourceY","targetY","sourceControlX","targetControlX","linkWidth","targetName","stroke","makeSankeyTooltip","links","nodes","labelFor","key","styleByName","link","source","target","_b","active","item","parts","targetKey","linkStyle","dotColor","dotOpacity","value","jsxs","React","formatTooltipValue","part","SankeyChart","className","data","nodePadding","nodeWidth","linkCurvature","sort","showLegend","showTooltip","tooltipContent","props","ref","chartId","nodeRenderer","defaultTooltip","nodeStats","incoming","outgoing","values","_","i","total","node","cn","ChartStyle","ChartContainer","RechartsSankey","ChartTooltip","pct"],"mappings":"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"}
@@ -0,0 +1,130 @@
1
+ import { jsx as t, jsxs as H } from "react/jsx-runtime";
2
+ import * as X from "react";
3
+ import { ScatterChart as Y, CartesianGrid as Z, XAxis as _, YAxis as q, ZAxis as z, Scatter as E } from "recharts";
4
+ import { cn as I } from "../../../lib/utils.js";
5
+ import { ChartContainer as J, ChartTooltip as O, ChartTooltipContent as P, ChartLegend as Q, ChartLegendContent as U } from "../chart/chart.js";
6
+ import { resolveAxisDomain as V } from "../chart/chart-format.js";
7
+ const W = X.forwardRef(
8
+ ({
9
+ className: c,
10
+ config: s,
11
+ series: m,
12
+ xKey: n,
13
+ yKey: l,
14
+ zKey: i,
15
+ zRange: d = [60, 400],
16
+ shape: h = "circle",
17
+ xAxisLabel: r,
18
+ yAxisLabel: o,
19
+ xUnit: u,
20
+ yUnit: f,
21
+ showGrid: p = !0,
22
+ showTooltip: v = !0,
23
+ showLegend: C = !0,
24
+ showXAxis: k = !0,
25
+ showYAxis: g = !0,
26
+ xTickFormatter: y,
27
+ yTickFormatter: S,
28
+ xAxisAngle: e,
29
+ xAxisInterval: D,
30
+ yAxisTickCount: T,
31
+ yAxisDomain: N,
32
+ gridDashed: b,
33
+ gridHorizontal: j,
34
+ gridVertical: w,
35
+ tooltipContent: F,
36
+ ...L
37
+ }, M) => {
38
+ const R = r ? { value: r, position: "insideBottom", offset: -8 } : void 0, $ = o ? {
39
+ value: o,
40
+ angle: -90,
41
+ position: "insideLeft",
42
+ style: { textAnchor: "middle" }
43
+ } : void 0, B = V(N), G = r || e != null ? 30 + (e != null ? 20 : 0) + (r ? 18 : 0) : void 0;
44
+ return /* @__PURE__ */ t("div", { ref: M, className: I(c), ...L, children: /* @__PURE__ */ t(
45
+ J,
46
+ {
47
+ config: s,
48
+ className: "size-full [&_.recharts-label]:fill-foreground",
49
+ children: /* @__PURE__ */ H(
50
+ Y,
51
+ {
52
+ margin: { top: 16, right: 16, bottom: 16, left: 16 },
53
+ children: [
54
+ p && /* @__PURE__ */ t(
55
+ Z,
56
+ {
57
+ horizontal: j ?? !0,
58
+ vertical: w ?? !0,
59
+ strokeDasharray: b ? "3 3" : void 0
60
+ }
61
+ ),
62
+ /* @__PURE__ */ t(
63
+ _,
64
+ {
65
+ type: "number",
66
+ dataKey: n,
67
+ name: n,
68
+ unit: u,
69
+ hide: !k,
70
+ tickLine: !1,
71
+ axisLine: !1,
72
+ tickMargin: 8,
73
+ tickFormatter: y,
74
+ angle: e,
75
+ interval: D,
76
+ textAnchor: e != null ? e < 0 ? "end" : "start" : void 0,
77
+ height: G,
78
+ label: R
79
+ }
80
+ ),
81
+ /* @__PURE__ */ t(
82
+ q,
83
+ {
84
+ type: "number",
85
+ dataKey: l,
86
+ name: l,
87
+ unit: f,
88
+ hide: !g,
89
+ tickLine: !1,
90
+ axisLine: !1,
91
+ tickMargin: 8,
92
+ tickFormatter: S,
93
+ tickCount: T,
94
+ domain: B,
95
+ width: o ? 72 : void 0,
96
+ label: $
97
+ }
98
+ ),
99
+ i && /* @__PURE__ */ t(z, { type: "number", dataKey: i, range: d, name: i }),
100
+ v && /* @__PURE__ */ t(
101
+ O,
102
+ {
103
+ cursor: { strokeDasharray: "3 3" },
104
+ content: F ?? /* @__PURE__ */ t(P, {})
105
+ }
106
+ ),
107
+ C && /* @__PURE__ */ t(Q, { content: /* @__PURE__ */ t(U, {}) }),
108
+ m.map((a) => /* @__PURE__ */ t(
109
+ E,
110
+ {
111
+ name: a.key,
112
+ data: a.data,
113
+ fill: `var(--color-${a.key})`,
114
+ shape: h,
115
+ isAnimationActive: !1
116
+ },
117
+ a.key
118
+ ))
119
+ ]
120
+ }
121
+ )
122
+ }
123
+ ) });
124
+ }
125
+ );
126
+ W.displayName = "ScatterChart";
127
+ export {
128
+ W as ScatterChart
129
+ };
130
+ //# sourceMappingURL=scatter-chart.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scatter-chart.js","sources":["../../../../src/components/ui/scatter-chart/scatter-chart.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport {\n CartesianGrid,\n Scatter,\n ScatterChart as RechartsScatterChart,\n XAxis,\n YAxis,\n ZAxis,\n} from 'recharts';\n\nimport { cn } from '@/lib/utils';\nimport {\n ChartContainer,\n ChartLegend,\n ChartLegendContent,\n ChartTooltip,\n ChartTooltipContent,\n resolveAxisDomain,\n type ChartConfig,\n type CartesianChartProps,\n} from '../chart';\n\n// A typed recharts composition over the shared `Chart` primitives. Unlike the\n// other chart types, a scatter has no visual \"mode\" to model as a CVA variant —\n// its shape is fixed (x/y points, optionally sized by z) and its expressiveness\n// comes from the data mapping. So there is no `cva` axis here (matches the\n// skill's \"usually none\"); marker `shape` and bubble sizing are plain props.\n// Each series carries its own point array (points aren't columns of a shared\n// row the way bar/line/area series are), so the API takes a `series` list rather\n// than `dataKeys` over one `data` array.\nexport type ScatterMarkerShape =\n | 'circle'\n | 'cross'\n | 'diamond'\n | 'square'\n | 'star'\n | 'triangle'\n | 'wye';\n\nexport interface ScatterSeries {\n /** Series key — must match a `config` entry; drives its `--color-<key>` fill and legend label. */\n key: string;\n /** This series' points — each row holds at least `xKey` and `yKey` (and `zKey` when used). */\n data: ReadonlyArray<Record<string, number>>;\n}\n\nexport interface ScatterChartProps\n extends Omit<React.ComponentProps<'div'>, 'children'>,\n CartesianChartProps {\n /** One `<Scatter>` per entry — each with its own point array. Use a single entry for an ungrouped scatter. */\n series: ScatterSeries[];\n /**\n * Per-series map of `label` / `color`, keyed by `series[].key` (imported from\n * the shared `Chart` primitives). Turned into `--color-<key>` custom\n * properties. Colors are caller-supplied — reference an existing semantic\n * `--ui-*` token; there is no chart palette tier yet.\n */\n config: ChartConfig;\n /** Numeric field for the horizontal axis. */\n xKey: string;\n /** Numeric field for the vertical axis. */\n yKey: string;\n /** Unit suffix appended to X-axis tick values (recharts `unit`). */\n xUnit?: string;\n /** Optional numeric field mapped to point size (a bubble chart), via recharts `ZAxis`. */\n zKey?: string;\n /** Point-size range `[min, max]` the `zKey` maps into. Ignored when `zKey` is unset (points use recharts' default size). */\n zRange?: [number, number];\n /** Marker shape for every point. */\n shape?: ScatterMarkerShape;\n showLegend?: boolean;\n}\n\nconst ScatterChart = React.forwardRef<HTMLDivElement, ScatterChartProps>(\n (\n {\n className,\n config,\n series,\n xKey,\n yKey,\n zKey,\n zRange = [60, 400],\n shape = 'circle',\n xAxisLabel,\n yAxisLabel,\n xUnit,\n yUnit,\n showGrid = true,\n showTooltip = true,\n showLegend = true,\n showXAxis = true,\n showYAxis = true,\n xTickFormatter,\n yTickFormatter,\n xAxisAngle,\n xAxisInterval,\n yAxisTickCount,\n yAxisDomain,\n gridDashed,\n gridHorizontal,\n gridVertical,\n tooltipContent,\n ...props\n },\n ref\n ) => {\n // Axis titles: the X title sits below the ticks; the Y title is rotated in\n // the left gutter. Passed to recharts' native `label` (themed via the\n // `.recharts-label` fill selector on the container).\n const xAxisTitle = xAxisLabel\n ? { value: xAxisLabel, position: 'insideBottom' as const, offset: -8 }\n : undefined;\n const yAxisTitle = yAxisLabel\n ? {\n value: yAxisLabel,\n angle: -90,\n position: 'insideLeft' as const,\n style: { textAnchor: 'middle' as const },\n }\n : undefined;\n\n const yDomain = resolveAxisDomain(yAxisDomain);\n\n // Room for the X tick row: recharts' default 30, plus a rotated tick row\n // (+20) and/or the axis title (+18). Additive — both can be present at once,\n // which the old label-or-angle ternary under-allocated.\n const xAxisHeight =\n xAxisLabel || xAxisAngle != null\n ? 30 + (xAxisAngle != null ? 20 : 0) + (xAxisLabel ? 18 : 0)\n : undefined;\n\n return (\n <div ref={ref} className={cn(className)} {...props}>\n <ChartContainer\n config={config}\n className=\"size-full [&_.recharts-label]:fill-foreground\"\n >\n <RechartsScatterChart\n margin={{ top: 16, right: 16, bottom: 16, left: 16 }}\n >\n {showGrid && (\n <CartesianGrid\n horizontal={gridHorizontal ?? true}\n vertical={gridVertical ?? true}\n strokeDasharray={gridDashed ? '3 3' : undefined}\n />\n )}\n <XAxis\n type=\"number\"\n dataKey={xKey}\n name={xKey}\n unit={xUnit}\n hide={!showXAxis}\n tickLine={false}\n axisLine={false}\n tickMargin={8}\n tickFormatter={xTickFormatter}\n angle={xAxisAngle}\n interval={xAxisInterval}\n textAnchor={\n xAxisAngle != null ? (xAxisAngle < 0 ? 'end' : 'start') : undefined\n }\n height={xAxisHeight}\n label={xAxisTitle}\n />\n <YAxis\n type=\"number\"\n dataKey={yKey}\n name={yKey}\n unit={yUnit}\n hide={!showYAxis}\n tickLine={false}\n axisLine={false}\n tickMargin={8}\n tickFormatter={yTickFormatter}\n tickCount={yAxisTickCount}\n domain={yDomain}\n width={yAxisLabel ? 72 : undefined}\n label={yAxisTitle}\n />\n {zKey && (\n <ZAxis type=\"number\" dataKey={zKey} range={zRange} name={zKey} />\n )}\n {showTooltip && (\n <ChartTooltip\n cursor={{ strokeDasharray: '3 3' }}\n content={tooltipContent ?? <ChartTooltipContent />}\n />\n )}\n {showLegend && <ChartLegend content={<ChartLegendContent />} />}\n {series.map((s) => (\n <Scatter\n key={s.key}\n name={s.key}\n data={s.data as Record<string, number>[]}\n fill={`var(--color-${s.key})`}\n shape={shape}\n isAnimationActive={false}\n />\n ))}\n </RechartsScatterChart>\n </ChartContainer>\n </div>\n );\n }\n);\nScatterChart.displayName = 'ScatterChart';\n\nexport { ScatterChart };\n"],"names":["ScatterChart","React","className","config","series","xKey","yKey","zKey","zRange","shape","xAxisLabel","yAxisLabel","xUnit","yUnit","showGrid","showTooltip","showLegend","showXAxis","showYAxis","xTickFormatter","yTickFormatter","xAxisAngle","xAxisInterval","yAxisTickCount","yAxisDomain","gridDashed","gridHorizontal","gridVertical","tooltipContent","props","ref","xAxisTitle","yAxisTitle","yDomain","resolveAxisDomain","xAxisHeight","jsx","cn","ChartContainer","jsxs","RechartsScatterChart","CartesianGrid","XAxis","YAxis","ZAxis","ChartTooltip","ChartTooltipContent","ChartLegend","ChartLegendContent","s","Scatter"],"mappings":"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"}
@@ -6,20 +6,20 @@ const j = t.forwardRef(
6
6
  ({
7
7
  className: p,
8
8
  type: v = "search",
9
- disabled: s,
10
- onClear: n,
9
+ disabled: n,
10
+ onClear: s,
11
11
  onChange: c,
12
12
  value: r,
13
13
  defaultValue: u,
14
- ...f
14
+ ...g
15
15
  }, i) => {
16
- const d = t.useRef(null), [x, l] = t.useState(
16
+ const d = t.useRef(null), [f, l] = t.useState(
17
17
  () => String(r ?? u ?? "").length > 0
18
18
  );
19
19
  t.useEffect(() => {
20
20
  r !== void 0 && l(String(r).length > 0);
21
21
  }, [r]);
22
- const g = t.useCallback(
22
+ const x = t.useCallback(
23
23
  (e) => {
24
24
  d.current = e, typeof i == "function" ? i(e) : i && (i.current = e);
25
25
  },
@@ -27,24 +27,24 @@ const j = t.forwardRef(
27
27
  ), m = (e) => {
28
28
  l(e.target.value.length > 0), c == null || c(e);
29
29
  }, y = () => {
30
- var h, b;
30
+ var b, h;
31
31
  const e = d.current;
32
32
  if (!e) return;
33
33
  let a;
34
34
  try {
35
- a = (b = Object.getOwnPropertyDescriptor(
36
- (h = globalThis.HTMLInputElement) == null ? void 0 : h.prototype,
35
+ a = (h = Object.getOwnPropertyDescriptor(
36
+ (b = globalThis.HTMLInputElement) == null ? void 0 : b.prototype,
37
37
  "value"
38
- )) == null ? void 0 : b.set;
38
+ )) == null ? void 0 : h.set;
39
39
  } catch {
40
40
  a = void 0;
41
41
  }
42
- a ? a.call(e, "") : e.value = "", e.dispatchEvent(new Event("input", { bubbles: !0 })), l(!1), e.focus(), n == null || n();
42
+ a ? a.call(e, "") : e.value = "", e.dispatchEvent(new Event("input", { bubbles: !0 })), l(!1), e.focus(), s == null || s();
43
43
  };
44
44
  return /* @__PURE__ */ w(
45
45
  "div",
46
46
  {
47
- "data-disabled": s || void 0,
47
+ "data-disabled": n || void 0,
48
48
  className: N(
49
49
  "group inline-flex h-[var(--ui-input-search-box-height)] w-full min-w-0 items-center gap-[var(--ui-input-search-box-gap)] rounded-[var(--ui-input-search-box-border-radius)] border bg-[var(--ui-input-search-box-color-idle)] border-[var(--ui-input-search-border-color-idle)] px-[var(--ui-input-search-box-padding-x)] text-sm leading-6 text-[var(--ui-input-search-value-color-idle)] transition-colors not-data-[disabled]:hover:bg-[var(--ui-input-search-box-color-hover)] not-data-[disabled]:hover:border-[var(--ui-input-search-border-color-hover)] focus-within:border-[var(--ui-input-search-border-color-hover)] focus-within:ring-[3px] focus-within:ring-[var(--ui-focus-primary)] data-[disabled]:cursor-not-allowed data-[disabled]:border-[var(--ui-input-search-border-color-disabled)] data-[disabled]:bg-[var(--ui-input-search-box-color-disabled)] data-[disabled]:text-[var(--ui-input-search-value-color-disabled)]",
50
50
  p
@@ -60,24 +60,24 @@ const j = t.forwardRef(
60
60
  /* @__PURE__ */ o(
61
61
  "input",
62
62
  {
63
- ref: g,
63
+ ref: x,
64
64
  type: v,
65
- disabled: s,
65
+ disabled: n,
66
66
  value: r,
67
67
  defaultValue: u,
68
68
  onChange: m,
69
69
  "aria-label": "Search",
70
70
  className: "h-full min-w-0 flex-1 border-0 bg-transparent p-0 text-inherit outline-none placeholder:text-[var(--ui-input-search-placeholder-color-idle)] disabled:cursor-not-allowed [&::-webkit-search-cancel-button]:appearance-none",
71
- ...f
71
+ ...g
72
72
  }
73
73
  ),
74
- x && !s && /* @__PURE__ */ o(
74
+ f && !n && /* @__PURE__ */ o(
75
75
  "button",
76
76
  {
77
77
  type: "button",
78
78
  "aria-label": "Clear search",
79
79
  onClick: y,
80
- className: "inline-flex shrink-0 cursor-pointer items-center justify-center rounded-sm text-[var(--ui-button-icon-global-icon-color-idle)] outline-none focus-visible:ring-2 focus-visible:ring-[var(--ui-focus-primary)] [&>svg]:size-4",
80
+ className: "inline-flex size-5 shrink-0 cursor-pointer items-center justify-center rounded-sm p-0.5 text-[var(--ui-button-icon-global-icon-color-idle)] outline-none hover:bg-[var(--ui-button-icon-global-container-color-hover)] active:bg-[var(--ui-button-icon-global-container-color-active)] focus-visible:ring-2 focus-visible:ring-[var(--ui-focus-primary)] [&>svg]:size-4",
81
81
  children: /* @__PURE__ */ o(k, { size: 16 })
82
82
  }
83
83
  )
@@ -1 +1 @@
1
- {"version":3,"file":"search.js","sources":["../../../../src/components/ui/search/search.tsx"],"sourcesContent":["import * as React from 'react';\nimport {\n MagnifierIcon,\n TimesIcon,\n} from '@acronis-platform/icons-react/stroke-mono';\n\nimport { cn } from '@/lib/utils';\n\n// Internal primitive: the bare search box behind the public `InputSearch` field\n// (which is also exported as `Search`). Not exported from the package; consumed\n// by `input-search`. A bordered box (the dedicated `--ui-input-search-*` token\n// tier) holding a leading magnifier, a borderless native input, and a trailing\n// clear button shown once there's a value. The box owns the visual state via\n// `focus-within` (the input-search tier has no focus/active border token, so the\n// focused border reuses `--ui-input-search-border-color-hover` plus a 3px\n// `--ui-focus-primary` ring) / hover / disabled; the magnifier uses\n// `--ui-input-search-icon-search-color-{idle,disabled}` (via the `group`) and the\n// clear button is a ghost ButtonIcon, so its glyph uses\n// `--ui-button-icon-global-icon-color-idle` (the input-search tier dropped its own\n// clear-icon token in the Figma sync).\n\nexport interface SearchBoxProps extends React.ComponentPropsWithoutRef<'input'> {\n /** Called when the clear (×) button is pressed, after the value is cleared. */\n onClear?: () => void;\n}\n\nconst SearchBox = React.forwardRef<HTMLInputElement, SearchBoxProps>(\n (\n {\n className,\n type = 'search',\n disabled,\n onClear,\n onChange,\n value,\n defaultValue,\n ...props\n },\n forwardedRef\n ) => {\n const innerRef = React.useRef<HTMLInputElement>(null);\n const [hasValue, setHasValue] = React.useState(\n () => String(value ?? defaultValue ?? '').length > 0\n );\n\n // Keep the clear button in sync when the value is controlled externally.\n React.useEffect(() => {\n if (value !== undefined) setHasValue(String(value).length > 0);\n }, [value]);\n\n const setRefs = React.useCallback(\n (node: HTMLInputElement | null) => {\n innerRef.current = node;\n if (typeof forwardedRef === 'function') forwardedRef(node);\n else if (forwardedRef) forwardedRef.current = node;\n },\n [forwardedRef]\n );\n\n const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n setHasValue(event.target.value.length > 0);\n onChange?.(event);\n };\n\n const handleClear = () => {\n const input = innerRef.current;\n if (!input) return;\n // Use the native value setter when available + dispatch a real input event\n // so React's onChange fires for both controlled and uncontrolled usage.\n let setter: ((this: HTMLInputElement, value: string) => void) | undefined;\n try {\n setter = Object.getOwnPropertyDescriptor(\n globalThis.HTMLInputElement?.prototype,\n 'value'\n )?.set;\n } catch {\n setter = undefined;\n }\n\n if (setter) setter.call(input, '');\n else input.value = '';\n\n input.dispatchEvent(new Event('input', { bubbles: true }));\n setHasValue(false);\n input.focus();\n onClear?.();\n };\n\n return (\n <div\n data-disabled={disabled || undefined}\n className={cn(\n 'group inline-flex h-[var(--ui-input-search-box-height)] w-full min-w-0 items-center gap-[var(--ui-input-search-box-gap)] rounded-[var(--ui-input-search-box-border-radius)] border bg-[var(--ui-input-search-box-color-idle)] border-[var(--ui-input-search-border-color-idle)] px-[var(--ui-input-search-box-padding-x)] text-sm leading-6 text-[var(--ui-input-search-value-color-idle)] transition-colors not-data-[disabled]:hover:bg-[var(--ui-input-search-box-color-hover)] not-data-[disabled]:hover:border-[var(--ui-input-search-border-color-hover)] focus-within:border-[var(--ui-input-search-border-color-hover)] focus-within:ring-[3px] focus-within:ring-[var(--ui-focus-primary)] data-[disabled]:cursor-not-allowed data-[disabled]:border-[var(--ui-input-search-border-color-disabled)] data-[disabled]:bg-[var(--ui-input-search-box-color-disabled)] data-[disabled]:text-[var(--ui-input-search-value-color-disabled)]',\n className\n )}\n >\n <MagnifierIcon\n size={16}\n className=\"shrink-0 text-[var(--ui-input-search-icon-search-color-idle)] group-data-[disabled]:text-[var(--ui-input-search-icon-search-color-disabled)]\"\n />\n <input\n ref={setRefs}\n type={type}\n disabled={disabled}\n value={value}\n defaultValue={defaultValue}\n onChange={handleChange}\n aria-label=\"Search\"\n className=\"h-full min-w-0 flex-1 border-0 bg-transparent p-0 text-inherit outline-none placeholder:text-[var(--ui-input-search-placeholder-color-idle)] disabled:cursor-not-allowed [&::-webkit-search-cancel-button]:appearance-none\"\n {...props}\n />\n {hasValue && !disabled && (\n <button\n type=\"button\"\n aria-label=\"Clear search\"\n onClick={handleClear}\n className=\"inline-flex shrink-0 cursor-pointer items-center justify-center rounded-sm text-[var(--ui-button-icon-global-icon-color-idle)] outline-none focus-visible:ring-2 focus-visible:ring-[var(--ui-focus-primary)] [&>svg]:size-4\"\n >\n <TimesIcon size={16} />\n </button>\n )}\n </div>\n );\n }\n);\nSearchBox.displayName = 'SearchBox';\n\nexport { SearchBox };\n"],"names":["SearchBox","React","className","type","disabled","onClear","onChange","value","defaultValue","props","forwardedRef","innerRef","hasValue","setHasValue","setRefs","node","handleChange","event","handleClear","input","setter","_b","_a","jsxs","cn","jsx","MagnifierIcon","TimesIcon"],"mappings":";;;;AA0BA,MAAMA,IAAYC,EAAM;AAAA,EACtB,CACE;AAAA,IACE,WAAAC;AAAA,IACA,MAAAC,IAAO;AAAA,IACP,UAAAC;AAAA,IACA,SAAAC;AAAA,IACA,UAAAC;AAAA,IACA,OAAAC;AAAA,IACA,cAAAC;AAAA,IACA,GAAGC;AAAA,EAAA,GAELC,MACG;AACH,UAAMC,IAAWV,EAAM,OAAyB,IAAI,GAC9C,CAACW,GAAUC,CAAW,IAAIZ,EAAM;AAAA,MACpC,MAAM,OAAOM,KAASC,KAAgB,EAAE,EAAE,SAAS;AAAA,IAAA;AAIrD,IAAAP,EAAM,UAAU,MAAM;AACpB,MAAIM,MAAU,UAAWM,EAAY,OAAON,CAAK,EAAE,SAAS,CAAC;AAAA,IAC/D,GAAG,CAACA,CAAK,CAAC;AAEV,UAAMO,IAAUb,EAAM;AAAA,MACpB,CAACc,MAAkC;AACjC,QAAAJ,EAAS,UAAUI,GACf,OAAOL,KAAiB,aAAYA,EAAaK,CAAI,IAChDL,QAA2B,UAAUK;AAAA,MAChD;AAAA,MACA,CAACL,CAAY;AAAA,IAAA,GAGTM,IAAe,CAACC,MAA+C;AACnE,MAAAJ,EAAYI,EAAM,OAAO,MAAM,SAAS,CAAC,GACzCX,KAAA,QAAAA,EAAWW;AAAA,IACb,GAEMC,IAAc,MAAM;;AACxB,YAAMC,IAAQR,EAAS;AACvB,UAAI,CAACQ,EAAO;AAGZ,UAAIC;AACJ,UAAI;AACF,QAAAA,KAASC,IAAA,OAAO;AAAA,WACdC,IAAA,WAAW,qBAAX,gBAAAA,EAA6B;AAAA,UAC7B;AAAA,QAAA,MAFO,gBAAAD,EAGN;AAAA,MACL,QAAQ;AACN,QAAAD,IAAS;AAAA,MACX;AAEA,MAAIA,IAAQA,EAAO,KAAKD,GAAO,EAAE,MACtB,QAAQ,IAEnBA,EAAM,cAAc,IAAI,MAAM,SAAS,EAAE,SAAS,GAAA,CAAM,CAAC,GACzDN,EAAY,EAAK,GACjBM,EAAM,MAAA,GACNd,KAAA,QAAAA;AAAA,IACF;AAEA,WACE,gBAAAkB;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,iBAAenB,KAAY;AAAA,QAC3B,WAAWoB;AAAA,UACT;AAAA,UACAtB;AAAA,QAAA;AAAA,QAGF,UAAA;AAAA,UAAA,gBAAAuB;AAAA,YAACC;AAAA,YAAA;AAAA,cACC,MAAM;AAAA,cACN,WAAU;AAAA,YAAA;AAAA,UAAA;AAAA,UAEZ,gBAAAD;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,KAAKX;AAAA,cACL,MAAAX;AAAA,cACA,UAAAC;AAAA,cACA,OAAAG;AAAA,cACA,cAAAC;AAAA,cACA,UAAUQ;AAAA,cACV,cAAW;AAAA,cACX,WAAU;AAAA,cACT,GAAGP;AAAA,YAAA;AAAA,UAAA;AAAA,UAELG,KAAY,CAACR,KACZ,gBAAAqB;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,cAAW;AAAA,cACX,SAASP;AAAA,cACT,WAAU;AAAA,cAEV,UAAA,gBAAAO,EAACE,GAAA,EAAU,MAAM,GAAA,CAAI;AAAA,YAAA;AAAA,UAAA;AAAA,QACvB;AAAA,MAAA;AAAA,IAAA;AAAA,EAIR;AACF;AACA3B,EAAU,cAAc;"}
1
+ {"version":3,"file":"search.js","sources":["../../../../src/components/ui/search/search.tsx"],"sourcesContent":["import * as React from 'react';\nimport {\n MagnifierIcon,\n TimesIcon,\n} from '@acronis-platform/icons-react/stroke-mono';\n\nimport { cn } from '@/lib/utils';\n\n// Internal primitive: the bare search box behind the public `InputSearch` field\n// (which is also exported as `Search`). Not exported from the package; consumed\n// by `input-search`. A bordered box (the dedicated `--ui-input-search-*` token\n// tier) holding a leading magnifier, a borderless native input, and a trailing\n// clear button shown once there's a value. The box owns the visual state via\n// `focus-within` (the input-search tier has no focus/active border token, so the\n// focused border reuses `--ui-input-search-border-color-hover` plus a 3px\n// `--ui-focus-primary` ring) / hover / disabled; the magnifier uses\n// `--ui-input-search-icon-search-color-{idle,disabled}` (via the `group`) and the\n// clear button is a ghost ButtonIcon, so its glyph uses\n// `--ui-button-icon-global-icon-color-idle` (the input-search tier dropped its own\n// clear-icon token in the Figma sync).\n\nexport interface SearchBoxProps extends React.ComponentPropsWithoutRef<'input'> {\n /** Called when the clear (×) button is pressed, after the value is cleared. */\n onClear?: () => void;\n}\n\nconst SearchBox = React.forwardRef<HTMLInputElement, SearchBoxProps>(\n (\n {\n className,\n type = 'search',\n disabled,\n onClear,\n onChange,\n value,\n defaultValue,\n ...props\n },\n forwardedRef\n ) => {\n const innerRef = React.useRef<HTMLInputElement>(null);\n const [hasValue, setHasValue] = React.useState(\n () => String(value ?? defaultValue ?? '').length > 0\n );\n\n // Keep the clear button in sync when the value is controlled externally.\n React.useEffect(() => {\n if (value !== undefined) setHasValue(String(value).length > 0);\n }, [value]);\n\n const setRefs = React.useCallback(\n (node: HTMLInputElement | null) => {\n innerRef.current = node;\n if (typeof forwardedRef === 'function') forwardedRef(node);\n else if (forwardedRef) forwardedRef.current = node;\n },\n [forwardedRef]\n );\n\n const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n setHasValue(event.target.value.length > 0);\n onChange?.(event);\n };\n\n const handleClear = () => {\n const input = innerRef.current;\n if (!input) return;\n // Use the native value setter when available + dispatch a real input event\n // so React's onChange fires for both controlled and uncontrolled usage.\n let setter: ((this: HTMLInputElement, value: string) => void) | undefined;\n try {\n setter = Object.getOwnPropertyDescriptor(\n globalThis.HTMLInputElement?.prototype,\n 'value'\n )?.set;\n } catch {\n setter = undefined;\n }\n\n if (setter) setter.call(input, '');\n else input.value = '';\n\n input.dispatchEvent(new Event('input', { bubbles: true }));\n setHasValue(false);\n input.focus();\n onClear?.();\n };\n\n return (\n <div\n data-disabled={disabled || undefined}\n className={cn(\n 'group inline-flex h-[var(--ui-input-search-box-height)] w-full min-w-0 items-center gap-[var(--ui-input-search-box-gap)] rounded-[var(--ui-input-search-box-border-radius)] border bg-[var(--ui-input-search-box-color-idle)] border-[var(--ui-input-search-border-color-idle)] px-[var(--ui-input-search-box-padding-x)] text-sm leading-6 text-[var(--ui-input-search-value-color-idle)] transition-colors not-data-[disabled]:hover:bg-[var(--ui-input-search-box-color-hover)] not-data-[disabled]:hover:border-[var(--ui-input-search-border-color-hover)] focus-within:border-[var(--ui-input-search-border-color-hover)] focus-within:ring-[3px] focus-within:ring-[var(--ui-focus-primary)] data-[disabled]:cursor-not-allowed data-[disabled]:border-[var(--ui-input-search-border-color-disabled)] data-[disabled]:bg-[var(--ui-input-search-box-color-disabled)] data-[disabled]:text-[var(--ui-input-search-value-color-disabled)]',\n className\n )}\n >\n <MagnifierIcon\n size={16}\n className=\"shrink-0 text-[var(--ui-input-search-icon-search-color-idle)] group-data-[disabled]:text-[var(--ui-input-search-icon-search-color-disabled)]\"\n />\n <input\n ref={setRefs}\n type={type}\n disabled={disabled}\n value={value}\n defaultValue={defaultValue}\n onChange={handleChange}\n aria-label=\"Search\"\n className=\"h-full min-w-0 flex-1 border-0 bg-transparent p-0 text-inherit outline-none placeholder:text-[var(--ui-input-search-placeholder-color-idle)] disabled:cursor-not-allowed [&::-webkit-search-cancel-button]:appearance-none\"\n {...props}\n />\n {hasValue && !disabled && (\n <button\n type=\"button\"\n aria-label=\"Clear search\"\n onClick={handleClear}\n className=\"inline-flex size-5 shrink-0 cursor-pointer items-center justify-center rounded-sm p-0.5 text-[var(--ui-button-icon-global-icon-color-idle)] outline-none hover:bg-[var(--ui-button-icon-global-container-color-hover)] active:bg-[var(--ui-button-icon-global-container-color-active)] focus-visible:ring-2 focus-visible:ring-[var(--ui-focus-primary)] [&>svg]:size-4\"\n >\n <TimesIcon size={16} />\n </button>\n )}\n </div>\n );\n }\n);\nSearchBox.displayName = 'SearchBox';\n\nexport { SearchBox };\n"],"names":["SearchBox","React","className","type","disabled","onClear","onChange","value","defaultValue","props","forwardedRef","innerRef","hasValue","setHasValue","setRefs","node","handleChange","event","handleClear","input","setter","_b","_a","jsxs","cn","jsx","MagnifierIcon","TimesIcon"],"mappings":";;;;AA0BA,MAAMA,IAAYC,EAAM;AAAA,EACtB,CACE;AAAA,IACE,WAAAC;AAAA,IACA,MAAAC,IAAO;AAAA,IACP,UAAAC;AAAA,IACA,SAAAC;AAAA,IACA,UAAAC;AAAA,IACA,OAAAC;AAAA,IACA,cAAAC;AAAA,IACA,GAAGC;AAAA,EAAA,GAELC,MACG;AACH,UAAMC,IAAWV,EAAM,OAAyB,IAAI,GAC9C,CAACW,GAAUC,CAAW,IAAIZ,EAAM;AAAA,MACpC,MAAM,OAAOM,KAASC,KAAgB,EAAE,EAAE,SAAS;AAAA,IAAA;AAIrD,IAAAP,EAAM,UAAU,MAAM;AACpB,MAAIM,MAAU,UAAWM,EAAY,OAAON,CAAK,EAAE,SAAS,CAAC;AAAA,IAC/D,GAAG,CAACA,CAAK,CAAC;AAEV,UAAMO,IAAUb,EAAM;AAAA,MACpB,CAACc,MAAkC;AACjC,QAAAJ,EAAS,UAAUI,GACf,OAAOL,KAAiB,aAAYA,EAAaK,CAAI,IAChDL,QAA2B,UAAUK;AAAA,MAChD;AAAA,MACA,CAACL,CAAY;AAAA,IAAA,GAGTM,IAAe,CAACC,MAA+C;AACnE,MAAAJ,EAAYI,EAAM,OAAO,MAAM,SAAS,CAAC,GACzCX,KAAA,QAAAA,EAAWW;AAAA,IACb,GAEMC,IAAc,MAAM;;AACxB,YAAMC,IAAQR,EAAS;AACvB,UAAI,CAACQ,EAAO;AAGZ,UAAIC;AACJ,UAAI;AACF,QAAAA,KAASC,IAAA,OAAO;AAAA,WACdC,IAAA,WAAW,qBAAX,gBAAAA,EAA6B;AAAA,UAC7B;AAAA,QAAA,MAFO,gBAAAD,EAGN;AAAA,MACL,QAAQ;AACN,QAAAD,IAAS;AAAA,MACX;AAEA,MAAIA,IAAQA,EAAO,KAAKD,GAAO,EAAE,MACtB,QAAQ,IAEnBA,EAAM,cAAc,IAAI,MAAM,SAAS,EAAE,SAAS,GAAA,CAAM,CAAC,GACzDN,EAAY,EAAK,GACjBM,EAAM,MAAA,GACNd,KAAA,QAAAA;AAAA,IACF;AAEA,WACE,gBAAAkB;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,iBAAenB,KAAY;AAAA,QAC3B,WAAWoB;AAAA,UACT;AAAA,UACAtB;AAAA,QAAA;AAAA,QAGF,UAAA;AAAA,UAAA,gBAAAuB;AAAA,YAACC;AAAA,YAAA;AAAA,cACC,MAAM;AAAA,cACN,WAAU;AAAA,YAAA;AAAA,UAAA;AAAA,UAEZ,gBAAAD;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,KAAKX;AAAA,cACL,MAAAX;AAAA,cACA,UAAAC;AAAA,cACA,OAAAG;AAAA,cACA,cAAAC;AAAA,cACA,UAAUQ;AAAA,cACV,cAAW;AAAA,cACX,WAAU;AAAA,cACT,GAAGP;AAAA,YAAA;AAAA,UAAA;AAAA,UAELG,KAAY,CAACR,KACZ,gBAAAqB;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,cAAW;AAAA,cACX,SAASP;AAAA,cACT,WAAU;AAAA,cAEV,UAAA,gBAAAO,EAACE,GAAA,EAAU,MAAM,GAAA,CAAI;AAAA,YAAA;AAAA,UAAA;AAAA,QACvB;AAAA,MAAA;AAAA,IAAA;AAAA,EAIR;AACF;AACA3B,EAAU,cAAc;"}
@@ -1,14 +1,14 @@
1
- import { jsxs as l, jsx as e, Fragment as S } from "react/jsx-runtime";
2
- import { Sheet as g, SheetTrigger as D, SheetContent as x, SheetHeader as N, SheetTitle as E, SheetCloseButton as L, SheetBody as T, SheetFooter as b } from "./sheet.js";
3
- import { Spinner as j } from "../spinner/spinner.js";
1
+ import { jsxs as l, jsx as e, Fragment as p } from "react/jsx-runtime";
2
+ import { Sheet as S, SheetTrigger as D, SheetContent as x, SheetHeader as L, SheetTitle as N, SheetCloseButton as E, SheetBody as T, SheetFooter as b } from "./sheet.js";
3
+ import { Loading as j } from "../loading/loading.js";
4
4
  import { Empty as w, EmptyHeader as B, EmptyTitle as v, EmptyDescription as C } from "../empty/empty.js";
5
5
  import { DescriptionList as F, DescriptionListItem as H, DescriptionListLabel as I, DescriptionListValue as V } from "../description-list/description-list.js";
6
6
  function k({
7
7
  contentState: t,
8
8
  properties: i,
9
9
  children: n,
10
- emptyTitle: h,
11
- emptyDescription: d,
10
+ emptyTitle: d,
11
+ emptyDescription: h,
12
12
  errorTitle: m,
13
13
  errorDescription: s
14
14
  }) {
@@ -17,11 +17,11 @@ function k({
17
17
  if (t === "empty" || t === "error") {
18
18
  const r = t === "error";
19
19
  return /* @__PURE__ */ e(w, { children: /* @__PURE__ */ l(B, { children: [
20
- /* @__PURE__ */ e(v, { children: r ? m ?? "Something went wrong" : h ?? "Nothing to show" }),
21
- /* @__PURE__ */ e(C, { children: r ? s ?? "The details could not be loaded." : d ?? "There are no details to display yet." })
20
+ /* @__PURE__ */ e(v, { children: r ? m ?? "Something went wrong" : d ?? "Nothing to show" }),
21
+ /* @__PURE__ */ e(C, { children: r ? s ?? "The details could not be loaded." : h ?? "There are no details to display yet." })
22
22
  ] }) });
23
23
  }
24
- return n ? /* @__PURE__ */ e(S, { children: n }) : i != null && i.length ? /* @__PURE__ */ e(
24
+ return n ? /* @__PURE__ */ e(p, { children: n }) : i != null && i.length ? /* @__PURE__ */ e(
25
25
  F,
26
26
  {
27
27
  className: "-mx-6",
@@ -37,8 +37,8 @@ function q({
37
37
  open: t,
38
38
  defaultOpen: i,
39
39
  onOpenChange: n,
40
- title: h,
41
- side: d = "right",
40
+ title: d,
41
+ side: h = "right",
42
42
  contentState: m = "content",
43
43
  properties: s,
44
44
  children: r,
@@ -48,14 +48,14 @@ function q({
48
48
  emptyDescription: u,
49
49
  errorTitle: f,
50
50
  errorDescription: y,
51
- portalContainer: p
51
+ portalContainer: g
52
52
  }) {
53
- return /* @__PURE__ */ l(g, { open: t, defaultOpen: i, onOpenChange: n, children: [
53
+ return /* @__PURE__ */ l(S, { open: t, defaultOpen: i, onOpenChange: n, children: [
54
54
  c ? /* @__PURE__ */ e(D, { render: c }) : null,
55
- /* @__PURE__ */ l(x, { side: d, portalContainer: p, children: [
56
- /* @__PURE__ */ l(N, { children: [
57
- /* @__PURE__ */ e(E, { children: h }),
58
- /* @__PURE__ */ e(L, {})
55
+ /* @__PURE__ */ l(x, { side: h, portalContainer: g, children: [
56
+ /* @__PURE__ */ l(L, { children: [
57
+ /* @__PURE__ */ e(N, { children: d }),
58
+ /* @__PURE__ */ e(E, {})
59
59
  ] }),
60
60
  /* @__PURE__ */ e(T, { children: /* @__PURE__ */ e(
61
61
  k,
@@ -1 +1 @@
1
- {"version":3,"file":"sheet-details.js","sources":["../../../../src/components/ui/sheet/sheet-details.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport {\n DescriptionList,\n DescriptionListItem,\n DescriptionListLabel,\n DescriptionListValue,\n} from '../description-list';\nimport {\n Empty,\n EmptyDescription,\n EmptyHeader,\n EmptyTitle,\n} from '../empty';\nimport { Spinner } from '../spinner';\nimport {\n Sheet,\n SheetBody,\n SheetCloseButton,\n type SheetContentProps,\n SheetContent,\n SheetFooter,\n SheetHeader,\n SheetTitle,\n SheetTrigger,\n} from './sheet';\n\n// `SheetDetails` is the preset for the `sheet-detail-panel` usage pattern — the\n// \"easy path that IS the pattern\". It bakes a right-anchored Sheet's header\n// (title + close), a body that switches by `contentState`\n// (loading → Spinner, empty/error → Empty, else a key/value property list or\n// custom children), and an optional footer of actions — so consumers don't\n// re-assemble (or hand-roll) the recipe. For anything outside the recipe, compose\n// the `Sheet*` parts directly. (React composition of the Vue kit's `Details`.)\n\nexport interface SheetDetailsProperty {\n label: React.ReactNode;\n value: React.ReactNode;\n}\n\nexport type SheetDetailsContentState = 'content' | 'loading' | 'empty' | 'error';\n\nexport interface SheetDetailsProps {\n /** Controlled open state. Pair with `onOpenChange`. */\n open?: boolean;\n /** Initial open state when uncontrolled. */\n defaultOpen?: boolean;\n /** Fires when the sheet opens or closes. */\n onOpenChange?: (open: boolean, eventDetails: unknown) => void;\n /** Panel title (header). Also the accessible name. */\n title: React.ReactNode;\n /** Edge the panel anchors to. Defaults to `right`. */\n side?: SheetContentProps['side'];\n /** Which body view to show. Defaults to `content`. */\n contentState?: SheetDetailsContentState;\n /** Key/value rows rendered as the body in the `content` state (unless `children`). */\n properties?: SheetDetailsProperty[];\n /** Custom body for the `content` state — overrides `properties`. */\n children?: React.ReactNode;\n /** Footer action(s). Omit for no footer. */\n actions?: React.ReactNode;\n /** Optional trigger element (rendered via the Sheet trigger's `render`). */\n trigger?: React.ReactElement;\n /** Empty-state copy (`contentState=\"empty\"`). */\n emptyTitle?: React.ReactNode;\n emptyDescription?: React.ReactNode;\n /** Error-state copy (`contentState=\"error\"`). */\n errorTitle?: React.ReactNode;\n errorDescription?: React.ReactNode;\n /** Portal container (shadow-root mount for isolated previews). */\n portalContainer?: SheetContentProps['portalContainer'];\n}\n\nfunction SheetDetailsBody({\n contentState,\n properties,\n children,\n emptyTitle,\n emptyDescription,\n errorTitle,\n errorDescription,\n}: Pick<\n SheetDetailsProps,\n | 'contentState'\n | 'properties'\n | 'children'\n | 'emptyTitle'\n | 'emptyDescription'\n | 'errorTitle'\n | 'errorDescription'\n>) {\n if (contentState === 'loading') {\n return (\n <div className=\"flex h-40 items-center justify-center\">\n <Spinner />\n </div>\n );\n }\n if (contentState === 'empty' || contentState === 'error') {\n const isError = contentState === 'error';\n return (\n <Empty>\n <EmptyHeader>\n <EmptyTitle>\n {isError\n ? (errorTitle ?? 'Something went wrong')\n : (emptyTitle ?? 'Nothing to show')}\n </EmptyTitle>\n <EmptyDescription>\n {isError\n ? (errorDescription ?? 'The details could not be loaded.')\n : (emptyDescription ?? 'There are no details to display yet.')}\n </EmptyDescription>\n </EmptyHeader>\n </Empty>\n );\n }\n if (children) return <>{children}</>;\n if (properties?.length) {\n // Render through DescriptionList. `-mx-6` cancels the SheetBody padding so\n // the row dividers go full-bleed while the content stays aligned at the\n // panel's 24px inset; the label column is tightened for the narrow panel.\n return (\n <DescriptionList\n className=\"-mx-6\"\n style={{ '--description-list-label': '9rem' } as React.CSSProperties}\n >\n {properties.map((p, i) => (\n <DescriptionListItem key={i}>\n <DescriptionListLabel className=\"text-muted-foreground\">\n {p.label}\n </DescriptionListLabel>\n <DescriptionListValue className=\"font-medium\">\n {p.value}\n </DescriptionListValue>\n </DescriptionListItem>\n ))}\n </DescriptionList>\n );\n }\n return null;\n}\n\nfunction SheetDetails({\n open,\n defaultOpen,\n onOpenChange,\n title,\n side = 'right',\n contentState = 'content',\n properties,\n children,\n actions,\n trigger,\n emptyTitle,\n emptyDescription,\n errorTitle,\n errorDescription,\n portalContainer,\n}: SheetDetailsProps) {\n return (\n <Sheet open={open} defaultOpen={defaultOpen} onOpenChange={onOpenChange}>\n {trigger ? <SheetTrigger render={trigger} /> : null}\n <SheetContent side={side} portalContainer={portalContainer}>\n <SheetHeader>\n <SheetTitle>{title}</SheetTitle>\n <SheetCloseButton />\n </SheetHeader>\n <SheetBody>\n <SheetDetailsBody\n contentState={contentState}\n properties={properties}\n emptyTitle={emptyTitle}\n emptyDescription={emptyDescription}\n errorTitle={errorTitle}\n errorDescription={errorDescription}\n >\n {children}\n </SheetDetailsBody>\n </SheetBody>\n {actions ? <SheetFooter>{actions}</SheetFooter> : null}\n </SheetContent>\n </Sheet>\n );\n}\nSheetDetails.displayName = 'SheetDetails';\n\nexport { SheetDetails };\n"],"names":["SheetDetailsBody","contentState","properties","children","emptyTitle","emptyDescription","errorTitle","errorDescription","jsx","Spinner","isError","Empty","jsxs","EmptyHeader","EmptyTitle","EmptyDescription","Fragment","DescriptionList","p","i","DescriptionListItem","DescriptionListLabel","DescriptionListValue","SheetDetails","open","defaultOpen","onOpenChange","title","side","actions","trigger","portalContainer","Sheet","SheetTrigger","SheetContent","SheetHeader","SheetTitle","SheetCloseButton","SheetBody","SheetFooter"],"mappings":";;;;;AAyEA,SAASA,EAAiB;AAAA,EACxB,cAAAC;AAAA,EACA,YAAAC;AAAA,EACA,UAAAC;AAAA,EACA,YAAAC;AAAA,EACA,kBAAAC;AAAA,EACA,YAAAC;AAAA,EACA,kBAAAC;AACF,GASG;AACD,MAAIN,MAAiB;AACnB,6BACG,OAAA,EAAI,WAAU,yCACb,UAAA,gBAAAO,EAACC,KAAQ,GACX;AAGJ,MAAIR,MAAiB,WAAWA,MAAiB,SAAS;AACxD,UAAMS,IAAUT,MAAiB;AACjC,WACE,gBAAAO,EAACG,GAAA,EACC,UAAA,gBAAAC,EAACC,GAAA,EACC,UAAA;AAAA,MAAA,gBAAAL,EAACM,GAAA,EACE,UAAAJ,IACIJ,KAAc,yBACdF,KAAc,mBACrB;AAAA,wBACCW,GAAA,EACE,UAAAL,IACIH,KAAoB,qCACpBF,KAAoB,uCAAA,CAC3B;AAAA,IAAA,EAAA,CACF,EAAA,CACF;AAAA,EAEJ;AACA,SAAIF,IAAiB,gBAAAK,EAAAQ,GAAA,EAAG,UAAAb,EAAA,CAAS,IAC7BD,KAAA,QAAAA,EAAY,SAKZ,gBAAAM;AAAA,IAACS;AAAA,IAAA;AAAA,MACC,WAAU;AAAA,MACV,OAAO,EAAE,4BAA4B,OAAA;AAAA,MAEpC,YAAW,IAAI,CAACC,GAAGC,wBACjBC,GAAA,EACC,UAAA;AAAA,QAAA,gBAAAZ,EAACa,GAAA,EAAqB,WAAU,yBAC7B,UAAAH,EAAE,OACL;AAAA,QACA,gBAAAV,EAACc,GAAA,EAAqB,WAAU,eAC7B,YAAE,MAAA,CACL;AAAA,MAAA,EAAA,GANwBH,CAO1B,CACD;AAAA,IAAA;AAAA,EAAA,IAIA;AACT;AAEA,SAASI,EAAa;AAAA,EACpB,MAAAC;AAAA,EACA,aAAAC;AAAA,EACA,cAAAC;AAAA,EACA,OAAAC;AAAA,EACA,MAAAC,IAAO;AAAA,EACP,cAAA3B,IAAe;AAAA,EACf,YAAAC;AAAA,EACA,UAAAC;AAAA,EACA,SAAA0B;AAAA,EACA,SAAAC;AAAA,EACA,YAAA1B;AAAA,EACA,kBAAAC;AAAA,EACA,YAAAC;AAAA,EACA,kBAAAC;AAAA,EACA,iBAAAwB;AACF,GAAsB;AACpB,SACE,gBAAAnB,EAACoB,GAAA,EAAM,MAAAR,GAAY,aAAAC,GAA0B,cAAAC,GAC1C,UAAA;AAAA,IAAAI,IAAU,gBAAAtB,EAACyB,GAAA,EAAa,QAAQH,EAAA,CAAS,IAAK;AAAA,IAC/C,gBAAAlB,EAACsB,GAAA,EAAa,MAAAN,GAAY,iBAAAG,GACxB,UAAA;AAAA,MAAA,gBAAAnB,EAACuB,GAAA,EACC,UAAA;AAAA,QAAA,gBAAA3B,EAAC4B,KAAY,UAAAT,EAAA,CAAM;AAAA,0BAClBU,GAAA,CAAA,CAAiB;AAAA,MAAA,GACpB;AAAA,wBACCC,GAAA,EACC,UAAA,gBAAA9B;AAAA,QAACR;AAAA,QAAA;AAAA,UACC,cAAAC;AAAA,UACA,YAAAC;AAAA,UACA,YAAAE;AAAA,UACA,kBAAAC;AAAA,UACA,YAAAC;AAAA,UACA,kBAAAC;AAAA,UAEC,UAAAJ;AAAA,QAAA;AAAA,MAAA,GAEL;AAAA,MACC0B,IAAU,gBAAArB,EAAC+B,GAAA,EAAa,UAAAV,EAAA,CAAQ,IAAiB;AAAA,IAAA,EAAA,CACpD;AAAA,EAAA,GACF;AAEJ;AACAN,EAAa,cAAc;"}
1
+ {"version":3,"file":"sheet-details.js","sources":["../../../../src/components/ui/sheet/sheet-details.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport {\n DescriptionList,\n DescriptionListItem,\n DescriptionListLabel,\n DescriptionListValue,\n} from '../description-list';\nimport {\n Empty,\n EmptyDescription,\n EmptyHeader,\n EmptyTitle,\n} from '../empty';\nimport { Loading } from '../loading';\nimport {\n Sheet,\n SheetBody,\n SheetCloseButton,\n type SheetContentProps,\n SheetContent,\n SheetFooter,\n SheetHeader,\n SheetTitle,\n SheetTrigger,\n} from './sheet';\n\n// `SheetDetails` is the preset for the `sheet-detail-panel` usage pattern — the\n// \"easy path that IS the pattern\". It bakes a right-anchored Sheet's header\n// (title + close), a body that switches by `contentState`\n// (loading → Loading, empty/error → Empty, else a key/value property list or\n// custom children), and an optional footer of actions — so consumers don't\n// re-assemble (or hand-roll) the recipe. For anything outside the recipe, compose\n// the `Sheet*` parts directly. (React composition of the Vue kit's `Details`.)\n\nexport interface SheetDetailsProperty {\n label: React.ReactNode;\n value: React.ReactNode;\n}\n\nexport type SheetDetailsContentState = 'content' | 'loading' | 'empty' | 'error';\n\nexport interface SheetDetailsProps {\n /** Controlled open state. Pair with `onOpenChange`. */\n open?: boolean;\n /** Initial open state when uncontrolled. */\n defaultOpen?: boolean;\n /** Fires when the sheet opens or closes. */\n onOpenChange?: (open: boolean, eventDetails: unknown) => void;\n /** Panel title (header). Also the accessible name. */\n title: React.ReactNode;\n /** Edge the panel anchors to. Defaults to `right`. */\n side?: SheetContentProps['side'];\n /** Which body view to show. Defaults to `content`. */\n contentState?: SheetDetailsContentState;\n /** Key/value rows rendered as the body in the `content` state (unless `children`). */\n properties?: SheetDetailsProperty[];\n /** Custom body for the `content` state — overrides `properties`. */\n children?: React.ReactNode;\n /** Footer action(s). Omit for no footer. */\n actions?: React.ReactNode;\n /** Optional trigger element (rendered via the Sheet trigger's `render`). */\n trigger?: React.ReactElement;\n /** Empty-state copy (`contentState=\"empty\"`). */\n emptyTitle?: React.ReactNode;\n emptyDescription?: React.ReactNode;\n /** Error-state copy (`contentState=\"error\"`). */\n errorTitle?: React.ReactNode;\n errorDescription?: React.ReactNode;\n /** Portal container (shadow-root mount for isolated previews). */\n portalContainer?: SheetContentProps['portalContainer'];\n}\n\nfunction SheetDetailsBody({\n contentState,\n properties,\n children,\n emptyTitle,\n emptyDescription,\n errorTitle,\n errorDescription,\n}: Pick<\n SheetDetailsProps,\n | 'contentState'\n | 'properties'\n | 'children'\n | 'emptyTitle'\n | 'emptyDescription'\n | 'errorTitle'\n | 'errorDescription'\n>) {\n if (contentState === 'loading') {\n return (\n <div className=\"flex h-40 items-center justify-center\">\n <Loading />\n </div>\n );\n }\n if (contentState === 'empty' || contentState === 'error') {\n const isError = contentState === 'error';\n return (\n <Empty>\n <EmptyHeader>\n <EmptyTitle>\n {isError\n ? (errorTitle ?? 'Something went wrong')\n : (emptyTitle ?? 'Nothing to show')}\n </EmptyTitle>\n <EmptyDescription>\n {isError\n ? (errorDescription ?? 'The details could not be loaded.')\n : (emptyDescription ?? 'There are no details to display yet.')}\n </EmptyDescription>\n </EmptyHeader>\n </Empty>\n );\n }\n if (children) return <>{children}</>;\n if (properties?.length) {\n // Render through DescriptionList. `-mx-6` cancels the SheetBody padding so\n // the row dividers go full-bleed while the content stays aligned at the\n // panel's 24px inset; the label column is tightened for the narrow panel.\n return (\n <DescriptionList\n className=\"-mx-6\"\n style={{ '--description-list-label': '9rem' } as React.CSSProperties}\n >\n {properties.map((p, i) => (\n <DescriptionListItem key={i}>\n <DescriptionListLabel className=\"text-muted-foreground\">\n {p.label}\n </DescriptionListLabel>\n <DescriptionListValue className=\"font-medium\">\n {p.value}\n </DescriptionListValue>\n </DescriptionListItem>\n ))}\n </DescriptionList>\n );\n }\n return null;\n}\n\nfunction SheetDetails({\n open,\n defaultOpen,\n onOpenChange,\n title,\n side = 'right',\n contentState = 'content',\n properties,\n children,\n actions,\n trigger,\n emptyTitle,\n emptyDescription,\n errorTitle,\n errorDescription,\n portalContainer,\n}: SheetDetailsProps) {\n return (\n <Sheet open={open} defaultOpen={defaultOpen} onOpenChange={onOpenChange}>\n {trigger ? <SheetTrigger render={trigger} /> : null}\n <SheetContent side={side} portalContainer={portalContainer}>\n <SheetHeader>\n <SheetTitle>{title}</SheetTitle>\n <SheetCloseButton />\n </SheetHeader>\n <SheetBody>\n <SheetDetailsBody\n contentState={contentState}\n properties={properties}\n emptyTitle={emptyTitle}\n emptyDescription={emptyDescription}\n errorTitle={errorTitle}\n errorDescription={errorDescription}\n >\n {children}\n </SheetDetailsBody>\n </SheetBody>\n {actions ? <SheetFooter>{actions}</SheetFooter> : null}\n </SheetContent>\n </Sheet>\n );\n}\nSheetDetails.displayName = 'SheetDetails';\n\nexport { SheetDetails };\n"],"names":["SheetDetailsBody","contentState","properties","children","emptyTitle","emptyDescription","errorTitle","errorDescription","jsx","Loading","isError","Empty","jsxs","EmptyHeader","EmptyTitle","EmptyDescription","Fragment","DescriptionList","p","i","DescriptionListItem","DescriptionListLabel","DescriptionListValue","SheetDetails","open","defaultOpen","onOpenChange","title","side","actions","trigger","portalContainer","Sheet","SheetTrigger","SheetContent","SheetHeader","SheetTitle","SheetCloseButton","SheetBody","SheetFooter"],"mappings":";;;;;AAyEA,SAASA,EAAiB;AAAA,EACxB,cAAAC;AAAA,EACA,YAAAC;AAAA,EACA,UAAAC;AAAA,EACA,YAAAC;AAAA,EACA,kBAAAC;AAAA,EACA,YAAAC;AAAA,EACA,kBAAAC;AACF,GASG;AACD,MAAIN,MAAiB;AACnB,6BACG,OAAA,EAAI,WAAU,yCACb,UAAA,gBAAAO,EAACC,KAAQ,GACX;AAGJ,MAAIR,MAAiB,WAAWA,MAAiB,SAAS;AACxD,UAAMS,IAAUT,MAAiB;AACjC,WACE,gBAAAO,EAACG,GAAA,EACC,UAAA,gBAAAC,EAACC,GAAA,EACC,UAAA;AAAA,MAAA,gBAAAL,EAACM,GAAA,EACE,UAAAJ,IACIJ,KAAc,yBACdF,KAAc,mBACrB;AAAA,wBACCW,GAAA,EACE,UAAAL,IACIH,KAAoB,qCACpBF,KAAoB,uCAAA,CAC3B;AAAA,IAAA,EAAA,CACF,EAAA,CACF;AAAA,EAEJ;AACA,SAAIF,IAAiB,gBAAAK,EAAAQ,GAAA,EAAG,UAAAb,EAAA,CAAS,IAC7BD,KAAA,QAAAA,EAAY,SAKZ,gBAAAM;AAAA,IAACS;AAAA,IAAA;AAAA,MACC,WAAU;AAAA,MACV,OAAO,EAAE,4BAA4B,OAAA;AAAA,MAEpC,YAAW,IAAI,CAACC,GAAGC,wBACjBC,GAAA,EACC,UAAA;AAAA,QAAA,gBAAAZ,EAACa,GAAA,EAAqB,WAAU,yBAC7B,UAAAH,EAAE,OACL;AAAA,QACA,gBAAAV,EAACc,GAAA,EAAqB,WAAU,eAC7B,YAAE,MAAA,CACL;AAAA,MAAA,EAAA,GANwBH,CAO1B,CACD;AAAA,IAAA;AAAA,EAAA,IAIA;AACT;AAEA,SAASI,EAAa;AAAA,EACpB,MAAAC;AAAA,EACA,aAAAC;AAAA,EACA,cAAAC;AAAA,EACA,OAAAC;AAAA,EACA,MAAAC,IAAO;AAAA,EACP,cAAA3B,IAAe;AAAA,EACf,YAAAC;AAAA,EACA,UAAAC;AAAA,EACA,SAAA0B;AAAA,EACA,SAAAC;AAAA,EACA,YAAA1B;AAAA,EACA,kBAAAC;AAAA,EACA,YAAAC;AAAA,EACA,kBAAAC;AAAA,EACA,iBAAAwB;AACF,GAAsB;AACpB,SACE,gBAAAnB,EAACoB,GAAA,EAAM,MAAAR,GAAY,aAAAC,GAA0B,cAAAC,GAC1C,UAAA;AAAA,IAAAI,IAAU,gBAAAtB,EAACyB,GAAA,EAAa,QAAQH,EAAA,CAAS,IAAK;AAAA,IAC/C,gBAAAlB,EAACsB,GAAA,EAAa,MAAAN,GAAY,iBAAAG,GACxB,UAAA;AAAA,MAAA,gBAAAnB,EAACuB,GAAA,EACC,UAAA;AAAA,QAAA,gBAAA3B,EAAC4B,KAAY,UAAAT,EAAA,CAAM;AAAA,0BAClBU,GAAA,CAAA,CAAiB;AAAA,MAAA,GACpB;AAAA,wBACCC,GAAA,EACC,UAAA,gBAAA9B;AAAA,QAACR;AAAA,QAAA;AAAA,UACC,cAAAC;AAAA,UACA,YAAAC;AAAA,UACA,YAAAE;AAAA,UACA,kBAAAC;AAAA,UACA,YAAAC;AAAA,UACA,kBAAAC;AAAA,UAEC,UAAAJ;AAAA,QAAA;AAAA,MAAA,GAEL;AAAA,MACC0B,IAAU,gBAAArB,EAAC+B,GAAA,EAAa,UAAAV,EAAA,CAAQ,IAAiB;AAAA,IAAA,EAAA,CACpD;AAAA,EAAA,GACF;AAEJ;AACAN,EAAa,cAAc;"}
@@ -1 +1 @@
1
- {"version":3,"file":"spinner.js","sources":["../../../../src/components/ui/spinner/spinner.tsx"],"sourcesContent":["import * as React from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\n\nimport { cn } from '@/lib/utils';\n\n// Ported from `@acronis-platform/shadcn-uikit`'s `spinner`\n// (packages/ui-legacy/src/components/ui/spinner.tsx). A CSS loading spinner — no\n// Base UI primitive. No `--ui-spinner-*` tier; the ring color defaults to the\n// brand action blue via `text-secondary` (--ui-background-brand-secondary, used\n// through `border-current`), replacing the legacy `--spinner-color` var.\n// Override the color with a `text-*` class. `size` mirrors the legacy scale.\nconst spinnerVariants = cva(\n 'inline-block animate-spin rounded-full border-2 border-solid border-current border-r-transparent text-secondary',\n {\n variants: {\n size: {\n sm: 'size-4',\n md: 'size-6',\n lg: 'size-8',\n xl: 'size-12',\n },\n },\n defaultVariants: {\n size: 'md',\n },\n }\n);\n\nexport interface SpinnerProps\n extends React.HTMLAttributes<HTMLDivElement>,\n VariantProps<typeof spinnerVariants> {}\n\nconst Spinner = React.forwardRef<HTMLDivElement, SpinnerProps>(\n ({ className, size, ...props }, ref) => (\n <div\n ref={ref}\n role=\"status\"\n aria-label=\"Loading\"\n className={cn(spinnerVariants({ size }), className)}\n {...props}\n >\n <span className=\"sr-only\">Loading…</span>\n </div>\n )\n);\nSpinner.displayName = 'Spinner';\n\nexport { Spinner, spinnerVariants };\n"],"names":["spinnerVariants","cva","Spinner","React","className","size","props","ref","jsx","cn"],"mappings":";;;;AAWA,MAAMA,IAAkBC;AAAA,EACtB;AAAA,EACA;AAAA,IACE,UAAU;AAAA,MACR,MAAM;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI;AAAA,MAAA;AAAA,IACN;AAAA,IAEF,iBAAiB;AAAA,MACf,MAAM;AAAA,IAAA;AAAA,EACR;AAEJ,GAMMC,IAAUC,EAAM;AAAA,EACpB,CAAC,EAAE,WAAAC,GAAW,MAAAC,GAAM,GAAGC,EAAA,GAASC,MAC9B,gBAAAC;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,KAAAD;AAAA,MACA,MAAK;AAAA,MACL,cAAW;AAAA,MACX,WAAWE,EAAGT,EAAgB,EAAE,MAAAK,EAAA,CAAM,GAAGD,CAAS;AAAA,MACjD,GAAGE;AAAA,MAEJ,UAAA,gBAAAE,EAAC,QAAA,EAAK,WAAU,WAAU,UAAA,WAAA,CAAQ;AAAA,IAAA;AAAA,EAAA;AAGxC;AACAN,EAAQ,cAAc;"}
1
+ {"version":3,"file":"spinner.js","sources":["../../../../src/components/ui/spinner/spinner.tsx"],"sourcesContent":["import * as React from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\n\nimport { cn } from '@/lib/utils';\n\n// Ported from `@acronis-platform/shadcn-uikit`'s `spinner`\n// (packages/ui-legacy/src/components/ui/spinner.tsx). A CSS loading spinner — no\n// Base UI primitive. No `--ui-spinner-*` tier; the ring color defaults to the\n// brand action blue via `text-secondary` (--ui-background-brand-secondary, used\n// through `border-current`), replacing the legacy `--spinner-color` var.\n// Override the color with a `text-*` class. `size` mirrors the legacy scale.\n//\n// Internal primitive — deliberately NOT re-exported from `src/index.ts` (mirrors\n// the InputBox/SearchBox pattern). Consumed by `Loading` (its icon), `Toast` (a\n// small inline icon), and `ChartState`. Apps building a standalone loading\n// state should use `Loading`, which wraps this ring with a label and\n// placement-context container tokens.\nconst spinnerVariants = cva(\n 'inline-block animate-spin rounded-full border-2 border-solid border-current border-r-transparent text-secondary',\n {\n variants: {\n size: {\n sm: 'size-4',\n md: 'size-6',\n lg: 'size-8',\n xl: 'size-12',\n },\n },\n defaultVariants: {\n size: 'md',\n },\n }\n);\n\nexport interface SpinnerProps\n extends React.HTMLAttributes<HTMLDivElement>,\n VariantProps<typeof spinnerVariants> {}\n\nconst Spinner = React.forwardRef<HTMLDivElement, SpinnerProps>(\n ({ className, size, ...props }, ref) => (\n <div\n ref={ref}\n role=\"status\"\n aria-label=\"Loading\"\n className={cn(spinnerVariants({ size }), className)}\n {...props}\n >\n <span className=\"sr-only\">Loading…</span>\n </div>\n )\n);\nSpinner.displayName = 'Spinner';\n\nexport { Spinner, spinnerVariants };\n"],"names":["spinnerVariants","cva","Spinner","React","className","size","props","ref","jsx","cn"],"mappings":";;;;AAiBA,MAAMA,IAAkBC;AAAA,EACtB;AAAA,EACA;AAAA,IACE,UAAU;AAAA,MACR,MAAM;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI;AAAA,MAAA;AAAA,IACN;AAAA,IAEF,iBAAiB;AAAA,MACf,MAAM;AAAA,IAAA;AAAA,EACR;AAEJ,GAMMC,IAAUC,EAAM;AAAA,EACpB,CAAC,EAAE,WAAAC,GAAW,MAAAC,GAAM,GAAGC,EAAA,GAASC,MAC9B,gBAAAC;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,KAAAD;AAAA,MACA,MAAK;AAAA,MACL,cAAW;AAAA,MACX,WAAWE,EAAGT,EAAgB,EAAE,MAAAK,EAAA,CAAM,GAAGD,CAAS;AAAA,MACjD,GAAGE;AAAA,MAEJ,UAAA,gBAAAE,EAAC,QAAA,EAAK,WAAU,WAAU,UAAA,WAAA,CAAQ;AAAA,IAAA;AAAA,EAAA;AAGxC;AACAN,EAAQ,cAAc;"}