@sproutsocial/seeds-react-pagination 0.1.28 → 0.1.31

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.
package/dist/index.js CHANGED
@@ -35,74 +35,16 @@ __export(index_exports, {
35
35
  });
36
36
  module.exports = __toCommonJS(index_exports);
37
37
 
38
- // src/Pagination.tsx
39
- var React = require("react");
38
+ // src/PaginationHybrid.tsx
39
+ var import_seeds_react_system_props = require("@sproutsocial/seeds-react-system-props");
40
+
41
+ // src/PaginationStyled.tsx
40
42
  var import_seeds_react_select = require("@sproutsocial/seeds-react-select");
41
43
  var import_seeds_react_icon = require("@sproutsocial/seeds-react-icon");
42
44
 
43
- // src/styles.ts
44
- var import_styled_components = __toESM(require("styled-components"));
45
- var import_seeds_react_text = require("@sproutsocial/seeds-react-text");
46
- var StyledPaginationContainer = import_styled_components.default.div`
47
- ${(props) => props.theme.typography[200]}
48
- display: flex;
49
- align-items: center;
50
- gap: ${(props) => props.theme.space[300]};
51
- margin-top: ${(props) => props.theme.space[400]};
52
- flex-wrap: wrap;
53
- `;
54
- var StyledPaginationControls = import_styled_components.default.div`
55
- display: flex;
56
- align-items: center;
57
- margin-left: auto;
58
- `;
59
- var StyledPaginationInfo = (0, import_styled_components.default)(import_seeds_react_text.Text)`
60
- white-space: nowrap;
61
- `;
62
- var StyledPageSizeSelector = import_styled_components.default.div`
63
- display: flex;
64
- align-items: center;
65
- gap: ${(props) => props.theme.space[300]};
66
- `;
67
- var StyledPageButtons = import_styled_components.default.div`
68
- display: inline-flex;
69
- flex-flow: row wrap;
70
- background-clip: padding-box;
71
- border: 1px solid
72
- ${(props) => props.theme.colors.button.secondary.border.base};
73
- border-radius: ${(props) => props.theme.radii.outer};
74
- padding: ${(props) => props.theme.space[100]};
75
- background: transparent;
76
- `;
77
- var StyledPaginationButton = import_styled_components.default.button`
78
- min-width: calc(${(props) => props.theme.space[500]} + 4px);
79
- min-height: calc(${(props) => props.theme.space[500]} + 2px);
80
- padding: calc(${(props) => props.theme.space[350]} - 6px);
81
- line-height: ${(props) => props.theme.space[400]};
82
- font-weight: ${(props) => props.theme.fontWeights.semibold};
83
- background-color: ${(props) => props.isSelected ? props.theme.colors.button.secondary.background.active : "transparent"};
84
- color: ${(props) => props.isSelected ? props.theme.colors.text.inverse : props.theme.colors.text.body};
85
- border: none;
86
- border-radius: ${(props) => props.theme.radii.inner};
87
- cursor: pointer;
88
- display: inline-flex;
89
- align-items: center;
90
- justify-content: center;
91
-
92
- &:hover:not(:disabled) {
93
- color: ${(props) => props.isSelected ? props.theme.colors.text.inverse : void 0};
94
- background-color: ${(props) => props.isSelected ? props.theme.colors.button.secondary.background.active : props.theme.colors.listItem.background.hover};
95
- }
96
-
97
- &:disabled {
98
- cursor: default;
99
- opacity: ${(props) => props.isSelected ? 1 : 0.5};
100
- }
101
- `;
102
-
103
- // src/Pagination.tsx
104
- var import_jsx_runtime = require("react/jsx-runtime");
105
- var Pagination = ({
45
+ // src/usePaginationModel.ts
46
+ var React = require("react");
47
+ var usePaginationModel = ({
106
48
  paginationConfig,
107
49
  currentPageIndex,
108
50
  pageSize,
@@ -169,10 +111,106 @@ var Pagination = ({
169
111
  return pages;
170
112
  };
171
113
  const pageNumbers = getPageNumbers();
114
+ return {
115
+ displayType,
116
+ pageSizeOptions,
117
+ tableCountFunction,
118
+ totalPages,
119
+ currentPage,
120
+ startRow,
121
+ endRow,
122
+ canGoPrevious,
123
+ canGoNext,
124
+ handlePrevious,
125
+ handleNext,
126
+ handlePageSizeChange,
127
+ pageNumbers
128
+ };
129
+ };
130
+
131
+ // src/styles.ts
132
+ var import_styled_components = __toESM(require("styled-components"));
133
+ var import_seeds_react_text = require("@sproutsocial/seeds-react-text");
134
+ var StyledPaginationContainer = import_styled_components.default.div`
135
+ ${(props) => props.theme.typography[200]}
136
+ display: flex;
137
+ align-items: center;
138
+ gap: ${(props) => props.theme.space[300]};
139
+ margin-top: ${(props) => props.theme.space[400]};
140
+ flex-wrap: wrap;
141
+ `;
142
+ var StyledPaginationControls = import_styled_components.default.div`
143
+ display: flex;
144
+ align-items: center;
145
+ margin-left: auto;
146
+ `;
147
+ var StyledPaginationInfo = (0, import_styled_components.default)(import_seeds_react_text.Text)`
148
+ white-space: nowrap;
149
+ `;
150
+ var StyledPageSizeSelector = import_styled_components.default.div`
151
+ display: flex;
152
+ align-items: center;
153
+ gap: ${(props) => props.theme.space[300]};
154
+ `;
155
+ var StyledPageButtons = import_styled_components.default.div`
156
+ display: inline-flex;
157
+ flex-flow: row wrap;
158
+ background-clip: padding-box;
159
+ border: 1px solid
160
+ ${(props) => props.theme.colors.button.secondary.border.base};
161
+ border-radius: ${(props) => props.theme.radii.outer};
162
+ padding: ${(props) => props.theme.space[100]};
163
+ background: transparent;
164
+ `;
165
+ var StyledPaginationButton = import_styled_components.default.button`
166
+ min-width: calc(${(props) => props.theme.space[500]} + 4px);
167
+ min-height: calc(${(props) => props.theme.space[500]} + 2px);
168
+ padding: calc(${(props) => props.theme.space[350]} - 6px);
169
+ line-height: ${(props) => props.theme.space[400]};
170
+ font-weight: ${(props) => props.theme.fontWeights.semibold};
171
+ background-color: ${(props) => props.isSelected ? props.theme.colors.button.secondary.background.active : "transparent"};
172
+ color: ${(props) => props.isSelected ? props.theme.colors.text.inverse : props.theme.colors.text.body};
173
+ border: none;
174
+ border-radius: ${(props) => props.theme.radii.inner};
175
+ cursor: pointer;
176
+ display: inline-flex;
177
+ align-items: center;
178
+ justify-content: center;
179
+
180
+ &:hover:not(:disabled) {
181
+ color: ${(props) => props.isSelected ? props.theme.colors.text.inverse : void 0};
182
+ background-color: ${(props) => props.isSelected ? props.theme.colors.button.secondary.background.active : props.theme.colors.listItem.background.hover};
183
+ }
184
+
185
+ &:disabled {
186
+ cursor: default;
187
+ opacity: ${(props) => props.isSelected ? 1 : 0.5};
188
+ }
189
+ `;
190
+
191
+ // src/PaginationStyled.tsx
192
+ var import_jsx_runtime = require("react/jsx-runtime");
193
+ var PaginationStyled = (props) => {
194
+ const { pageSize, totalRows, onPageChange, className } = props;
195
+ const {
196
+ displayType,
197
+ pageSizeOptions,
198
+ tableCountFunction,
199
+ totalPages,
200
+ currentPage,
201
+ startRow,
202
+ endRow,
203
+ canGoPrevious,
204
+ canGoNext,
205
+ handlePrevious,
206
+ handleNext,
207
+ handlePageSizeChange,
208
+ pageNumbers
209
+ } = usePaginationModel(props);
172
210
  if (totalPages <= 1 && !pageSizeOptions) {
173
211
  return null;
174
212
  }
175
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(StyledPaginationContainer, { children: [
213
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(StyledPaginationContainer, { className, children: [
176
214
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(StyledPaginationInfo, { children: tableCountFunction({
177
215
  startNum: startRow,
178
216
  endNum: endRow,
@@ -243,6 +281,141 @@ var Pagination = ({
243
281
  ] });
244
282
  };
245
283
 
284
+ // src/PaginationTailwind.tsx
285
+ var import_seeds_react_select2 = require("@sproutsocial/seeds-react-select");
286
+ var import_seeds_react_icon2 = require("@sproutsocial/seeds-react-icon");
287
+ var import_seeds_react_text2 = require("@sproutsocial/seeds-react-text");
288
+ var import_jsx_runtime2 = require("react/jsx-runtime");
289
+ function cn(...inputs) {
290
+ const classes = [];
291
+ for (const input of inputs) {
292
+ if (!input) continue;
293
+ if (typeof input === "string") {
294
+ classes.push(input);
295
+ } else if (typeof input === "object") {
296
+ for (const [key, value] of Object.entries(input)) {
297
+ if (value) {
298
+ classes.push(key);
299
+ }
300
+ }
301
+ }
302
+ }
303
+ return classes.join(" ");
304
+ }
305
+ var PaginationTailwind = (props) => {
306
+ const { pageSize, totalRows, onPageChange, className } = props;
307
+ const {
308
+ displayType,
309
+ pageSizeOptions,
310
+ tableCountFunction,
311
+ totalPages,
312
+ currentPage,
313
+ startRow,
314
+ endRow,
315
+ canGoPrevious,
316
+ canGoNext,
317
+ handlePrevious,
318
+ handleNext,
319
+ handlePageSizeChange,
320
+ pageNumbers
321
+ } = usePaginationModel(props);
322
+ if (totalPages <= 1 && !pageSizeOptions) {
323
+ return null;
324
+ }
325
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: cn("seeds-pagination-container", className), children: [
326
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_seeds_react_text2.Text, { className: cn("seeds-pagination-info"), children: tableCountFunction({
327
+ startNum: startRow,
328
+ endNum: endRow,
329
+ totalRowCount: totalRows
330
+ }) }),
331
+ pageSizeOptions && displayType === "dropdown" && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: cn("seeds-pagination-page-size-selector"), children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
332
+ import_seeds_react_select2.Select,
333
+ {
334
+ id: "page-size-select",
335
+ name: "page-size",
336
+ value: String(pageSize),
337
+ onChange: handlePageSizeChange,
338
+ ariaLabel: "Rows per page",
339
+ size: "small",
340
+ children: pageSizeOptions.map((size) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("option", { value: size, children: [
341
+ size,
342
+ " per page"
343
+ ] }, size))
344
+ }
345
+ ) }),
346
+ totalPages > 1 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: cn("seeds-pagination-controls"), children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: cn("seeds-pagination-page-buttons"), children: [
347
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
348
+ "button",
349
+ {
350
+ type: "button",
351
+ className: cn("seeds-pagination-button"),
352
+ onClick: handlePrevious,
353
+ disabled: !canGoPrevious,
354
+ "aria-label": "Previous page",
355
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_seeds_react_icon2.Icon, { name: "chevron-left-outline" })
356
+ }
357
+ ),
358
+ pageNumbers.map((pageNum, index) => {
359
+ if (pageNum === "...") {
360
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
361
+ "button",
362
+ {
363
+ type: "button",
364
+ className: cn("seeds-pagination-button"),
365
+ disabled: true,
366
+ "aria-label": "More pages",
367
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_seeds_react_icon2.Icon, { name: "ellipsis-horizontal-outline" })
368
+ },
369
+ `ellipsis-${index}`
370
+ );
371
+ }
372
+ const page = pageNum;
373
+ const isCurrentPage = page === currentPage;
374
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
375
+ "button",
376
+ {
377
+ type: "button",
378
+ className: cn("seeds-pagination-button", {
379
+ "seeds-pagination-button-selected": isCurrentPage
380
+ }),
381
+ onClick: () => onPageChange(page - 1),
382
+ disabled: isCurrentPage,
383
+ "aria-label": `Page ${page}`,
384
+ "aria-current": isCurrentPage ? "page" : void 0,
385
+ children: page
386
+ },
387
+ page
388
+ );
389
+ }),
390
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
391
+ "button",
392
+ {
393
+ type: "button",
394
+ className: cn("seeds-pagination-button"),
395
+ onClick: handleNext,
396
+ disabled: !canGoNext,
397
+ "aria-label": "Next page",
398
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_seeds_react_icon2.Icon, { name: "chevron-right-outline" })
399
+ }
400
+ )
401
+ ] }) })
402
+ ] });
403
+ };
404
+
405
+ // src/PaginationHybrid.tsx
406
+ var import_jsx_runtime3 = require("react/jsx-runtime");
407
+ var PaginationHybrid = (props) => {
408
+ if ((0, import_seeds_react_system_props.hasStyledProps)(props)) {
409
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PaginationStyled, { ...props });
410
+ }
411
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PaginationTailwind, { ...props });
412
+ };
413
+
414
+ // src/Pagination.tsx
415
+ var import_jsx_runtime4 = require("react/jsx-runtime");
416
+ var Pagination = (props) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(PaginationHybrid, { ...props });
417
+ Pagination.displayName = "Pagination";
418
+
246
419
  // src/PaginationTypes.ts
247
420
  var React2 = require("react");
248
421
  var PAGE_SIZE_OPTIONS_STANDARD = [10, 25, 50, 100];
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/Pagination.tsx","../src/styles.ts","../src/PaginationTypes.ts"],"sourcesContent":["export { Pagination } from \"./Pagination\";\nexport * from \"./PaginationTypes\";\n","import * as React from \"react\";\nimport { Select } from \"@sproutsocial/seeds-react-select\";\nimport { Icon } from \"@sproutsocial/seeds-react-icon\";\nimport type { TypePaginationConfig } from \"./PaginationTypes\";\nimport {\n StyledPaginationContainer,\n StyledPaginationControls,\n StyledPaginationInfo,\n StyledPageSizeSelector,\n StyledPageButtons,\n StyledPaginationButton,\n} from \"./styles\";\n\ninterface PaginationProps {\n paginationConfig: TypePaginationConfig;\n currentPageIndex: number;\n pageSize: number;\n totalRows: number;\n onPageChange: (pageIndex: number) => void;\n onPageSizeChange: (pageSize: number) => void;\n}\n\nexport const Pagination = ({\n paginationConfig,\n currentPageIndex,\n pageSize,\n totalRows,\n onPageChange,\n onPageSizeChange,\n}: PaginationProps) => {\n const { displayType, pageSizeOptions, tableCountFunction } = paginationConfig;\n\n // Calculate pagination values\n const totalPages = Math.ceil(totalRows / pageSize);\n const currentPage = currentPageIndex + 1; // Convert 0-based to 1-based for display\n const startRow = totalRows === 0 ? 0 : currentPageIndex * pageSize + 1;\n const endRow = Math.min((currentPageIndex + 1) * pageSize, totalRows);\n\n const canGoPrevious = currentPageIndex > 0;\n const canGoNext = currentPageIndex < totalPages - 1;\n\n const handlePrevious = () => {\n if (canGoPrevious) {\n onPageChange(currentPageIndex - 1);\n }\n };\n\n const handleNext = () => {\n if (canGoNext) {\n onPageChange(currentPageIndex + 1);\n }\n };\n\n const handlePageSizeChange = (e: React.SyntheticEvent<HTMLSelectElement>) => {\n const newPageSize = Number(e.currentTarget.value);\n onPageSizeChange(newPageSize);\n // Reset to first page when page size changes\n onPageChange(0);\n };\n\n // Generate page number buttons using web-app-core's algorithm\n const getPageNumbers = () => {\n const pages: (number | string)[] = [];\n const size = paginationConfig.size || \"default\";\n\n // Configuration for how many pages to show around current page\n const NUM_PAGE_LOWER = size === \"mini\" ? 0 : 1;\n const NUM_PAGE_UPPER = size === \"mini\" ? 0 : 2;\n\n // If number of pages is small enough, show all the page tokens without ellipsis\n if (totalPages <= 5 + NUM_PAGE_LOWER + NUM_PAGE_UPPER) {\n for (let i = 1; i <= totalPages; i++) {\n pages.push(i);\n }\n } else {\n // Add first page\n pages.push(1);\n\n // Add ellipsis at the beginning if needed\n if (currentPage > 3 + NUM_PAGE_LOWER) {\n pages.push(\"...\");\n }\n\n // Add pages in the middle\n let start: number;\n let end: number; // inclusive index\n\n // If near beginning - Show number of pages before ending ellipsis\n if (currentPage <= 3 + NUM_PAGE_LOWER) {\n start = 2;\n end = 3 + NUM_PAGE_LOWER + NUM_PAGE_UPPER;\n } else if (currentPage > totalPages - (3 + NUM_PAGE_UPPER)) {\n // If near end - Show number of pages after starting ellipsis\n start = totalPages - (2 + NUM_PAGE_LOWER + NUM_PAGE_UPPER);\n end = totalPages - 1;\n } else {\n // If in the middle - Show number of pages between two ellipses\n start = currentPage - NUM_PAGE_LOWER;\n end = currentPage + NUM_PAGE_UPPER;\n }\n\n for (let i = start; i <= end; i++) {\n pages.push(i);\n }\n\n // Add a final ellipsis if necessary\n if (currentPage < totalPages - (2 + NUM_PAGE_UPPER)) {\n pages.push(\"...\");\n }\n\n // Add the last page number\n pages.push(totalPages);\n }\n\n return pages;\n };\n\n const pageNumbers = getPageNumbers();\n\n if (totalPages <= 1 && !pageSizeOptions) {\n // No pagination needed if only one page and no page size options\n return null;\n }\n\n return (\n <StyledPaginationContainer>\n <StyledPaginationInfo>\n {tableCountFunction({\n startNum: startRow,\n endNum: endRow,\n totalRowCount: totalRows,\n })}\n </StyledPaginationInfo>\n {/* Page size selector */}\n {pageSizeOptions && displayType === \"dropdown\" && (\n <StyledPageSizeSelector>\n <Select\n id=\"page-size-select\"\n name=\"page-size\"\n value={String(pageSize)}\n onChange={handlePageSizeChange}\n ariaLabel=\"Rows per page\"\n size=\"small\"\n >\n {pageSizeOptions.map((size) => (\n <option key={size} value={size}>\n {size} per page\n </option>\n ))}\n </Select>\n </StyledPageSizeSelector>\n )}\n\n {/* TODO: Add inline page size selector for displayType === 'inline' */}\n\n {/* Page navigation controls */}\n {totalPages > 1 && (\n <StyledPaginationControls>\n <StyledPageButtons>\n <StyledPaginationButton\n onClick={handlePrevious}\n disabled={!canGoPrevious}\n aria-label=\"Previous page\"\n >\n <Icon name=\"chevron-left-outline\" />\n </StyledPaginationButton>\n\n {pageNumbers.map((pageNum, index) => {\n if (pageNum === \"...\") {\n return (\n <StyledPaginationButton\n key={`ellipsis-${index}`}\n disabled\n aria-label=\"More pages\"\n >\n <Icon name=\"ellipsis-horizontal-outline\" />\n </StyledPaginationButton>\n );\n }\n\n const page = pageNum as number;\n const isCurrentPage = page === currentPage;\n\n return (\n <StyledPaginationButton\n key={page}\n onClick={() => onPageChange(page - 1)}\n disabled={isCurrentPage}\n aria-label={`Page ${page}`}\n aria-current={isCurrentPage ? \"page\" : undefined}\n isSelected={isCurrentPage}\n >\n {page}\n </StyledPaginationButton>\n );\n })}\n\n <StyledPaginationButton\n onClick={handleNext}\n disabled={!canGoNext}\n aria-label=\"Next page\"\n >\n <Icon name=\"chevron-right-outline\" />\n </StyledPaginationButton>\n </StyledPageButtons>\n </StyledPaginationControls>\n )}\n </StyledPaginationContainer>\n );\n};\n","import styled from \"styled-components\";\nimport { Text } from \"@sproutsocial/seeds-react-text\";\n\n// Pagination Styles\nexport const StyledPaginationContainer = styled.div`\n ${(props) => props.theme.typography[200]}\n display: flex;\n align-items: center;\n gap: ${(props) => props.theme.space[300]};\n margin-top: ${(props) => props.theme.space[400]};\n flex-wrap: wrap;\n`;\n\nexport const StyledPaginationControls = styled.div`\n display: flex;\n align-items: center;\n margin-left: auto;\n`;\n\nexport const StyledPaginationInfo = styled(Text)`\n white-space: nowrap;\n`;\n\nexport const StyledPageSizeSelector = styled.div`\n display: flex;\n align-items: center;\n gap: ${(props) => props.theme.space[300]};\n`;\n\nexport const StyledPageButtons = styled.div`\n display: inline-flex;\n flex-flow: row wrap;\n background-clip: padding-box;\n border: 1px solid\n ${(props) => props.theme.colors.button.secondary.border.base};\n border-radius: ${(props) => props.theme.radii.outer};\n padding: ${(props) => props.theme.space[100]};\n background: transparent;\n`;\n\nexport const StyledPaginationButton = styled.button<{ isSelected?: boolean }>`\n min-width: calc(${(props) => props.theme.space[500]} + 4px);\n min-height: calc(${(props) => props.theme.space[500]} + 2px);\n padding: calc(${(props) => props.theme.space[350]} - 6px);\n line-height: ${(props) => props.theme.space[400]};\n font-weight: ${(props) => props.theme.fontWeights.semibold};\n background-color: ${(props) =>\n props.isSelected\n ? props.theme.colors.button.secondary.background.active\n : \"transparent\"};\n color: ${(props) =>\n props.isSelected\n ? props.theme.colors.text.inverse\n : props.theme.colors.text.body};\n border: none;\n border-radius: ${(props) => props.theme.radii.inner};\n cursor: pointer;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n\n &:hover:not(:disabled) {\n color: ${(props) =>\n props.isSelected ? props.theme.colors.text.inverse : undefined};\n background-color: ${(props) =>\n props.isSelected\n ? props.theme.colors.button.secondary.background.active\n : props.theme.colors.listItem.background.hover};\n }\n\n &:disabled {\n cursor: default;\n opacity: ${(props) => (props.isSelected ? 1 : 0.5)};\n }\n`;\n","import * as React from \"react\";\n\n/**\n * Standard page size option sets for pagination.\n * Export these constants to maintain consistency across tables.\n */\nconst PAGE_SIZE_OPTIONS_STANDARD = [10, 25, 50, 100] as const;\nconst PAGE_SIZE_OPTIONS_COMPACT = [5, 10, 20] as const;\nconst PAGE_SIZE_OPTIONS_LARGE = [50, 100, 200, 500] as const;\n\nexport const PAGE_SIZE_OPTIONS = {\n STANDARD: PAGE_SIZE_OPTIONS_STANDARD,\n COMPACT: PAGE_SIZE_OPTIONS_COMPACT,\n LARGE: PAGE_SIZE_OPTIONS_LARGE,\n};\n\n/**\n * Allowed page size option sets.\n * Use one of the predefined PAGE_SIZE_OPTIONS for consistency.\n */\nexport type TypeAllowedPageSizeOptions =\n | typeof PAGE_SIZE_OPTIONS_STANDARD\n | typeof PAGE_SIZE_OPTIONS_COMPACT\n | typeof PAGE_SIZE_OPTIONS_LARGE;\n\n/**\n * Configuration for pagination controls with page navigation and size selection.\n *\n * @example\n * ```tsx\n * <Pagination\n * paginationConfig={{\n * initialPageSize: 25,\n * displayType: 'dropdown',\n * pageSizeOptions: PAGE_SIZE_OPTIONS.STANDARD,\n * tableCountFunction: ({ startNum, endNum, totalRowCount }) =>\n * `${startNum}-${endNum} of ${totalRowCount}`\n * }}\n * currentPageIndex={0}\n * pageSize={25}\n * totalRows={100}\n * onPageChange={(index) => console.log('Page:', index)}\n * onPageSizeChange={(size) => console.log('Page size:', size)}\n * />\n * ```\n */\nexport interface TypePaginationConfig {\n /**\n * Initial number of rows per page.\n * @default 10\n */\n initialPageSize: number;\n /**\n * Function that returns the intl for displaying the table counts underneath a DataTable\n */\n tableCountFunction: (args: {\n startNum: number;\n endNum: number;\n totalRowCount: number;\n }) => React.ReactNode;\n /**\n * Display mode for page size selector.\n * - 'dropdown': Shows page size selector as a dropdown\n * Only used when pageSizeOptions is provided.\n * @default 'dropdown'\n */\n displayType?: \"dropdown\";\n /**\n * Optional array of page size options for the selector.\n * If not provided, page size selection will not be available.\n * Use PAGE_SIZE_OPTIONS constants for consistency.\n *\n * @example\n * pageSizeOptions: PAGE_SIZE_OPTIONS.STANDARD // [10, 25, 50, 100]\n */\n pageSizeOptions?: TypeAllowedPageSizeOptions;\n /**\n * Size variant for page number display.\n * - 'default': Shows current page ±1-2 pages (more visible pages)\n * - 'mini': Shows only current page (fewer visible pages)\n * @default 'default'\n */\n size?: \"default\" | \"mini\";\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,YAAuB;AACvB,gCAAuB;AACvB,8BAAqB;;;ACFrB,+BAAmB;AACnB,8BAAqB;AAGd,IAAM,4BAA4B,yBAAAA,QAAO;AAAA,IAC5C,CAAC,UAAU,MAAM,MAAM,WAAW,GAAG,CAAC;AAAA;AAAA;AAAA,SAGjC,CAAC,UAAU,MAAM,MAAM,MAAM,GAAG,CAAC;AAAA,gBAC1B,CAAC,UAAU,MAAM,MAAM,MAAM,GAAG,CAAC;AAAA;AAAA;AAI1C,IAAM,2BAA2B,yBAAAA,QAAO;AAAA;AAAA;AAAA;AAAA;AAMxC,IAAM,2BAAuB,yBAAAA,SAAO,4BAAI;AAAA;AAAA;AAIxC,IAAM,yBAAyB,yBAAAA,QAAO;AAAA;AAAA;AAAA,SAGpC,CAAC,UAAU,MAAM,MAAM,MAAM,GAAG,CAAC;AAAA;AAGnC,IAAM,oBAAoB,yBAAAA,QAAO;AAAA;AAAA;AAAA;AAAA;AAAA,MAKlC,CAAC,UAAU,MAAM,MAAM,OAAO,OAAO,UAAU,OAAO,IAAI;AAAA,mBAC7C,CAAC,UAAU,MAAM,MAAM,MAAM,KAAK;AAAA,aACxC,CAAC,UAAU,MAAM,MAAM,MAAM,GAAG,CAAC;AAAA;AAAA;AAIvC,IAAM,yBAAyB,yBAAAA,QAAO;AAAA,oBACzB,CAAC,UAAU,MAAM,MAAM,MAAM,GAAG,CAAC;AAAA,qBAChC,CAAC,UAAU,MAAM,MAAM,MAAM,GAAG,CAAC;AAAA,kBACpC,CAAC,UAAU,MAAM,MAAM,MAAM,GAAG,CAAC;AAAA,iBAClC,CAAC,UAAU,MAAM,MAAM,MAAM,GAAG,CAAC;AAAA,iBACjC,CAAC,UAAU,MAAM,MAAM,YAAY,QAAQ;AAAA,sBACtC,CAAC,UACnB,MAAM,aACF,MAAM,MAAM,OAAO,OAAO,UAAU,WAAW,SAC/C,aAAa;AAAA,WACV,CAAC,UACR,MAAM,aACF,MAAM,MAAM,OAAO,KAAK,UACxB,MAAM,MAAM,OAAO,KAAK,IAAI;AAAA;AAAA,mBAEjB,CAAC,UAAU,MAAM,MAAM,MAAM,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,aAOxC,CAAC,UACR,MAAM,aAAa,MAAM,MAAM,OAAO,KAAK,UAAU,MAAS;AAAA,wBAC5C,CAAC,UACnB,MAAM,aACF,MAAM,MAAM,OAAO,OAAO,UAAU,WAAW,SAC/C,MAAM,MAAM,OAAO,SAAS,WAAW,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA,eAKvC,CAAC,UAAW,MAAM,aAAa,IAAI,GAAI;AAAA;AAAA;;;ADsDhD;AAxGC,IAAM,aAAa,CAAC;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAAuB;AACrB,QAAM,EAAE,aAAa,iBAAiB,mBAAmB,IAAI;AAG7D,QAAM,aAAa,KAAK,KAAK,YAAY,QAAQ;AACjD,QAAM,cAAc,mBAAmB;AACvC,QAAM,WAAW,cAAc,IAAI,IAAI,mBAAmB,WAAW;AACrE,QAAM,SAAS,KAAK,KAAK,mBAAmB,KAAK,UAAU,SAAS;AAEpE,QAAM,gBAAgB,mBAAmB;AACzC,QAAM,YAAY,mBAAmB,aAAa;AAElD,QAAM,iBAAiB,MAAM;AAC3B,QAAI,eAAe;AACjB,mBAAa,mBAAmB,CAAC;AAAA,IACnC;AAAA,EACF;AAEA,QAAM,aAAa,MAAM;AACvB,QAAI,WAAW;AACb,mBAAa,mBAAmB,CAAC;AAAA,IACnC;AAAA,EACF;AAEA,QAAM,uBAAuB,CAAC,MAA+C;AAC3E,UAAM,cAAc,OAAO,EAAE,cAAc,KAAK;AAChD,qBAAiB,WAAW;AAE5B,iBAAa,CAAC;AAAA,EAChB;AAGA,QAAM,iBAAiB,MAAM;AAC3B,UAAM,QAA6B,CAAC;AACpC,UAAM,OAAO,iBAAiB,QAAQ;AAGtC,UAAM,iBAAiB,SAAS,SAAS,IAAI;AAC7C,UAAM,iBAAiB,SAAS,SAAS,IAAI;AAG7C,QAAI,cAAc,IAAI,iBAAiB,gBAAgB;AACrD,eAAS,IAAI,GAAG,KAAK,YAAY,KAAK;AACpC,cAAM,KAAK,CAAC;AAAA,MACd;AAAA,IACF,OAAO;AAEL,YAAM,KAAK,CAAC;AAGZ,UAAI,cAAc,IAAI,gBAAgB;AACpC,cAAM,KAAK,KAAK;AAAA,MAClB;AAGA,UAAI;AACJ,UAAI;AAGJ,UAAI,eAAe,IAAI,gBAAgB;AACrC,gBAAQ;AACR,cAAM,IAAI,iBAAiB;AAAA,MAC7B,WAAW,cAAc,cAAc,IAAI,iBAAiB;AAE1D,gBAAQ,cAAc,IAAI,iBAAiB;AAC3C,cAAM,aAAa;AAAA,MACrB,OAAO;AAEL,gBAAQ,cAAc;AACtB,cAAM,cAAc;AAAA,MACtB;AAEA,eAAS,IAAI,OAAO,KAAK,KAAK,KAAK;AACjC,cAAM,KAAK,CAAC;AAAA,MACd;AAGA,UAAI,cAAc,cAAc,IAAI,iBAAiB;AACnD,cAAM,KAAK,KAAK;AAAA,MAClB;AAGA,YAAM,KAAK,UAAU;AAAA,IACvB;AAEA,WAAO;AAAA,EACT;AAEA,QAAM,cAAc,eAAe;AAEnC,MAAI,cAAc,KAAK,CAAC,iBAAiB;AAEvC,WAAO;AAAA,EACT;AAEA,SACE,6CAAC,6BACC;AAAA,gDAAC,wBACE,6BAAmB;AAAA,MAClB,UAAU;AAAA,MACV,QAAQ;AAAA,MACR,eAAe;AAAA,IACjB,CAAC,GACH;AAAA,IAEC,mBAAmB,gBAAgB,cAClC,4CAAC,0BACC;AAAA,MAAC;AAAA;AAAA,QACC,IAAG;AAAA,QACH,MAAK;AAAA,QACL,OAAO,OAAO,QAAQ;AAAA,QACtB,UAAU;AAAA,QACV,WAAU;AAAA,QACV,MAAK;AAAA,QAEJ,0BAAgB,IAAI,CAAC,SACpB,6CAAC,YAAkB,OAAO,MACvB;AAAA;AAAA,UAAK;AAAA,aADK,IAEb,CACD;AAAA;AAAA,IACH,GACF;AAAA,IAMD,aAAa,KACZ,4CAAC,4BACC,uDAAC,qBACC;AAAA;AAAA,QAAC;AAAA;AAAA,UACC,SAAS;AAAA,UACT,UAAU,CAAC;AAAA,UACX,cAAW;AAAA,UAEX,sDAAC,gCAAK,MAAK,wBAAuB;AAAA;AAAA,MACpC;AAAA,MAEC,YAAY,IAAI,CAAC,SAAS,UAAU;AACnC,YAAI,YAAY,OAAO;AACrB,iBACE;AAAA,YAAC;AAAA;AAAA,cAEC,UAAQ;AAAA,cACR,cAAW;AAAA,cAEX,sDAAC,gCAAK,MAAK,+BAA8B;AAAA;AAAA,YAJpC,YAAY,KAAK;AAAA,UAKxB;AAAA,QAEJ;AAEA,cAAM,OAAO;AACb,cAAM,gBAAgB,SAAS;AAE/B,eACE;AAAA,UAAC;AAAA;AAAA,YAEC,SAAS,MAAM,aAAa,OAAO,CAAC;AAAA,YACpC,UAAU;AAAA,YACV,cAAY,QAAQ,IAAI;AAAA,YACxB,gBAAc,gBAAgB,SAAS;AAAA,YACvC,YAAY;AAAA,YAEX;AAAA;AAAA,UAPI;AAAA,QAQP;AAAA,MAEJ,CAAC;AAAA,MAED;AAAA,QAAC;AAAA;AAAA,UACC,SAAS;AAAA,UACT,UAAU,CAAC;AAAA,UACX,cAAW;AAAA,UAEX,sDAAC,gCAAK,MAAK,yBAAwB;AAAA;AAAA,MACrC;AAAA,OACF,GACF;AAAA,KAEJ;AAEJ;;;AEjNA,IAAAC,SAAuB;AAMvB,IAAM,6BAA6B,CAAC,IAAI,IAAI,IAAI,GAAG;AACnD,IAAM,4BAA4B,CAAC,GAAG,IAAI,EAAE;AAC5C,IAAM,0BAA0B,CAAC,IAAI,KAAK,KAAK,GAAG;AAE3C,IAAM,oBAAoB;AAAA,EAC/B,UAAU;AAAA,EACV,SAAS;AAAA,EACT,OAAO;AACT;","names":["styled","React"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/PaginationHybrid.tsx","../src/PaginationStyled.tsx","../src/usePaginationModel.ts","../src/styles.ts","../src/PaginationTailwind.tsx","../src/Pagination.tsx","../src/PaginationTypes.ts"],"sourcesContent":["export { Pagination } from \"./Pagination\";\nexport * from \"./PaginationTypes\";\n","/**\n * Hybrid Pagination component.\n * Routes between the Tailwind implementation (preferred) and the\n * styled-components implementation (for consumers using system props).\n */\n\nimport { hasStyledProps } from \"@sproutsocial/seeds-react-system-props\";\nimport { PaginationStyled } from \"./PaginationStyled\";\nimport { PaginationTailwind } from \"./PaginationTailwind\";\nimport type { PaginationProps } from \"./PaginationTypes\";\n\nexport const PaginationHybrid = (props: PaginationProps) => {\n // Pagination exposes domain props plus an optional className, none of which\n // are styled-system props, so hasStyledProps is effectively always false; the\n // styled-components branch is retained as a pattern-conformance fallback.\n if (hasStyledProps(props)) {\n return <PaginationStyled {...props} />;\n }\n return <PaginationTailwind {...props} />;\n};\n","/**\n * Styled-components implementation of the Pagination component.\n * Composes the styled sub-components from styles.ts. Retained for backward\n * compatibility (system props / styled() extension) via PaginationHybrid.\n */\n\nimport { Select } from \"@sproutsocial/seeds-react-select\";\nimport { Icon } from \"@sproutsocial/seeds-react-icon\";\nimport type { PaginationProps } from \"./PaginationTypes\";\nimport { usePaginationModel } from \"./usePaginationModel\";\nimport {\n StyledPaginationContainer,\n StyledPaginationControls,\n StyledPaginationInfo,\n StyledPageSizeSelector,\n StyledPageButtons,\n StyledPaginationButton,\n} from \"./styles\";\n\nexport const PaginationStyled = (props: PaginationProps) => {\n const { pageSize, totalRows, onPageChange, className } = props;\n const {\n displayType,\n pageSizeOptions,\n tableCountFunction,\n totalPages,\n currentPage,\n startRow,\n endRow,\n canGoPrevious,\n canGoNext,\n handlePrevious,\n handleNext,\n handlePageSizeChange,\n pageNumbers,\n } = usePaginationModel(props);\n\n if (totalPages <= 1 && !pageSizeOptions) {\n // No pagination needed if only one page and no page size options\n return null;\n }\n\n return (\n <StyledPaginationContainer className={className}>\n <StyledPaginationInfo>\n {tableCountFunction({\n startNum: startRow,\n endNum: endRow,\n totalRowCount: totalRows,\n })}\n </StyledPaginationInfo>\n {/* Page size selector */}\n {pageSizeOptions && displayType === \"dropdown\" && (\n <StyledPageSizeSelector>\n <Select\n id=\"page-size-select\"\n name=\"page-size\"\n value={String(pageSize)}\n onChange={handlePageSizeChange}\n ariaLabel=\"Rows per page\"\n size=\"small\"\n >\n {pageSizeOptions.map((size) => (\n <option key={size} value={size}>\n {size} per page\n </option>\n ))}\n </Select>\n </StyledPageSizeSelector>\n )}\n\n {/* TODO: Add inline page size selector for displayType === 'inline' */}\n\n {/* Page navigation controls */}\n {totalPages > 1 && (\n <StyledPaginationControls>\n <StyledPageButtons>\n <StyledPaginationButton\n onClick={handlePrevious}\n disabled={!canGoPrevious}\n aria-label=\"Previous page\"\n >\n <Icon name=\"chevron-left-outline\" />\n </StyledPaginationButton>\n\n {pageNumbers.map((pageNum, index) => {\n if (pageNum === \"...\") {\n return (\n <StyledPaginationButton\n key={`ellipsis-${index}`}\n disabled\n aria-label=\"More pages\"\n >\n <Icon name=\"ellipsis-horizontal-outline\" />\n </StyledPaginationButton>\n );\n }\n\n const page = pageNum as number;\n const isCurrentPage = page === currentPage;\n\n return (\n <StyledPaginationButton\n key={page}\n onClick={() => onPageChange(page - 1)}\n disabled={isCurrentPage}\n aria-label={`Page ${page}`}\n aria-current={isCurrentPage ? \"page\" : undefined}\n isSelected={isCurrentPage}\n >\n {page}\n </StyledPaginationButton>\n );\n })}\n\n <StyledPaginationButton\n onClick={handleNext}\n disabled={!canGoNext}\n aria-label=\"Next page\"\n >\n <Icon name=\"chevron-right-outline\" />\n </StyledPaginationButton>\n </StyledPageButtons>\n </StyledPaginationControls>\n )}\n </StyledPaginationContainer>\n );\n};\n","/**\n * Presentation-agnostic Pagination model: page math, the page-number token\n * list, and the event handlers consumed identically by PaginationTailwind and\n * PaginationStyled. Contains NO rendering — the JSX and the `return null` guard\n * stay in each component — so the two implementations cannot drift apart. Call\n * it unconditionally at the top of each component, before any early return.\n */\n\nimport * as React from \"react\";\nimport type { PaginationProps } from \"./PaginationTypes\";\n\nexport const usePaginationModel = ({\n paginationConfig,\n currentPageIndex,\n pageSize,\n totalRows,\n onPageChange,\n onPageSizeChange,\n}: PaginationProps) => {\n const { displayType, pageSizeOptions, tableCountFunction } = paginationConfig;\n\n // Calculate pagination values\n const totalPages = Math.ceil(totalRows / pageSize);\n const currentPage = currentPageIndex + 1; // Convert 0-based to 1-based for display\n const startRow = totalRows === 0 ? 0 : currentPageIndex * pageSize + 1;\n const endRow = Math.min((currentPageIndex + 1) * pageSize, totalRows);\n\n const canGoPrevious = currentPageIndex > 0;\n const canGoNext = currentPageIndex < totalPages - 1;\n\n const handlePrevious = () => {\n if (canGoPrevious) {\n onPageChange(currentPageIndex - 1);\n }\n };\n\n const handleNext = () => {\n if (canGoNext) {\n onPageChange(currentPageIndex + 1);\n }\n };\n\n const handlePageSizeChange = (e: React.SyntheticEvent<HTMLSelectElement>) => {\n const newPageSize = Number(e.currentTarget.value);\n onPageSizeChange(newPageSize);\n // Reset to first page when page size changes\n onPageChange(0);\n };\n\n // Generate page number buttons using web-app-core's algorithm\n const getPageNumbers = () => {\n const pages: (number | string)[] = [];\n const size = paginationConfig.size || \"default\";\n\n // Configuration for how many pages to show around current page\n const NUM_PAGE_LOWER = size === \"mini\" ? 0 : 1;\n const NUM_PAGE_UPPER = size === \"mini\" ? 0 : 2;\n\n // If number of pages is small enough, show all the page tokens without ellipsis\n if (totalPages <= 5 + NUM_PAGE_LOWER + NUM_PAGE_UPPER) {\n for (let i = 1; i <= totalPages; i++) {\n pages.push(i);\n }\n } else {\n // Add first page\n pages.push(1);\n\n // Add ellipsis at the beginning if needed\n if (currentPage > 3 + NUM_PAGE_LOWER) {\n pages.push(\"...\");\n }\n\n // Add pages in the middle\n let start: number;\n let end: number; // inclusive index\n\n // If near beginning - Show number of pages before ending ellipsis\n if (currentPage <= 3 + NUM_PAGE_LOWER) {\n start = 2;\n end = 3 + NUM_PAGE_LOWER + NUM_PAGE_UPPER;\n } else if (currentPage > totalPages - (3 + NUM_PAGE_UPPER)) {\n // If near end - Show number of pages after starting ellipsis\n start = totalPages - (2 + NUM_PAGE_LOWER + NUM_PAGE_UPPER);\n end = totalPages - 1;\n } else {\n // If in the middle - Show number of pages between two ellipses\n start = currentPage - NUM_PAGE_LOWER;\n end = currentPage + NUM_PAGE_UPPER;\n }\n\n for (let i = start; i <= end; i++) {\n pages.push(i);\n }\n\n // Add a final ellipsis if necessary\n if (currentPage < totalPages - (2 + NUM_PAGE_UPPER)) {\n pages.push(\"...\");\n }\n\n // Add the last page number\n pages.push(totalPages);\n }\n\n return pages;\n };\n\n const pageNumbers = getPageNumbers();\n\n return {\n displayType,\n pageSizeOptions,\n tableCountFunction,\n totalPages,\n currentPage,\n startRow,\n endRow,\n canGoPrevious,\n canGoNext,\n handlePrevious,\n handleNext,\n handlePageSizeChange,\n pageNumbers,\n };\n};\n","import styled from \"styled-components\";\nimport { Text } from \"@sproutsocial/seeds-react-text\";\n\n// Pagination Styles\nexport const StyledPaginationContainer = styled.div`\n ${(props) => props.theme.typography[200]}\n display: flex;\n align-items: center;\n gap: ${(props) => props.theme.space[300]};\n margin-top: ${(props) => props.theme.space[400]};\n flex-wrap: wrap;\n`;\n\nexport const StyledPaginationControls = styled.div`\n display: flex;\n align-items: center;\n margin-left: auto;\n`;\n\nexport const StyledPaginationInfo = styled(Text)`\n white-space: nowrap;\n`;\n\nexport const StyledPageSizeSelector = styled.div`\n display: flex;\n align-items: center;\n gap: ${(props) => props.theme.space[300]};\n`;\n\nexport const StyledPageButtons = styled.div`\n display: inline-flex;\n flex-flow: row wrap;\n background-clip: padding-box;\n border: 1px solid\n ${(props) => props.theme.colors.button.secondary.border.base};\n border-radius: ${(props) => props.theme.radii.outer};\n padding: ${(props) => props.theme.space[100]};\n background: transparent;\n`;\n\nexport const StyledPaginationButton = styled.button<{ isSelected?: boolean }>`\n min-width: calc(${(props) => props.theme.space[500]} + 4px);\n min-height: calc(${(props) => props.theme.space[500]} + 2px);\n padding: calc(${(props) => props.theme.space[350]} - 6px);\n line-height: ${(props) => props.theme.space[400]};\n font-weight: ${(props) => props.theme.fontWeights.semibold};\n background-color: ${(props) =>\n props.isSelected\n ? props.theme.colors.button.secondary.background.active\n : \"transparent\"};\n color: ${(props) =>\n props.isSelected\n ? props.theme.colors.text.inverse\n : props.theme.colors.text.body};\n border: none;\n border-radius: ${(props) => props.theme.radii.inner};\n cursor: pointer;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n\n &:hover:not(:disabled) {\n color: ${(props) =>\n props.isSelected ? props.theme.colors.text.inverse : undefined};\n background-color: ${(props) =>\n props.isSelected\n ? props.theme.colors.button.secondary.background.active\n : props.theme.colors.listItem.background.hover};\n }\n\n &:disabled {\n cursor: default;\n opacity: ${(props) => (props.isSelected ? 1 : 0.5)};\n }\n`;\n","/**\n * Tailwind/CSS implementation of the Pagination component.\n * Uses Seeds pagination CSS classes from pagination.css.\n */\n\nimport { Select } from \"@sproutsocial/seeds-react-select\";\nimport { Icon } from \"@sproutsocial/seeds-react-icon\";\nimport { Text } from \"@sproutsocial/seeds-react-text\";\nimport type { PaginationProps } from \"./PaginationTypes\";\nimport { usePaginationModel } from \"./usePaginationModel\";\n\n// Utility for merging class names properly\nfunction cn(\n ...inputs: (string | undefined | null | false | Record<string, boolean>)[]\n): string {\n const classes: string[] = [];\n\n for (const input of inputs) {\n if (!input) continue;\n\n if (typeof input === \"string\") {\n classes.push(input);\n } else if (typeof input === \"object\") {\n for (const [key, value] of Object.entries(input)) {\n if (value) {\n classes.push(key);\n }\n }\n }\n }\n\n return classes.join(\" \");\n}\n\nexport const PaginationTailwind = (props: PaginationProps) => {\n const { pageSize, totalRows, onPageChange, className } = props;\n const {\n displayType,\n pageSizeOptions,\n tableCountFunction,\n totalPages,\n currentPage,\n startRow,\n endRow,\n canGoPrevious,\n canGoNext,\n handlePrevious,\n handleNext,\n handlePageSizeChange,\n pageNumbers,\n } = usePaginationModel(props);\n\n if (totalPages <= 1 && !pageSizeOptions) {\n // No pagination needed if only one page and no page size options\n return null;\n }\n\n return (\n <div className={cn(\"seeds-pagination-container\", className)}>\n <Text className={cn(\"seeds-pagination-info\")}>\n {tableCountFunction({\n startNum: startRow,\n endNum: endRow,\n totalRowCount: totalRows,\n })}\n </Text>\n {/* Page size selector */}\n {pageSizeOptions && displayType === \"dropdown\" && (\n <div className={cn(\"seeds-pagination-page-size-selector\")}>\n <Select\n id=\"page-size-select\"\n name=\"page-size\"\n value={String(pageSize)}\n onChange={handlePageSizeChange}\n ariaLabel=\"Rows per page\"\n size=\"small\"\n >\n {pageSizeOptions.map((size) => (\n <option key={size} value={size}>\n {size} per page\n </option>\n ))}\n </Select>\n </div>\n )}\n\n {/* TODO: Add inline page size selector for displayType === 'inline' */}\n\n {/* Page navigation controls */}\n {totalPages > 1 && (\n <div className={cn(\"seeds-pagination-controls\")}>\n <div className={cn(\"seeds-pagination-page-buttons\")}>\n <button\n type=\"button\"\n className={cn(\"seeds-pagination-button\")}\n onClick={handlePrevious}\n disabled={!canGoPrevious}\n aria-label=\"Previous page\"\n >\n <Icon name=\"chevron-left-outline\" />\n </button>\n\n {pageNumbers.map((pageNum, index) => {\n if (pageNum === \"...\") {\n return (\n <button\n type=\"button\"\n key={`ellipsis-${index}`}\n className={cn(\"seeds-pagination-button\")}\n disabled\n aria-label=\"More pages\"\n >\n <Icon name=\"ellipsis-horizontal-outline\" />\n </button>\n );\n }\n\n const page = pageNum as number;\n const isCurrentPage = page === currentPage;\n\n return (\n <button\n type=\"button\"\n key={page}\n className={cn(\"seeds-pagination-button\", {\n \"seeds-pagination-button-selected\": isCurrentPage,\n })}\n onClick={() => onPageChange(page - 1)}\n disabled={isCurrentPage}\n aria-label={`Page ${page}`}\n aria-current={isCurrentPage ? \"page\" : undefined}\n >\n {page}\n </button>\n );\n })}\n\n <button\n type=\"button\"\n className={cn(\"seeds-pagination-button\")}\n onClick={handleNext}\n disabled={!canGoNext}\n aria-label=\"Next page\"\n >\n <Icon name=\"chevron-right-outline\" />\n </button>\n </div>\n </div>\n )}\n </div>\n );\n};\n","import { PaginationHybrid } from \"./PaginationHybrid\";\nimport type { PaginationProps } from \"./PaginationTypes\";\n\n/**\n * Pagination component. Automatically routes between the Tailwind implementation\n * (preferred) and the styled-components implementation (for consumers using\n * system props or styled() extension).\n *\n * Defined as a self-named component (rather than a bare re-export of\n * PaginationHybrid) so the `react-docgen` props-docs generation in the Publish\n * pipeline has a suitable component definition to analyze.\n */\nexport const Pagination = (props: PaginationProps) => (\n <PaginationHybrid {...props} />\n);\n\nPagination.displayName = \"Pagination\";\n","import * as React from \"react\";\n\n/**\n * Standard page size option sets for pagination.\n * Export these constants to maintain consistency across tables.\n */\nconst PAGE_SIZE_OPTIONS_STANDARD = [10, 25, 50, 100] as const;\nconst PAGE_SIZE_OPTIONS_COMPACT = [5, 10, 20] as const;\nconst PAGE_SIZE_OPTIONS_LARGE = [50, 100, 200, 500] as const;\n\nexport const PAGE_SIZE_OPTIONS = {\n STANDARD: PAGE_SIZE_OPTIONS_STANDARD,\n COMPACT: PAGE_SIZE_OPTIONS_COMPACT,\n LARGE: PAGE_SIZE_OPTIONS_LARGE,\n};\n\n/**\n * Allowed page size option sets.\n * Use one of the predefined PAGE_SIZE_OPTIONS for consistency.\n */\nexport type TypeAllowedPageSizeOptions =\n | typeof PAGE_SIZE_OPTIONS_STANDARD\n | typeof PAGE_SIZE_OPTIONS_COMPACT\n | typeof PAGE_SIZE_OPTIONS_LARGE;\n\n/**\n * Configuration for pagination controls with page navigation and size selection.\n *\n * @example\n * ```tsx\n * <Pagination\n * paginationConfig={{\n * initialPageSize: 25,\n * displayType: 'dropdown',\n * pageSizeOptions: PAGE_SIZE_OPTIONS.STANDARD,\n * tableCountFunction: ({ startNum, endNum, totalRowCount }) =>\n * `${startNum}-${endNum} of ${totalRowCount}`\n * }}\n * currentPageIndex={0}\n * pageSize={25}\n * totalRows={100}\n * onPageChange={(index) => console.log('Page:', index)}\n * onPageSizeChange={(size) => console.log('Page size:', size)}\n * />\n * ```\n */\n/**\n * Props for the Pagination component.\n */\nexport interface PaginationProps {\n paginationConfig: TypePaginationConfig;\n currentPageIndex: number;\n pageSize: number;\n totalRows: number;\n onPageChange: (pageIndex: number) => void;\n onPageSizeChange: (pageSize: number) => void;\n /**\n * Optional class name applied to the root container. Lets consumers layer\n * Tailwind utility overrides (e.g. `mx-200`, `p-300`) on top of the component\n * styles. Because `className` is not a styled-system prop, providing it keeps\n * the component on the Tailwind rendering path.\n */\n className?: string;\n}\n\nexport interface TypePaginationConfig {\n /**\n * Initial number of rows per page.\n * @default 10\n */\n initialPageSize: number;\n /**\n * Function that returns the intl for displaying the table counts underneath a DataTable\n */\n tableCountFunction: (args: {\n startNum: number;\n endNum: number;\n totalRowCount: number;\n }) => React.ReactNode;\n /**\n * Display mode for page size selector.\n * - 'dropdown': Shows page size selector as a dropdown\n * Only used when pageSizeOptions is provided.\n * @default 'dropdown'\n */\n displayType?: \"dropdown\";\n /**\n * Optional array of page size options for the selector.\n * If not provided, page size selection will not be available.\n * Use PAGE_SIZE_OPTIONS constants for consistency.\n *\n * @example\n * pageSizeOptions: PAGE_SIZE_OPTIONS.STANDARD // [10, 25, 50, 100]\n */\n pageSizeOptions?: TypeAllowedPageSizeOptions;\n /**\n * Size variant for page number display.\n * - 'default': Shows current page ±1-2 pages (more visible pages)\n * - 'mini': Shows only current page (fewer visible pages)\n * @default 'default'\n */\n size?: \"default\" | \"mini\";\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACMA,sCAA+B;;;ACA/B,gCAAuB;AACvB,8BAAqB;;;ACCrB,YAAuB;AAGhB,IAAM,qBAAqB,CAAC;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAAuB;AACrB,QAAM,EAAE,aAAa,iBAAiB,mBAAmB,IAAI;AAG7D,QAAM,aAAa,KAAK,KAAK,YAAY,QAAQ;AACjD,QAAM,cAAc,mBAAmB;AACvC,QAAM,WAAW,cAAc,IAAI,IAAI,mBAAmB,WAAW;AACrE,QAAM,SAAS,KAAK,KAAK,mBAAmB,KAAK,UAAU,SAAS;AAEpE,QAAM,gBAAgB,mBAAmB;AACzC,QAAM,YAAY,mBAAmB,aAAa;AAElD,QAAM,iBAAiB,MAAM;AAC3B,QAAI,eAAe;AACjB,mBAAa,mBAAmB,CAAC;AAAA,IACnC;AAAA,EACF;AAEA,QAAM,aAAa,MAAM;AACvB,QAAI,WAAW;AACb,mBAAa,mBAAmB,CAAC;AAAA,IACnC;AAAA,EACF;AAEA,QAAM,uBAAuB,CAAC,MAA+C;AAC3E,UAAM,cAAc,OAAO,EAAE,cAAc,KAAK;AAChD,qBAAiB,WAAW;AAE5B,iBAAa,CAAC;AAAA,EAChB;AAGA,QAAM,iBAAiB,MAAM;AAC3B,UAAM,QAA6B,CAAC;AACpC,UAAM,OAAO,iBAAiB,QAAQ;AAGtC,UAAM,iBAAiB,SAAS,SAAS,IAAI;AAC7C,UAAM,iBAAiB,SAAS,SAAS,IAAI;AAG7C,QAAI,cAAc,IAAI,iBAAiB,gBAAgB;AACrD,eAAS,IAAI,GAAG,KAAK,YAAY,KAAK;AACpC,cAAM,KAAK,CAAC;AAAA,MACd;AAAA,IACF,OAAO;AAEL,YAAM,KAAK,CAAC;AAGZ,UAAI,cAAc,IAAI,gBAAgB;AACpC,cAAM,KAAK,KAAK;AAAA,MAClB;AAGA,UAAI;AACJ,UAAI;AAGJ,UAAI,eAAe,IAAI,gBAAgB;AACrC,gBAAQ;AACR,cAAM,IAAI,iBAAiB;AAAA,MAC7B,WAAW,cAAc,cAAc,IAAI,iBAAiB;AAE1D,gBAAQ,cAAc,IAAI,iBAAiB;AAC3C,cAAM,aAAa;AAAA,MACrB,OAAO;AAEL,gBAAQ,cAAc;AACtB,cAAM,cAAc;AAAA,MACtB;AAEA,eAAS,IAAI,OAAO,KAAK,KAAK,KAAK;AACjC,cAAM,KAAK,CAAC;AAAA,MACd;AAGA,UAAI,cAAc,cAAc,IAAI,iBAAiB;AACnD,cAAM,KAAK,KAAK;AAAA,MAClB;AAGA,YAAM,KAAK,UAAU;AAAA,IACvB;AAEA,WAAO;AAAA,EACT;AAEA,QAAM,cAAc,eAAe;AAEnC,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;;;AC3HA,+BAAmB;AACnB,8BAAqB;AAGd,IAAM,4BAA4B,yBAAAA,QAAO;AAAA,IAC5C,CAAC,UAAU,MAAM,MAAM,WAAW,GAAG,CAAC;AAAA;AAAA;AAAA,SAGjC,CAAC,UAAU,MAAM,MAAM,MAAM,GAAG,CAAC;AAAA,gBAC1B,CAAC,UAAU,MAAM,MAAM,MAAM,GAAG,CAAC;AAAA;AAAA;AAI1C,IAAM,2BAA2B,yBAAAA,QAAO;AAAA;AAAA;AAAA;AAAA;AAMxC,IAAM,2BAAuB,yBAAAA,SAAO,4BAAI;AAAA;AAAA;AAIxC,IAAM,yBAAyB,yBAAAA,QAAO;AAAA;AAAA;AAAA,SAGpC,CAAC,UAAU,MAAM,MAAM,MAAM,GAAG,CAAC;AAAA;AAGnC,IAAM,oBAAoB,yBAAAA,QAAO;AAAA;AAAA;AAAA;AAAA;AAAA,MAKlC,CAAC,UAAU,MAAM,MAAM,OAAO,OAAO,UAAU,OAAO,IAAI;AAAA,mBAC7C,CAAC,UAAU,MAAM,MAAM,MAAM,KAAK;AAAA,aACxC,CAAC,UAAU,MAAM,MAAM,MAAM,GAAG,CAAC;AAAA;AAAA;AAIvC,IAAM,yBAAyB,yBAAAA,QAAO;AAAA,oBACzB,CAAC,UAAU,MAAM,MAAM,MAAM,GAAG,CAAC;AAAA,qBAChC,CAAC,UAAU,MAAM,MAAM,MAAM,GAAG,CAAC;AAAA,kBACpC,CAAC,UAAU,MAAM,MAAM,MAAM,GAAG,CAAC;AAAA,iBAClC,CAAC,UAAU,MAAM,MAAM,MAAM,GAAG,CAAC;AAAA,iBACjC,CAAC,UAAU,MAAM,MAAM,YAAY,QAAQ;AAAA,sBACtC,CAAC,UACnB,MAAM,aACF,MAAM,MAAM,OAAO,OAAO,UAAU,WAAW,SAC/C,aAAa;AAAA,WACV,CAAC,UACR,MAAM,aACF,MAAM,MAAM,OAAO,KAAK,UACxB,MAAM,MAAM,OAAO,KAAK,IAAI;AAAA;AAAA,mBAEjB,CAAC,UAAU,MAAM,MAAM,MAAM,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,aAOxC,CAAC,UACR,MAAM,aAAa,MAAM,MAAM,OAAO,KAAK,UAAU,MAAS;AAAA,wBAC5C,CAAC,UACnB,MAAM,aACF,MAAM,MAAM,OAAO,OAAO,UAAU,WAAW,SAC/C,MAAM,MAAM,OAAO,SAAS,WAAW,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA,eAKvC,CAAC,UAAW,MAAM,aAAa,IAAI,GAAI;AAAA;AAAA;;;AF5BhD;AAzBC,IAAM,mBAAmB,CAAC,UAA2B;AAC1D,QAAM,EAAE,UAAU,WAAW,cAAc,UAAU,IAAI;AACzD,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI,mBAAmB,KAAK;AAE5B,MAAI,cAAc,KAAK,CAAC,iBAAiB;AAEvC,WAAO;AAAA,EACT;AAEA,SACE,6CAAC,6BAA0B,WACzB;AAAA,gDAAC,wBACE,6BAAmB;AAAA,MAClB,UAAU;AAAA,MACV,QAAQ;AAAA,MACR,eAAe;AAAA,IACjB,CAAC,GACH;AAAA,IAEC,mBAAmB,gBAAgB,cAClC,4CAAC,0BACC;AAAA,MAAC;AAAA;AAAA,QACC,IAAG;AAAA,QACH,MAAK;AAAA,QACL,OAAO,OAAO,QAAQ;AAAA,QACtB,UAAU;AAAA,QACV,WAAU;AAAA,QACV,MAAK;AAAA,QAEJ,0BAAgB,IAAI,CAAC,SACpB,6CAAC,YAAkB,OAAO,MACvB;AAAA;AAAA,UAAK;AAAA,aADK,IAEb,CACD;AAAA;AAAA,IACH,GACF;AAAA,IAMD,aAAa,KACZ,4CAAC,4BACC,uDAAC,qBACC;AAAA;AAAA,QAAC;AAAA;AAAA,UACC,SAAS;AAAA,UACT,UAAU,CAAC;AAAA,UACX,cAAW;AAAA,UAEX,sDAAC,gCAAK,MAAK,wBAAuB;AAAA;AAAA,MACpC;AAAA,MAEC,YAAY,IAAI,CAAC,SAAS,UAAU;AACnC,YAAI,YAAY,OAAO;AACrB,iBACE;AAAA,YAAC;AAAA;AAAA,cAEC,UAAQ;AAAA,cACR,cAAW;AAAA,cAEX,sDAAC,gCAAK,MAAK,+BAA8B;AAAA;AAAA,YAJpC,YAAY,KAAK;AAAA,UAKxB;AAAA,QAEJ;AAEA,cAAM,OAAO;AACb,cAAM,gBAAgB,SAAS;AAE/B,eACE;AAAA,UAAC;AAAA;AAAA,YAEC,SAAS,MAAM,aAAa,OAAO,CAAC;AAAA,YACpC,UAAU;AAAA,YACV,cAAY,QAAQ,IAAI;AAAA,YACxB,gBAAc,gBAAgB,SAAS;AAAA,YACvC,YAAY;AAAA,YAEX;AAAA;AAAA,UAPI;AAAA,QAQP;AAAA,MAEJ,CAAC;AAAA,MAED;AAAA,QAAC;AAAA;AAAA,UACC,SAAS;AAAA,UACT,UAAU,CAAC;AAAA,UACX,cAAW;AAAA,UAEX,sDAAC,gCAAK,MAAK,yBAAwB;AAAA;AAAA,MACrC;AAAA,OACF,GACF;AAAA,KAEJ;AAEJ;;;AG1HA,IAAAC,6BAAuB;AACvB,IAAAC,2BAAqB;AACrB,IAAAC,2BAAqB;AAoDf,IAAAC,sBAAA;AA/CN,SAAS,MACJ,QACK;AACR,QAAM,UAAoB,CAAC;AAE3B,aAAW,SAAS,QAAQ;AAC1B,QAAI,CAAC,MAAO;AAEZ,QAAI,OAAO,UAAU,UAAU;AAC7B,cAAQ,KAAK,KAAK;AAAA,IACpB,WAAW,OAAO,UAAU,UAAU;AACpC,iBAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,KAAK,GAAG;AAChD,YAAI,OAAO;AACT,kBAAQ,KAAK,GAAG;AAAA,QAClB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO,QAAQ,KAAK,GAAG;AACzB;AAEO,IAAM,qBAAqB,CAAC,UAA2B;AAC5D,QAAM,EAAE,UAAU,WAAW,cAAc,UAAU,IAAI;AACzD,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI,mBAAmB,KAAK;AAE5B,MAAI,cAAc,KAAK,CAAC,iBAAiB;AAEvC,WAAO;AAAA,EACT;AAEA,SACE,8CAAC,SAAI,WAAW,GAAG,8BAA8B,SAAS,GACxD;AAAA,iDAAC,iCAAK,WAAW,GAAG,uBAAuB,GACxC,6BAAmB;AAAA,MAClB,UAAU;AAAA,MACV,QAAQ;AAAA,MACR,eAAe;AAAA,IACjB,CAAC,GACH;AAAA,IAEC,mBAAmB,gBAAgB,cAClC,6CAAC,SAAI,WAAW,GAAG,qCAAqC,GACtD;AAAA,MAAC;AAAA;AAAA,QACC,IAAG;AAAA,QACH,MAAK;AAAA,QACL,OAAO,OAAO,QAAQ;AAAA,QACtB,UAAU;AAAA,QACV,WAAU;AAAA,QACV,MAAK;AAAA,QAEJ,0BAAgB,IAAI,CAAC,SACpB,8CAAC,YAAkB,OAAO,MACvB;AAAA;AAAA,UAAK;AAAA,aADK,IAEb,CACD;AAAA;AAAA,IACH,GACF;AAAA,IAMD,aAAa,KACZ,6CAAC,SAAI,WAAW,GAAG,2BAA2B,GAC5C,wDAAC,SAAI,WAAW,GAAG,+BAA+B,GAChD;AAAA;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,WAAW,GAAG,yBAAyB;AAAA,UACvC,SAAS;AAAA,UACT,UAAU,CAAC;AAAA,UACX,cAAW;AAAA,UAEX,uDAAC,iCAAK,MAAK,wBAAuB;AAAA;AAAA,MACpC;AAAA,MAEC,YAAY,IAAI,CAAC,SAAS,UAAU;AACnC,YAAI,YAAY,OAAO;AACrB,iBACE;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cAEL,WAAW,GAAG,yBAAyB;AAAA,cACvC,UAAQ;AAAA,cACR,cAAW;AAAA,cAEX,uDAAC,iCAAK,MAAK,+BAA8B;AAAA;AAAA,YALpC,YAAY,KAAK;AAAA,UAMxB;AAAA,QAEJ;AAEA,cAAM,OAAO;AACb,cAAM,gBAAgB,SAAS;AAE/B,eACE;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YAEL,WAAW,GAAG,2BAA2B;AAAA,cACvC,oCAAoC;AAAA,YACtC,CAAC;AAAA,YACD,SAAS,MAAM,aAAa,OAAO,CAAC;AAAA,YACpC,UAAU;AAAA,YACV,cAAY,QAAQ,IAAI;AAAA,YACxB,gBAAc,gBAAgB,SAAS;AAAA,YAEtC;AAAA;AAAA,UATI;AAAA,QAUP;AAAA,MAEJ,CAAC;AAAA,MAED;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,WAAW,GAAG,yBAAyB;AAAA,UACvC,SAAS;AAAA,UACT,UAAU,CAAC;AAAA,UACX,cAAW;AAAA,UAEX,uDAAC,iCAAK,MAAK,yBAAwB;AAAA;AAAA,MACrC;AAAA,OACF,GACF;AAAA,KAEJ;AAEJ;;;AJvIW,IAAAC,sBAAA;AALJ,IAAM,mBAAmB,CAAC,UAA2B;AAI1D,UAAI,gDAAe,KAAK,GAAG;AACzB,WAAO,6CAAC,oBAAkB,GAAG,OAAO;AAAA,EACtC;AACA,SAAO,6CAAC,sBAAoB,GAAG,OAAO;AACxC;;;AKNE,IAAAC,sBAAA;AADK,IAAM,aAAa,CAAC,UACzB,6CAAC,oBAAkB,GAAG,OAAO;AAG/B,WAAW,cAAc;;;AChBzB,IAAAC,SAAuB;AAMvB,IAAM,6BAA6B,CAAC,IAAI,IAAI,IAAI,GAAG;AACnD,IAAM,4BAA4B,CAAC,GAAG,IAAI,EAAE;AAC5C,IAAM,0BAA0B,CAAC,IAAI,KAAK,KAAK,GAAG;AAE3C,IAAM,oBAAoB;AAAA,EAC/B,UAAU;AAAA,EACV,SAAS;AAAA,EACT,OAAO;AACT;","names":["styled","import_seeds_react_select","import_seeds_react_icon","import_seeds_react_text","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","React"]}
@@ -0,0 +1,99 @@
1
+ /**
2
+ * Seeds Pagination component classes
3
+ * Use these instead of writing out individual Tailwind utility classes.
4
+ *
5
+ * Requires @sproutsocial/seeds-react-theme/dist/theme-all.css imported for
6
+ * CSS variable definitions and dark mode support.
7
+ *
8
+ * Rules are wrapped in @layer components so consumer Tailwind utilities (which
9
+ * live in @layer utilities) win the cascade. Without this layer the unlayered
10
+ * component CSS would beat utilities like mx-200 / p-300 / inline-flex and they
11
+ * could not override component styling. Keep every rule inside this single block
12
+ * in source order — the -selected modifier and the :disabled overrides resolve
13
+ * by source order within the same layer.
14
+ */
15
+
16
+ @layer components {
17
+ /* StyledPaginationContainer */
18
+ .seeds-pagination-container {
19
+ font-size: var(--font-size-200);
20
+ line-height: var(--line-height-200);
21
+ display: flex;
22
+ align-items: center;
23
+ gap: var(--space-300);
24
+ margin-top: var(--space-400);
25
+ flex-wrap: wrap;
26
+ }
27
+
28
+ /* StyledPaginationInfo (styled(Text)) */
29
+ .seeds-pagination-info {
30
+ white-space: nowrap;
31
+ }
32
+
33
+ /* StyledPageSizeSelector */
34
+ .seeds-pagination-page-size-selector {
35
+ display: flex;
36
+ align-items: center;
37
+ gap: var(--space-300);
38
+ }
39
+
40
+ /* StyledPaginationControls */
41
+ .seeds-pagination-controls {
42
+ display: flex;
43
+ align-items: center;
44
+ margin-left: auto;
45
+ }
46
+
47
+ /* StyledPageButtons */
48
+ .seeds-pagination-page-buttons {
49
+ display: inline-flex;
50
+ flex-flow: row wrap;
51
+ background-clip: padding-box;
52
+ border: 1px solid var(--color-button-secondary-border-base);
53
+ border-radius: var(--radius-outer);
54
+ padding: var(--space-100);
55
+ background: transparent;
56
+ }
57
+
58
+ /* StyledPaginationButton — base */
59
+ .seeds-pagination-button {
60
+ min-width: calc(var(--space-500) + 4px);
61
+ min-height: calc(var(--space-500) + 2px);
62
+ padding: calc(var(--space-350) - 6px);
63
+ line-height: var(--space-400);
64
+ font-weight: var(--font-weight-semibold);
65
+ background-color: transparent;
66
+ color: var(--color-text-body);
67
+ border: none;
68
+ border-radius: var(--radius-inner);
69
+ cursor: pointer;
70
+ display: inline-flex;
71
+ align-items: center;
72
+ justify-content: center;
73
+ }
74
+
75
+ /* selected modifier MUST follow base (equal specificity — source order wins) */
76
+ .seeds-pagination-button-selected {
77
+ background-color: var(--color-button-secondary-bg-active);
78
+ color: var(--color-text-inverse);
79
+ }
80
+
81
+ .seeds-pagination-button:hover:not(:disabled) {
82
+ background-color: var(--color-listItem-bg-hover);
83
+ }
84
+
85
+ .seeds-pagination-button-selected:hover:not(:disabled) {
86
+ background-color: var(--color-button-secondary-bg-active);
87
+ color: var(--color-text-inverse);
88
+ }
89
+
90
+ .seeds-pagination-button:disabled {
91
+ cursor: default;
92
+ opacity: 0.5;
93
+ }
94
+
95
+ /* current page renders disabled + selected and must stay fully opaque */
96
+ .seeds-pagination-button-selected:disabled {
97
+ opacity: 1;
98
+ }
99
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sproutsocial/seeds-react-pagination",
3
- "version": "0.1.28",
3
+ "version": "0.1.31",
4
4
  "description": "Seeds React Pagination",
5
5
  "author": "Sprout Social, Inc.",
6
6
  "license": "MIT",
@@ -12,11 +12,12 @@
12
12
  "types": "./dist/index.d.ts",
13
13
  "import": "./dist/esm/index.js",
14
14
  "require": "./dist/index.js"
15
- }
15
+ },
16
+ "./dist/pagination.css": "./dist/pagination.css"
16
17
  },
17
18
  "scripts": {
18
- "build": "tsup --dts",
19
- "build:debug": "tsup --dts --metafile",
19
+ "build": "tsup --dts && cp src/pagination.css dist/pagination.css",
20
+ "build:debug": "tsup --dts --metafile && cp src/pagination.css dist/pagination.css",
20
21
  "dev": "tsup --watch --dts",
21
22
  "clean": "rm -rf .turbo dist",
22
23
  "clean:modules": "rm -rf node_modules",
@@ -25,11 +26,11 @@
25
26
  "test:watch": "jest --watch --coverage=false"
26
27
  },
27
28
  "dependencies": {
28
- "@sproutsocial/seeds-react-theme": "^4.3.1",
29
- "@sproutsocial/seeds-react-system-props": "^3.1.3",
30
- "@sproutsocial/seeds-react-icon": "^2.4.7",
31
- "@sproutsocial/seeds-react-select": "^1.1.48",
32
- "@sproutsocial/seeds-react-text": "^1.5.2"
29
+ "@sproutsocial/seeds-react-theme": "^4.4.0",
30
+ "@sproutsocial/seeds-react-system-props": "^3.2.0",
31
+ "@sproutsocial/seeds-react-icon": "^2.5.0",
32
+ "@sproutsocial/seeds-react-select": "^1.1.51",
33
+ "@sproutsocial/seeds-react-text": "^1.5.4"
33
34
  },
34
35
  "devDependencies": {
35
36
  "@types/react": "^18.0.0",
@@ -0,0 +1,6 @@
1
+ // Empty PostCSS config — prevents tsup from picking up the root postcss.config.js
2
+ // (which runs Tailwind CSS and would fail without a tailwind.config.js in scope).
3
+ // pagination.css uses plain CSS custom properties and needs no PostCSS processing.
4
+ export default {
5
+ plugins: {},
6
+ };
@@ -0,0 +1,58 @@
1
+ import type { Meta, StoryObj } from "@storybook/react";
2
+ import { Pagination } from "./Pagination";
3
+ import { PAGE_SIZE_OPTIONS } from "./PaginationTypes";
4
+
5
+ const meta = {
6
+ title: "Components/Pagination",
7
+ component: Pagination,
8
+ } satisfies Meta<typeof Pagination>;
9
+
10
+ export default meta;
11
+ type Story = StoryObj<typeof Pagination>;
12
+
13
+ const paginationConfig = {
14
+ initialPageSize: 10,
15
+ tableCountFunction: ({
16
+ startNum,
17
+ endNum,
18
+ totalRowCount,
19
+ }: {
20
+ startNum: number;
21
+ endNum: number;
22
+ totalRowCount: number;
23
+ }) => `${startNum}-${endNum} of ${totalRowCount}`,
24
+ pageSizeOptions: PAGE_SIZE_OPTIONS.STANDARD,
25
+ };
26
+
27
+ export const defaultStory: Story = {
28
+ name: "Default",
29
+ args: {
30
+ paginationConfig,
31
+ currentPageIndex: 0,
32
+ pageSize: 10,
33
+ totalRows: 100,
34
+ onPageChange: () => {},
35
+ onPageSizeChange: () => {},
36
+ },
37
+ };
38
+
39
+ /**
40
+ * Demonstrates that consumer Tailwind utility classes override the component's
41
+ * own styling. `className="mx-200 p-300 inline-flex"` is forwarded to the root
42
+ * container and wins the cascade only because the component CSS is wrapped in
43
+ * `@layer components` (consumer utilities live in `@layer utilities`, which has
44
+ * higher priority). Because `className` is not a styled-system prop, the
45
+ * component stays on the Tailwind rendering path.
46
+ */
47
+ export const tailwindOverride: Story = {
48
+ name: "🚀 Tailwind class override (NEW!)",
49
+ args: {
50
+ paginationConfig,
51
+ currentPageIndex: 0,
52
+ pageSize: 10,
53
+ totalRows: 100,
54
+ className: "mx-200 p-300 inline-flex",
55
+ onPageChange: () => {},
56
+ onPageSizeChange: () => {},
57
+ },
58
+ };