@shohojdhara/atomix 0.3.5 → 0.3.6

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 (173) hide show
  1. package/README.md +101 -199
  2. package/atomix.config.ts +241 -0
  3. package/dist/atomix.css +260 -179
  4. package/dist/atomix.css.map +1 -1
  5. package/dist/atomix.min.css +250 -179
  6. package/dist/atomix.min.css.map +1 -1
  7. package/dist/charts.js +61 -66
  8. package/dist/charts.js.map +1 -1
  9. package/dist/core.js +47 -31
  10. package/dist/core.js.map +1 -1
  11. package/dist/forms.js +47 -31
  12. package/dist/forms.js.map +1 -1
  13. package/dist/heavy.js +47 -31
  14. package/dist/heavy.js.map +1 -1
  15. package/dist/index.d.ts +1841 -1633
  16. package/dist/index.esm.js +4975 -4113
  17. package/dist/index.esm.js.map +1 -1
  18. package/dist/index.js +5151 -4290
  19. package/dist/index.js.map +1 -1
  20. package/dist/index.min.js +1 -1
  21. package/dist/index.min.js.map +1 -1
  22. package/dist/theme.d.ts +1572 -1442
  23. package/dist/theme.js +4816 -4080
  24. package/dist/theme.js.map +1 -1
  25. package/package.json +6 -20
  26. package/src/components/Accordion/Accordion.stories.tsx +50 -17
  27. package/src/components/AtomixGlass/AtomixGlass.tsx +65 -31
  28. package/src/components/AtomixGlass/AtomixGlassContainer.tsx +11 -4
  29. package/src/components/AtomixGlass/stories/AtomixGlass.stories.tsx +1 -32
  30. package/src/components/AtomixGlass/stories/Examples.stories.tsx +2 -2
  31. package/src/components/AtomixGlass/stories/shared-components.tsx +0 -31
  32. package/src/components/Avatar/Avatar.stories.tsx +7 -0
  33. package/src/components/Badge/Badge.stories.tsx +91 -13
  34. package/src/components/Block/Block.stories.tsx +7 -23
  35. package/src/components/Breadcrumb/Breadcrumb.stories.tsx +7 -0
  36. package/src/components/Button/Button.stories.tsx +141 -22
  37. package/src/components/Button/ButtonGroup.stories.tsx +315 -0
  38. package/src/components/Button/ButtonGroup.tsx +67 -0
  39. package/src/components/Button/index.ts +2 -0
  40. package/src/components/Callout/Callout.stories.tsx +8 -6
  41. package/src/components/Card/Card.stories.tsx +82 -28
  42. package/src/components/Chart/AnimatedChart.tsx +0 -1
  43. package/src/components/Chart/AreaChart.tsx +0 -1
  44. package/src/components/Chart/BarChart.tsx +0 -1
  45. package/src/components/Chart/BubbleChart.tsx +0 -1
  46. package/src/components/Chart/CandlestickChart.tsx +0 -1
  47. package/src/components/Chart/Chart.stories.tsx +5 -7
  48. package/src/components/Chart/Chart.tsx +0 -16
  49. package/src/components/Chart/ChartRenderer.tsx +1 -1
  50. package/src/components/Chart/DonutChart.tsx +0 -1
  51. package/src/components/Chart/FunnelChart.tsx +0 -1
  52. package/src/components/Chart/GaugeChart.tsx +0 -1
  53. package/src/components/Chart/HeatmapChart.tsx +0 -1
  54. package/src/components/Chart/LineChart.tsx +0 -1
  55. package/src/components/Chart/MultiAxisChart.tsx +0 -1
  56. package/src/components/Chart/PieChart.tsx +0 -1
  57. package/src/components/Chart/RadarChart.tsx +0 -1
  58. package/src/components/Chart/ScatterChart.tsx +0 -1
  59. package/src/components/Chart/WaterfallChart.tsx +0 -1
  60. package/src/components/ColorModeToggle/ColorModeToggle.stories.tsx +7 -0
  61. package/src/components/DataTable/DataTable.stories.tsx +23 -16
  62. package/src/components/DatePicker/DatePicker.stories.tsx +27 -19
  63. package/src/components/Dropdown/Dropdown.stories.tsx +11 -19
  64. package/src/components/EdgePanel/EdgePanel.stories.tsx +1 -0
  65. package/src/components/Footer/Footer.stories.tsx +8 -6
  66. package/src/components/Footer/FooterLink.tsx +9 -2
  67. package/src/components/Form/Checkbox.stories.tsx +7 -0
  68. package/src/components/Form/Form.stories.tsx +7 -0
  69. package/src/components/Form/FormGroup.stories.tsx +9 -1
  70. package/src/components/Form/Input.stories.tsx +69 -16
  71. package/src/components/Form/Radio.stories.tsx +9 -1
  72. package/src/components/Form/Select.stories.tsx +9 -1
  73. package/src/components/Form/Textarea.stories.tsx +10 -2
  74. package/src/components/Hero/Hero.stories.tsx +7 -0
  75. package/src/components/List/List.stories.tsx +7 -0
  76. package/src/components/Messages/Messages.stories.tsx +8 -7
  77. package/src/components/Modal/Modal.stories.tsx +17 -6
  78. package/src/components/Navigation/Menu/Menu.stories.tsx +7 -0
  79. package/src/components/Navigation/Nav/Nav.stories.tsx +7 -0
  80. package/src/components/Navigation/Navbar/Navbar.stories.tsx +1 -0
  81. package/src/components/Navigation/SideMenu/SideMenu.stories.tsx +1 -1
  82. package/src/components/Pagination/Pagination.stories.tsx +188 -111
  83. package/src/components/Pagination/Pagination.tsx +83 -3
  84. package/src/components/PhotoViewer/PhotoViewer.stories.tsx +10 -5
  85. package/src/components/Popover/Popover.stories.tsx +191 -115
  86. package/src/components/ProductReview/ProductReview.stories.tsx +80 -58
  87. package/src/components/Progress/Progress.stories.tsx +79 -49
  88. package/src/components/Rating/Rating.stories.tsx +109 -84
  89. package/src/components/River/River.stories.tsx +194 -114
  90. package/src/components/SectionIntro/SectionIntro.stories.tsx +19 -9
  91. package/src/components/Slider/Slider.stories.tsx +7 -0
  92. package/src/components/Spinner/Spinner.stories.tsx +15 -11
  93. package/src/components/Steps/Steps.stories.tsx +132 -98
  94. package/src/components/Tabs/Tabs.stories.tsx +163 -112
  95. package/src/components/Testimonial/Testimonial.stories.tsx +114 -68
  96. package/src/components/Todo/Todo.stories.tsx +38 -12
  97. package/src/components/Toggle/Toggle.stories.tsx +61 -28
  98. package/src/components/Tooltip/Tooltip.stories.tsx +318 -200
  99. package/src/components/Upload/Upload.stories.tsx +122 -84
  100. package/src/components/VideoPlayer/VideoPlayer.stories.tsx +7 -24
  101. package/src/components/index.ts +1 -0
  102. package/src/lib/composables/useAtomixGlass.ts +2 -3
  103. package/src/lib/composables/useNavbar.ts +0 -10
  104. package/src/lib/config/loader.ts +2 -1
  105. package/src/lib/constants/components.ts +10 -0
  106. package/src/lib/hooks/useComponentCustomization.ts +1 -1
  107. package/src/lib/theme/README.md +174 -0
  108. package/src/lib/theme/adapters/index.ts +31 -0
  109. package/src/lib/theme/adapters/themeAdapter.ts +287 -0
  110. package/src/lib/theme/config/__tests__/configLoader.test.ts +207 -0
  111. package/src/lib/theme/config/configLoader.ts +254 -0
  112. package/src/lib/theme/config/loader.ts +37 -48
  113. package/src/lib/theme/config/types.ts +2 -2
  114. package/src/lib/theme/config/validator.ts +15 -91
  115. package/src/lib/theme/{constants.ts → constants/constants.ts} +0 -18
  116. package/src/lib/theme/constants/index.ts +8 -0
  117. package/src/lib/theme/core/ThemeRegistry.ts +19 -6
  118. package/src/lib/theme/core/__tests__/createTheme.test.ts +132 -0
  119. package/src/lib/theme/core/composeTheme.ts +155 -0
  120. package/src/lib/theme/core/createTheme.ts +94 -0
  121. package/src/lib/theme/{createTheme.ts → core/createThemeObject.ts} +10 -6
  122. package/src/lib/theme/core/index.ts +5 -19
  123. package/src/lib/theme/devtools/Comparator.tsx +346 -22
  124. package/src/lib/theme/devtools/IMPROVEMENTS.md +139 -38
  125. package/src/lib/theme/devtools/Inspector.tsx +335 -51
  126. package/src/lib/theme/devtools/LiveEditor.tsx +478 -107
  127. package/src/lib/theme/devtools/Preview.tsx +471 -221
  128. package/src/lib/theme/{core → devtools}/ThemeValidator.ts +1 -1
  129. package/src/lib/theme/devtools/index.ts +14 -4
  130. package/src/lib/theme/devtools/useHistory.ts +130 -0
  131. package/src/lib/theme/errors/index.ts +12 -0
  132. package/src/lib/theme/generators/cssFile.ts +79 -0
  133. package/src/lib/theme/generators/generateCSS.ts +89 -0
  134. package/src/lib/theme/{generateCSSVariables.ts → generators/generateCSSVariables.ts} +3 -13
  135. package/src/lib/theme/generators/index.ts +19 -0
  136. package/src/lib/theme/i18n/rtl.ts +5 -6
  137. package/src/lib/theme/index.ts +120 -15
  138. package/src/lib/theme/runtime/ThemeApplicator.ts +52 -111
  139. package/src/lib/theme/{ThemeContext.tsx → runtime/ThemeContext.tsx} +1 -1
  140. package/src/lib/theme/runtime/ThemeErrorBoundary.tsx +1 -1
  141. package/src/lib/theme/runtime/ThemeProvider.tsx +456 -179
  142. package/src/lib/theme/runtime/index.ts +1 -2
  143. package/src/lib/theme/runtime/useTheme.ts +1 -2
  144. package/src/lib/theme/test/testTheme.ts +385 -0
  145. package/src/lib/theme/tokens/index.ts +12 -0
  146. package/src/lib/theme/tokens/tokens.ts +721 -0
  147. package/src/lib/theme/types.ts +6 -42
  148. package/src/lib/theme/{utils.ts → utils/domUtils.ts} +2 -2
  149. package/src/lib/theme/utils/index.ts +11 -0
  150. package/src/lib/theme/utils/injectCSS.ts +90 -0
  151. package/src/lib/theme/utils/themeHelpers.ts +78 -0
  152. package/src/lib/theme/{themeUtils.ts → utils/themeUtils.ts} +1 -1
  153. package/src/lib/theme-tools.ts +7 -8
  154. package/src/lib/types/components.ts +40 -130
  155. package/src/lib/utils/componentUtils.ts +1 -1
  156. package/src/styles/01-settings/_settings.design-tokens.scss +4 -1
  157. package/src/styles/02-tools/_tools.button.scss +66 -79
  158. package/src/styles/06-components/_components.atomix-glass.scss +13 -3
  159. package/src/styles/06-components/_components.pagination.scss +88 -0
  160. package/scripts/sync-theme-config.js +0 -309
  161. package/src/lib/theme/composeTheme.ts +0 -370
  162. package/src/lib/theme/core/ThemeCache.ts +0 -283
  163. package/src/lib/theme/core/ThemeEngine.test.ts +0 -146
  164. package/src/lib/theme/core/ThemeEngine.ts +0 -665
  165. package/src/lib/theme/createThemeFromConfig.ts +0 -132
  166. package/src/lib/theme/devtools/CLI.ts +0 -364
  167. package/src/lib/theme/runtime/ThemeManager.test.ts +0 -192
  168. package/src/lib/theme/runtime/ThemeManager.ts +0 -446
  169. package/src/styles/03-generic/_generated-root.css +0 -26
  170. package/src/themes/README.md +0 -442
  171. package/src/themes/themes.config.js +0 -68
  172. /package/src/lib/theme/{cssVariableMapper.ts → adapters/cssVariableMapper.ts} +0 -0
  173. /package/src/lib/theme/{errors.ts → errors/errors.ts} +0 -0
@@ -1,38 +1,62 @@
1
1
  import React, { useState } from 'react';
2
- import { Meta, StoryFn } from '@storybook/react';
3
- import { fn } from '@storybook/test';
2
+ import type { Meta, StoryObj } from '@storybook/react';
4
3
  import { Pagination } from './Pagination';
5
- import { PaginationProps } from '../../lib/types/components';
4
+ import { SIZES } from '../../lib/constants/components';
6
5
 
7
- export default {
6
+ const meta = {
8
7
  title: 'Components/Pagination',
9
8
  component: Pagination,
9
+ parameters: {
10
+ layout: 'centered',
11
+ docs: {
12
+ description: {
13
+ component:
14
+ 'The Pagination component provides navigation controls for moving through multiple pages of content. It displays page numbers, ellipsis for large page ranges, and optional first/last and previous/next buttons. Pagination supports keyboard navigation and is fully accessible.',
15
+ },
16
+ },
17
+ },
18
+ tags: ['autodocs'],
10
19
  argTypes: {
11
20
  currentPage: {
12
21
  control: 'number',
13
22
  description: 'Current active page',
23
+ defaultValue: 1,
14
24
  },
15
25
  totalPages: {
16
26
  control: 'number',
17
27
  description: 'Total number of pages',
28
+ defaultValue: 10,
18
29
  },
19
-
20
30
  siblingCount: {
21
31
  control: 'number',
22
32
  description: 'Number of page links to show before and after current page',
33
+ defaultValue: 1,
23
34
  },
24
35
  showFirstLastButtons: {
25
36
  control: 'boolean',
26
37
  description: 'Whether to show first/last page buttons',
38
+ defaultValue: true,
27
39
  },
28
40
  showPrevNextButtons: {
29
41
  control: 'boolean',
30
42
  description: 'Whether to show previous/next page buttons',
43
+ defaultValue: true,
44
+ },
45
+ showSearch: {
46
+ control: 'boolean',
47
+ description: 'Whether to show search input for jumping to a specific page',
48
+ defaultValue: false,
49
+ },
50
+ searchPlaceholder: {
51
+ control: 'text',
52
+ description: 'Placeholder text for the search input',
53
+ defaultValue: 'Go to page',
31
54
  },
32
55
  size: {
33
- control: 'select',
34
- options: ['sm', 'md', 'lg'],
56
+ control: { type: 'select' },
57
+ options: SIZES,
35
58
  description: 'Size variant for pagination',
59
+ defaultValue: 'md',
36
60
  },
37
61
  ariaLabel: {
38
62
  control: 'text',
@@ -47,19 +71,14 @@ export default {
47
71
  description: 'Enable glass morphism effect',
48
72
  },
49
73
  },
50
- parameters: {
51
- docs: {
52
- description: {
53
- component:
54
- 'A Pagination component for navigating through pages of content with enhanced accessibility, configurable sizes, and icons for navigation buttons.',
55
- },
56
- },
57
- },
58
- } as Meta<typeof Pagination>;
74
+ } satisfies Meta<typeof Pagination>;
75
+
76
+ export default meta;
77
+ type Story = StoryObj<typeof meta>;
59
78
 
60
- // Template with controlled state
61
- const ControlledTemplate: StoryFn<PaginationProps> = args => {
62
- const [currentPage, setCurrentPage] = useState(args.currentPage);
79
+ // Helper component for controlled pagination
80
+ const ControlledPagination = (args: React.ComponentProps<typeof Pagination>) => {
81
+ const [currentPage, setCurrentPage] = useState(args.currentPage || 1);
63
82
 
64
83
  const handlePageChange = (page: number) => {
65
84
  setCurrentPage(page);
@@ -69,129 +88,145 @@ const ControlledTemplate: StoryFn<PaginationProps> = args => {
69
88
  return <Pagination {...args} currentPage={currentPage} onPageChange={handlePageChange} />;
70
89
  };
71
90
 
72
- export const Default = ControlledTemplate.bind({});
73
- Default.args = {
74
- currentPage: 1,
75
- totalPages: 10,
76
- siblingCount: 1,
77
- showFirstLastButtons: true,
78
- showPrevNextButtons: true,
79
- size: 'md',
80
- ariaLabel: 'Pagination',
81
- };
82
- Default.parameters = {
83
- docs: {
84
- description: {
85
- story: 'Default pagination with first/last and previous/next navigation buttons using icons.',
91
+ export const Default: Story = {
92
+ render: args => <ControlledPagination {...args} />,
93
+ args: {
94
+ currentPage: 1,
95
+ totalPages: 10,
96
+ siblingCount: 1,
97
+ showFirstLastButtons: true,
98
+ showPrevNextButtons: true,
99
+ size: 'md',
100
+ ariaLabel: 'Pagination',
101
+ },
102
+ parameters: {
103
+ docs: {
104
+ description: {
105
+ story: 'Default pagination with first/last and previous/next navigation buttons using icons.',
106
+ },
86
107
  },
87
108
  },
88
109
  };
89
110
 
90
- export const WithMorePages = ControlledTemplate.bind({});
91
- WithMorePages.args = {
92
- currentPage: 25,
93
- totalPages: 50,
94
- siblingCount: 2,
95
- size: 'md',
96
- };
97
- WithMorePages.parameters = {
98
- docs: {
99
- description: {
100
- story: 'Pagination with many pages, showing the ellipsis (dots) for page ranges.',
111
+ export const WithMorePages: Story = {
112
+ render: args => <ControlledPagination {...args} />,
113
+ args: {
114
+ currentPage: 25,
115
+ totalPages: 50,
116
+ siblingCount: 2,
117
+ size: 'md',
118
+ },
119
+ parameters: {
120
+ docs: {
121
+ description: {
122
+ story: 'Pagination with many pages, showing the ellipsis (dots) for page ranges.',
123
+ },
101
124
  },
102
125
  },
103
126
  };
104
127
 
105
- export const SmallSize = ControlledTemplate.bind({});
106
- SmallSize.args = {
107
- currentPage: 4,
108
- totalPages: 10,
109
- siblingCount: 1,
110
- size: 'sm',
111
- };
112
- SmallSize.parameters = {
113
- docs: {
114
- description: {
115
- story: 'Small-sized pagination component with smaller icons and buttons.',
128
+ export const SmallSize: Story = {
129
+ render: args => <ControlledPagination {...args} />,
130
+ args: {
131
+ currentPage: 4,
132
+ totalPages: 10,
133
+ siblingCount: 1,
134
+ size: 'sm',
135
+ },
136
+ parameters: {
137
+ docs: {
138
+ description: {
139
+ story: 'Small-sized pagination component with smaller icons and buttons.',
140
+ },
116
141
  },
117
142
  },
118
143
  };
119
144
 
120
- export const LargeSize = ControlledTemplate.bind({});
121
- LargeSize.args = {
122
- currentPage: 4,
123
- totalPages: 10,
124
- siblingCount: 1,
125
- size: 'lg',
126
- };
127
- LargeSize.parameters = {
128
- docs: {
129
- description: {
130
- story: 'Large-sized pagination component with larger icons and buttons.',
145
+ export const LargeSize: Story = {
146
+ render: args => <ControlledPagination {...args} />,
147
+ args: {
148
+ currentPage: 4,
149
+ totalPages: 10,
150
+ siblingCount: 1,
151
+ size: 'lg',
152
+ },
153
+ parameters: {
154
+ docs: {
155
+ description: {
156
+ story: 'Large-sized pagination component with larger icons and buttons.',
157
+ },
131
158
  },
132
159
  },
133
160
  };
134
161
 
135
- export const FewPages = ControlledTemplate.bind({});
136
- FewPages.args = {
137
- currentPage: 2,
138
- totalPages: 3,
139
- siblingCount: 1,
140
- };
141
- FewPages.parameters = {
142
- docs: {
143
- description: {
144
- story: 'Pagination with only a few pages, showing all page numbers without ellipsis.',
162
+ export const FewPages: Story = {
163
+ render: args => <ControlledPagination {...args} />,
164
+ args: {
165
+ currentPage: 2,
166
+ totalPages: 3,
167
+ siblingCount: 1,
168
+ },
169
+ parameters: {
170
+ docs: {
171
+ description: {
172
+ story: 'Pagination with only a few pages, showing all page numbers without ellipsis.',
173
+ },
145
174
  },
146
175
  },
147
176
  };
148
177
 
149
- export const NoFirstLastButtons = ControlledTemplate.bind({});
150
- NoFirstLastButtons.args = {
151
- currentPage: 5,
152
- totalPages: 15,
153
- showFirstLastButtons: false,
154
- showPrevNextButtons: true,
155
- };
156
- NoFirstLastButtons.parameters = {
157
- docs: {
158
- description: {
159
- story: 'Pagination with only previous/next navigation buttons (no skip to first/last).',
178
+ export const NoFirstLastButtons: Story = {
179
+ render: args => <ControlledPagination {...args} />,
180
+ args: {
181
+ currentPage: 5,
182
+ totalPages: 15,
183
+ showFirstLastButtons: false,
184
+ showPrevNextButtons: true,
185
+ },
186
+ parameters: {
187
+ docs: {
188
+ description: {
189
+ story: 'Pagination with only previous/next navigation buttons (no skip to first/last).',
190
+ },
160
191
  },
161
192
  },
162
193
  };
163
194
 
164
- export const OnlyPageNumbers = ControlledTemplate.bind({});
165
- OnlyPageNumbers.args = {
166
- currentPage: 5,
167
- totalPages: 15,
168
- showFirstLastButtons: false,
169
- showPrevNextButtons: false,
170
- };
171
- OnlyPageNumbers.parameters = {
172
- docs: {
173
- description: {
174
- story: 'Pagination with only page numbers, no navigation buttons.',
195
+ export const OnlyPageNumbers: Story = {
196
+ render: args => <ControlledPagination {...args} />,
197
+ args: {
198
+ currentPage: 5,
199
+ totalPages: 15,
200
+ showFirstLastButtons: false,
201
+ showPrevNextButtons: false,
202
+ },
203
+ parameters: {
204
+ docs: {
205
+ description: {
206
+ story: 'Pagination with only page numbers, no navigation buttons.',
207
+ },
175
208
  },
176
209
  },
177
210
  };
178
211
 
179
- export const CustomStyling = ControlledTemplate.bind({});
180
- CustomStyling.args = {
181
- currentPage: 5,
182
- totalPages: 15,
183
- className: 'custom-pagination-class',
184
- showFirstLastButtons: false,
185
- };
186
- CustomStyling.parameters = {
187
- docs: {
188
- description: {
189
- story: 'Pagination with custom CSS class for additional styling.',
212
+ export const CustomStyling: Story = {
213
+ render: args => <ControlledPagination {...args} />,
214
+ args: {
215
+ currentPage: 5,
216
+ totalPages: 15,
217
+ className: 'custom-pagination-class',
218
+ showFirstLastButtons: false,
219
+ },
220
+ parameters: {
221
+ docs: {
222
+ description: {
223
+ story: 'Pagination with custom CSS class for additional styling.',
224
+ },
190
225
  },
191
226
  },
192
227
  };
193
228
 
194
- export const Glass = {
229
+ export const Glass: Story = {
195
230
  args: {
196
231
  currentPage: 5,
197
232
  totalPages: 15,
@@ -233,7 +268,7 @@ export const Glass = {
233
268
  },
234
269
  };
235
270
 
236
- export const GlassCustom = {
271
+ export const GlassCustom: Story = {
237
272
  args: {
238
273
  currentPage: 5,
239
274
  totalPages: 15,
@@ -294,3 +329,45 @@ export const GlassCustom = {
294
329
  },
295
330
  },
296
331
  };
332
+
333
+ export const WithSearch: Story = {
334
+ render: args => <ControlledPagination {...args} />,
335
+ args: {
336
+ currentPage: 5,
337
+ totalPages: 50,
338
+ siblingCount: 2,
339
+ showFirstLastButtons: true,
340
+ showPrevNextButtons: true,
341
+ showSearch: true,
342
+ searchPlaceholder: 'Go to page',
343
+ size: 'md',
344
+ },
345
+ parameters: {
346
+ docs: {
347
+ description: {
348
+ story: 'Pagination with search functionality to quickly jump to a specific page. Users can type a page number and submit to navigate directly.',
349
+ },
350
+ },
351
+ },
352
+ };
353
+
354
+ export const WithSearchLargeDataset: Story = {
355
+ render: args => <ControlledPagination {...args} />,
356
+ args: {
357
+ currentPage: 250,
358
+ totalPages: 1000,
359
+ siblingCount: 2,
360
+ showFirstLastButtons: true,
361
+ showPrevNextButtons: true,
362
+ showSearch: true,
363
+ searchPlaceholder: 'Enter page number',
364
+ size: 'md',
365
+ },
366
+ parameters: {
367
+ docs: {
368
+ description: {
369
+ story: 'Pagination with search functionality for large datasets. The search feature is especially useful when dealing with many pages.',
370
+ },
371
+ },
372
+ },
373
+ };
@@ -1,12 +1,10 @@
1
- import React, { memo } from 'react';
1
+ import React, { memo, useState, FormEvent } from 'react';
2
2
  import { PaginationProps } from '../../lib/types/components';
3
3
  import { usePagination, DOTS } from '../../lib/composables/usePagination';
4
4
  import { PAGINATION_DEFAULTS } from '../../lib/constants/components';
5
5
  import { Icon, IconProps } from '../Icon/Icon';
6
6
  import { AtomixGlass } from '../AtomixGlass/AtomixGlass';
7
7
 
8
- // @TODO: Add Search functionality for pagination
9
-
10
8
  /**
11
9
  * Navigation button types for pagination
12
10
  */
@@ -59,6 +57,8 @@ export const Pagination: React.FC<PaginationProps> = memo(({
59
57
  siblingCount = PAGINATION_DEFAULTS.siblingCount,
60
58
  showFirstLastButtons = PAGINATION_DEFAULTS.showFirstLastButtons,
61
59
  showPrevNextButtons = PAGINATION_DEFAULTS.showPrevNextButtons,
60
+ showSearch = false,
61
+ searchPlaceholder = 'Go to page',
62
62
  size = PAGINATION_DEFAULTS.size,
63
63
  className = '',
64
64
  style,
@@ -72,11 +72,48 @@ export const Pagination: React.FC<PaginationProps> = memo(({
72
72
  onPageChange,
73
73
  });
74
74
 
75
+ const [searchValue, setSearchValue] = useState<string>('');
76
+ const [searchError, setSearchError] = useState<string>('');
77
+
75
78
  // Don't render pagination with a single page or no pages
76
79
  if (currentPage === 0 || paginationRange.length < 2) {
77
80
  return null;
78
81
  }
79
82
 
83
+ const handleSearchSubmit = (e: FormEvent<HTMLFormElement>) => {
84
+ e.preventDefault();
85
+ setSearchError('');
86
+
87
+ const pageNumber = parseInt(searchValue, 10);
88
+
89
+ if (isNaN(pageNumber)) {
90
+ setSearchError('Please enter a valid page number');
91
+ return;
92
+ }
93
+
94
+ if (pageNumber < 1 || pageNumber > totalPages) {
95
+ setSearchError(`Page must be between 1 and ${totalPages}`);
96
+ return;
97
+ }
98
+
99
+ if (pageNumber === currentPage) {
100
+ setSearchError('You are already on this page');
101
+ return;
102
+ }
103
+
104
+ goToPage(pageNumber);
105
+ setSearchValue('');
106
+ };
107
+
108
+ const handleSearchChange = (e: React.ChangeEvent<HTMLInputElement>) => {
109
+ const value = e.target.value;
110
+ // Only allow numbers
111
+ if (value === '' || /^\d+$/.test(value)) {
112
+ setSearchValue(value);
113
+ setSearchError('');
114
+ }
115
+ };
116
+
80
117
  const paginationContent = (
81
118
  <nav
82
119
  className={`c-pagination c-pagination--${size} ${className}`}
@@ -158,6 +195,49 @@ export const Pagination: React.FC<PaginationProps> = memo(({
158
195
  />
159
196
  )}
160
197
  </ul>
198
+
199
+ {showSearch && (
200
+ <form
201
+ className="c-pagination__search"
202
+ onSubmit={handleSearchSubmit}
203
+ aria-label="Jump to page"
204
+ >
205
+ <div className="c-pagination__search-wrapper">
206
+ <label htmlFor={`pagination-search-${currentPage}`} className="c-pagination__search-label">
207
+ <span className="c-pagination__search-label-text">Go to page:</span>
208
+ <input
209
+ id={`pagination-search-${currentPage}`}
210
+ type="text"
211
+ inputMode="numeric"
212
+ pattern="[0-9]*"
213
+ className={`c-pagination__search-input ${searchError ? 'is-error' : ''}`}
214
+ placeholder={searchPlaceholder}
215
+ value={searchValue}
216
+ onChange={handleSearchChange}
217
+ aria-label="Page number"
218
+ aria-invalid={searchError ? 'true' : 'false'}
219
+ aria-describedby={searchError ? `pagination-error-${currentPage}` : undefined}
220
+ />
221
+ </label>
222
+ <button
223
+ type="submit"
224
+ className="c-pagination__search-button"
225
+ aria-label="Go to page"
226
+ >
227
+ <Icon name="ArrowRight" size="sm" aria-hidden="true" />
228
+ </button>
229
+ </div>
230
+ {searchError && (
231
+ <div
232
+ id={`pagination-error-${currentPage}`}
233
+ className="c-pagination__search-error"
234
+ role="alert"
235
+ >
236
+ {searchError}
237
+ </div>
238
+ )}
239
+ </form>
240
+ )}
161
241
  </nav>
162
242
  );
163
243
 
@@ -1,11 +1,11 @@
1
- import { Meta, StoryObj } from '@storybook/react';
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
2
  import React from 'react';
3
3
  import { ImageType } from '../../lib/types/components';
4
4
  import { Badge } from '../Badge/Badge';
5
5
  import { Button } from '../Button/Button';
6
6
  import { PhotoViewer } from './PhotoViewer';
7
7
 
8
- const meta: Meta<typeof PhotoViewer> = {
8
+ const meta = {
9
9
  title: 'Components/PhotoViewer',
10
10
  component: PhotoViewer,
11
11
  parameters: {
@@ -13,29 +13,34 @@ const meta: Meta<typeof PhotoViewer> = {
13
13
  docs: {
14
14
  description: {
15
15
  component:
16
- 'A modern, fully-featured photo viewer component with zoom, pan, navigation, and metadata display capabilities.',
16
+ 'The PhotoViewer component provides a modern, fully-featured image viewing experience with zoom, pan, navigation, and metadata display. It supports image galleries, keyboard navigation, touch gestures, and fullscreen mode. Ideal for photo galleries, media libraries, or any application requiring detailed image viewing capabilities.',
17
17
  },
18
18
  },
19
19
  },
20
+ tags: ['autodocs'],
20
21
  argTypes: {
21
22
  thumbnailPosition: {
22
23
  control: 'select',
23
24
  options: ['bottom', 'top', 'left', 'right', 'none'],
25
+ description: 'Position of the thumbnail navigation',
24
26
  },
25
27
  enableKeyboardNavigation: {
26
28
  control: 'boolean',
29
+ description: 'Whether to enable keyboard navigation',
27
30
  },
28
31
  enableGestures: {
29
32
  control: 'boolean',
33
+ description: 'Whether to enable touch gestures',
30
34
  },
31
35
  enableFullscreen: {
32
36
  control: 'boolean',
37
+ description: 'Whether to enable fullscreen mode',
33
38
  },
34
39
  },
35
- };
40
+ } satisfies Meta<typeof PhotoViewer>;
36
41
 
37
42
  export default meta;
38
- type Story = StoryObj<typeof PhotoViewer>;
43
+ type Story = StoryObj<typeof meta>;
39
44
 
40
45
  // Sample images with rich metadata
41
46
  const sampleImages: ImageType[] = [