@alexgorbatchev/shadcn 0.0.22 → 0.0.24

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 (272) hide show
  1. package/dist/{chunk-x1z72h7w.js → chunk-0eqk27kc.js} +1 -1
  2. package/dist/{chunk-ryvvtyjq.js → chunk-0p3jnj86.js} +1 -1
  3. package/dist/{chunk-seeed8a2.js → chunk-0v2xjev7.js} +1 -1
  4. package/dist/{chunk-zbm0xcq3.js → chunk-12cghfb8.js} +1 -1
  5. package/dist/{chunk-2tmvz090.js → chunk-1akzryj1.js} +1 -1
  6. package/dist/{chunk-e0gcczqk.js → chunk-1ask024n.js} +1 -1
  7. package/dist/{chunk-ge705y2w.js → chunk-1j834gzz.js} +1 -1
  8. package/dist/{chunk-5r99spxq.js → chunk-1te71te7.js} +1 -1
  9. package/dist/{chunk-m2ct74my.js → chunk-1yzgj2f3.js} +1 -1
  10. package/dist/{chunk-f307aaa6.js → chunk-2j8qna99.js} +2 -2
  11. package/dist/{chunk-s83v0taa.js → chunk-2jgpjz76.js} +1 -1
  12. package/dist/{chunk-tetvt0c3.js → chunk-2kekr0w0.js} +2 -2
  13. package/dist/{chunk-e59sfvpe.js → chunk-2rexmqbv.js} +1 -1
  14. package/dist/{chunk-w1w71edg.js → chunk-2z603ebe.js} +1 -1
  15. package/dist/{chunk-m0e0an33.js → chunk-34y9y8gj.js} +1 -1
  16. package/dist/{chunk-7ppfbxdh.js → chunk-3ct523v1.js} +1 -1
  17. package/dist/{chunk-nkw2vsf3.js → chunk-4k6mrxg7.js} +1 -1
  18. package/dist/{chunk-41wmtqkq.js → chunk-4wzr5pcs.js} +1 -1
  19. package/dist/{chunk-0vgs0ebx.js → chunk-50en3zdr.js} +1 -1
  20. package/dist/{chunk-a6kyjjfk.js → chunk-553hk2j3.js} +2 -2
  21. package/dist/{chunk-02qymemz.js → chunk-5gzdqj2y.js} +1 -1
  22. package/dist/{chunk-vq8nc5xa.js → chunk-5jcy5td1.js} +2 -2
  23. package/dist/{chunk-vxera95d.js → chunk-5mwbjeg6.js} +1 -1
  24. package/dist/{chunk-vs1n47pw.js → chunk-5xhpp4er.js} +1 -1
  25. package/dist/{chunk-qgjjcmpa.js → chunk-5yagsnc8.js} +1 -1
  26. package/dist/{chunk-g03nphs1.js → chunk-61ngfnp5.js} +2 -2
  27. package/dist/{chunk-3qqdfft7.js → chunk-69wkq8ez.js} +1 -1
  28. package/dist/{chunk-1c5jjkhw.js → chunk-6chyagqx.js} +1 -1
  29. package/dist/{chunk-jba22682.js → chunk-6hhsm369.js} +3 -3
  30. package/dist/{chunk-24pefkd5.js → chunk-6jwvd1q3.js} +2 -2
  31. package/dist/{chunk-qcsxnn16.js → chunk-6njgm8rp.js} +1 -1
  32. package/dist/{chunk-1p7pend8.js → chunk-6zvcgbw0.js} +3 -3
  33. package/dist/{chunk-y4gbweym.js → chunk-70mtpeme.js} +1 -1
  34. package/dist/{chunk-f4c0tg2x.js → chunk-7mhje7ps.js} +1 -1
  35. package/dist/{chunk-8a15x4a8.js → chunk-7n3fv64d.js} +1 -1
  36. package/dist/{chunk-dq7kr5y0.js → chunk-82wxsc8p.js} +7 -3
  37. package/dist/{chunk-dgkj6442.js → chunk-87f2y2t4.js} +1 -1
  38. package/dist/{chunk-ef04mmf4.js → chunk-8vnnqhxa.js} +2 -2
  39. package/dist/{chunk-dnvb9r71.js → chunk-8xsqfwxr.js} +1 -1
  40. package/dist/{chunk-1jeg5z55.js → chunk-8zhqkj8r.js} +1 -1
  41. package/dist/{chunk-bcpy6gpz.js → chunk-9s9sqz92.js} +1 -1
  42. package/dist/{chunk-3d9v39ga.js → chunk-9wawqspa.js} +2 -2
  43. package/dist/{chunk-72qr0gqe.js → chunk-9y9py6dq.js} +1 -1
  44. package/dist/{chunk-tynbgc30.js → chunk-a49zznxv.js} +2 -2
  45. package/dist/{chunk-tx19w12r.js → chunk-a4y5e1cm.js} +1 -1
  46. package/dist/{chunk-548kkcx4.js → chunk-ach9vxze.js} +1 -1
  47. package/dist/{chunk-ep057ccn.js → chunk-apv9pgkz.js} +1 -1
  48. package/dist/{chunk-j9d304dz.js → chunk-aw4w72j3.js} +1 -1
  49. package/dist/{chunk-2tn2pg48.js → chunk-b2g9ddvx.js} +1 -1
  50. package/dist/{chunk-nkx7ncf1.js → chunk-b74w8860.js} +1 -1
  51. package/dist/{chunk-yp12vs0s.js → chunk-bcw9x5wy.js} +1 -1
  52. package/dist/{chunk-gkkbg7rq.js → chunk-bk0ar3x2.js} +1 -1
  53. package/dist/{chunk-73rkr9ct.js → chunk-btz12z1j.js} +1 -0
  54. package/dist/{chunk-rc9kpszb.js → chunk-bv2w14vr.js} +1 -1
  55. package/dist/{chunk-aehkndxh.js → chunk-c2kt288z.js} +1 -1
  56. package/dist/{chunk-ynh7v8n7.js → chunk-dvk7mx0q.js} +1 -1
  57. package/dist/{chunk-djm7qq62.js → chunk-e1qbnvm0.js} +2 -2
  58. package/dist/{chunk-xkvyk2qf.js → chunk-e86g3dpe.js} +1 -1
  59. package/dist/{chunk-5ayp2vkw.js → chunk-f3kqqnr1.js} +1 -1
  60. package/dist/{chunk-1tgrhacr.js → chunk-fb0jkkvq.js} +1 -1
  61. package/dist/{chunk-3t4dphfj.js → chunk-fkcw3t7k.js} +1 -1
  62. package/dist/{chunk-smdxxnb8.js → chunk-g3eshdaf.js} +1 -1
  63. package/dist/{chunk-e6tx49rb.js → chunk-gkhv7nze.js} +1 -1
  64. package/dist/{chunk-ff8bpz3p.js → chunk-gxfdfxet.js} +1 -1
  65. package/dist/{chunk-zp1emfpq.js → chunk-h3ezg4sw.js} +1 -1
  66. package/dist/{chunk-ttyqqw3y.js → chunk-h6660c6j.js} +1 -1
  67. package/dist/{chunk-b2jkgq4n.js → chunk-h8fz1tbr.js} +1 -1
  68. package/dist/{chunk-zj06vvcz.js → chunk-hanf12ka.js} +1 -1
  69. package/dist/{chunk-vjtbpkht.js → chunk-hcgfqetz.js} +3 -3
  70. package/dist/{chunk-pkegpb49.js → chunk-hcwwnj9p.js} +1 -1
  71. package/dist/{chunk-f25bby84.js → chunk-hm1mmdqa.js} +1 -1
  72. package/dist/{chunk-gg39sggp.js → chunk-hyq4nwg2.js} +1 -1
  73. package/dist/{chunk-493ghkkr.js → chunk-j3ncv76v.js} +1 -1
  74. package/dist/{chunk-d3ad53et.js → chunk-j777f8b2.js} +8 -8
  75. package/dist/{chunk-mznfmtt8.js → chunk-jcmbn82d.js} +1 -1
  76. package/dist/{chunk-wbj4frbk.js → chunk-jfc7fwn1.js} +1 -1
  77. package/dist/{chunk-jpamrhdk.js → chunk-jmr8c2ek.js} +1 -1
  78. package/dist/{chunk-bt5ksk3z.js → chunk-jq22e0sq.js} +1 -1
  79. package/dist/{chunk-9dqspkha.js → chunk-jzy3z4mb.js} +2 -2
  80. package/dist/{chunk-8g1npthk.js → chunk-kmx0nmsj.js} +1 -1
  81. package/dist/{chunk-q4264v6h.js → chunk-kx617qt6.js} +2 -2
  82. package/dist/{chunk-k8v9y2dw.js → chunk-m1f0s5j7.js} +1 -1
  83. package/dist/{chunk-wwyzwptb.js → chunk-mjfdfmg7.js} +3 -3
  84. package/dist/{chunk-6krk6rjd.js → chunk-n8r5dkve.js} +1 -1
  85. package/dist/{chunk-djrb64cg.js → chunk-nb6aye6j.js} +1 -1
  86. package/dist/{chunk-kbg2e95b.js → chunk-nx21zbg9.js} +1 -1
  87. package/dist/{chunk-zve48bc0.js → chunk-nx51fh7f.js} +1 -1
  88. package/dist/{chunk-xjxhnvcc.js → chunk-nxerwfyv.js} +1 -1
  89. package/dist/{chunk-nz2e73h2.js → chunk-p3byyeva.js} +1 -1
  90. package/dist/{chunk-m1hr3w94.js → chunk-p8z3ekmf.js} +1 -1
  91. package/dist/{chunk-ve9gpkxd.js → chunk-pch7thbg.js} +1 -1
  92. package/dist/{chunk-ds65prb9.js → chunk-qadvww75.js} +1 -1
  93. package/dist/{chunk-a3r74mbf.js → chunk-qbm35ft9.js} +1 -1
  94. package/dist/{chunk-74aknkhq.js → chunk-qcvhjbrj.js} +1 -1
  95. package/dist/{chunk-83cckb23.js → chunk-qvp46ymf.js} +1 -1
  96. package/dist/{chunk-ghmkxqn5.js → chunk-r0097h0v.js} +2 -2
  97. package/dist/{chunk-gc0s6z4e.js → chunk-r1qydj1b.js} +1 -1
  98. package/dist/{chunk-70vndezn.js → chunk-rg7c7wxt.js} +1 -1
  99. package/dist/{chunk-gdtrt9dz.js → chunk-rzh23c9y.js} +1 -1
  100. package/dist/{chunk-67dkgsm3.js → chunk-tfqpraqf.js} +1 -1
  101. package/dist/{chunk-0nmj2qb8.js → chunk-tpa8ffve.js} +1 -1
  102. package/dist/{chunk-wkpf4bv7.js → chunk-tpk1251s.js} +1 -1
  103. package/dist/{chunk-23ey5ek0.js → chunk-v354xm3e.js} +1 -1
  104. package/dist/{chunk-5wemmqv5.js → chunk-vt6qq24c.js} +1 -1
  105. package/dist/{chunk-qk167mcx.js → chunk-w6axtxge.js} +1 -1
  106. package/dist/{chunk-41vczcvf.js → chunk-w6h0cvrg.js} +2 -2
  107. package/dist/{chunk-f9ha76ap.js → chunk-w86hc7zw.js} +4 -4
  108. package/dist/{chunk-eqmptn43.js → chunk-w8903thr.js} +1 -1
  109. package/dist/{chunk-k4qz4q7r.js → chunk-wbqdq9ap.js} +1 -1
  110. package/dist/{chunk-0w6rxpr5.js → chunk-wpfjpa27.js} +1 -1
  111. package/dist/{chunk-n94jf71r.js → chunk-x2d6pk16.js} +1 -1
  112. package/dist/{chunk-6f3qpy7v.js → chunk-xfcn631v.js} +1 -1
  113. package/dist/{chunk-8799zv5c.js → chunk-xfqy8t06.js} +1 -1
  114. package/dist/{chunk-3kp7kvdb.js → chunk-xtsvx1rv.js} +2 -2
  115. package/dist/{chunk-s29j7505.js → chunk-xvd0mw2e.js} +1 -1
  116. package/dist/{chunk-az81pc04.js → chunk-xw24jh9z.js} +8 -8
  117. package/dist/{chunk-zjbk25js.js → chunk-yeb2p173.js} +1 -1
  118. package/dist/{chunk-d2z4gebj.js → chunk-yecmha03.js} +1 -1
  119. package/dist/{chunk-wy701sqv.js → chunk-yxxw9m8m.js} +1 -1
  120. package/dist/{chunk-2y5f271v.js → chunk-yz8txs66.js} +2 -2
  121. package/dist/{chunk-21wbz345.js → chunk-z1dkx9dm.js} +1 -1
  122. package/dist/{chunk-m9zsppp2.js → chunk-zb83vq43.js} +3 -3
  123. package/dist/{chunk-tea1nrwn.js → chunk-zxap8db1.js} +2 -2
  124. package/dist/components/Avatar.d.ts +1 -1
  125. package/dist/components/Button.d.ts +1 -1
  126. package/dist/components/LayoutGuard.d.ts +4 -0
  127. package/dist/components/ScrollGuard.d.ts +2 -4
  128. package/dist/components/assistant-ui/elements/AgentCard.js +2 -2
  129. package/dist/components/assistant-ui/elements/ApprovalCard.js +2 -2
  130. package/dist/components/assistant-ui/elements/ArtifactCard.js +2 -2
  131. package/dist/components/assistant-ui/elements/AudioPlayer.js +2 -2
  132. package/dist/components/assistant-ui/elements/BackgroundInbox.js +2 -2
  133. package/dist/components/assistant-ui/elements/CanvasSplit.js +2 -2
  134. package/dist/components/assistant-ui/elements/ChatPanel.js +3 -3
  135. package/dist/components/assistant-ui/elements/CheckpointHistory.js +2 -2
  136. package/dist/components/assistant-ui/elements/Citation.js +2 -2
  137. package/dist/components/assistant-ui/elements/CodeRunner.js +2 -2
  138. package/dist/components/assistant-ui/elements/CommandPalette.js +5 -5
  139. package/dist/components/assistant-ui/elements/ComposerAttachButton.js +2 -2
  140. package/dist/components/assistant-ui/elements/ComposerAttachmentChip.js +2 -2
  141. package/dist/components/assistant-ui/elements/ComposerAttachments.js +3 -3
  142. package/dist/components/assistant-ui/elements/ComposerBar.js +3 -3
  143. package/dist/components/assistant-ui/elements/ComposerCommandItem.js +3 -3
  144. package/dist/components/assistant-ui/elements/ComposerContext.js +2 -2
  145. package/dist/components/assistant-ui/elements/ComposerInput.js +3 -3
  146. package/dist/components/assistant-ui/elements/ComposerMenuItem.js +2 -2
  147. package/dist/components/assistant-ui/elements/ComposerModelItem.js +3 -3
  148. package/dist/components/assistant-ui/elements/ComposerModelTrigger.js +2 -2
  149. package/dist/components/assistant-ui/elements/ComposerPersonItem.js +3 -3
  150. package/dist/components/assistant-ui/elements/ComposerSend.js +2 -2
  151. package/dist/components/assistant-ui/elements/ComposerToolbar.js +3 -3
  152. package/dist/components/assistant-ui/elements/ComposerVoiceButton.js +2 -2
  153. package/dist/components/assistant-ui/elements/ConnectionState.js +2 -2
  154. package/dist/components/assistant-ui/elements/ConversationSearch.js +3 -3
  155. package/dist/components/assistant-ui/elements/DataTable.js +2 -2
  156. package/dist/components/assistant-ui/elements/Diagram.js +2 -2
  157. package/dist/components/assistant-ui/elements/DiffViewer.js +3 -3
  158. package/dist/components/assistant-ui/elements/DiffViewerHeader.js +2 -2
  159. package/dist/components/assistant-ui/elements/DocumentReference.js +2 -2
  160. package/dist/components/assistant-ui/elements/DraftRestore.js +2 -2
  161. package/dist/components/assistant-ui/elements/EditMessage.js +2 -2
  162. package/dist/components/assistant-ui/elements/ElicitationForm.js +2 -2
  163. package/dist/components/assistant-ui/elements/EmptyStateComposer.js +3 -3
  164. package/dist/components/assistant-ui/elements/EmptyStateSuggestion.js +2 -2
  165. package/dist/components/assistant-ui/elements/ErrorState.js +2 -2
  166. package/dist/components/assistant-ui/elements/EveAskQuestion.js +3 -3
  167. package/dist/components/assistant-ui/elements/FeedbackDialog.js +2 -2
  168. package/dist/components/assistant-ui/elements/File.js +3 -3
  169. package/dist/components/assistant-ui/elements/GenerativeUi.js +6 -6
  170. package/dist/components/assistant-ui/elements/GeoMap.js +2 -2
  171. package/dist/components/assistant-ui/elements/GuardrailNotice.js +2 -2
  172. package/dist/components/assistant-ui/elements/Image.js +3 -3
  173. package/dist/components/assistant-ui/elements/ImageGallery.js +3 -3
  174. package/dist/components/assistant-ui/elements/ImageGeneration.js +2 -2
  175. package/dist/components/assistant-ui/elements/JobProgress.js +2 -2
  176. package/dist/components/assistant-ui/elements/LauncherBubble.js +2 -2
  177. package/dist/components/assistant-ui/elements/MapAnswer.js +2 -2
  178. package/dist/components/assistant-ui/elements/MarkdownText.js +3 -3
  179. package/dist/components/assistant-ui/elements/McpServerPanel.js +2 -2
  180. package/dist/components/assistant-ui/elements/MemoryChips.js +2 -2
  181. package/dist/components/assistant-ui/elements/MermaidDiagram.js +4 -4
  182. package/dist/components/assistant-ui/elements/MermaidZoom.js +3 -3
  183. package/dist/components/assistant-ui/elements/MessageActions.js +2 -2
  184. package/dist/components/assistant-ui/elements/MessageAttachments.js +2 -2
  185. package/dist/components/assistant-ui/elements/MessageBranches.js +2 -2
  186. package/dist/components/assistant-ui/elements/MessagePair.js +2 -2
  187. package/dist/components/assistant-ui/elements/MessageQueue.js +2 -2
  188. package/dist/components/assistant-ui/elements/MobileComposer.js +3 -3
  189. package/dist/components/assistant-ui/elements/ModelSelector.js +11 -11
  190. package/dist/components/assistant-ui/elements/ModelSelectorContent.js +10 -10
  191. package/dist/components/assistant-ui/elements/ModelSelectorEmpty.js +5 -5
  192. package/dist/components/assistant-ui/elements/ModelSelectorFocusAnchor.js +5 -5
  193. package/dist/components/assistant-ui/elements/ModelSelectorGroup.js +5 -5
  194. package/dist/components/assistant-ui/elements/ModelSelectorItem.js +5 -5
  195. package/dist/components/assistant-ui/elements/ModelSelectorList.js +7 -7
  196. package/dist/components/assistant-ui/elements/ModelSelectorSearch.js +5 -5
  197. package/dist/components/assistant-ui/elements/ModelSelectorSeparator.js +5 -5
  198. package/dist/components/assistant-ui/elements/Onboarding.js +2 -2
  199. package/dist/components/assistant-ui/elements/OptionList.js +2 -2
  200. package/dist/components/assistant-ui/elements/PermissionGrant.js +2 -2
  201. package/dist/components/assistant-ui/elements/PromptLibrary.js +3 -3
  202. package/dist/components/assistant-ui/elements/QuestionFlow.js +3 -3
  203. package/dist/components/assistant-ui/elements/QuotaBanner.js +2 -2
  204. package/dist/components/assistant-ui/elements/QuoteReply.js +2 -2
  205. package/dist/components/assistant-ui/elements/ReadAloud.js +2 -2
  206. package/dist/components/assistant-ui/elements/RecommendationCard.js +2 -2
  207. package/dist/components/assistant-ui/elements/RegenerateMenu.js +2 -2
  208. package/dist/components/assistant-ui/elements/ReviewableDiff.js +2 -2
  209. package/dist/components/assistant-ui/elements/SettingsPanel.js +2 -2
  210. package/dist/components/assistant-ui/elements/SharedConversation.js +2 -2
  211. package/dist/components/assistant-ui/elements/StoppedRun.js +2 -2
  212. package/dist/components/assistant-ui/elements/Suggestions.js +2 -2
  213. package/dist/components/assistant-ui/elements/TaskCard.js +2 -2
  214. package/dist/components/assistant-ui/elements/TerminalBlock.js +2 -2
  215. package/dist/components/assistant-ui/elements/ThreadList.js +2 -2
  216. package/dist/components/assistant-ui/elements/ThreadSearch.js +3 -3
  217. package/dist/components/assistant-ui/elements/TodoList.js +2 -2
  218. package/dist/components/assistant-ui/elements/ToolError.js +2 -2
  219. package/dist/components/assistant-ui/elements/ToolGroup.js +2 -2
  220. package/dist/components/assistant-ui/elements/TooltipIconButton.js +2 -2
  221. package/dist/components/assistant-ui/elements/VoiceConversation.js +2 -2
  222. package/dist/components/assistant-ui/elements/WebPreview.js +2 -2
  223. package/dist/components/assistant-ui/eveAskQuestionToolkit.js +4 -4
  224. package/dist/components/assistant-ui/index.js +101 -101
  225. package/dist/components/assistant-ui/native/AssistantModal.js +14 -14
  226. package/dist/components/assistant-ui/native/AssistantSidebar.js +13 -13
  227. package/dist/components/assistant-ui/native/AttachmentPreview.js +5 -5
  228. package/dist/components/assistant-ui/native/McpConfigDialog.js +3 -3
  229. package/dist/components/assistant-ui/native/MermaidDiagram.js +5 -5
  230. package/dist/components/assistant-ui/native/ModelSelector.js +13 -13
  231. package/dist/components/assistant-ui/native/Reasoning.js +4 -4
  232. package/dist/components/assistant-ui/native/TaskCard.js +6 -6
  233. package/dist/components/assistant-ui/native/TaskGroup.js +7 -7
  234. package/dist/components/assistant-ui/native/Thread.js +12 -12
  235. package/dist/components/assistant-ui/native/ThreadList.d.ts +1 -1
  236. package/dist/components/assistant-ui/native/ThreadList.js +2 -2
  237. package/dist/components/assistant-ui/native/ThreadListSidebar.js +4 -4
  238. package/dist/components/assistant-ui/native/ToolFallbackRoot.js +2 -2
  239. package/dist/components/assistant-ui/native/VoiceConnectButton.js +2 -2
  240. package/dist/components/assistant-ui/native/VoiceControl.js +6 -6
  241. package/dist/components/assistant-ui/native/VoiceConversation.js +3 -3
  242. package/dist/components/assistant-ui/native/VoiceDisconnectButton.js +3 -3
  243. package/dist/components/assistant-ui/native/VoiceMuteButton.js +3 -3
  244. package/dist/components/assistant-ui/native/index.js +41 -41
  245. package/dist/components/calendar/index.js +2 -2
  246. package/dist/components/carousel/index.js +1 -1
  247. package/dist/components/command/index.js +4 -4
  248. package/dist/components/data-grid/index.js +1 -1
  249. package/dist/components/editor/index.js +2 -2
  250. package/dist/components/event-calendar/index.js +1 -1
  251. package/dist/components/file-upload/index.js +1 -1
  252. package/dist/components/gantt/index.js +2 -2
  253. package/dist/components/message-scroller/index.js +1 -1
  254. package/dist/components/persian-calendar/index.js +2 -2
  255. package/dist/components/questionnaire/index.js +1 -1
  256. package/dist/components/sonner/index.js +1 -1
  257. package/dist/components/tree/TreeItem.d.ts +1 -1
  258. package/dist/components/tree/index.js +25 -22
  259. package/dist/hooks/useDocumentGuard.d.ts +8 -0
  260. package/dist/index.d.ts +4 -0
  261. package/dist/index.js +245 -67
  262. package/dist/utils/collectLayoutViolations.d.ts +13 -0
  263. package/dist/utils/getLayoutAnimations.d.ts +2 -0
  264. package/dist/utils/observeLayoutChanges.d.ts +2 -0
  265. package/dist/utils/observeLayoutGuards.d.ts +2 -0
  266. package/dist/utils/observeScrollGuards.d.ts +0 -1
  267. package/llms/components/actions/Button.md +17 -1
  268. package/llms/components/data-display/Avatar.md +14 -1
  269. package/llms/components/navigation/Sidebar.md +44 -4
  270. package/llms/components/providers/LayoutGuard.md +24 -0
  271. package/llms.txt +1 -0
  272. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -4,7 +4,7 @@ import {
4
4
  import {
5
5
  buttonVariants2,
6
6
  Button2
7
- } from "./chunk-73rkr9ct.js";
7
+ } from "./chunk-btz12z1j.js";
8
8
  import {
9
9
  DensityContext,
10
10
  useDensity
@@ -80,7 +80,7 @@ import {
80
80
  DialogFooter2,
81
81
  DialogTitle2,
82
82
  DialogDescription2
83
- } from "./chunk-70vndezn.js";
83
+ } from "./chunk-rg7c7wxt.js";
84
84
  import {
85
85
  Slider2
86
86
  } from "./chunk-644cnngf.js";
@@ -116,7 +116,7 @@ import {
116
116
  InputGroupText2,
117
117
  InputGroupInput2,
118
118
  InputGroupTextarea2
119
- } from "./chunk-1jeg5z55.js";
119
+ } from "./chunk-8zhqkj8r.js";
120
120
  import {
121
121
  Tabs2,
122
122
  tabsListVariants2,
@@ -131,7 +131,7 @@ import {
131
131
  useDropTarget2,
132
132
  DropTarget2,
133
133
  Kanban2
134
- } from "./chunk-kbg2e95b.js";
134
+ } from "./chunk-nx21zbg9.js";
135
135
  import {
136
136
  badgeVariants2,
137
137
  Badge2
@@ -174,7 +174,7 @@ import {
174
174
  AvatarBadge2,
175
175
  AvatarGroup2,
176
176
  AvatarGroupCount2
177
- } from "./chunk-gg39sggp.js";
177
+ } from "./chunk-hyq4nwg2.js";
178
178
  import {
179
179
  Progress2,
180
180
  ProgressTrack2,
@@ -244,7 +244,7 @@ import {
244
244
  SidebarMenuSub2,
245
245
  SidebarMenuSubItem2,
246
246
  SidebarMenuSubButton2
247
- } from "./chunk-dq7kr5y0.js";
247
+ } from "./chunk-82wxsc8p.js";
248
248
  import {
249
249
  Toolbar2,
250
250
  ToolbarButton2,
@@ -252,7 +252,7 @@ import {
252
252
  ToolbarInput2,
253
253
  ToolbarGroup2,
254
254
  ToolbarSeparator2
255
- } from "./chunk-21wbz345.js";
255
+ } from "./chunk-z1dkx9dm.js";
256
256
  // src/components/ButtonLink.tsx
257
257
  import { mergeProps } from "@base-ui/react/merge-props";
258
258
  import { useRender } from "@base-ui/react/use-render";
@@ -923,51 +923,171 @@ function DensityProvider({
923
923
  children: element
924
924
  });
925
925
  }
926
- // src/components/ThemeProvider.tsx
927
- import { useMemo } from "react";
928
- import { useIsomorphicLayoutEffect, useTernaryDarkMode } from "usehooks-ts";
929
-
930
- // src/components/ScrollGuard.tsx
926
+ // src/hooks/useDocumentGuard.ts
931
927
  import { useEffect } from "react";
928
+ var registrations = new WeakMap;
929
+ function useDocumentGuard(observe, ownerDocument) {
930
+ useEffect(() => {
931
+ if (process.env.NODE_ENV === "production")
932
+ return;
933
+ const target = ownerDocument ?? document;
934
+ let observers = registrations.get(target);
935
+ if (!observers) {
936
+ observers = new Map;
937
+ registrations.set(target, observers);
938
+ }
939
+ let registration = observers.get(observe);
940
+ if (!registration) {
941
+ registration = { users: 0, disconnect: observe(target) };
942
+ observers.set(observe, registration);
943
+ }
944
+ registration.users++;
945
+ return () => {
946
+ registration.users--;
947
+ if (!registration.users) {
948
+ registration.disconnect();
949
+ observers.delete(observe);
950
+ if (!observers.size)
951
+ registrations.delete(target);
952
+ }
953
+ };
954
+ }, [observe, ownerDocument]);
955
+ }
932
956
 
933
- // src/utils/observeScrollGuards.ts
934
- function throwViolation(error) {
935
- throw error;
957
+ // src/utils/getLayoutAnimations.ts
958
+ function getLayoutAnimations(root) {
959
+ const document2 = root.ownerDocument ?? root;
960
+ const view = document2.defaultView;
961
+ if (!view)
962
+ return [];
963
+ const boundaries = [...root.querySelectorAll("[data-layout-boundary]")];
964
+ if (root instanceof view.Element && root.hasAttribute("data-layout-boundary"))
965
+ boundaries.push(root);
966
+ return document2.getAnimations().filter((animation) => {
967
+ if (animation.playState !== "running" || animation.effect?.getComputedTiming().iterations === Infinity)
968
+ return false;
969
+ const target = animation.effect instanceof view.KeyframeEffect ? animation.effect.target : null;
970
+ return target instanceof view.Element && boundaries.some((boundary) => boundary.contains(target) || target.contains(boundary));
971
+ });
936
972
  }
937
- function getViolation(element, view) {
938
- if (!element.getClientRects().length)
939
- return;
973
+
974
+ // src/utils/collectLayoutViolations.ts
975
+ function identify(element) {
976
+ const slot = element.getAttribute("data-slot");
977
+ const name = element.getAttribute("aria-label") ?? element.textContent?.trim().slice(0, 60);
978
+ return `${element.localName}${element.id ? `#${element.id}` : slot ? `[data-slot="${slot}"]` : ""}${name ? ` "${name}"` : ""}`;
979
+ }
980
+ function isHidden(element, view) {
981
+ if (element.closest('[inert], [data-layout-exclude]:not([data-layout-exclude=""])'))
982
+ return true;
983
+ if (!element.checkVisibility({ visibilityProperty: true, opacityProperty: true }))
984
+ return true;
940
985
  const style = view.getComputedStyle(element);
941
- if (style.visibility !== "visible")
942
- return;
943
- const axes = [];
944
- if (["auto", "scroll"].includes(style.overflowX) && element.scrollWidth > element.clientWidth) {
945
- axes.push(`horizontal: ${element.scrollWidth}px > ${element.clientWidth}px`);
946
- }
947
- if (["auto", "scroll"].includes(style.overflowY) && element.scrollHeight > element.clientHeight) {
948
- axes.push(`vertical: ${element.scrollHeight}px > ${element.clientHeight}px`);
986
+ return style.clip === "rect(0px, 0px, 0px, 0px)" || style.clipPath === "inset(50%)";
987
+ }
988
+ function collectLayoutViolations(root, tolerance = 1) {
989
+ const document2 = root.nodeType === Node.DOCUMENT_NODE ? root : root.ownerDocument;
990
+ const view = document2.defaultView;
991
+ if (!view)
992
+ return [];
993
+ const boundaries = [...root.querySelectorAll("[data-layout-boundary]")];
994
+ if (root instanceof view.Element && root.hasAttribute("data-layout-boundary"))
995
+ boundaries.unshift(root);
996
+ const violations = [];
997
+ for (const boundary of boundaries) {
998
+ if (isHidden(boundary, view))
999
+ continue;
1000
+ const bounds = boundary.getBoundingClientRect();
1001
+ const axis = boundary.getAttribute("data-layout-boundary");
1002
+ for (const element of [boundary, ...boundary.querySelectorAll("*")]) {
1003
+ if (isHidden(element, view) || element.parentElement?.closest("svg"))
1004
+ continue;
1005
+ let checkX = axis !== "y";
1006
+ let checkY = axis !== "x";
1007
+ const isControl = element.matches("button, a[href], input, select, textarea, [tabindex], [role=button]");
1008
+ const elementBounds = element.getBoundingClientRect();
1009
+ const limits = { left: bounds.left, right: bounds.right, top: bounds.top, bottom: bounds.bottom };
1010
+ if (isControl) {
1011
+ limits.left = Math.max(limits.left, elementBounds.left);
1012
+ limits.right = Math.min(limits.right, elementBounds.right);
1013
+ limits.top = Math.max(limits.top, elementBounds.top);
1014
+ limits.bottom = Math.min(limits.bottom, elementBounds.bottom);
1015
+ }
1016
+ let ancestor = element === boundary ? null : element.parentElement;
1017
+ let hidden = false;
1018
+ while (ancestor && ancestor !== boundary) {
1019
+ if (isHidden(ancestor, view)) {
1020
+ hidden = true;
1021
+ break;
1022
+ }
1023
+ const style = view.getComputedStyle(ancestor);
1024
+ if (isControl) {
1025
+ const clip = ancestor.getBoundingClientRect();
1026
+ if (["hidden", "clip"].includes(style.overflowX)) {
1027
+ limits.left = Math.max(limits.left, clip.left);
1028
+ limits.right = Math.min(limits.right, clip.right);
1029
+ }
1030
+ if (["hidden", "clip"].includes(style.overflowY)) {
1031
+ limits.top = Math.max(limits.top, clip.top);
1032
+ limits.bottom = Math.min(limits.bottom, clip.bottom);
1033
+ }
1034
+ }
1035
+ if (["auto", "scroll"].includes(style.overflowX))
1036
+ checkX = false;
1037
+ if (["auto", "scroll"].includes(style.overflowY))
1038
+ checkY = false;
1039
+ ancestor = ancestor.parentElement;
1040
+ }
1041
+ if (hidden)
1042
+ continue;
1043
+ const rectangles = [...element.getClientRects()];
1044
+ const style = view.getComputedStyle(element);
1045
+ if (style.textOverflow !== "ellipsis") {
1046
+ for (const child of element.childNodes) {
1047
+ if (child.nodeType !== Node.TEXT_NODE || !child.textContent?.trim())
1048
+ continue;
1049
+ const range = document2.createRange();
1050
+ range.selectNodeContents(child);
1051
+ rectangles.push(...range.getClientRects());
1052
+ }
1053
+ }
1054
+ for (const edge of ["left", "right", "top", "bottom"]) {
1055
+ if (edge === "left" || edge === "right" ? !checkX : !checkY)
1056
+ continue;
1057
+ const overflow = Math.max(0, ...rectangles.map((rect) => edge === "left" || edge === "top" ? limits[edge] - rect[edge] : rect[edge] - limits[edge]));
1058
+ if (overflow <= tolerance)
1059
+ continue;
1060
+ violations.push({
1061
+ boundary,
1062
+ element,
1063
+ edge,
1064
+ overflow,
1065
+ message: `${identify(element)} exceeds ${identify(boundary)} ${edge} edge by ${Math.round(overflow * 100) / 100}px`
1066
+ });
1067
+ }
1068
+ }
949
1069
  }
950
- if (!axes.length)
951
- return;
952
- const slot = element.getAttribute("data-slot");
953
- const identity = element.id ? ` id="${element.id}"` : slot ? ` data-slot="${slot}"` : "";
954
- return `<${element.localName}${identity}> (${axes.join(", ")})`;
1070
+ return violations;
955
1071
  }
956
- function observeScrollGuards(ownerDocument, reportViolation = throwViolation) {
1072
+
1073
+ // src/utils/observeLayoutChanges.ts
1074
+ function observeLayoutChanges(ownerDocument, selector, checkLayout) {
957
1075
  const view = ownerDocument.defaultView;
958
1076
  if (!view)
959
1077
  return () => {};
1078
+ let isConnected = true;
960
1079
  let frame;
961
1080
  let needsRefresh = true;
962
1081
  let guarded = [];
963
1082
  const observed = new Set;
964
- const reported = new WeakSet;
965
1083
  const schedule = () => {
1084
+ if (!isConnected)
1085
+ return;
966
1086
  frame ??= view.requestAnimationFrame(check);
967
1087
  };
968
1088
  const resizeObserver = new view.ResizeObserver(schedule);
969
1089
  const refresh = () => {
970
- guarded = [...ownerDocument.querySelectorAll('[data-scroll="none"]')];
1090
+ guarded = [...ownerDocument.querySelectorAll(selector)];
971
1091
  const targets = new Set(guarded.flatMap((element) => [element, ...element.querySelectorAll("*")]));
972
1092
  for (const element of observed) {
973
1093
  if (!targets.has(element)) {
@@ -987,22 +1107,10 @@ function observeScrollGuards(ownerDocument, reportViolation = throwViolation) {
987
1107
  frame = undefined;
988
1108
  if (needsRefresh)
989
1109
  refresh();
990
- const violations = [];
991
- for (const element of guarded) {
992
- const violation = getViolation(element, view);
993
- if (!violation) {
994
- reported.delete(element);
995
- } else if (!reported.has(element)) {
996
- reported.add(element);
997
- violations.push(violation);
998
- }
999
- }
1000
- if (violations.length) {
1001
- reportViolation(new Error(`[shadcn] Scrolling is forbidden by data-scroll="none": ${violations.join("; ")}. ` + "Move scrolling content into a nested ScrollArea or another explicit scroll viewport."));
1002
- }
1110
+ checkLayout(guarded, schedule);
1003
1111
  };
1004
1112
  const mutations = new view.MutationObserver((records) => {
1005
- needsRefresh ||= records.some((record) => record.type === "childList" || record.attributeName === "data-scroll");
1113
+ needsRefresh ||= records.some((record) => record.type === "childList" || record.type === "attributes");
1006
1114
  schedule();
1007
1115
  });
1008
1116
  mutations.observe(ownerDocument.documentElement, {
@@ -1012,17 +1120,20 @@ function observeScrollGuards(ownerDocument, reportViolation = throwViolation) {
1012
1120
  attributes: true
1013
1121
  });
1014
1122
  view.addEventListener("resize", schedule);
1123
+ ownerDocument.addEventListener("scroll", schedule, true);
1015
1124
  ownerDocument.addEventListener("load", schedule, true);
1016
1125
  ownerDocument.addEventListener("transitionend", schedule, true);
1017
1126
  ownerDocument.addEventListener("animationend", schedule, true);
1018
1127
  ownerDocument.fonts.addEventListener("loadingdone", schedule);
1019
1128
  schedule();
1020
1129
  return () => {
1130
+ isConnected = false;
1021
1131
  mutations.disconnect();
1022
1132
  resizeObserver.disconnect();
1023
1133
  if (frame !== undefined)
1024
1134
  view.cancelAnimationFrame(frame);
1025
1135
  view.removeEventListener("resize", schedule);
1136
+ ownerDocument.removeEventListener("scroll", schedule, true);
1026
1137
  ownerDocument.removeEventListener("load", schedule, true);
1027
1138
  ownerDocument.removeEventListener("transitionend", schedule, true);
1028
1139
  ownerDocument.removeEventListener("animationend", schedule, true);
@@ -1030,28 +1141,92 @@ function observeScrollGuards(ownerDocument, reportViolation = throwViolation) {
1030
1141
  };
1031
1142
  }
1032
1143
 
1144
+ // src/utils/observeLayoutGuards.ts
1145
+ function throwViolation(error) {
1146
+ throw error;
1147
+ }
1148
+ function observeLayoutGuards(document2, report = throwViolation) {
1149
+ const pending = new WeakSet;
1150
+ let previous = "";
1151
+ return observeLayoutChanges(document2, "[data-layout-boundary]", (_elements, schedule) => {
1152
+ const animations = getLayoutAnimations(document2);
1153
+ for (const animation of animations) {
1154
+ if (pending.has(animation))
1155
+ continue;
1156
+ pending.add(animation);
1157
+ const settled = () => {
1158
+ pending.delete(animation);
1159
+ schedule();
1160
+ };
1161
+ animation.finished.then(settled, settled);
1162
+ }
1163
+ if (animations.length)
1164
+ return;
1165
+ const message = collectLayoutViolations(document2).map((violation) => violation.message).join("; ");
1166
+ const hasChanged = message !== previous;
1167
+ previous = message;
1168
+ if (message && hasChanged)
1169
+ report(new Error(`[shadcn] Layout containment: ${message}`));
1170
+ });
1171
+ }
1172
+
1173
+ // src/components/LayoutGuard.tsx
1174
+ "use client";
1175
+ function LayoutGuard({ ownerDocument }) {
1176
+ useDocumentGuard(observeLayoutGuards, ownerDocument);
1177
+ return null;
1178
+ }
1179
+
1180
+ // src/components/ThemeProvider.tsx
1181
+ import { useMemo } from "react";
1182
+ import { useIsomorphicLayoutEffect, useTernaryDarkMode } from "usehooks-ts";
1183
+
1184
+ // src/utils/observeScrollGuards.ts
1185
+ function throwViolation2(error) {
1186
+ throw error;
1187
+ }
1188
+ function getViolation(element, view) {
1189
+ if (!element.getClientRects().length)
1190
+ return;
1191
+ const style = view.getComputedStyle(element);
1192
+ if (style.visibility !== "visible")
1193
+ return;
1194
+ const axes = [];
1195
+ if (["auto", "scroll"].includes(style.overflowX) && element.scrollWidth > element.clientWidth) {
1196
+ axes.push(`horizontal: ${element.scrollWidth}px > ${element.clientWidth}px`);
1197
+ }
1198
+ if (["auto", "scroll"].includes(style.overflowY) && element.scrollHeight > element.clientHeight) {
1199
+ axes.push(`vertical: ${element.scrollHeight}px > ${element.clientHeight}px`);
1200
+ }
1201
+ if (!axes.length)
1202
+ return;
1203
+ const slot = element.getAttribute("data-slot");
1204
+ const identity = element.id ? ` id="${element.id}"` : slot ? ` data-slot="${slot}"` : "";
1205
+ return `<${element.localName}${identity}> (${axes.join(", ")})`;
1206
+ }
1207
+ function observeScrollGuards(ownerDocument, reportViolation = throwViolation2) {
1208
+ const reported = new WeakSet;
1209
+ return observeLayoutChanges(ownerDocument, '[data-scroll="none"]', (guarded) => {
1210
+ const view = ownerDocument.defaultView;
1211
+ const violations = [];
1212
+ for (const element of guarded) {
1213
+ const violation = getViolation(element, view);
1214
+ if (!violation)
1215
+ reported.delete(element);
1216
+ else if (!reported.has(element)) {
1217
+ reported.add(element);
1218
+ violations.push(violation);
1219
+ }
1220
+ }
1221
+ if (violations.length)
1222
+ reportViolation(new Error('[shadcn] Scrolling is forbidden by data-scroll="none": ' + violations.join("; ") + ". " + "Move scrolling content into a nested ScrollArea or another explicit scroll viewport."));
1223
+ });
1224
+ }
1225
+
1033
1226
  // src/components/ScrollGuard.tsx
1034
1227
  "use client";
1035
- var registrations = new WeakMap;
1036
1228
  function ScrollGuard({ ownerDocument }) {
1037
- useEffect(() => {
1038
- if (process.env.NODE_ENV === "production")
1039
- return;
1040
- const target = ownerDocument ?? document;
1041
- let registration = registrations.get(target);
1042
- if (!registration) {
1043
- registration = { users: 0, disconnect: observeScrollGuards(target) };
1044
- registrations.set(target, registration);
1045
- }
1046
- registration.users++;
1047
- return () => {
1048
- registration.users--;
1049
- if (!registration.users) {
1050
- registration.disconnect();
1051
- registrations.delete(target);
1052
- }
1053
- };
1054
- }, [ownerDocument]);
1229
+ useDocumentGuard(observeScrollGuards, ownerDocument);
1055
1230
  return null;
1056
1231
  }
1057
1232
 
@@ -1089,6 +1264,7 @@ function ThemePalette({
1089
1264
  value,
1090
1265
  children: [
1091
1266
  /* @__PURE__ */ jsx10(ScrollGuard, {}),
1267
+ /* @__PURE__ */ jsx10(LayoutGuard, {}),
1092
1268
  children
1093
1269
  ]
1094
1270
  });
@@ -4075,6 +4251,7 @@ export {
4075
4251
  Kbd2 as Kbd,
4076
4252
  KbdGroup2 as KbdGroup,
4077
4253
  Label2 as Label,
4254
+ LayoutGuard,
4078
4255
  Marker,
4079
4256
  MarkerContent,
4080
4257
  MarkerIcon,
@@ -4247,6 +4424,7 @@ export {
4247
4424
  buttonGroupVariants,
4248
4425
  buttonVariants2 as buttonVariants,
4249
4426
  cn2 as cn,
4427
+ collectLayoutViolations,
4250
4428
  createToastManager,
4251
4429
  markerVariants,
4252
4430
  navigationMenuTriggerStyle,
@@ -0,0 +1,13 @@
1
+ export interface ILayoutViolation {
2
+ boundary: Element;
3
+ element: Element;
4
+ edge: "left" | "right" | "top" | "bottom";
5
+ overflow: number;
6
+ message: string;
7
+ }
8
+ /** Checks marked boundaries in the supplied root, including the root itself.
9
+ * data-layout-boundary="x" or "y" checks only that axis; an empty value checks both.
10
+ * Native scroll viewports permit displacement along their scrolling axes.
11
+ * data-layout-exclude requires a descriptive reason and excludes an intentional escape.
12
+ */
13
+ export declare function collectLayoutViolations(root: Document | Element, tolerance?: number): ILayoutViolation[];
@@ -0,0 +1,2 @@
1
+ /** Finite animations affecting marked boundaries, including animated ancestors. */
2
+ export declare function getLayoutAnimations(root: Document | Element): Animation[];
@@ -0,0 +1,2 @@
1
+ /** Batch document, portal, font and geometry changes into animation-frame checks. */
2
+ export declare function observeLayoutChanges(ownerDocument: Document, selector: string, checkLayout: (elements: Element[], schedule: () => void) => void): () => void;
@@ -0,0 +1,2 @@
1
+ /** Observe marked boundaries, including portals, after finite animations settle. */
2
+ export declare function observeLayoutGuards(document: Document, report?: (error: Error) => void): () => void;
@@ -1,4 +1,3 @@
1
1
  type ReportViolation = (error: Error) => void;
2
- /** Observe the current document, including portals. Descendant scroll viewports remain independent. */
3
2
  export declare function observeScrollGuards(ownerDocument: Document, reportViolation?: ReportViolation): () => void;
4
3
  export {};
@@ -29,7 +29,7 @@ Button
29
29
  {
30
30
  variant: {
31
31
  control: "select",
32
- options: ["default", "outline", "secondary", "ghost", "destructive", "success", "warning", "link"],
32
+ options: ["default", "outline", "secondary", "ghost", "destructive", "success", "warning", "link", "pad"],
33
33
  },
34
34
  size: {
35
35
  control: "select",
@@ -119,6 +119,22 @@ Storybook CSF excerpts. Default args and render apply unless overridden. Local h
119
119
  }
120
120
  ```
121
121
 
122
+ ### Pad
123
+
124
+ ```tsx
125
+ {
126
+ args: { variant: "pad", size: "content" }
127
+ }
128
+ ```
129
+
130
+ ### DisabledPad
131
+
132
+ ```tsx
133
+ {
134
+ args: { variant: "pad", size: "content", disabled: true }
135
+ }
136
+ ```
137
+
122
138
  ### Disabled
123
139
 
124
140
  ```tsx
@@ -27,7 +27,7 @@ Avatar
27
27
  ## Story controls
28
28
 
29
29
  ```tsx
30
- { size: { control: "select", options: ["default", "sm", "lg", "preview"] } }
30
+ { size: { control: "select", options: ["default", "sm", "lg", "preview", "full"] } }
31
31
  ```
32
32
 
33
33
  ## Default render
@@ -67,6 +67,19 @@ Storybook CSF excerpts. Default args and render apply unless overridden. Local h
67
67
  }
68
68
  ```
69
69
 
70
+ ### FullWidth
71
+
72
+ ```tsx
73
+ {
74
+ args: { size: "full", shape: "square" },
75
+ decorators: [
76
+ (Story) => (<div data-testid="Avatar--container" className="w-52">
77
+ <Story />
78
+ </div>),
79
+ ]
80
+ }
81
+ ```
82
+
70
83
  ### Square
71
84
 
72
85
  ```tsx
@@ -17,7 +17,7 @@ import { Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupActio
17
17
  import type { Input } from "@base-ui/react/input";
18
18
  import type { ComponentProps, ReactElement } from "react";
19
19
  import { useRef, useState } from "react";
20
- import { FileIcon, HomeIcon, PlusIcon } from "lucide-react";
20
+ import { FileIcon, HomeIcon, PlusIcon, SettingsIcon } from "lucide-react";
21
21
  ```
22
22
 
23
23
  ## Default component
@@ -48,7 +48,7 @@ Storybook CSF excerpts. Default args and render apply unless overridden. Local h
48
48
 
49
49
  ```tsx
50
50
  {
51
- render: () => <WorkspaceLayout />
51
+ render: (args) => <WorkspaceLayout {...args}/>
52
52
  }
53
53
  ```
54
54
 
@@ -217,7 +217,16 @@ Storybook CSF excerpts. Default args and render apply unless overridden. Local h
217
217
  {
218
218
  render: (args) => (<SidebarProvider>
219
219
  <Sidebar {...args} aria-label="Loading projects">
220
- <SidebarHeader>Loading projects</SidebarHeader>
220
+ <SidebarHeader>
221
+ <SidebarMenu>
222
+ <SidebarMenuItem>
223
+ <SidebarMenuButton disabled>
224
+ <HomeIcon aria-hidden/>
225
+ <span>Loading projects</span>
226
+ </SidebarMenuButton>
227
+ </SidebarMenuItem>
228
+ </SidebarMenu>
229
+ </SidebarHeader>
221
230
  <SidebarContent>
222
231
  <SidebarMenu>
223
232
  <SidebarMenuItem>
@@ -250,7 +259,10 @@ Storybook CSF excerpts. Default args and render apply unless overridden. Local h
250
259
  <SidebarGroupContent>
251
260
  <SidebarMenu>
252
261
  <SidebarMenuItem>
253
- <SidebarMenuButton render={<a href="#folder"/>}>Folder link</SidebarMenuButton>
262
+ <SidebarMenuButton render={<a href="#folder"/>}>
263
+ <FileIcon aria-hidden/>
264
+ <span>Folder link</span>
265
+ </SidebarMenuButton>
254
266
  </SidebarMenuItem>
255
267
  </SidebarMenu>
256
268
  </SidebarGroupContent>
@@ -328,3 +340,31 @@ Storybook CSF excerpts. Default args and render apply unless overridden. Local h
328
340
  ```tsx
329
341
  {}
330
342
  ```
343
+
344
+ ### WorkspaceMenusCompactRight
345
+
346
+ ```tsx
347
+ {
348
+ render: (args) => <WorkspaceLayout {...args}/>,
349
+ args: { side: "right" },
350
+ globals: { density: "compact", theme: "light" }
351
+ }
352
+ ```
353
+
354
+ ### RightCompactDensity
355
+
356
+ ```tsx
357
+ {
358
+ args: { side: "right" },
359
+ globals: { density: "compact", theme: "light" }
360
+ }
361
+ ```
362
+
363
+ ### RightComfortableDensity
364
+
365
+ ```tsx
366
+ {
367
+ args: { side: "right" },
368
+ globals: { density: "comfortable", theme: "light" }
369
+ }
370
+ ```
@@ -0,0 +1,24 @@
1
+ # LayoutGuard
2
+
3
+ ThemeProvider installs LayoutGuard in development. Mark a surface with data-layout-boundary="" to check both axes, or "x" / "y" for one axis. collectLayoutViolations(root, tolerance = 1) returns elements, edges, pixel overflow, and diagnostic messages for browser assertions. Checks include text ranges and clipped controls. Native scroll viewports permit displacement on their scrolling axes. Hidden/inert content and screen-reader labels are excluded; ellipsis text is allowed. Use data-layout-exclude="reason" only for intentional escape such as an edge-mounted resize rail. Portals are independent: mark their own surfaces. Finite layout animations settle before development errors; production installs no observer. Check every meaningful interaction state in tests. Axis-aligned DOM geometry does not measure shadows, pseudo-elements, or painted SVG paths.
4
+
5
+ Story: @alexgorbatchev/shadcn/components/providers/LayoutGuard
6
+ Source: src/components/stories/providers/LayoutGuard.stories.tsx
7
+
8
+ [Full source and local helpers](https://github.com/alexgorbatchev/shadcn/blob/main/src/components/stories/providers/LayoutGuard.stories.tsx)
9
+
10
+ ## Public imports
11
+
12
+ ```tsx
13
+ import { LayoutGuard } from "@alexgorbatchev/shadcn";
14
+ ```
15
+
16
+ ## Default component
17
+
18
+ ```tsx
19
+ LayoutGuard
20
+ ```
21
+
22
+ ## Examples
23
+
24
+ Storybook CSF excerpts. Default args and render apply unless overridden. Local helpers, fixtures, decorators, and providers may be required; these are reference excerpts, not standalone consumer modules. Interaction tests are omitted.
package/llms.txt CHANGED
@@ -457,6 +457,7 @@ Generated from the public package exports and Storybook sources.
457
457
 
458
458
  - [DensityProvider](./llms/components/providers/DensityProvider.md)
459
459
  - [DirectionProvider](./llms/components/providers/DirectionProvider.md)
460
+ - [LayoutGuard](./llms/components/providers/LayoutGuard.md): ThemeProvider installs LayoutGuard in development. Mark a surface with data-layout-boundary="" to check both axes, or "x" / "y" for one axis. collectLayoutViolations(root, tolerance = 1) returns elements, edges, pixel overflow, and diagnostic messages for browser assertions. Checks include text ranges and clipped controls. Native scroll viewports permit displacement on their scrolling axes. Hidden/inert content and screen-reader labels are excluded; ellipsis text is allowed. Use data-layout-exclude="reason" only for intentional escape such as an edge-mounted resize rail. Portals are independent: mark their own surfaces. Finite layout animations settle before development errors; production installs no observer. Check every meaningful interaction state in tests. Axis-aligned DOM geometry does not measure shadows, pseudo-elements, or painted SVG paths.
460
461
  - [PortalProvider](./llms/components/providers/PortalProvider.md)
461
462
  - [ScrollGuard](./llms/components/providers/ScrollGuard.md): ThemeProvider mounts ScrollGuard automatically in development. Mark any HTML element with data-scroll="none" to reject accidental scrolling on that element. Place intentional scrolling in a nested ScrollArea or native scroll viewport. Errors identify the offending element and axis. Production builds install no observers.
462
463
  - [ThemeProvider](./llms/components/providers/ThemeProvider.md): The preview decorator owns one document-wide ThemeProvider. These controls change its persisted preference. The theme toolbar can force a palette on any other story.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alexgorbatchev/shadcn",
3
- "version": "0.0.22",
3
+ "version": "0.0.24",
4
4
  "description": "Sharp, monospace React components with compact and comfortable densities.",
5
5
  "license": "MIT",
6
6
  "repository": {