@podosoft/podokit 0.3.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (245) hide show
  1. package/README.md +2 -2
  2. package/dist/add.d.ts +2 -0
  3. package/dist/add.js +5 -1
  4. package/dist/assemble.d.ts +14 -0
  5. package/dist/assemble.js +60 -0
  6. package/dist/create.d.ts +2 -0
  7. package/dist/create.js +7 -0
  8. package/dist/eject.d.ts +11 -0
  9. package/dist/eject.js +27 -0
  10. package/dist/index.d.ts +2 -0
  11. package/dist/index.js +122 -1
  12. package/dist/inspect.d.ts +43 -0
  13. package/dist/inspect.js +82 -0
  14. package/dist/lockfile.d.ts +80 -0
  15. package/dist/lockfile.js +193 -0
  16. package/dist/templates/base/dot-env.example +11 -6
  17. package/dist/templates/fullstack-nest-svelte/README.md +2 -2
  18. package/dist/templates/fullstack-nest-svelte/apps/api/package.json +21 -2
  19. package/dist/templates/fullstack-nest-svelte/apps/api/src/app.module.ts +6 -3
  20. package/dist/templates/fullstack-nest-svelte/apps/api/src/common/app-exception.ts +4 -12
  21. package/dist/templates/fullstack-nest-svelte/apps/api/src/config/env.validation.ts +1 -1
  22. package/dist/templates/fullstack-nest-svelte/apps/api/src/main.ts +1 -1
  23. package/dist/templates/fullstack-nest-svelte/apps/api/tsconfig.json +14 -5
  24. package/dist/templates/fullstack-nest-svelte/apps/web/package.json +4 -3
  25. package/dist/templates/fullstack-nest-svelte/apps/web/src/lib/api.ts +5 -0
  26. package/dist/templates/fullstack-nest-svelte/apps/web/src/lib/components/ui/select/select-content.svelte +1 -1
  27. package/dist/templates/fullstack-nest-svelte/apps/web/src/lib/components/ui/select/select-item.svelte +1 -1
  28. package/dist/templates/fullstack-nest-svelte/apps/web/src/lib/components/ui/switch/index.ts +7 -0
  29. package/dist/templates/fullstack-nest-svelte/apps/web/src/lib/components/ui/switch/switch.svelte +29 -0
  30. package/dist/templates/fullstack-nest-svelte/apps/web/src/lib/server/api.ts +19 -0
  31. package/dist/templates/fullstack-nest-svelte/apps/web/src/lib/server/backend-proxy.ts +44 -5
  32. package/dist/templates/fullstack-nest-svelte/apps/web/src/routes/+page.svelte +8 -3
  33. package/dist/templates/fullstack-nest-svelte/apps/web/src/routes/api/[...path]/+server.ts +12 -0
  34. package/dist/templates/fullstack-nest-svelte/apps/web/src/routes/api/auth/[...all]/+server.ts +12 -0
  35. package/dist/templates/fullstack-nest-svelte/dot-env.example +10 -5
  36. package/dist/templates/fullstack-nest-svelte/dot-gitignore +5 -0
  37. package/dist/templates/fullstack-nest-svelte/infra/docker/docker-compose.yml +37 -0
  38. package/dist/templates/fullstack-nest-svelte/infra/docker/sms-sink.mjs +40 -0
  39. package/dist/templates/fullstack-nest-svelte/package.json +11 -3
  40. package/dist/templates/fullstack-nest-svelte/tests/README.md +15 -0
  41. package/dist/templates/fullstack-nest-svelte/tests/api/health.api.spec.ts +14 -0
  42. package/dist/templates/fullstack-nest-svelte/tests/package.json +15 -0
  43. package/dist/templates/fullstack-nest-svelte/tests/playwright.config.ts +25 -0
  44. package/dist/templates/fullstack-nest-svelte/tests/ui/smoke.ui.spec.ts +8 -0
  45. package/dist/templates/modules/admin-dashboard/files/apps/web/src/app.d.ts +26 -0
  46. package/dist/templates/modules/admin-dashboard/files/apps/web/src/hooks.server.ts +20 -0
  47. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/app-sidebar.svelte +65 -0
  48. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/data-table.svelte +149 -0
  49. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/language-switch.svelte +33 -0
  50. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/sidebar-user-menu.svelte +44 -0
  51. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/table-pagination.svelte +39 -0
  52. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/table-toolbar.svelte +93 -0
  53. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/theme-toggle.svelte +27 -0
  54. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/collapsible/collapsible-content.svelte +7 -0
  55. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/collapsible/collapsible-trigger.svelte +7 -0
  56. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/collapsible/collapsible.svelte +11 -0
  57. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/collapsible/index.ts +13 -0
  58. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/pagination/index.ts +31 -0
  59. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/pagination/pagination-content.svelte +20 -0
  60. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/pagination/pagination-ellipsis.svelte +22 -0
  61. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/pagination/pagination-item.svelte +14 -0
  62. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/pagination/pagination-link.svelte +42 -0
  63. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/pagination/pagination-next-button.svelte +31 -0
  64. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/pagination/pagination-next.svelte +26 -0
  65. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/pagination/pagination-prev-button.svelte +31 -0
  66. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/pagination/pagination-previous.svelte +26 -0
  67. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/pagination/pagination.svelte +28 -0
  68. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sheet/index.ts +34 -0
  69. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sheet/sheet-close.svelte +7 -0
  70. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sheet/sheet-content.svelte +55 -0
  71. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sheet/sheet-description.svelte +17 -0
  72. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sheet/sheet-footer.svelte +20 -0
  73. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sheet/sheet-header.svelte +20 -0
  74. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sheet/sheet-overlay.svelte +17 -0
  75. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sheet/sheet-portal.svelte +7 -0
  76. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sheet/sheet-title.svelte +17 -0
  77. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sheet/sheet-trigger.svelte +7 -0
  78. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sheet/sheet.svelte +7 -0
  79. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/constants.ts +6 -0
  80. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/context.svelte.ts +81 -0
  81. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/index.ts +75 -0
  82. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/sidebar-content.svelte +24 -0
  83. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/sidebar-footer.svelte +21 -0
  84. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/sidebar-group-action.svelte +33 -0
  85. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/sidebar-group-content.svelte +21 -0
  86. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/sidebar-group-label.svelte +33 -0
  87. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/sidebar-group.svelte +21 -0
  88. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/sidebar-header.svelte +21 -0
  89. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/sidebar-input.svelte +21 -0
  90. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/sidebar-inset.svelte +20 -0
  91. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/sidebar-menu-action.svelte +37 -0
  92. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/sidebar-menu-badge.svelte +24 -0
  93. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/sidebar-menu-button.svelte +102 -0
  94. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/sidebar-menu-item.svelte +21 -0
  95. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/sidebar-menu-skeleton.svelte +36 -0
  96. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/sidebar-menu-sub-button.svelte +39 -0
  97. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/sidebar-menu-sub-item.svelte +21 -0
  98. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/sidebar-menu-sub.svelte +21 -0
  99. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/sidebar-menu.svelte +21 -0
  100. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/sidebar-provider.svelte +53 -0
  101. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/sidebar-rail.svelte +36 -0
  102. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/sidebar-separator.svelte +19 -0
  103. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/sidebar-trigger.svelte +36 -0
  104. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/sidebar.svelte +108 -0
  105. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/user-avatar.svelte +12 -0
  106. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/hooks/is-mobile.svelte.ts +9 -0
  107. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/i18n/index.ts +27 -0
  108. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/i18n/messages.ts +575 -0
  109. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/server/guards.ts +22 -0
  110. package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/(app)/+layout.server.ts +30 -0
  111. package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/(app)/+layout.svelte +50 -0
  112. package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/(app)/accept-invitation/[id]/+page.svelte +36 -0
  113. package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/(app)/admin/+page.svelte +45 -0
  114. package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/(app)/admin/account/+page.server.ts +5 -0
  115. package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/(app)/admin/account/+page.svelte +685 -0
  116. package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/(app)/admin/audit/+page.server.ts +6 -0
  117. package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/(app)/admin/audit/+page.svelte +123 -0
  118. package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/(app)/admin/organizations/+page.server.ts +6 -0
  119. package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/(app)/admin/organizations/+page.svelte +264 -0
  120. package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/(app)/admin/sessions/+page.server.ts +7 -0
  121. package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/(app)/admin/sessions/+page.svelte +156 -0
  122. package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/(app)/admin/settings/+page.server.ts +26 -0
  123. package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/(app)/admin/settings/+page.svelte +322 -0
  124. package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/(app)/admin/users/+page.server.ts +7 -0
  125. package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/(app)/admin/users/+page.svelte +552 -0
  126. package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/(auth)/+layout.svelte +13 -0
  127. package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/(auth)/forgot-password/+page.svelte +61 -0
  128. package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/(auth)/login/+page.server.ts +14 -0
  129. package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/(auth)/login/+page.svelte +181 -0
  130. package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/(auth)/reset-password/+page.svelte +51 -0
  131. package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/(auth)/signup/+page.svelte +76 -0
  132. package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/(auth)/verify-email/+page.svelte +63 -0
  133. package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/+layout.server.ts +22 -0
  134. package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/+layout.svelte +20 -0
  135. package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/+page.svelte +22 -0
  136. package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/oauth2/consent/+page.svelte +54 -0
  137. package/dist/templates/modules/admin-dashboard/files/tests/api/audit.api.spec.ts +97 -0
  138. package/dist/templates/modules/admin-dashboard/files/tests/api/auth-config.api.spec.ts +80 -0
  139. package/dist/templates/modules/admin-dashboard/files/tests/api/auth.api.spec.ts +306 -0
  140. package/dist/templates/modules/admin-dashboard/files/tests/api/email.api.spec.ts +120 -0
  141. package/dist/templates/modules/admin-dashboard/files/tests/api/users-admin.api.spec.ts +134 -0
  142. package/dist/templates/modules/admin-dashboard/files/tests/helpers/accounts.ts +6 -0
  143. package/dist/templates/modules/admin-dashboard/files/tests/helpers/hydration.ts +9 -0
  144. package/dist/templates/modules/admin-dashboard/files/tests/helpers/mailpit.ts +49 -0
  145. package/dist/templates/modules/admin-dashboard/files/tests/helpers/sms.ts +35 -0
  146. package/dist/templates/modules/admin-dashboard/files/tests/helpers/totp.ts +9 -0
  147. package/dist/templates/modules/admin-dashboard/files/tests/playwright.config.ts +26 -0
  148. package/dist/templates/modules/admin-dashboard/files/tests/seed.setup.ts +40 -0
  149. package/dist/templates/modules/admin-dashboard/files/tests/ui/account.ui.spec.ts +126 -0
  150. package/dist/templates/modules/admin-dashboard/files/tests/ui/audit.ui.spec.ts +16 -0
  151. package/dist/templates/modules/admin-dashboard/files/tests/ui/auth.ui.spec.ts +45 -0
  152. package/dist/templates/modules/admin-dashboard/files/tests/ui/dashboard.ui.spec.ts +25 -0
  153. package/dist/templates/modules/admin-dashboard/files/tests/ui/data-table.ui.spec.ts +32 -0
  154. package/dist/templates/modules/admin-dashboard/files/tests/ui/email-admin.ui.spec.ts +60 -0
  155. package/dist/templates/modules/admin-dashboard/files/tests/ui/email.ui.spec.ts +42 -0
  156. package/dist/templates/modules/admin-dashboard/files/tests/ui/guards.ui.spec.ts +22 -0
  157. package/dist/templates/modules/admin-dashboard/files/tests/ui/i18n.ui.spec.ts +13 -0
  158. package/dist/templates/modules/admin-dashboard/files/tests/ui/oidc.ui.spec.ts +57 -0
  159. package/dist/templates/modules/admin-dashboard/files/tests/ui/organizations.ui.spec.ts +52 -0
  160. package/dist/templates/modules/admin-dashboard/files/tests/ui/passkey.ui.spec.ts +36 -0
  161. package/dist/templates/modules/admin-dashboard/files/tests/ui/sessions.ui.spec.ts +22 -0
  162. package/dist/templates/modules/admin-dashboard/files/tests/ui/settings.ui.spec.ts +34 -0
  163. package/dist/templates/modules/admin-dashboard/files/tests/ui/sidebar.ui.spec.ts +16 -0
  164. package/dist/templates/modules/admin-dashboard/files/tests/ui/table-toolbar.ui.spec.ts +32 -0
  165. package/dist/templates/modules/admin-dashboard/files/tests/ui/users-crud.ui.spec.ts +145 -0
  166. package/dist/templates/modules/admin-dashboard/files/tests/ui/users.ui.spec.ts +51 -0
  167. package/dist/templates/modules/admin-dashboard/module.manifest.json +47 -0
  168. package/dist/templates/modules/api-key-auth/module.manifest.json +3 -3
  169. package/dist/templates/modules/audit-log/files/apps/api/src/audit/README.md +59 -0
  170. package/dist/templates/modules/audit-log/files/apps/api/src/audit/audit-enabled.ts +16 -0
  171. package/dist/templates/modules/audit-log/files/apps/api/src/audit/audit-events.ts +34 -0
  172. package/dist/templates/modules/audit-log/files/apps/api/src/audit/audit-hook.ts +74 -0
  173. package/dist/templates/modules/audit-log/files/apps/api/src/audit/audit-log.entity.ts +29 -8
  174. package/dist/templates/modules/audit-log/files/apps/api/src/audit/audit.controller.ts +7 -2
  175. package/dist/templates/modules/audit-log/files/apps/api/src/audit/audit.decorator.ts +23 -0
  176. package/dist/templates/modules/audit-log/files/apps/api/src/audit/audit.interceptor.ts +38 -21
  177. package/dist/templates/modules/audit-log/files/apps/api/src/audit/audit.module.ts +2 -1
  178. package/dist/templates/modules/audit-log/files/apps/api/src/audit/audit.service.ts +36 -0
  179. package/dist/templates/modules/audit-log/files/apps/api/src/migrations/1720300000000-InitAuditLogs.ts +10 -4
  180. package/dist/templates/modules/audit-log/module.manifest.json +37 -8
  181. package/dist/templates/modules/auth/files/apps/api/src/account/account.controller.ts +85 -3
  182. package/dist/templates/modules/auth/files/apps/api/src/account/account.module.ts +2 -1
  183. package/dist/templates/modules/auth/files/apps/api/src/auth/auth-provider.ts +73 -0
  184. package/dist/templates/modules/auth/files/apps/api/src/auth/auth.ts +199 -31
  185. package/dist/templates/modules/auth/files/apps/api/src/auth/db.ts +12 -0
  186. package/dist/templates/modules/auth/files/apps/api/src/auth/feature-gate.ts +56 -0
  187. package/dist/templates/modules/auth/files/apps/api/src/auth/org-permissions.ts +22 -0
  188. package/dist/templates/modules/auth/files/apps/api/src/auth/permissions.ts +23 -0
  189. package/dist/templates/modules/auth/files/apps/api/src/auth-config/auth-config.controller.ts +33 -0
  190. package/dist/templates/modules/auth/files/apps/api/src/auth-config/auth-config.entity.ts +26 -0
  191. package/dist/templates/modules/auth/files/apps/api/src/auth-config/auth-config.module.ts +12 -0
  192. package/dist/templates/modules/auth/files/apps/api/src/auth-config/auth-config.service.ts +118 -0
  193. package/dist/templates/modules/auth/files/apps/api/src/mail/mailer.ts +65 -0
  194. package/dist/templates/modules/auth/files/apps/api/src/migrations/1720400000000-InitAppSettings.ts +38 -0
  195. package/dist/templates/modules/auth/files/apps/api/src/migrations/1720500000000-InitAuthConfig.ts +27 -0
  196. package/dist/templates/modules/auth/files/apps/api/src/settings/app-setting.entity.ts +16 -0
  197. package/dist/templates/modules/auth/files/apps/api/src/settings/flag-defaults.ts +25 -0
  198. package/dist/templates/modules/auth/files/apps/api/src/settings/settings.module.ts +11 -0
  199. package/dist/templates/modules/auth/files/apps/api/src/settings/settings.service.ts +57 -0
  200. package/dist/templates/modules/auth/files/apps/api/src/sms/sms.ts +23 -0
  201. package/dist/templates/modules/auth/module.manifest.json +54 -20
  202. package/dist/templates/modules/bullmq/files/apps/api/src/jobs/worker.module.ts +6 -3
  203. package/dist/templates/modules/bullmq/module.manifest.json +4 -4
  204. package/dist/templates/modules/file-upload/module.manifest.json +3 -3
  205. package/dist/templates/modules/job-progress/module.manifest.json +9 -9
  206. package/dist/templates/modules/logging/module.manifest.json +3 -3
  207. package/dist/templates/modules/object-storage-s3/files/infra/docker/minio.compose.yml +5 -3
  208. package/dist/templates/modules/object-storage-s3/module.manifest.json +5 -5
  209. package/dist/templates/modules/rate-limit/module.manifest.json +2 -2
  210. package/dist/templates/modules/redis/module.manifest.json +4 -4
  211. package/dist/templates/modules/sse/module.manifest.json +4 -4
  212. package/dist/templates/todo/README.md +2 -2
  213. package/dist/templates/todo/apps/api/package.json +21 -2
  214. package/dist/templates/todo/apps/api/src/app.module.ts +6 -3
  215. package/dist/templates/todo/apps/api/src/common/app-exception.ts +4 -12
  216. package/dist/templates/todo/apps/api/src/config/env.validation.ts +1 -1
  217. package/dist/templates/todo/apps/api/src/main.ts +1 -1
  218. package/dist/templates/todo/apps/api/tsconfig.json +14 -5
  219. package/dist/templates/todo/apps/web/package.json +4 -3
  220. package/dist/templates/todo/apps/web/src/lib/api.ts +5 -0
  221. package/dist/templates/todo/apps/web/src/lib/components/ui/switch/index.ts +7 -0
  222. package/dist/templates/todo/apps/web/src/lib/components/ui/switch/switch.svelte +29 -0
  223. package/dist/templates/todo/apps/web/src/lib/server/api.ts +19 -0
  224. package/dist/templates/todo/apps/web/src/lib/server/backend-proxy.ts +44 -5
  225. package/dist/templates/todo/apps/web/src/routes/+page.svelte +19 -18
  226. package/dist/templates/todo/apps/web/src/routes/api/[...path]/+server.ts +12 -0
  227. package/dist/templates/todo/apps/web/src/routes/api/auth/[...all]/+server.ts +12 -0
  228. package/dist/templates/todo/dot-env.example +10 -5
  229. package/dist/templates/todo/dot-gitignore +5 -0
  230. package/dist/templates/todo/infra/docker/docker-compose.yml +4 -0
  231. package/dist/templates/todo/package.json +11 -3
  232. package/dist/templates/todo/tests/README.md +15 -0
  233. package/dist/templates/todo/tests/api/health.api.spec.ts +14 -0
  234. package/dist/templates/todo/tests/package.json +15 -0
  235. package/dist/templates/todo/tests/playwright.config.ts +25 -0
  236. package/dist/templates/todo/tests/ui/smoke.ui.spec.ts +8 -0
  237. package/dist/update.d.ts +49 -0
  238. package/dist/update.js +158 -0
  239. package/package.json +2 -2
  240. package/dist/templates/fullstack-nest-svelte/apps/api/test/health.e2e-spec.ts +0 -23
  241. package/dist/templates/fullstack-nest-svelte/apps/web/src/routes/api/health/+server.ts +0 -12
  242. package/dist/templates/todo/apps/api/test/health.e2e-spec.ts +0 -23
  243. package/dist/templates/todo/apps/web/src/routes/api/health/+server.ts +0 -12
  244. package/dist/templates/todo/apps/web/src/routes/api/todos/+server.ts +0 -24
  245. package/dist/templates/todo/apps/web/src/routes/api/todos/[id]/+server.ts +0 -24
@@ -0,0 +1,7 @@
1
+ <script lang="ts">
2
+ import { Dialog as SheetPrimitive } from "bits-ui";
3
+
4
+ let { open = $bindable(false), ...restProps }: SheetPrimitive.RootProps = $props();
5
+ </script>
6
+
7
+ <SheetPrimitive.Root bind:open {...restProps} />
@@ -0,0 +1,6 @@
1
+ export const SIDEBAR_COOKIE_NAME = "sidebar_state";
2
+ export const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7;
3
+ export const SIDEBAR_WIDTH = "16rem";
4
+ export const SIDEBAR_WIDTH_MOBILE = "18rem";
5
+ export const SIDEBAR_WIDTH_ICON = "3rem";
6
+ export const SIDEBAR_KEYBOARD_SHORTCUT = "b";
@@ -0,0 +1,81 @@
1
+ import { IsMobile } from "$lib/hooks/is-mobile.svelte.js";
2
+ import { getContext, setContext } from "svelte";
3
+ import { SIDEBAR_KEYBOARD_SHORTCUT } from "./constants.js";
4
+
5
+ type Getter<T> = () => T;
6
+
7
+ export type SidebarStateProps = {
8
+ /**
9
+ * A getter function that returns the current open state of the sidebar.
10
+ * We use a getter function here to support `bind:open` on the `Sidebar.Provider`
11
+ * component.
12
+ */
13
+ open: Getter<boolean>;
14
+
15
+ /**
16
+ * A function that sets the open state of the sidebar. To support `bind:open`, we need
17
+ * a source of truth for changing the open state to ensure it will be synced throughout
18
+ * the sub-components and any `bind:` references.
19
+ */
20
+ setOpen: (open: boolean) => void;
21
+ };
22
+
23
+ class SidebarState {
24
+ readonly props: SidebarStateProps;
25
+ open = $derived.by(() => this.props.open());
26
+ openMobile = $state(false);
27
+ setOpen: SidebarStateProps["setOpen"];
28
+ #isMobile: IsMobile;
29
+ state = $derived.by(() => (this.open ? "expanded" : "collapsed"));
30
+
31
+ constructor(props: SidebarStateProps) {
32
+ this.setOpen = props.setOpen;
33
+ this.#isMobile = new IsMobile();
34
+ this.props = props;
35
+ }
36
+
37
+ // Convenience getter for checking if the sidebar is mobile
38
+ // without this, we would need to use `sidebar.isMobile.current` everywhere
39
+ get isMobile() {
40
+ return this.#isMobile.current;
41
+ }
42
+
43
+ // Event handler to apply to the `<svelte:window>`
44
+ handleShortcutKeydown = (e: KeyboardEvent) => {
45
+ if (e.key === SIDEBAR_KEYBOARD_SHORTCUT && (e.metaKey || e.ctrlKey)) {
46
+ e.preventDefault();
47
+ this.toggle();
48
+ }
49
+ };
50
+
51
+ setOpenMobile = (value: boolean) => {
52
+ this.openMobile = value;
53
+ };
54
+
55
+ toggle = () => {
56
+ return this.#isMobile.current
57
+ ? (this.openMobile = !this.openMobile)
58
+ : this.setOpen(!this.open);
59
+ };
60
+ }
61
+
62
+ const SYMBOL_KEY = "scn-sidebar";
63
+
64
+ /**
65
+ * Instantiates a new `SidebarState` instance and sets it in the context.
66
+ *
67
+ * @param props The constructor props for the `SidebarState` class.
68
+ * @returns The `SidebarState` instance.
69
+ */
70
+ export function setSidebar(props: SidebarStateProps): SidebarState {
71
+ return setContext(Symbol.for(SYMBOL_KEY), new SidebarState(props));
72
+ }
73
+
74
+ /**
75
+ * Retrieves the `SidebarState` instance from the context. This is a class instance,
76
+ * so you cannot destructure it.
77
+ * @returns The `SidebarState` instance.
78
+ */
79
+ export function useSidebar(): SidebarState {
80
+ return getContext(Symbol.for(SYMBOL_KEY));
81
+ }
@@ -0,0 +1,75 @@
1
+ import { useSidebar } from "./context.svelte.js";
2
+ import Content from "./sidebar-content.svelte";
3
+ import Footer from "./sidebar-footer.svelte";
4
+ import GroupAction from "./sidebar-group-action.svelte";
5
+ import GroupContent from "./sidebar-group-content.svelte";
6
+ import GroupLabel from "./sidebar-group-label.svelte";
7
+ import Group from "./sidebar-group.svelte";
8
+ import Header from "./sidebar-header.svelte";
9
+ import Input from "./sidebar-input.svelte";
10
+ import Inset from "./sidebar-inset.svelte";
11
+ import MenuAction from "./sidebar-menu-action.svelte";
12
+ import MenuBadge from "./sidebar-menu-badge.svelte";
13
+ import MenuButton from "./sidebar-menu-button.svelte";
14
+ import MenuItem from "./sidebar-menu-item.svelte";
15
+ import MenuSkeleton from "./sidebar-menu-skeleton.svelte";
16
+ import MenuSubButton from "./sidebar-menu-sub-button.svelte";
17
+ import MenuSubItem from "./sidebar-menu-sub-item.svelte";
18
+ import MenuSub from "./sidebar-menu-sub.svelte";
19
+ import Menu from "./sidebar-menu.svelte";
20
+ import Provider from "./sidebar-provider.svelte";
21
+ import Rail from "./sidebar-rail.svelte";
22
+ import Separator from "./sidebar-separator.svelte";
23
+ import Trigger from "./sidebar-trigger.svelte";
24
+ import Root from "./sidebar.svelte";
25
+
26
+ export {
27
+ Content,
28
+ Footer,
29
+ Group,
30
+ GroupAction,
31
+ GroupContent,
32
+ GroupLabel,
33
+ Header,
34
+ Input,
35
+ Inset,
36
+ Menu,
37
+ MenuAction,
38
+ MenuBadge,
39
+ MenuButton,
40
+ MenuItem,
41
+ MenuSkeleton,
42
+ MenuSub,
43
+ MenuSubButton,
44
+ MenuSubItem,
45
+ Provider,
46
+ Rail,
47
+ Root,
48
+ Separator,
49
+ //
50
+ Root as Sidebar,
51
+ Content as SidebarContent,
52
+ Footer as SidebarFooter,
53
+ Group as SidebarGroup,
54
+ GroupAction as SidebarGroupAction,
55
+ GroupContent as SidebarGroupContent,
56
+ GroupLabel as SidebarGroupLabel,
57
+ Header as SidebarHeader,
58
+ Input as SidebarInput,
59
+ Inset as SidebarInset,
60
+ Menu as SidebarMenu,
61
+ MenuAction as SidebarMenuAction,
62
+ MenuBadge as SidebarMenuBadge,
63
+ MenuButton as SidebarMenuButton,
64
+ MenuItem as SidebarMenuItem,
65
+ MenuSkeleton as SidebarMenuSkeleton,
66
+ MenuSub as SidebarMenuSub,
67
+ MenuSubButton as SidebarMenuSubButton,
68
+ MenuSubItem as SidebarMenuSubItem,
69
+ Provider as SidebarProvider,
70
+ Rail as SidebarRail,
71
+ Separator as SidebarSeparator,
72
+ Trigger as SidebarTrigger,
73
+ Trigger,
74
+ useSidebar,
75
+ };
@@ -0,0 +1,24 @@
1
+ <script lang="ts">
2
+ import type { HTMLAttributes } from "svelte/elements";
3
+ import { cn, type WithElementRef } from "$lib/utils.js";
4
+
5
+ let {
6
+ ref = $bindable(null),
7
+ class: className,
8
+ children,
9
+ ...restProps
10
+ }: WithElementRef<HTMLAttributes<HTMLElement>> = $props();
11
+ </script>
12
+
13
+ <div
14
+ bind:this={ref}
15
+ data-slot="sidebar-content"
16
+ data-sidebar="content"
17
+ class={cn(
18
+ "no-scrollbar gap-0 flex min-h-0 flex-1 flex-col overflow-auto group-data-[collapsible=icon]:overflow-hidden",
19
+ className
20
+ )}
21
+ {...restProps}
22
+ >
23
+ {@render children?.()}
24
+ </div>
@@ -0,0 +1,21 @@
1
+ <script lang="ts">
2
+ import type { HTMLAttributes } from "svelte/elements";
3
+ import { cn, type WithElementRef } from "$lib/utils.js";
4
+
5
+ let {
6
+ ref = $bindable(null),
7
+ class: className,
8
+ children,
9
+ ...restProps
10
+ }: WithElementRef<HTMLAttributes<HTMLElement>> = $props();
11
+ </script>
12
+
13
+ <div
14
+ bind:this={ref}
15
+ data-slot="sidebar-footer"
16
+ data-sidebar="footer"
17
+ class={cn("gap-2 p-2 flex flex-col", className)}
18
+ {...restProps}
19
+ >
20
+ {@render children?.()}
21
+ </div>
@@ -0,0 +1,33 @@
1
+ <script lang="ts">
2
+ import { cn, type WithElementRef } from "$lib/utils.js";
3
+ import type { Snippet } from "svelte";
4
+ import type { HTMLButtonAttributes } from "svelte/elements";
5
+
6
+ let {
7
+ ref = $bindable(null),
8
+ class: className,
9
+ children,
10
+ child,
11
+ ...restProps
12
+ }: WithElementRef<HTMLButtonAttributes> & {
13
+ child?: Snippet<[{ props: Record<string, unknown> }]>;
14
+ } = $props();
15
+
16
+ const mergedProps = $derived({
17
+ class: cn(
18
+ "text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground absolute top-3.5 right-3 w-5 rounded-md p-0 focus-visible:ring-2 [&>svg]:size-4 flex aspect-square items-center justify-center outline-hidden transition-transform group-data-[collapsible=icon]:hidden after:absolute after:-inset-2 md:after:hidden [&>svg]:shrink-0",
19
+ className
20
+ ),
21
+ "data-slot": "sidebar-group-action",
22
+ "data-sidebar": "group-action",
23
+ ...restProps,
24
+ });
25
+ </script>
26
+
27
+ {#if child}
28
+ {@render child({ props: mergedProps })}
29
+ {:else}
30
+ <button bind:this={ref} {...mergedProps}>
31
+ {@render children?.()}
32
+ </button>
33
+ {/if}
@@ -0,0 +1,21 @@
1
+ <script lang="ts">
2
+ import { cn, type WithElementRef } from "$lib/utils.js";
3
+ import type { HTMLAttributes } from "svelte/elements";
4
+
5
+ let {
6
+ ref = $bindable(null),
7
+ class: className,
8
+ children,
9
+ ...restProps
10
+ }: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
11
+ </script>
12
+
13
+ <div
14
+ bind:this={ref}
15
+ data-slot="sidebar-group-content"
16
+ data-sidebar="group-content"
17
+ class={cn("text-sm w-full", className)}
18
+ {...restProps}
19
+ >
20
+ {@render children?.()}
21
+ </div>
@@ -0,0 +1,33 @@
1
+ <script lang="ts">
2
+ import { cn, type WithElementRef } from "$lib/utils.js";
3
+ import type { Snippet } from "svelte";
4
+ import type { HTMLAttributes } from "svelte/elements";
5
+
6
+ let {
7
+ ref = $bindable(null),
8
+ children,
9
+ child,
10
+ class: className,
11
+ ...restProps
12
+ }: WithElementRef<HTMLAttributes<HTMLElement>> & {
13
+ child?: Snippet<[{ props: Record<string, unknown> }]>;
14
+ } = $props();
15
+
16
+ const mergedProps = $derived({
17
+ class: cn(
18
+ "text-sidebar-foreground/70 ring-sidebar-ring h-8 rounded-md px-2 text-xs font-medium transition-[margin,opacity] duration-200 ease-linear group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0 focus-visible:ring-2 [&>svg]:size-4 flex shrink-0 items-center outline-hidden [&>svg]:shrink-0",
19
+ className
20
+ ),
21
+ "data-slot": "sidebar-group-label",
22
+ "data-sidebar": "group-label",
23
+ ...restProps,
24
+ });
25
+ </script>
26
+
27
+ {#if child}
28
+ {@render child({ props: mergedProps })}
29
+ {:else}
30
+ <div bind:this={ref} {...mergedProps}>
31
+ {@render children?.()}
32
+ </div>
33
+ {/if}
@@ -0,0 +1,21 @@
1
+ <script lang="ts">
2
+ import type { HTMLAttributes } from "svelte/elements";
3
+ import { cn, type WithElementRef } from "$lib/utils.js";
4
+
5
+ let {
6
+ ref = $bindable(null),
7
+ class: className,
8
+ children,
9
+ ...restProps
10
+ }: WithElementRef<HTMLAttributes<HTMLElement>> = $props();
11
+ </script>
12
+
13
+ <div
14
+ bind:this={ref}
15
+ data-slot="sidebar-group"
16
+ data-sidebar="group"
17
+ class={cn("p-2 relative flex w-full min-w-0 flex-col", className)}
18
+ {...restProps}
19
+ >
20
+ {@render children?.()}
21
+ </div>
@@ -0,0 +1,21 @@
1
+ <script lang="ts">
2
+ import type { HTMLAttributes } from "svelte/elements";
3
+ import { cn, type WithElementRef } from "$lib/utils.js";
4
+
5
+ let {
6
+ ref = $bindable(null),
7
+ class: className,
8
+ children,
9
+ ...restProps
10
+ }: WithElementRef<HTMLAttributes<HTMLElement>> = $props();
11
+ </script>
12
+
13
+ <div
14
+ bind:this={ref}
15
+ data-slot="sidebar-header"
16
+ data-sidebar="header"
17
+ class={cn("gap-2 p-2 flex flex-col", className)}
18
+ {...restProps}
19
+ >
20
+ {@render children?.()}
21
+ </div>
@@ -0,0 +1,21 @@
1
+ <script lang="ts">
2
+ import type { ComponentProps } from "svelte";
3
+ import { Input } from "$lib/components/ui/input/index.js";
4
+ import { cn } from "$lib/utils.js";
5
+
6
+ let {
7
+ ref = $bindable(null),
8
+ value = $bindable(""),
9
+ class: className,
10
+ ...restProps
11
+ }: ComponentProps<typeof Input> = $props();
12
+ </script>
13
+
14
+ <Input
15
+ bind:ref
16
+ bind:value
17
+ data-slot="sidebar-input"
18
+ data-sidebar="input"
19
+ class={cn("bg-background h-8 w-full shadow-none", className)}
20
+ {...restProps}
21
+ />
@@ -0,0 +1,20 @@
1
+ <script lang="ts">
2
+ import { cn, type WithElementRef } from "$lib/utils.js";
3
+ import type { HTMLAttributes } from "svelte/elements";
4
+
5
+ let {
6
+ ref = $bindable(null),
7
+ class: className,
8
+ children,
9
+ ...restProps
10
+ }: WithElementRef<HTMLAttributes<HTMLElement>> = $props();
11
+ </script>
12
+
13
+ <main
14
+ bind:this={ref}
15
+ data-slot="sidebar-inset"
16
+ class={cn("bg-background 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 relative flex w-full flex-1 flex-col", className)}
17
+ {...restProps}
18
+ >
19
+ {@render children?.()}
20
+ </main>
@@ -0,0 +1,37 @@
1
+ <script lang="ts">
2
+ import { cn, type WithElementRef } from "$lib/utils.js";
3
+ import type { Snippet } from "svelte";
4
+ import type { HTMLButtonAttributes } from "svelte/elements";
5
+
6
+ let {
7
+ ref = $bindable(null),
8
+ class: className,
9
+ showOnHover = false,
10
+ children,
11
+ child,
12
+ ...restProps
13
+ }: WithElementRef<HTMLButtonAttributes> & {
14
+ child?: Snippet<[{ props: Record<string, unknown> }]>;
15
+ showOnHover?: boolean;
16
+ } = $props();
17
+
18
+ const mergedProps = $derived({
19
+ class: cn(
20
+ "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 aspect-square w-5 rounded-md p-0 peer-data-[size=default]/menu-button:top-1.5 peer-data-[size=lg]/menu-button:top-2.5 peer-data-[size=sm]/menu-button:top-1 focus-visible:ring-2 [&>svg]:size-4 flex items-center justify-center outline-hidden transition-transform group-data-[collapsible=icon]:hidden after:absolute after:-inset-2 md:after:hidden [&>svg]:shrink-0",
21
+ showOnHover &&
22
+ "peer-data-active/menu-button:text-sidebar-accent-foreground group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 data-open:opacity-100 md:opacity-0",
23
+ className
24
+ ),
25
+ "data-slot": "sidebar-menu-action",
26
+ "data-sidebar": "menu-action",
27
+ ...restProps,
28
+ });
29
+ </script>
30
+
31
+ {#if child}
32
+ {@render child({ props: mergedProps })}
33
+ {:else}
34
+ <button bind:this={ref} {...mergedProps}>
35
+ {@render children?.()}
36
+ </button>
37
+ {/if}
@@ -0,0 +1,24 @@
1
+ <script lang="ts">
2
+ import { cn, type WithElementRef } from "$lib/utils.js";
3
+ import type { HTMLAttributes } from "svelte/elements";
4
+
5
+ let {
6
+ ref = $bindable(null),
7
+ class: className,
8
+ children,
9
+ ...restProps
10
+ }: WithElementRef<HTMLAttributes<HTMLElement>> = $props();
11
+ </script>
12
+
13
+ <div
14
+ bind:this={ref}
15
+ data-slot="sidebar-menu-badge"
16
+ data-sidebar="menu-badge"
17
+ class={cn(
18
+ "text-sidebar-foreground peer-hover/menu-button:text-sidebar-accent-foreground peer-data-active/menu-button:text-sidebar-accent-foreground pointer-events-none absolute right-1 flex h-5 min-w-5 rounded-md px-1 text-xs font-medium peer-data-[size=default]/menu-button:top-1.5 peer-data-[size=lg]/menu-button:top-2.5 peer-data-[size=sm]/menu-button:top-1 flex items-center justify-center tabular-nums select-none group-data-[collapsible=icon]:hidden",
19
+ className
20
+ )}
21
+ {...restProps}
22
+ >
23
+ {@render children?.()}
24
+ </div>
@@ -0,0 +1,102 @@
1
+ <script lang="ts" module>
2
+ import { tv, type VariantProps } from "tailwind-variants";
3
+
4
+ export const sidebarMenuButtonVariants = tv({
5
+ base: "ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground active:bg-sidebar-accent active:text-sidebar-accent-foreground data-active:bg-sidebar-accent data-active:text-sidebar-accent-foreground data-open:hover:bg-sidebar-accent data-open:hover:text-sidebar-accent-foreground gap-2 rounded-md p-2 text-left text-sm transition-[width,height,padding] group-has-data-[sidebar=menu-action]/menu-item:pr-8 group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! focus-visible:ring-2 data-active:font-medium peer/menu-button group/menu-button flex w-full items-center overflow-hidden outline-hidden disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&_svg]:size-4 [&_svg]:shrink-0 [&>span:last-child]:truncate",
6
+ variants: {
7
+ variant: {
8
+ default: "hover:bg-sidebar-accent hover:text-sidebar-accent-foreground",
9
+ outline: "bg-background hover:bg-sidebar-accent hover:text-sidebar-accent-foreground shadow-[0_0_0_1px_var(--sidebar-border)] hover:shadow-[0_0_0_1px_var(--sidebar-accent)]",
10
+ },
11
+ size: {
12
+ default: "h-8 text-sm",
13
+ sm: "h-7 text-xs",
14
+ lg: "h-12 text-sm group-data-[collapsible=icon]:p-0!",
15
+ },
16
+ },
17
+ defaultVariants: {
18
+ variant: "default",
19
+ size: "default",
20
+ },
21
+ });
22
+
23
+ export type SidebarMenuButtonVariant = VariantProps<
24
+ typeof sidebarMenuButtonVariants
25
+ >["variant"];
26
+ export type SidebarMenuButtonSize = VariantProps<typeof sidebarMenuButtonVariants>["size"];
27
+ </script>
28
+
29
+ <script lang="ts">
30
+ import * as Tooltip from "$lib/components/ui/tooltip/index.js";
31
+ import { cn, type WithElementRef, type WithoutChildrenOrChild } from "$lib/utils.js";
32
+ import { mergeProps } from "bits-ui";
33
+ import type { ComponentProps, Snippet } from "svelte";
34
+ import type { HTMLAttributes } from "svelte/elements";
35
+ import { useSidebar } from "./context.svelte.js";
36
+
37
+ let {
38
+ ref = $bindable(null),
39
+ class: className,
40
+ children,
41
+ child,
42
+ variant = "default",
43
+ size = "default",
44
+ isActive = false,
45
+ tooltipContent,
46
+ tooltipContentProps,
47
+ ...restProps
48
+ }: WithElementRef<HTMLAttributes<HTMLButtonElement>, HTMLButtonElement> & {
49
+ isActive?: boolean;
50
+ variant?: SidebarMenuButtonVariant;
51
+ size?: SidebarMenuButtonSize;
52
+ tooltipContent?: Snippet | string;
53
+ tooltipContentProps?: WithoutChildrenOrChild<ComponentProps<typeof Tooltip.Content>>;
54
+ child?: Snippet<[{ props: Record<string, unknown> }]>;
55
+ } = $props();
56
+
57
+ const sidebar = useSidebar();
58
+
59
+ const buttonProps = $derived({
60
+ class: cn(sidebarMenuButtonVariants({ variant, size }), className),
61
+ "data-slot": "sidebar-menu-button",
62
+ "data-sidebar": "menu-button",
63
+ "data-size": size,
64
+ "data-active": isActive,
65
+ ...restProps,
66
+ });
67
+ </script>
68
+
69
+ {#snippet Button({ props }: { props?: Record<string, unknown> })}
70
+ {@const mergedProps = mergeProps(buttonProps, props)}
71
+ {#if child}
72
+ {@render child({ props: mergedProps })}
73
+ {:else}
74
+ <button bind:this={ref} {...mergedProps}>
75
+ {@render children?.()}
76
+ </button>
77
+ {/if}
78
+ {/snippet}
79
+
80
+ {#if !tooltipContent}
81
+ {@render Button({})}
82
+ {:else}
83
+ <Tooltip.Root>
84
+ <Tooltip.Trigger>
85
+ {#snippet child({ props })}
86
+ {@render Button({ props })}
87
+ {/snippet}
88
+ </Tooltip.Trigger>
89
+ <Tooltip.Content
90
+ side="right"
91
+ align="center"
92
+ hidden={sidebar.state !== "collapsed" || sidebar.isMobile}
93
+ {...tooltipContentProps}
94
+ >
95
+ {#if typeof tooltipContent === "string"}
96
+ {tooltipContent}
97
+ {:else if tooltipContent}
98
+ {@render tooltipContent()}
99
+ {/if}
100
+ </Tooltip.Content>
101
+ </Tooltip.Root>
102
+ {/if}
@@ -0,0 +1,21 @@
1
+ <script lang="ts">
2
+ import { cn, type WithElementRef } from "$lib/utils.js";
3
+ import type { HTMLAttributes } from "svelte/elements";
4
+
5
+ let {
6
+ ref = $bindable(null),
7
+ class: className,
8
+ children,
9
+ ...restProps
10
+ }: WithElementRef<HTMLAttributes<HTMLLIElement>, HTMLLIElement> = $props();
11
+ </script>
12
+
13
+ <li
14
+ bind:this={ref}
15
+ data-slot="sidebar-menu-item"
16
+ data-sidebar="menu-item"
17
+ class={cn("group/menu-item relative", className)}
18
+ {...restProps}
19
+ >
20
+ {@render children?.()}
21
+ </li>
@@ -0,0 +1,36 @@
1
+ <script lang="ts">
2
+ import { cn, type WithElementRef } from "$lib/utils.js";
3
+ import { Skeleton } from "$lib/components/ui/skeleton/index.js";
4
+ import type { HTMLAttributes } from "svelte/elements";
5
+
6
+ let {
7
+ ref = $bindable(null),
8
+ class: className,
9
+ showIcon = false,
10
+ children,
11
+ ...restProps
12
+ }: WithElementRef<HTMLAttributes<HTMLElement>> & {
13
+ showIcon?: boolean;
14
+ } = $props();
15
+
16
+ // Random width between 50% and 90%
17
+ const width = `${Math.floor(Math.random() * 40) + 50}%`;
18
+ </script>
19
+
20
+ <div
21
+ bind:this={ref}
22
+ data-slot="sidebar-menu-skeleton"
23
+ data-sidebar="menu-skeleton"
24
+ class={cn("h-8 gap-2 rounded-md px-2 flex items-center", className)}
25
+ {...restProps}
26
+ >
27
+ {#if showIcon}
28
+ <Skeleton class="size-4 rounded-md" data-sidebar="menu-skeleton-icon" />
29
+ {/if}
30
+ <Skeleton
31
+ class="h-4 max-w-(--skeleton-width) flex-1"
32
+ data-sidebar="menu-skeleton-text"
33
+ style="--skeleton-width: {width};"
34
+ />
35
+ {@render children?.()}
36
+ </div>
@@ -0,0 +1,39 @@
1
+ <script lang="ts">
2
+ import { cn, type WithElementRef } from "$lib/utils.js";
3
+ import type { Snippet } from "svelte";
4
+ import type { HTMLAnchorAttributes } from "svelte/elements";
5
+
6
+ let {
7
+ ref = $bindable(null),
8
+ children,
9
+ child,
10
+ class: className,
11
+ size = "md",
12
+ isActive = false,
13
+ ...restProps
14
+ }: WithElementRef<HTMLAnchorAttributes> & {
15
+ child?: Snippet<[{ props: Record<string, unknown> }]>;
16
+ size?: "sm" | "md";
17
+ isActive?: boolean;
18
+ } = $props();
19
+
20
+ const mergedProps = $derived({
21
+ class: cn(
22
+ "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 data-active:bg-sidebar-accent data-active:text-sidebar-accent-foreground h-7 gap-2 rounded-md px-2 focus-visible:ring-2 data-[size=md]:text-sm data-[size=sm]:text-xs [&>svg]:size-4 flex min-w-0 -translate-x-px items-center overflow-hidden outline-hidden group-data-[collapsible=icon]:hidden disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&>svg]:shrink-0",
23
+ className
24
+ ),
25
+ "data-slot": "sidebar-menu-sub-button",
26
+ "data-sidebar": "menu-sub-button",
27
+ "data-size": size,
28
+ "data-active": isActive,
29
+ ...restProps,
30
+ });
31
+ </script>
32
+
33
+ {#if child}
34
+ {@render child({ props: mergedProps })}
35
+ {:else}
36
+ <a bind:this={ref} {...mergedProps}>
37
+ {@render children?.()}
38
+ </a>
39
+ {/if}