@axzydev/axzy_ui_system 1.2.1 → 1.2.2

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 (202) hide show
  1. package/dist/index.css +82 -1
  2. package/dist/index.css.map +1 -1
  3. package/package.json +2 -2
  4. package/src/App.tsx +354 -0
  5. package/src/assets/logo.png +0 -0
  6. package/src/assets/react.svg +1 -0
  7. package/src/components/alert/alert.props.ts +13 -0
  8. package/src/components/alert/alert.stories.tsx +41 -0
  9. package/src/components/alert/alert.tsx +53 -0
  10. package/src/components/avatar/avatar.props.ts +14 -0
  11. package/src/components/avatar/avatar.stories.tsx +46 -0
  12. package/src/components/avatar/avatar.tsx +53 -0
  13. package/src/components/badget/badget.props.ts +12 -0
  14. package/src/components/badget/badget.stories.tsx +76 -0
  15. package/src/components/badget/badget.tsx +61 -0
  16. package/src/components/breadcrumbs/breadcrumbs.props.ts +13 -0
  17. package/src/components/breadcrumbs/breadcrumbs.stories.tsx +21 -0
  18. package/src/components/breadcrumbs/breadcrumbs.tsx +34 -0
  19. package/src/components/button/button.props.ts +18 -0
  20. package/src/components/button/button.stories.tsx +174 -0
  21. package/src/components/button/button.tsx +117 -0
  22. package/src/components/calendar/calendar.props.ts +33 -0
  23. package/src/components/calendar/calendar.stories.tsx +91 -0
  24. package/src/components/calendar/calendar.tsx +608 -0
  25. package/src/components/calendar/index.ts +3 -0
  26. package/src/components/card/card.props.ts +13 -0
  27. package/src/components/card/card.stories.tsx +58 -0
  28. package/src/components/card/card.tsx +79 -0
  29. package/src/components/checkbox/checkbox.props.ts +11 -0
  30. package/src/components/checkbox/checkbox.stories.tsx +54 -0
  31. package/src/components/checkbox/checkbox.tsx +52 -0
  32. package/src/components/confirm-dialog/confirm-dialog.props.ts +14 -0
  33. package/src/components/confirm-dialog/confirm-dialog.stories.tsx +33 -0
  34. package/src/components/confirm-dialog/confirm-dialog.tsx +45 -0
  35. package/src/components/data-table/ITDataTable.stories.tsx +213 -0
  36. package/src/components/data-table/dataTable.props.ts +69 -0
  37. package/src/components/data-table/dataTable.tsx +313 -0
  38. package/src/components/date-picker/date-picker.props.ts +30 -0
  39. package/src/components/date-picker/date-picker.stories.tsx +90 -0
  40. package/src/components/date-picker/datePicker.tsx +307 -0
  41. package/src/components/dialog/dialog.props.ts +9 -0
  42. package/src/components/dialog/dialog.stories.tsx +80 -0
  43. package/src/components/dialog/dialog.tsx +88 -0
  44. package/src/components/divider/divider.props.ts +8 -0
  45. package/src/components/divider/divider.stories.tsx +34 -0
  46. package/src/components/divider/divider.tsx +21 -0
  47. package/src/components/drawer/drawer.props.ts +14 -0
  48. package/src/components/drawer/drawer.stories.tsx +41 -0
  49. package/src/components/drawer/drawer.tsx +53 -0
  50. package/src/components/dropfile/dropfile.stories.tsx +75 -0
  51. package/src/components/dropfile/dropfile.tsx +407 -0
  52. package/src/components/empty-state/empty-state.props.ts +9 -0
  53. package/src/components/empty-state/empty-state.stories.tsx +20 -0
  54. package/src/components/empty-state/empty-state.tsx +21 -0
  55. package/src/components/flex/flex.props.ts +22 -0
  56. package/src/components/flex/flex.stories.tsx +71 -0
  57. package/src/components/flex/flex.tsx +79 -0
  58. package/src/components/form-builder/fieldRenderer.tsx +218 -0
  59. package/src/components/form-builder/formBuilder.context.tsx +70 -0
  60. package/src/components/form-builder/formBuilder.props.ts +43 -0
  61. package/src/components/form-builder/formBuilder.stories.tsx +317 -0
  62. package/src/components/form-builder/formBuilder.tsx +186 -0
  63. package/src/components/form-builder/useFormBuilder.ts +80 -0
  64. package/src/components/form-header/form-header.props.ts +5 -0
  65. package/src/components/form-header/form-header.tsx +38 -0
  66. package/src/components/grid/grid.props.ts +17 -0
  67. package/src/components/grid/grid.stories.tsx +72 -0
  68. package/src/components/grid/grid.tsx +69 -0
  69. package/src/components/image/image.props.ts +7 -0
  70. package/src/components/image/image.tsx +38 -0
  71. package/src/components/input/input.props.ts +49 -0
  72. package/src/components/input/input.stories.tsx +115 -0
  73. package/src/components/input/input.tsx +615 -0
  74. package/src/components/layout/layout.props.ts +10 -0
  75. package/src/components/layout/layout.stories.tsx +114 -0
  76. package/src/components/layout/layout.tsx +80 -0
  77. package/src/components/loader/loader.props.ts +8 -0
  78. package/src/components/loader/loader.stories.tsx +105 -0
  79. package/src/components/loader/loader.tsx +108 -0
  80. package/src/components/navbar/navbar.props.ts +37 -0
  81. package/src/components/navbar/navbar.tsx +328 -0
  82. package/src/components/page/page.props.ts +19 -0
  83. package/src/components/page/page.stories.tsx +98 -0
  84. package/src/components/page/page.tsx +90 -0
  85. package/src/components/page-header/page-header.props.ts +11 -0
  86. package/src/components/page-header/page-header.stories.tsx +61 -0
  87. package/src/components/page-header/page-header.tsx +62 -0
  88. package/src/components/pagination/pagination.props.ts +53 -0
  89. package/src/components/pagination/pagination.stories.tsx +111 -0
  90. package/src/components/pagination/pagination.tsx +241 -0
  91. package/src/components/popover/popover.props.ts +12 -0
  92. package/src/components/popover/popover.stories.tsx +25 -0
  93. package/src/components/popover/popover.tsx +45 -0
  94. package/src/components/progress/progress.props.ts +12 -0
  95. package/src/components/progress/progress.stories.tsx +40 -0
  96. package/src/components/progress/progress.tsx +52 -0
  97. package/src/components/radio/radio.props.ts +16 -0
  98. package/src/components/radio/radio.stories.tsx +50 -0
  99. package/src/components/radio/radio.tsx +58 -0
  100. package/src/components/search-select/index.ts +2 -0
  101. package/src/components/search-select/search-select.props.ts +46 -0
  102. package/src/components/search-select/search-select.stories.tsx +129 -0
  103. package/src/components/search-select/search-select.tsx +229 -0
  104. package/src/components/searchTable/components/EditableCell.tsx +149 -0
  105. package/src/components/searchTable/components/PaginationControls.tsx +86 -0
  106. package/src/components/searchTable/components/PaginationInfo.tsx +20 -0
  107. package/src/components/searchTable/components/SearchAndSortBar.tsx +53 -0
  108. package/src/components/searchTable/components/SearchInput.tsx +33 -0
  109. package/src/components/searchTable/components/SortButton.tsx +50 -0
  110. package/src/components/searchTable/components/TableEmptyState.tsx +22 -0
  111. package/src/components/searchTable/components/TableHeader.tsx +35 -0
  112. package/src/components/searchTable/components/TableHeaderCell.tsx +43 -0
  113. package/src/components/searchTable/components/TableRow.tsx +144 -0
  114. package/src/components/searchTable/searchTable.props.ts +56 -0
  115. package/src/components/searchTable/searchTable.tsx +187 -0
  116. package/src/components/segmented-control/segmented-control.props.ts +18 -0
  117. package/src/components/segmented-control/segmented-control.stories.tsx +63 -0
  118. package/src/components/segmented-control/segmented-control.tsx +52 -0
  119. package/src/components/select/select.props.ts +25 -0
  120. package/src/components/select/select.stories.tsx +86 -0
  121. package/src/components/select/select.tsx +150 -0
  122. package/src/components/sidebar/sidebar.props.ts +28 -0
  123. package/src/components/sidebar/sidebar.stories.tsx +117 -0
  124. package/src/components/sidebar/sidebar.tsx +313 -0
  125. package/src/components/skeleton/skeleton.props.ts +12 -0
  126. package/src/components/skeleton/skeleton.stories.tsx +30 -0
  127. package/src/components/skeleton/skeleton.tsx +45 -0
  128. package/src/components/slide/slide.props.ts +45 -0
  129. package/src/components/slide/slide.stories.tsx +121 -0
  130. package/src/components/slide/slide.tsx +109 -0
  131. package/src/components/slider/slider.props.ts +10 -0
  132. package/src/components/slider/slider.stories.tsx +30 -0
  133. package/src/components/slider/slider.tsx +49 -0
  134. package/src/components/stack/stack.props.ts +19 -0
  135. package/src/components/stack/stack.stories.tsx +79 -0
  136. package/src/components/stack/stack.tsx +79 -0
  137. package/src/components/stat-card/stat-card.props.ts +13 -0
  138. package/src/components/stat-card/stat-card.stories.tsx +41 -0
  139. package/src/components/stat-card/stat-card.tsx +44 -0
  140. package/src/components/stepper/stepper.css +26 -0
  141. package/src/components/stepper/stepper.props.ts +29 -0
  142. package/src/components/stepper/stepper.stories.tsx +155 -0
  143. package/src/components/stepper/stepper.tsx +227 -0
  144. package/src/components/table/table.props.ts +43 -0
  145. package/src/components/table/table.stories.tsx +189 -0
  146. package/src/components/table/table.tsx +376 -0
  147. package/src/components/tabs/tabs.props.ts +18 -0
  148. package/src/components/tabs/tabs.stories.tsx +32 -0
  149. package/src/components/tabs/tabs.tsx +74 -0
  150. package/src/components/text/text.props.ts +9 -0
  151. package/src/components/text/text.tsx +20 -0
  152. package/src/components/textarea/textarea.props.ts +15 -0
  153. package/src/components/textarea/textarea.stories.tsx +27 -0
  154. package/src/components/textarea/textarea.tsx +55 -0
  155. package/src/components/theme-provider/themeProvider.props.ts +28 -0
  156. package/src/components/theme-provider/themeProvider.tsx +1854 -0
  157. package/src/components/time-picker/timePicker.props.ts +16 -0
  158. package/src/components/time-picker/timePicker.stories.tsx +131 -0
  159. package/src/components/time-picker/timePicker.tsx +317 -0
  160. package/src/components/toast/toast.css +32 -0
  161. package/src/components/toast/toast.props.ts +13 -0
  162. package/src/components/toast/toast.stories.tsx +138 -0
  163. package/src/components/toast/toast.tsx +87 -0
  164. package/src/components/tooltip/tooltip.props.ts +11 -0
  165. package/src/components/tooltip/tooltip.stories.tsx +20 -0
  166. package/src/components/tooltip/tooltip.tsx +55 -0
  167. package/src/components/topbar/topbar.props.ts +21 -0
  168. package/src/components/topbar/topbar.stories.tsx +80 -0
  169. package/src/components/topbar/topbar.tsx +205 -0
  170. package/src/components/triple-filter/tripleFilter.props.ts +15 -0
  171. package/src/components/triple-filter/tripleFilter.stories.tsx +32 -0
  172. package/src/components/triple-filter/tripleFilter.tsx +50 -0
  173. package/src/hooks/useClickOutside.ts +21 -0
  174. package/src/hooks/useDebouncedSearch.ts +55 -0
  175. package/src/hooks/useEditableRow.ts +157 -0
  176. package/src/hooks/useTableState.ts +122 -0
  177. package/src/index.css +168 -0
  178. package/src/index.ts +165 -0
  179. package/src/main.tsx +9 -0
  180. package/src/showcases/DataShowcases.tsx +260 -0
  181. package/src/showcases/FeedbackShowcases.tsx +268 -0
  182. package/src/showcases/FormShowcases.tsx +1159 -0
  183. package/src/showcases/HomeShowcase.tsx +324 -0
  184. package/src/showcases/LayoutPrimitivesShowcases.tsx +569 -0
  185. package/src/showcases/NavigationShowcases.tsx +193 -0
  186. package/src/showcases/PageShowcases.tsx +207 -0
  187. package/src/showcases/ShowcaseLayout.tsx +139 -0
  188. package/src/showcases/StructureShowcases.tsx +152 -0
  189. package/src/types/badget.types.ts +37 -0
  190. package/src/types/button.types.ts +16 -0
  191. package/src/types/colors.types.ts +3 -0
  192. package/src/types/field.types.ts +103 -0
  193. package/src/types/formik.types.ts +15 -0
  194. package/src/types/input.types.ts +14 -0
  195. package/src/types/loader.types.ts +9 -0
  196. package/src/types/sizes.types.ts +1 -0
  197. package/src/types/table.types.ts +15 -0
  198. package/src/types/toast.types.ts +8 -0
  199. package/src/types/yup.types.ts +11 -0
  200. package/src/utils/color.utils.ts +99 -0
  201. package/src/utils/styles.ts +120 -0
  202. package/src/utils/table.utils.ts +10 -0
@@ -0,0 +1,114 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import ITLayout from './layout';
3
+ import { FaHome, FaUsers, FaChartBar, FaCog, FaShieldAlt } from 'react-icons/fa';
4
+
5
+ const meta: Meta<typeof ITLayout> = {
6
+ title: 'Components/Layout & Navigation/ITLayout',
7
+ component: ITLayout,
8
+ parameters: {
9
+ layout: 'fullscreen', // Ver en fullscreen por defecto
10
+ docs: {
11
+ story: {
12
+ inline: false, // Forzar iframe para ver responsividad
13
+ iframeHeight: 700,
14
+ },
15
+ description: {
16
+ component: 'El contenedor principal ("Shell") de la interfaz. El Topbar abarca el ancho completo en la parte superior. El Sidebar está debajo del Topbar a la izquierda, y flota sobre el contenido cuando se expande (por hover) para no desplazar el diseño principal.',
17
+ },
18
+ },
19
+ },
20
+ tags: ['autodocs'],
21
+ };
22
+
23
+ export default meta;
24
+ type Story = StoryObj<typeof ITLayout>;
25
+
26
+ const mockUserMenu = {
27
+ userName: 'Alejandro G.',
28
+ userEmail: 'alejandro@axzy.io',
29
+ userImage: 'https://i.pravatar.cc/150?u=a042581f4e29026024d',
30
+ menuItems: [
31
+ { label: 'Mi Perfil', onClick: () => console.log('Perfil clicked') },
32
+ { label: 'Cerrar Sesión', onClick: () => console.log('Logout clicked') },
33
+ ],
34
+ };
35
+
36
+ const mockNavigationItems = [
37
+ { id: 'dashboard', label: 'Dashboard', icon: <FaHome />, action: () => {}, isActive: true },
38
+ {
39
+ id: 'users',
40
+ label: 'Usuarios',
41
+ icon: <FaUsers />,
42
+ subitems: [
43
+ { id: 'list', label: 'Listado', action: () => {} },
44
+ { id: 'roles', label: 'Roles', action: () => {} }
45
+ ]
46
+ },
47
+ { id: 'analytics', label: 'Reportes', icon: <FaChartBar />, action: () => {} },
48
+ { id: 'settings', label: 'Ajustes', icon: <FaCog />, action: () => {} },
49
+ ];
50
+
51
+ export const DefaultShell: Story = {
52
+ args: {
53
+ sidebar: {
54
+ navigationItems: mockNavigationItems,
55
+ },
56
+ topBar: {
57
+ logoText: 'AXZY SYSTEM',
58
+ userMenu: mockUserMenu,
59
+ navItems: [
60
+ { id: 'sec', label: 'Seguridad', icon: <FaShieldAlt />, action: () => {} }
61
+ ]
62
+ },
63
+ },
64
+ render: (args) => (
65
+ <div className="h-[700px] w-full border border-gray-200 overflow-hidden rounded-xl shadow-lg my-8 mx-auto xl:max-w-6xl">
66
+ <ITLayout {...args}>
67
+ {/* Mocked Page Content */}
68
+ <div className="max-w-4xl mx-auto space-y-6 pb-20">
69
+ <header className="mb-8">
70
+ <h1 className="text-3xl font-bold tracking-tight text-slate-900">Bienvenido de vuelta, Alejandro</h1>
71
+ <p className="mt-2 text-slate-500 text-sm">A continuación un resumen de la actividad de tu plataforma.</p>
72
+ </header>
73
+
74
+ {/* Metric Cards Mock */}
75
+ <div className="grid grid-cols-1 md:grid-cols-3 gap-6">
76
+ {[
77
+ { title: 'Usuarios Activos', value: '1,245', trend: '+12% este mes' },
78
+ { title: 'Reportes Hoy', value: '45', trend: '-2% este mes' },
79
+ { title: 'Ventas USD', value: '$12,400', trend: '+5.4% este mes' }
80
+ ].map((stat, i) => (
81
+ <div key={i} className="bg-white p-6 rounded-2xl shadow-sm border border-slate-100 flex flex-col hover:shadow-md transition-shadow">
82
+ <span className="text-sm font-medium text-slate-500">{stat.title}</span>
83
+ <span className="text-3xl font-bold text-slate-800 mt-2">{stat.value}</span>
84
+ <span className="text-xs font-semibold text-emerald-500 mt-4 bg-emerald-50 w-fit px-2 py-1 rounded-md">{stat.trend}</span>
85
+ </div>
86
+ ))}
87
+ </div>
88
+
89
+ {/* Table Mock */}
90
+ <div className="bg-white rounded-2xl border border-slate-200 shadow-sm mt-8 overflow-hidden hover:shadow-md transition-shadow">
91
+ <div className="p-6 border-b border-slate-100 flex justify-between items-center bg-slate-50/50">
92
+ <h3 className="text-base font-semibold text-slate-800">Actividad Reciente</h3>
93
+ <button className="text-sm font-medium text-emerald-600 hover:text-emerald-700">Ver todo →</button>
94
+ </div>
95
+ <div className="p-6">
96
+ <div className="animate-pulse space-y-4">
97
+ {[1,2,3,4].map(i => (
98
+ <div key={i} className="flex gap-4 items-center">
99
+ <div className="w-10 h-10 rounded-full bg-slate-100"></div>
100
+ <div className="flex-1 space-y-2">
101
+ <div className="h-3 bg-slate-100 rounded-full w-1/4"></div>
102
+ <div className="h-2 bg-slate-50 rounded-full w-1/3"></div>
103
+ </div>
104
+ <div className="w-20 h-6 bg-slate-100 rounded-full"></div>
105
+ </div>
106
+ ))}
107
+ </div>
108
+ </div>
109
+ </div>
110
+ </div>
111
+ </ITLayout>
112
+ </div>
113
+ )
114
+ };
@@ -0,0 +1,80 @@
1
+ import { useState } from "react";
2
+ import ITTopBar from "../topbar/topbar";
3
+ import ITSidebar from "../sidebar/sidebar";
4
+ import { ITLayoutProps } from "./layout.props";
5
+ export default function ITLayout({
6
+ topBar,
7
+ sidebar,
8
+ children,
9
+ className = "",
10
+ contentClassName = "",
11
+ }: ITLayoutProps) {
12
+
13
+ // Desktop states
14
+ const [desktopCollapsed, setDesktopCollapsed] = useState(true); // Default to collapsed
15
+
16
+ // Mobile drawer state
17
+ const [mobileSidebarOpen, setMobileSidebarOpen] = useState(false);
18
+
19
+ return (
20
+ <div className={`flex flex-col h-screen overflow-hidden w-full ${className}`}>
21
+
22
+ {/* TOPBAR - Full Width at Top */}
23
+ <ITTopBar
24
+ {...topBar}
25
+ showMobileMenuButton
26
+ onToggleMobileMenu={() => setMobileSidebarOpen(v => !v)}
27
+ />
28
+
29
+ <div className="flex flex-1 overflow-hidden relative" style={{ backgroundColor: "var(--layout-bg, #f8fafc)" }}>
30
+
31
+ {/* DESKTOP SIDEBAR - Floating over content when expanded */}
32
+ <div className="hidden lg:block relative z-40 h-full">
33
+ {/* Spacer to keep main content from shifting. Width matches collapsed sidebar. */}
34
+ <div className="w-[88px] h-full flex-shrink-0" />
35
+
36
+ <div className="absolute top-0 left-0 h-full">
37
+ <ITSidebar
38
+ {...sidebar}
39
+ isCollapsed={desktopCollapsed}
40
+ onToggleCollapse={() => setDesktopCollapsed(v => !v)}
41
+ visibleOnMobile={false}
42
+ className={`h-full drop-shadow-2xl transition-all duration-400 ease-[cubic-bezier(0.2,0,0,1)] flex-shrink-0`}
43
+ />
44
+ </div>
45
+ </div>
46
+
47
+ {/* MOBILE SIDEBAR PANE */}
48
+ {mobileSidebarOpen && (
49
+ <div
50
+ className="lg:hidden fixed inset-0 z-50 transition-opacity duration-300 backdrop-blur-sm bg-black/40"
51
+ onClick={() => setMobileSidebarOpen(false)}
52
+ >
53
+ <div
54
+ className="h-full w-fit flex transform transition-transform duration-300 ease-[cubic-bezier(0.2,0,0,1)]"
55
+ onClick={(e) => e.stopPropagation()}
56
+ >
57
+ <ITSidebar
58
+ {...sidebar}
59
+ isCollapsed={false}
60
+ visibleOnMobile={true}
61
+ className="h-full shadow-2xl relative z-[60]"
62
+ onToggleCollapse={() => setMobileSidebarOpen(false)}
63
+ onItemClick={() => setMobileSidebarOpen(false)}
64
+ onSubItemClick={() => setMobileSidebarOpen(false)}
65
+ />
66
+ </div>
67
+ </div>
68
+ )}
69
+
70
+ {/* MAIN CONTENT AREA */}
71
+ <main className="flex-1 overflow-y-auto w-full custom-scrollbar relative z-0">
72
+ <div className={`mx-auto w-full h-full ${contentClassName}`}>
73
+ {children}
74
+ </div>
75
+ </main>
76
+
77
+ </div>
78
+ </div>
79
+ );
80
+ }
@@ -0,0 +1,8 @@
1
+ import { LoaderSize, LoaderVariant } from "@/types/loader.types";
2
+
3
+ export interface LoaderProps {
4
+ size?: LoaderSize;
5
+ variant?: LoaderVariant;
6
+ color?: string;
7
+ className?: string;
8
+ }
@@ -0,0 +1,105 @@
1
+ import type { Meta, StoryObj } from "@storybook/react";
2
+ import ITLoader from "./loader";
3
+
4
+ const meta: Meta<typeof ITLoader> = {
5
+ title: "Components/Feedback/ITLoader",
6
+ component: ITLoader,
7
+ parameters: {
8
+ layout: "centered",
9
+ },
10
+ tags: ["autodocs"],
11
+ argTypes: {
12
+ size: {
13
+ control: "select",
14
+ options: ["sm", "md", "lg", "xl"],
15
+ description: "Size of the loader",
16
+ },
17
+ variant: {
18
+ control: "select",
19
+ options: ["spinner", "dots", "bar", "pulse"],
20
+ description: "Visual style of the loader",
21
+ },
22
+ color: {
23
+ control: "select",
24
+ options: ["primary", "secondary", "success", "danger", "warning", "info", "purple"],
25
+ description: "Semantic color from theme",
26
+ },
27
+ },
28
+ };
29
+
30
+ export default meta;
31
+ type Story = StoryObj<typeof ITLoader>;
32
+
33
+ export const Spinner: Story = {
34
+ args: {
35
+ variant: "spinner",
36
+ color: "primary",
37
+ size: "md",
38
+ },
39
+ };
40
+
41
+ export const Dots: Story = {
42
+ args: {
43
+ variant: "dots",
44
+ color: "secondary",
45
+ size: "md",
46
+ },
47
+ };
48
+
49
+ export const Pulse: Story = {
50
+ args: {
51
+ variant: "pulse",
52
+ color: "danger",
53
+ size: "lg",
54
+ },
55
+ };
56
+
57
+ export const Bar: Story = {
58
+ render: (args) => (
59
+ <div className="w-[300px]">
60
+ <ITLoader {...args} />
61
+ </div>
62
+ ),
63
+ args: {
64
+ variant: "bar",
65
+ color: "success",
66
+ size: "md",
67
+ },
68
+ };
69
+
70
+ export const AllColors: Story = {
71
+ render: (args) => (
72
+ <div className="flex gap-4 items-center">
73
+ {(['primary', 'secondary', 'success', 'danger', 'warning', 'info', 'purple'] as const).map((color) => (
74
+ <ITLoader key={color} {...args} color={color} />
75
+ ))}
76
+ </div>
77
+ ),
78
+ args: {
79
+ variant: "spinner",
80
+ size: "md",
81
+ },
82
+ };
83
+
84
+ export const AllVariants: Story = {
85
+ render: (args) => (
86
+ <div className="flex flex-col gap-8 items-center">
87
+ <div className="flex gap-4 items-center">
88
+ <span className="w-20 text-sm font-bold text-gray-500">Spinner</span>
89
+ <ITLoader variant="spinner" color="primary" />
90
+ </div>
91
+ <div className="flex gap-4 items-center">
92
+ <span className="w-20 text-sm font-bold text-gray-500">Dots</span>
93
+ <ITLoader variant="dots" color="primary" />
94
+ </div>
95
+ <div className="flex gap-4 items-center">
96
+ <span className="w-20 text-sm font-bold text-gray-500">Pulse</span>
97
+ <ITLoader variant="pulse" color="primary" />
98
+ </div>
99
+ <div className="flex gap-4 items-center w-[300px]">
100
+ <span className="w-20 text-sm font-bold text-gray-500">Bar</span>
101
+ <ITLoader variant="bar" color="primary" />
102
+ </div>
103
+ </div>
104
+ ),
105
+ };
@@ -0,0 +1,108 @@
1
+ import { theme } from "@/theme/theme";
2
+ import { LoaderSize, sizeClasses } from "@/types/loader.types";
3
+ import { LoaderProps } from "./loader.props";
4
+ import ITText from "@/components/text/text";
5
+
6
+ export default function ITLoader({
7
+ size = "md",
8
+ variant = "spinner",
9
+ color = "primary", // Default to semantic primary
10
+ className = "",
11
+ }: LoaderProps) {
12
+
13
+ // Resolve color: Check if it's a semantic color in theme, otherwise use as-is
14
+ const isSemantic = color in theme.colors;
15
+ const resolvedColor = isSemantic
16
+ ? theme.colors[color as keyof typeof theme.colors][500]
17
+ : color;
18
+
19
+ // Helper for conditional styles
20
+ const isCssValue = isSemantic || color.startsWith("#") || color.startsWith("rgb");
21
+
22
+ // Base style object
23
+ const style = isCssValue ? { color: resolvedColor } : {};
24
+ const bgStyle = isCssValue ? { backgroundColor: resolvedColor } : {};
25
+
26
+ // Legacy class handling: if it's not a CSS value, inject it as a class
27
+ const colorClass = !isCssValue ? color : "";
28
+
29
+ if (variant === "spinner") {
30
+ return (
31
+ <div
32
+ className={`inline-block ${sizeClasses[size]} animate-spin rounded-full border-2 border-solid border-current border-r-transparent align-[-0.125em] motion-reduce:animate-[spin_1.5s_linear_infinite] ${colorClass} ${className}`}
33
+ role="status"
34
+ style={style}
35
+ >
36
+ <ITText as="span" className="!absolute !-m-px !h-px !w-px !overflow-hidden !whitespace-nowrap !border-0 !p-0 ![clip:rect(0,0,0,0)]">
37
+ Loading...
38
+ </ITText>
39
+ </div>
40
+ );
41
+ }
42
+
43
+ // Dots loader
44
+ if (variant === "dots") {
45
+ return (
46
+ <div
47
+ className={`flex items-center justify-center space-x-2 ${className}`}
48
+ >
49
+ {[...Array(3)].map((_, i) => (
50
+ <div
51
+ key={i}
52
+ className={`${
53
+ sizeClasses[size.replace(/l|g/, "") as LoaderSize]
54
+ } animate-bounce rounded-full ${colorClass}`}
55
+ style={{
56
+ ...bgStyle,
57
+ animationDelay: `${i * 0.1}s`
58
+ }}
59
+ />
60
+ ))}
61
+ </div>
62
+ );
63
+ }
64
+
65
+ // Bar loader
66
+ if (variant === "bar") {
67
+ // For bar, we need a lighter shade for the background 'track' if possible,
68
+ // or just use gray-200.
69
+ // And the progress bar uses the resolved color.
70
+ return (
71
+ <div
72
+ className={`w-full ${
73
+ size === "sm"
74
+ ? "h-1"
75
+ : size === "md"
76
+ ? "h-1.5"
77
+ : size === "lg"
78
+ ? "h-2"
79
+ : "h-2.5"
80
+ } bg-gray-200 rounded-full overflow-hidden ${className}`}
81
+ >
82
+ <div
83
+ className={`h-full animate-progress ${colorClass}`}
84
+ style={{
85
+ backgroundColor: resolvedColor,
86
+ // Simplified gradient for modern look, or keep it solid
87
+ backgroundImage: isCssValue
88
+ ? `linear-gradient(to right, ${resolvedColor}DD, ${resolvedColor})`
89
+ : undefined,
90
+ animation: "progress 1.5s ease-in-out infinite",
91
+ }}
92
+ />
93
+ </div>
94
+ );
95
+ }
96
+
97
+ // Pulse loader
98
+ if (variant === "pulse") {
99
+ return (
100
+ <div
101
+ className={`rounded-full ${sizeClasses[size]} animate-pulse ${colorClass} ${className}`}
102
+ style={bgStyle}
103
+ />
104
+ );
105
+ }
106
+
107
+ return null;
108
+ }
@@ -0,0 +1,37 @@
1
+ // navbar.props.ts
2
+ export interface ITNavigationItem {
3
+ id: string;
4
+ label: string;
5
+ icon?: React.ReactNode;
6
+ action?: () => void;
7
+ isActive?: boolean;
8
+ subitems?: ITNavigationSubItem[];
9
+ }
10
+
11
+ export interface ITNavigationSubItem {
12
+ id: string;
13
+ label: string;
14
+ action: () => void;
15
+ isActive?: boolean;
16
+ }
17
+
18
+ export interface ITNavbarProps {
19
+ logo?: React.ReactNode;
20
+ logoText?: string;
21
+ navigationItems?: ITNavigationItem[];
22
+ userMenu?: {
23
+ userImage?: string;
24
+ userName: string;
25
+ userEmail: string;
26
+ menuItems: Array<{
27
+ label: string;
28
+ onClick: () => void;
29
+ }>;
30
+ };
31
+ children?: React.ReactNode;
32
+ // Legacy props for backward compatibility
33
+ navItems?: React.ReactNode;
34
+ showSidebar?: boolean;
35
+ showSidebarOnMobile?: boolean;
36
+ sidebarItems?: React.ReactNode;
37
+ }