react-lookup-select 1.0.2 → 1.0.4

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.d.cts CHANGED
@@ -71,6 +71,21 @@ type ValueMapper<T> = {
71
71
  /** Optional: disable check */
72
72
  getDisabled?: (row: T) => boolean;
73
73
  };
74
+ /**
75
+ * Virtualization configuration
76
+ */
77
+ type VirtualizationConfig = {
78
+ /** Is virtualization active? */
79
+ enabled: boolean;
80
+ /** Fixed row height (px) */
81
+ rowHeight: number;
82
+ /** Number of extra rows to render outside visible area */
83
+ overscan: number;
84
+ /** Container height (px) */
85
+ containerHeight: number;
86
+ /** Virtualization threshold - activates with more items than this number */
87
+ threshold: number;
88
+ };
74
89
  /**
75
90
  * Return value shape
76
91
  */
@@ -134,6 +149,130 @@ type i18nStrings = {
134
149
  /** Clear filters - "Clear filters" */
135
150
  clearFilters?: string;
136
151
  };
152
+ /**
153
+ * Render Props Interfaces - for custom rendering functions
154
+ */
155
+ type ModalRenderProps<T> = {
156
+ /** Is modal open? */
157
+ isOpen: boolean;
158
+ /** Close modal callback */
159
+ onClose: () => void;
160
+ /** Modal content */
161
+ children: ReactNode;
162
+ /** Modal title */
163
+ title?: string;
164
+ /** Loading state */
165
+ loading?: boolean;
166
+ /** Error message */
167
+ error?: string | null;
168
+ /** Current query state */
169
+ query?: QueryState;
170
+ /** Selected items count */
171
+ selectedCount: number;
172
+ /** Total items count */
173
+ totalCount: number;
174
+ };
175
+ type GridRenderProps<T> = {
176
+ /** Grid data */
177
+ data: T[];
178
+ /** Column definitions */
179
+ columns: ColumnDef<T>[];
180
+ /** Selected row IDs */
181
+ selectedIds: (string | number)[];
182
+ /** Row selection callback */
183
+ onRowSelect: (row: T) => void;
184
+ /** Select all callback */
185
+ onSelectAll?: () => void;
186
+ /** Clear all selections callback */
187
+ onClearAll?: () => void;
188
+ /** Loading state */
189
+ loading?: boolean;
190
+ /** Error state */
191
+ error?: string | null;
192
+ /** Selection mode */
193
+ mode: SelectMode;
194
+ /** Value mapper */
195
+ mapper: ValueMapper<T>;
196
+ /** Virtualization config */
197
+ virtualization?: VirtualizationConfig;
198
+ /** Row selectability checker */
199
+ selectableRow?: (row: T) => boolean;
200
+ /** Sort change callback */
201
+ onSortChange?: (sortBy: string, sortDir: 'asc' | 'desc') => void;
202
+ /** Current sort state */
203
+ sortBy?: string;
204
+ sortDir?: 'asc' | 'desc';
205
+ };
206
+ type HeaderRenderProps<T> = {
207
+ /** Current search value */
208
+ searchValue: string;
209
+ /** Search change callback */
210
+ onSearchChange: (value: string) => void;
211
+ /** Total items count */
212
+ totalCount: number;
213
+ /** Selected items count */
214
+ selectedCount: number;
215
+ /** Clear all selections callback */
216
+ onClearAll: () => void;
217
+ /** Modal title */
218
+ title?: string;
219
+ /** Close modal callback */
220
+ onClose: () => void;
221
+ /** Loading state */
222
+ loading?: boolean;
223
+ };
224
+ type FooterRenderProps<T> = {
225
+ /** Selected items count */
226
+ selectedCount: number;
227
+ /** Total items count */
228
+ totalCount: number;
229
+ /** Confirm selection callback */
230
+ onConfirm: () => void;
231
+ /** Cancel selection callback */
232
+ onCancel: () => void;
233
+ /** Current page info */
234
+ currentPage: number;
235
+ /** Total pages */
236
+ totalPages: number;
237
+ /** Page change callback */
238
+ onPageChange: (page: number) => void;
239
+ /** Page size */
240
+ pageSize: number;
241
+ /** Page size change callback */
242
+ onPageSizeChange?: (size: number) => void;
243
+ /** Loading state */
244
+ loading?: boolean;
245
+ /** Selection mode */
246
+ mode: SelectMode;
247
+ };
248
+ type SearchRenderProps = {
249
+ /** Current search value */
250
+ value: string;
251
+ /** Search change callback */
252
+ onChange: (value: string) => void;
253
+ /** Search placeholder */
254
+ placeholder?: string;
255
+ /** Loading state */
256
+ loading?: boolean;
257
+ /** Clear search callback */
258
+ onClear?: () => void;
259
+ };
260
+ type PaginationRenderProps = {
261
+ /** Current page (1-indexed) */
262
+ currentPage: number;
263
+ /** Total pages */
264
+ totalPages: number;
265
+ /** Page change callback */
266
+ onPageChange: (page: number) => void;
267
+ /** Page size */
268
+ pageSize: number;
269
+ /** Page size change callback */
270
+ onPageSizeChange?: (size: number) => void;
271
+ /** Total items count */
272
+ totalCount: number;
273
+ /** Loading state */
274
+ loading?: boolean;
275
+ };
137
276
  /**
138
277
  * Component overrides - preserves headless core
139
278
  */
@@ -247,6 +386,18 @@ type LookupSelectProps<T> = {
247
386
  icon?: ReactNode;
248
387
  /** Completely custom trigger render function */
249
388
  renderTrigger?: (selected: T | T[] | null) => ReactNode;
389
+ /** Custom modal render function */
390
+ renderModal?: (props: ModalRenderProps<T>) => ReactNode;
391
+ /** Custom grid render function */
392
+ renderGrid?: (props: GridRenderProps<T>) => ReactNode;
393
+ /** Custom header render function */
394
+ renderHeader?: (props: HeaderRenderProps<T>) => ReactNode;
395
+ /** Custom footer render function */
396
+ renderFooter?: (props: FooterRenderProps<T>) => ReactNode;
397
+ /** Custom search input render function */
398
+ renderSearch?: (props: SearchRenderProps) => ReactNode;
399
+ /** Custom pagination render function */
400
+ renderPagination?: (props: PaginationRenderProps) => ReactNode;
250
401
  /** Row-based selection constraint function */
251
402
  selectableRow?: (row: T) => boolean;
252
403
  /** Is virtualization active for large data? */
@@ -290,4 +441,4 @@ type LookupSelectProps<T> = {
290
441
  */
291
442
  declare function LookupSelect<T = any>(props: LookupSelectProps<T>): react_jsx_runtime.JSX.Element;
292
443
 
293
- export { type ClassNames, type ColumnDef, type ComponentsOverrides, type DataSourceFn, type DataSourceResult, LookupSelect, type LookupSelectProps, type QueryState, type ReturnMap, type ReturnShape, type SelectMode, type Styles, type ThemeTokens, type ValueMapper, type i18nStrings };
444
+ export { type ClassNames, type ColumnDef, type ComponentsOverrides, type DataSourceFn, type DataSourceResult, type FooterRenderProps, type GridRenderProps, type HeaderRenderProps, LookupSelect, type LookupSelectProps, type ModalRenderProps, type PaginationRenderProps, type QueryState, type ReturnMap, type ReturnShape, type SearchRenderProps, type SelectMode, type Styles, type ThemeTokens, type ValueMapper, type i18nStrings };
package/dist/index.d.ts CHANGED
@@ -71,6 +71,21 @@ type ValueMapper<T> = {
71
71
  /** Optional: disable check */
72
72
  getDisabled?: (row: T) => boolean;
73
73
  };
74
+ /**
75
+ * Virtualization configuration
76
+ */
77
+ type VirtualizationConfig = {
78
+ /** Is virtualization active? */
79
+ enabled: boolean;
80
+ /** Fixed row height (px) */
81
+ rowHeight: number;
82
+ /** Number of extra rows to render outside visible area */
83
+ overscan: number;
84
+ /** Container height (px) */
85
+ containerHeight: number;
86
+ /** Virtualization threshold - activates with more items than this number */
87
+ threshold: number;
88
+ };
74
89
  /**
75
90
  * Return value shape
76
91
  */
@@ -134,6 +149,130 @@ type i18nStrings = {
134
149
  /** Clear filters - "Clear filters" */
135
150
  clearFilters?: string;
136
151
  };
152
+ /**
153
+ * Render Props Interfaces - for custom rendering functions
154
+ */
155
+ type ModalRenderProps<T> = {
156
+ /** Is modal open? */
157
+ isOpen: boolean;
158
+ /** Close modal callback */
159
+ onClose: () => void;
160
+ /** Modal content */
161
+ children: ReactNode;
162
+ /** Modal title */
163
+ title?: string;
164
+ /** Loading state */
165
+ loading?: boolean;
166
+ /** Error message */
167
+ error?: string | null;
168
+ /** Current query state */
169
+ query?: QueryState;
170
+ /** Selected items count */
171
+ selectedCount: number;
172
+ /** Total items count */
173
+ totalCount: number;
174
+ };
175
+ type GridRenderProps<T> = {
176
+ /** Grid data */
177
+ data: T[];
178
+ /** Column definitions */
179
+ columns: ColumnDef<T>[];
180
+ /** Selected row IDs */
181
+ selectedIds: (string | number)[];
182
+ /** Row selection callback */
183
+ onRowSelect: (row: T) => void;
184
+ /** Select all callback */
185
+ onSelectAll?: () => void;
186
+ /** Clear all selections callback */
187
+ onClearAll?: () => void;
188
+ /** Loading state */
189
+ loading?: boolean;
190
+ /** Error state */
191
+ error?: string | null;
192
+ /** Selection mode */
193
+ mode: SelectMode;
194
+ /** Value mapper */
195
+ mapper: ValueMapper<T>;
196
+ /** Virtualization config */
197
+ virtualization?: VirtualizationConfig;
198
+ /** Row selectability checker */
199
+ selectableRow?: (row: T) => boolean;
200
+ /** Sort change callback */
201
+ onSortChange?: (sortBy: string, sortDir: 'asc' | 'desc') => void;
202
+ /** Current sort state */
203
+ sortBy?: string;
204
+ sortDir?: 'asc' | 'desc';
205
+ };
206
+ type HeaderRenderProps<T> = {
207
+ /** Current search value */
208
+ searchValue: string;
209
+ /** Search change callback */
210
+ onSearchChange: (value: string) => void;
211
+ /** Total items count */
212
+ totalCount: number;
213
+ /** Selected items count */
214
+ selectedCount: number;
215
+ /** Clear all selections callback */
216
+ onClearAll: () => void;
217
+ /** Modal title */
218
+ title?: string;
219
+ /** Close modal callback */
220
+ onClose: () => void;
221
+ /** Loading state */
222
+ loading?: boolean;
223
+ };
224
+ type FooterRenderProps<T> = {
225
+ /** Selected items count */
226
+ selectedCount: number;
227
+ /** Total items count */
228
+ totalCount: number;
229
+ /** Confirm selection callback */
230
+ onConfirm: () => void;
231
+ /** Cancel selection callback */
232
+ onCancel: () => void;
233
+ /** Current page info */
234
+ currentPage: number;
235
+ /** Total pages */
236
+ totalPages: number;
237
+ /** Page change callback */
238
+ onPageChange: (page: number) => void;
239
+ /** Page size */
240
+ pageSize: number;
241
+ /** Page size change callback */
242
+ onPageSizeChange?: (size: number) => void;
243
+ /** Loading state */
244
+ loading?: boolean;
245
+ /** Selection mode */
246
+ mode: SelectMode;
247
+ };
248
+ type SearchRenderProps = {
249
+ /** Current search value */
250
+ value: string;
251
+ /** Search change callback */
252
+ onChange: (value: string) => void;
253
+ /** Search placeholder */
254
+ placeholder?: string;
255
+ /** Loading state */
256
+ loading?: boolean;
257
+ /** Clear search callback */
258
+ onClear?: () => void;
259
+ };
260
+ type PaginationRenderProps = {
261
+ /** Current page (1-indexed) */
262
+ currentPage: number;
263
+ /** Total pages */
264
+ totalPages: number;
265
+ /** Page change callback */
266
+ onPageChange: (page: number) => void;
267
+ /** Page size */
268
+ pageSize: number;
269
+ /** Page size change callback */
270
+ onPageSizeChange?: (size: number) => void;
271
+ /** Total items count */
272
+ totalCount: number;
273
+ /** Loading state */
274
+ loading?: boolean;
275
+ };
137
276
  /**
138
277
  * Component overrides - preserves headless core
139
278
  */
@@ -247,6 +386,18 @@ type LookupSelectProps<T> = {
247
386
  icon?: ReactNode;
248
387
  /** Completely custom trigger render function */
249
388
  renderTrigger?: (selected: T | T[] | null) => ReactNode;
389
+ /** Custom modal render function */
390
+ renderModal?: (props: ModalRenderProps<T>) => ReactNode;
391
+ /** Custom grid render function */
392
+ renderGrid?: (props: GridRenderProps<T>) => ReactNode;
393
+ /** Custom header render function */
394
+ renderHeader?: (props: HeaderRenderProps<T>) => ReactNode;
395
+ /** Custom footer render function */
396
+ renderFooter?: (props: FooterRenderProps<T>) => ReactNode;
397
+ /** Custom search input render function */
398
+ renderSearch?: (props: SearchRenderProps) => ReactNode;
399
+ /** Custom pagination render function */
400
+ renderPagination?: (props: PaginationRenderProps) => ReactNode;
250
401
  /** Row-based selection constraint function */
251
402
  selectableRow?: (row: T) => boolean;
252
403
  /** Is virtualization active for large data? */
@@ -290,4 +441,4 @@ type LookupSelectProps<T> = {
290
441
  */
291
442
  declare function LookupSelect<T = any>(props: LookupSelectProps<T>): react_jsx_runtime.JSX.Element;
292
443
 
293
- export { type ClassNames, type ColumnDef, type ComponentsOverrides, type DataSourceFn, type DataSourceResult, LookupSelect, type LookupSelectProps, type QueryState, type ReturnMap, type ReturnShape, type SelectMode, type Styles, type ThemeTokens, type ValueMapper, type i18nStrings };
444
+ export { type ClassNames, type ColumnDef, type ComponentsOverrides, type DataSourceFn, type DataSourceResult, type FooterRenderProps, type GridRenderProps, type HeaderRenderProps, LookupSelect, type LookupSelectProps, type ModalRenderProps, type PaginationRenderProps, type QueryState, type ReturnMap, type ReturnShape, type SearchRenderProps, type SelectMode, type Styles, type ThemeTokens, type ValueMapper, type i18nStrings };
package/dist/index.js CHANGED
@@ -1244,7 +1244,7 @@ function Pagination({
1244
1244
  }
1245
1245
 
1246
1246
  // src/components/LookupSelect.tsx
1247
- import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
1247
+ import { Fragment as Fragment2, jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
1248
1248
  function LookupSelect(props) {
1249
1249
  const {
1250
1250
  columns,
@@ -1256,6 +1256,12 @@ function LookupSelect(props) {
1256
1256
  size = "medium",
1257
1257
  icon,
1258
1258
  renderTrigger,
1259
+ renderModal,
1260
+ renderGrid,
1261
+ renderHeader,
1262
+ renderFooter,
1263
+ renderSearch,
1264
+ renderPagination,
1259
1265
  modalTitle,
1260
1266
  classNames,
1261
1267
  styles,
@@ -1419,7 +1425,7 @@ function LookupSelect(props) {
1419
1425
  virtualThreshold
1420
1426
  ]
1421
1427
  );
1422
- const renderGrid = React3.useCallback(() => {
1428
+ const renderGridComponent = React3.useCallback(() => {
1423
1429
  const commonGridProps = {
1424
1430
  data: currentData,
1425
1431
  columns,
@@ -1470,6 +1476,96 @@ function LookupSelect(props) {
1470
1476
  shouldUseVirtualization,
1471
1477
  virtualizationConfig
1472
1478
  ]);
1479
+ const renderModalContent = () => {
1480
+ const defaultContent = /* @__PURE__ */ jsxs6(Fragment2, { children: [
1481
+ renderSearch ? renderSearch({
1482
+ value: searchValue,
1483
+ onChange: handleSearchChange,
1484
+ placeholder: texts.searchPlaceholder,
1485
+ loading,
1486
+ onClear: () => handleSearchChange("")
1487
+ }) : /* @__PURE__ */ jsx6(
1488
+ SearchInput,
1489
+ {
1490
+ value: searchValue,
1491
+ onChange: handleSearchChange,
1492
+ placeholder: texts.searchPlaceholder
1493
+ }
1494
+ ),
1495
+ /* @__PURE__ */ jsxs6("div", { className: "lookup-select__modal-content", children: [
1496
+ renderGrid ? renderGrid({
1497
+ data: currentData,
1498
+ columns,
1499
+ selectedIds: currentSelections.map(mapper.getId),
1500
+ onRowSelect: toggleRowSelection,
1501
+ onSelectAll: mode === "multiple" ? () => {
1502
+ const allIds = currentData.map(mapper.getId);
1503
+ const selectedIds = currentSelections.map(mapper.getId);
1504
+ if (allIds.length === selectedIds.length) {
1505
+ clearSelections();
1506
+ } else {
1507
+ currentData.forEach((row) => {
1508
+ if (!isRowSelected(row)) {
1509
+ toggleRowSelection(row);
1510
+ }
1511
+ });
1512
+ }
1513
+ } : void 0,
1514
+ onClearAll: clearSelections,
1515
+ loading,
1516
+ error,
1517
+ mode,
1518
+ mapper,
1519
+ virtualization: shouldUseVirtualization ? virtualizationConfig : void 0,
1520
+ selectableRow,
1521
+ onSortChange: handleSortChange,
1522
+ sortBy: getCurrentQuery().sortBy,
1523
+ sortDir: getCurrentQuery().sortDir
1524
+ }) : renderGridComponent(),
1525
+ dataSource && !renderPagination && /* @__PURE__ */ jsx6(
1526
+ Pagination,
1527
+ {
1528
+ currentPage,
1529
+ totalCount,
1530
+ pageSize: optimizedPageSize,
1531
+ onPageChange: handlePageChange
1532
+ }
1533
+ ),
1534
+ dataSource && renderPagination && renderPagination({
1535
+ currentPage,
1536
+ totalPages: Math.ceil(totalCount / optimizedPageSize),
1537
+ onPageChange: handlePageChange,
1538
+ pageSize: optimizedPageSize,
1539
+ onPageSizeChange: (newSize) => {
1540
+ },
1541
+ totalCount,
1542
+ loading
1543
+ })
1544
+ ] }),
1545
+ renderFooter ? renderFooter({
1546
+ selectedCount: currentSelections.length,
1547
+ totalCount,
1548
+ onConfirm: confirmSelection,
1549
+ onCancel: cancelSelection,
1550
+ currentPage,
1551
+ totalPages: Math.ceil(totalCount / optimizedPageSize),
1552
+ onPageChange: handlePageChange,
1553
+ pageSize: optimizedPageSize,
1554
+ loading,
1555
+ mode
1556
+ }) : /* @__PURE__ */ jsx6(
1557
+ ModalFooter,
1558
+ {
1559
+ onConfirm: confirmSelection,
1560
+ onCancel: cancelSelection,
1561
+ confirmText: texts.confirmText,
1562
+ cancelText: texts.cancelText,
1563
+ selectedCount: currentSelections.length
1564
+ }
1565
+ )
1566
+ ] });
1567
+ return defaultContent;
1568
+ };
1473
1569
  const getThemeClasses = () => {
1474
1570
  const classes = ["lookup-select"];
1475
1571
  if (variant && variant !== "default") {
@@ -1517,7 +1613,17 @@ function LookupSelect(props) {
1517
1613
  onRemoveTag: (item) => toggleRowSelection(item)
1518
1614
  }
1519
1615
  ),
1520
- /* @__PURE__ */ jsxs6(
1616
+ renderModal ? renderModal({
1617
+ isOpen: modalOpen,
1618
+ onClose: cancelSelection,
1619
+ children: renderModalContent(),
1620
+ title: modalTitle || texts.modalTitle,
1621
+ loading,
1622
+ error,
1623
+ query: getCurrentQuery(),
1624
+ selectedCount: currentSelections.length,
1625
+ totalCount
1626
+ }) : /* @__PURE__ */ jsx6(
1521
1627
  Modal,
1522
1628
  {
1523
1629
  isOpen: modalOpen,
@@ -1525,38 +1631,7 @@ function LookupSelect(props) {
1525
1631
  title: modalTitle || texts.modalTitle,
1526
1632
  className: classNames?.modal,
1527
1633
  style: styles?.modal,
1528
- children: [
1529
- /* @__PURE__ */ jsx6(
1530
- SearchInput,
1531
- {
1532
- value: searchValue,
1533
- onChange: handleSearchChange,
1534
- placeholder: texts.searchPlaceholder
1535
- }
1536
- ),
1537
- /* @__PURE__ */ jsxs6("div", { className: "lookup-select__modal-content", children: [
1538
- renderGrid(),
1539
- dataSource && /* @__PURE__ */ jsx6(
1540
- Pagination,
1541
- {
1542
- currentPage,
1543
- totalCount,
1544
- pageSize: optimizedPageSize,
1545
- onPageChange: handlePageChange
1546
- }
1547
- )
1548
- ] }),
1549
- /* @__PURE__ */ jsx6(
1550
- ModalFooter,
1551
- {
1552
- onConfirm: confirmSelection,
1553
- onCancel: cancelSelection,
1554
- confirmText: texts.confirmText,
1555
- cancelText: texts.cancelText,
1556
- selectedCount: currentSelections.length
1557
- }
1558
- )
1559
- ]
1634
+ children: renderModalContent()
1560
1635
  }
1561
1636
  )
1562
1637
  ] });