@corbits/react-ui 0.1.0 → 0.2.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/LICENSE +174 -499
  2. package/README.md +228 -85
  3. package/dist/blocks/login/auth-layout.d.ts +1 -1
  4. package/dist/blocks/login/auth-layout.js +3 -33
  5. package/dist/blocks/login/login-form.js +6 -119
  6. package/dist/hooks/use-command-palette-navigation.js +18 -17
  7. package/dist/hooks/use-controllable-state.d.ts +2 -2
  8. package/dist/hooks/use-controllable-state.js +23 -15
  9. package/dist/hooks/use-delayed-autofocus.js +10 -11
  10. package/dist/hooks/use-dismissable-popover.d.ts +2 -2
  11. package/dist/hooks/use-dismissable-popover.js +21 -29
  12. package/dist/hooks/use-list-selection.js +54 -85
  13. package/dist/hooks/use-prefers-reduced-motion.js +8 -4
  14. package/dist/hooks/use-scroll-current-into-view.js +5 -7
  15. package/dist/index.d.ts +0 -11
  16. package/dist/index.js +10 -19
  17. package/dist/lib/artifact.js +16 -35
  18. package/dist/lib/chart-geometry.js +33 -20
  19. package/dist/lib/chart-palette.js +17 -31
  20. package/dist/lib/chat-message.js +32 -13
  21. package/dist/lib/chat-parts.js +2 -1
  22. package/dist/lib/csv.js +42 -26
  23. package/dist/lib/metrics.js +30 -48
  24. package/dist/lib/now-item.js +26 -25
  25. package/dist/lib/relative-time.js +14 -29
  26. package/dist/lib/theme.js +32 -30
  27. package/dist/lib/url.js +9 -8
  28. package/dist/lib/workflow-display-flow.js +37 -33
  29. package/dist/lib/workflow-registry.d.ts +0 -41
  30. package/dist/lib/workflow-registry.js +13 -23
  31. package/dist/lib/workflow-run-error.js +16 -20
  32. package/dist/lib/workflow-run-progress.js +94 -52
  33. package/dist/lib/workflow-run.js +17 -13
  34. package/dist/styles.css +11 -11
  35. package/dist/test/render-hook.js +11 -12
  36. package/dist/theme.css +51 -14
  37. package/dist/ui/agent-turn.d.ts +1 -1
  38. package/dist/ui/agent-turn.js +4 -37
  39. package/dist/ui/animated-number.js +15 -28
  40. package/dist/ui/approval-card.js +5 -90
  41. package/dist/ui/artifact-body.js +47 -125
  42. package/dist/ui/artifact-notice.d.ts +1 -1
  43. package/dist/ui/artifact-notice.js +9 -16
  44. package/dist/ui/avatar.d.ts +1 -1
  45. package/dist/ui/avatar.js +11 -48
  46. package/dist/ui/badge.js +4 -12
  47. package/dist/ui/bar-chart.d.ts +1 -1
  48. package/dist/ui/bar-chart.js +22 -74
  49. package/dist/ui/block-card.js +7 -45
  50. package/dist/ui/boot-screen.d.ts +1 -1
  51. package/dist/ui/boot-screen.js +4 -33
  52. package/dist/ui/bulk-action-bar.d.ts +1 -1
  53. package/dist/ui/bulk-action-bar.js +14 -33
  54. package/dist/ui/button.js +10 -24
  55. package/dist/ui/card.js +5 -25
  56. package/dist/ui/category-bars.js +14 -59
  57. package/dist/ui/chart-frame.d.ts +2 -2
  58. package/dist/ui/chart-frame.js +6 -85
  59. package/dist/ui/chat-composer.js +4 -16
  60. package/dist/ui/chat-dock-timing.js +7 -3
  61. package/dist/ui/chat-input.js +20 -100
  62. package/dist/ui/chat-panel.d.ts +1 -1
  63. package/dist/ui/chat-panel.js +7 -41
  64. package/dist/ui/chat-thread.js +13 -31
  65. package/dist/ui/checkbox.js +10 -52
  66. package/dist/ui/command-palette.js +71 -246
  67. package/dist/ui/compare-body.d.ts +1 -1
  68. package/dist/ui/compare-body.js +28 -98
  69. package/dist/ui/confirm-button.js +8 -15
  70. package/dist/ui/corbits-mark.js +7 -16
  71. package/dist/ui/csv-table.d.ts +1 -1
  72. package/dist/ui/csv-table.js +8 -50
  73. package/dist/ui/dialog.d.ts +1 -1
  74. package/dist/ui/dialog.js +32 -62
  75. package/dist/ui/dictation-status-line.js +7 -25
  76. package/dist/ui/dither-canvas.d.ts +1 -1
  77. package/dist/ui/dither-canvas.js +31 -56
  78. package/dist/ui/embed-body.d.ts +1 -1
  79. package/dist/ui/embed-body.js +7 -56
  80. package/dist/ui/empty-state.d.ts +1 -1
  81. package/dist/ui/empty-state.js +3 -26
  82. package/dist/ui/file-input.js +17 -37
  83. package/dist/ui/filter-bar.d.ts +1 -1
  84. package/dist/ui/filter-bar.js +11 -71
  85. package/dist/ui/filter-chip.d.ts +1 -1
  86. package/dist/ui/filter-chip.js +7 -15
  87. package/dist/ui/gate-block.d.ts +2 -1
  88. package/dist/ui/gate-block.js +4 -29
  89. package/dist/ui/horizontal-stepper.d.ts +1 -1
  90. package/dist/ui/horizontal-stepper.js +18 -45
  91. package/dist/ui/input.js +1 -6
  92. package/dist/ui/inspector-shell.d.ts +5 -5
  93. package/dist/ui/inspector-shell.js +14 -81
  94. package/dist/ui/intake-form.d.ts +1 -1
  95. package/dist/ui/intake-form.js +21 -97
  96. package/dist/ui/kind-card-grid.js +9 -31
  97. package/dist/ui/library-page-header.js +4 -32
  98. package/dist/ui/list-detail.js +5 -35
  99. package/dist/ui/live-run-banner.d.ts +1 -1
  100. package/dist/ui/live-run-banner.js +5 -15
  101. package/dist/ui/live-status-line.js +6 -24
  102. package/dist/ui/menu.js +7 -24
  103. package/dist/ui/message-bubble.d.ts +3 -3
  104. package/dist/ui/message-bubble.js +5 -44
  105. package/dist/ui/mic-button.d.ts +1 -1
  106. package/dist/ui/mic-button.js +15 -21
  107. package/dist/ui/mic-permission-dialog.js +5 -41
  108. package/dist/ui/notifications-bell.js +9 -43
  109. package/dist/ui/now-cards.d.ts +2 -2
  110. package/dist/ui/now-cards.js +16 -94
  111. package/dist/ui/page-panel.js +11 -11
  112. package/dist/ui/page-shell.js +4 -11
  113. package/dist/ui/parts-renderer.js +51 -149
  114. package/dist/ui/profile-card.js +7 -111
  115. package/dist/ui/progress-checklist.js +11 -49
  116. package/dist/ui/provider-mark.d.ts +2 -2
  117. package/dist/ui/provider-mark.js +9 -16
  118. package/dist/ui/quick-reply-chips.js +6 -14
  119. package/dist/ui/quote-card.js +12 -32
  120. package/dist/ui/reasoning-block.d.ts +1 -1
  121. package/dist/ui/reasoning-block.js +14 -33
  122. package/dist/ui/research-body.js +32 -213
  123. package/dist/ui/rich-empty-state.js +6 -48
  124. package/dist/ui/run-now-button.js +14 -15
  125. package/dist/ui/section.d.ts +1 -1
  126. package/dist/ui/section.js +4 -40
  127. package/dist/ui/select.js +1 -15
  128. package/dist/ui/selection-checkbox.d.ts +1 -1
  129. package/dist/ui/selection-checkbox.js +11 -29
  130. package/dist/ui/settings-panel.js +7 -50
  131. package/dist/ui/shimmer-text.js +3 -6
  132. package/dist/ui/sidebar-item-row.d.ts +1 -1
  133. package/dist/ui/sidebar-item-row.js +9 -39
  134. package/dist/ui/sidebar-panel.js +15 -40
  135. package/dist/ui/sidebar.js +15 -76
  136. package/dist/ui/skeleton.js +3 -7
  137. package/dist/ui/sortable-table.js +29 -72
  138. package/dist/ui/sparkline.js +14 -38
  139. package/dist/ui/stat-grid.js +17 -52
  140. package/dist/ui/status-dot.d.ts +1 -1
  141. package/dist/ui/status-dot.js +8 -20
  142. package/dist/ui/step-list.d.ts +1 -0
  143. package/dist/ui/step-list.js +11 -50
  144. package/dist/ui/switch.js +4 -16
  145. package/dist/ui/table.js +7 -32
  146. package/dist/ui/tabs.js +39 -54
  147. package/dist/ui/textarea.js +10 -19
  148. package/dist/ui/theme-provider.js +54 -78
  149. package/dist/ui/theme-toggle.js +13 -16
  150. package/dist/ui/thinking-indicator.js +3 -15
  151. package/dist/ui/thinking-label.js +16 -35
  152. package/dist/ui/thinking-mark.d.ts +1 -1
  153. package/dist/ui/thinking-mark.js +4 -145
  154. package/dist/ui/time-series-chart.js +43 -174
  155. package/dist/ui/toast.js +12 -20
  156. package/dist/ui/token-mosaic.js +5 -43
  157. package/dist/ui/tool-block.js +18 -70
  158. package/dist/ui/tool-narrative.d.ts +1 -1
  159. package/dist/ui/tool-narrative.js +10 -57
  160. package/dist/ui/tool-picker.js +57 -145
  161. package/dist/ui/tooltip.d.ts +1 -1
  162. package/dist/ui/tooltip.js +4 -33
  163. package/dist/ui/top-bar.js +14 -72
  164. package/dist/ui/trace-waterfall.d.ts +1 -1
  165. package/dist/ui/trace-waterfall.js +21 -93
  166. package/dist/ui/typing-indicator.d.ts +1 -1
  167. package/dist/ui/typing-indicator.js +4 -18
  168. package/dist/ui/view-toggle.js +10 -29
  169. package/dist/ui/voice-waveform.js +3 -11
  170. package/package.json +94 -535
@@ -10,24 +10,15 @@ import { cn } from "../lib/utils.js";
10
10
  * It fills with `currentColor`, so it takes the colour of whatever it sits in
11
11
  * and needs no dark-mode variant. Size it with a class; there is no `size` prop
12
12
  * because `className` already does that job in a Tailwind codebase.
13
- */ export const CORBITS_MARK_PATH = "M392.899 189.107L397.586 197.031C397.586 197.031 399.539 202.891 399.539 204.844L403.094 222.422C407 222.813 407.39 226.328 409.734 227.109C412.078 228.281 415.203 231.797 416.765 235.313C417.156 236.875 418.718 240.781 420.671 244.688C422.234 247.422 422.625 250.156 424.578 251.719L426.921 254.062C432.39 258.359 432.781 261.484 433.171 272.422C432.781 280.625 434.734 295.078 435.906 301.328C436.296 302.891 436.296 302.891 437.468 303.281C438.25 304.063 437.078 302.891 437.859 303.281C439.031 304.063 443.328 304.844 449.187 307.188C451.921 307.969 454.265 309.141 455.046 313.828C456.609 320.469 464.421 350.938 467.156 369.688L468.328 385.313L447.977 371.026C443.68 353.057 435.867 327.667 433.914 323.76C431.57 321.026 423.758 320.245 419.461 319.463C416.336 319.073 413.992 317.12 412.43 312.042C412.43 308.135 411.649 301.495 410.086 292.51C408.914 285.088 408.914 281.182 408.914 277.276C408.914 272.198 406.57 270.245 400.32 263.995L397.977 259.307C391.336 246.807 390.945 244.854 387.039 244.073C385.376 244.024 384.994 238.473 383.562 235.313C383.562 234.141 384.734 231.016 383.562 225.156L368.288 212.656C361.648 212.266 357.352 225.825 353.445 232.466L348.367 244.966L342.899 261.372L341.727 263.326L340.555 266.06L330.008 281.294L326.102 287.544L324.93 289.107L317.117 299.263L308.524 309.029L291.727 327.779L287.039 334.029L284.305 335.982L270.242 352.779L267.508 355.513L265.555 358.638L264.383 359.81L256.18 368.404L248.367 375.044L246.805 376.607L241.336 380.904C238.602 384.029 231.57 384.531 228.055 384.531C225.71 382.578 216.248 381.938 217.508 379.62L226.883 372.588L228.836 371.026L234.695 364.776L237.039 362.432L242.508 357.354C247.195 352.667 251.102 349.151 253.055 340.948C254.227 336.651 264.383 326.104 268.289 321.807L269.07 321.417L295.242 293.682L315.273 261.372L318.397 253.56C320.35 249.654 320.741 247.086 321.522 244.464C322.013 242.815 326.6 216.563 324.93 212.656C323.26 208.75 332.088 195.551 326.209 189.721C323.866 187.768 320.35 185.815 318.397 183.862C313.507 178.972 300.038 175.659 301.6 169.409L300.711 159.81C303.445 148.482 306.57 135.982 303.445 135.982C301.492 135.982 290.945 149.654 286.258 155.513L285.086 156.685C276.883 168.013 266.336 177.779 258.133 191.841L242.899 218.404L237.039 226.997C235.476 228.281 229.617 232.188 227.663 232.188C221.804 228.281 222.586 225.825 217.508 234.419L203.055 260.201L201.492 264.107L200.711 265.279L197.977 270.357L196.414 273.872L182.742 296.919L173.758 314.107L170.242 319.185L168.68 321.919L167.117 323.984L163.992 327.779C163.958 327.968 156.476 332.069 155.399 331.797C154.321 331.525 148.835 329.953 147.586 327.779C146.337 325.605 148.281 323.835 149.149 322.7C154.227 316.06 153.445 310.313 153.445 308.359C153.445 306.406 151.492 298.594 151.492 296.641C151.492 294.688 151.102 294.688 151.492 284.922C152.274 273.594 143.289 274.654 144.852 265.279C145.633 259.029 146.414 251.216 143.289 253.56C141.727 253.56 129.617 266.841 124.149 273.482L114.774 285.982L99.5392 305.122L96.0236 308.247L90.5548 313.716L87.4298 315.669C84.6954 319.966 77.2736 323.091 73.3673 329.732L67.1173 340.279L64.7736 344.966L61.6486 349.654L60.4767 350.826L57.7423 355.513L55.3986 358.247L42.1173 375.826L35.0861 383.247C33.7739 384.117 33.1434 384.48 32.3517 384.531C31.5599 384.582 32.3525 374.383 32.3525 374.383L33.1329 370.859L33.9142 369.185C36.6486 363.325 41.3361 357.076 46.0236 350.826C51.1017 343.404 57.3517 329.732 63.6017 320.747L68.6798 316.06L75.3204 308.247C78.0548 306.294 81.9611 301.997 86.2579 296.529L87.8204 295.357L94.8517 286.763C100.711 278.56 116.727 261.372 126.492 251.997L128.055 249.766L130.789 247.31C137.43 241.451 143.68 233.247 148.758 233.247C156.961 233.638 162.43 240.279 167.117 244.966L184.305 261.372C185.867 262.935 187.43 262.154 188.211 260.591C200.32 237.935 210.867 216.841 219.461 216.06H226.492L229.617 213.716C236.258 202.779 244.07 187.935 250.711 178.169C258.524 167.622 283.914 134.81 298.758 121.138C302.274 117.232 305.008 115.781 307.742 115C311.649 115 315.555 116.841 319.07 119.575C333.524 131.685 356.961 157.857 366.336 168.404L372.195 173.091L387.039 181.294L390.556 185.313L392.899 189.107Z";
14
- /** The mark's viewBox, exported so non-SVG consumers can map path space to pixels. */ export const CORBITS_MARK_VIEWBOX = {
13
+ */
14
+ export const CORBITS_MARK_PATH = "M392.899 189.107L397.586 197.031C397.586 197.031 399.539 202.891 399.539 204.844L403.094 222.422C407 222.813 407.39 226.328 409.734 227.109C412.078 228.281 415.203 231.797 416.765 235.313C417.156 236.875 418.718 240.781 420.671 244.688C422.234 247.422 422.625 250.156 424.578 251.719L426.921 254.062C432.39 258.359 432.781 261.484 433.171 272.422C432.781 280.625 434.734 295.078 435.906 301.328C436.296 302.891 436.296 302.891 437.468 303.281C438.25 304.063 437.078 302.891 437.859 303.281C439.031 304.063 443.328 304.844 449.187 307.188C451.921 307.969 454.265 309.141 455.046 313.828C456.609 320.469 464.421 350.938 467.156 369.688L468.328 385.313L447.977 371.026C443.68 353.057 435.867 327.667 433.914 323.76C431.57 321.026 423.758 320.245 419.461 319.463C416.336 319.073 413.992 317.12 412.43 312.042C412.43 308.135 411.649 301.495 410.086 292.51C408.914 285.088 408.914 281.182 408.914 277.276C408.914 272.198 406.57 270.245 400.32 263.995L397.977 259.307C391.336 246.807 390.945 244.854 387.039 244.073C385.376 244.024 384.994 238.473 383.562 235.313C383.562 234.141 384.734 231.016 383.562 225.156L368.288 212.656C361.648 212.266 357.352 225.825 353.445 232.466L348.367 244.966L342.899 261.372L341.727 263.326L340.555 266.06L330.008 281.294L326.102 287.544L324.93 289.107L317.117 299.263L308.524 309.029L291.727 327.779L287.039 334.029L284.305 335.982L270.242 352.779L267.508 355.513L265.555 358.638L264.383 359.81L256.18 368.404L248.367 375.044L246.805 376.607L241.336 380.904C238.602 384.029 231.57 384.531 228.055 384.531C225.71 382.578 216.248 381.938 217.508 379.62L226.883 372.588L228.836 371.026L234.695 364.776L237.039 362.432L242.508 357.354C247.195 352.667 251.102 349.151 253.055 340.948C254.227 336.651 264.383 326.104 268.289 321.807L269.07 321.417L295.242 293.682L315.273 261.372L318.397 253.56C320.35 249.654 320.741 247.086 321.522 244.464C322.013 242.815 326.6 216.563 324.93 212.656C323.26 208.75 332.088 195.551 326.209 189.721C323.866 187.768 320.35 185.815 318.397 183.862C313.507 178.972 300.038 175.659 301.6 169.409L300.711 159.81C303.445 148.482 306.57 135.982 303.445 135.982C301.492 135.982 290.945 149.654 286.258 155.513L285.086 156.685C276.883 168.013 266.336 177.779 258.133 191.841L242.899 218.404L237.039 226.997C235.476 228.281 229.617 232.188 227.663 232.188C221.804 228.281 222.586 225.825 217.508 234.419L203.055 260.201L201.492 264.107L200.711 265.279L197.977 270.357L196.414 273.872L182.742 296.919L173.758 314.107L170.242 319.185L168.68 321.919L167.117 323.984L163.992 327.779C163.958 327.968 156.476 332.069 155.399 331.797C154.321 331.525 148.835 329.953 147.586 327.779C146.337 325.605 148.281 323.835 149.149 322.7C154.227 316.06 153.445 310.313 153.445 308.359C153.445 306.406 151.492 298.594 151.492 296.641C151.492 294.688 151.102 294.688 151.492 284.922C152.274 273.594 143.289 274.654 144.852 265.279C145.633 259.029 146.414 251.216 143.289 253.56C141.727 253.56 129.617 266.841 124.149 273.482L114.774 285.982L99.5392 305.122L96.0236 308.247L90.5548 313.716L87.4298 315.669C84.6954 319.966 77.2736 323.091 73.3673 329.732L67.1173 340.279L64.7736 344.966L61.6486 349.654L60.4767 350.826L57.7423 355.513L55.3986 358.247L42.1173 375.826L35.0861 383.247C33.7739 384.117 33.1434 384.48 32.3517 384.531C31.5599 384.582 32.3525 374.383 32.3525 374.383L33.1329 370.859L33.9142 369.185C36.6486 363.325 41.3361 357.076 46.0236 350.826C51.1017 343.404 57.3517 329.732 63.6017 320.747L68.6798 316.06L75.3204 308.247C78.0548 306.294 81.9611 301.997 86.2579 296.529L87.8204 295.357L94.8517 286.763C100.711 278.56 116.727 261.372 126.492 251.997L128.055 249.766L130.789 247.31C137.43 241.451 143.68 233.247 148.758 233.247C156.961 233.638 162.43 240.279 167.117 244.966L184.305 261.372C185.867 262.935 187.43 262.154 188.211 260.591C200.32 237.935 210.867 216.841 219.461 216.06H226.492L229.617 213.716C236.258 202.779 244.07 187.935 250.711 178.169C258.524 167.622 283.914 134.81 298.758 121.138C302.274 117.232 305.008 115.781 307.742 115C311.649 115 315.555 116.841 319.07 119.575C333.524 131.685 356.961 157.857 366.336 168.404L372.195 173.091L387.039 181.294L390.556 185.313L392.899 189.107Z";
15
+ /** The mark's viewBox, exported so non-SVG consumers can map path space to pixels. */
16
+ export const CORBITS_MARK_VIEWBOX = {
15
17
  x: 32,
16
18
  y: 115,
17
19
  width: 437,
18
- height: 270
20
+ height: 270,
19
21
  };
20
- export function CorbitsMark({ title = "Corbits", decorative = false, className }) {
21
- return /*#__PURE__*/ _jsx("svg", {
22
- viewBox: "32 115 437 270",
23
- fill: "none",
24
- role: decorative ? undefined : "img",
25
- "aria-hidden": decorative ? true : undefined,
26
- "aria-label": decorative ? undefined : title,
27
- className: cn("size-6", className),
28
- children: /*#__PURE__*/ _jsx("path", {
29
- d: CORBITS_MARK_PATH,
30
- fill: "currentColor"
31
- })
32
- });
22
+ export function CorbitsMark({ title = "Corbits", decorative = false, className, }) {
23
+ return (_jsx("svg", { viewBox: "32 115 437 270", fill: "none", role: decorative ? undefined : "img", "aria-hidden": decorative ? true : undefined, "aria-label": decorative ? undefined : title, className: cn("size-6", className), children: _jsx("path", { d: CORBITS_MARK_PATH, fill: "currentColor" }) }));
33
24
  }
@@ -16,7 +16,7 @@
16
16
  * freely and headers are routinely empty or repeated ("", two "Name" columns);
17
17
  * a content key would collide and drop data.
18
18
  */
19
- export declare function CsvTable({ text, caption }: {
19
+ export declare function CsvTable({ text, caption, }: {
20
20
  readonly text: string;
21
21
  readonly caption?: string;
22
22
  }): import("react").JSX.Element;
@@ -1,7 +1,8 @@
1
+ "use client";
1
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
3
  import { useMemo } from "react";
3
4
  import { capCsv, isTabular, parseCsv } from "../lib/csv.js";
4
- import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "./table.js";
5
+ import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "./table.js";
5
6
  /**
6
7
  * CSV text, rendered as a table when that is honest and as raw text when it is
7
8
  * not.
@@ -19,23 +20,16 @@ import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from ".
19
20
  * Columns and rows are keyed by index, never by content. CSV rows duplicate
20
21
  * freely and headers are routinely empty or repeated ("", two "Name" columns);
21
22
  * a content key would collide and drop data.
22
- */ export function CsvTable({ text, caption = "CSV contents" }) {
23
- const parsed = useMemo(()=>parseCsv(text), [
24
- text
25
- ]);
23
+ */
24
+ export function CsvTable({ text, caption = "CSV contents", }) {
25
+ const parsed = useMemo(() => parseCsv(text), [text]);
26
26
  if (parsed === null) {
27
- return /*#__PURE__*/ _jsx("p", {
28
- className: "rounded-md border border-border bg-muted px-4 py-6 text-center text-sm text-muted-foreground",
29
- children: "This file is too large to preview — download it to see the whole thing."
30
- });
27
+ return (_jsx("p", { className: "rounded-md border border-border bg-muted px-4 py-6 text-center text-sm text-muted-foreground", children: "This file is too large to preview \u2014 download it to see the whole thing." }));
31
28
  }
32
29
  if (!isTabular(parsed)) {
33
30
  // Height-capped with its own scroll: a multi-thousand-line file as one
34
31
  // <pre> is the same DOM freeze the size guard exists to prevent.
35
- return /*#__PURE__*/ _jsx("pre", {
36
- className: "max-h-96 overflow-auto rounded-md border border-border bg-muted p-3 font-mono text-xs",
37
- children: text
38
- });
32
+ return (_jsx("pre", { className: "max-h-96 overflow-auto rounded-md border border-border bg-muted p-3 font-mono text-xs", children: text }));
39
33
  }
40
34
  const capped = capCsv(parsed);
41
35
  const notes = [];
@@ -45,41 +39,5 @@ import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from ".
45
39
  if (capped.columnsTruncated) {
46
40
  notes.push(`${capped.headers.length.toLocaleString()} of ${capped.totalColumns.toLocaleString()} columns`);
47
41
  }
48
- return /*#__PURE__*/ _jsxs("div", {
49
- className: "flex flex-col gap-2",
50
- children: [
51
- /*#__PURE__*/ _jsx("div", {
52
- className: "max-h-[32rem] overflow-auto rounded-md border border-border",
53
- children: /*#__PURE__*/ _jsxs(Table, {
54
- "aria-label": caption,
55
- children: [
56
- /*#__PURE__*/ _jsx(TableHeader, {
57
- children: /*#__PURE__*/ _jsx(TableRow, {
58
- children: capped.headers.map((header, index)=>/*#__PURE__*/ _jsx(TableHead, {
59
- scope: "col",
60
- children: header
61
- }, index))
62
- })
63
- }),
64
- /*#__PURE__*/ _jsx(TableBody, {
65
- children: capped.rows.map((row, rowIndex)=>/*#__PURE__*/ _jsx(TableRow, {
66
- children: capped.headers.map((_, cellIndex)=>/*#__PURE__*/ _jsx(TableCell, {
67
- className: "font-mono text-xs",
68
- children: row[cellIndex] ?? ""
69
- }, cellIndex))
70
- }, rowIndex))
71
- })
72
- ]
73
- })
74
- }),
75
- notes.length === 0 ? null : /*#__PURE__*/ _jsxs("p", {
76
- className: "text-xs text-muted-foreground",
77
- children: [
78
- "Showing ",
79
- notes.join(" and "),
80
- " — download for the full file."
81
- ]
82
- })
83
- ]
84
- });
42
+ return (_jsxs("div", { className: "flex flex-col gap-2", children: [_jsx("div", { className: "max-h-[32rem] overflow-auto rounded-md border border-border", children: _jsxs(Table, { "aria-label": caption, children: [_jsx(TableHeader, { children: _jsx(TableRow, { children: capped.headers.map((header, index) => (_jsx(TableHead, { scope: "col", children: header }, index))) }) }), _jsx(TableBody, { children: capped.rows.map((row, rowIndex) => (_jsx(TableRow, { children: capped.headers.map((_, cellIndex) => (_jsx(TableCell, { className: "font-mono text-xs", children: row[cellIndex] ?? "" }, cellIndex))) }, rowIndex))) })] }) }), notes.length === 0 ? null : (_jsxs("p", { className: "text-xs text-muted-foreground", children: ["Showing ", notes.join(" and "), " \u2014 download for the full file."] }))] }));
85
43
  }
@@ -24,7 +24,7 @@ export declare const DialogTrigger: React.ForwardRefExoticComponent<DialogPrimit
24
24
  export declare const DialogClose: React.ForwardRefExoticComponent<DialogPrimitive.DialogCloseProps & React.RefAttributes<HTMLButtonElement>>;
25
25
  export type DialogSide = "center" | "left" | "right";
26
26
  export declare function DialogContent({ className, children, side, ...props }: React.ComponentProps<typeof DialogPrimitive.Content> & {
27
- side?: DialogSide;
27
+ side?: DialogSide | undefined;
28
28
  }): React.JSX.Element;
29
29
  /** `pr-8` keeps the title clear of the close control in the corner. */
30
30
  export declare function DialogHeader({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
package/dist/ui/dialog.js CHANGED
@@ -1,3 +1,4 @@
1
+ "use client";
1
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
3
  import * as DialogPrimitive from "@radix-ui/react-dialog";
3
4
  import { XIcon } from "lucide-react";
@@ -20,86 +21,55 @@ import { cn } from "../lib/utils.js";
20
21
  * inside `DialogBody` rather than growing past the viewport. `left` and
21
22
  * `right` are full-height sheets; they also use `DialogBody` so the header and
22
23
  * footer stay put while the middle scrolls.
23
- */ export const Dialog = DialogPrimitive.Root;
24
+ */
25
+ export const Dialog = DialogPrimitive.Root;
24
26
  export const DialogTrigger = DialogPrimitive.Trigger;
25
27
  export const DialogClose = DialogPrimitive.Close;
26
28
  const SIDE_CLASS = {
27
29
  // Guttered width + capped height so the surface never kisses the viewport
28
30
  // edge or spills past ~one form-screen of content. Overflow is clipped here;
29
31
  // scroll lives on DialogBody.
30
- center: "top-1/2 left-1/2 w-[min(calc(100vw-2rem),32rem)] max-h-[min(90dvh,42rem)] " + "overflow-hidden -translate-x-1/2 -translate-y-1/2 rounded-lg border " + "max-sm:w-[min(calc(100vw-1.25rem),32rem)] max-sm:max-h-[min(92dvh,42rem)] " + "data-[state=open]:animate-[corbits-dialog-in_150ms_ease-out] data-[state=closed]:animate-[corbits-dialog-out_120ms_ease-in]",
31
- right: "inset-y-0 right-0 w-full max-w-lg border-l " + "data-[state=open]:animate-[corbits-drawer-in-right_200ms_ease-out] data-[state=closed]:animate-[corbits-drawer-out-right_160ms_ease-in]",
32
- left: "inset-y-0 left-0 w-full max-w-lg border-r " + "data-[state=open]:animate-[corbits-drawer-in-left_200ms_ease-out] data-[state=closed]:animate-[corbits-drawer-out-left_160ms_ease-in]"
32
+ center: "top-1/2 left-1/2 w-[min(calc(100vw-2rem),32rem)] max-h-[min(90dvh,42rem)] " +
33
+ "overflow-hidden -translate-x-1/2 -translate-y-1/2 rounded-lg border " +
34
+ "max-sm:w-[min(calc(100vw-1.25rem),32rem)] max-sm:max-h-[min(92dvh,42rem)] " +
35
+ "data-[state=open]:animate-[corbits-dialog-in_150ms_ease-out] data-[state=closed]:animate-[corbits-dialog-out_120ms_ease-in]",
36
+ right: "inset-y-0 right-0 w-full max-w-lg border-l " +
37
+ "data-[state=open]:animate-[corbits-drawer-in-right_200ms_ease-out] data-[state=closed]:animate-[corbits-drawer-out-right_160ms_ease-in]",
38
+ left: "inset-y-0 left-0 w-full max-w-lg border-r " +
39
+ "data-[state=open]:animate-[corbits-drawer-in-left_200ms_ease-out] data-[state=closed]:animate-[corbits-drawer-out-left_160ms_ease-in]",
33
40
  };
34
41
  export function DialogContent({ className, children, side = "center", ...props }) {
35
- return /*#__PURE__*/ _jsxs(DialogPrimitive.Portal, {
36
- children: [
37
- /*#__PURE__*/ _jsx(DialogPrimitive.Overlay, {
38
- className: "fixed inset-0 z-50 bg-black/50 backdrop-blur-[2px] data-[state=open]:animate-[corbits-fade-in_150ms_ease-out] data-[state=closed]:animate-[corbits-fade-out_120ms_ease-in]"
39
- }),
40
- /*#__PURE__*/ _jsxs(DialogPrimitive.Content, {
41
- "data-slot": "dialog-content",
42
- "data-side": side,
43
- className: cn("fixed z-50 flex flex-col gap-4 border-border bg-popover p-6 text-popover-foreground shadow-lg", // Keyframes are installed into your globals.css by this registry item.
44
- SIDE_CLASS[side], className),
45
- ...props,
46
- children: [
47
- children,
48
- /*#__PURE__*/ _jsx(DialogPrimitive.Close, {
49
- "aria-label": "Close",
50
- className: cn("absolute top-[0.85rem] right-[0.85rem] inline-flex size-[1.8rem] items-center justify-center", "rounded-[0.45rem] p-0 text-muted-foreground transition-colors", "hover:bg-foreground/5 hover:text-foreground", // Soft primary-tint focus instead of the theme outline — the close
42
+ return (_jsxs(DialogPrimitive.Portal, { children: [_jsx(DialogPrimitive.Overlay, { className: "fixed inset-0 z-50 bg-black/50 backdrop-blur-[2px] data-[state=open]:animate-[corbits-fade-in_150ms_ease-out] data-[state=closed]:animate-[corbits-fade-out_120ms_ease-in]" }), _jsxs(DialogPrimitive.Content, { "data-slot": "dialog-content", "data-side": side, className: cn("fixed z-50 flex flex-col gap-4 border-border bg-popover p-6 text-popover-foreground shadow-lg",
43
+ // Keyframes are installed into your globals.css by this registry item.
44
+ SIDE_CLASS[side], className), ...props, children: [children, _jsx(DialogPrimitive.Close, { "aria-label": "Close", className: cn("absolute top-[0.85rem] right-[0.85rem] inline-flex size-[1.8rem] items-center justify-center", "rounded-[0.45rem] p-0 text-muted-foreground transition-colors", "hover:bg-foreground/5 hover:text-foreground",
45
+ // Soft primary-tint focus instead of the theme outline — the close
51
46
  // control sits on the popover surface and a hard ring reads heavy.
52
- "focus-visible:text-foreground focus-visible:outline-none", "focus-visible:shadow-[0_0_0_3px_color-mix(in_srgb,var(--primary)_22%,transparent)]"),
53
- children: /*#__PURE__*/ _jsx(XIcon, {
54
- className: "size-4"
55
- })
56
- })
57
- ]
58
- })
59
- ]
60
- });
47
+ "focus-visible:text-foreground focus-visible:outline-none", "focus-visible:shadow-[0_0_0_3px_color-mix(in_srgb,var(--primary)_22%,transparent)]"), children: _jsx(XIcon, { className: "size-4" }) })] })] }));
61
48
  }
62
- /** `pr-8` keeps the title clear of the close control in the corner. */ export function DialogHeader({ className, ...props }) {
63
- return /*#__PURE__*/ _jsx("div", {
64
- "data-slot": "dialog-header",
65
- className: cn("flex shrink-0 flex-col gap-1 pr-8", className),
66
- ...props
67
- });
49
+ /** `pr-8` keeps the title clear of the close control in the corner. */
50
+ export function DialogHeader({ className, ...props }) {
51
+ return (_jsx("div", { "data-slot": "dialog-header", className: cn("flex shrink-0 flex-col gap-1 pr-8", className), ...props }));
68
52
  }
69
- /** Scrolls; the header and footer stay put. Needed by tall centre dialogs and side sheets. */ export function DialogBody({ className, ...props }) {
70
- return /*#__PURE__*/ _jsx("div", {
71
- "data-slot": "dialog-body",
72
- className: cn("min-h-0 flex-auto overflow-y-auto overscroll-contain [scrollbar-width:thin]", className),
73
- ...props
74
- });
53
+ /** Scrolls; the header and footer stay put. Needed by tall centre dialogs and side sheets. */
54
+ export function DialogBody({ className, ...props }) {
55
+ return (_jsx("div", { "data-slot": "dialog-body", className: cn("min-h-0 flex-auto overflow-y-auto overscroll-contain [scrollbar-width:thin]", className), ...props }));
75
56
  }
76
57
  export function DialogFooter({ className, ...props }) {
77
- return /*#__PURE__*/ _jsx("div", {
78
- "data-slot": "dialog-footer",
79
- className: cn(// Stable bar: pinned to the bottom of the flex column, subtle top rule
58
+ return (_jsx("div", { "data-slot": "dialog-footer", className: cn(
59
+ // Stable bar: pinned to the bottom of the flex column, subtle top rule
80
60
  // and wash so actions read as chrome rather than more body content.
81
- "mt-auto flex shrink-0 flex-wrap items-center justify-end gap-2", "border-t border-foreground/10 bg-foreground/[0.025] pt-[0.85rem]", // Narrow viewports: stack full-width so primary/secondary hit areas
61
+ "mt-auto flex shrink-0 flex-wrap items-center justify-end gap-2", "border-t border-foreground/10 bg-foreground/[0.025] pt-[0.85rem]",
62
+ // Narrow viewports: stack full-width so primary/secondary hit areas
82
63
  // don't compete for a single row of thumb space.
83
- "max-sm:flex-col max-sm:flex-nowrap max-sm:items-stretch max-sm:[&>*]:w-full", className),
84
- ...props
85
- });
64
+ "max-sm:flex-col max-sm:flex-nowrap max-sm:items-stretch max-sm:[&>*]:w-full", className), ...props }));
86
65
  }
87
66
  export function DialogTitle({ className, ...props }) {
88
- return /*#__PURE__*/ _jsx(DialogPrimitive.Title, {
89
- className: cn("m-0 text-[0.95rem] font-[650] leading-[1.3] tracking-[-0.01em] text-foreground", className),
90
- ...props
91
- });
67
+ return (_jsx(DialogPrimitive.Title, { className: cn("m-0 text-[0.95rem] font-[650] leading-[1.3] tracking-[-0.01em] text-foreground", className), ...props }));
92
68
  }
93
69
  export function DialogDescription({ className, ...props }) {
94
- return /*#__PURE__*/ _jsx(DialogPrimitive.Description, {
95
- className: cn("m-0 text-[0.8125rem] leading-[1.4] text-muted-foreground", className),
96
- ...props
97
- });
70
+ return (_jsx(DialogPrimitive.Description, { className: cn("m-0 text-[0.8125rem] leading-[1.4] text-muted-foreground", className), ...props }));
98
71
  }
99
- /** Uppercase field label used inside dialog forms. */ export function DialogFieldLabel({ className, ...props }) {
100
- return /*#__PURE__*/ _jsx("label", {
101
- "data-slot": "dialog-field-label",
102
- className: cn("text-[10.5px] font-bold uppercase tracking-[0.06em] text-muted-foreground", className),
103
- ...props
104
- });
72
+ /** Uppercase field label used inside dialog forms. */
73
+ export function DialogFieldLabel({ className, ...props }) {
74
+ return (_jsx("label", { "data-slot": "dialog-field-label", className: cn("text-[10.5px] font-bold uppercase tracking-[0.06em] text-muted-foreground", className), ...props }));
105
75
  }
@@ -6,33 +6,15 @@ import { cn } from "../lib/utils.js";
6
6
  * with a waveform, a starting message, or a refusal — never more than one of
7
7
  * these, and absent entirely once `state` is `"idle"` or `"unsupported"`, so
8
8
  * the row does not otherwise change the composer's shape.
9
- */ export function DictationStatusLine({ state, levels = [], startingLabel = "Starting microphone…", listeningLabel = "Listening:", errorMessage, className }) {
10
- if (state === "idle" || state === "unsupported") return null;
9
+ */
10
+ export function DictationStatusLine({ state, levels = [], startingLabel = "Starting microphone…", listeningLabel = "Listening:", errorMessage, className, }) {
11
+ if (state === "idle" || state === "unsupported")
12
+ return null;
11
13
  if (state === "denied") {
12
- return /*#__PURE__*/ _jsx("p", {
13
- role: "alert",
14
- className: cn("text-xs text-destructive", className),
15
- children: errorMessage ?? "Microphone access was blocked."
16
- });
14
+ return (_jsx("p", { role: "alert", className: cn("text-xs text-destructive", className), children: errorMessage ?? "Microphone access was blocked." }));
17
15
  }
18
16
  if (state === "starting") {
19
- return /*#__PURE__*/ _jsx("p", {
20
- "aria-live": "polite",
21
- className: cn("text-xs text-muted-foreground", className),
22
- children: startingLabel
23
- });
17
+ return (_jsx("p", { "aria-live": "polite", className: cn("text-xs text-muted-foreground", className), children: startingLabel }));
24
18
  }
25
- return /*#__PURE__*/ _jsxs("p", {
26
- "aria-live": "polite",
27
- className: cn("flex items-center gap-2 text-xs text-muted-foreground", className),
28
- children: [
29
- /*#__PURE__*/ _jsx("span", {
30
- children: listeningLabel
31
- }),
32
- /*#__PURE__*/ _jsx(VoiceWaveform, {
33
- levels: levels,
34
- className: "text-ok"
35
- })
36
- ]
37
- });
19
+ return (_jsxs("p", { "aria-live": "polite", className: cn("flex items-center gap-2 text-xs text-muted-foreground", className), children: [_jsx("span", { children: listeningLabel }), _jsx(VoiceWaveform, { levels: levels, className: "text-ok" })] }));
38
20
  }
@@ -28,4 +28,4 @@ export type DitherCanvasProps = {
28
28
  * that the grid is resampled by the compositor on a retina display and the
29
29
  * crisp dot pattern — the entire effect — turns to mush.
30
30
  */
31
- export declare function DitherCanvas({ cell, color, warpRadius, className }: DitherCanvasProps): import("react").JSX.Element;
31
+ export declare function DitherCanvas({ cell, color, warpRadius, className, }: DitherCanvasProps): import("react").JSX.Element;
@@ -1,3 +1,4 @@
1
+ "use client";
1
2
  import { jsx as _jsx } from "react/jsx-runtime";
2
3
  import { useEffect, useRef } from "react";
3
4
  import { usePrefersReducedMotion } from "../hooks/use-prefers-reduced-motion.js";
@@ -10,32 +11,13 @@ import { cn } from "../lib/utils.js";
10
11
  * recomputed cheaply every frame, and the pattern crawls when anything moves.
11
12
  * An ordered matrix is a pure function of position, so a frame costs one pass
12
13
  * and the texture stays locked to the surface instead of swimming.
13
- */ const BAYER = [
14
- [
15
- 0,
16
- 8,
17
- 2,
18
- 10
19
- ],
20
- [
21
- 12,
22
- 4,
23
- 14,
24
- 6
25
- ],
26
- [
27
- 3,
28
- 11,
29
- 1,
30
- 9
31
- ],
32
- [
33
- 15,
34
- 7,
35
- 13,
36
- 5
37
- ]
38
- ].map((row)=>row.map((value)=>(value + 0.5) / 16));
14
+ */
15
+ const BAYER = [
16
+ [0, 8, 2, 10],
17
+ [12, 4, 14, 6],
18
+ [3, 11, 1, 9],
19
+ [15, 7, 13, 5],
20
+ ].map((row) => row.map((value) => (value + 0.5) / 16));
39
21
  /**
40
22
  * A dithered field that reacts to the pointer — decoration for a full-bleed
41
23
  * panel, and nothing else.
@@ -56,14 +38,17 @@ import { cn } from "../lib/utils.js";
56
38
  * The canvas is sized in device pixels and scaled by `devicePixelRatio`. Without
57
39
  * that the grid is resampled by the compositor on a retina display and the
58
40
  * crisp dot pattern — the entire effect — turns to mush.
59
- */ export function DitherCanvas({ cell = 4, color, warpRadius = 160, className }) {
41
+ */
42
+ export function DitherCanvas({ cell = 4, color, warpRadius = 160, className, }) {
60
43
  const ref = useRef(null);
61
44
  const reduce = usePrefersReducedMotion();
62
- useEffect(()=>{
45
+ useEffect(() => {
63
46
  const canvas = ref.current;
64
- if (canvas === null) return;
47
+ if (canvas === null)
48
+ return;
65
49
  const context = canvas.getContext("2d");
66
- if (context === null) return;
50
+ if (context === null)
51
+ return;
67
52
  // Resolved once per mount: reading a custom property costs a style
68
53
  // recalculation, which is not something to do sixty times a second. The
69
54
  // fallback reads the canvas's own computed `color` rather than a literal
@@ -73,14 +58,11 @@ import { cn } from "../lib/utils.js";
73
58
  const computed = getComputedStyle(canvas);
74
59
  const themeInk = computed.getPropertyValue("--primary").trim();
75
60
  const ink = color ?? (themeInk === "" ? computed.color : themeInk);
76
- const pointer = {
77
- x: -1e6,
78
- y: -1e6
79
- };
61
+ const pointer = { x: -1e6, y: -1e6 };
80
62
  let frame = 0;
81
63
  let width = 0;
82
64
  let height = 0;
83
- const resize = ()=>{
65
+ const resize = () => {
84
66
  const ratio = window.devicePixelRatio || 1;
85
67
  const box = canvas.getBoundingClientRect();
86
68
  width = box.width;
@@ -89,14 +71,14 @@ import { cn } from "../lib/utils.js";
89
71
  canvas.height = Math.max(1, Math.round(height * ratio));
90
72
  context.setTransform(ratio, 0, 0, ratio, 0, 0);
91
73
  };
92
- const draw = (time)=>{
74
+ const draw = (time) => {
93
75
  context.clearRect(0, 0, width, height);
94
76
  context.fillStyle = ink;
95
77
  const drift = reduce ? 0 : time / 3000;
96
78
  const columns = Math.ceil(width / cell);
97
79
  const rows = Math.ceil(height / cell);
98
- for(let row = 0; row < rows; row += 1){
99
- for(let column = 0; column < columns; column += 1){
80
+ for (let row = 0; row < rows; row += 1) {
81
+ for (let column = 0; column < columns; column += 1) {
100
82
  const x = column * cell;
101
83
  const y = row * cell;
102
84
  // Base field: a soft diagonal gradient with a slow sine drift, so the
@@ -123,47 +105,40 @@ import { cn } from "../lib/utils.js";
123
105
  }
124
106
  }
125
107
  };
126
- const loop = (time)=>{
108
+ const loop = (time) => {
127
109
  draw(time);
128
110
  frame = requestAnimationFrame(loop);
129
111
  };
130
- const onPointerMove = (event)=>{
112
+ const onPointerMove = (event) => {
131
113
  const box = canvas.getBoundingClientRect();
132
114
  pointer.x = event.clientX - box.left;
133
115
  pointer.y = event.clientY - box.top;
134
116
  };
135
- const onPointerLeave = ()=>{
117
+ const onPointerLeave = () => {
136
118
  pointer.x = -1e6;
137
119
  pointer.y = -1e6;
138
120
  };
139
121
  resize();
140
- const observer = new ResizeObserver(()=>{
122
+ const observer = new ResizeObserver(() => {
141
123
  resize();
142
- if (reduce) draw(0);
124
+ if (reduce)
125
+ draw(0);
143
126
  });
144
127
  observer.observe(canvas);
145
128
  if (reduce) {
146
129
  draw(0);
147
- } else {
130
+ }
131
+ else {
148
132
  frame = requestAnimationFrame(loop);
149
133
  canvas.addEventListener("pointermove", onPointerMove);
150
134
  canvas.addEventListener("pointerleave", onPointerLeave);
151
135
  }
152
- return ()=>{
136
+ return () => {
153
137
  cancelAnimationFrame(frame);
154
138
  observer.disconnect();
155
139
  canvas.removeEventListener("pointermove", onPointerMove);
156
140
  canvas.removeEventListener("pointerleave", onPointerLeave);
157
141
  };
158
- }, [
159
- cell,
160
- color,
161
- warpRadius,
162
- reduce
163
- ]);
164
- return /*#__PURE__*/ _jsx("canvas", {
165
- ref: ref,
166
- "aria-hidden": true,
167
- className: cn("block size-full", className)
168
- });
142
+ }, [cell, color, warpRadius, reduce]);
143
+ return (_jsx("canvas", { ref: ref, "aria-hidden": true, className: cn("block size-full", className) }));
169
144
  }
@@ -27,4 +27,4 @@ export type EmbedBodyProps = {
27
27
  * the direct link is always present rather than being a fallback we would have
28
28
  * to detect our way into.
29
29
  */
30
- export declare function EmbedBody({ url, title, description, downloadUrl, aspect, className }: EmbedBodyProps): import("react").JSX.Element;
30
+ export declare function EmbedBody({ url, title, description, downloadUrl, aspect, className, }: EmbedBodyProps): import("react").JSX.Element;
@@ -17,10 +17,9 @@ import { buttonVariants } from "./button.js";
17
17
  * `allow-top-navigation` (redirect the tab out from under them),
18
18
  * `allow-popups` (open a tab that outlives the frame), and `allow-forms` (POST
19
19
  * credentials somewhere). A viewer needs none of the three.
20
- */ const EMBED_SANDBOX = "allow-scripts allow-same-origin allow-presentation";
21
- const EMBED_ALLOWED_PROTOCOLS = [
22
- "https:"
23
- ];
20
+ */
21
+ const EMBED_SANDBOX = "allow-scripts allow-same-origin allow-presentation";
22
+ const EMBED_ALLOWED_PROTOCOLS = ["https:"];
24
23
  /**
25
24
  * A third-party URL, framed.
26
25
  *
@@ -34,59 +33,11 @@ const EMBED_ALLOWED_PROTOCOLS = [
34
33
  * login wall, and an iframe that renders blank fires no error we can catch — so
35
34
  * the direct link is always present rather than being a fallback we would have
36
35
  * to detect our way into.
37
- */ export function EmbedBody({ url, title, description, downloadUrl, aspect = "wide", className }) {
36
+ */
37
+ export function EmbedBody({ url, title, description, downloadUrl, aspect = "wide", className, }) {
38
38
  if (!isSafeUrl(url, EMBED_ALLOWED_PROTOCOLS)) {
39
- return /*#__PURE__*/ _jsx(ArtifactNotice, {
40
- message: "This link is missing or is not a secure (https) address, so it cannot be shown."
41
- });
39
+ return (_jsx(ArtifactNotice, { message: "This link is missing or is not a secure (https) address, so it cannot be shown." }));
42
40
  }
43
41
  const safeDownloadUrl = toSafeHref(downloadUrl);
44
- return /*#__PURE__*/ _jsxs("div", {
45
- className: cn("flex w-full flex-col gap-3", className),
46
- children: [
47
- description === undefined ? null : /*#__PURE__*/ _jsx("p", {
48
- className: "max-w-prose text-sm text-muted-foreground",
49
- children: description
50
- }),
51
- /*#__PURE__*/ _jsx("div", {
52
- className: cn("w-full overflow-hidden rounded-lg border border-border bg-card", aspect === "wide" ? "aspect-video" : "aspect-[3/4] max-h-[75vh]"),
53
- children: /*#__PURE__*/ _jsx("iframe", {
54
- src: url,
55
- title: title,
56
- sandbox: EMBED_SANDBOX,
57
- allow: "fullscreen",
58
- className: "size-full border-0"
59
- })
60
- }),
61
- /*#__PURE__*/ _jsxs("div", {
62
- className: "flex items-center gap-2",
63
- children: [
64
- /*#__PURE__*/ _jsxs("a", {
65
- href: url,
66
- target: "_blank",
67
- rel: "noopener noreferrer",
68
- className: buttonVariants({
69
- variant: "outline",
70
- size: "sm"
71
- }),
72
- children: [
73
- /*#__PURE__*/ _jsx(ExternalLink, {
74
- "aria-hidden": true
75
- }),
76
- "Open in a new tab"
77
- ]
78
- }),
79
- safeDownloadUrl === undefined ? null : /*#__PURE__*/ _jsx("a", {
80
- href: safeDownloadUrl,
81
- download: true,
82
- className: buttonVariants({
83
- variant: "ghost",
84
- size: "sm"
85
- }),
86
- children: "Download"
87
- })
88
- ]
89
- })
90
- ]
91
- });
42
+ return (_jsxs("div", { className: cn("flex w-full flex-col gap-3", className), children: [description === undefined ? null : (_jsx("p", { className: "max-w-prose text-sm text-muted-foreground", children: description })), _jsx("div", { className: cn("w-full overflow-hidden rounded-lg border border-border bg-card", aspect === "wide" ? "aspect-video" : "aspect-[3/4] max-h-[75vh]"), children: _jsx("iframe", { src: url, title: title, sandbox: EMBED_SANDBOX, allow: "fullscreen", className: "size-full border-0" }) }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsxs("a", { href: url, target: "_blank", rel: "noopener noreferrer", className: buttonVariants({ variant: "outline", size: "sm" }), children: [_jsx(ExternalLink, { "aria-hidden": true }), "Open in a new tab"] }), safeDownloadUrl === undefined ? null : (_jsx("a", { href: safeDownloadUrl, download: true, className: buttonVariants({ variant: "ghost", size: "sm" }), children: "Download" }))] })] }));
92
43
  }
@@ -23,4 +23,4 @@ export type EmptyStateProps = {
23
23
  * Not a `role="status"`. An empty state is the rendered result of a finished
24
24
  * load, not an announcement — the surface that was loading owns that.
25
25
  */
26
- export declare function EmptyState({ title, description, icon, action, className }: EmptyStateProps): import("react").JSX.Element;
26
+ export declare function EmptyState({ title, description, icon, action, className, }: EmptyStateProps): import("react").JSX.Element;
@@ -13,30 +13,7 @@ import { cn } from "../lib/utils.js";
13
13
  *
14
14
  * Not a `role="status"`. An empty state is the rendered result of a finished
15
15
  * load, not an announcement — the surface that was loading owns that.
16
- */ export function EmptyState({ title, description, icon, action, className }) {
17
- return /*#__PURE__*/ _jsxs("div", {
18
- "data-slot": "empty-state",
19
- className: cn("flex flex-col items-center gap-3 px-6 py-12 text-center", className),
20
- children: [
21
- icon === undefined ? null : /*#__PURE__*/ _jsx("span", {
22
- "aria-hidden": true,
23
- className: "grid size-11 place-items-center rounded-full bg-muted text-muted-foreground [&_svg]:size-5",
24
- children: icon
25
- }),
26
- /*#__PURE__*/ _jsxs("div", {
27
- className: "flex flex-col gap-1",
28
- children: [
29
- /*#__PURE__*/ _jsx("p", {
30
- className: "text-sm font-medium",
31
- children: title
32
- }),
33
- description === undefined ? null : /*#__PURE__*/ _jsx("p", {
34
- className: "max-w-prose text-xs leading-relaxed text-muted-foreground",
35
- children: description
36
- })
37
- ]
38
- }),
39
- action
40
- ]
41
- });
16
+ */
17
+ export function EmptyState({ title, description, icon, action, className, }) {
18
+ return (_jsxs("div", { "data-slot": "empty-state", className: cn("flex flex-col items-center gap-3 px-6 py-12 text-center", className), children: [icon === undefined ? null : (_jsx("span", { "aria-hidden": true, className: "grid size-11 place-items-center rounded-full bg-muted text-muted-foreground [&_svg]:size-5", children: icon })), _jsxs("div", { className: "flex flex-col gap-1", children: [_jsx("p", { className: "text-sm font-medium", children: title }), description === undefined ? null : (_jsx("p", { className: "max-w-prose text-xs leading-relaxed text-muted-foreground", children: description }))] }), action] }));
42
19
  }