frame.select 1.1.1 → 1.1.3

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/App.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../src/App.tsx"],"names":[],"mappings":"AACA,OAAO,WAAW,CAAC;AAInB,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,iBAAS,GAAG,sBAuGX;AAED,eAAe,GAAG,CAAC"}
1
+ {"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../src/App.tsx"],"names":[],"mappings":"AACA,OAAO,WAAW,CAAC;AAInB,OAAO,KAAK,MAAM,OAAO,CAAC;AAU1B,iBAAS,GAAG,sBA6LX;AAED,eAAe,GAAG,CAAC"}
package/dist/App.js CHANGED
@@ -1,10 +1,11 @@
1
1
  import { createColumnHelper } from '@tanstack/react-table';
2
2
  import './App.css';
3
- import ItemList from './components/ItemList';
4
3
  import { useState } from 'react';
5
4
  import React from 'react';
6
5
  import { BrandList } from './components/BrandList';
6
+ import { FrameList } from './components/FrameList';
7
7
  function App() {
8
+ const [brand, setBrand] = useState('');
8
9
  const brands = [
9
10
  {
10
11
  name: 'Adidas',
@@ -43,24 +44,102 @@ function App() {
43
44
  // item: ['New Balance'],
44
45
  },
45
46
  ];
46
- const columnHelper = createColumnHelper();
47
- const extraColumns = [
48
- columnHelper.accessor((row) => row.description, {
47
+ const framesAdidas = [
48
+ 'ADI0000000000000000014362150000',
49
+ 'ADI0000000000000000018362150000',
50
+ 'ADI0000000000000000019362150000',
51
+ // 3456789 123456789 12345678901
52
+ 'AFF000000000000000TMA4750190000',
53
+ ];
54
+ const frameNike = [
55
+ 'NIK0000000000000000030362150000',
56
+ 'NIK0000000000000000031362150000',
57
+ ];
58
+ const framePuma = [
59
+ 'PUM000000000000000PUMA162150000',
60
+ 'PUM000000000000000PUMA262150000',
61
+ ];
62
+ const frameReebok = [
63
+ 'REB000000000000000REEBO62150000',
64
+ 'REB000000000000000EEBOK62150000',
65
+ ];
66
+ const frameUnderArmour = [
67
+ 'UND000000000000000UARMR62150000',
68
+ 'UND000000000000000UNDER62150000',
69
+ ];
70
+ const frameNewBalance = [
71
+ 'NEW000000000000000NEWBL62150000',
72
+ 'NEW000000000000000NWBLC62150000',
73
+ ];
74
+ const frames = [
75
+ { brand: 'Adidas', frames: framesAdidas },
76
+ { brand: 'Nike', frames: frameNike },
77
+ { brand: 'Puma', frames: framePuma },
78
+ { brand: 'Reebok', frames: frameReebok },
79
+ { brand: 'Under Armour', frames: frameUnderArmour },
80
+ { brand: 'New Balance', frames: frameNewBalance },
81
+ ];
82
+ function convertFrames(brand) {
83
+ const foundFrames = frames.find((b) => b.brand === brand);
84
+ if (!foundFrames) {
85
+ return [];
86
+ }
87
+ return foundFrames.frames.map((frame) => ({
88
+ id: frame,
89
+ name: frame.substring(18, 23),
90
+ length: parseInt(frame.substring(23, 25)),
91
+ width: parseInt(frame.substring(25, 27)),
92
+ }));
93
+ }
94
+ const brandColumnHelper = createColumnHelper();
95
+ const extraBrandColumns = [
96
+ brandColumnHelper.accessor((row) => row.description, {
49
97
  header: 'description',
50
98
  cell: (info) => React.createElement("div", null, info.getValue()),
51
99
  }),
52
100
  ];
53
- const colWidth = [
101
+ const brandColWidth = [
54
102
  {
55
- column: extraColumns[0],
103
+ column: extraBrandColumns[0],
104
+ },
105
+ ];
106
+ const frameColumnHelper = createColumnHelper();
107
+ const extraFrameColumns = [
108
+ frameColumnHelper.accessor((row) => row.length.toString(), {
109
+ header: 'length',
110
+ cell: (info) => React.createElement("div", null, info.getValue()),
111
+ }),
112
+ frameColumnHelper.accessor((row) => row.width.toString(), {
113
+ // Convert to string
114
+ header: 'width',
115
+ cell: (info) => React.createElement("div", null, info.getValue()),
116
+ }),
117
+ ];
118
+ const frameColWidth = [
119
+ {
120
+ column: extraFrameColumns[0],
121
+ },
122
+ {
123
+ column: extraFrameColumns[1],
56
124
  },
57
125
  ];
58
126
  const onClickItem = (item) => {
59
127
  window.alert(`Item clicked: ${item.getValue()}\n${JSON.stringify(item.row.original)}`);
60
128
  };
61
- const onClickBrand = (index) => {
62
- window.alert(`Item clicked: ${index}\n${JSON.stringify(brands[index], null, 2)}`);
129
+ const onClickBrand = (cell, index) => {
130
+ console.log(`cell: ${JSON.stringify(cell.row.original, null, 2)}`);
131
+ const brand = brands.find((b) => b.name === cell.row.original.name);
132
+ // window.alert(`Item clicked: ${index}\n${JSON.stringify(brand, null, 2)}`);
133
+ if (brand) {
134
+ setBrand(brand.name);
135
+ }
136
+ };
137
+ const onClickFrame = (cell, index) => {
138
+ window.alert(`Frame clicked: ${JSON.stringify(cell.row.original)} at index ${index}`);
63
139
  };
140
+ // const onClickFrame = (frame: string, index: number) => {
141
+ // window.alert(`Frame clicked: ${frame} at index ${index}`);
142
+ // };
64
143
  const [filter, setFilter] = useState('');
65
144
  function filterMatches(item, fltr) {
66
145
  const match = item.name
@@ -75,12 +154,13 @@ function App() {
75
154
  filterMatches,
76
155
  placeholder: 'Filter Brands',
77
156
  };
78
- const renderItem = (item) => React.createElement("h4", null, item);
157
+ // const renderItem = (item: string) => <h4>{item}</h4>;
79
158
  return (React.createElement(React.Fragment, null,
80
159
  React.createElement("h1", null, "Brand List"),
81
- React.createElement(ItemList, { itemList: brands, renderItem: renderItem, clickFunc: onClickItem, itemFilter: tItemFilter, extraColumns: colWidth }),
82
160
  React.createElement(BrandList, { brandList: brands, onClick: onClickBrand,
83
161
  // renderItem={renderItem}
84
- extraColumns: colWidth })));
162
+ extraColumns: brandColWidth }),
163
+ React.createElement("h2", null, "Frame List"),
164
+ React.createElement(FrameList, { frameList: convertFrames(brand), onClick: onClickFrame, extraColumns: frameColWidth, style: { border: '1px solid black', padding: '10px' } })));
85
165
  }
86
166
  export default App;
@@ -1,10 +1,11 @@
1
+ import { Cell } from '@tanstack/react-table';
1
2
  import { TColumn } from './itemTypes';
2
3
  import { JSX } from 'react';
3
4
  import React from 'react';
4
5
  import { TBrandObj } from './types';
5
6
  export declare function BrandList(props: {
6
7
  brandList: TBrandObj[];
7
- onClick?: (index: number) => void;
8
+ onClick?: (cell: Cell<TBrandObj, unknown>, index: number) => void;
8
9
  renderItem?: (item: string) => React.ReactNode;
9
10
  extraColumns?: TColumn<TBrandObj>[];
10
11
  style?: React.CSSProperties;
@@ -1 +1 @@
1
- {"version":3,"file":"BrandList.d.ts","sourceRoot":"","sources":["../../src/components/BrandList.tsx"],"names":[],"mappings":"AAmBA,OAAO,EAAe,OAAO,EAAS,MAAM,aAAa,CAAC;AAC1D,OAAO,EAAE,GAAG,EAA6C,MAAM,OAAO,CAAC;AACvE,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEpC,wBAAgB,SAAS,CAAC,KAAK,EAAE;IAC/B,SAAS,EAAE,SAAS,EAAE,CAAC;IACvB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,KAAK,CAAC,SAAS,CAAC;IAC/C,YAAY,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;IACpC,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;CAC7B,GAAG,GAAG,CAAC,OAAO,CAmLd"}
1
+ {"version":3,"file":"BrandList.d.ts","sourceRoot":"","sources":["../../src/components/BrandList.tsx"],"names":[],"mappings":"AASA,OAAO,EAIL,IAAI,EAKL,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAe,OAAO,EAAS,MAAM,aAAa,CAAC;AAC1D,OAAO,EAAE,GAAG,EAA6C,MAAM,OAAO,CAAC;AACvE,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEpC,wBAAgB,SAAS,CAAC,KAAK,EAAE;IAC/B,SAAS,EAAE,SAAS,EAAE,CAAC;IACvB,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClE,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,KAAK,CAAC,SAAS,CAAC;IAC/C,YAAY,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;IACpC,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;CAC7B,GAAG,GAAG,CAAC,OAAO,CA8Ld"}
@@ -29,6 +29,7 @@ export function BrandList(props) {
29
29
  }
30
30
  // eslint-disable-next-line react-hooks/exhaustive-deps
31
31
  }, [serializedExtraColumns]); // Use the serialized version as a dependency
32
+ /***************************** filtered items *******************************/
32
33
  const filteredItems = useMemo(() => {
33
34
  if (!tBrandFilter) {
34
35
  return props.brandList;
@@ -45,6 +46,7 @@ export function BrandList(props) {
45
46
  // tBrandFilter.filterEvent?.(filteredList)
46
47
  return filteredList;
47
48
  }, [tBrandFilter, props.brandList, extraCols]);
49
+ /****************************************************************************/
48
50
  const defaultHeader = 'Name';
49
51
  const columnHelper = createColumnHelper();
50
52
  const defaultColumns = [
@@ -60,9 +62,9 @@ export function BrandList(props) {
60
62
  columns.push(col.column);
61
63
  }
62
64
  });
63
- const onClick = (index) => () => {
65
+ const onClick = (cell, index) => () => {
64
66
  if (props.onClick) {
65
- props.onClick?.(index);
67
+ props.onClick?.(cell, index);
66
68
  }
67
69
  else {
68
70
  console.log(`Clicked item index: ${index}`);
@@ -86,31 +88,35 @@ export function BrandList(props) {
86
88
  }
87
89
  return filter;
88
90
  }
89
- function displayBody(cell) {
90
- let cellContent = React.createElement("div", null);
91
- const cll = cell.getValue();
92
- if (cell.column.columnDef.header === defaultHeader) {
93
- cellContent = (React.createElement(TableCell, { style: { backgroundColor: 'white', padding: 2 }, key: cell.id },
94
- React.createElement(Button, { onClick: onClick(cell.row.index) }, props.renderItem
95
- ? props.renderItem(cll)
96
- : flexRender(cell.column.columnDef.cell, cell.getContext()))));
97
- }
98
- else {
99
- cellContent = (React.createElement(TableCell, { style: { backgroundColor: 'white', padding: 2 }, key: cell.id }, props.renderItem ? props.renderItem(cll) : React.createElement("div", null, cll)));
100
- }
101
- return cellContent;
102
- }
103
91
  const table = useReactTable({
104
92
  data: filteredItems,
105
93
  columns,
106
94
  getCoreRowModel: getCoreRowModel(),
107
95
  getFilteredRowModel: getFilteredRowModel(),
108
96
  });
97
+ const paginatedRows = table.getRowModel().rows;
98
+ const renderRows = React.useCallback((rows) => {
99
+ function displayBody(cell) {
100
+ let cellContent = React.createElement("div", null);
101
+ const cll = cell.getValue();
102
+ if (cell.column.columnDef.header === defaultHeader) {
103
+ cellContent = (React.createElement(TableCell, { style: { backgroundColor: 'white', padding: 2 }, key: cell.id },
104
+ React.createElement(Button, { onClick: onClick(cell, cell.row.index) }, props.renderItem
105
+ ? props.renderItem(cll)
106
+ : flexRender(cell.column.columnDef.cell, cell.getContext()))));
107
+ }
108
+ else {
109
+ cellContent = (React.createElement(TableCell, { style: { backgroundColor: 'white', padding: 2 }, key: cell.id }, props.renderItem ? props.renderItem(cll) : React.createElement("div", null, cll)));
110
+ }
111
+ return cellContent;
112
+ }
113
+ return rows.map((row) => (React.createElement(TableRow, { key: row.id }, row.getVisibleCells().map((cell) => {
114
+ // console.log(`cell: ${JSON.stringify(cell, null)}`)
115
+ return displayBody(cell);
116
+ }))));
117
+ }, [onClick, props]);
109
118
  return (React.createElement(TableContainer, { "data-testid": "frame.select-TableContainer", style: props.style },
110
119
  React.createElement(Table, { stickyHeader: true, "aria-label": "sticky table" },
111
120
  React.createElement(TableHead, null, table.getHeaderGroups().map((headerGroup) => (React.createElement(TableRow, { key: headerGroup.id, "data-testid": headerGroup.id }, headerGroup.headers.map((header) => (React.createElement(TableCell, { key: header.id }, displayHeader(header)))))))),
112
- React.createElement(TableBody, null, table.getRowModel().rows.map((row) => (React.createElement(TableRow, { key: row.id }, row.getVisibleCells().map((cell) => {
113
- // console.log(`cell: ${JSON.stringify(cell, null)}`)
114
- return displayBody(cell);
115
- }))))))));
121
+ React.createElement(TableBody, { "data-testid": "table.list-of-brands" }, renderRows(paginatedRows)))));
116
122
  }
@@ -0,0 +1,13 @@
1
+ import { Cell } from '@tanstack/react-table';
2
+ import { TColumn } from './itemTypes';
3
+ import { JSX } from 'react';
4
+ import React from 'react';
5
+ import { TFrameObj } from './types';
6
+ export declare function FrameList(props: {
7
+ frameList: TFrameObj[];
8
+ onClick?: (cell: Cell<TFrameObj, unknown>, index: number) => void;
9
+ renderItem?: (item: string) => React.ReactNode;
10
+ extraColumns?: TColumn<TFrameObj>[];
11
+ style?: React.CSSProperties;
12
+ }): JSX.Element;
13
+ //# sourceMappingURL=FrameList.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FrameList.d.ts","sourceRoot":"","sources":["../../src/components/FrameList.tsx"],"names":[],"mappings":"AASA,OAAO,EAIL,IAAI,EAKL,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAe,OAAO,EAAS,MAAM,aAAa,CAAC;AAC1D,OAAO,EAAE,GAAG,EAA6C,MAAM,OAAO,CAAC;AACvE,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEpC,wBAAgB,SAAS,CAAC,KAAK,EAAE;IAC/B,SAAS,EAAE,SAAS,EAAE,CAAC;IACvB,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClE,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,KAAK,CAAC,SAAS,CAAC;IAC/C,YAAY,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;IACpC,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;CAC7B,GAAG,GAAG,CAAC,OAAO,CA8Ld"}
@@ -0,0 +1,122 @@
1
+ import { TableContainer, Table, TableHead, TableRow, TableCell, TableBody, Button, } from '@mui/material';
2
+ import { useReactTable, getCoreRowModel, getFilteredRowModel, createColumnHelper, flexRender, } from '@tanstack/react-table';
3
+ import ItemFilter from './ItemFilter';
4
+ import { useMemo, useState, useCallback } from 'react';
5
+ import React from 'react';
6
+ export function FrameList(props) {
7
+ 'use no memo'; // For React Compiler compatibility with TanStack Table
8
+ const [filter, setFilter] = useState('');
9
+ const filterMatches = useCallback((item, fltr) => {
10
+ const match = item.name
11
+ .toLowerCase()
12
+ .includes(fltr ? fltr.toLowerCase() : '');
13
+ return match;
14
+ }, []);
15
+ const tFrameFilter = useMemo(() => ({
16
+ property: 'name',
17
+ filter,
18
+ setFilter,
19
+ filterMatches,
20
+ placeholder: 'Frames',
21
+ }), [filter, filterMatches]);
22
+ const serializedExtraColumns = useMemo(() => JSON.stringify(props.extraColumns), [props.extraColumns]);
23
+ const extraCols = useMemo(() => {
24
+ if (props.extraColumns) {
25
+ return props.extraColumns.filter((col) => col !== undefined);
26
+ }
27
+ else {
28
+ return [];
29
+ }
30
+ // eslint-disable-next-line react-hooks/exhaustive-deps
31
+ }, [serializedExtraColumns]); // Use the serialized version as a dependency
32
+ /***************************** filtered items *******************************/
33
+ const filteredItems = useMemo(() => {
34
+ if (!tFrameFilter) {
35
+ return props.frameList;
36
+ }
37
+ let filteredList = props.frameList;
38
+ if (tFrameFilter.filterMatches) {
39
+ filteredList = props.frameList.filter((item) => tFrameFilter.filterMatches(item, tFrameFilter.filter));
40
+ }
41
+ extraCols.forEach((col) => {
42
+ if (col?.filter) {
43
+ filteredList = filteredList.filter((item) => col.filter?.filterMatches(item, col.filter.filter));
44
+ }
45
+ });
46
+ // tBrandFilter.filterEvent?.(filteredList)
47
+ return filteredList;
48
+ }, [tFrameFilter, props.frameList, extraCols]);
49
+ /****************************************************************************/
50
+ const defaultHeader = 'Name';
51
+ const columnHelper = createColumnHelper();
52
+ const defaultColumns = [
53
+ columnHelper.accessor((row) => row.name, {
54
+ header: defaultHeader,
55
+ cell: (info) => (React.createElement("div", { style: { fontWeight: 'bold' } }, info.getValue())),
56
+ footer: (info) => info.column.id,
57
+ }),
58
+ ];
59
+ const columns = [...defaultColumns];
60
+ extraCols.forEach((col) => {
61
+ if (col) {
62
+ columns.push(col.column);
63
+ }
64
+ });
65
+ const onClick = (cell, index) => () => {
66
+ if (props.onClick) {
67
+ props.onClick?.(cell, index);
68
+ }
69
+ else {
70
+ console.log(`Clicked item index: ${index}`);
71
+ }
72
+ };
73
+ function displayHeader(header) {
74
+ let filter = React.createElement("div", null);
75
+ if (header.id === defaultHeader) {
76
+ if (tFrameFilter) {
77
+ filter = (React.createElement("div", { style: { width: '100%' } },
78
+ React.createElement(ItemFilter, { itemFilter: tFrameFilter })));
79
+ }
80
+ }
81
+ else {
82
+ extraCols.forEach((col) => {
83
+ if (col && header.id === col.column.header) {
84
+ filter = col.filter ? (React.createElement("div", { style: { width: '100%' } },
85
+ React.createElement(ItemFilter, { itemFilter: col.filter }))) : (React.createElement("div", null));
86
+ }
87
+ });
88
+ }
89
+ return filter;
90
+ }
91
+ const table = useReactTable({
92
+ data: filteredItems,
93
+ columns,
94
+ getCoreRowModel: getCoreRowModel(),
95
+ getFilteredRowModel: getFilteredRowModel(),
96
+ });
97
+ const paginatedRows = table.getRowModel().rows;
98
+ const renderRows = React.useCallback((rows) => {
99
+ function displayBody(cell) {
100
+ let cellContent = React.createElement("div", null);
101
+ const cll = cell.getValue();
102
+ if (cell.column.columnDef.header === defaultHeader) {
103
+ cellContent = (React.createElement(TableCell, { style: { backgroundColor: 'white', padding: 2 }, key: cell.id },
104
+ React.createElement(Button, { onClick: onClick(cell, cell.row.index) }, props.renderItem
105
+ ? props.renderItem(cll)
106
+ : flexRender(cell.column.columnDef.cell, cell.getContext()))));
107
+ }
108
+ else {
109
+ cellContent = (React.createElement(TableCell, { style: { backgroundColor: 'white', padding: 2 }, key: cell.id }, props.renderItem ? props.renderItem(cll) : React.createElement("div", null, cll)));
110
+ }
111
+ return cellContent;
112
+ }
113
+ return rows.map((row) => (React.createElement(TableRow, { key: row.id }, row.getVisibleCells().map((cell) => {
114
+ // console.log(`cell: ${JSON.stringify(cell, null)}`)
115
+ return displayBody(cell);
116
+ }))));
117
+ }, [onClick, props]);
118
+ return (React.createElement(TableContainer, { "data-testid": "frame.select-TableContainer", style: props.style },
119
+ React.createElement(Table, { stickyHeader: true, "aria-label": "sticky table" },
120
+ React.createElement(TableHead, null, table.getHeaderGroups().map((headerGroup) => (React.createElement(TableRow, { key: headerGroup.id, "data-testid": headerGroup.id }, headerGroup.headers.map((header) => (React.createElement(TableCell, { key: header.id }, displayHeader(header)))))))),
121
+ React.createElement(TableBody, { "data-testid": "table.list-of-frames" }, renderRows(paginatedRows)))));
122
+ }
@@ -3,4 +3,10 @@ export type TBrandObj = {
3
3
  id: number;
4
4
  description: string;
5
5
  };
6
+ export type TFrameObj = {
7
+ name: string;
8
+ length: number;
9
+ width: number;
10
+ id: string;
11
+ };
6
12
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/components/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/components/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AACF,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;CACZ,CAAC"}
@@ -1 +1 @@
1
- {"root":["../src/app.tsx","../src/index.ts","../src/main.tsx","../src/vite-env.d.ts","../src/components/brandfilter.tsx","../src/components/brandlist.tsx","../src/components/debounceinput.tsx","../src/components/itemfilter.test.tsx","../src/components/itemfilter.tsx","../src/components/itemlist.test.tsx","../src/components/itemlist.tsx","../src/components/itemtypes.ts","../src/components/types.ts"],"version":"5.9.3"}
1
+ {"root":["../src/app.tsx","../src/index.ts","../src/main.tsx","../src/vite-env.d.ts","../src/components/brandlist.tsx","../src/components/framelist.tsx","../src/components/itemfilter.tsx","../src/components/itemlist.tsx","../src/components/itemtypes.ts","../src/components/types.ts"],"version":"5.9.3"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "frame.select",
3
- "version": "1.1.1",
3
+ "version": "1.1.3",
4
4
  "description": "A React component for selecting items from a list with a search bar.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -35,18 +35,18 @@
35
35
  "@eslint/js": "^9.39.2",
36
36
  "@testing-library/dom": "^10.4.1",
37
37
  "@testing-library/jest-dom": "^6.9.1",
38
- "@testing-library/react": "^16.2.0",
38
+ "@testing-library/react": "^16.3.1",
39
39
  "@types/react": "^19.2.7",
40
40
  "@types/react-dom": "^19.2.3",
41
41
  "@vitejs/plugin-react": "^5.1.2",
42
42
  "eslint": "^9.39.2",
43
43
  "eslint-plugin-react-hooks": "^7.0.1",
44
- "eslint-plugin-react-refresh": "^0.4.25",
44
+ "eslint-plugin-react-refresh": "^0.4.26",
45
45
  "globals": "^16.5.0",
46
46
  "jsdom": "^27.3.0",
47
47
  "typescript": "~5.9.3",
48
- "typescript-eslint": "^8.49.0",
49
- "vite": "^7.2.7",
50
- "vitest": "^4.0.15"
48
+ "typescript-eslint": "^8.50.0",
49
+ "vite": "^7.3.0",
50
+ "vitest": "^4.0.16"
51
51
  }
52
52
  }
@@ -1,6 +0,0 @@
1
- import { Column } from '@tanstack/react-table';
2
- import React from 'react';
3
- export declare function BrandFilter({ column }: {
4
- column: Column<any, unknown>;
5
- }): React.JSX.Element;
6
- //# sourceMappingURL=BrandFilter.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"BrandFilter.d.ts","sourceRoot":"","sources":["../../src/components/BrandFilter.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAI/C,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,wBAAgB,WAAW,CAAC,EAAE,MAAM,EAAE,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC,CAAA;CAAE,qBAgDvE"}
@@ -1,32 +0,0 @@
1
- import { useMemo } from 'react';
2
- import { DebouncedInput } from './DebounceInput';
3
- // import { Message } from '../../../../common/commands';
4
- import React from 'react';
5
- export function BrandFilter({ column }) {
6
- const columnFilterValue = column.getFilterValue();
7
- const [value, setFilterValue] = React.useState('');
8
- // const { filterVariant } = column.columnDef.meta ?? {};
9
- React.useEffect(() => {
10
- console.log(`has changed`);
11
- setFilterValue(columnFilterValue);
12
- }, [columnFilterValue]);
13
- React.useEffect(() => {
14
- console.log(`BrandFilter.CommandDBBrandFilter`);
15
- // window.electron.ipcRenderer.on(
16
- // Message.CommandDBBrandFilter,
17
- // (_event: unknown, data: string) => {
18
- // setVal(data);
19
- // setFilterValue(data);
20
- // }
21
- // );
22
- }, []);
23
- // setFilterValue((columnFilterValue ?? '') as string);
24
- const setVal = React.useCallback((str) => {
25
- column.setFilterValue(str);
26
- }, [column]);
27
- return useMemo(() => (React.createElement(DebouncedInput, { className: "w-36 border shadow rounded", title: "brand", onChange: (value) => {
28
- document.body.style.cursor = 'wait';
29
- setVal(value);
30
- document.body.style.cursor = 'default';
31
- }, placeholder: `Search...`, type: "text", value: value })), [setVal, value]);
32
- }
@@ -1,8 +0,0 @@
1
- import React from 'react';
2
- export declare function DebouncedInput({ value: initialValue, title, onChange, debounce, }: {
3
- value: string | number;
4
- title: string;
5
- onChange: (value: string | number) => void;
6
- debounce?: number;
7
- } & Omit<React.InputHTMLAttributes<HTMLInputElement>, 'onChange'>): React.JSX.Element;
8
- //# sourceMappingURL=DebounceInput.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"DebounceInput.d.ts","sourceRoot":"","sources":["../../src/components/DebounceInput.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,wBAAgB,cAAc,CAAC,EAC7B,KAAK,EAAE,YAAY,EACnB,KAAK,EACL,QAAQ,EACR,QAAY,GACb,EAAE;IACD,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,KAAK,IAAI,CAAC;IAC3C,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,GAAG,IAAI,CAAC,KAAK,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,EAAE,UAAU,CAAC,qBAkEhE"}
@@ -1,41 +0,0 @@
1
- import { Box, Button, TextField } from '@mui/material';
2
- import CancelPresentationRounded from '@mui/icons-material/CancelPresentationRounded';
3
- import React from 'react';
4
- // import { Message } from '../../../../common/commands';
5
- export function DebouncedInput({ value: initialValue, title, onChange, debounce = 0, }) {
6
- const [value, setValue] = React.useState(initialValue);
7
- React.useEffect(() => {
8
- console.log(`DebounceInput.clearTextField`);
9
- // window.electron.ipcRenderer.on(
10
- // Message.CommandDBBrandClearFilter,
11
- // (_event: unknown, _data: string) => {
12
- // clearTextField();
13
- // }
14
- // );
15
- }, []);
16
- React.useEffect(() => {
17
- setValue(initialValue);
18
- }, [initialValue]);
19
- React.useEffect(() => {
20
- const timeout = setTimeout(() => {
21
- onChange(value);
22
- }, debounce);
23
- return () => clearTimeout(timeout);
24
- }, [value]);
25
- function clearTextField() {
26
- setValue('');
27
- }
28
- return (React.createElement("div", null,
29
- React.createElement(Box, { sx: { display: 'flex', alignItems: 'flex-end' } },
30
- React.createElement(Button, { "data-testid": `button.clear-${title}`, style: {
31
- height: '100%',
32
- display: 'flex',
33
- alignItems: 'center',
34
- marginLeft: '8px',
35
- }, onClick: clearTextField },
36
- React.createElement(CancelPresentationRounded, null)),
37
- React.createElement(TextField, { id: "input-with-sx", label: title, variant: "standard", value: value, onChange: (e) => {
38
- console.log(e.target.value);
39
- setValue(e.target.value);
40
- }, sx: { width: '100px' } }))));
41
- }
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=ItemFilter.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ItemFilter.test.d.ts","sourceRoot":"","sources":["../../src/components/ItemFilter.test.tsx"],"names":[],"mappings":""}
@@ -1,41 +0,0 @@
1
- import { render, fireEvent } from '@testing-library/react';
2
- import { describe, it, expect, vi } from 'vitest';
3
- import ItemFilter from './ItemFilter';
4
- import React from 'react';
5
- describe('ItemFilter', () => {
6
- it('should clear the filter when clearFilter is called', () => {
7
- const setFilterMock = vi.fn();
8
- const itemFilter = {
9
- filter: 'test',
10
- setFilter: setFilterMock,
11
- placeholder: 'Filter Items',
12
- property: 'name',
13
- filterMatches: vi.fn(),
14
- };
15
- const { getByPlaceholderText, getByRole } = render(React.createElement(ItemFilter, { itemFilter: itemFilter }));
16
- const input = getByPlaceholderText('Filter Items');
17
- const button = getByRole('button');
18
- // Ensure the input has the initial filter value
19
- expect(input.value).toBe('test');
20
- // Click the clear button
21
- fireEvent.click(button);
22
- // Ensure the setFilter function was called with an empty string
23
- expect(setFilterMock).toHaveBeenCalledWith('');
24
- });
25
- it('should update the filter when handleInputChange is called', () => {
26
- const setFilterMock = vi.fn();
27
- const itemFilter = {
28
- filter: '',
29
- setFilter: setFilterMock,
30
- placeholder: 'Filter Items',
31
- property: 'name',
32
- filterMatches: vi.fn(),
33
- };
34
- const { getByPlaceholderText } = render(React.createElement(ItemFilter, { itemFilter: itemFilter }));
35
- const input = getByPlaceholderText('Filter Items');
36
- // Simulate typing in the input field
37
- fireEvent.change(input, { target: { value: 'new filter' } });
38
- // Ensure the setFilter function was called with the new value
39
- expect(setFilterMock).toHaveBeenCalledWith('new filter');
40
- });
41
- });
@@ -1,2 +0,0 @@
1
- import '@testing-library/jest-dom';
2
- //# sourceMappingURL=ItemList.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ItemList.test.d.ts","sourceRoot":"","sources":["../../src/components/ItemList.test.tsx"],"names":[],"mappings":"AACA,OAAO,2BAA2B,CAAC"}
@@ -1,74 +0,0 @@
1
- import { render, screen, fireEvent } from '@testing-library/react';
2
- import '@testing-library/jest-dom';
3
- import { describe, expect, it, vi } from 'vitest';
4
- import { createColumnHelper } from '@tanstack/react-table';
5
- import React from 'react';
6
- import ItemList from './ItemList';
7
- describe('ItemList', () => {
8
- const itemList = [
9
- { name: 'Item 1' },
10
- { name: 'Item 2' },
11
- { name: 'Item 3' },
12
- ];
13
- const filterMatches = (item, filter) => item.name.includes(filter);
14
- // const filterEvent = vi.fn()
15
- const renderItem = (item) => React.createElement("span", null, item);
16
- const clickFunc = vi.fn();
17
- const itemFilter = {
18
- filter: 'Item',
19
- setFilter: vi.fn(),
20
- property: 'name',
21
- filterMatches,
22
- placeholder: 'Filter Items',
23
- };
24
- it('renders the item list', () => {
25
- render(React.createElement(ItemList, { itemList: itemList }));
26
- itemList.forEach((item) => {
27
- expect(screen.getByText(item.name)).toBeInTheDocument();
28
- });
29
- });
30
- it('filters the item list based on filterMatches', () => {
31
- render(React.createElement(ItemList, { itemList: itemList, itemFilter: itemFilter }));
32
- expect(screen.getByText('Item 1')).toBeInTheDocument();
33
- expect(screen.getByText('Item 2')).toBeInTheDocument();
34
- expect(screen.getByText('Item 3')).toBeInTheDocument();
35
- });
36
- // it('calls filterEvent when filter is applied', () => {
37
- // render(<ItemList itemList={itemList} filterEvent={filterEvent} itemFilter={itemFilter} />)
38
- // expect(filterEvent).toHaveBeenCalledWith(itemList)
39
- // })
40
- it('renders custom item using renderItem', () => {
41
- render(React.createElement(ItemList, { itemList: itemList, renderItem: renderItem }));
42
- itemList.forEach((item) => {
43
- expect(screen.getByText(item.name)).toBeInTheDocument();
44
- });
45
- });
46
- it('calls clickFunc with the correct cell when an item is clicked', () => {
47
- render(React.createElement(ItemList, { itemList: itemList, clickFunc: clickFunc }));
48
- const itemButton = screen.getByText('Item 1').closest('button');
49
- fireEvent.click(itemButton);
50
- expect(clickFunc).toHaveBeenCalled();
51
- expect(clickFunc.mock.calls[0][0].getValue()).toBe('Item 1');
52
- });
53
- });
54
- describe('ItemList - createColumnHelper', () => {
55
- it('creates columns correctly', () => {
56
- const columnHelper = createColumnHelper();
57
- const columns = [
58
- columnHelper.accessor('name', {
59
- header: 'Name',
60
- cell: (info) => React.createElement("span", null, info.getValue()),
61
- }),
62
- columnHelper.accessor('age', {
63
- header: 'Age',
64
- cell: (info) => React.createElement("span", null, info.getValue()),
65
- }),
66
- ];
67
- expect(columns).toHaveLength(2);
68
- expect(columns[0].accessorKey).toBe('name');
69
- expect(columns[0].header).toBe('Name');
70
- expect(typeof columns[0].cell).toBe('function');
71
- expect(columns[1].header).toBe('Age');
72
- expect(typeof columns[1].cell).toBe('function');
73
- });
74
- });