@intlayer/design-system 8.12.4 → 9.0.0-canary.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 (119) hide show
  1. package/dist/esm/api/hooks/project.mjs +12 -1
  2. package/dist/esm/api/hooks/project.mjs.map +1 -1
  3. package/dist/esm/api/index.mjs +2 -2
  4. package/dist/esm/components/Avatar/index.mjs +1 -1
  5. package/dist/esm/components/Avatar/index.mjs.map +1 -1
  6. package/dist/esm/components/Breadcrumb/index.mjs +10 -7
  7. package/dist/esm/components/Breadcrumb/index.mjs.map +1 -1
  8. package/dist/esm/components/Button/Button.mjs +4 -2
  9. package/dist/esm/components/Button/Button.mjs.map +1 -1
  10. package/dist/esm/components/Carousel/index.mjs +1 -1
  11. package/dist/esm/components/Carousel/index.mjs.map +1 -1
  12. package/dist/esm/components/Container/index.mjs.map +1 -1
  13. package/dist/esm/components/DictionaryFieldEditor/DictionaryCreationForm/DictionaryCreationForm.mjs +1 -1
  14. package/dist/esm/components/DictionaryFieldEditor/DictionaryCreationForm/DictionaryCreationForm.mjs.map +1 -1
  15. package/dist/esm/components/DropDown/index.mjs.map +1 -1
  16. package/dist/esm/components/ExpandCollapse/ExpandCollapse.mjs +1 -1
  17. package/dist/esm/components/ExpandCollapse/ExpandCollapse.mjs.map +1 -1
  18. package/dist/esm/components/Headers/index.mjs +6 -6
  19. package/dist/esm/components/Headers/index.mjs.map +1 -1
  20. package/dist/esm/components/HeightResizer/index.mjs +1 -1
  21. package/dist/esm/components/HeightResizer/index.mjs.map +1 -1
  22. package/dist/esm/components/Input/Input.mjs.map +1 -1
  23. package/dist/esm/components/KeyboardShortcut/KeyboardShortcut.mjs.map +1 -1
  24. package/dist/esm/components/Link/Link.mjs +1 -1
  25. package/dist/esm/components/Link/Link.mjs.map +1 -1
  26. package/dist/esm/components/MarkDownRender/MarkDownRender.mjs +1 -1
  27. package/dist/esm/components/MarkDownRender/MarkDownRender.mjs.map +1 -1
  28. package/dist/esm/components/Modal/Modal.mjs.map +1 -1
  29. package/dist/esm/components/Navbar/Burger.mjs +1 -1
  30. package/dist/esm/components/Navbar/Burger.mjs.map +1 -1
  31. package/dist/esm/components/Navbar/MobileNavbar.mjs +1 -1
  32. package/dist/esm/components/Navbar/MobileNavbar.mjs.map +1 -1
  33. package/dist/esm/components/Pagination/Pagination.mjs.map +1 -1
  34. package/dist/esm/components/Popover/static.mjs +1 -1
  35. package/dist/esm/components/Popover/static.mjs.map +1 -1
  36. package/dist/esm/components/RightDrawer/RightDrawer.mjs +1 -1
  37. package/dist/esm/components/RightDrawer/RightDrawer.mjs.map +1 -1
  38. package/dist/esm/components/Select/Select.mjs.map +1 -1
  39. package/dist/esm/components/Steps/index.mjs +2 -2
  40. package/dist/esm/components/Steps/index.mjs.map +1 -1
  41. package/dist/esm/components/SwitchSelector/SwitchSelector.mjs +1 -1
  42. package/dist/esm/components/SwitchSelector/SwitchSelector.mjs.map +1 -1
  43. package/dist/esm/components/SwitchSelector/VerticalSwitchSelector.mjs.map +1 -1
  44. package/dist/esm/components/TabSelector/TabSelector.mjs.map +1 -1
  45. package/dist/esm/components/Tag/index.mjs.map +1 -1
  46. package/dist/esm/components/TextArea/AutoSizeTextArea.mjs +1 -1
  47. package/dist/esm/components/TextArea/AutoSizeTextArea.mjs.map +1 -1
  48. package/dist/esm/components/ThemeSwitcherDropDown/DesktopThemeSwitcher.mjs +1 -1
  49. package/dist/esm/components/ThemeSwitcherDropDown/DesktopThemeSwitcher.mjs.map +1 -1
  50. package/dist/esm/components/Toaster/Toast.mjs +1 -1
  51. package/dist/esm/components/Toaster/Toast.mjs.map +1 -1
  52. package/dist/esm/routes.mjs +4 -4
  53. package/dist/esm/routes.mjs.map +1 -1
  54. package/dist/esm/structured-data/buildAuthorJsonLd.mjs +15 -0
  55. package/dist/esm/structured-data/buildAuthorJsonLd.mjs.map +1 -0
  56. package/dist/esm/structured-data/buildBreadcrumbsJsonLd.mjs +21 -0
  57. package/dist/esm/structured-data/buildBreadcrumbsJsonLd.mjs.map +1 -0
  58. package/dist/esm/structured-data/buildCreativeWorkJsonLd.mjs +45 -0
  59. package/dist/esm/structured-data/buildCreativeWorkJsonLd.mjs.map +1 -0
  60. package/dist/esm/structured-data/buildFAQPageJsonLd.mjs +23 -0
  61. package/dist/esm/structured-data/buildFAQPageJsonLd.mjs.map +1 -0
  62. package/dist/esm/structured-data/buildOrganizationJsonLd.mjs +32 -0
  63. package/dist/esm/structured-data/buildOrganizationJsonLd.mjs.map +1 -0
  64. package/dist/esm/structured-data/buildProductJsonLd.mjs +24 -0
  65. package/dist/esm/structured-data/buildProductJsonLd.mjs.map +1 -0
  66. package/dist/esm/structured-data/buildSoftwareApplicationJsonLd.mjs +54 -0
  67. package/dist/esm/structured-data/buildSoftwareApplicationJsonLd.mjs.map +1 -0
  68. package/dist/esm/structured-data/buildWebsiteJsonLd.mjs +30 -0
  69. package/dist/esm/structured-data/buildWebsiteJsonLd.mjs.map +1 -0
  70. package/dist/esm/structured-data/index.mjs +10 -0
  71. package/dist/types/api/hooks/project.d.ts +2 -1
  72. package/dist/types/api/hooks/project.d.ts.map +1 -1
  73. package/dist/types/api/index.d.ts +2 -2
  74. package/dist/types/api/useIntlayerAPI.d.ts +1 -0
  75. package/dist/types/api/useIntlayerAPI.d.ts.map +1 -1
  76. package/dist/types/components/Badge/index.d.ts +2 -2
  77. package/dist/types/components/Breadcrumb/index.d.ts +2 -2
  78. package/dist/types/components/Breadcrumb/index.d.ts.map +1 -1
  79. package/dist/types/components/Button/Button.d.ts +6 -6
  80. package/dist/types/components/Button/Button.d.ts.map +1 -1
  81. package/dist/types/components/CollapsibleTable/CollapsibleTable.d.ts +2 -2
  82. package/dist/types/components/Command/index.d.ts +2 -2
  83. package/dist/types/components/Container/index.d.ts +3 -3
  84. package/dist/types/components/Container/index.d.ts.map +1 -1
  85. package/dist/types/components/DropDown/index.d.ts.map +1 -1
  86. package/dist/types/components/Headers/index.d.ts.map +1 -1
  87. package/dist/types/components/Input/Checkbox.d.ts +2 -2
  88. package/dist/types/components/Input/Input.d.ts.map +1 -1
  89. package/dist/types/components/Input/Radio.d.ts +2 -2
  90. package/dist/types/components/Link/Link.d.ts +2 -2
  91. package/dist/types/components/Modal/Modal.d.ts.map +1 -1
  92. package/dist/types/components/Pagination/Pagination.d.ts.map +1 -1
  93. package/dist/types/components/Select/Select.d.ts.map +1 -1
  94. package/dist/types/components/SwitchSelector/SwitchSelector.d.ts +1 -1
  95. package/dist/types/components/SwitchSelector/VerticalSwitchSelector.d.ts.map +1 -1
  96. package/dist/types/components/Tag/index.d.ts +2 -2
  97. package/dist/types/components/Tag/index.d.ts.map +1 -1
  98. package/dist/types/components/TextArea/AutoSizeTextArea.d.ts +1 -1
  99. package/dist/types/components/Toaster/Toast.d.ts +1 -1
  100. package/dist/types/routes.d.ts +6 -6
  101. package/dist/types/structured-data/buildAuthorJsonLd.d.ts +25 -0
  102. package/dist/types/structured-data/buildAuthorJsonLd.d.ts.map +1 -0
  103. package/dist/types/structured-data/buildBreadcrumbsJsonLd.d.ts +36 -0
  104. package/dist/types/structured-data/buildBreadcrumbsJsonLd.d.ts.map +1 -0
  105. package/dist/types/structured-data/buildCreativeWorkJsonLd.d.ts +80 -0
  106. package/dist/types/structured-data/buildCreativeWorkJsonLd.d.ts.map +1 -0
  107. package/dist/types/structured-data/buildFAQPageJsonLd.d.ts +32 -0
  108. package/dist/types/structured-data/buildFAQPageJsonLd.d.ts.map +1 -0
  109. package/dist/types/structured-data/buildOrganizationJsonLd.d.ts +47 -0
  110. package/dist/types/structured-data/buildOrganizationJsonLd.d.ts.map +1 -0
  111. package/dist/types/structured-data/buildProductJsonLd.d.ts +44 -0
  112. package/dist/types/structured-data/buildProductJsonLd.d.ts.map +1 -0
  113. package/dist/types/structured-data/buildSoftwareApplicationJsonLd.d.ts +83 -0
  114. package/dist/types/structured-data/buildSoftwareApplicationJsonLd.d.ts.map +1 -0
  115. package/dist/types/structured-data/buildWebsiteJsonLd.d.ts +43 -0
  116. package/dist/types/structured-data/buildWebsiteJsonLd.d.ts.map +1 -0
  117. package/dist/types/structured-data/index.d.ts +9 -0
  118. package/package.json +25 -20
  119. package/tailwind.css +11 -3
@@ -15,6 +15,17 @@ const useGetProjects = (filters, options) => {
15
15
  ...options
16
16
  });
17
17
  };
18
+ const useGetProjectInsights = (options) => {
19
+ const projectAPI = useProjectAPI();
20
+ return useAppQuery({
21
+ queryKey: ["project", "insights"],
22
+ queryFn: ({ signal }) => projectAPI.getProjectInsights({ signal }),
23
+ requireUser: true,
24
+ requireOrganization: true,
25
+ requireProject: true,
26
+ ...options
27
+ });
28
+ };
18
29
  const useAddProject = () => {
19
30
  const projectAPI = useProjectAPI();
20
31
  return useMutation({
@@ -191,5 +202,5 @@ const useUpdateMemberAccess = () => {
191
202
  };
192
203
 
193
204
  //#endregion
194
- export { useAddNewAccessKey, useAddProject, useDeleteAccessKey, useDeleteProject, useDeleteProjectById, useGetCIConfig, useGetProjects, usePushCIConfig, usePushProjectConfiguration, useRefreshAccessKey, useSelectProject, useTriggerBuild, useTriggerWebhook, useUnselectProject, useUpdateMemberAccess, useUpdateProject, useUpdateProjectMembers };
205
+ export { useAddNewAccessKey, useAddProject, useDeleteAccessKey, useDeleteProject, useDeleteProjectById, useGetCIConfig, useGetProjectInsights, useGetProjects, usePushCIConfig, usePushProjectConfiguration, useRefreshAccessKey, useSelectProject, useTriggerBuild, useTriggerWebhook, useUnselectProject, useUpdateMemberAccess, useUpdateProject, useUpdateProjectMembers };
195
206
  //# sourceMappingURL=project.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"project.mjs","names":[],"sources":["../../../../src/api/hooks/project.ts"],"sourcesContent":["'use client';\n\nimport type {\n AddNewAccessKeyBody,\n AddProjectBody,\n DeleteAccessKeyBody,\n GetProjectsParams,\n PushProjectConfigurationBody,\n RefreshAccessKeyBody,\n SelectProjectParam,\n UpdateMemberAccessBody,\n UpdateProjectBody,\n UpdateProjectMembersBody,\n} from '@intlayer/backend';\nimport {\n type UseQueryOptions,\n useMutation,\n useQueryClient,\n} from '@tanstack/react-query';\nimport { useProjectAPI } from '../useIntlayerAPI';\nimport { useAppQuery } from './utils';\n\nexport const useGetProjects = (\n filters?: GetProjectsParams,\n options?: Partial<UseQueryOptions>\n) => {\n const projectAPI = useProjectAPI();\n\n return useAppQuery({\n queryKey: ['projects', filters],\n queryFn: ({ signal }) => projectAPI.getProjects(filters, { signal }),\n // placeholderData: keepPreviousData,\n requireUser: true,\n requireOrganization: true,\n ...options,\n });\n};\n\nexport const useAddProject = () => {\n const projectAPI = useProjectAPI();\n\n return useMutation({\n mutationKey: ['projects'],\n mutationFn: (args: AddProjectBody) => projectAPI.addProject(args),\n meta: {\n invalidateQueries: [['projects']],\n },\n });\n};\n\nexport const useUpdateProject = () => {\n const projectAPI = useProjectAPI();\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationKey: ['projects'],\n mutationFn: (args: UpdateProjectBody) => projectAPI.updateProject(args),\n meta: {\n invalidateQueries: [['projects']],\n },\n onSuccess: (data) => {\n const session = queryClient.getQueryData(['session']);\n\n queryClient.setQueryData(['session'], {\n ...(session ?? {}),\n project: data.data,\n });\n },\n });\n};\n\nexport const usePushProjectConfiguration = () => {\n const projectAPI = useProjectAPI();\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationKey: ['project', 'push-configuration'],\n mutationFn: (args: PushProjectConfigurationBody) =>\n projectAPI.pushProjectConfiguration(args),\n onSuccess: (data) => {\n const session = queryClient.getQueryData(['session']);\n\n queryClient.setQueryData(['session'], {\n ...(session ?? {}),\n project: data.data,\n });\n },\n });\n};\n\nexport const useUpdateProjectMembers = () => {\n const projectAPI = useProjectAPI();\n\n return useMutation({\n mutationKey: ['projects'],\n mutationFn: (args: UpdateProjectMembersBody) =>\n projectAPI.updateProjectMembers(args),\n meta: {\n invalidateQueries: [['projects']],\n },\n });\n};\n\nexport const useDeleteProject = () => {\n const projectAPI = useProjectAPI();\n\n return useMutation({\n mutationKey: ['projects'],\n mutationFn: () => projectAPI.deleteProject(),\n meta: {\n invalidateQueries: [['projects']],\n },\n });\n};\n\nexport const useDeleteProjectById = () => {\n const projectAPI = useProjectAPI();\n\n return useMutation({\n mutationKey: ['projects'],\n mutationFn: (projectId: string) =>\n projectAPI.deleteProjectByIdAdmin(projectId),\n meta: {\n invalidateQueries: [['projects']],\n },\n });\n};\n\nexport const useSelectProject = () => {\n const projectAPI = useProjectAPI();\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationKey: ['session-projects'],\n mutationFn: (args: SelectProjectParam) => projectAPI.selectProject(args),\n meta: {\n invalidateQueries: [\n ['session'],\n ['projects'],\n ['dictionaries'],\n ['tags'],\n ['subscription'],\n ['users'],\n ],\n },\n onSuccess: (data) => {\n const session = queryClient.getQueryData(['session']);\n\n queryClient.setQueryData(['session'], {\n ...(session ?? {}),\n project: data.data,\n });\n },\n });\n};\n\nexport const useUnselectProject = () => {\n const projectAPI = useProjectAPI();\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationKey: ['session-projects'],\n mutationFn: () => projectAPI.unselectProject(),\n meta: {\n resetQueries: [\n ['session'],\n ['projects'],\n ['dictionaries'],\n ['tags'],\n ['subscription'],\n ['users'],\n ],\n },\n onSuccess: () => {\n const session = queryClient.getQueryData(['session']);\n\n queryClient.setQueryData(['session'], {\n ...(session ?? {}),\n project: null,\n });\n },\n });\n};\n\nexport const useGetCIConfig = (options?: Partial<UseQueryOptions>) => {\n const projectAPI = useProjectAPI();\n\n return useAppQuery({\n queryKey: ['ci-config'],\n queryFn: ({ signal }) => projectAPI.getCIConfig({ signal }),\n requireProject: true,\n ...options,\n });\n};\n\nexport const usePushCIConfig = () => {\n const projectAPI = useProjectAPI();\n\n return useMutation({\n mutationKey: ['ci-config'],\n mutationFn: () => projectAPI.pushCIConfig(),\n meta: {\n invalidateQueries: [['ci-config']],\n },\n });\n};\n\nexport const useTriggerBuild = () => {\n const projectAPI = useProjectAPI();\n\n return useMutation({\n mutationKey: ['projects', 'build'],\n mutationFn: () => projectAPI.triggerBuild(),\n meta: {\n invalidateQueries: [['projects']],\n },\n });\n};\n\nexport const useTriggerWebhook = () => {\n const projectAPI = useProjectAPI();\n\n return useMutation({\n mutationKey: ['projects', 'webhook'],\n mutationFn: (webhookIndex: number) =>\n projectAPI.triggerWebhook(webhookIndex),\n meta: {\n invalidateQueries: [['projects']],\n },\n });\n};\n\nexport const useAddNewAccessKey = () => {\n const projectAPI = useProjectAPI();\n\n return useMutation({\n mutationKey: ['session', 'access-keys'],\n mutationFn: (args: AddNewAccessKeyBody) => projectAPI.addNewAccessKey(args),\n meta: {\n invalidateQueries: [['session']],\n },\n });\n};\n\nexport const useDeleteAccessKey = () => {\n const projectAPI = useProjectAPI();\n\n return useMutation({\n mutationKey: ['session', 'access-keys'],\n mutationFn: (args: DeleteAccessKeyBody) => projectAPI.deleteAccessKey(args),\n meta: {\n invalidateQueries: [['session']],\n },\n });\n};\n\nexport const useRefreshAccessKey = () => {\n const projectAPI = useProjectAPI();\n\n return useMutation({\n mutationKey: ['session', 'access-keys'],\n mutationFn: (args: RefreshAccessKeyBody) =>\n projectAPI.refreshAccessKey(args),\n meta: {\n invalidateQueries: [['session']],\n },\n });\n};\n\nexport const useUpdateMemberAccess = () => {\n const projectAPI = useProjectAPI();\n\n return useMutation({\n mutationKey: ['projects', 'member-access'],\n mutationFn: ({\n userId,\n ...body\n }: UpdateMemberAccessBody & { userId: string }) =>\n projectAPI.updateMemberAccess(userId, body),\n meta: {\n invalidateQueries: [['projects'], ['session']],\n },\n });\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"project.mjs","names":[],"sources":["../../../../src/api/hooks/project.ts"],"sourcesContent":["'use client';\n\nimport type {\n AddNewAccessKeyBody,\n AddProjectBody,\n DeleteAccessKeyBody,\n GetProjectsParams,\n PushProjectConfigurationBody,\n RefreshAccessKeyBody,\n SelectProjectParam,\n UpdateMemberAccessBody,\n UpdateProjectBody,\n UpdateProjectMembersBody,\n} from '@intlayer/backend';\nimport {\n type UseQueryOptions,\n useMutation,\n useQueryClient,\n} from '@tanstack/react-query';\nimport { useProjectAPI } from '../useIntlayerAPI';\nimport { useAppQuery } from './utils';\n\nexport const useGetProjects = (\n filters?: GetProjectsParams,\n options?: Partial<UseQueryOptions>\n) => {\n const projectAPI = useProjectAPI();\n\n return useAppQuery({\n queryKey: ['projects', filters],\n queryFn: ({ signal }) => projectAPI.getProjects(filters, { signal }),\n // placeholderData: keepPreviousData,\n requireUser: true,\n requireOrganization: true,\n ...options,\n });\n};\n\nexport const useGetProjectInsights = (options?: Partial<UseQueryOptions>) => {\n const projectAPI = useProjectAPI();\n\n return useAppQuery({\n queryKey: ['project', 'insights'],\n queryFn: ({ signal }) => projectAPI.getProjectInsights({ signal }),\n requireUser: true,\n requireOrganization: true,\n requireProject: true,\n ...options,\n });\n};\n\nexport const useAddProject = () => {\n const projectAPI = useProjectAPI();\n\n return useMutation({\n mutationKey: ['projects'],\n mutationFn: (args: AddProjectBody) => projectAPI.addProject(args),\n meta: {\n invalidateQueries: [['projects']],\n },\n });\n};\n\nexport const useUpdateProject = () => {\n const projectAPI = useProjectAPI();\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationKey: ['projects'],\n mutationFn: (args: UpdateProjectBody) => projectAPI.updateProject(args),\n meta: {\n invalidateQueries: [['projects']],\n },\n onSuccess: (data) => {\n const session = queryClient.getQueryData(['session']);\n\n queryClient.setQueryData(['session'], {\n ...(session ?? {}),\n project: data.data,\n });\n },\n });\n};\n\nexport const usePushProjectConfiguration = () => {\n const projectAPI = useProjectAPI();\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationKey: ['project', 'push-configuration'],\n mutationFn: (args: PushProjectConfigurationBody) =>\n projectAPI.pushProjectConfiguration(args),\n onSuccess: (data) => {\n const session = queryClient.getQueryData(['session']);\n\n queryClient.setQueryData(['session'], {\n ...(session ?? {}),\n project: data.data,\n });\n },\n });\n};\n\nexport const useUpdateProjectMembers = () => {\n const projectAPI = useProjectAPI();\n\n return useMutation({\n mutationKey: ['projects'],\n mutationFn: (args: UpdateProjectMembersBody) =>\n projectAPI.updateProjectMembers(args),\n meta: {\n invalidateQueries: [['projects']],\n },\n });\n};\n\nexport const useDeleteProject = () => {\n const projectAPI = useProjectAPI();\n\n return useMutation({\n mutationKey: ['projects'],\n mutationFn: () => projectAPI.deleteProject(),\n meta: {\n invalidateQueries: [['projects']],\n },\n });\n};\n\nexport const useDeleteProjectById = () => {\n const projectAPI = useProjectAPI();\n\n return useMutation({\n mutationKey: ['projects'],\n mutationFn: (projectId: string) =>\n projectAPI.deleteProjectByIdAdmin(projectId),\n meta: {\n invalidateQueries: [['projects']],\n },\n });\n};\n\nexport const useSelectProject = () => {\n const projectAPI = useProjectAPI();\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationKey: ['session-projects'],\n mutationFn: (args: SelectProjectParam) => projectAPI.selectProject(args),\n meta: {\n invalidateQueries: [\n ['session'],\n ['projects'],\n ['dictionaries'],\n ['tags'],\n ['subscription'],\n ['users'],\n ],\n },\n onSuccess: (data) => {\n const session = queryClient.getQueryData(['session']);\n\n queryClient.setQueryData(['session'], {\n ...(session ?? {}),\n project: data.data,\n });\n },\n });\n};\n\nexport const useUnselectProject = () => {\n const projectAPI = useProjectAPI();\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationKey: ['session-projects'],\n mutationFn: () => projectAPI.unselectProject(),\n meta: {\n resetQueries: [\n ['session'],\n ['projects'],\n ['dictionaries'],\n ['tags'],\n ['subscription'],\n ['users'],\n ],\n },\n onSuccess: () => {\n const session = queryClient.getQueryData(['session']);\n\n queryClient.setQueryData(['session'], {\n ...(session ?? {}),\n project: null,\n });\n },\n });\n};\n\nexport const useGetCIConfig = (options?: Partial<UseQueryOptions>) => {\n const projectAPI = useProjectAPI();\n\n return useAppQuery({\n queryKey: ['ci-config'],\n queryFn: ({ signal }) => projectAPI.getCIConfig({ signal }),\n requireProject: true,\n ...options,\n });\n};\n\nexport const usePushCIConfig = () => {\n const projectAPI = useProjectAPI();\n\n return useMutation({\n mutationKey: ['ci-config'],\n mutationFn: () => projectAPI.pushCIConfig(),\n meta: {\n invalidateQueries: [['ci-config']],\n },\n });\n};\n\nexport const useTriggerBuild = () => {\n const projectAPI = useProjectAPI();\n\n return useMutation({\n mutationKey: ['projects', 'build'],\n mutationFn: () => projectAPI.triggerBuild(),\n meta: {\n invalidateQueries: [['projects']],\n },\n });\n};\n\nexport const useTriggerWebhook = () => {\n const projectAPI = useProjectAPI();\n\n return useMutation({\n mutationKey: ['projects', 'webhook'],\n mutationFn: (webhookIndex: number) =>\n projectAPI.triggerWebhook(webhookIndex),\n meta: {\n invalidateQueries: [['projects']],\n },\n });\n};\n\nexport const useAddNewAccessKey = () => {\n const projectAPI = useProjectAPI();\n\n return useMutation({\n mutationKey: ['session', 'access-keys'],\n mutationFn: (args: AddNewAccessKeyBody) => projectAPI.addNewAccessKey(args),\n meta: {\n invalidateQueries: [['session']],\n },\n });\n};\n\nexport const useDeleteAccessKey = () => {\n const projectAPI = useProjectAPI();\n\n return useMutation({\n mutationKey: ['session', 'access-keys'],\n mutationFn: (args: DeleteAccessKeyBody) => projectAPI.deleteAccessKey(args),\n meta: {\n invalidateQueries: [['session']],\n },\n });\n};\n\nexport const useRefreshAccessKey = () => {\n const projectAPI = useProjectAPI();\n\n return useMutation({\n mutationKey: ['session', 'access-keys'],\n mutationFn: (args: RefreshAccessKeyBody) =>\n projectAPI.refreshAccessKey(args),\n meta: {\n invalidateQueries: [['session']],\n },\n });\n};\n\nexport const useUpdateMemberAccess = () => {\n const projectAPI = useProjectAPI();\n\n return useMutation({\n mutationKey: ['projects', 'member-access'],\n mutationFn: ({\n userId,\n ...body\n }: UpdateMemberAccessBody & { userId: string }) =>\n projectAPI.updateMemberAccess(userId, body),\n meta: {\n invalidateQueries: [['projects'], ['session']],\n },\n });\n};\n"],"mappings":"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"}
@@ -14,7 +14,7 @@ import { useGithubAuth, useGithubCheckConfig, useGithubGetAuthUrl, useGithubGetC
14
14
  import { useGitlabAuth, useGitlabCheckConfig, useGitlabGetConfigFile, useGitlabProjects } from "./hooks/gitlab.mjs";
15
15
  import { useGetNewsletterStatus, useSubscribeToNewsletter, useUnsubscribeFromNewsletter } from "./hooks/newsletter.mjs";
16
16
  import { useAddOrganization, useAddOrganizationMember, useDeleteOrganization, useDeleteOrganizationById, useGetOrganizations, useSelectOrganization, useUnselectOrganization, useUpdateOrganization, useUpdateOrganizationMembers, useUpdateOrganizationMembersById } from "./hooks/organization.mjs";
17
- import { useAddNewAccessKey, useAddProject, useDeleteAccessKey, useDeleteProject, useDeleteProjectById, useGetCIConfig, useGetProjects, usePushCIConfig, usePushProjectConfiguration, useRefreshAccessKey, useSelectProject, useTriggerBuild, useTriggerWebhook, useUnselectProject, useUpdateMemberAccess, useUpdateProject, useUpdateProjectMembers } from "./hooks/project.mjs";
17
+ import { useAddNewAccessKey, useAddProject, useDeleteAccessKey, useDeleteProject, useDeleteProjectById, useGetCIConfig, useGetProjectInsights, useGetProjects, usePushCIConfig, usePushProjectConfiguration, useRefreshAccessKey, useSelectProject, useTriggerBuild, useTriggerWebhook, useUnselectProject, useUpdateMemberAccess, useUpdateProject, useUpdateProjectMembers } from "./hooks/project.mjs";
18
18
  import { useContactReviewer, useCreateMission, useDeleteReviewerProfile, useEstimateMission, useGetAdminReviewers, useGetChatHistory, useGetMissionById, useGetMyMissions, useGetMyReviewerProfile, useGetReviewerById, useGetReviewerMarketplace, useGetReviewerPriceDistribution, useGetReviewerReviews, useRegisterAsReviewer, useSendReviewerMessage, useSubmitReview, useUpdateMissionStatus, useUpdateReviewerProfile, useUploadReviewerCoverPicture, useUploadReviewerMainPicture, useValidateReviewerProfile } from "./hooks/reviewer.mjs";
19
19
  import { useSearchDoc } from "./hooks/search.mjs";
20
20
  import { useDeleteShowcaseProject, useGetOtherShowcaseProjects, useGetShowcaseProjectById, useGetShowcaseProjects, useSubmitShowcaseProject, useToggleShowcaseDownvote, useToggleShowcaseUpvote, useUpdateShowcaseProject } from "./hooks/showcaseProject.mjs";
@@ -24,4 +24,4 @@ import { useFillAllTranslations, usePauseTranslationJob, useResumeTranslationJob
24
24
  import { useCreateUser, useDeleteUser, useGetUserById, useGetUsers, useUpdateUser, useUploadUserAvatar } from "./hooks/user.mjs";
25
25
  import { useUser } from "./useUser/index.mjs";
26
26
 
27
- export { useAcceptAffiliateInvitation, useAddDictionary, useAddEnvironment, useAddNewAccessKey, useAddOrganization, useAddOrganizationMember, useAddPasskey, useAddProject, useAddTag, useAiAPI, useAskDocQuestion, useAskResetPassword, useAuditAPI, useAuditContentDeclaration, useAuditContentDeclarationField, useAuditContentDeclarationMetadata, useAuditScan, useAuditTag, useAuth, useAutocomplete, useBitbucketAPI, useBitbucketAuth, useBitbucketCheckConfig, useBitbucketGetConfigFile, useBitbucketRepos, useCancelSubscription, useChangePassword, useChat, useContactReviewer, useCreateMission, useCreatePortalSession, useCreatePromoCode, useCreateUser, useDeleteAccessKey, useDeleteDictionary, useDeleteEnvironment, useDeleteOrganization, useDeleteOrganizationById, useDeletePasskey, useDeleteProject, useDeleteProjectById, useDeletePromoCode, useDeleteReviewerProfile, useDeleteSSOProvider, useDeleteShowcaseProject, useDeleteTag, useDeleteUser, useDictionaryAPI, useDisableTwoFactor, useEditorAPI, useEnableTwoFactor, useEnvironmentAPI, useEstimateMission, useFillAllTranslations, useGetAdminReviewers, useGetAffiliate, useGetAffiliateAccountSession, useGetAffiliateById, useGetAffiliateInvitation, useGetAffiliateInvitations, useGetAffiliateOnboardingLink, useGetAffiliatePromoCode, useGetAffiliateStats, useGetAffiliates, useGetCIConfig, useGetChatHistory, useGetDictionaries, useGetDictionariesKeys, useGetDictionary, useGetDiscussions, useGetDiscussionsData, useGetEditorDictionaries, useGetInvoices, useGetMissionById, useGetMyMissions, useGetMyReviewerProfile, useGetNewsletterStatus, useGetOrganizations, useGetOtherShowcaseProjects, useGetPaymentMethod, useGetPricing, useGetProjects, useGetPromoCodeById, useGetPromoCodes, useGetRecursiveAuditStatus, useGetReviewerById, useGetReviewerMarketplace, useGetReviewerPriceDistribution, useGetReviewerReviews, useGetShowcaseProjectById, useGetShowcaseProjects, useGetSubscription, useGetTags, useGetUserByAccount, useGetUserById, useGetUsers, useGetVerifyEmailStatus, useGithubAPI, useGithubAuth, useGithubCheckConfig, useGithubGetAuthUrl, useGithubGetConfigFile, useGithubRepos, useGithubToken, useGitlabAPI, useGitlabAuth, useGitlabCheckConfig, useGitlabGetConfigFile, useGitlabProjects, useGrantAffiliateAccess, useInfiniteGetDictionaries, useIntlayerAuth, useIntlayerOAuth, useIntlayerOAuthOptions, useLinkSocial, useListAccounts, useListPasskeys, useListSSOProviders, useLogin, useLogout, useMigrateEnvironment, useNewsletterAPI, useOAuth2, useOAuthAPI, useOrganizationAPI, usePauseTranslationJob, useProjectAPI, usePushCIConfig, usePushDictionaries, usePushProjectConfiguration, useRefreshAccessKey, useRegister, useRegisterAsReviewer, useRegisterSSO, useResetPassword, useResetToProductionEnvironment, useResumeTranslationJob, useReviewerAPI, useSearchAPI, useSearchDoc, useSelectEnvironment, useSelectOrganization, useSelectProject, useSendAffiliateInvitation, useSendReviewerMessage, useSession, useShowcaseProjectAPI, useSignInMagicLink, useSignInPasskey, useSignInSSO, useStartRecursiveAudit, useStopTranslationJob, useStripeAPI, useSubmitReview, useSubmitShowcaseProject, useSubscribeToNewsletter, useTagAPI, useToggleShowcaseDownvote, useToggleShowcaseUpvote, useTranslateAPI, useTranslateJSONDeclaration, useTriggerBuild, useTriggerWebhook, useUnlinkAccount, useUnselectOrganization, useUnselectProject, useUnsubscribeFromNewsletter, useUpdateAffiliateStatus, useUpdateDictionary, useUpdateEnvironment, useUpdateMemberAccess, useUpdateMissionStatus, useUpdateOrganization, useUpdateOrganizationMembers, useUpdateOrganizationMembersById, useUpdateProject, useUpdateProjectMembers, useUpdatePromoCode, useUpdateReviewerProfile, useUpdateShowcaseProject, useUpdateTag, useUpdateUser, useUploadReviewerCoverPicture, useUploadReviewerMainPicture, useUploadUserAvatar, useUser, useUserAPI, useValidateReviewerProfile, useVerifyBackupCode, useVerifyEmail, useVerifyTotp, useWriteDictionary };
27
+ export { useAcceptAffiliateInvitation, useAddDictionary, useAddEnvironment, useAddNewAccessKey, useAddOrganization, useAddOrganizationMember, useAddPasskey, useAddProject, useAddTag, useAiAPI, useAskDocQuestion, useAskResetPassword, useAuditAPI, useAuditContentDeclaration, useAuditContentDeclarationField, useAuditContentDeclarationMetadata, useAuditScan, useAuditTag, useAuth, useAutocomplete, useBitbucketAPI, useBitbucketAuth, useBitbucketCheckConfig, useBitbucketGetConfigFile, useBitbucketRepos, useCancelSubscription, useChangePassword, useChat, useContactReviewer, useCreateMission, useCreatePortalSession, useCreatePromoCode, useCreateUser, useDeleteAccessKey, useDeleteDictionary, useDeleteEnvironment, useDeleteOrganization, useDeleteOrganizationById, useDeletePasskey, useDeleteProject, useDeleteProjectById, useDeletePromoCode, useDeleteReviewerProfile, useDeleteSSOProvider, useDeleteShowcaseProject, useDeleteTag, useDeleteUser, useDictionaryAPI, useDisableTwoFactor, useEditorAPI, useEnableTwoFactor, useEnvironmentAPI, useEstimateMission, useFillAllTranslations, useGetAdminReviewers, useGetAffiliate, useGetAffiliateAccountSession, useGetAffiliateById, useGetAffiliateInvitation, useGetAffiliateInvitations, useGetAffiliateOnboardingLink, useGetAffiliatePromoCode, useGetAffiliateStats, useGetAffiliates, useGetCIConfig, useGetChatHistory, useGetDictionaries, useGetDictionariesKeys, useGetDictionary, useGetDiscussions, useGetDiscussionsData, useGetEditorDictionaries, useGetInvoices, useGetMissionById, useGetMyMissions, useGetMyReviewerProfile, useGetNewsletterStatus, useGetOrganizations, useGetOtherShowcaseProjects, useGetPaymentMethod, useGetPricing, useGetProjectInsights, useGetProjects, useGetPromoCodeById, useGetPromoCodes, useGetRecursiveAuditStatus, useGetReviewerById, useGetReviewerMarketplace, useGetReviewerPriceDistribution, useGetReviewerReviews, useGetShowcaseProjectById, useGetShowcaseProjects, useGetSubscription, useGetTags, useGetUserByAccount, useGetUserById, useGetUsers, useGetVerifyEmailStatus, useGithubAPI, useGithubAuth, useGithubCheckConfig, useGithubGetAuthUrl, useGithubGetConfigFile, useGithubRepos, useGithubToken, useGitlabAPI, useGitlabAuth, useGitlabCheckConfig, useGitlabGetConfigFile, useGitlabProjects, useGrantAffiliateAccess, useInfiniteGetDictionaries, useIntlayerAuth, useIntlayerOAuth, useIntlayerOAuthOptions, useLinkSocial, useListAccounts, useListPasskeys, useListSSOProviders, useLogin, useLogout, useMigrateEnvironment, useNewsletterAPI, useOAuth2, useOAuthAPI, useOrganizationAPI, usePauseTranslationJob, useProjectAPI, usePushCIConfig, usePushDictionaries, usePushProjectConfiguration, useRefreshAccessKey, useRegister, useRegisterAsReviewer, useRegisterSSO, useResetPassword, useResetToProductionEnvironment, useResumeTranslationJob, useReviewerAPI, useSearchAPI, useSearchDoc, useSelectEnvironment, useSelectOrganization, useSelectProject, useSendAffiliateInvitation, useSendReviewerMessage, useSession, useShowcaseProjectAPI, useSignInMagicLink, useSignInPasskey, useSignInSSO, useStartRecursiveAudit, useStopTranslationJob, useStripeAPI, useSubmitReview, useSubmitShowcaseProject, useSubscribeToNewsletter, useTagAPI, useToggleShowcaseDownvote, useToggleShowcaseUpvote, useTranslateAPI, useTranslateJSONDeclaration, useTriggerBuild, useTriggerWebhook, useUnlinkAccount, useUnselectOrganization, useUnselectProject, useUnsubscribeFromNewsletter, useUpdateAffiliateStatus, useUpdateDictionary, useUpdateEnvironment, useUpdateMemberAccess, useUpdateMissionStatus, useUpdateOrganization, useUpdateOrganizationMembers, useUpdateOrganizationMembersById, useUpdateProject, useUpdateProjectMembers, useUpdatePromoCode, useUpdateReviewerProfile, useUpdateShowcaseProject, useUpdateTag, useUpdateUser, useUploadReviewerCoverPicture, useUploadReviewerMainPicture, useUploadUserAvatar, useUser, useUserAPI, useValidateReviewerProfile, useVerifyBackupCode, useVerifyEmail, useVerifyTotp, useWriteDictionary };
@@ -85,7 +85,7 @@ const Avatar = ({ fullname, className, isLoading = false, isLoggedIn = true, src
85
85
  ]);
86
86
  return /* @__PURE__ */ jsx(Container, {
87
87
  isClickable,
88
- className: cn(`rounded-full border-[1.3px] border-text p-[1.5px] ring-offset-0 transition-ring duration-200`, size === "sm" && "size-7 border-[1px] p-[1px]", size === "md" && "size-9", size === "lg" && "size-12", size === "xl" && "size-16", size === "2xl" && "size-24", isClickable && `cursor-pointer hover:opacity-80 focus:outline-none focus:ring-3 focus:ring-text/50 focus:ring-offset-2`, hoverable && `hover:opacity-80 hover:ring-4 hover:ring-text/30 hover:ring-offset-2`, !isClickable && focusable && `focus:outline-none focus:ring-3 focus:ring-text/50 focus:ring-offset-2`, displayLoader && "animate-pulse", className),
88
+ className: cn(`rounded-full border-[1.3px] border-text p-0.38 ring-offset-0 transition-ring duration-200`, size === "sm" && "size-7 border-[1px] p-0.25", size === "md" && "size-9", size === "lg" && "size-12", size === "xl" && "size-16", size === "2xl" && "size-24", isClickable && `cursor-pointer hover:opacity-80 focus:outline-none focus:ring-3 focus:ring-text/50 focus:ring-offset-2`, hoverable && `hover:opacity-80 hover:ring-4 hover:ring-text/30 hover:ring-offset-2`, !isClickable && focusable && `focus:outline-none focus:ring-3 focus:ring-text/50 focus:ring-offset-2`, displayLoader && "animate-pulse", className),
89
89
  onClick,
90
90
  ...accessibilityProps,
91
91
  ...props,
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../../../src/components/Avatar/index.tsx"],"sourcesContent":["import { cn } from '@utils/cn';\nimport { User } from 'lucide-react';\nimport type { ComponentProps, FC, HTMLAttributes } from 'react';\nimport { useMemo } from 'react';\nimport { Loader } from '../Loader';\n\n/**\n * Props for the Avatar component\n */\nexport interface AvatarProps extends Omit<ComponentProps<'button'>, 'onClick'> {\n /** Image source URL for the avatar */\n src?: string;\n /** Full name used to generate initials and alt text */\n fullname?: string;\n /** Displays a loading spinner when true */\n isLoading?: boolean;\n /** Whether the user is authenticated */\n isLoggedIn?: boolean;\n /** Size variant of the avatar */\n size?: 'sm' | 'md' | 'lg' | 'xl' | '2xl';\n /** Click handler - when provided, makes the avatar clickable */\n onClick?: (event: React.MouseEvent<HTMLButtonElement>) => void;\n /** Alternative text for accessibility */\n alt?: string;\n /** Whether the avatar should be focusable when not clickable */\n focusable?: boolean;\n /** Whether the avatar should be hoverable */\n hoverable?: boolean;\n}\n\n/**\n * @description Gets the capital letters from a name.\n * @param name - The name to extract capitals from.\n * @param separator - The separator to split the name (default is an empty string, which splits by each character).\n * @returns {string[]} An array of capital letters from the name.\n */\nexport const getCapitals = (name: string, separator = ' '): string[] => {\n if (!name) return [];\n\n const parts =\n separator === ' '\n ? name.trim().split(/\\s+/) // handle multiple spaces\n : name.split(separator);\n\n return parts.filter(Boolean).map((word) => word.charAt(0).toUpperCase());\n};\n\n/**\n * Container component that renders either a button or div based on interactivity\n */\nconst Container: FC<\n HTMLAttributes<HTMLElement> & {\n isClickable: boolean;\n onClick?: (event: React.MouseEvent<HTMLButtonElement>) => void;\n }\n> = ({ isClickable, onClick, ...props }) => {\n if (isClickable && onClick) {\n return (\n <button\n {...(props as ComponentProps<'button'>)}\n onClick={onClick}\n type=\"button\"\n />\n );\n }\n\n return (\n <div\n {...(props as ComponentProps<'div'>)}\n role={\n props.tabIndex !== undefined || props['aria-label'] ? 'img' : undefined\n }\n />\n );\n};\n\n/**\n * Avatar component that displays user profile images, initials, or a default user icon.\n * Supports loading states, authentication states, and accessibility features.\n *\n * @example\n * ```tsx\n * // With image\n * <Avatar src=\"https://example.com/avatar.jpg\" fullname=\"John Doe\" />\n *\n * // With initials\n * <Avatar fullname=\"John Doe\" />\n *\n * // Clickable avatar\n * <Avatar\n * fullname=\"John Doe\"\n * onClick={(e) => console.log('Avatar clicked')}\n * />\n *\n * // Loading state\n * <Avatar isLoading fullname=\"John Doe\" />\n * ```\n */\nexport const Avatar: FC<AvatarProps> = ({\n fullname,\n className,\n isLoading = false,\n isLoggedIn = true,\n src,\n onClick,\n size = 'md',\n alt,\n focusable = false,\n hoverable = false,\n ...props\n}) => {\n const isImageDefined = Boolean(src);\n const isNameDefined = Boolean((fullname ?? '').length > 0);\n const capitals = fullname ? getCapitals(fullname) : undefined;\n\n // Display logic\n const displayLoader = isLoading;\n const displayAvatar = isLoggedIn && !displayLoader && isImageDefined;\n const displayInitials =\n isLoggedIn && !displayLoader && !displayAvatar && isNameDefined;\n const displayUserIcon =\n isLoggedIn && !displayLoader && !displayAvatar && !displayInitials;\n\n const isClickable = onClick !== undefined;\n\n // Accessibility attributes\n const accessibilityProps = useMemo(() => {\n const baseProps: Record<string, any> = {};\n\n if (displayAvatar && alt) {\n baseProps['aria-label'] = alt;\n } else if (displayAvatar && fullname) {\n baseProps['aria-label'] = `Avatar of ${fullname}`;\n } else if (displayInitials && fullname) {\n baseProps['aria-label'] = `Avatar initials for ${fullname}`;\n } else if (displayUserIcon) {\n baseProps['aria-label'] = 'Default user avatar';\n } else if (displayLoader) {\n baseProps['aria-label'] = 'Loading avatar';\n baseProps['aria-busy'] = true;\n }\n\n if (!isClickable && focusable) {\n baseProps.tabIndex = 0;\n }\n\n if (isClickable) {\n baseProps['aria-describedby'] = 'avatar-description';\n }\n\n return baseProps;\n }, [\n displayAvatar,\n displayInitials,\n displayUserIcon,\n displayLoader,\n alt,\n fullname,\n isClickable,\n focusable,\n ]);\n\n return (\n <Container\n isClickable={isClickable}\n className={cn(\n `rounded-full border-[1.3px] border-text p-[1.5px] ring-offset-0 transition-ring duration-200`,\n size === 'sm' && 'size-7 border-[1px] p-[1px]',\n size === 'md' && 'size-9',\n size === 'lg' && 'size-12',\n size === 'xl' && 'size-16',\n size === '2xl' && 'size-24',\n isClickable &&\n `cursor-pointer hover:opacity-80 focus:outline-none focus:ring-3 focus:ring-text/50 focus:ring-offset-2`,\n hoverable &&\n `hover:opacity-80 hover:ring-4 hover:ring-text/30 hover:ring-offset-2`,\n !isClickable &&\n focusable &&\n `focus:outline-none focus:ring-3 focus:ring-text/50 focus:ring-offset-2`,\n displayLoader && 'animate-pulse',\n className\n )}\n onClick={onClick}\n {...accessibilityProps}\n {...props}\n >\n <div className=\"relative flex aspect-square size-full flex-row items-center justify-center\">\n <div className=\"absolute top-0 left-0 flex aspect-square size-full flex-col items-center justify-center rounded-full bg-text text-text-opposite\">\n {displayLoader && (\n <Loader className=\"w-3/4\" aria-label=\"Loading user avatar\" />\n )}\n\n {displayAvatar && (\n <img\n className=\"size-full rounded-full object-cover\"\n src={src}\n srcSet={src}\n alt={alt ?? `Avatar of ${fullname}`}\n width={59}\n height={59}\n loading=\"lazy\"\n draggable={false}\n />\n )}\n\n {displayInitials && (\n <div\n className={cn(\n 'flex size-full items-center justify-center gap-[0.1rem] font-bold max-md:py-1',\n size === 'sm' && 'text-xs',\n size === 'md' && 'text-sm',\n size === 'lg' && 'text-base',\n size === 'xl' && 'text-lg',\n size === '2xl' && 'text-xl'\n )}\n >\n {capitals?.map((capital, index) => (\n // biome-ignore lint/suspicious/noArrayIndexKey: Capitals are primitives and order is fixed\n <span key={`${capital}-${index}`}>{capital}</span>\n ))}\n </div>\n )}\n\n {displayUserIcon && (\n <User\n size={cn(\n size === 'sm' && 14,\n size === 'md' && 25,\n size === 'lg' && 30,\n size === 'xl' && 40\n )}\n aria-label=\"Default user icon\"\n />\n )}\n </div>\n </div>\n </Container>\n );\n};\n"],"mappings":";;;;;;;;;;;;;AAoCA,MAAa,eAAe,MAAc,YAAY,QAAkB;AACtE,KAAI,CAAC,KAAM,QAAO,EAAE;AAOpB,SAJE,cAAc,MACV,KAAK,MAAM,CAAC,MAAM,MAAM,GACxB,KAAK,MAAM,UAAU,EAEd,OAAO,QAAQ,CAAC,KAAK,SAAS,KAAK,OAAO,EAAE,CAAC,aAAa,CAAC;;;;;AAM1E,MAAM,aAKD,EAAE,aAAa,SAAS,GAAG,YAAY;AAC1C,KAAI,eAAe,QACjB,QACE,oBAAC,UAAD;EACE,GAAK;EACI;EACT,MAAK;EACL;AAIN,QACE,oBAAC,OAAD;EACE,GAAK;EACL,MACE,MAAM,aAAa,UAAa,MAAM,gBAAgB,QAAQ;EAEhE;;;;;;;;;;;;;;;;;;;;;;;;AA0BN,MAAa,UAA2B,EACtC,UACA,WACA,YAAY,OACZ,aAAa,MACb,KACA,SACA,OAAO,MACP,KACA,YAAY,OACZ,YAAY,OACZ,GAAG,YACC;CACJ,MAAM,iBAAiB,QAAQ,IAAI;CACnC,MAAM,gBAAgB,SAAS,YAAY,IAAI,SAAS,EAAE;CAC1D,MAAM,WAAW,WAAW,YAAY,SAAS,GAAG;CAGpD,MAAM,gBAAgB;CACtB,MAAM,gBAAgB,cAAc,CAAC,iBAAiB;CACtD,MAAM,kBACJ,cAAc,CAAC,iBAAiB,CAAC,iBAAiB;CACpD,MAAM,kBACJ,cAAc,CAAC,iBAAiB,CAAC,iBAAiB,CAAC;CAErD,MAAM,cAAc,YAAY;CAGhC,MAAM,qBAAqB,cAAc;EACvC,MAAM,YAAiC,EAAE;AAEzC,MAAI,iBAAiB,IACnB,WAAU,gBAAgB;WACjB,iBAAiB,SAC1B,WAAU,gBAAgB,aAAa;WAC9B,mBAAmB,SAC5B,WAAU,gBAAgB,uBAAuB;WACxC,gBACT,WAAU,gBAAgB;WACjB,eAAe;AACxB,aAAU,gBAAgB;AAC1B,aAAU,eAAe;;AAG3B,MAAI,CAAC,eAAe,UAClB,WAAU,WAAW;AAGvB,MAAI,YACF,WAAU,sBAAsB;AAGlC,SAAO;IACN;EACD;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CAAC;AAEF,QACE,oBAAC,WAAD;EACe;EACb,WAAW,GACT,gGACA,SAAS,QAAQ,+BACjB,SAAS,QAAQ,UACjB,SAAS,QAAQ,WACjB,SAAS,QAAQ,WACjB,SAAS,SAAS,WAClB,eACE,0GACF,aACE,wEACF,CAAC,eACC,aACA,0EACF,iBAAiB,iBACjB,UACD;EACQ;EACT,GAAI;EACJ,GAAI;YAEJ,oBAAC,OAAD;GAAK,WAAU;aACb,qBAAC,OAAD;IAAK,WAAU;cAAf;KACG,iBACC,oBAAC,QAAD;MAAQ,WAAU;MAAQ,cAAW;MAAwB;KAG9D,iBACC,oBAAC,OAAD;MACE,WAAU;MACL;MACL,QAAQ;MACR,KAAK,OAAO,aAAa;MACzB,OAAO;MACP,QAAQ;MACR,SAAQ;MACR,WAAW;MACX;KAGH,mBACC,oBAAC,OAAD;MACE,WAAW,GACT,iFACA,SAAS,QAAQ,WACjB,SAAS,QAAQ,WACjB,SAAS,QAAQ,aACjB,SAAS,QAAQ,WACjB,SAAS,SAAS,UACnB;gBAEA,UAAU,KAAK,SAAS,UAEvB,oBAAC,QAAD,YAAmC,SAAe,EAAvC,GAAG,QAAQ,GAAG,QAAyB,CAClD;MACE;KAGP,mBACC,oBAAC,MAAD;MACE,MAAM,GACJ,SAAS,QAAQ,IACjB,SAAS,QAAQ,IACjB,SAAS,QAAQ,IACjB,SAAS,QAAQ,GAClB;MACD,cAAW;MACX;KAEA;;GACF;EACI"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../../../src/components/Avatar/index.tsx"],"sourcesContent":["import { cn } from '@utils/cn';\nimport { User } from 'lucide-react';\nimport type { ComponentProps, FC, HTMLAttributes } from 'react';\nimport { useMemo } from 'react';\nimport { Loader } from '../Loader';\n\n/**\n * Props for the Avatar component\n */\nexport interface AvatarProps extends Omit<ComponentProps<'button'>, 'onClick'> {\n /** Image source URL for the avatar */\n src?: string;\n /** Full name used to generate initials and alt text */\n fullname?: string;\n /** Displays a loading spinner when true */\n isLoading?: boolean;\n /** Whether the user is authenticated */\n isLoggedIn?: boolean;\n /** Size variant of the avatar */\n size?: 'sm' | 'md' | 'lg' | 'xl' | '2xl';\n /** Click handler - when provided, makes the avatar clickable */\n onClick?: (event: React.MouseEvent<HTMLButtonElement>) => void;\n /** Alternative text for accessibility */\n alt?: string;\n /** Whether the avatar should be focusable when not clickable */\n focusable?: boolean;\n /** Whether the avatar should be hoverable */\n hoverable?: boolean;\n}\n\n/**\n * @description Gets the capital letters from a name.\n * @param name - The name to extract capitals from.\n * @param separator - The separator to split the name (default is an empty string, which splits by each character).\n * @returns {string[]} An array of capital letters from the name.\n */\nexport const getCapitals = (name: string, separator = ' '): string[] => {\n if (!name) return [];\n\n const parts =\n separator === ' '\n ? name.trim().split(/\\s+/) // handle multiple spaces\n : name.split(separator);\n\n return parts.filter(Boolean).map((word) => word.charAt(0).toUpperCase());\n};\n\n/**\n * Container component that renders either a button or div based on interactivity\n */\nconst Container: FC<\n HTMLAttributes<HTMLElement> & {\n isClickable: boolean;\n onClick?: (event: React.MouseEvent<HTMLButtonElement>) => void;\n }\n> = ({ isClickable, onClick, ...props }) => {\n if (isClickable && onClick) {\n return (\n <button\n {...(props as ComponentProps<'button'>)}\n onClick={onClick}\n type=\"button\"\n />\n );\n }\n\n return (\n <div\n {...(props as ComponentProps<'div'>)}\n role={\n props.tabIndex !== undefined || props['aria-label'] ? 'img' : undefined\n }\n />\n );\n};\n\n/**\n * Avatar component that displays user profile images, initials, or a default user icon.\n * Supports loading states, authentication states, and accessibility features.\n *\n * @example\n * ```tsx\n * // With image\n * <Avatar src=\"https://example.com/avatar.jpg\" fullname=\"John Doe\" />\n *\n * // With initials\n * <Avatar fullname=\"John Doe\" />\n *\n * // Clickable avatar\n * <Avatar\n * fullname=\"John Doe\"\n * onClick={(e) => console.log('Avatar clicked')}\n * />\n *\n * // Loading state\n * <Avatar isLoading fullname=\"John Doe\" />\n * ```\n */\nexport const Avatar: FC<AvatarProps> = ({\n fullname,\n className,\n isLoading = false,\n isLoggedIn = true,\n src,\n onClick,\n size = 'md',\n alt,\n focusable = false,\n hoverable = false,\n ...props\n}) => {\n const isImageDefined = Boolean(src);\n const isNameDefined = Boolean((fullname ?? '').length > 0);\n const capitals = fullname ? getCapitals(fullname) : undefined;\n\n // Display logic\n const displayLoader = isLoading;\n const displayAvatar = isLoggedIn && !displayLoader && isImageDefined;\n const displayInitials =\n isLoggedIn && !displayLoader && !displayAvatar && isNameDefined;\n const displayUserIcon =\n isLoggedIn && !displayLoader && !displayAvatar && !displayInitials;\n\n const isClickable = onClick !== undefined;\n\n // Accessibility attributes\n const accessibilityProps = useMemo(() => {\n const baseProps: Record<string, any> = {};\n\n if (displayAvatar && alt) {\n baseProps['aria-label'] = alt;\n } else if (displayAvatar && fullname) {\n baseProps['aria-label'] = `Avatar of ${fullname}`;\n } else if (displayInitials && fullname) {\n baseProps['aria-label'] = `Avatar initials for ${fullname}`;\n } else if (displayUserIcon) {\n baseProps['aria-label'] = 'Default user avatar';\n } else if (displayLoader) {\n baseProps['aria-label'] = 'Loading avatar';\n baseProps['aria-busy'] = true;\n }\n\n if (!isClickable && focusable) {\n baseProps.tabIndex = 0;\n }\n\n if (isClickable) {\n baseProps['aria-describedby'] = 'avatar-description';\n }\n\n return baseProps;\n }, [\n displayAvatar,\n displayInitials,\n displayUserIcon,\n displayLoader,\n alt,\n fullname,\n isClickable,\n focusable,\n ]);\n\n return (\n <Container\n isClickable={isClickable}\n className={cn(\n `rounded-full border-[1.3px] border-text p-0.38 ring-offset-0 transition-ring duration-200`,\n size === 'sm' && 'size-7 border-[1px] p-0.25',\n size === 'md' && 'size-9',\n size === 'lg' && 'size-12',\n size === 'xl' && 'size-16',\n size === '2xl' && 'size-24',\n isClickable &&\n `cursor-pointer hover:opacity-80 focus:outline-none focus:ring-3 focus:ring-text/50 focus:ring-offset-2`,\n hoverable &&\n `hover:opacity-80 hover:ring-4 hover:ring-text/30 hover:ring-offset-2`,\n !isClickable &&\n focusable &&\n `focus:outline-none focus:ring-3 focus:ring-text/50 focus:ring-offset-2`,\n displayLoader && 'animate-pulse',\n className\n )}\n onClick={onClick}\n {...accessibilityProps}\n {...props}\n >\n <div className=\"relative flex aspect-square size-full flex-row items-center justify-center\">\n <div className=\"absolute top-0 left-0 flex aspect-square size-full flex-col items-center justify-center rounded-full bg-text text-text-opposite\">\n {displayLoader && (\n <Loader className=\"w-3/4\" aria-label=\"Loading user avatar\" />\n )}\n\n {displayAvatar && (\n <img\n className=\"size-full rounded-full object-cover\"\n src={src}\n srcSet={src}\n alt={alt ?? `Avatar of ${fullname}`}\n width={59}\n height={59}\n loading=\"lazy\"\n draggable={false}\n />\n )}\n\n {displayInitials && (\n <div\n className={cn(\n 'flex size-full items-center justify-center gap-[0.1rem] font-bold max-md:py-1',\n size === 'sm' && 'text-xs',\n size === 'md' && 'text-sm',\n size === 'lg' && 'text-base',\n size === 'xl' && 'text-lg',\n size === '2xl' && 'text-xl'\n )}\n >\n {capitals?.map((capital, index) => (\n // biome-ignore lint/suspicious/noArrayIndexKey: Capitals are primitives and order is fixed\n <span key={`${capital}-${index}`}>{capital}</span>\n ))}\n </div>\n )}\n\n {displayUserIcon && (\n <User\n size={cn(\n size === 'sm' && 14,\n size === 'md' && 25,\n size === 'lg' && 30,\n size === 'xl' && 40\n )}\n aria-label=\"Default user icon\"\n />\n )}\n </div>\n </div>\n </Container>\n );\n};\n"],"mappings":";;;;;;;;;;;;;AAoCA,MAAa,eAAe,MAAc,YAAY,QAAkB;AACtE,KAAI,CAAC,KAAM,QAAO,EAAE;AAOpB,SAJE,cAAc,MACV,KAAK,MAAM,CAAC,MAAM,MAAM,GACxB,KAAK,MAAM,UAAU,EAEd,OAAO,QAAQ,CAAC,KAAK,SAAS,KAAK,OAAO,EAAE,CAAC,aAAa,CAAC;;;;;AAM1E,MAAM,aAKD,EAAE,aAAa,SAAS,GAAG,YAAY;AAC1C,KAAI,eAAe,QACjB,QACE,oBAAC,UAAD;EACE,GAAK;EACI;EACT,MAAK;EACL;AAIN,QACE,oBAAC,OAAD;EACE,GAAK;EACL,MACE,MAAM,aAAa,UAAa,MAAM,gBAAgB,QAAQ;EAEhE;;;;;;;;;;;;;;;;;;;;;;;;AA0BN,MAAa,UAA2B,EACtC,UACA,WACA,YAAY,OACZ,aAAa,MACb,KACA,SACA,OAAO,MACP,KACA,YAAY,OACZ,YAAY,OACZ,GAAG,YACC;CACJ,MAAM,iBAAiB,QAAQ,IAAI;CACnC,MAAM,gBAAgB,SAAS,YAAY,IAAI,SAAS,EAAE;CAC1D,MAAM,WAAW,WAAW,YAAY,SAAS,GAAG;CAGpD,MAAM,gBAAgB;CACtB,MAAM,gBAAgB,cAAc,CAAC,iBAAiB;CACtD,MAAM,kBACJ,cAAc,CAAC,iBAAiB,CAAC,iBAAiB;CACpD,MAAM,kBACJ,cAAc,CAAC,iBAAiB,CAAC,iBAAiB,CAAC;CAErD,MAAM,cAAc,YAAY;CAGhC,MAAM,qBAAqB,cAAc;EACvC,MAAM,YAAiC,EAAE;AAEzC,MAAI,iBAAiB,IACnB,WAAU,gBAAgB;WACjB,iBAAiB,SAC1B,WAAU,gBAAgB,aAAa;WAC9B,mBAAmB,SAC5B,WAAU,gBAAgB,uBAAuB;WACxC,gBACT,WAAU,gBAAgB;WACjB,eAAe;AACxB,aAAU,gBAAgB;AAC1B,aAAU,eAAe;;AAG3B,MAAI,CAAC,eAAe,UAClB,WAAU,WAAW;AAGvB,MAAI,YACF,WAAU,sBAAsB;AAGlC,SAAO;IACN;EACD;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CAAC;AAEF,QACE,oBAAC,WAAD;EACe;EACb,WAAW,GACT,6FACA,SAAS,QAAQ,8BACjB,SAAS,QAAQ,UACjB,SAAS,QAAQ,WACjB,SAAS,QAAQ,WACjB,SAAS,SAAS,WAClB,eACE,0GACF,aACE,wEACF,CAAC,eACC,aACA,0EACF,iBAAiB,iBACjB,UACD;EACQ;EACT,GAAI;EACJ,GAAI;YAEJ,oBAAC,OAAD;GAAK,WAAU;aACb,qBAAC,OAAD;IAAK,WAAU;cAAf;KACG,iBACC,oBAAC,QAAD;MAAQ,WAAU;MAAQ,cAAW;MAAwB;KAG9D,iBACC,oBAAC,OAAD;MACE,WAAU;MACL;MACL,QAAQ;MACR,KAAK,OAAO,aAAa;MACzB,OAAO;MACP,QAAQ;MACR,SAAQ;MACR,WAAW;MACX;KAGH,mBACC,oBAAC,OAAD;MACE,WAAW,GACT,iFACA,SAAS,QAAQ,WACjB,SAAS,QAAQ,WACjB,SAAS,QAAQ,aACjB,SAAS,QAAQ,WACjB,SAAS,SAAS,UACnB;gBAEA,UAAU,KAAK,SAAS,UAEvB,oBAAC,QAAD,YAAmC,SAAe,EAAvC,GAAG,QAAQ,GAAG,QAAyB,CAClD;MACE;KAGP,mBACC,oBAAC,MAAD;MACE,MAAM,GACJ,SAAS,QAAQ,IACjB,SAAS,QAAQ,IACjB,SAAS,QAAQ,IACjB,SAAS,QAAQ,GAClB;MACD,cAAW;MACX;KAEA;;GACF;EACI"}
@@ -32,12 +32,14 @@ const getColorClass = (color) => {
32
32
  /**
33
33
  * Breadcrumb variant styles using class-variance-authority
34
34
  */
35
- const breadcrumbVariants = cva("flex flex-row flex-wrap items-center text-sm", {
35
+ const breadcrumbVariants = cva("flex flex-row flex-wrap items-center", {
36
36
  variants: {
37
37
  size: {
38
- small: "gap-1 text-xs",
39
- medium: "gap-2 text-sm",
40
- large: "gap-3 text-base"
38
+ xs: "gap-1 text-xs",
39
+ sm: "gap-1.5 text-sm",
40
+ md: "gap-2 text-base",
41
+ lg: "gap-3 text-lg",
42
+ xl: "gap-4 text-xl"
41
43
  },
42
44
  spacing: {
43
45
  compact: "gap-1",
@@ -46,7 +48,7 @@ const breadcrumbVariants = cva("flex flex-row flex-wrap items-center text-sm", {
46
48
  }
47
49
  },
48
50
  defaultVariants: {
49
- size: "medium",
51
+ size: "md",
50
52
  spacing: "normal"
51
53
  }
52
54
  });
@@ -67,7 +69,7 @@ const LinkLink = ({ href, lang, children, onClick, color, position, locale, clas
67
69
  ...props,
68
70
  label: `${linkLabel} ${children}`,
69
71
  itemID: href,
70
- size: "sm",
72
+ size: "custom",
71
73
  children: /* @__PURE__ */ jsx("span", {
72
74
  itemProp: "name",
73
75
  children
@@ -88,6 +90,7 @@ const ButtonLink = ({ children: text, onClick, color, position, className, ...pr
88
90
  label: `${linkLabel} ${text}`,
89
91
  color,
90
92
  itemProp: "item",
93
+ size: "custom",
91
94
  ...props,
92
95
  children: /* @__PURE__ */ jsx("span", {
93
96
  itemProp: "name",
@@ -134,7 +137,7 @@ const Span = ({ children, position, className, ...props }) => /* @__PURE__ */ js
134
137
  * { onClick: handleCategory, text: 'Electronics' },
135
138
  * 'Smartphones'
136
139
  * ]}
137
- * size="medium"
140
+ * size="md"
138
141
  * ariaLabel="Product navigation"
139
142
  * />
140
143
  * ```
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../../../src/components/Breadcrumb/index.tsx"],"sourcesContent":["'use client';\n\nimport type { LocalesValues } from '@intlayer/types/module_augmentation';\nimport { cn } from '@utils/cn';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { getIntlayer } from 'intlayer';\nimport { ChevronRightIcon } from 'lucide-react';\nimport { type FC, Fragment, type HTMLAttributes, type ReactNode } from 'react';\nimport { useIntlayer } from 'react-intlayer';\nimport { Button, type ButtonProps } from '../Button';\nimport { Link, type LinkColor } from '../Link';\n\n/**\n * Props for LinkLink sub-component that renders breadcrumb items as links\n */\ntype LinkLinkProps = {\n /**\n * Position of the breadcrumb item in the list (1-based index)\n */\n position: number;\n /**\n * Locale for internationalization\n */\n locale?: LocalesValues;\n /**\n * URL to navigate to\n */\n href?: string;\n /**\n * Link color\n */\n color?: LinkColor | `${LinkColor}`;\n /**\n * Click handler\n */\n onClick?: () => void;\n /**\n * Children content\n */\n children?: string;\n /**\n * Additional CSS classes\n */\n className?: string;\n} & Omit<\n HTMLAttributes<HTMLAnchorElement>,\n 'href' | 'onClick' | 'color' | 'children' | 'className'\n>;\n\n/**\n * Maps LinkColor to corresponding Tailwind text color classes\n */\nconst getColorClass = (color?: LinkColor | `${LinkColor}`): string => {\n if (!color) return '';\n\n const colorMap: Record<LinkColor, string> = {\n primary: 'text-primary',\n secondary: 'text-secondary',\n neutral: 'text-neutral',\n light: 'text-white',\n dark: 'text-neutral-800',\n text: 'text-text',\n 'text-inverse': 'text-text-opposite',\n error: 'text-error',\n success: 'text-success',\n custom: '',\n };\n\n return colorMap[color as LinkColor] || '';\n};\n\n/**\n * Breadcrumb variant styles using class-variance-authority\n */\nconst breadcrumbVariants = cva('flex flex-row flex-wrap items-center text-sm', {\n variants: {\n size: {\n small: 'gap-1 text-xs',\n medium: 'gap-2 text-sm',\n large: 'gap-3 text-base',\n },\n spacing: {\n compact: 'gap-1',\n normal: 'gap-2',\n loose: 'gap-4',\n },\n },\n defaultVariants: {\n size: 'medium',\n spacing: 'normal',\n },\n});\n\n/**\n * LinkLink sub-component for breadcrumb items that navigate to other pages\n */\nconst LinkLink: FC<LinkLinkProps> = ({\n href,\n lang,\n children,\n onClick,\n color,\n position,\n locale,\n className,\n ...props\n}) => {\n const content = getIntlayer('breadcrumb');\n const linkLabel = content.linkLabel;\n\n return (\n <>\n <Link\n href={href}\n locale={locale}\n color={color}\n onClick={onClick}\n itemProp=\"item\"\n isExternalLink={false}\n itemScope\n itemType=\"https://schema.org/WebPage\"\n {...props}\n label={`${linkLabel} ${children}`}\n itemID={href}\n size=\"sm\"\n >\n <span itemProp=\"name\">{children}</span>\n </Link>\n <meta itemProp=\"position\" content={position.toString()} />\n </>\n );\n};\n\n/**\n * Props for ButtonLink sub-component that renders breadcrumb items as interactive buttons\n */\ntype ButtonButtonProps = {\n /**\n * Text content for the breadcrumb button\n */\n children: string;\n /**\n * Position of the breadcrumb item in the list (1-based index)\n */\n position: number;\n} & Omit<ButtonProps, 'children' | 'label'>;\n\n/**\n * ButtonLink sub-component for breadcrumb items with click handlers\n */\nconst ButtonLink: FC<ButtonButtonProps> = ({\n children: text,\n onClick,\n color,\n position,\n className,\n ...props\n}) => {\n const { linkLabel } = useIntlayer('breadcrumb');\n\n return (\n <>\n <Button\n onClick={onClick}\n variant=\"link\"\n label={`${linkLabel} ${text}`}\n color={color}\n itemProp=\"item\"\n {...props}\n >\n <span itemProp=\"name\">{text}</span>\n </Button>\n <meta itemProp=\"position\" content={position.toString()} />\n </>\n );\n};\n\n/**\n * Props for Span sub-component that renders static breadcrumb text\n */\ntype SpanProps = {\n /**\n * Text content for the static breadcrumb item\n */\n children: string;\n /**\n * Position of the breadcrumb item in the list (1-based index)\n */\n position: number;\n} & HTMLAttributes<HTMLSpanElement>;\n\n/**\n * Span sub-component for static breadcrumb text items\n */\nconst Span: FC<SpanProps> = ({ children, position, className, ...props }) => (\n <span\n itemProp=\"item\"\n className={cn(\n 'inline-flex items-center',\n 'font-medium text-neutral-700',\n 'transition-colors duration-200',\n className\n )}\n >\n <span itemProp=\"name\" {...props}>\n {children}\n </span>\n <meta itemProp=\"position\" content={position.toString()} />\n </span>\n);\n\n/**\n * Detailed breadcrumb link configuration with optional href or onClick\n */\ntype DetailedBreadcrumbLink = {\n /**\n * URL to navigate to when the breadcrumb item is clicked\n */\n href?: string;\n /**\n * Text content to display for this breadcrumb item\n */\n text: string;\n /**\n * Custom click handler function for interactive breadcrumb items\n */\n onClick?: () => void;\n};\n\n/**\n * Union type representing different breadcrumb item configurations:\n * - string: Simple text breadcrumb item\n * - DetailedBreadcrumbLink: Object with href, text, and/or onClick properties\n */\nexport type BreadcrumbLink = string | DetailedBreadcrumbLink;\n\nexport type BreadcrumbProps = {\n /**\n * Array of breadcrumb items\n */\n links: BreadcrumbLink[];\n /**\n * Color scheme for breadcrumb links\n * @default \"text\"\n */\n color?: LinkColor | `${LinkColor}`;\n /**\n * Locale for internationalization\n */\n locale?: LocalesValues;\n /**\n * Element type for ARIA current attribute\n * @default 'page'\n */\n elementType?: 'page' | 'location';\n /**\n * Custom separator between breadcrumb items\n * @default ChevronRightIcon\n */\n separator?: ReactNode;\n /**\n * ARIA label for breadcrumb navigation\n * @default 'breadcrumb'\n */\n ariaLabel?: string;\n /**\n * Whether to include structured data markup\n * @default true\n */\n includeStructuredData?: boolean;\n /**\n * Maximum number of breadcrumb items to show before truncation\n */\n maxItems?: number;\n} & VariantProps<typeof breadcrumbVariants> &\n HTMLAttributes<HTMLOListElement>;\n\n/**\n * Breadcrumb component providing navigational context with accessibility features\n *\n * Features:\n * - Supports links, buttons, and static text elements\n * - Full keyboard navigation support\n * - ARIA attributes for screen readers\n * - Schema.org structured data for SEO\n * - Customizable separators and styling\n * - Internationalization support\n * - Responsive design variants\n *\n * @example\n * ```tsx\n * <Breadcrumb\n * links={[\n * 'Home',\n * { href: '/products', text: 'Products' },\n * { onClick: handleCategory, text: 'Electronics' },\n * 'Smartphones'\n * ]}\n * size=\"medium\"\n * ariaLabel=\"Product navigation\"\n * />\n * ```\n */\nexport const Breadcrumb: FC<BreadcrumbProps> = ({\n links,\n className,\n color = 'text',\n locale,\n elementType = 'page',\n separator = <ChevronRightIcon size={10} />,\n ariaLabel = 'breadcrumb',\n includeStructuredData = true,\n maxItems,\n size,\n spacing,\n ...props\n}) => {\n const displayLinks =\n maxItems && links.length > maxItems\n ? [...links.slice(0, 1), '...', ...links.slice(-(maxItems - 2))]\n : links;\n\n return (\n <nav aria-label={ariaLabel}>\n <ol\n className={cn(breadcrumbVariants({ size, spacing }), className)}\n {...(includeStructuredData && {\n itemScope: true,\n itemType: 'http://schema.org/BreadcrumbList',\n })}\n {...props}\n >\n {displayLinks.map((link, index) => {\n const isLastLink = index === displayLinks.length - 1;\n const isLink =\n typeof link === 'object' && typeof link.href === 'string';\n const isButton =\n typeof link === 'object' && typeof link.onClick === 'function';\n const isActive = index === displayLinks.length - 1;\n const ariaCurrent = isActive ? elementType : undefined;\n const isTruncated = link === '...';\n\n const text = (link as DetailedBreadcrumbLink).text ?? link;\n\n const separatorColorClass = getColorClass(color);\n\n if (isTruncated) {\n return (\n <Fragment key={`truncated-${text}`}>\n <li className=\"flex items-center\" aria-hidden=\"true\">\n <span className=\"text-neutral-500\">…</span>\n </li>\n {!isLastLink && (\n <li aria-hidden=\"true\" className=\"flex items-center\">\n <span className={cn(separatorColorClass)}>{separator}</span>\n </li>\n )}\n </Fragment>\n );\n }\n\n let section = (\n <Span\n key={text}\n position={index + 1}\n aria-current={ariaCurrent}\n className={cn(\n 'transition-colors duration-200',\n isActive && 'text-neutral-900'\n )}\n >\n {text}\n </Span>\n );\n\n if (isLink) {\n section = (\n <LinkLink\n key={text}\n href={link.href!}\n color={color}\n position={index + 1}\n locale={locale}\n aria-current={ariaCurrent}\n className={cn(isActive && 'cursor-default text-neutral-900')}\n >\n {text}\n </LinkLink>\n );\n } else if (isButton) {\n section = (\n <ButtonLink\n key={text}\n onClick={link.onClick!}\n color={color}\n position={index + 1}\n aria-current={ariaCurrent}\n className={cn(isActive && 'cursor-default text-neutral-900')}\n >\n {text}\n </ButtonLink>\n );\n }\n\n const listElement = (\n <li\n {...(includeStructuredData && {\n itemProp: 'itemListElement',\n itemScope: true,\n itemType: 'https://schema.org/ListItem',\n })}\n key={text}\n className=\"flex items-center\"\n >\n {section}\n </li>\n );\n\n if (isLastLink) {\n return listElement;\n }\n\n return (\n <Fragment key={text}>\n {listElement}\n <li aria-hidden=\"true\" className=\"flex items-center\">\n <span className={cn(separatorColorClass)}>{separator}</span>\n </li>\n </Fragment>\n );\n })}\n </ol>\n </nav>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../../../src/components/Breadcrumb/index.tsx"],"sourcesContent":["'use client';\n\nimport type { LocalesValues } from '@intlayer/types/module_augmentation';\nimport { cn } from '@utils/cn';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { getIntlayer } from 'intlayer';\nimport { ChevronRightIcon } from 'lucide-react';\nimport { type FC, Fragment, type HTMLAttributes, type ReactNode } from 'react';\nimport { useIntlayer } from 'react-intlayer';\nimport { Button, type ButtonProps } from '../Button';\nimport { Link, type LinkColor } from '../Link';\n\n/**\n * Props for LinkLink sub-component that renders breadcrumb items as links\n */\ntype LinkLinkProps = {\n /**\n * Position of the breadcrumb item in the list (1-based index)\n */\n position: number;\n /**\n * Locale for internationalization\n */\n locale?: LocalesValues;\n /**\n * URL to navigate to\n */\n href?: string;\n /**\n * Link color\n */\n color?: LinkColor | `${LinkColor}`;\n /**\n * Click handler\n */\n onClick?: () => void;\n /**\n * Children content\n */\n children?: string;\n /**\n * Additional CSS classes\n */\n className?: string;\n} & Omit<\n HTMLAttributes<HTMLAnchorElement>,\n 'href' | 'onClick' | 'color' | 'children' | 'className'\n>;\n\n/**\n * Maps LinkColor to corresponding Tailwind text color classes\n */\nconst getColorClass = (color?: LinkColor | `${LinkColor}`): string => {\n if (!color) return '';\n\n const colorMap: Record<LinkColor, string> = {\n primary: 'text-primary',\n secondary: 'text-secondary',\n neutral: 'text-neutral',\n light: 'text-white',\n dark: 'text-neutral-800',\n text: 'text-text',\n 'text-inverse': 'text-text-opposite',\n error: 'text-error',\n success: 'text-success',\n custom: '',\n };\n\n return colorMap[color as LinkColor] || '';\n};\n\n/**\n * Breadcrumb variant styles using class-variance-authority\n */\nconst breadcrumbVariants = cva('flex flex-row flex-wrap items-center', {\n variants: {\n size: {\n xs: 'gap-1 text-xs',\n sm: 'gap-1.5 text-sm',\n md: 'gap-2 text-base',\n lg: 'gap-3 text-lg',\n xl: 'gap-4 text-xl',\n },\n spacing: {\n compact: 'gap-1',\n normal: 'gap-2',\n loose: 'gap-4',\n },\n },\n defaultVariants: {\n size: 'md',\n spacing: 'normal',\n },\n});\n\n/**\n * LinkLink sub-component for breadcrumb items that navigate to other pages\n */\nconst LinkLink: FC<LinkLinkProps> = ({\n href,\n lang,\n children,\n onClick,\n color,\n position,\n locale,\n className,\n ...props\n}) => {\n const content = getIntlayer('breadcrumb');\n const linkLabel = content.linkLabel;\n\n return (\n <>\n <Link\n href={href}\n locale={locale}\n color={color}\n onClick={onClick}\n itemProp=\"item\"\n isExternalLink={false}\n itemScope\n itemType=\"https://schema.org/WebPage\"\n {...props}\n label={`${linkLabel} ${children}`}\n itemID={href}\n size=\"custom\"\n >\n <span itemProp=\"name\">{children}</span>\n </Link>\n <meta itemProp=\"position\" content={position.toString()} />\n </>\n );\n};\n\n/**\n * Props for ButtonLink sub-component that renders breadcrumb items as interactive buttons\n */\ntype ButtonButtonProps = {\n /**\n * Text content for the breadcrumb button\n */\n children: string;\n /**\n * Position of the breadcrumb item in the list (1-based index)\n */\n position: number;\n} & Omit<ButtonProps, 'children' | 'label'>;\n\n/**\n * ButtonLink sub-component for breadcrumb items with click handlers\n */\nconst ButtonLink: FC<ButtonButtonProps> = ({\n children: text,\n onClick,\n color,\n position,\n className,\n ...props\n}) => {\n const { linkLabel } = useIntlayer('breadcrumb');\n\n return (\n <>\n <Button\n onClick={onClick}\n variant=\"link\"\n label={`${linkLabel} ${text}`}\n color={color}\n itemProp=\"item\"\n size=\"custom\"\n {...props}\n >\n <span itemProp=\"name\">{text}</span>\n </Button>\n <meta itemProp=\"position\" content={position.toString()} />\n </>\n );\n};\n\n/**\n * Props for Span sub-component that renders static breadcrumb text\n */\ntype SpanProps = {\n /**\n * Text content for the static breadcrumb item\n */\n children: string;\n /**\n * Position of the breadcrumb item in the list (1-based index)\n */\n position: number;\n} & HTMLAttributes<HTMLSpanElement>;\n\n/**\n * Span sub-component for static breadcrumb text items\n */\nconst Span: FC<SpanProps> = ({ children, position, className, ...props }) => (\n <span\n itemProp=\"item\"\n className={cn(\n 'inline-flex items-center',\n 'font-medium text-neutral-700',\n 'transition-colors duration-200',\n className\n )}\n >\n <span itemProp=\"name\" {...props}>\n {children}\n </span>\n <meta itemProp=\"position\" content={position.toString()} />\n </span>\n);\n\n/**\n * Detailed breadcrumb link configuration with optional href or onClick\n */\ntype DetailedBreadcrumbLink = {\n /**\n * URL to navigate to when the breadcrumb item is clicked\n */\n href?: string;\n /**\n * Text content to display for this breadcrumb item\n */\n text: string;\n /**\n * Custom click handler function for interactive breadcrumb items\n */\n onClick?: () => void;\n};\n\n/**\n * Union type representing different breadcrumb item configurations:\n * - string: Simple text breadcrumb item\n * - DetailedBreadcrumbLink: Object with href, text, and/or onClick properties\n */\nexport type BreadcrumbLink = string | DetailedBreadcrumbLink;\n\nexport type BreadcrumbProps = {\n /**\n * Array of breadcrumb items\n */\n links: BreadcrumbLink[];\n /**\n * Color scheme for breadcrumb links\n * @default \"text\"\n */\n color?: LinkColor | `${LinkColor}`;\n /**\n * Locale for internationalization\n */\n locale?: LocalesValues;\n /**\n * Element type for ARIA current attribute\n * @default 'page'\n */\n elementType?: 'page' | 'location';\n /**\n * Custom separator between breadcrumb items\n * @default ChevronRightIcon\n */\n separator?: ReactNode;\n /**\n * ARIA label for breadcrumb navigation\n * @default 'breadcrumb'\n */\n ariaLabel?: string;\n /**\n * Whether to include structured data markup\n * @default true\n */\n includeStructuredData?: boolean;\n /**\n * Maximum number of breadcrumb items to show before truncation\n */\n maxItems?: number;\n} & VariantProps<typeof breadcrumbVariants> &\n HTMLAttributes<HTMLOListElement>;\n\n/**\n * Breadcrumb component providing navigational context with accessibility features\n *\n * Features:\n * - Supports links, buttons, and static text elements\n * - Full keyboard navigation support\n * - ARIA attributes for screen readers\n * - Schema.org structured data for SEO\n * - Customizable separators and styling\n * - Internationalization support\n * - Responsive design variants\n *\n * @example\n * ```tsx\n * <Breadcrumb\n * links={[\n * 'Home',\n * { href: '/products', text: 'Products' },\n * { onClick: handleCategory, text: 'Electronics' },\n * 'Smartphones'\n * ]}\n * size=\"md\"\n * ariaLabel=\"Product navigation\"\n * />\n * ```\n */\nexport const Breadcrumb: FC<BreadcrumbProps> = ({\n links,\n className,\n color = 'text',\n locale,\n elementType = 'page',\n separator = <ChevronRightIcon size={10} />,\n ariaLabel = 'breadcrumb',\n includeStructuredData = true,\n maxItems,\n size,\n spacing,\n ...props\n}) => {\n const displayLinks =\n maxItems && links.length > maxItems\n ? [...links.slice(0, 1), '...', ...links.slice(-(maxItems - 2))]\n : links;\n\n return (\n <nav aria-label={ariaLabel}>\n <ol\n className={cn(breadcrumbVariants({ size, spacing }), className)}\n {...(includeStructuredData && {\n itemScope: true,\n itemType: 'http://schema.org/BreadcrumbList',\n })}\n {...props}\n >\n {displayLinks.map((link, index) => {\n const isLastLink = index === displayLinks.length - 1;\n const isLink =\n typeof link === 'object' && typeof link.href === 'string';\n const isButton =\n typeof link === 'object' && typeof link.onClick === 'function';\n const isActive = index === displayLinks.length - 1;\n const ariaCurrent = isActive ? elementType : undefined;\n const isTruncated = link === '...';\n\n const text = (link as DetailedBreadcrumbLink).text ?? link;\n\n const separatorColorClass = getColorClass(color);\n\n if (isTruncated) {\n return (\n <Fragment key={`truncated-${text}`}>\n <li className=\"flex items-center\" aria-hidden=\"true\">\n <span className=\"text-neutral-500\">…</span>\n </li>\n {!isLastLink && (\n <li aria-hidden=\"true\" className=\"flex items-center\">\n <span className={cn(separatorColorClass)}>{separator}</span>\n </li>\n )}\n </Fragment>\n );\n }\n\n let section = (\n <Span\n key={text}\n position={index + 1}\n aria-current={ariaCurrent}\n className={cn(\n 'transition-colors duration-200',\n isActive && 'text-neutral-900'\n )}\n >\n {text}\n </Span>\n );\n\n if (isLink) {\n section = (\n <LinkLink\n key={text}\n href={link.href!}\n color={color}\n position={index + 1}\n locale={locale}\n aria-current={ariaCurrent}\n className={cn(isActive && 'cursor-default text-neutral-900')}\n >\n {text}\n </LinkLink>\n );\n } else if (isButton) {\n section = (\n <ButtonLink\n key={text}\n onClick={link.onClick!}\n color={color}\n position={index + 1}\n aria-current={ariaCurrent}\n className={cn(isActive && 'cursor-default text-neutral-900')}\n >\n {text}\n </ButtonLink>\n );\n }\n\n const listElement = (\n <li\n {...(includeStructuredData && {\n itemProp: 'itemListElement',\n itemScope: true,\n itemType: 'https://schema.org/ListItem',\n })}\n key={text}\n className=\"flex items-center\"\n >\n {section}\n </li>\n );\n\n if (isLastLink) {\n return listElement;\n }\n\n return (\n <Fragment key={text}>\n {listElement}\n <li aria-hidden=\"true\" className=\"flex items-center\">\n <span className={cn(separatorColorClass)}>{separator}</span>\n </li>\n </Fragment>\n );\n })}\n </ol>\n </nav>\n );\n};\n"],"mappings":"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"}
@@ -14,7 +14,8 @@ const buttonIconVariants = cva("flex-none shrink-0", {
14
14
  "icon-sm": "size-3",
15
15
  "icon-md": "size-4",
16
16
  "icon-lg": "size-5",
17
- "icon-xl": "size-6"
17
+ "icon-xl": "size-6",
18
+ custom: ""
18
19
  } },
19
20
  defaultVariants: { size: "md" }
20
21
  });
@@ -32,7 +33,8 @@ const buttonVariants = cva("relative inline-flex cursor-pointer items-center jus
32
33
  "icon-sm": "p-1.5",
33
34
  "icon-md": "p-1.5",
34
35
  "icon-lg": "p-1.5",
35
- "icon-xl": "p-3"
36
+ "icon-xl": "p-3",
37
+ custom: ""
36
38
  },
37
39
  color: {
38
40
  primary: "hover-primary-500/20 text-primary ring-primary-500/20 *:text-text-light",
@@ -1 +1 @@
1
- {"version":3,"file":"Button.mjs","names":[],"sources":["../../../../src/components/Button/Button.tsx"],"sourcesContent":["import { cn } from '@utils/cn';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport type { LucideIcon } from 'lucide-react';\nimport type { ButtonHTMLAttributes, DetailedHTMLProps, FC } from 'react';\nimport { Loader } from '../Loader';\n\n/**\n * Button size variants for different use cases\n */\nexport type ButtonSize =\n | 'xs'\n | 'sm'\n | 'md'\n | 'lg'\n | 'xl'\n | 'icon-sm'\n | 'icon-md'\n | 'icon-lg'\n | 'icon-xl';\n\nconst buttonIconVariants = cva('flex-none shrink-0', {\n variants: {\n size: {\n xs: 'size-2',\n sm: 'size-3',\n md: 'size-4',\n lg: 'size-5',\n xl: 'size-6',\n 'icon-sm': 'size-3',\n 'icon-md': 'size-4',\n 'icon-lg': 'size-5',\n 'icon-xl': 'size-6',\n },\n },\n defaultVariants: {\n size: 'md',\n },\n});\n\n/**\n * Button visual style variants\n */\nexport type ButtonVariant =\n | 'default'\n | 'none'\n | 'outline'\n | 'link'\n | 'invisible-link'\n | 'hoverable'\n | 'fade'\n | 'input';\n\n/**\n * Button color themes that work with the design system\n */\nexport type ButtonColor =\n | 'primary'\n | 'secondary'\n | 'neutral'\n | 'light'\n | 'dark'\n | 'text'\n | 'card'\n | 'text-inverse'\n | 'current'\n | 'error'\n | 'success'\n | 'custom';\n\n/**\n * Text alignment options for button content\n */\nexport type ButtonTextAlign = 'left' | 'center' | 'right';\n\n/**\n * Enhanced button variants with improved accessibility and focus states\n */\nexport const buttonVariants = cva(\n 'relative inline-flex cursor-pointer items-center justify-center font-medium ring-0 transition-all duration-300 focus-visible:outline-none disabled:pointer-events-none disabled:opacity-50',\n {\n variants: {\n size: {\n xs: 'min-h-7 px-3 text-xs max-md:py-1',\n sm: 'min-h-7 px-3 text-xs max-md:py-1',\n md: 'min-h-8 px-6 text-sm max-md:py-2',\n lg: 'min-h-10 px-8 text-lg max-md:py-3',\n xl: 'min-h-11 px-10 text-xl max-md:py-4',\n 'icon-sm': 'p-1.5',\n 'icon-md': 'p-1.5',\n 'icon-lg': 'p-1.5',\n 'icon-xl': 'p-3',\n },\n color: {\n primary:\n 'hover-primary-500/20 text-primary ring-primary-500/20 *:text-text-light',\n secondary:\n 'hover-secondary-500/20 text-secondary ring-secondary-500/20 *:text-text-light',\n neutral: 'text-neutral ring-neutral-500/5 *:text-text-light',\n card: 'hover-card-500/20 text-card ring-card-500/20 *:text-text-light',\n light: 'hover-white-500/20 text-white ring-white/20 *:text-text-light',\n dark: 'text-neutral-800 ring-text-light/50 *:text-text-light',\n text: 'text-text ring-text/20 *:text-text-opposite',\n current:\n 'hover-current-500/10 text-current ring-current/10 *:text-text-light',\n 'text-inverse': 'text-text-opposite ring-text-opposite/20 *:text-text',\n error: 'hover-error-500/20 text-error ring-error/20 *:text-text-light',\n success:\n 'hover-success-500/20 text-success ring-success/20 *:text-text-light',\n custom: '',\n },\n roundedSize: {\n none: 'rounded-none',\n sm: 'rounded-lg [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-xl',\n md: 'rounded-xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-2xl',\n lg: 'rounded-2xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-3xl',\n xl: 'rounded-3xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-4xl',\n '2xl':\n 'rounded-4xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-[2.5rem]',\n '3xl':\n 'rounded-[2.5rem] [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-[3rem]',\n '4xl':\n 'rounded-[3rem] [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-[4rem]',\n '5xl':\n 'rounded-[4rem] [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-[5rem]',\n full: 'rounded-full',\n },\n variant: {\n default: [\n 'bg-current',\n 'hover:bg-current/90',\n 'hover:ring-5',\n 'aria-selected:ring-5',\n ],\n\n outline: [\n 'rounded-2xl border-[1.3px] border-current bg-current/0 *:text-current!',\n 'hover:bg-current/20 focus-visible:bg-current/20',\n 'hover:ring-5 focus-visible:ring-5',\n 'aria-selected:ring-5',\n ],\n\n none: 'border-none bg-current/0 text-inherit hover:bg-current/0',\n\n link: 'h-auto justify-start border-inherit bg-transparent px-1 underline-offset-4 *:text-current! hover:bg-transparent hover:underline',\n\n 'invisible-link':\n 'h-auto justify-start border-inherit bg-transparent px-1 underline-offset-4 *:text-current! hover:bg-transparent',\n\n hoverable:\n 'rounded-lg border-none bg-current/0 transition *:text-current! hover:bg-current/10 aria-[current]:bg-current/5',\n\n fade: [\n 'rounded-lg border-none bg-current/10 ring-current/5 transition *:text-current! hover:bg-current/20 aria-[current]:bg-current/5',\n 'hover:ring-5 focus-visible:ring-5',\n 'aria-selected:ring-5',\n ],\n input: [\n // base styles\n 'text-text',\n 'w-full select-text resize-none rounded-2xl text-base shadow-none outline-none supports-[corner-shape:squircle]:rounded-4xl',\n 'transition-shadow duration-100 md:text-sm',\n 'ring-0', // base ring\n 'disabled:opacity-50',\n\n 'text-text',\n 'bg-neutral-50 dark:bg-neutral-950',\n 'ring-neutral-100 dark:ring-neutral-700',\n\n // Hover ring (similar spirit to your input)\n 'hover:ring-3', // width\n 'aria-selected:ring-4',\n 'focus-visible:ring-3',\n 'disabled:ring-0',\n\n // Focus ring + animation\n 'focus-visible:outline-none',\n\n // Remove any weird box-shadow\n '[box-shadow:none] focus:[box-shadow:none]',\n\n // aria-invalid border color\n 'aria-invalid:border-error',\n ],\n },\n\n textAlign: {\n left: 'justify-start text-left',\n center: 'justify-center text-center',\n right: 'justify-end text-right',\n },\n\n isFullWidth: {\n true: 'w-full',\n false: '',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'md',\n color: 'text',\n roundedSize: 'md',\n textAlign: 'center',\n isFullWidth: false,\n },\n }\n);\n\n/**\n * Enhanced Button component props with comprehensive type safety and accessibility features\n */\nexport type ButtonProps = DetailedHTMLProps<\n ButtonHTMLAttributes<HTMLButtonElement>,\n HTMLButtonElement\n> &\n VariantProps<typeof buttonVariants> & {\n /**\n * Accessible label for screen readers and assistive technologies.\n * This is required for accessibility compliance.\n */\n label: string | null;\n\n /**\n * Optional icon to display on the left side of the button\n */\n Icon?: FC | LucideIcon;\n\n /**\n * Optional icon to display on the right side of the button\n */\n IconRight?: FC | LucideIcon;\n\n /**\n * Additional CSS classes for icon styling\n */\n iconClassName?: string;\n\n /**\n * Shows loading spinner and disables button interaction when true\n */\n isLoading?: boolean;\n\n /**\n * Marks the button as active (useful for navigation or toggle states)\n */\n isActive?: boolean;\n\n /**\n * Marks the button as selected\n */\n isSelected?: boolean;\n\n /**\n * Makes the button span the full width of its container\n */\n isFullWidth?: boolean;\n\n /**\n * Additional description for complex buttons (optional)\n */\n 'aria-describedby'?: string;\n\n /**\n * Expanded state for collapsible sections (optional)\n */\n 'aria-expanded'?: boolean;\n\n /**\n * Controls whether the button has popup/menu (optional)\n */\n 'aria-haspopup'?:\n | boolean\n | 'true'\n | 'false'\n | 'menu'\n | 'listbox'\n | 'tree'\n | 'grid'\n | 'dialog';\n\n /**\n * Indicates if button controls are currently pressed (for toggle buttons)\n */\n 'aria-pressed'?: boolean;\n };\n\n/**\n * Button Component - A comprehensive, accessible button component\n *\n * Features:\n * - Full accessibility compliance with ARIA attributes\n * - Multiple variants and sizes for different use cases\n * - Icon support (left and right positioning)\n * - Loading states with spinner\n * - Keyboard navigation support\n * - Focus management with visible indicators\n * - Responsive design adaptations\n *\n * @example\n * ```tsx\n * // Basic button\n * <Button label=\"Click me\">Click me</Button>\n *\n * // Button with icon and loading state\n * <Button\n * label=\"Save document\"\n * Icon={SaveIcon}\n * isLoading={saving}\n * disabled={!hasChanges}\n * >\n * Save\n * </Button>\n *\n * // Error action button\n * <Button\n * variant=\"outline\"\n * color=\"error\"\n * label=\"Delete item permanently\"\n * aria-describedby=\"delete-warning\"\n * >\n * Delete\n * </Button>\n * ```\n */\nexport const Button: FC<ButtonProps> = ({\n variant,\n size,\n color,\n children,\n Icon,\n IconRight,\n iconClassName,\n isLoading = false,\n isActive,\n isSelected,\n isFullWidth,\n roundedSize,\n textAlign,\n disabled,\n label,\n className,\n type = 'button',\n 'aria-describedby': ariaDescribedBy,\n 'aria-expanded': ariaExpanded,\n 'aria-haspopup': ariaHasPopup,\n 'aria-pressed': ariaPressed,\n ...props\n}) => {\n const isLink = variant === 'link' || variant === 'invisible-link';\n const isIconOnly = !children && (Icon || IconRight);\n\n const accessibilityProps = {\n 'aria-label': isIconOnly ? (label ?? undefined) : undefined,\n 'aria-labelledby': !isIconOnly ? undefined : undefined,\n 'aria-describedby': ariaDescribedBy,\n 'aria-expanded': ariaExpanded,\n 'aria-haspopup': ariaHasPopup,\n 'aria-pressed': isActive !== undefined ? isActive : ariaPressed,\n 'aria-busy': isLoading,\n 'aria-current': (isActive ? 'page' : undefined) as 'page' | undefined,\n 'aria-disabled': disabled || isLoading,\n 'aria-selected': isSelected,\n };\n\n const isSquareButton =\n size === 'icon-sm' ||\n size === 'icon-md' ||\n size === 'icon-lg' ||\n size === 'icon-xl';\n\n return (\n <button\n disabled={isLoading || disabled}\n role={isLink ? 'link' : 'button'}\n type={type}\n className={buttonVariants({\n variant,\n size,\n color,\n isFullWidth,\n roundedSize,\n textAlign: textAlign ?? (IconRight ? 'left' : 'center'),\n className,\n })}\n {...accessibilityProps}\n {...props}\n >\n {Icon && !isLoading && (\n <Icon\n className={buttonIconVariants({\n size,\n className: cn(!isSquareButton && 'mr-3', iconClassName),\n })}\n aria-hidden=\"true\"\n />\n )}\n\n <div\n className={cn(\n 'flex items-center justify-center transition-[width] duration-300',\n isLoading && size === 'sm' && 'w-3',\n isLoading && size === 'md' && 'w-4',\n isLoading && size === 'lg' && 'w-6',\n isLoading && size === 'xl' && 'w-8'\n )}\n >\n <Loader\n className={buttonIconVariants({\n size,\n className: cn(!isSquareButton && 'mr-3', iconClassName),\n })}\n isLoading={isLoading}\n aria-hidden=\"true\"\n data-testid=\"loader\"\n />\n </div>\n\n {children && (\n <span className=\"flex-1 truncate whitespace-nowrap\">{children}</span>\n )}\n\n {!children && isIconOnly && <span className=\"sr-only\">{label}</span>}\n\n {IconRight && (\n <IconRight\n className={buttonIconVariants({\n size,\n className: cn(!isSquareButton && 'ml-3', iconClassName),\n })}\n aria-hidden=\"true\"\n />\n )}\n </button>\n );\n};\n"],"mappings":";;;;;;AAoBA,MAAM,qBAAqB,IAAI,sBAAsB;CACnD,UAAU,EACR,MAAM;EACJ,IAAI;EACJ,IAAI;EACJ,IAAI;EACJ,IAAI;EACJ,IAAI;EACJ,WAAW;EACX,WAAW;EACX,WAAW;EACX,WAAW;EACZ,EACF;CACD,iBAAiB,EACf,MAAM,MACP;CACF,CAAC;;;;AAwCF,MAAa,iBAAiB,IAC5B,8LACA;CACE,UAAU;EACR,MAAM;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,WAAW;GACX,WAAW;GACX,WAAW;GACX,WAAW;GACZ;EACD,OAAO;GACL,SACE;GACF,WACE;GACF,SAAS;GACT,MAAM;GACN,OAAO;GACP,MAAM;GACN,MAAM;GACN,SACE;GACF,gBAAgB;GAChB,OAAO;GACP,SACE;GACF,QAAQ;GACT;EACD,aAAa;GACX,MAAM;GACN,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,OACE;GACF,OACE;GACF,OACE;GACF,OACE;GACF,MAAM;GACP;EACD,SAAS;GACP,SAAS;IACP;IACA;IACA;IACA;IACD;GAED,SAAS;IACP;IACA;IACA;IACA;IACD;GAED,MAAM;GAEN,MAAM;GAEN,kBACE;GAEF,WACE;GAEF,MAAM;IACJ;IACA;IACA;IACD;GACD,OAAO;IAEL;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IAGA;IACA;IACA;IACA;IAGA;IAGA;IAGA;IACD;GACF;EAED,WAAW;GACT,MAAM;GACN,QAAQ;GACR,OAAO;GACR;EAED,aAAa;GACX,MAAM;GACN,OAAO;GACR;EACF;CACD,iBAAiB;EACf,SAAS;EACT,MAAM;EACN,OAAO;EACP,aAAa;EACb,WAAW;EACX,aAAa;EACd;CACF,CACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsHD,MAAa,UAA2B,EACtC,SACA,MACA,OACA,UACA,MACA,WACA,eACA,YAAY,OACZ,UACA,YACA,aACA,aACA,WACA,UACA,OACA,WACA,OAAO,UACP,oBAAoB,iBACpB,iBAAiB,cACjB,iBAAiB,cACjB,gBAAgB,aAChB,GAAG,YACC;CACJ,MAAM,SAAS,YAAY,UAAU,YAAY;CACjD,MAAM,aAAa,CAAC,aAAa,QAAQ;CAEzC,MAAM,qBAAqB;EACzB,cAAc,aAAc,SAAS,SAAa;EAClD,mBAAmB,CAAC,aAAa,SAAY;EAC7C,oBAAoB;EACpB,iBAAiB;EACjB,iBAAiB;EACjB,gBAAgB,aAAa,SAAY,WAAW;EACpD,aAAa;EACb,gBAAiB,WAAW,SAAS;EACrC,iBAAiB,YAAY;EAC7B,iBAAiB;EAClB;CAED,MAAM,iBACJ,SAAS,aACT,SAAS,aACT,SAAS,aACT,SAAS;AAEX,QACE,qBAAC,UAAD;EACE,UAAU,aAAa;EACvB,MAAM,SAAS,SAAS;EAClB;EACN,WAAW,eAAe;GACxB;GACA;GACA;GACA;GACA;GACA,WAAW,cAAc,YAAY,SAAS;GAC9C;GACD,CAAC;EACF,GAAI;EACJ,GAAI;YAdN;GAgBG,QAAQ,CAAC,aACR,oBAAC,MAAD;IACE,WAAW,mBAAmB;KAC5B;KACA,WAAW,GAAG,CAAC,kBAAkB,QAAQ,cAAc;KACxD,CAAC;IACF,eAAY;IACZ;GAGJ,oBAAC,OAAD;IACE,WAAW,GACT,oEACA,aAAa,SAAS,QAAQ,OAC9B,aAAa,SAAS,QAAQ,OAC9B,aAAa,SAAS,QAAQ,OAC9B,aAAa,SAAS,QAAQ,MAC/B;cAED,oBAAC,QAAD;KACE,WAAW,mBAAmB;MAC5B;MACA,WAAW,GAAG,CAAC,kBAAkB,QAAQ,cAAc;MACxD,CAAC;KACS;KACX,eAAY;KACZ,eAAY;KACZ;IACE;GAEL,YACC,oBAAC,QAAD;IAAM,WAAU;IAAqC;IAAgB;GAGtE,CAAC,YAAY,cAAc,oBAAC,QAAD;IAAM,WAAU;cAAW;IAAa;GAEnE,aACC,oBAAC,WAAD;IACE,WAAW,mBAAmB;KAC5B;KACA,WAAW,GAAG,CAAC,kBAAkB,QAAQ,cAAc;KACxD,CAAC;IACF,eAAY;IACZ;GAEG"}
1
+ {"version":3,"file":"Button.mjs","names":[],"sources":["../../../../src/components/Button/Button.tsx"],"sourcesContent":["import { cn } from '@utils/cn';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport type { LucideIcon } from 'lucide-react';\nimport type { ButtonHTMLAttributes, DetailedHTMLProps, FC } from 'react';\nimport { Loader } from '../Loader';\n\n/**\n * Button size variants for different use cases\n */\nexport type ButtonSize =\n | 'xs'\n | 'sm'\n | 'md'\n | 'lg'\n | 'xl'\n | 'icon-sm'\n | 'icon-md'\n | 'icon-lg'\n | 'icon-xl'\n | 'custom';\n\nconst buttonIconVariants = cva('flex-none shrink-0', {\n variants: {\n size: {\n xs: 'size-2',\n sm: 'size-3',\n md: 'size-4',\n lg: 'size-5',\n xl: 'size-6',\n 'icon-sm': 'size-3',\n 'icon-md': 'size-4',\n 'icon-lg': 'size-5',\n 'icon-xl': 'size-6',\n custom: '',\n },\n },\n defaultVariants: {\n size: 'md',\n },\n});\n\n/**\n * Button visual style variants\n */\nexport type ButtonVariant =\n | 'default'\n | 'none'\n | 'outline'\n | 'link'\n | 'invisible-link'\n | 'hoverable'\n | 'fade'\n | 'input';\n\n/**\n * Button color themes that work with the design system\n */\nexport type ButtonColor =\n | 'primary'\n | 'secondary'\n | 'neutral'\n | 'light'\n | 'dark'\n | 'text'\n | 'card'\n | 'text-inverse'\n | 'current'\n | 'error'\n | 'success'\n | 'custom';\n\n/**\n * Text alignment options for button content\n */\nexport type ButtonTextAlign = 'left' | 'center' | 'right';\n\n/**\n * Enhanced button variants with improved accessibility and focus states\n */\nexport const buttonVariants = cva(\n 'relative inline-flex cursor-pointer items-center justify-center font-medium ring-0 transition-all duration-300 focus-visible:outline-none disabled:pointer-events-none disabled:opacity-50',\n {\n variants: {\n size: {\n xs: 'min-h-7 px-3 text-xs max-md:py-1',\n sm: 'min-h-7 px-3 text-xs max-md:py-1',\n md: 'min-h-8 px-6 text-sm max-md:py-2',\n lg: 'min-h-10 px-8 text-lg max-md:py-3',\n xl: 'min-h-11 px-10 text-xl max-md:py-4',\n 'icon-sm': 'p-1.5',\n 'icon-md': 'p-1.5',\n 'icon-lg': 'p-1.5',\n 'icon-xl': 'p-3',\n custom: '',\n },\n color: {\n primary:\n 'hover-primary-500/20 text-primary ring-primary-500/20 *:text-text-light',\n secondary:\n 'hover-secondary-500/20 text-secondary ring-secondary-500/20 *:text-text-light',\n neutral: 'text-neutral ring-neutral-500/5 *:text-text-light',\n card: 'hover-card-500/20 text-card ring-card-500/20 *:text-text-light',\n light: 'hover-white-500/20 text-white ring-white/20 *:text-text-light',\n dark: 'text-neutral-800 ring-text-light/50 *:text-text-light',\n text: 'text-text ring-text/20 *:text-text-opposite',\n current:\n 'hover-current-500/10 text-current ring-current/10 *:text-text-light',\n 'text-inverse': 'text-text-opposite ring-text-opposite/20 *:text-text',\n error: 'hover-error-500/20 text-error ring-error/20 *:text-text-light',\n success:\n 'hover-success-500/20 text-success ring-success/20 *:text-text-light',\n custom: '',\n },\n roundedSize: {\n none: 'rounded-none',\n sm: 'rounded-lg [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-xl',\n md: 'rounded-xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-2xl',\n lg: 'rounded-2xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-3xl',\n xl: 'rounded-3xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-4xl',\n '2xl':\n 'rounded-4xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-[2.5rem]',\n '3xl':\n 'rounded-[2.5rem] [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-[3rem]',\n '4xl':\n 'rounded-[3rem] [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-[4rem]',\n '5xl':\n 'rounded-[4rem] [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-[5rem]',\n full: 'rounded-full',\n },\n variant: {\n default: [\n 'bg-current',\n 'hover:bg-current/90',\n 'hover:ring-5',\n 'aria-selected:ring-5',\n ],\n\n outline: [\n 'rounded-2xl border-[1.3px] border-current bg-current/0 *:text-current!',\n 'hover:bg-current/20 focus-visible:bg-current/20',\n 'hover:ring-5 focus-visible:ring-5',\n 'aria-selected:ring-5',\n ],\n\n none: 'border-none bg-current/0 text-inherit hover:bg-current/0',\n\n link: 'h-auto justify-start border-inherit bg-transparent px-1 underline-offset-4 *:text-current! hover:bg-transparent hover:underline',\n\n 'invisible-link':\n 'h-auto justify-start border-inherit bg-transparent px-1 underline-offset-4 *:text-current! hover:bg-transparent',\n\n hoverable:\n 'rounded-lg border-none bg-current/0 transition *:text-current! hover:bg-current/10 aria-[current]:bg-current/5',\n\n fade: [\n 'rounded-lg border-none bg-current/10 ring-current/5 transition *:text-current! hover:bg-current/20 aria-[current]:bg-current/5',\n 'hover:ring-5 focus-visible:ring-5',\n 'aria-selected:ring-5',\n ],\n input: [\n // base styles\n 'text-text',\n 'w-full select-text resize-none rounded-2xl text-base shadow-none outline-none supports-[corner-shape:squircle]:rounded-4xl',\n 'transition-shadow duration-100 md:text-sm',\n 'ring-0', // base ring\n 'disabled:opacity-50',\n\n 'text-text',\n 'bg-neutral-50 dark:bg-neutral-950',\n 'ring-neutral-100 dark:ring-neutral-700',\n\n // Hover ring (similar spirit to your input)\n 'hover:ring-3', // width\n 'aria-selected:ring-4',\n 'focus-visible:ring-3',\n 'disabled:ring-0',\n\n // Focus ring + animation\n 'focus-visible:outline-none',\n\n // Remove any weird box-shadow\n '[box-shadow:none] focus:[box-shadow:none]',\n\n // aria-invalid border color\n 'aria-invalid:border-error',\n ],\n },\n\n textAlign: {\n left: 'justify-start text-left',\n center: 'justify-center text-center',\n right: 'justify-end text-right',\n },\n\n isFullWidth: {\n true: 'w-full',\n false: '',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'md',\n color: 'text',\n roundedSize: 'md',\n textAlign: 'center',\n isFullWidth: false,\n },\n }\n);\n\n/**\n * Enhanced Button component props with comprehensive type safety and accessibility features\n */\nexport type ButtonProps = DetailedHTMLProps<\n ButtonHTMLAttributes<HTMLButtonElement>,\n HTMLButtonElement\n> &\n VariantProps<typeof buttonVariants> & {\n /**\n * Accessible label for screen readers and assistive technologies.\n * This is required for accessibility compliance.\n */\n label: string | null;\n\n /**\n * Optional icon to display on the left side of the button\n */\n Icon?: FC | LucideIcon;\n\n /**\n * Optional icon to display on the right side of the button\n */\n IconRight?: FC | LucideIcon;\n\n /**\n * Additional CSS classes for icon styling\n */\n iconClassName?: string;\n\n /**\n * Shows loading spinner and disables button interaction when true\n */\n isLoading?: boolean;\n\n /**\n * Marks the button as active (useful for navigation or toggle states)\n */\n isActive?: boolean;\n\n /**\n * Marks the button as selected\n */\n isSelected?: boolean;\n\n /**\n * Makes the button span the full width of its container\n */\n isFullWidth?: boolean;\n\n /**\n * Additional description for complex buttons (optional)\n */\n 'aria-describedby'?: string;\n\n /**\n * Expanded state for collapsible sections (optional)\n */\n 'aria-expanded'?: boolean;\n\n /**\n * Controls whether the button has popup/menu (optional)\n */\n 'aria-haspopup'?:\n | boolean\n | 'true'\n | 'false'\n | 'menu'\n | 'listbox'\n | 'tree'\n | 'grid'\n | 'dialog';\n\n /**\n * Indicates if button controls are currently pressed (for toggle buttons)\n */\n 'aria-pressed'?: boolean;\n };\n\n/**\n * Button Component - A comprehensive, accessible button component\n *\n * Features:\n * - Full accessibility compliance with ARIA attributes\n * - Multiple variants and sizes for different use cases\n * - Icon support (left and right positioning)\n * - Loading states with spinner\n * - Keyboard navigation support\n * - Focus management with visible indicators\n * - Responsive design adaptations\n *\n * @example\n * ```tsx\n * // Basic button\n * <Button label=\"Click me\">Click me</Button>\n *\n * // Button with icon and loading state\n * <Button\n * label=\"Save document\"\n * Icon={SaveIcon}\n * isLoading={saving}\n * disabled={!hasChanges}\n * >\n * Save\n * </Button>\n *\n * // Error action button\n * <Button\n * variant=\"outline\"\n * color=\"error\"\n * label=\"Delete item permanently\"\n * aria-describedby=\"delete-warning\"\n * >\n * Delete\n * </Button>\n * ```\n */\nexport const Button: FC<ButtonProps> = ({\n variant,\n size,\n color,\n children,\n Icon,\n IconRight,\n iconClassName,\n isLoading = false,\n isActive,\n isSelected,\n isFullWidth,\n roundedSize,\n textAlign,\n disabled,\n label,\n className,\n type = 'button',\n 'aria-describedby': ariaDescribedBy,\n 'aria-expanded': ariaExpanded,\n 'aria-haspopup': ariaHasPopup,\n 'aria-pressed': ariaPressed,\n ...props\n}) => {\n const isLink = variant === 'link' || variant === 'invisible-link';\n const isIconOnly = !children && (Icon || IconRight);\n\n const accessibilityProps = {\n 'aria-label': isIconOnly ? (label ?? undefined) : undefined,\n 'aria-labelledby': !isIconOnly ? undefined : undefined,\n 'aria-describedby': ariaDescribedBy,\n 'aria-expanded': ariaExpanded,\n 'aria-haspopup': ariaHasPopup,\n 'aria-pressed': isActive !== undefined ? isActive : ariaPressed,\n 'aria-busy': isLoading,\n 'aria-current': (isActive ? 'page' : undefined) as 'page' | undefined,\n 'aria-disabled': disabled || isLoading,\n 'aria-selected': isSelected,\n };\n\n const isSquareButton =\n size === 'icon-sm' ||\n size === 'icon-md' ||\n size === 'icon-lg' ||\n size === 'icon-xl';\n\n return (\n <button\n disabled={isLoading || disabled}\n role={isLink ? 'link' : 'button'}\n type={type}\n className={buttonVariants({\n variant,\n size,\n color,\n isFullWidth,\n roundedSize,\n textAlign: textAlign ?? (IconRight ? 'left' : 'center'),\n className,\n })}\n {...accessibilityProps}\n {...props}\n >\n {Icon && !isLoading && (\n <Icon\n className={buttonIconVariants({\n size,\n className: cn(!isSquareButton && 'mr-3', iconClassName),\n })}\n aria-hidden=\"true\"\n />\n )}\n\n <div\n className={cn(\n 'flex items-center justify-center transition-[width] duration-300',\n isLoading && size === 'sm' && 'w-3',\n isLoading && size === 'md' && 'w-4',\n isLoading && size === 'lg' && 'w-6',\n isLoading && size === 'xl' && 'w-8'\n )}\n >\n <Loader\n className={buttonIconVariants({\n size,\n className: cn(!isSquareButton && 'mr-3', iconClassName),\n })}\n isLoading={isLoading}\n aria-hidden=\"true\"\n data-testid=\"loader\"\n />\n </div>\n\n {children && (\n <span className=\"flex-1 truncate whitespace-nowrap\">{children}</span>\n )}\n\n {!children && isIconOnly && <span className=\"sr-only\">{label}</span>}\n\n {IconRight && (\n <IconRight\n className={buttonIconVariants({\n size,\n className: cn(!isSquareButton && 'ml-3', iconClassName),\n })}\n aria-hidden=\"true\"\n />\n )}\n </button>\n );\n};\n"],"mappings":";;;;;;AAqBA,MAAM,qBAAqB,IAAI,sBAAsB;CACnD,UAAU,EACR,MAAM;EACJ,IAAI;EACJ,IAAI;EACJ,IAAI;EACJ,IAAI;EACJ,IAAI;EACJ,WAAW;EACX,WAAW;EACX,WAAW;EACX,WAAW;EACX,QAAQ;EACT,EACF;CACD,iBAAiB,EACf,MAAM,MACP;CACF,CAAC;;;;AAwCF,MAAa,iBAAiB,IAC5B,8LACA;CACE,UAAU;EACR,MAAM;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,WAAW;GACX,WAAW;GACX,WAAW;GACX,WAAW;GACX,QAAQ;GACT;EACD,OAAO;GACL,SACE;GACF,WACE;GACF,SAAS;GACT,MAAM;GACN,OAAO;GACP,MAAM;GACN,MAAM;GACN,SACE;GACF,gBAAgB;GAChB,OAAO;GACP,SACE;GACF,QAAQ;GACT;EACD,aAAa;GACX,MAAM;GACN,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,OACE;GACF,OACE;GACF,OACE;GACF,OACE;GACF,MAAM;GACP;EACD,SAAS;GACP,SAAS;IACP;IACA;IACA;IACA;IACD;GAED,SAAS;IACP;IACA;IACA;IACA;IACD;GAED,MAAM;GAEN,MAAM;GAEN,kBACE;GAEF,WACE;GAEF,MAAM;IACJ;IACA;IACA;IACD;GACD,OAAO;IAEL;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IAGA;IACA;IACA;IACA;IAGA;IAGA;IAGA;IACD;GACF;EAED,WAAW;GACT,MAAM;GACN,QAAQ;GACR,OAAO;GACR;EAED,aAAa;GACX,MAAM;GACN,OAAO;GACR;EACF;CACD,iBAAiB;EACf,SAAS;EACT,MAAM;EACN,OAAO;EACP,aAAa;EACb,WAAW;EACX,aAAa;EACd;CACF,CACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsHD,MAAa,UAA2B,EACtC,SACA,MACA,OACA,UACA,MACA,WACA,eACA,YAAY,OACZ,UACA,YACA,aACA,aACA,WACA,UACA,OACA,WACA,OAAO,UACP,oBAAoB,iBACpB,iBAAiB,cACjB,iBAAiB,cACjB,gBAAgB,aAChB,GAAG,YACC;CACJ,MAAM,SAAS,YAAY,UAAU,YAAY;CACjD,MAAM,aAAa,CAAC,aAAa,QAAQ;CAEzC,MAAM,qBAAqB;EACzB,cAAc,aAAc,SAAS,SAAa;EAClD,mBAAmB,CAAC,aAAa,SAAY;EAC7C,oBAAoB;EACpB,iBAAiB;EACjB,iBAAiB;EACjB,gBAAgB,aAAa,SAAY,WAAW;EACpD,aAAa;EACb,gBAAiB,WAAW,SAAS;EACrC,iBAAiB,YAAY;EAC7B,iBAAiB;EAClB;CAED,MAAM,iBACJ,SAAS,aACT,SAAS,aACT,SAAS,aACT,SAAS;AAEX,QACE,qBAAC,UAAD;EACE,UAAU,aAAa;EACvB,MAAM,SAAS,SAAS;EAClB;EACN,WAAW,eAAe;GACxB;GACA;GACA;GACA;GACA;GACA,WAAW,cAAc,YAAY,SAAS;GAC9C;GACD,CAAC;EACF,GAAI;EACJ,GAAI;YAdN;GAgBG,QAAQ,CAAC,aACR,oBAAC,MAAD;IACE,WAAW,mBAAmB;KAC5B;KACA,WAAW,GAAG,CAAC,kBAAkB,QAAQ,cAAc;KACxD,CAAC;IACF,eAAY;IACZ;GAGJ,oBAAC,OAAD;IACE,WAAW,GACT,oEACA,aAAa,SAAS,QAAQ,OAC9B,aAAa,SAAS,QAAQ,OAC9B,aAAa,SAAS,QAAQ,OAC9B,aAAa,SAAS,QAAQ,MAC/B;cAED,oBAAC,QAAD;KACE,WAAW,mBAAmB;MAC5B;MACA,WAAW,GAAG,CAAC,kBAAkB,QAAQ,cAAc;MACxD,CAAC;KACS;KACX,eAAY;KACZ,eAAY;KACZ;IACE;GAEL,YACC,oBAAC,QAAD;IAAM,WAAU;IAAqC;IAAgB;GAGtE,CAAC,YAAY,cAAc,oBAAC,QAAD;IAAM,WAAU;cAAW;IAAa;GAEnE,aACC,oBAAC,WAAD;IACE,WAAW,mBAAmB;KAC5B;KACA,WAAW,GAAG,CAAC,kBAAkB,QAAQ,cAAc;KACxD,CAAC;IACF,eAAY;IACZ;GAEG"}
@@ -239,7 +239,7 @@ const CarouselRoot = ({ children, className, initialIndex = 0, onIndexChange, ..
239
239
  },
240
240
  children: /* @__PURE__ */ jsxs("div", {
241
241
  ref: containerRef,
242
- className: cn("relative flex w-full cursor-grab select-none items-center overflow-hidden pb-4 outline-none transition-[height] duration-300 ease-in-out focus:outline-none focus:outline-none focus:ring-0 active:cursor-grabbing", "max-w-[1400px]", className),
242
+ className: cn("relative flex w-full cursor-grab select-none items-center overflow-hidden pb-4 outline-none transition-[height] duration-300 ease-in-out focus:outline-none focus:outline-none focus:ring-0 active:cursor-grabbing", "max-w-350", className),
243
243
  style: {
244
244
  height: containerHeight > 0 ? containerHeight : "auto",
245
245
  minHeight: "400px"
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../../../src/components/Carousel/index.tsx"],"sourcesContent":["'use client';\n\nimport { Button } from '@components/Button';\nimport { KeyboardShortcut } from '@components/KeyboardShortcut';\nimport { Popover } from '@components/Popover';\nimport { cn } from '@utils/cn';\nimport { ChevronLeft, ChevronRight } from 'lucide-react';\nimport {\n Children,\n createContext,\n type FC,\n type HTMLAttributes,\n isValidElement,\n type MouseEventHandler,\n type ReactElement,\n type ReactNode,\n type TouchEventHandler,\n useContext,\n useEffect,\n useLayoutEffect,\n useRef,\n useState,\n} from 'react';\nimport { useIntlayer } from 'react-intlayer';\n\n// ------------------------------------------------------------------\n// Configuration\n// ------------------------------------------------------------------\nconst SWIPE_THRESHOLD_DIVISOR = 5;\nconst TRANSITION_DELAY_MS = 50;\n\n// ------------------------------------------------------------------\n// Context Definition\n// ------------------------------------------------------------------\ntype CarouselContextValue = {\n selectedIndex: number;\n setSelectedIndex: (index: number) => void;\n totalItems: number;\n handlePrev: () => void;\n handleNext: () => void;\n};\n\nconst CarouselContext = createContext<CarouselContextValue | null>(null);\n\nconst useCarousel = () => {\n const context = useContext(CarouselContext);\n if (!context) {\n throw new Error('useCarousel must be used within a Carousel');\n }\n return context;\n};\n\n// ------------------------------------------------------------------\n// Helper Functions\n// ------------------------------------------------------------------\nconst getCardStyle = (index: number, displayedIndex: number) => {\n const diff = Math.abs(index - displayedIndex);\n switch (diff) {\n case 0:\n return 'opacity-100 z-40';\n case 1:\n return 'opacity-75 z-30 cursor-pointer';\n case 2:\n return 'opacity-50 z-20 pointer-events-none';\n default:\n return 'opacity-0 z-10 pointer-events-none';\n }\n};\n\nconst getCardScale = (index: number, displayedIndex: number) => {\n const diff = Math.abs(index - displayedIndex);\n switch (diff) {\n case 0:\n return 1;\n case 1:\n return 0.9;\n case 2:\n return 0.8;\n default:\n return 0.7;\n }\n};\n\n// This allows the calculation to work on SSR without hydration mismatch.\n// Your original logic: (3 * screenWidth) / 10 === 30% of viewport width\nconst getCardPositionX = (\n index: number,\n displayedIndex: number,\n containerWidth: number\n) => {\n const diff = index - displayedIndex;\n const gapPercentage = containerWidth < 600 ? 0.15 : 0.3; // Dropped to 15% for a tighter cluster\n const step = Math.min(containerWidth * gapPercentage, 300);\n\n // The 'px' here is mandatory\n return `${diff * step}px`;\n};\n\n// ------------------------------------------------------------------\n// Sub-Component: Item\n// ------------------------------------------------------------------\ntype CarouselItemProps = HTMLAttributes<HTMLDivElement> & {\n children: ReactNode;\n};\n\nconst CarouselItem: FC<CarouselItemProps> & { isCarouselItem: true } =\n Object.assign(\n ({ children, className, ...props }: CarouselItemProps) => (\n <div className={cn('size-full', className)} {...props}>\n {children}\n </div>\n ),\n { isCarouselItem: true as const }\n );\n\n// ------------------------------------------------------------------\n// Sub-Component: Indicators (Controller)\n// ------------------------------------------------------------------\ntype CarouselIndicatorsProps = HTMLAttributes<HTMLDivElement> & {\n disableKeyboardShortcuts?: boolean;\n};\n\nconst CarouselIndicators: FC<CarouselIndicatorsProps> = ({\n className,\n disableKeyboardShortcuts = false,\n ...props\n}) => {\n const {\n selectedIndex,\n setSelectedIndex,\n totalItems,\n handlePrev,\n handleNext,\n } = useCarousel();\n const { goToSlide, previousSlide, nextSlide } = useIntlayer('carousel');\n\n if (totalItems <= 1) return null;\n\n return (\n <div\n className={cn(\n 'absolute bottom-0 left-1/2 z-50 flex -translate-x-1/2 flex-row items-center gap-2',\n className\n )}\n {...props}\n >\n <Popover identifier=\"carousel-prev\">\n <Button\n variant=\"hoverable\"\n color=\"neutral\"\n label={previousSlide.value}\n roundedSize=\"full\"\n onClick={(e) => {\n e.stopPropagation();\n handlePrev();\n }}\n Icon={ChevronLeft}\n size=\"icon-md\"\n disabled={selectedIndex === 0}\n />\n\n <Popover.Detail identifier=\"carousel-prev\">\n <div className=\"flex items-center gap-2 p-2\">\n <span className=\"whitespace-nowrap text-neutral text-xs\">\n {previousSlide.value}\n </span>\n <KeyboardShortcut\n shortcut=\"ArrowLeft\"\n disabled={disableKeyboardShortcuts}\n size=\"sm\"\n onTriggered={handlePrev}\n />\n </div>\n </Popover.Detail>\n </Popover>\n\n {Array.from({ length: totalItems }).map((_, index) => {\n const isActive = index === selectedIndex;\n return (\n <button\n key={index}\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n setSelectedIndex(index);\n }}\n aria-label={goToSlide({ index: index + 1 }).value}\n className={cn(\n 'h-2.5 w-2.5 rounded-full transition-all duration-300 focus:outline-none focus:ring-2 focus:ring-neutral-400 focus:ring-offset-2',\n isActive ? 'scale-110 bg-text' : 'bg-text/20 hover:bg-text/40'\n )}\n />\n );\n })}\n\n <Popover identifier=\"carousel-next\">\n <Button\n variant=\"hoverable\"\n color=\"neutral\"\n roundedSize=\"full\"\n label={nextSlide.value}\n onClick={(e) => {\n e.stopPropagation();\n handleNext();\n }}\n Icon={ChevronRight}\n size=\"icon-md\"\n disabled={selectedIndex === totalItems - 1}\n />\n\n <Popover.Detail identifier=\"carousel-next\">\n <div className=\"flex items-center gap-2 p-2\">\n <span className=\"whitespace-nowrap text-neutral text-xs\">\n {nextSlide.value}\n </span>\n <KeyboardShortcut\n shortcut=\"ArrowRight\"\n size=\"sm\"\n onTriggered={handleNext}\n disabled={disableKeyboardShortcuts}\n />\n </div>\n </Popover.Detail>\n </Popover>\n </div>\n );\n};\n\n// ------------------------------------------------------------------\n// Main Component: Carousel Root\n// ------------------------------------------------------------------\ntype CarouselProps = HTMLAttributes<HTMLDivElement> & {\n children: ReactNode;\n initialIndex?: number;\n onIndexChange?: (index: number) => void;\n};\n\nconst partitionCarouselChildren = (\n children: ReactNode[]\n): [ReactElement[], ReactNode[]] => {\n const slides: ReactElement[] = [];\n const others: ReactNode[] = [];\n\n children.forEach((child) => {\n if (\n isValidElement(child) &&\n (child.type === CarouselItem ||\n (child.type as { isCarouselItem?: boolean }).isCarouselItem === true)\n ) {\n slides.push(child);\n } else {\n others.push(child);\n }\n });\n\n return [slides, others];\n};\n\nconst CarouselRoot: FC<CarouselProps> = ({\n children,\n className,\n initialIndex = 0,\n onIndexChange,\n ...props\n}) => {\n const allChildren = Children.toArray(children);\n const [slides, others] = partitionCarouselChildren(allChildren);\n const totalItems = slides.length;\n\n // State Management\n const [selectedIndex, setSelectedIndex] = useState<number>(initialIndex);\n const [displayedIndex, setDisplayedIndex] = useState<number>(initialIndex);\n const [containerHeight, setContainerHeight] = useState<number>(0);\n const [containerWidth, setContainerWidth] = useState<number>(0);\n\n useLayoutEffect(() => {\n const calculateDimensions = () => {\n if (!containerRef.current) return;\n\n // Track Width\n const width = containerRef.current.clientWidth;\n setContainerWidth(width);\n\n // Track Height (existing logic)\n const heights = itemsRef.current.map((item) => item?.offsetHeight || 0);\n const maxHeight = Math.max(0, ...heights);\n if (maxHeight > 0) {\n setContainerHeight(maxHeight + 40);\n }\n };\n\n calculateDimensions();\n\n const observer = new ResizeObserver(() => {\n calculateDimensions();\n });\n\n if (containerRef.current) observer.observe(containerRef.current);\n itemsRef.current.forEach((item) => {\n if (item) observer.observe(item);\n });\n\n return () => observer.disconnect();\n }, [totalItems]);\n\n // Drag State\n const [startX, setStartX] = useState(0);\n const [isDragging, setIsDragging] = useState(false);\n\n // Refs\n const containerRef = useRef<HTMLDivElement>(null);\n const itemsRef = useRef<(HTMLDivElement | null)[]>([]);\n\n // Navigation Logic\n const handleSwitchItem = (diff: number) => {\n if (containerWidth === 0) return;\n\n // Use container width for the threshold\n const swipeStep = containerWidth / SWIPE_THRESHOLD_DIVISOR;\n const numSwipe = Math.round(diff / swipeStep);\n\n if (Math.abs(numSwipe) >= 1) {\n const newIndex = displayedIndex - numSwipe;\n const clampedIndex = Math.max(0, Math.min(newIndex, totalItems - 1));\n\n if (clampedIndex !== selectedIndex) {\n setSelectedIndex(clampedIndex);\n setStartX((prev) => prev + diff);\n }\n }\n };\n\n const handleNext = () => {\n setSelectedIndex((prev) => Math.min(prev + 1, totalItems - 1));\n };\n\n const handlePrev = () => {\n setSelectedIndex((prev) => Math.max(prev - 1, 0));\n };\n\n // Input Handlers\n const handleMouseDown: MouseEventHandler<HTMLDivElement> = (e) => {\n setIsDragging(true);\n setStartX(e.clientX);\n };\n const handleMouseMove: MouseEventHandler<HTMLDivElement> = (e) => {\n if (isDragging) handleSwitchItem(e.clientX - startX);\n };\n const handleDragEnd = () => setIsDragging(false);\n const handleTouchStart: TouchEventHandler<HTMLDivElement> = (e) => {\n setIsDragging(true);\n setStartX(e.touches[0]!.clientX);\n };\n const handleTouchMove: TouchEventHandler<HTMLDivElement> = (e) => {\n if (isDragging) handleSwitchItem(e.touches[0]!.clientX - startX);\n };\n\n // Effects\n useEffect(() => {\n if (selectedIndex) onIndexChange?.(selectedIndex);\n }, [selectedIndex, onIndexChange]);\n\n useEffect(() => {\n let interval: NodeJS.Timeout;\n\n if (selectedIndex !== displayedIndex) {\n interval = setInterval(() => {\n setDisplayedIndex((prev) => {\n if (prev === selectedIndex) {\n clearInterval(interval);\n return prev;\n }\n return prev < selectedIndex ? prev + 1 : prev - 1;\n });\n }, TRANSITION_DELAY_MS);\n }\n return () => clearInterval(interval);\n }, [selectedIndex, displayedIndex]);\n\n // Calculate height based on the MAX height of ALL items\n useLayoutEffect(() => {\n const calculateMaxHeight = () => {\n const heights = itemsRef.current.map((item) => item?.offsetHeight || 0);\n const maxHeight = Math.max(0, ...heights);\n\n if (maxHeight > 0) {\n setContainerHeight(maxHeight + 40);\n }\n };\n\n calculateMaxHeight();\n\n const observer = new ResizeObserver(() => {\n calculateMaxHeight();\n });\n\n itemsRef.current.forEach((item) => {\n if (item) observer.observe(item);\n });\n\n return () => observer.disconnect();\n }, [totalItems]); // Removed isMounted dependency\n\n return (\n <CarouselContext.Provider\n value={{\n selectedIndex,\n setSelectedIndex,\n totalItems,\n handlePrev,\n handleNext,\n }}\n >\n <div\n ref={containerRef}\n className={cn(\n 'relative flex w-full cursor-grab select-none items-center overflow-hidden pb-4 outline-none transition-[height] duration-300 ease-in-out focus:outline-none focus:outline-none focus:ring-0 active:cursor-grabbing',\n 'max-w-[1400px]',\n className\n )}\n style={{\n height: containerHeight > 0 ? containerHeight : 'auto',\n minHeight: '400px',\n }}\n onMouseDown={handleMouseDown}\n onMouseMove={handleMouseMove}\n onMouseUp={handleDragEnd}\n onMouseLeave={handleDragEnd}\n onTouchStart={handleTouchStart}\n onTouchMove={handleTouchMove}\n onTouchEnd={handleDragEnd}\n role=\"region\"\n aria-label=\"Carousel\"\n {...props}\n >\n {slides.map((child, index) => {\n return (\n <div\n key={index}\n role=\"button\"\n tabIndex={0}\n ref={(el) => {\n itemsRef.current[index] = el;\n }}\n // FIX 2: Removed isMounted checks and invisible classes.\n // CSS units allow correct SSR rendering.\n className={cn(\n 'absolute left-1/2 -translate-x-1/2 transition-all duration-300 ease-in-out',\n 'outline-none ring-0 focus:outline-none focus:ring-0 focus:ring-offset-0 focus-visible:outline-none focus-visible:ring-0 focus-visible:ring-offset-0',\n getCardStyle(index, displayedIndex)\n )}\n onClick={(e) => {\n e.stopPropagation();\n setSelectedIndex(index);\n }}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') setSelectedIndex(index);\n }}\n style={{\n transform: `\n translateX(${getCardPositionX(\n index,\n displayedIndex,\n containerWidth\n )})\n scale(${getCardScale(index, displayedIndex)})\n `,\n }}\n >\n {child}\n </div>\n );\n })}\n\n {others}\n </div>\n </CarouselContext.Provider>\n );\n};\n\nexport const Carousel = Object.assign(CarouselRoot, {\n Item: CarouselItem,\n Indicators: CarouselIndicators,\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../../../src/components/Carousel/index.tsx"],"sourcesContent":["'use client';\n\nimport { Button } from '@components/Button';\nimport { KeyboardShortcut } from '@components/KeyboardShortcut';\nimport { Popover } from '@components/Popover';\nimport { cn } from '@utils/cn';\nimport { ChevronLeft, ChevronRight } from 'lucide-react';\nimport {\n Children,\n createContext,\n type FC,\n type HTMLAttributes,\n isValidElement,\n type MouseEventHandler,\n type ReactElement,\n type ReactNode,\n type TouchEventHandler,\n useContext,\n useEffect,\n useLayoutEffect,\n useRef,\n useState,\n} from 'react';\nimport { useIntlayer } from 'react-intlayer';\n\n// ------------------------------------------------------------------\n// Configuration\n// ------------------------------------------------------------------\nconst SWIPE_THRESHOLD_DIVISOR = 5;\nconst TRANSITION_DELAY_MS = 50;\n\n// ------------------------------------------------------------------\n// Context Definition\n// ------------------------------------------------------------------\ntype CarouselContextValue = {\n selectedIndex: number;\n setSelectedIndex: (index: number) => void;\n totalItems: number;\n handlePrev: () => void;\n handleNext: () => void;\n};\n\nconst CarouselContext = createContext<CarouselContextValue | null>(null);\n\nconst useCarousel = () => {\n const context = useContext(CarouselContext);\n if (!context) {\n throw new Error('useCarousel must be used within a Carousel');\n }\n return context;\n};\n\n// ------------------------------------------------------------------\n// Helper Functions\n// ------------------------------------------------------------------\nconst getCardStyle = (index: number, displayedIndex: number) => {\n const diff = Math.abs(index - displayedIndex);\n switch (diff) {\n case 0:\n return 'opacity-100 z-40';\n case 1:\n return 'opacity-75 z-30 cursor-pointer';\n case 2:\n return 'opacity-50 z-20 pointer-events-none';\n default:\n return 'opacity-0 z-10 pointer-events-none';\n }\n};\n\nconst getCardScale = (index: number, displayedIndex: number) => {\n const diff = Math.abs(index - displayedIndex);\n switch (diff) {\n case 0:\n return 1;\n case 1:\n return 0.9;\n case 2:\n return 0.8;\n default:\n return 0.7;\n }\n};\n\n// This allows the calculation to work on SSR without hydration mismatch.\n// Your original logic: (3 * screenWidth) / 10 === 30% of viewport width\nconst getCardPositionX = (\n index: number,\n displayedIndex: number,\n containerWidth: number\n) => {\n const diff = index - displayedIndex;\n const gapPercentage = containerWidth < 600 ? 0.15 : 0.3; // Dropped to 15% for a tighter cluster\n const step = Math.min(containerWidth * gapPercentage, 300);\n\n // The 'px' here is mandatory\n return `${diff * step}px`;\n};\n\n// ------------------------------------------------------------------\n// Sub-Component: Item\n// ------------------------------------------------------------------\ntype CarouselItemProps = HTMLAttributes<HTMLDivElement> & {\n children: ReactNode;\n};\n\nconst CarouselItem: FC<CarouselItemProps> & { isCarouselItem: true } =\n Object.assign(\n ({ children, className, ...props }: CarouselItemProps) => (\n <div className={cn('size-full', className)} {...props}>\n {children}\n </div>\n ),\n { isCarouselItem: true as const }\n );\n\n// ------------------------------------------------------------------\n// Sub-Component: Indicators (Controller)\n// ------------------------------------------------------------------\ntype CarouselIndicatorsProps = HTMLAttributes<HTMLDivElement> & {\n disableKeyboardShortcuts?: boolean;\n};\n\nconst CarouselIndicators: FC<CarouselIndicatorsProps> = ({\n className,\n disableKeyboardShortcuts = false,\n ...props\n}) => {\n const {\n selectedIndex,\n setSelectedIndex,\n totalItems,\n handlePrev,\n handleNext,\n } = useCarousel();\n const { goToSlide, previousSlide, nextSlide } = useIntlayer('carousel');\n\n if (totalItems <= 1) return null;\n\n return (\n <div\n className={cn(\n 'absolute bottom-0 left-1/2 z-50 flex -translate-x-1/2 flex-row items-center gap-2',\n className\n )}\n {...props}\n >\n <Popover identifier=\"carousel-prev\">\n <Button\n variant=\"hoverable\"\n color=\"neutral\"\n label={previousSlide.value}\n roundedSize=\"full\"\n onClick={(e) => {\n e.stopPropagation();\n handlePrev();\n }}\n Icon={ChevronLeft}\n size=\"icon-md\"\n disabled={selectedIndex === 0}\n />\n\n <Popover.Detail identifier=\"carousel-prev\">\n <div className=\"flex items-center gap-2 p-2\">\n <span className=\"whitespace-nowrap text-neutral text-xs\">\n {previousSlide.value}\n </span>\n <KeyboardShortcut\n shortcut=\"ArrowLeft\"\n disabled={disableKeyboardShortcuts}\n size=\"sm\"\n onTriggered={handlePrev}\n />\n </div>\n </Popover.Detail>\n </Popover>\n\n {Array.from({ length: totalItems }).map((_, index) => {\n const isActive = index === selectedIndex;\n return (\n <button\n key={index}\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n setSelectedIndex(index);\n }}\n aria-label={goToSlide({ index: index + 1 }).value}\n className={cn(\n 'h-2.5 w-2.5 rounded-full transition-all duration-300 focus:outline-none focus:ring-2 focus:ring-neutral-400 focus:ring-offset-2',\n isActive ? 'scale-110 bg-text' : 'bg-text/20 hover:bg-text/40'\n )}\n />\n );\n })}\n\n <Popover identifier=\"carousel-next\">\n <Button\n variant=\"hoverable\"\n color=\"neutral\"\n roundedSize=\"full\"\n label={nextSlide.value}\n onClick={(e) => {\n e.stopPropagation();\n handleNext();\n }}\n Icon={ChevronRight}\n size=\"icon-md\"\n disabled={selectedIndex === totalItems - 1}\n />\n\n <Popover.Detail identifier=\"carousel-next\">\n <div className=\"flex items-center gap-2 p-2\">\n <span className=\"whitespace-nowrap text-neutral text-xs\">\n {nextSlide.value}\n </span>\n <KeyboardShortcut\n shortcut=\"ArrowRight\"\n size=\"sm\"\n onTriggered={handleNext}\n disabled={disableKeyboardShortcuts}\n />\n </div>\n </Popover.Detail>\n </Popover>\n </div>\n );\n};\n\n// ------------------------------------------------------------------\n// Main Component: Carousel Root\n// ------------------------------------------------------------------\ntype CarouselProps = HTMLAttributes<HTMLDivElement> & {\n children: ReactNode;\n initialIndex?: number;\n onIndexChange?: (index: number) => void;\n};\n\nconst partitionCarouselChildren = (\n children: ReactNode[]\n): [ReactElement[], ReactNode[]] => {\n const slides: ReactElement[] = [];\n const others: ReactNode[] = [];\n\n children.forEach((child) => {\n if (\n isValidElement(child) &&\n (child.type === CarouselItem ||\n (child.type as { isCarouselItem?: boolean }).isCarouselItem === true)\n ) {\n slides.push(child);\n } else {\n others.push(child);\n }\n });\n\n return [slides, others];\n};\n\nconst CarouselRoot: FC<CarouselProps> = ({\n children,\n className,\n initialIndex = 0,\n onIndexChange,\n ...props\n}) => {\n const allChildren = Children.toArray(children);\n const [slides, others] = partitionCarouselChildren(allChildren);\n const totalItems = slides.length;\n\n // State Management\n const [selectedIndex, setSelectedIndex] = useState<number>(initialIndex);\n const [displayedIndex, setDisplayedIndex] = useState<number>(initialIndex);\n const [containerHeight, setContainerHeight] = useState<number>(0);\n const [containerWidth, setContainerWidth] = useState<number>(0);\n\n useLayoutEffect(() => {\n const calculateDimensions = () => {\n if (!containerRef.current) return;\n\n // Track Width\n const width = containerRef.current.clientWidth;\n setContainerWidth(width);\n\n // Track Height (existing logic)\n const heights = itemsRef.current.map((item) => item?.offsetHeight || 0);\n const maxHeight = Math.max(0, ...heights);\n if (maxHeight > 0) {\n setContainerHeight(maxHeight + 40);\n }\n };\n\n calculateDimensions();\n\n const observer = new ResizeObserver(() => {\n calculateDimensions();\n });\n\n if (containerRef.current) observer.observe(containerRef.current);\n itemsRef.current.forEach((item) => {\n if (item) observer.observe(item);\n });\n\n return () => observer.disconnect();\n }, [totalItems]);\n\n // Drag State\n const [startX, setStartX] = useState(0);\n const [isDragging, setIsDragging] = useState(false);\n\n // Refs\n const containerRef = useRef<HTMLDivElement>(null);\n const itemsRef = useRef<(HTMLDivElement | null)[]>([]);\n\n // Navigation Logic\n const handleSwitchItem = (diff: number) => {\n if (containerWidth === 0) return;\n\n // Use container width for the threshold\n const swipeStep = containerWidth / SWIPE_THRESHOLD_DIVISOR;\n const numSwipe = Math.round(diff / swipeStep);\n\n if (Math.abs(numSwipe) >= 1) {\n const newIndex = displayedIndex - numSwipe;\n const clampedIndex = Math.max(0, Math.min(newIndex, totalItems - 1));\n\n if (clampedIndex !== selectedIndex) {\n setSelectedIndex(clampedIndex);\n setStartX((prev) => prev + diff);\n }\n }\n };\n\n const handleNext = () => {\n setSelectedIndex((prev) => Math.min(prev + 1, totalItems - 1));\n };\n\n const handlePrev = () => {\n setSelectedIndex((prev) => Math.max(prev - 1, 0));\n };\n\n // Input Handlers\n const handleMouseDown: MouseEventHandler<HTMLDivElement> = (e) => {\n setIsDragging(true);\n setStartX(e.clientX);\n };\n const handleMouseMove: MouseEventHandler<HTMLDivElement> = (e) => {\n if (isDragging) handleSwitchItem(e.clientX - startX);\n };\n const handleDragEnd = () => setIsDragging(false);\n const handleTouchStart: TouchEventHandler<HTMLDivElement> = (e) => {\n setIsDragging(true);\n setStartX(e.touches[0]!.clientX);\n };\n const handleTouchMove: TouchEventHandler<HTMLDivElement> = (e) => {\n if (isDragging) handleSwitchItem(e.touches[0]!.clientX - startX);\n };\n\n // Effects\n useEffect(() => {\n if (selectedIndex) onIndexChange?.(selectedIndex);\n }, [selectedIndex, onIndexChange]);\n\n useEffect(() => {\n let interval: NodeJS.Timeout;\n\n if (selectedIndex !== displayedIndex) {\n interval = setInterval(() => {\n setDisplayedIndex((prev) => {\n if (prev === selectedIndex) {\n clearInterval(interval);\n return prev;\n }\n return prev < selectedIndex ? prev + 1 : prev - 1;\n });\n }, TRANSITION_DELAY_MS);\n }\n return () => clearInterval(interval);\n }, [selectedIndex, displayedIndex]);\n\n // Calculate height based on the MAX height of ALL items\n useLayoutEffect(() => {\n const calculateMaxHeight = () => {\n const heights = itemsRef.current.map((item) => item?.offsetHeight || 0);\n const maxHeight = Math.max(0, ...heights);\n\n if (maxHeight > 0) {\n setContainerHeight(maxHeight + 40);\n }\n };\n\n calculateMaxHeight();\n\n const observer = new ResizeObserver(() => {\n calculateMaxHeight();\n });\n\n itemsRef.current.forEach((item) => {\n if (item) observer.observe(item);\n });\n\n return () => observer.disconnect();\n }, [totalItems]); // Removed isMounted dependency\n\n return (\n <CarouselContext.Provider\n value={{\n selectedIndex,\n setSelectedIndex,\n totalItems,\n handlePrev,\n handleNext,\n }}\n >\n <div\n ref={containerRef}\n className={cn(\n 'relative flex w-full cursor-grab select-none items-center overflow-hidden pb-4 outline-none transition-[height] duration-300 ease-in-out focus:outline-none focus:outline-none focus:ring-0 active:cursor-grabbing',\n 'max-w-350',\n className\n )}\n style={{\n height: containerHeight > 0 ? containerHeight : 'auto',\n minHeight: '400px',\n }}\n onMouseDown={handleMouseDown}\n onMouseMove={handleMouseMove}\n onMouseUp={handleDragEnd}\n onMouseLeave={handleDragEnd}\n onTouchStart={handleTouchStart}\n onTouchMove={handleTouchMove}\n onTouchEnd={handleDragEnd}\n role=\"region\"\n aria-label=\"Carousel\"\n {...props}\n >\n {slides.map((child, index) => {\n return (\n <div\n key={index}\n role=\"button\"\n tabIndex={0}\n ref={(el) => {\n itemsRef.current[index] = el;\n }}\n // FIX 2: Removed isMounted checks and invisible classes.\n // CSS units allow correct SSR rendering.\n className={cn(\n 'absolute left-1/2 -translate-x-1/2 transition-all duration-300 ease-in-out',\n 'outline-none ring-0 focus:outline-none focus:ring-0 focus:ring-offset-0 focus-visible:outline-none focus-visible:ring-0 focus-visible:ring-offset-0',\n getCardStyle(index, displayedIndex)\n )}\n onClick={(e) => {\n e.stopPropagation();\n setSelectedIndex(index);\n }}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') setSelectedIndex(index);\n }}\n style={{\n transform: `\n translateX(${getCardPositionX(\n index,\n displayedIndex,\n containerWidth\n )})\n scale(${getCardScale(index, displayedIndex)})\n `,\n }}\n >\n {child}\n </div>\n );\n })}\n\n {others}\n </div>\n </CarouselContext.Provider>\n );\n};\n\nexport const Carousel = Object.assign(CarouselRoot, {\n Item: CarouselItem,\n Indicators: CarouselIndicators,\n});\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../../../src/components/Container/index.tsx"],"sourcesContent":["import { cn } from '@utils/cn';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport type {\n DetailedHTMLProps,\n FC,\n HTMLAttributes,\n PropsWithChildren,\n} from 'react';\n\n/**\n * Container component variants using class-variance-authority\n * Provides flexible styling options for background, padding, borders, and layout\n */\nexport const containerVariants = cva('flex flex-col text-text backdrop-blur', {\n variants: {\n roundedSize: {\n none: 'rounded-none',\n sm: 'rounded-sm [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-md',\n md: 'rounded-md [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-lg',\n lg: 'rounded-lg [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-xl',\n xl: 'rounded-xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-2xl',\n '2xl':\n 'rounded-2xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-3xl',\n '3xl':\n 'rounded-3xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-4xl',\n '4xl':\n 'rounded-4xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-[2.5rem]',\n full: 'rounded-full',\n },\n transparency: {\n none: 'bg-card',\n xs: 'bg-card/95',\n sm: 'bg-card/90',\n md: 'bg-card/70',\n lg: 'bg-card/40',\n xl: 'bg-card/20',\n full: '',\n },\n padding: {\n none: 'p-0',\n sm: 'px-3 py-2',\n md: 'px-4 py-3',\n lg: 'px-6 py-4',\n xl: 'px-8 py-6',\n '2xl': 'px-10 py-8',\n },\n separator: {\n without: '',\n x: 'divide-x divide-dashed divide-text/20',\n y: 'divide-y divide-dashed divide-text/20',\n both: 'divide-x divide-y divide-dashed divide-text/20',\n },\n border: {\n none: '',\n with: 'border-[1.3px]',\n },\n borderColor: {\n primary: 'border-primary',\n secondary: 'border-secondary',\n neutral: 'border-neutral/20',\n card: 'border-card',\n text: 'border-text',\n error: 'border-error',\n warning: 'border-warning',\n success: 'border-success',\n },\n background: {\n none: 'backdrop-blur-none',\n hoverable:\n 'bg-opacity-5! backdrop-blur-0 hover:bg-opacity-10! hover:backdrop-blur focus:bg-opacity-10! focus:backdrop-blur aria-selected:bg-opacity-15! aria-selected:backdrop-blur',\n with: '',\n },\n gap: {\n none: 'gap-0',\n sm: 'gap-1',\n md: 'gap-3',\n lg: 'gap-5',\n xl: 'gap-8',\n '2xl': 'gap-10',\n },\n },\n defaultVariants: {\n roundedSize: 'lg',\n border: 'none',\n borderColor: 'text',\n transparency: 'md',\n padding: 'none',\n separator: 'without',\n gap: 'none',\n },\n compoundVariants: [\n {\n background: 'none',\n class: 'bg-transparent',\n },\n ],\n});\n\n/** Available rounded corner sizes for the container */\nexport type ContainerRoundedSize = \n | 'none' |\n 'sm' |\n 'md' |\n 'lg' |\n 'xl' |\n 'full';\n\n/** Background transparency levels for the container */\nexport type ContainerTransparency = \n | 'none' |\n 'sm' |\n 'md' |\n 'lg' |\n 'xl' |\n 'full';\n\n/** Padding sizes for container content */\nexport type ContainerPadding = \n | 'none' |\n 'sm' |\n 'md' |\n 'lg' |\n 'xl';\n\n/** Separator options for dividing container children */\nexport type ContainerSeparator = \n | 'without' |\n 'x' |\n 'y' |\n 'both';\n\n/** Border color options for the container */\nexport type ContainerBorderColor = \n | 'primary' |\n 'secondary' |\n 'neutral' |\n 'card' |\n 'text' |\n 'error' |\n 'warning' |\n 'success';\n\n/** Background interaction states for the container */\nexport type ContainerBackground = \n | 'none' |\n 'hoverable' |\n 'with';\n\n/** Gap sizes between container children */\nexport type ContainerGap = \n | 'none' |\n 'sm' |\n 'md' |\n 'lg' |\n 'xl';\n\n/** Container component props extending HTML div attributes */\nexport type ContainerProps = PropsWithChildren<\n Omit<VariantProps<typeof containerVariants>, 'border'>\n> &\n DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement> & {\n /** Whether to show a border around the container */\n border?: boolean;\n };\n\n/**\n * Container Component\n *\n * A flexible container component for organizing content with customizable styling options.\n * Supports various visual states, layouts, and accessibility features.\n *\n * ## Features\n * - **Flexible Layout**: Supports different padding, gap, and separator options\n * - **Visual Variants**: Multiple background transparency levels and border styles\n * - **Responsive Design**: Configurable rounded corners and spacing\n * - **Semantic HTML**: Proper div element with extensible attributes\n *\n * ## Accessibility\n * - Inherits all standard div accessibility features\n * - Supports ARIA attributes through spread props\n * - Maintains proper semantic structure for screen readers\n *\n * @param children - The content to display inside the container\n * @param roundedSize - Border radius size (default: 'md')\n * @param transparency - Background transparency level (default: 'md')\n * @param padding - Internal padding size (default: 'none')\n * @param separator - Divider lines between children (default: 'without')\n * @param border - Whether to show border (default: false)\n * @param borderColor - Color of the border (default: 'text')\n * @param background - Background interaction behavior (default: 'none')\n * @param gap - Space between child elements (default: 'none')\n * @param className - Additional CSS classes\n * @param props - Additional HTML div attributes including ARIA attributes\n */\nexport const Container: FC<ContainerProps> = ({\n children,\n roundedSize,\n padding,\n transparency,\n separator,\n className,\n border,\n borderColor,\n background,\n gap,\n ...props\n}) => (\n <div\n className={cn(\n containerVariants({\n roundedSize,\n transparency,\n padding,\n separator,\n border:\n typeof border === 'boolean' ? (border ? 'with' : 'none') : undefined,\n background,\n borderColor,\n gap,\n }),\n className\n )}\n {...props}\n >\n {children}\n </div>\n);\n"],"mappings":";;;;;;;;;AAaA,MAAa,oBAAoB,IAAI,yCAAyC;CAC5E,UAAU;EACR,aAAa;GACX,MAAM;GACN,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,OACE;GACF,OACE;GACF,OACE;GACF,MAAM;GACP;EACD,cAAc;GACZ,MAAM;GACN,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,MAAM;GACP;EACD,SAAS;GACP,MAAM;GACN,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,OAAO;GACR;EACD,WAAW;GACT,SAAS;GACT,GAAG;GACH,GAAG;GACH,MAAM;GACP;EACD,QAAQ;GACN,MAAM;GACN,MAAM;GACP;EACD,aAAa;GACX,SAAS;GACT,WAAW;GACX,SAAS;GACT,MAAM;GACN,MAAM;GACN,OAAO;GACP,SAAS;GACT,SAAS;GACV;EACD,YAAY;GACV,MAAM;GACN,WACE;GACF,MAAM;GACP;EACD,KAAK;GACH,MAAM;GACN,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,OAAO;GACR;EACF;CACD,iBAAiB;EACf,aAAa;EACb,QAAQ;EACR,aAAa;EACb,cAAc;EACd,SAAS;EACT,WAAW;EACX,KAAK;EACN;CACD,kBAAkB,CAChB;EACE,YAAY;EACZ,OAAO;EACR,CACF;CACF,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkGF,MAAa,aAAiC,EAC5C,UACA,aACA,SACA,cACA,WACA,WACA,QACA,aACA,YACA,KACA,GAAG,YAEH,oBAAC,OAAD;CACE,WAAW,GACT,kBAAkB;EAChB;EACA;EACA;EACA;EACA,QACE,OAAO,WAAW,YAAa,SAAS,SAAS,SAAU;EAC7D;EACA;EACA;EACD,CAAC,EACF,UACD;CACD,GAAI;CAEH;CACG"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../../../src/components/Container/index.tsx"],"sourcesContent":["import { cn } from '@utils/cn';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport type {\n DetailedHTMLProps,\n FC,\n HTMLAttributes,\n PropsWithChildren,\n} from 'react';\n\n/**\n * Container component variants using class-variance-authority\n * Provides flexible styling options for background, padding, borders, and layout\n */\nexport const containerVariants = cva('flex flex-col text-text backdrop-blur', {\n variants: {\n roundedSize: {\n none: 'rounded-none',\n sm: 'rounded-sm [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-md',\n md: 'rounded-md [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-lg',\n lg: 'rounded-lg [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-xl',\n xl: 'rounded-xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-2xl',\n '2xl':\n 'rounded-2xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-3xl',\n '3xl':\n 'rounded-3xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-4xl',\n '4xl':\n 'rounded-4xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-[2.5rem]',\n full: 'rounded-full',\n },\n transparency: {\n none: 'bg-card',\n xs: 'bg-card/95',\n sm: 'bg-card/90',\n md: 'bg-card/70',\n lg: 'bg-card/40',\n xl: 'bg-card/20',\n full: '',\n },\n padding: {\n none: 'p-0',\n sm: 'px-3 py-2',\n md: 'px-4 py-3',\n lg: 'px-6 py-4',\n xl: 'px-8 py-6',\n '2xl': 'px-10 py-8',\n },\n separator: {\n without: '',\n x: 'divide-x divide-dashed divide-text/20',\n y: 'divide-y divide-dashed divide-text/20',\n both: 'divide-x divide-y divide-dashed divide-text/20',\n },\n border: {\n none: '',\n with: 'border-[1.3px]',\n },\n borderColor: {\n primary: 'border-primary',\n secondary: 'border-secondary',\n neutral: 'border-neutral/20',\n card: 'border-card',\n text: 'border-text',\n error: 'border-error',\n warning: 'border-warning',\n success: 'border-success',\n },\n background: {\n none: 'backdrop-blur-none',\n hoverable:\n 'bg-opacity-5! backdrop-blur-0 hover:bg-opacity-10! hover:backdrop-blur focus:bg-opacity-10! focus:backdrop-blur aria-selected:bg-opacity-15! aria-selected:backdrop-blur',\n with: '',\n },\n gap: {\n none: 'gap-0',\n sm: 'gap-1',\n md: 'gap-3',\n lg: 'gap-5',\n xl: 'gap-8',\n '2xl': 'gap-10',\n },\n },\n defaultVariants: {\n roundedSize: 'lg',\n border: 'none',\n borderColor: 'text',\n transparency: 'md',\n padding: 'none',\n separator: 'without',\n gap: 'none',\n },\n compoundVariants: [\n {\n background: 'none',\n class: 'bg-transparent',\n },\n ],\n});\n\n/** Available rounded corner sizes for the container */\nexport type ContainerRoundedSize = 'none' | 'sm' | 'md' | 'lg' | 'xl' | 'full';\n\n/** Background transparency levels for the container */\nexport type ContainerTransparency = 'none' | 'sm' | 'md' | 'lg' | 'xl' | 'full';\n\n/** Padding sizes for container content */\nexport type ContainerPadding = 'none' | 'sm' | 'md' | 'lg' | 'xl';\n\n/** Separator options for dividing container children */\nexport type ContainerSeparator = 'without' | 'x' | 'y' | 'both';\n\n/** Border color options for the container */\nexport type ContainerBorderColor =\n | 'primary'\n | 'secondary'\n | 'neutral'\n | 'card'\n | 'text'\n | 'error'\n | 'warning'\n | 'success';\n\n/** Background interaction states for the container */\nexport type ContainerBackground = 'none' | 'hoverable' | 'with';\n\n/** Gap sizes between container children */\nexport type ContainerGap = 'none' | 'sm' | 'md' | 'lg' | 'xl';\n\n/** Container component props extending HTML div attributes */\nexport type ContainerProps = PropsWithChildren<\n Omit<VariantProps<typeof containerVariants>, 'border'>\n> &\n DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement> & {\n /** Whether to show a border around the container */\n border?: boolean;\n };\n\n/**\n * Container Component\n *\n * A flexible container component for organizing content with customizable styling options.\n * Supports various visual states, layouts, and accessibility features.\n *\n * ## Features\n * - **Flexible Layout**: Supports different padding, gap, and separator options\n * - **Visual Variants**: Multiple background transparency levels and border styles\n * - **Responsive Design**: Configurable rounded corners and spacing\n * - **Semantic HTML**: Proper div element with extensible attributes\n *\n * ## Accessibility\n * - Inherits all standard div accessibility features\n * - Supports ARIA attributes through spread props\n * - Maintains proper semantic structure for screen readers\n *\n * @param children - The content to display inside the container\n * @param roundedSize - Border radius size (default: 'md')\n * @param transparency - Background transparency level (default: 'md')\n * @param padding - Internal padding size (default: 'none')\n * @param separator - Divider lines between children (default: 'without')\n * @param border - Whether to show border (default: false)\n * @param borderColor - Color of the border (default: 'text')\n * @param background - Background interaction behavior (default: 'none')\n * @param gap - Space between child elements (default: 'none')\n * @param className - Additional CSS classes\n * @param props - Additional HTML div attributes including ARIA attributes\n */\nexport const Container: FC<ContainerProps> = ({\n children,\n roundedSize,\n padding,\n transparency,\n separator,\n className,\n border,\n borderColor,\n background,\n gap,\n ...props\n}) => (\n <div\n className={cn(\n containerVariants({\n roundedSize,\n transparency,\n padding,\n separator,\n border:\n typeof border === 'boolean' ? (border ? 'with' : 'none') : undefined,\n background,\n borderColor,\n gap,\n }),\n className\n )}\n {...props}\n >\n {children}\n </div>\n);\n"],"mappings":";;;;;;;;;AAaA,MAAa,oBAAoB,IAAI,yCAAyC;CAC5E,UAAU;EACR,aAAa;GACX,MAAM;GACN,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,OACE;GACF,OACE;GACF,OACE;GACF,MAAM;GACP;EACD,cAAc;GACZ,MAAM;GACN,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,MAAM;GACP;EACD,SAAS;GACP,MAAM;GACN,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,OAAO;GACR;EACD,WAAW;GACT,SAAS;GACT,GAAG;GACH,GAAG;GACH,MAAM;GACP;EACD,QAAQ;GACN,MAAM;GACN,MAAM;GACP;EACD,aAAa;GACX,SAAS;GACT,WAAW;GACX,SAAS;GACT,MAAM;GACN,MAAM;GACN,OAAO;GACP,SAAS;GACT,SAAS;GACV;EACD,YAAY;GACV,MAAM;GACN,WACE;GACF,MAAM;GACP;EACD,KAAK;GACH,MAAM;GACN,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,OAAO;GACR;EACF;CACD,iBAAiB;EACf,aAAa;EACb,QAAQ;EACR,aAAa;EACb,cAAc;EACd,SAAS;EACT,WAAW;EACX,KAAK;EACN;CACD,kBAAkB,CAChB;EACE,YAAY;EACZ,OAAO;EACR,CACF;CACF,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqEF,MAAa,aAAiC,EAC5C,UACA,aACA,SACA,cACA,WACA,WACA,QACA,aACA,YACA,KACA,GAAG,YAEH,oBAAC,OAAD;CACE,WAAW,GACT,kBAAkB;EAChB;EACA;EACA;EACA;EACA,QACE,OAAO,WAAW,YAAa,SAAS,SAAS,SAAU;EAC7D;EACA;EACA;EACD,CAAC,EACF,UACD;CACD,GAAI;CAEH;CACG"}
@@ -27,7 +27,7 @@ const DictionaryCreationForm = ({ onDictionaryCreated }) => {
27
27
  return /* @__PURE__ */ jsxs(Form, {
28
28
  schema: DictionarySchema,
29
29
  onSubmitSuccess,
30
- className: "m-auto w-full max-w-[400px]",
30
+ className: "m-auto w-full max-w-100",
31
31
  ...form,
32
32
  children: [
33
33
  /* @__PURE__ */ jsx(Form.Input, {