@vendure-platform/create 0.4.0 → 0.5.1

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 (334) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/README.md +39 -39
  3. package/dist/add-to-existing.js +1 -1
  4. package/dist/assets/demo-data/initial-data.json +663 -663
  5. package/dist/assets/storefront/components.json +20 -20
  6. package/dist/assets/storefront/eslint.config.mjs +10 -10
  7. package/dist/assets/storefront/graphql.config.yml +1 -1
  8. package/dist/assets/storefront/messages/de.json +2 -0
  9. package/dist/assets/storefront/messages/en.json +2 -0
  10. package/dist/assets/storefront/next.config.ts +5 -4
  11. package/dist/assets/storefront/package.json +1 -1
  12. package/dist/assets/storefront/postcss.config.mjs +1 -1
  13. package/dist/assets/storefront/src/app/[locale]/(catalog)/catalog/page.tsx +17 -21
  14. package/dist/assets/storefront/src/app/[locale]/(catalog)/collection/[slug]/page.tsx +64 -42
  15. package/dist/assets/storefront/src/app/[locale]/(catalog)/layout.tsx +1 -5
  16. package/dist/assets/storefront/src/app/[locale]/(catalog)/product/[slug]/actions.ts +69 -65
  17. package/dist/assets/storefront/src/app/[locale]/(catalog)/product/[slug]/page.tsx +68 -37
  18. package/dist/assets/storefront/src/app/[locale]/(catalog)/search/page.tsx +24 -27
  19. package/dist/assets/storefront/src/app/[locale]/(catalog)/search/search-results.tsx +11 -9
  20. package/dist/assets/storefront/src/app/[locale]/(catalog)/search/search-term.tsx +4 -4
  21. package/dist/assets/storefront/src/app/[locale]/(scenario)/[...path]/page.tsx +1 -1
  22. package/dist/assets/storefront/src/app/[locale]/accept-invitation/[token]/accept-invitation-client.tsx +8 -13
  23. package/dist/assets/storefront/src/app/[locale]/accept-invitation/[token]/actions.ts +11 -14
  24. package/dist/assets/storefront/src/app/[locale]/accept-invitation/[token]/page.tsx +30 -33
  25. package/dist/assets/storefront/src/app/[locale]/accept-invitation/[token]/sign-out-and-retry.tsx +6 -6
  26. package/dist/assets/storefront/src/app/[locale]/account/addresses/actions.ts +30 -45
  27. package/dist/assets/storefront/src/app/[locale]/account/addresses/address-form.tsx +166 -159
  28. package/dist/assets/storefront/src/app/[locale]/account/addresses/addresses-client.tsx +35 -26
  29. package/dist/assets/storefront/src/app/[locale]/account/addresses/loading.tsx +1 -3
  30. package/dist/assets/storefront/src/app/[locale]/account/addresses/page.tsx +16 -18
  31. package/dist/assets/storefront/src/app/[locale]/account/approvals/actions.ts +5 -8
  32. package/dist/assets/storefront/src/app/[locale]/account/approvals/page.tsx +77 -69
  33. package/dist/assets/storefront/src/app/[locale]/account/company/actions.ts +10 -11
  34. package/dist/assets/storefront/src/app/[locale]/account/company/addresses/actions.ts +6 -15
  35. package/dist/assets/storefront/src/app/[locale]/account/company/addresses/address-form.tsx +57 -49
  36. package/dist/assets/storefront/src/app/[locale]/account/company/addresses/addresses-client.tsx +23 -25
  37. package/dist/assets/storefront/src/app/[locale]/account/company/addresses/page.tsx +30 -30
  38. package/dist/assets/storefront/src/app/[locale]/account/company/business-units/actions.ts +20 -29
  39. package/dist/assets/storefront/src/app/[locale]/account/company/business-units/business-unit-form.tsx +32 -37
  40. package/dist/assets/storefront/src/app/[locale]/account/company/business-units/business-units-client.tsx +32 -25
  41. package/dist/assets/storefront/src/app/[locale]/account/company/business-units/page.tsx +24 -24
  42. package/dist/assets/storefront/src/app/[locale]/account/company/business-units/types.ts +7 -4
  43. package/dist/assets/storefront/src/app/[locale]/account/company/edit-company-form.tsx +11 -21
  44. package/dist/assets/storefront/src/app/[locale]/account/company/page.tsx +23 -28
  45. package/dist/assets/storefront/src/app/[locale]/account/company/payment-methods/page.tsx +24 -24
  46. package/dist/assets/storefront/src/app/[locale]/account/company/payment-methods/payment-methods-client.tsx +5 -7
  47. package/dist/assets/storefront/src/app/[locale]/account/company/roles/page.tsx +22 -25
  48. package/dist/assets/storefront/src/app/[locale]/account/company/roles/roles-client.tsx +11 -26
  49. package/dist/assets/storefront/src/app/[locale]/account/company/tax-ids/actions.ts +6 -10
  50. package/dist/assets/storefront/src/app/[locale]/account/company/tax-ids/page.tsx +18 -16
  51. package/dist/assets/storefront/src/app/[locale]/account/company/tax-ids/tax-ids-client.tsx +74 -67
  52. package/dist/assets/storefront/src/app/[locale]/account/company/users/actions.ts +16 -25
  53. package/dist/assets/storefront/src/app/[locale]/account/company/users/edit-user-form.tsx +27 -25
  54. package/dist/assets/storefront/src/app/[locale]/account/company/users/invite-user-form.tsx +27 -19
  55. package/dist/assets/storefront/src/app/[locale]/account/company/users/page.tsx +32 -29
  56. package/dist/assets/storefront/src/app/[locale]/account/company/users/users-client.tsx +35 -38
  57. package/dist/assets/storefront/src/app/[locale]/account/error.tsx +1 -3
  58. package/dist/assets/storefront/src/app/[locale]/account/layout.tsx +16 -22
  59. package/dist/assets/storefront/src/app/[locale]/account/orders/[code]/page.tsx +151 -103
  60. package/dist/assets/storefront/src/app/[locale]/account/orders/[code]/reorder-actions.ts +6 -7
  61. package/dist/assets/storefront/src/app/[locale]/account/orders/[code]/reorder-dialog.tsx +22 -48
  62. package/dist/assets/storefront/src/app/[locale]/account/orders/loading.tsx +8 -8
  63. package/dist/assets/storefront/src/app/[locale]/account/orders/page.tsx +101 -61
  64. package/dist/assets/storefront/src/app/[locale]/account/profile/actions.ts +32 -23
  65. package/dist/assets/storefront/src/app/[locale]/account/profile/change-password-form.tsx +6 -16
  66. package/dist/assets/storefront/src/app/[locale]/account/profile/edit-email-form.tsx +7 -17
  67. package/dist/assets/storefront/src/app/[locale]/account/profile/edit-profile-form.tsx +6 -16
  68. package/dist/assets/storefront/src/app/[locale]/account/profile/loading.tsx +12 -18
  69. package/dist/assets/storefront/src/app/[locale]/account/profile/page.tsx +15 -15
  70. package/dist/assets/storefront/src/app/[locale]/account/quick-order/file-upload-tab.tsx +2 -6
  71. package/dist/assets/storefront/src/app/[locale]/account/quick-order/manual-entry-tab.tsx +18 -15
  72. package/dist/assets/storefront/src/app/[locale]/account/quick-order/page.tsx +3 -6
  73. package/dist/assets/storefront/src/app/[locale]/account/quick-order/preview-table.tsx +10 -2
  74. package/dist/assets/storefront/src/app/[locale]/account/quick-order/save-to-list-dialog.tsx +24 -26
  75. package/dist/assets/storefront/src/app/[locale]/account/quick-order/sku-autocomplete.tsx +19 -10
  76. package/dist/assets/storefront/src/app/[locale]/account/quick-order/text-input-tab.tsx +3 -8
  77. package/dist/assets/storefront/src/app/[locale]/account/quotes/[id]/page.tsx +86 -59
  78. package/dist/assets/storefront/src/app/[locale]/account/quotes/actions.ts +38 -45
  79. package/dist/assets/storefront/src/app/[locale]/account/quotes/new/new-quote-form.tsx +3 -5
  80. package/dist/assets/storefront/src/app/[locale]/account/quotes/new/page.tsx +6 -6
  81. package/dist/assets/storefront/src/app/[locale]/account/quotes/page.tsx +92 -59
  82. package/dist/assets/storefront/src/app/[locale]/account/shared-carts/[id]/activity-feed.tsx +152 -0
  83. package/dist/assets/storefront/src/app/[locale]/account/shared-carts/[id]/add-item-search.tsx +132 -0
  84. package/dist/assets/storefront/src/app/[locale]/account/shared-carts/[id]/add-member-form.tsx +140 -0
  85. package/dist/assets/storefront/src/app/[locale]/account/shared-carts/[id]/members-panel.tsx +259 -0
  86. package/dist/assets/storefront/src/app/[locale]/account/shared-carts/[id]/page.tsx +55 -0
  87. package/dist/assets/storefront/src/app/[locale]/account/shared-carts/[id]/rename-dialog.tsx +117 -0
  88. package/dist/assets/storefront/src/app/[locale]/account/shared-carts/[id]/shared-cart-detail-client.tsx +555 -0
  89. package/dist/assets/storefront/src/app/[locale]/account/shared-carts/actions.ts +305 -0
  90. package/dist/assets/storefront/src/app/[locale]/account/shared-carts/new/new-shared-cart-form.tsx +84 -0
  91. package/dist/assets/storefront/src/app/[locale]/account/shared-carts/new/page.tsx +47 -0
  92. package/dist/assets/storefront/src/app/[locale]/account/shared-carts/page.tsx +276 -0
  93. package/dist/assets/storefront/src/app/[locale]/account/shopping-lists/[id]/page.tsx +22 -8
  94. package/dist/assets/storefront/src/app/[locale]/account/shopping-lists/[id]/shopping-list-detail-client.tsx +62 -49
  95. package/dist/assets/storefront/src/app/[locale]/account/shopping-lists/actions.ts +9 -4
  96. package/dist/assets/storefront/src/app/[locale]/account/shopping-lists/create-shopping-list-form.tsx +5 -11
  97. package/dist/assets/storefront/src/app/[locale]/account/shopping-lists/loading.tsx +1 -1
  98. package/dist/assets/storefront/src/app/[locale]/account/shopping-lists/page.tsx +32 -42
  99. package/dist/assets/storefront/src/app/[locale]/account/store-credits/actions.ts +8 -8
  100. package/dist/assets/storefront/src/app/[locale]/account/store-credits/claim-form.tsx +6 -10
  101. package/dist/assets/storefront/src/app/[locale]/account/store-credits/page.tsx +76 -55
  102. package/dist/assets/storefront/src/app/[locale]/account/store-credits/reveal-code.tsx +10 -6
  103. package/dist/assets/storefront/src/app/[locale]/account/verify-email/page.tsx +32 -39
  104. package/dist/assets/storefront/src/app/[locale]/cart/actions.ts +29 -23
  105. package/dist/assets/storefront/src/app/[locale]/cart/cart-items.tsx +111 -40
  106. package/dist/assets/storefront/src/app/[locale]/cart/cart-line-actions.tsx +9 -9
  107. package/dist/assets/storefront/src/app/[locale]/cart/cart-quantity-control.tsx +61 -48
  108. package/dist/assets/storefront/src/app/[locale]/cart/cart-remove-button.tsx +15 -9
  109. package/dist/assets/storefront/src/app/[locale]/cart/cart.tsx +38 -41
  110. package/dist/assets/storefront/src/app/[locale]/cart/code-input.tsx +8 -8
  111. package/dist/assets/storefront/src/app/[locale]/cart/order-summary.tsx +70 -29
  112. package/dist/assets/storefront/src/app/[locale]/cart/page.tsx +11 -11
  113. package/dist/assets/storefront/src/app/[locale]/cart/promotion-code.tsx +48 -42
  114. package/dist/assets/storefront/src/app/[locale]/cart/reapproval-confirm.tsx +22 -20
  115. package/dist/assets/storefront/src/app/[locale]/cart/request-quote-button.tsx +7 -16
  116. package/dist/assets/storefront/src/app/[locale]/checkout/actions.ts +39 -65
  117. package/dist/assets/storefront/src/app/[locale]/checkout/cancel-quote-checkout-button.tsx +5 -5
  118. package/dist/assets/storefront/src/app/[locale]/checkout/checkout-flow.tsx +202 -202
  119. package/dist/assets/storefront/src/app/[locale]/checkout/checkout-provider.tsx +142 -142
  120. package/dist/assets/storefront/src/app/[locale]/checkout/order-summary.tsx +158 -139
  121. package/dist/assets/storefront/src/app/[locale]/checkout/page.tsx +56 -47
  122. package/dist/assets/storefront/src/app/[locale]/checkout/steps/delivery-step.tsx +86 -88
  123. package/dist/assets/storefront/src/app/[locale]/checkout/steps/payment-step.tsx +90 -91
  124. package/dist/assets/storefront/src/app/[locale]/checkout/steps/review-step.tsx +166 -161
  125. package/dist/assets/storefront/src/app/[locale]/checkout/steps/shipping-address-step.tsx +573 -494
  126. package/dist/assets/storefront/src/app/[locale]/error.tsx +3 -5
  127. package/dist/assets/storefront/src/app/[locale]/forgot-password/actions.ts +10 -7
  128. package/dist/assets/storefront/src/app/[locale]/forgot-password/forgot-password-form.tsx +10 -25
  129. package/dist/assets/storefront/src/app/[locale]/forgot-password/page.tsx +5 -5
  130. package/dist/assets/storefront/src/app/[locale]/globals.css +48 -48
  131. package/dist/assets/storefront/src/app/[locale]/layout.tsx +53 -47
  132. package/dist/assets/storefront/src/app/[locale]/not-found.tsx +3 -5
  133. package/dist/assets/storefront/src/app/[locale]/order-confirmation/[code]/order-confirmation.tsx +71 -44
  134. package/dist/assets/storefront/src/app/[locale]/order-confirmation/[code]/page.tsx +7 -5
  135. package/dist/assets/storefront/src/app/[locale]/page.tsx +33 -35
  136. package/dist/assets/storefront/src/app/[locale]/register/actions.ts +7 -7
  137. package/dist/assets/storefront/src/app/[locale]/register/page.tsx +22 -16
  138. package/dist/assets/storefront/src/app/[locale]/register/registration-form.tsx +22 -34
  139. package/dist/assets/storefront/src/app/[locale]/register-company/actions.ts +15 -19
  140. package/dist/assets/storefront/src/app/[locale]/register-company/page.tsx +17 -15
  141. package/dist/assets/storefront/src/app/[locale]/register-company/registration-form.tsx +9 -15
  142. package/dist/assets/storefront/src/app/[locale]/reset-password/actions.ts +7 -8
  143. package/dist/assets/storefront/src/app/[locale]/reset-password/page.tsx +18 -12
  144. package/dist/assets/storefront/src/app/[locale]/reset-password/reset-password-form.tsx +8 -16
  145. package/dist/assets/storefront/src/app/[locale]/shopping-list/[code]/add-to-cart-button.tsx +10 -4
  146. package/dist/assets/storefront/src/app/[locale]/shopping-list/[code]/page.tsx +62 -30
  147. package/dist/assets/storefront/src/app/[locale]/sign-in/actions.ts +14 -16
  148. package/dist/assets/storefront/src/app/[locale]/sign-in/login-form.tsx +17 -30
  149. package/dist/assets/storefront/src/app/[locale]/sign-in/page.tsx +35 -30
  150. package/dist/assets/storefront/src/app/[locale]/verify/actions.ts +8 -8
  151. package/dist/assets/storefront/src/app/[locale]/verify/page.tsx +18 -14
  152. package/dist/assets/storefront/src/app/[locale]/verify/verify-content.tsx +25 -27
  153. package/dist/assets/storefront/src/app/[locale]/verify-pending/page.tsx +23 -23
  154. package/dist/assets/storefront/src/app/api/clear-company-context/route.ts +6 -3
  155. package/dist/assets/storefront/src/app/api/revalidate/route.ts +19 -28
  156. package/dist/assets/storefront/src/app/api/search-analytics/route.ts +1 -1
  157. package/dist/assets/storefront/src/components/commerce/account-nav-items.ts +44 -17
  158. package/dist/assets/storefront/src/components/commerce/account-sidebar.tsx +30 -22
  159. package/dist/assets/storefront/src/components/commerce/active-filters.tsx +1 -1
  160. package/dist/assets/storefront/src/components/commerce/add-to-shared-cart.tsx +247 -0
  161. package/dist/assets/storefront/src/components/commerce/approval-decision-form.tsx +9 -13
  162. package/dist/assets/storefront/src/components/commerce/approval-status-badge.tsx +23 -15
  163. package/dist/assets/storefront/src/components/commerce/business-unit-switcher.tsx +11 -11
  164. package/dist/assets/storefront/src/components/commerce/catalog-search-bar.tsx +2 -2
  165. package/dist/assets/storefront/src/components/commerce/category-product-section.tsx +28 -16
  166. package/dist/assets/storefront/src/components/commerce/category-sidebar.tsx +31 -18
  167. package/dist/assets/storefront/src/components/commerce/collection-hero-banner.tsx +2 -4
  168. package/dist/assets/storefront/src/components/commerce/company-state-badge.tsx +10 -16
  169. package/dist/assets/storefront/src/components/commerce/company-switcher.tsx +12 -12
  170. package/dist/assets/storefront/src/components/commerce/configurator-form.tsx +188 -79
  171. package/dist/assets/storefront/src/components/commerce/facet-filters.tsx +29 -49
  172. package/dist/assets/storefront/src/components/commerce/gift-card-pdp.tsx +4 -4
  173. package/dist/assets/storefront/src/components/commerce/gift-card-product-info.tsx +20 -30
  174. package/dist/assets/storefront/src/components/commerce/instant-search-dropdown.tsx +258 -227
  175. package/dist/assets/storefront/src/components/commerce/order-status-badge.tsx +27 -19
  176. package/dist/assets/storefront/src/components/commerce/packaging-unit-selector.tsx +27 -26
  177. package/dist/assets/storefront/src/components/commerce/permission-gate.tsx +4 -4
  178. package/dist/assets/storefront/src/components/commerce/price-range-filter.tsx +5 -5
  179. package/dist/assets/storefront/src/components/commerce/price-tiers.tsx +38 -21
  180. package/dist/assets/storefront/src/components/commerce/price.tsx +3 -3
  181. package/dist/assets/storefront/src/components/commerce/product-card-list.tsx +35 -14
  182. package/dist/assets/storefront/src/components/commerce/product-card.tsx +31 -16
  183. package/dist/assets/storefront/src/components/commerce/product-carousel.tsx +20 -12
  184. package/dist/assets/storefront/src/components/commerce/product-grid.tsx +14 -13
  185. package/dist/assets/storefront/src/components/commerce/product-image-carousel.tsx +10 -8
  186. package/dist/assets/storefront/src/components/commerce/product-info.tsx +129 -72
  187. package/dist/assets/storefront/src/components/commerce/product-list-expansion.tsx +102 -74
  188. package/dist/assets/storefront/src/components/commerce/product-list-view.tsx +1 -1
  189. package/dist/assets/storefront/src/components/commerce/product-sidebar.tsx +36 -11
  190. package/dist/assets/storefront/src/components/commerce/product-view-switcher.tsx +33 -21
  191. package/dist/assets/storefront/src/components/commerce/quote-action-buttons.tsx +54 -36
  192. package/dist/assets/storefront/src/components/commerce/quote-activity-timeline.tsx +126 -50
  193. package/dist/assets/storefront/src/components/commerce/quote-comment-form.tsx +9 -13
  194. package/dist/assets/storefront/src/components/commerce/quote-csv-export-button.tsx +6 -6
  195. package/dist/assets/storefront/src/components/commerce/quote-product-search.tsx +22 -18
  196. package/dist/assets/storefront/src/components/commerce/quote-request-form.tsx +28 -27
  197. package/dist/assets/storefront/src/components/commerce/quote-status-badge.tsx +26 -18
  198. package/dist/assets/storefront/src/components/commerce/quote-validity-indicator.tsx +7 -7
  199. package/dist/assets/storefront/src/components/commerce/quote-version-comparison.tsx +50 -30
  200. package/dist/assets/storefront/src/components/commerce/related-products.tsx +37 -28
  201. package/dist/assets/storefront/src/components/commerce/shared-cart-role.ts +39 -0
  202. package/dist/assets/storefront/src/components/commerce/shared-cart-status-badge.tsx +28 -0
  203. package/dist/assets/storefront/src/components/commerce/shop-by-category.tsx +8 -7
  204. package/dist/assets/storefront/src/components/commerce/shopping-list-toggle.tsx +14 -20
  205. package/dist/assets/storefront/src/components/commerce/sort-dropdown.tsx +9 -16
  206. package/dist/assets/storefront/src/components/commerce/store-credit-summary.tsx +30 -32
  207. package/dist/assets/storefront/src/components/commerce/subcollection-tiles.tsx +11 -13
  208. package/dist/assets/storefront/src/components/layout/auth-page-shell.tsx +2 -2
  209. package/dist/assets/storefront/src/components/layout/draft-mode-indicator.tsx +2 -7
  210. package/dist/assets/storefront/src/components/layout/draft-mode-link.tsx +4 -2
  211. package/dist/assets/storefront/src/components/layout/footer.tsx +70 -28
  212. package/dist/assets/storefront/src/components/layout/navbar/actions.ts +9 -12
  213. package/dist/assets/storefront/src/components/layout/navbar/cart-icon.tsx +9 -9
  214. package/dist/assets/storefront/src/components/layout/navbar/channel-picker-wrapper.tsx +4 -9
  215. package/dist/assets/storefront/src/components/layout/navbar/channel-picker.tsx +13 -8
  216. package/dist/assets/storefront/src/components/layout/navbar/currency-picker-wrapper.tsx +4 -4
  217. package/dist/assets/storefront/src/components/layout/navbar/currency-picker.tsx +11 -6
  218. package/dist/assets/storefront/src/components/layout/navbar/language-picker.tsx +7 -7
  219. package/dist/assets/storefront/src/components/layout/navbar/login-button.tsx +24 -21
  220. package/dist/assets/storefront/src/components/layout/navbar/mobile-nav.tsx +8 -8
  221. package/dist/assets/storefront/src/components/layout/navbar/nav-menu-items.tsx +4 -6
  222. package/dist/assets/storefront/src/components/layout/navbar/navbar-cart.tsx +1 -1
  223. package/dist/assets/storefront/src/components/layout/navbar/navbar-collections.tsx +41 -42
  224. package/dist/assets/storefront/src/components/layout/navbar/navbar-link.tsx +7 -10
  225. package/dist/assets/storefront/src/components/layout/navbar/navbar-user.tsx +18 -23
  226. package/dist/assets/storefront/src/components/layout/navbar/theme-switcher.tsx +9 -9
  227. package/dist/assets/storefront/src/components/layout/navbar.tsx +36 -31
  228. package/dist/assets/storefront/src/components/layout/search-input.tsx +35 -32
  229. package/dist/assets/storefront/src/components/providers/awaiting-approval-banner.tsx +12 -10
  230. package/dist/assets/storefront/src/components/providers/cart-count-server.tsx +14 -12
  231. package/dist/assets/storefront/src/components/providers/company-context-guard.tsx +4 -4
  232. package/dist/assets/storefront/src/components/providers/company-permissions-server.tsx +2 -6
  233. package/dist/assets/storefront/src/components/providers/theme-provider.tsx +3 -3
  234. package/dist/assets/storefront/src/components/shared/breadcrumbs.tsx +4 -1
  235. package/dist/assets/storefront/src/components/shared/country-select.tsx +63 -67
  236. package/dist/assets/storefront/src/components/shared/pagination.tsx +15 -28
  237. package/dist/assets/storefront/src/components/shared/prefetch-link.tsx +1 -1
  238. package/dist/assets/storefront/src/components/shared/skeletons/search-input-skeleton.tsx +1 -3
  239. package/dist/assets/storefront/src/components/ui/accordion.tsx +46 -51
  240. package/dist/assets/storefront/src/components/ui/alert-dialog.tsx +94 -121
  241. package/dist/assets/storefront/src/components/ui/alert.tsx +48 -54
  242. package/dist/assets/storefront/src/components/ui/aspect-ratio.tsx +5 -7
  243. package/dist/assets/storefront/src/components/ui/avatar.tsx +29 -44
  244. package/dist/assets/storefront/src/components/ui/badge.tsx +28 -37
  245. package/dist/assets/storefront/src/components/ui/breadcrumb.tsx +82 -89
  246. package/dist/assets/storefront/src/components/ui/button.tsx +43 -49
  247. package/dist/assets/storefront/src/components/ui/calendar.tsx +157 -198
  248. package/dist/assets/storefront/src/components/ui/card.tsx +53 -76
  249. package/dist/assets/storefront/src/components/ui/carousel.tsx +194 -212
  250. package/dist/assets/storefront/src/components/ui/chart.tsx +274 -317
  251. package/dist/assets/storefront/src/components/ui/checkbox.tsx +24 -27
  252. package/dist/assets/storefront/src/components/ui/collapsible.tsx +9 -21
  253. package/dist/assets/storefront/src/components/ui/command.tsx +114 -159
  254. package/dist/assets/storefront/src/components/ui/context-menu.tsx +167 -199
  255. package/dist/assets/storefront/src/components/ui/dialog.tsx +97 -114
  256. package/dist/assets/storefront/src/components/ui/drawer.tsx +93 -107
  257. package/dist/assets/storefront/src/components/ui/dropdown-menu.tsx +171 -206
  258. package/dist/assets/storefront/src/components/ui/empty-state.tsx +5 -5
  259. package/dist/assets/storefront/src/components/ui/field.tsx +196 -208
  260. package/dist/assets/storefront/src/components/ui/form.tsx +115 -139
  261. package/dist/assets/storefront/src/components/ui/hover-card.tsx +27 -33
  262. package/dist/assets/storefront/src/components/ui/input-otp.tsx +50 -59
  263. package/dist/assets/storefront/src/components/ui/input.tsx +17 -17
  264. package/dist/assets/storefront/src/components/ui/kbd-shortcut.tsx +3 -1
  265. package/dist/assets/storefront/src/components/ui/label.tsx +16 -19
  266. package/dist/assets/storefront/src/components/ui/menubar.tsx +193 -223
  267. package/dist/assets/storefront/src/components/ui/navigation-menu.tsx +123 -130
  268. package/dist/assets/storefront/src/components/ui/pagination.tsx +87 -108
  269. package/dist/assets/storefront/src/components/ui/popover.tsx +29 -35
  270. package/dist/assets/storefront/src/components/ui/progress.tsx +19 -26
  271. package/dist/assets/storefront/src/components/ui/radio-group.tsx +32 -38
  272. package/dist/assets/storefront/src/components/ui/resizable.tsx +37 -42
  273. package/dist/assets/storefront/src/components/ui/scroll-area.tsx +41 -47
  274. package/dist/assets/storefront/src/components/ui/select.tsx +130 -152
  275. package/dist/assets/storefront/src/components/ui/separator.tsx +21 -21
  276. package/dist/assets/storefront/src/components/ui/sheet.tsx +90 -111
  277. package/dist/assets/storefront/src/components/ui/sidebar.tsx +611 -649
  278. package/dist/assets/storefront/src/components/ui/skeleton.tsx +10 -10
  279. package/dist/assets/storefront/src/components/ui/slider.tsx +50 -55
  280. package/dist/assets/storefront/src/components/ui/sonner.tsx +20 -20
  281. package/dist/assets/storefront/src/components/ui/switch.tsx +23 -26
  282. package/dist/assets/storefront/src/components/ui/table.tsx +65 -97
  283. package/dist/assets/storefront/src/components/ui/tabs.tsx +39 -55
  284. package/dist/assets/storefront/src/components/ui/textarea.tsx +14 -14
  285. package/dist/assets/storefront/src/components/ui/toggle-group.tsx +56 -62
  286. package/dist/assets/storefront/src/components/ui/toggle.tsx +37 -38
  287. package/dist/assets/storefront/src/components/ui/tooltip.tsx +38 -46
  288. package/dist/assets/storefront/src/config/scenario-meta.ts +2 -2
  289. package/dist/assets/storefront/src/config/scenario.ts +14 -16
  290. package/dist/assets/storefront/src/contexts/auth-context.tsx +5 -6
  291. package/dist/assets/storefront/src/graphql-env.d.ts +18 -5
  292. package/dist/assets/storefront/src/graphql.ts +5 -5
  293. package/dist/assets/storefront/src/hooks/use-mobile.ts +13 -13
  294. package/dist/assets/storefront/src/i18n/locale-utils.ts +3 -3
  295. package/dist/assets/storefront/src/i18n/navigation.ts +4 -4
  296. package/dist/assets/storefront/src/i18n/request.ts +4 -4
  297. package/dist/assets/storefront/src/i18n/routing.ts +5 -5
  298. package/dist/assets/storefront/src/i18n/server.ts +3 -3
  299. package/dist/assets/storefront/src/lib/actions/switch-channel.ts +9 -9
  300. package/dist/assets/storefront/src/lib/actions/switch-currency.ts +7 -7
  301. package/dist/assets/storefront/src/lib/auth.ts +1 -1
  302. package/dist/assets/storefront/src/lib/backend-health.ts +3 -3
  303. package/dist/assets/storefront/src/lib/cart-count-context.tsx +10 -4
  304. package/dist/assets/storefront/src/lib/cart-guard-utils.ts +2 -1
  305. package/dist/assets/storefront/src/lib/cart-guard.ts +7 -6
  306. package/dist/assets/storefront/src/lib/channel-server.ts +4 -4
  307. package/dist/assets/storefront/src/lib/company-context.ts +1 -1
  308. package/dist/assets/storefront/src/lib/company-permissions-context.tsx +1 -5
  309. package/dist/assets/storefront/src/lib/currency-server.ts +4 -4
  310. package/dist/assets/storefront/src/lib/format.ts +16 -7
  311. package/dist/assets/storefront/src/lib/metadata.ts +39 -44
  312. package/dist/assets/storefront/src/lib/quantity.ts +2 -4
  313. package/dist/assets/storefront/src/lib/search-bar-context.tsx +7 -4
  314. package/dist/assets/storefront/src/lib/use-recent-searches.ts +8 -6
  315. package/dist/assets/storefront/src/lib/utils.ts +3 -3
  316. package/dist/assets/storefront/src/lib/vendure/actions.ts +18 -16
  317. package/dist/assets/storefront/src/lib/vendure/api.ts +44 -27
  318. package/dist/assets/storefront/src/lib/vendure/approval-utils.ts +9 -8
  319. package/dist/assets/storefront/src/lib/vendure/cached.ts +20 -15
  320. package/dist/assets/storefront/src/lib/vendure/mutations.ts +96 -0
  321. package/dist/assets/storefront/src/lib/vendure/queries.ts +157 -5
  322. package/dist/assets/storefront/src/middleware.ts +1 -1
  323. package/dist/assets/storefront/src/scenarios/customer/hero.tsx +2 -2
  324. package/dist/assets/storefront/src/scenarios/customer/meta.ts +1 -1
  325. package/dist/assets/storefront/src/schema.graphql +134 -0
  326. package/dist/bin/run.js +1 -1
  327. package/dist/cli.d.ts +1 -1
  328. package/dist/index.d.ts +5 -5
  329. package/dist/index.js +1 -1
  330. package/dist/plugin-registry.js +1 -1
  331. package/dist/scaffold-storefront-only.js +1 -1
  332. package/dist/scaffolder.js +1 -1
  333. package/dist/template-renderer.js +1 -1
  334. package/package.json +2 -2
@@ -1,728 +1,690 @@
1
- "use client"
2
-
3
- import * as React from "react"
4
- import { Slot } from "@radix-ui/react-slot"
5
- import { cva, VariantProps } from "class-variance-authority"
6
- import { PanelLeftIcon } from "lucide-react"
7
-
8
- import { useIsMobile } from "@/hooks/use-mobile"
9
- import { cn } from "@/lib/utils"
10
- import { Button } from "@/components/ui/button"
11
- import { Input } from "@/components/ui/input"
12
- import { Separator } from "@/components/ui/separator"
13
- import {
14
- Sheet,
15
- SheetContent,
16
- SheetDescription,
17
- SheetHeader,
18
- SheetTitle,
19
- } from "@/components/ui/sheet"
20
- import { Skeleton } from "@/components/ui/skeleton"
21
- import {
22
- Tooltip,
23
- TooltipContent,
24
- TooltipProvider,
25
- TooltipTrigger,
26
- } from "@/components/ui/tooltip"
27
-
28
- const SIDEBAR_COOKIE_NAME = "sidebar_state"
29
- const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7
30
- const SIDEBAR_WIDTH = "16rem"
31
- const SIDEBAR_WIDTH_MOBILE = "18rem"
32
- const SIDEBAR_WIDTH_ICON = "3rem"
33
- const SIDEBAR_KEYBOARD_SHORTCUT = "b"
1
+ 'use client';
2
+
3
+ import { Slot } from '@radix-ui/react-slot';
4
+ import { cva, VariantProps } from 'class-variance-authority';
5
+ import { PanelLeftIcon } from 'lucide-react';
6
+ import * as React from 'react';
7
+
8
+ import { Button } from '@/components/ui/button';
9
+ import { Input } from '@/components/ui/input';
10
+ import { Separator } from '@/components/ui/separator';
11
+ import { Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle } from '@/components/ui/sheet';
12
+ import { Skeleton } from '@/components/ui/skeleton';
13
+ import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip';
14
+ import { useIsMobile } from '@/hooks/use-mobile';
15
+ import { cn } from '@/lib/utils';
16
+
17
+ const SIDEBAR_COOKIE_NAME = 'sidebar_state';
18
+ const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7;
19
+ const SIDEBAR_WIDTH = '16rem';
20
+ const SIDEBAR_WIDTH_MOBILE = '18rem';
21
+ const SIDEBAR_WIDTH_ICON = '3rem';
22
+ const SIDEBAR_KEYBOARD_SHORTCUT = 'b';
34
23
 
35
24
  type SidebarContextProps = {
36
- state: "expanded" | "collapsed"
37
- open: boolean
38
- setOpen: (open: boolean) => void
39
- openMobile: boolean
40
- setOpenMobile: (open: boolean) => void
41
- isMobile: boolean
42
- toggleSidebar: () => void
43
- }
25
+ state: 'expanded' | 'collapsed';
26
+ open: boolean;
27
+ setOpen: (open: boolean) => void;
28
+ openMobile: boolean;
29
+ setOpenMobile: (open: boolean) => void;
30
+ isMobile: boolean;
31
+ toggleSidebar: () => void;
32
+ };
44
33
 
45
- const SidebarContext = React.createContext<SidebarContextProps | null>(null)
34
+ const SidebarContext = React.createContext<SidebarContextProps | null>(null);
46
35
 
47
36
  function useSidebar() {
48
- const context = React.useContext(SidebarContext)
49
- if (!context) {
50
- throw new Error("useSidebar must be used within a SidebarProvider.")
51
- }
37
+ const context = React.useContext(SidebarContext);
38
+ if (!context) {
39
+ throw new Error('useSidebar must be used within a SidebarProvider.');
40
+ }
52
41
 
53
- return context
42
+ return context;
54
43
  }
55
44
 
56
45
  function SidebarProvider({
57
- defaultOpen = true,
58
- open: openProp,
59
- onOpenChange: setOpenProp,
60
- className,
61
- style,
62
- children,
63
- ...props
64
- }: React.ComponentProps<"div"> & {
65
- defaultOpen?: boolean
66
- open?: boolean
67
- onOpenChange?: (open: boolean) => void
46
+ defaultOpen = true,
47
+ open: openProp,
48
+ onOpenChange: setOpenProp,
49
+ className,
50
+ style,
51
+ children,
52
+ ...props
53
+ }: React.ComponentProps<'div'> & {
54
+ defaultOpen?: boolean;
55
+ open?: boolean;
56
+ onOpenChange?: (open: boolean) => void;
68
57
  }) {
69
- const isMobile = useIsMobile()
70
- const [openMobile, setOpenMobile] = React.useState(false)
71
-
72
- // This is the internal state of the sidebar.
73
- // We use openProp and setOpenProp for control from outside the component.
74
- const [_open, _setOpen] = React.useState(defaultOpen)
75
- const open = openProp ?? _open
76
- const setOpen = React.useCallback(
77
- (value: boolean | ((value: boolean) => boolean)) => {
78
- const openState = typeof value === "function" ? value(open) : value
79
- if (setOpenProp) {
80
- setOpenProp(openState)
81
- } else {
82
- _setOpen(openState)
83
- }
84
-
85
- // This sets the cookie to keep the sidebar state.
86
- document.cookie = `${SIDEBAR_COOKIE_NAME}=${openState}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}`
87
- },
88
- [setOpenProp, open]
89
- )
90
-
91
- // Helper to toggle the sidebar.
92
- const toggleSidebar = React.useCallback(() => {
93
- return isMobile ? setOpenMobile((open) => !open) : setOpen((open) => !open)
94
- }, [isMobile, setOpen, setOpenMobile])
95
-
96
- // Adds a keyboard shortcut to toggle the sidebar.
97
- React.useEffect(() => {
98
- const handleKeyDown = (event: KeyboardEvent) => {
99
- if (
100
- event.key === SIDEBAR_KEYBOARD_SHORTCUT &&
101
- (event.metaKey || event.ctrlKey)
102
- ) {
103
- event.preventDefault()
104
- toggleSidebar()
105
- }
106
- }
58
+ const isMobile = useIsMobile();
59
+ const [openMobile, setOpenMobile] = React.useState(false);
60
+
61
+ // This is the internal state of the sidebar.
62
+ // We use openProp and setOpenProp for control from outside the component.
63
+ const [_open, _setOpen] = React.useState(defaultOpen);
64
+ const open = openProp ?? _open;
65
+ const setOpen = React.useCallback(
66
+ (value: boolean | ((value: boolean) => boolean)) => {
67
+ const openState = typeof value === 'function' ? value(open) : value;
68
+ if (setOpenProp) {
69
+ setOpenProp(openState);
70
+ } else {
71
+ _setOpen(openState);
72
+ }
73
+
74
+ // This sets the cookie to keep the sidebar state.
75
+ document.cookie = `${SIDEBAR_COOKIE_NAME}=${openState}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}`;
76
+ },
77
+ [setOpenProp, open],
78
+ );
79
+
80
+ // Helper to toggle the sidebar.
81
+ const toggleSidebar = React.useCallback(() => {
82
+ return isMobile ? setOpenMobile((open) => !open) : setOpen((open) => !open);
83
+ }, [isMobile, setOpen, setOpenMobile]);
84
+
85
+ // Adds a keyboard shortcut to toggle the sidebar.
86
+ React.useEffect(() => {
87
+ const handleKeyDown = (event: KeyboardEvent) => {
88
+ if (event.key === SIDEBAR_KEYBOARD_SHORTCUT && (event.metaKey || event.ctrlKey)) {
89
+ event.preventDefault();
90
+ toggleSidebar();
91
+ }
92
+ };
93
+
94
+ window.addEventListener('keydown', handleKeyDown);
95
+ return () => window.removeEventListener('keydown', handleKeyDown);
96
+ }, [toggleSidebar]);
97
+
98
+ // We add a state so that we can do data-state="expanded" or "collapsed".
99
+ // This makes it easier to style the sidebar with Tailwind classes.
100
+ const state = open ? 'expanded' : 'collapsed';
101
+
102
+ const contextValue = React.useMemo<SidebarContextProps>(
103
+ () => ({
104
+ state,
105
+ open,
106
+ setOpen,
107
+ isMobile,
108
+ openMobile,
109
+ setOpenMobile,
110
+ toggleSidebar,
111
+ }),
112
+ [state, open, setOpen, isMobile, openMobile, setOpenMobile, toggleSidebar],
113
+ );
107
114
 
108
- window.addEventListener("keydown", handleKeyDown)
109
- return () => window.removeEventListener("keydown", handleKeyDown)
110
- }, [toggleSidebar])
111
-
112
- // We add a state so that we can do data-state="expanded" or "collapsed".
113
- // This makes it easier to style the sidebar with Tailwind classes.
114
- const state = open ? "expanded" : "collapsed"
115
-
116
- const contextValue = React.useMemo<SidebarContextProps>(
117
- () => ({
118
- state,
119
- open,
120
- setOpen,
121
- isMobile,
122
- openMobile,
123
- setOpenMobile,
124
- toggleSidebar,
125
- }),
126
- [state, open, setOpen, isMobile, openMobile, setOpenMobile, toggleSidebar]
127
- )
128
-
129
- return (
130
- <SidebarContext.Provider value={contextValue}>
131
- <TooltipProvider delayDuration={0}>
132
- <div
133
- data-slot="sidebar-wrapper"
134
- style={
135
- {
136
- "--sidebar-width": SIDEBAR_WIDTH,
137
- "--sidebar-width-icon": SIDEBAR_WIDTH_ICON,
138
- ...style,
139
- } as React.CSSProperties
140
- }
141
- className={cn(
142
- "group/sidebar-wrapper has-data-[variant=inset]:bg-sidebar flex min-h-svh w-full",
143
- className
144
- )}
145
- {...props}
146
- >
147
- {children}
148
- </div>
149
- </TooltipProvider>
150
- </SidebarContext.Provider>
151
- )
115
+ return (
116
+ <SidebarContext.Provider value={contextValue}>
117
+ <TooltipProvider delayDuration={0}>
118
+ <div
119
+ data-slot="sidebar-wrapper"
120
+ style={
121
+ {
122
+ '--sidebar-width': SIDEBAR_WIDTH,
123
+ '--sidebar-width-icon': SIDEBAR_WIDTH_ICON,
124
+ ...style,
125
+ } as React.CSSProperties
126
+ }
127
+ className={cn(
128
+ 'group/sidebar-wrapper has-data-[variant=inset]:bg-sidebar flex min-h-svh w-full',
129
+ className,
130
+ )}
131
+ {...props}
132
+ >
133
+ {children}
134
+ </div>
135
+ </TooltipProvider>
136
+ </SidebarContext.Provider>
137
+ );
152
138
  }
153
139
 
154
140
  function Sidebar({
155
- side = "left",
156
- variant = "sidebar",
157
- collapsible = "offcanvas",
158
- className,
159
- children,
160
- ...props
161
- }: React.ComponentProps<"div"> & {
162
- side?: "left" | "right"
163
- variant?: "sidebar" | "floating" | "inset"
164
- collapsible?: "offcanvas" | "icon" | "none"
141
+ side = 'left',
142
+ variant = 'sidebar',
143
+ collapsible = 'offcanvas',
144
+ className,
145
+ children,
146
+ ...props
147
+ }: React.ComponentProps<'div'> & {
148
+ side?: 'left' | 'right';
149
+ variant?: 'sidebar' | 'floating' | 'inset';
150
+ collapsible?: 'offcanvas' | 'icon' | 'none';
165
151
  }) {
166
- const { isMobile, state, openMobile, setOpenMobile } = useSidebar()
152
+ const { isMobile, state, openMobile, setOpenMobile } = useSidebar();
153
+
154
+ if (collapsible === 'none') {
155
+ return (
156
+ <div
157
+ data-slot="sidebar"
158
+ className={cn(
159
+ 'bg-sidebar text-sidebar-foreground flex h-full w-(--sidebar-width) flex-col',
160
+ className,
161
+ )}
162
+ {...props}
163
+ >
164
+ {children}
165
+ </div>
166
+ );
167
+ }
168
+
169
+ if (isMobile) {
170
+ return (
171
+ <Sheet open={openMobile} onOpenChange={setOpenMobile} {...props}>
172
+ <SheetContent
173
+ data-sidebar="sidebar"
174
+ data-slot="sidebar"
175
+ data-mobile="true"
176
+ className="bg-sidebar text-sidebar-foreground w-(--sidebar-width) p-0 [&>button]:hidden"
177
+ style={
178
+ {
179
+ '--sidebar-width': SIDEBAR_WIDTH_MOBILE,
180
+ } as React.CSSProperties
181
+ }
182
+ side={side}
183
+ >
184
+ <SheetHeader className="sr-only">
185
+ <SheetTitle>Sidebar</SheetTitle>
186
+ <SheetDescription>Displays the mobile sidebar.</SheetDescription>
187
+ </SheetHeader>
188
+ <div className="flex h-full w-full flex-col">{children}</div>
189
+ </SheetContent>
190
+ </Sheet>
191
+ );
192
+ }
167
193
 
168
- if (collapsible === "none") {
169
- return (
170
- <div
171
- data-slot="sidebar"
172
- className={cn(
173
- "bg-sidebar text-sidebar-foreground flex h-full w-(--sidebar-width) flex-col",
174
- className
175
- )}
176
- {...props}
177
- >
178
- {children}
179
- </div>
180
- )
181
- }
182
-
183
- if (isMobile) {
184
194
  return (
185
- <Sheet open={openMobile} onOpenChange={setOpenMobile} {...props}>
186
- <SheetContent
187
- data-sidebar="sidebar"
188
- data-slot="sidebar"
189
- data-mobile="true"
190
- className="bg-sidebar text-sidebar-foreground w-(--sidebar-width) p-0 [&>button]:hidden"
191
- style={
192
- {
193
- "--sidebar-width": SIDEBAR_WIDTH_MOBILE,
194
- } as React.CSSProperties
195
- }
196
- side={side}
197
- >
198
- <SheetHeader className="sr-only">
199
- <SheetTitle>Sidebar</SheetTitle>
200
- <SheetDescription>Displays the mobile sidebar.</SheetDescription>
201
- </SheetHeader>
202
- <div className="flex h-full w-full flex-col">{children}</div>
203
- </SheetContent>
204
- </Sheet>
205
- )
206
- }
207
-
208
- return (
209
- <div
210
- className="group peer text-sidebar-foreground hidden md:block"
211
- data-state={state}
212
- data-collapsible={state === "collapsed" ? collapsible : ""}
213
- data-variant={variant}
214
- data-side={side}
215
- data-slot="sidebar"
216
- >
217
- {/* This is what handles the sidebar gap on desktop */}
218
- <div
219
- data-slot="sidebar-gap"
220
- className={cn(
221
- "relative w-(--sidebar-width) bg-transparent transition-[width] duration-200 ease-linear",
222
- "group-data-[collapsible=offcanvas]:w-0",
223
- "group-data-[side=right]:rotate-180",
224
- variant === "floating" || variant === "inset"
225
- ? "group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]"
226
- : "group-data-[collapsible=icon]:w-(--sidebar-width-icon)"
227
- )}
228
- />
229
- <div
230
- data-slot="sidebar-container"
231
- className={cn(
232
- "fixed inset-y-0 z-10 hidden h-svh w-(--sidebar-width) transition-[left,right,width] duration-200 ease-linear md:flex",
233
- side === "left"
234
- ? "left-0 group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)]"
235
- : "right-0 group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)]",
236
- // Adjust the padding for floating and inset variants.
237
- variant === "floating" || variant === "inset"
238
- ? "p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4))+2px)]"
239
- : "group-data-[collapsible=icon]:w-(--sidebar-width-icon) group-data-[side=left]:border-r group-data-[side=right]:border-l",
240
- className
241
- )}
242
- {...props}
243
- >
244
195
  <div
245
- data-sidebar="sidebar"
246
- data-slot="sidebar-inner"
247
- className="bg-sidebar group-data-[variant=floating]:border-sidebar-border flex h-full w-full flex-col group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:border group-data-[variant=floating]:shadow-sm"
196
+ className="group peer text-sidebar-foreground hidden md:block"
197
+ data-state={state}
198
+ data-collapsible={state === 'collapsed' ? collapsible : ''}
199
+ data-variant={variant}
200
+ data-side={side}
201
+ data-slot="sidebar"
248
202
  >
249
- {children}
203
+ {/* This is what handles the sidebar gap on desktop */}
204
+ <div
205
+ data-slot="sidebar-gap"
206
+ className={cn(
207
+ 'relative w-(--sidebar-width) bg-transparent transition-[width] duration-200 ease-linear',
208
+ 'group-data-[collapsible=offcanvas]:w-0',
209
+ 'group-data-[side=right]:rotate-180',
210
+ variant === 'floating' || variant === 'inset'
211
+ ? 'group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]'
212
+ : 'group-data-[collapsible=icon]:w-(--sidebar-width-icon)',
213
+ )}
214
+ />
215
+ <div
216
+ data-slot="sidebar-container"
217
+ className={cn(
218
+ 'fixed inset-y-0 z-10 hidden h-svh w-(--sidebar-width) transition-[left,right,width] duration-200 ease-linear md:flex',
219
+ side === 'left'
220
+ ? 'left-0 group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)]'
221
+ : 'right-0 group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)]',
222
+ // Adjust the padding for floating and inset variants.
223
+ variant === 'floating' || variant === 'inset'
224
+ ? 'p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4))+2px)]'
225
+ : 'group-data-[collapsible=icon]:w-(--sidebar-width-icon) group-data-[side=left]:border-r group-data-[side=right]:border-l',
226
+ className,
227
+ )}
228
+ {...props}
229
+ >
230
+ <div
231
+ data-sidebar="sidebar"
232
+ data-slot="sidebar-inner"
233
+ className="bg-sidebar group-data-[variant=floating]:border-sidebar-border flex h-full w-full flex-col group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:border group-data-[variant=floating]:shadow-sm"
234
+ >
235
+ {children}
236
+ </div>
237
+ </div>
250
238
  </div>
251
- </div>
252
- </div>
253
- )
239
+ );
254
240
  }
255
241
 
256
- function SidebarTrigger({
257
- className,
258
- onClick,
259
- ...props
260
- }: React.ComponentProps<typeof Button>) {
261
- const { toggleSidebar } = useSidebar()
262
-
263
- return (
264
- <Button
265
- data-sidebar="trigger"
266
- data-slot="sidebar-trigger"
267
- variant="ghost"
268
- size="icon"
269
- className={cn("size-7", className)}
270
- onClick={(event) => {
271
- onClick?.(event)
272
- toggleSidebar()
273
- }}
274
- {...props}
275
- >
276
- <PanelLeftIcon />
277
- <span className="sr-only">Toggle Sidebar</span>
278
- </Button>
279
- )
242
+ function SidebarTrigger({ className, onClick, ...props }: React.ComponentProps<typeof Button>) {
243
+ const { toggleSidebar } = useSidebar();
244
+
245
+ return (
246
+ <Button
247
+ data-sidebar="trigger"
248
+ data-slot="sidebar-trigger"
249
+ variant="ghost"
250
+ size="icon"
251
+ className={cn('size-7', className)}
252
+ onClick={(event) => {
253
+ onClick?.(event);
254
+ toggleSidebar();
255
+ }}
256
+ {...props}
257
+ >
258
+ <PanelLeftIcon />
259
+ <span className="sr-only">Toggle Sidebar</span>
260
+ </Button>
261
+ );
280
262
  }
281
263
 
282
- function SidebarRail({ className, ...props }: React.ComponentProps<"button">) {
283
- const { toggleSidebar } = useSidebar()
284
-
285
- return (
286
- <button
287
- data-sidebar="rail"
288
- data-slot="sidebar-rail"
289
- aria-label="Toggle Sidebar"
290
- tabIndex={-1}
291
- onClick={toggleSidebar}
292
- title="Toggle Sidebar"
293
- className={cn(
294
- "hover:after:bg-sidebar-border absolute inset-y-0 z-20 hidden w-4 -translate-x-1/2 transition-all ease-linear group-data-[side=left]:-right-4 group-data-[side=right]:left-0 after:absolute after:inset-y-0 after:left-1/2 after:w-[2px] sm:flex",
295
- "in-data-[side=left]:cursor-w-resize in-data-[side=right]:cursor-e-resize",
296
- "[[data-side=left][data-state=collapsed]_&]:cursor-e-resize [[data-side=right][data-state=collapsed]_&]:cursor-w-resize",
297
- "hover:group-data-[collapsible=offcanvas]:bg-sidebar group-data-[collapsible=offcanvas]:translate-x-0 group-data-[collapsible=offcanvas]:after:left-full",
298
- "[[data-side=left][data-collapsible=offcanvas]_&]:-right-2",
299
- "[[data-side=right][data-collapsible=offcanvas]_&]:-left-2",
300
- className
301
- )}
302
- {...props}
303
- />
304
- )
264
+ function SidebarRail({ className, ...props }: React.ComponentProps<'button'>) {
265
+ const { toggleSidebar } = useSidebar();
266
+
267
+ return (
268
+ <button
269
+ data-sidebar="rail"
270
+ data-slot="sidebar-rail"
271
+ aria-label="Toggle Sidebar"
272
+ tabIndex={-1}
273
+ onClick={toggleSidebar}
274
+ title="Toggle Sidebar"
275
+ className={cn(
276
+ 'hover:after:bg-sidebar-border absolute inset-y-0 z-20 hidden w-4 -translate-x-1/2 transition-all ease-linear group-data-[side=left]:-right-4 group-data-[side=right]:left-0 after:absolute after:inset-y-0 after:left-1/2 after:w-[2px] sm:flex',
277
+ 'in-data-[side=left]:cursor-w-resize in-data-[side=right]:cursor-e-resize',
278
+ '[[data-side=left][data-state=collapsed]_&]:cursor-e-resize [[data-side=right][data-state=collapsed]_&]:cursor-w-resize',
279
+ 'hover:group-data-[collapsible=offcanvas]:bg-sidebar group-data-[collapsible=offcanvas]:translate-x-0 group-data-[collapsible=offcanvas]:after:left-full',
280
+ '[[data-side=left][data-collapsible=offcanvas]_&]:-right-2',
281
+ '[[data-side=right][data-collapsible=offcanvas]_&]:-left-2',
282
+ className,
283
+ )}
284
+ {...props}
285
+ />
286
+ );
305
287
  }
306
288
 
307
- function SidebarInset({ className, ...props }: React.ComponentProps<"main">) {
308
- return (
309
- <main
310
- data-slot="sidebar-inset"
311
- className={cn(
312
- "bg-background relative flex w-full flex-1 flex-col",
313
- "md:peer-data-[variant=inset]:m-2 md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:rounded-xl md:peer-data-[variant=inset]:shadow-sm md:peer-data-[variant=inset]:peer-data-[state=collapsed]:ml-2",
314
- className
315
- )}
316
- {...props}
317
- />
318
- )
289
+ function SidebarInset({ className, ...props }: React.ComponentProps<'main'>) {
290
+ return (
291
+ <main
292
+ data-slot="sidebar-inset"
293
+ className={cn(
294
+ 'bg-background relative flex w-full flex-1 flex-col',
295
+ 'md:peer-data-[variant=inset]:m-2 md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:rounded-xl md:peer-data-[variant=inset]:shadow-sm md:peer-data-[variant=inset]:peer-data-[state=collapsed]:ml-2',
296
+ className,
297
+ )}
298
+ {...props}
299
+ />
300
+ );
319
301
  }
320
302
 
321
- function SidebarInput({
322
- className,
323
- ...props
324
- }: React.ComponentProps<typeof Input>) {
325
- return (
326
- <Input
327
- data-slot="sidebar-input"
328
- data-sidebar="input"
329
- className={cn("bg-background h-8 w-full shadow-none", className)}
330
- {...props}
331
- />
332
- )
303
+ function SidebarInput({ className, ...props }: React.ComponentProps<typeof Input>) {
304
+ return (
305
+ <Input
306
+ data-slot="sidebar-input"
307
+ data-sidebar="input"
308
+ className={cn('bg-background h-8 w-full shadow-none', className)}
309
+ {...props}
310
+ />
311
+ );
333
312
  }
334
313
 
335
- function SidebarHeader({ className, ...props }: React.ComponentProps<"div">) {
336
- return (
337
- <div
338
- data-slot="sidebar-header"
339
- data-sidebar="header"
340
- className={cn("flex flex-col gap-2 p-2", className)}
341
- {...props}
342
- />
343
- )
314
+ function SidebarHeader({ className, ...props }: React.ComponentProps<'div'>) {
315
+ return (
316
+ <div
317
+ data-slot="sidebar-header"
318
+ data-sidebar="header"
319
+ className={cn('flex flex-col gap-2 p-2', className)}
320
+ {...props}
321
+ />
322
+ );
344
323
  }
345
324
 
346
- function SidebarFooter({ className, ...props }: React.ComponentProps<"div">) {
347
- return (
348
- <div
349
- data-slot="sidebar-footer"
350
- data-sidebar="footer"
351
- className={cn("flex flex-col gap-2 p-2", className)}
352
- {...props}
353
- />
354
- )
325
+ function SidebarFooter({ className, ...props }: React.ComponentProps<'div'>) {
326
+ return (
327
+ <div
328
+ data-slot="sidebar-footer"
329
+ data-sidebar="footer"
330
+ className={cn('flex flex-col gap-2 p-2', className)}
331
+ {...props}
332
+ />
333
+ );
355
334
  }
356
335
 
357
- function SidebarSeparator({
358
- className,
359
- ...props
360
- }: React.ComponentProps<typeof Separator>) {
361
- return (
362
- <Separator
363
- data-slot="sidebar-separator"
364
- data-sidebar="separator"
365
- className={cn("bg-sidebar-border mx-2 w-auto", className)}
366
- {...props}
367
- />
368
- )
336
+ function SidebarSeparator({ className, ...props }: React.ComponentProps<typeof Separator>) {
337
+ return (
338
+ <Separator
339
+ data-slot="sidebar-separator"
340
+ data-sidebar="separator"
341
+ className={cn('bg-sidebar-border mx-2 w-auto', className)}
342
+ {...props}
343
+ />
344
+ );
369
345
  }
370
346
 
371
- function SidebarContent({ className, ...props }: React.ComponentProps<"div">) {
372
- return (
373
- <div
374
- data-slot="sidebar-content"
375
- data-sidebar="content"
376
- className={cn(
377
- "flex min-h-0 flex-1 flex-col gap-2 overflow-auto group-data-[collapsible=icon]:overflow-hidden",
378
- className
379
- )}
380
- {...props}
381
- />
382
- )
347
+ function SidebarContent({ className, ...props }: React.ComponentProps<'div'>) {
348
+ return (
349
+ <div
350
+ data-slot="sidebar-content"
351
+ data-sidebar="content"
352
+ className={cn(
353
+ 'flex min-h-0 flex-1 flex-col gap-2 overflow-auto group-data-[collapsible=icon]:overflow-hidden',
354
+ className,
355
+ )}
356
+ {...props}
357
+ />
358
+ );
383
359
  }
384
360
 
385
- function SidebarGroup({ className, ...props }: React.ComponentProps<"div">) {
386
- return (
387
- <div
388
- data-slot="sidebar-group"
389
- data-sidebar="group"
390
- className={cn("relative flex w-full min-w-0 flex-col p-2", className)}
391
- {...props}
392
- />
393
- )
361
+ function SidebarGroup({ className, ...props }: React.ComponentProps<'div'>) {
362
+ return (
363
+ <div
364
+ data-slot="sidebar-group"
365
+ data-sidebar="group"
366
+ className={cn('relative flex w-full min-w-0 flex-col p-2', className)}
367
+ {...props}
368
+ />
369
+ );
394
370
  }
395
371
 
396
372
  function SidebarGroupLabel({
397
- className,
398
- asChild = false,
399
- ...props
400
- }: React.ComponentProps<"div"> & { asChild?: boolean }) {
401
- const Comp = asChild ? Slot : "div"
402
-
403
- return (
404
- <Comp
405
- data-slot="sidebar-group-label"
406
- data-sidebar="group-label"
407
- className={cn(
408
- "text-sidebar-foreground/70 ring-sidebar-ring flex h-8 shrink-0 items-center rounded-md px-2 text-xs font-medium outline-hidden transition-[margin,opacity] duration-200 ease-linear focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0",
409
- "group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0",
410
- className
411
- )}
412
- {...props}
413
- />
414
- )
373
+ className,
374
+ asChild = false,
375
+ ...props
376
+ }: React.ComponentProps<'div'> & { asChild?: boolean }) {
377
+ const Comp = asChild ? Slot : 'div';
378
+
379
+ return (
380
+ <Comp
381
+ data-slot="sidebar-group-label"
382
+ data-sidebar="group-label"
383
+ className={cn(
384
+ 'text-sidebar-foreground/70 ring-sidebar-ring flex h-8 shrink-0 items-center rounded-md px-2 text-xs font-medium outline-hidden transition-[margin,opacity] duration-200 ease-linear focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0',
385
+ 'group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0',
386
+ className,
387
+ )}
388
+ {...props}
389
+ />
390
+ );
415
391
  }
416
392
 
417
393
  function SidebarGroupAction({
418
- className,
419
- asChild = false,
420
- ...props
421
- }: React.ComponentProps<"button"> & { asChild?: boolean }) {
422
- const Comp = asChild ? Slot : "button"
423
-
424
- return (
425
- <Comp
426
- data-slot="sidebar-group-action"
427
- data-sidebar="group-action"
428
- className={cn(
429
- "text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground absolute top-3.5 right-3 flex aspect-square w-5 items-center justify-center rounded-md p-0 outline-hidden transition-transform focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0",
430
- // Increases the hit area of the button on mobile.
431
- "after:absolute after:-inset-2 md:after:hidden",
432
- "group-data-[collapsible=icon]:hidden",
433
- className
434
- )}
435
- {...props}
436
- />
437
- )
394
+ className,
395
+ asChild = false,
396
+ ...props
397
+ }: React.ComponentProps<'button'> & { asChild?: boolean }) {
398
+ const Comp = asChild ? Slot : 'button';
399
+
400
+ return (
401
+ <Comp
402
+ data-slot="sidebar-group-action"
403
+ data-sidebar="group-action"
404
+ className={cn(
405
+ 'text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground absolute top-3.5 right-3 flex aspect-square w-5 items-center justify-center rounded-md p-0 outline-hidden transition-transform focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0',
406
+ // Increases the hit area of the button on mobile.
407
+ 'after:absolute after:-inset-2 md:after:hidden',
408
+ 'group-data-[collapsible=icon]:hidden',
409
+ className,
410
+ )}
411
+ {...props}
412
+ />
413
+ );
438
414
  }
439
415
 
440
- function SidebarGroupContent({
441
- className,
442
- ...props
443
- }: React.ComponentProps<"div">) {
444
- return (
445
- <div
446
- data-slot="sidebar-group-content"
447
- data-sidebar="group-content"
448
- className={cn("w-full text-sm", className)}
449
- {...props}
450
- />
451
- )
416
+ function SidebarGroupContent({ className, ...props }: React.ComponentProps<'div'>) {
417
+ return (
418
+ <div
419
+ data-slot="sidebar-group-content"
420
+ data-sidebar="group-content"
421
+ className={cn('w-full text-sm', className)}
422
+ {...props}
423
+ />
424
+ );
452
425
  }
453
426
 
454
- function SidebarMenu({ className, ...props }: React.ComponentProps<"ul">) {
455
- return (
456
- <ul
457
- data-slot="sidebar-menu"
458
- data-sidebar="menu"
459
- className={cn("flex w-full min-w-0 flex-col gap-1", className)}
460
- {...props}
461
- />
462
- )
427
+ function SidebarMenu({ className, ...props }: React.ComponentProps<'ul'>) {
428
+ return (
429
+ <ul
430
+ data-slot="sidebar-menu"
431
+ data-sidebar="menu"
432
+ className={cn('flex w-full min-w-0 flex-col gap-1', className)}
433
+ {...props}
434
+ />
435
+ );
463
436
  }
464
437
 
465
- function SidebarMenuItem({ className, ...props }: React.ComponentProps<"li">) {
466
- return (
467
- <li
468
- data-slot="sidebar-menu-item"
469
- data-sidebar="menu-item"
470
- className={cn("group/menu-item relative", className)}
471
- {...props}
472
- />
473
- )
438
+ function SidebarMenuItem({ className, ...props }: React.ComponentProps<'li'>) {
439
+ return (
440
+ <li
441
+ data-slot="sidebar-menu-item"
442
+ data-sidebar="menu-item"
443
+ className={cn('group/menu-item relative', className)}
444
+ {...props}
445
+ />
446
+ );
474
447
  }
475
448
 
476
449
  const sidebarMenuButtonVariants = cva(
477
- "peer/menu-button flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-left text-sm outline-hidden ring-sidebar-ring transition-[width,height,padding] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 group-has-data-[sidebar=menu-action]/menu-item:pr-8 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:bg-sidebar-accent data-[active=true]:font-medium data-[active=true]:text-sidebar-accent-foreground data-[state=open]:hover:bg-sidebar-accent data-[state=open]:hover:text-sidebar-accent-foreground group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0",
478
- {
479
- variants: {
480
- variant: {
481
- default: "hover:bg-sidebar-accent hover:text-sidebar-accent-foreground",
482
- outline:
483
- "bg-background shadow-[0_0_0_1px_hsl(var(--sidebar-border))] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground hover:shadow-[0_0_0_1px_hsl(var(--sidebar-accent))]",
484
- },
485
- size: {
486
- default: "h-8 text-sm",
487
- sm: "h-7 text-xs",
488
- lg: "h-12 text-sm group-data-[collapsible=icon]:p-0!",
489
- },
490
- },
491
- defaultVariants: {
492
- variant: "default",
493
- size: "default",
450
+ 'peer/menu-button flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-left text-sm outline-hidden ring-sidebar-ring transition-[width,height,padding] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 group-has-data-[sidebar=menu-action]/menu-item:pr-8 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:bg-sidebar-accent data-[active=true]:font-medium data-[active=true]:text-sidebar-accent-foreground data-[state=open]:hover:bg-sidebar-accent data-[state=open]:hover:text-sidebar-accent-foreground group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0',
451
+ {
452
+ variants: {
453
+ variant: {
454
+ default: 'hover:bg-sidebar-accent hover:text-sidebar-accent-foreground',
455
+ outline:
456
+ 'bg-background shadow-[0_0_0_1px_hsl(var(--sidebar-border))] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground hover:shadow-[0_0_0_1px_hsl(var(--sidebar-accent))]',
457
+ },
458
+ size: {
459
+ default: 'h-8 text-sm',
460
+ sm: 'h-7 text-xs',
461
+ lg: 'h-12 text-sm group-data-[collapsible=icon]:p-0!',
462
+ },
463
+ },
464
+ defaultVariants: {
465
+ variant: 'default',
466
+ size: 'default',
467
+ },
494
468
  },
495
- }
496
- )
469
+ );
497
470
 
498
471
  function SidebarMenuButton({
499
- asChild = false,
500
- isActive = false,
501
- variant = "default",
502
- size = "default",
503
- tooltip,
504
- className,
505
- ...props
506
- }: React.ComponentProps<"button"> & {
507
- asChild?: boolean
508
- isActive?: boolean
509
- tooltip?: string | React.ComponentProps<typeof TooltipContent>
472
+ asChild = false,
473
+ isActive = false,
474
+ variant = 'default',
475
+ size = 'default',
476
+ tooltip,
477
+ className,
478
+ ...props
479
+ }: React.ComponentProps<'button'> & {
480
+ asChild?: boolean;
481
+ isActive?: boolean;
482
+ tooltip?: string | React.ComponentProps<typeof TooltipContent>;
510
483
  } & VariantProps<typeof sidebarMenuButtonVariants>) {
511
- const Comp = asChild ? Slot : "button"
512
- const { isMobile, state } = useSidebar()
513
-
514
- const button = (
515
- <Comp
516
- data-slot="sidebar-menu-button"
517
- data-sidebar="menu-button"
518
- data-size={size}
519
- data-active={isActive}
520
- className={cn(sidebarMenuButtonVariants({ variant, size }), className)}
521
- {...props}
522
- />
523
- )
524
-
525
- if (!tooltip) {
526
- return button
527
- }
528
-
529
- if (typeof tooltip === "string") {
530
- tooltip = {
531
- children: tooltip,
484
+ const Comp = asChild ? Slot : 'button';
485
+ const { isMobile, state } = useSidebar();
486
+
487
+ const button = (
488
+ <Comp
489
+ data-slot="sidebar-menu-button"
490
+ data-sidebar="menu-button"
491
+ data-size={size}
492
+ data-active={isActive}
493
+ className={cn(sidebarMenuButtonVariants({ variant, size }), className)}
494
+ {...props}
495
+ />
496
+ );
497
+
498
+ if (!tooltip) {
499
+ return button;
532
500
  }
533
- }
534
-
535
- return (
536
- <Tooltip>
537
- <TooltipTrigger asChild>{button}</TooltipTrigger>
538
- <TooltipContent
539
- side="right"
540
- align="center"
541
- hidden={state !== "collapsed" || isMobile}
542
- {...tooltip}
543
- />
544
- </Tooltip>
545
- )
501
+
502
+ if (typeof tooltip === 'string') {
503
+ tooltip = {
504
+ children: tooltip,
505
+ };
506
+ }
507
+
508
+ return (
509
+ <Tooltip>
510
+ <TooltipTrigger asChild>{button}</TooltipTrigger>
511
+ <TooltipContent
512
+ side="right"
513
+ align="center"
514
+ hidden={state !== 'collapsed' || isMobile}
515
+ {...tooltip}
516
+ />
517
+ </Tooltip>
518
+ );
546
519
  }
547
520
 
548
521
  function SidebarMenuAction({
549
- className,
550
- asChild = false,
551
- showOnHover = false,
552
- ...props
553
- }: React.ComponentProps<"button"> & {
554
- asChild?: boolean
555
- showOnHover?: boolean
522
+ className,
523
+ asChild = false,
524
+ showOnHover = false,
525
+ ...props
526
+ }: React.ComponentProps<'button'> & {
527
+ asChild?: boolean;
528
+ showOnHover?: boolean;
556
529
  }) {
557
- const Comp = asChild ? Slot : "button"
558
-
559
- return (
560
- <Comp
561
- data-slot="sidebar-menu-action"
562
- data-sidebar="menu-action"
563
- className={cn(
564
- "text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground peer-hover/menu-button:text-sidebar-accent-foreground absolute top-1.5 right-1 flex aspect-square w-5 items-center justify-center rounded-md p-0 outline-hidden transition-transform focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0",
565
- // Increases the hit area of the button on mobile.
566
- "after:absolute after:-inset-2 md:after:hidden",
567
- "peer-data-[size=sm]/menu-button:top-1",
568
- "peer-data-[size=default]/menu-button:top-1.5",
569
- "peer-data-[size=lg]/menu-button:top-2.5",
570
- "group-data-[collapsible=icon]:hidden",
571
- showOnHover &&
572
- "peer-data-[active=true]/menu-button:text-sidebar-accent-foreground group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 data-[state=open]:opacity-100 md:opacity-0",
573
- className
574
- )}
575
- {...props}
576
- />
577
- )
530
+ const Comp = asChild ? Slot : 'button';
531
+
532
+ return (
533
+ <Comp
534
+ data-slot="sidebar-menu-action"
535
+ data-sidebar="menu-action"
536
+ className={cn(
537
+ 'text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground peer-hover/menu-button:text-sidebar-accent-foreground absolute top-1.5 right-1 flex aspect-square w-5 items-center justify-center rounded-md p-0 outline-hidden transition-transform focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0',
538
+ // Increases the hit area of the button on mobile.
539
+ 'after:absolute after:-inset-2 md:after:hidden',
540
+ 'peer-data-[size=sm]/menu-button:top-1',
541
+ 'peer-data-[size=default]/menu-button:top-1.5',
542
+ 'peer-data-[size=lg]/menu-button:top-2.5',
543
+ 'group-data-[collapsible=icon]:hidden',
544
+ showOnHover &&
545
+ 'peer-data-[active=true]/menu-button:text-sidebar-accent-foreground group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 data-[state=open]:opacity-100 md:opacity-0',
546
+ className,
547
+ )}
548
+ {...props}
549
+ />
550
+ );
578
551
  }
579
552
 
580
- function SidebarMenuBadge({
581
- className,
582
- ...props
583
- }: React.ComponentProps<"div">) {
584
- return (
585
- <div
586
- data-slot="sidebar-menu-badge"
587
- data-sidebar="menu-badge"
588
- className={cn(
589
- "text-sidebar-foreground pointer-events-none absolute right-1 flex h-5 min-w-5 items-center justify-center rounded-md px-1 text-xs font-medium tabular-nums select-none",
590
- "peer-hover/menu-button:text-sidebar-accent-foreground peer-data-[active=true]/menu-button:text-sidebar-accent-foreground",
591
- "peer-data-[size=sm]/menu-button:top-1",
592
- "peer-data-[size=default]/menu-button:top-1.5",
593
- "peer-data-[size=lg]/menu-button:top-2.5",
594
- "group-data-[collapsible=icon]:hidden",
595
- className
596
- )}
597
- {...props}
598
- />
599
- )
553
+ function SidebarMenuBadge({ className, ...props }: React.ComponentProps<'div'>) {
554
+ return (
555
+ <div
556
+ data-slot="sidebar-menu-badge"
557
+ data-sidebar="menu-badge"
558
+ className={cn(
559
+ 'text-sidebar-foreground pointer-events-none absolute right-1 flex h-5 min-w-5 items-center justify-center rounded-md px-1 text-xs font-medium tabular-nums select-none',
560
+ 'peer-hover/menu-button:text-sidebar-accent-foreground peer-data-[active=true]/menu-button:text-sidebar-accent-foreground',
561
+ 'peer-data-[size=sm]/menu-button:top-1',
562
+ 'peer-data-[size=default]/menu-button:top-1.5',
563
+ 'peer-data-[size=lg]/menu-button:top-2.5',
564
+ 'group-data-[collapsible=icon]:hidden',
565
+ className,
566
+ )}
567
+ {...props}
568
+ />
569
+ );
600
570
  }
601
571
 
602
572
  function SidebarMenuSkeleton({
603
- className,
604
- showIcon = false,
605
- ...props
606
- }: React.ComponentProps<"div"> & {
607
- showIcon?: boolean
573
+ className,
574
+ showIcon = false,
575
+ ...props
576
+ }: React.ComponentProps<'div'> & {
577
+ showIcon?: boolean;
608
578
  }) {
609
- // Deterministic width for skeleton placeholder.
610
- const id = React.useId()
611
- const width = React.useMemo(() => {
612
- const hash = id.split('').reduce((a, c) => a + c.charCodeAt(0), 0)
613
- return `${(hash % 40) + 50}%`
614
- }, [id])
615
-
616
- return (
617
- <div
618
- data-slot="sidebar-menu-skeleton"
619
- data-sidebar="menu-skeleton"
620
- className={cn("flex h-8 items-center gap-2 rounded-md px-2", className)}
621
- {...props}
622
- >
623
- {showIcon && (
624
- <Skeleton
625
- className="size-4 rounded-md"
626
- data-sidebar="menu-skeleton-icon"
627
- />
628
- )}
629
- <Skeleton
630
- className="h-4 max-w-(--skeleton-width) flex-1"
631
- data-sidebar="menu-skeleton-text"
632
- style={
633
- {
634
- "--skeleton-width": width,
635
- } as React.CSSProperties
636
- }
637
- />
638
- </div>
639
- )
579
+ // Deterministic width for skeleton placeholder.
580
+ const id = React.useId();
581
+ const width = React.useMemo(() => {
582
+ const hash = id.split('').reduce((a, c) => a + c.charCodeAt(0), 0);
583
+ return `${(hash % 40) + 50}%`;
584
+ }, [id]);
585
+
586
+ return (
587
+ <div
588
+ data-slot="sidebar-menu-skeleton"
589
+ data-sidebar="menu-skeleton"
590
+ className={cn('flex h-8 items-center gap-2 rounded-md px-2', className)}
591
+ {...props}
592
+ >
593
+ {showIcon && <Skeleton className="size-4 rounded-md" data-sidebar="menu-skeleton-icon" />}
594
+ <Skeleton
595
+ className="h-4 max-w-(--skeleton-width) flex-1"
596
+ data-sidebar="menu-skeleton-text"
597
+ style={
598
+ {
599
+ '--skeleton-width': width,
600
+ } as React.CSSProperties
601
+ }
602
+ />
603
+ </div>
604
+ );
640
605
  }
641
606
 
642
- function SidebarMenuSub({ className, ...props }: React.ComponentProps<"ul">) {
643
- return (
644
- <ul
645
- data-slot="sidebar-menu-sub"
646
- data-sidebar="menu-sub"
647
- className={cn(
648
- "border-sidebar-border mx-3.5 flex min-w-0 translate-x-px flex-col gap-1 border-l px-2.5 py-0.5",
649
- "group-data-[collapsible=icon]:hidden",
650
- className
651
- )}
652
- {...props}
653
- />
654
- )
607
+ function SidebarMenuSub({ className, ...props }: React.ComponentProps<'ul'>) {
608
+ return (
609
+ <ul
610
+ data-slot="sidebar-menu-sub"
611
+ data-sidebar="menu-sub"
612
+ className={cn(
613
+ 'border-sidebar-border mx-3.5 flex min-w-0 translate-x-px flex-col gap-1 border-l px-2.5 py-0.5',
614
+ 'group-data-[collapsible=icon]:hidden',
615
+ className,
616
+ )}
617
+ {...props}
618
+ />
619
+ );
655
620
  }
656
621
 
657
- function SidebarMenuSubItem({
658
- className,
659
- ...props
660
- }: React.ComponentProps<"li">) {
661
- return (
662
- <li
663
- data-slot="sidebar-menu-sub-item"
664
- data-sidebar="menu-sub-item"
665
- className={cn("group/menu-sub-item relative", className)}
666
- {...props}
667
- />
668
- )
622
+ function SidebarMenuSubItem({ className, ...props }: React.ComponentProps<'li'>) {
623
+ return (
624
+ <li
625
+ data-slot="sidebar-menu-sub-item"
626
+ data-sidebar="menu-sub-item"
627
+ className={cn('group/menu-sub-item relative', className)}
628
+ {...props}
629
+ />
630
+ );
669
631
  }
670
632
 
671
633
  function SidebarMenuSubButton({
672
- asChild = false,
673
- size = "md",
674
- isActive = false,
675
- className,
676
- ...props
677
- }: React.ComponentProps<"a"> & {
678
- asChild?: boolean
679
- size?: "sm" | "md"
680
- isActive?: boolean
634
+ asChild = false,
635
+ size = 'md',
636
+ isActive = false,
637
+ className,
638
+ ...props
639
+ }: React.ComponentProps<'a'> & {
640
+ asChild?: boolean;
641
+ size?: 'sm' | 'md';
642
+ isActive?: boolean;
681
643
  }) {
682
- const Comp = asChild ? Slot : "a"
683
-
684
- return (
685
- <Comp
686
- data-slot="sidebar-menu-sub-button"
687
- data-sidebar="menu-sub-button"
688
- data-size={size}
689
- data-active={isActive}
690
- className={cn(
691
- "text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground active:bg-sidebar-accent active:text-sidebar-accent-foreground [&>svg]:text-sidebar-accent-foreground flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md px-2 outline-hidden focus-visible:ring-2 disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0",
692
- "data-[active=true]:bg-sidebar-accent data-[active=true]:text-sidebar-accent-foreground",
693
- size === "sm" && "text-xs",
694
- size === "md" && "text-sm",
695
- "group-data-[collapsible=icon]:hidden",
696
- className
697
- )}
698
- {...props}
699
- />
700
- )
644
+ const Comp = asChild ? Slot : 'a';
645
+
646
+ return (
647
+ <Comp
648
+ data-slot="sidebar-menu-sub-button"
649
+ data-sidebar="menu-sub-button"
650
+ data-size={size}
651
+ data-active={isActive}
652
+ className={cn(
653
+ 'text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground active:bg-sidebar-accent active:text-sidebar-accent-foreground [&>svg]:text-sidebar-accent-foreground flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md px-2 outline-hidden focus-visible:ring-2 disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0',
654
+ 'data-[active=true]:bg-sidebar-accent data-[active=true]:text-sidebar-accent-foreground',
655
+ size === 'sm' && 'text-xs',
656
+ size === 'md' && 'text-sm',
657
+ 'group-data-[collapsible=icon]:hidden',
658
+ className,
659
+ )}
660
+ {...props}
661
+ />
662
+ );
701
663
  }
702
664
 
703
665
  export {
704
- Sidebar,
705
- SidebarContent,
706
- SidebarFooter,
707
- SidebarGroup,
708
- SidebarGroupAction,
709
- SidebarGroupContent,
710
- SidebarGroupLabel,
711
- SidebarHeader,
712
- SidebarInput,
713
- SidebarInset,
714
- SidebarMenu,
715
- SidebarMenuAction,
716
- SidebarMenuBadge,
717
- SidebarMenuButton,
718
- SidebarMenuItem,
719
- SidebarMenuSkeleton,
720
- SidebarMenuSub,
721
- SidebarMenuSubButton,
722
- SidebarMenuSubItem,
723
- SidebarProvider,
724
- SidebarRail,
725
- SidebarSeparator,
726
- SidebarTrigger,
727
- useSidebar,
728
- }
666
+ Sidebar,
667
+ SidebarContent,
668
+ SidebarFooter,
669
+ SidebarGroup,
670
+ SidebarGroupAction,
671
+ SidebarGroupContent,
672
+ SidebarGroupLabel,
673
+ SidebarHeader,
674
+ SidebarInput,
675
+ SidebarInset,
676
+ SidebarMenu,
677
+ SidebarMenuAction,
678
+ SidebarMenuBadge,
679
+ SidebarMenuButton,
680
+ SidebarMenuItem,
681
+ SidebarMenuSkeleton,
682
+ SidebarMenuSub,
683
+ SidebarMenuSubButton,
684
+ SidebarMenuSubItem,
685
+ SidebarProvider,
686
+ SidebarRail,
687
+ SidebarSeparator,
688
+ SidebarTrigger,
689
+ useSidebar,
690
+ };