frame.select 1.2.1 → 1.2.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;AAGnB,OAAO,KAAK,MAAM,OAAO,CAAC;AAU1B,iBAAS,GAAG,sBAuMX;AAED,eAAe,GAAG,CAAC"}
1
+ {"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../src/App.tsx"],"names":[],"mappings":"AACA,OAAO,WAAW,CAAC;AAGnB,OAAO,KAAK,MAAM,OAAO,CAAC;AAU1B,iBAAS,GAAG,sBAwMX;AAED,eAAe,GAAG,CAAC"}
package/dist/App.js CHANGED
@@ -6,6 +6,8 @@ import { BrandList } from './components/BrandList';
6
6
  import { FrameList } from './components/FrameList';
7
7
  function App() {
8
8
  const [brand, setBrand] = useState('');
9
+ const [filterWidth, setFilterWidth] = useState('');
10
+ const [filterHeight, setFilterHeight] = useState('');
9
11
  const brands = [
10
12
  {
11
13
  name: 'Adidas',
@@ -38,16 +40,27 @@ function App() {
38
40
  // item: ['Under Armour'],
39
41
  },
40
42
  {
41
- name: 'New Balance',
43
+ name: 'Alpina',
42
44
  id: 6,
43
- description: 'Description of New Balance',
44
- // item: ['New Balance'],
45
+ description: 'Description of Alpina',
45
46
  },
46
47
  {
47
48
  name: 'Brooks',
48
49
  id: 6,
49
50
  description: 'Description of Brooks',
50
51
  },
52
+ {
53
+ name: 'Brand 1',
54
+ id: 7,
55
+ },
56
+ {
57
+ name: 'Brand 2',
58
+ id: 8,
59
+ },
60
+ {
61
+ name: 'Brand 3',
62
+ id: 9,
63
+ },
51
64
  ];
52
65
  const framesAdidas = [
53
66
  'ADI0000000000000000014362150000',
@@ -70,8 +83,18 @@ function App() {
70
83
  'ADI000000000000000TODDC50190012',
71
84
  ];
72
85
  const frameNike = [
73
- 'NIK0000000000000000030362150000',
74
- 'NIK0000000000000000031362150000',
86
+ 'AFF000000000000000TMA4750190000',
87
+ 'AFF000000000000000TMA4948190000',
88
+ 'AFF000000000000000TMA5046180000',
89
+ 'AFF00000000000000AOE18036160000',
90
+ 'AFF00000000000000AOE18038160000',
91
+ 'AFF00000000000000AOE19043180000',
92
+ 'AFF000000000000000TMA4750190000',
93
+ 'AFF000000000000000TMA4948190000',
94
+ 'AFF000000000000000TMA5046180000',
95
+ 'AFF00000000000000AOE18036160000',
96
+ 'AFF00000000000000AOE18038160000',
97
+ 'AFF00000000000000AOE19043180000',
75
98
  ];
76
99
  const framePuma = [
77
100
  'PUM000000000000000PUMA162150000',
@@ -85,9 +108,9 @@ function App() {
85
108
  'UND000000000000000UARMR62150000',
86
109
  'UND000000000000000UNDER62150000',
87
110
  ];
88
- const frameNewBalance = [
89
- 'NEW000000000000000NEWBL62150000',
90
- 'NEW000000000000000NWBLC62150000',
111
+ const frameAlpina = [
112
+ 'ALP0000000000000000843471100000',
113
+ 'ALP000000000008434-KURZ69100000',
91
114
  ];
92
115
  const frameBrooks = [
93
116
  'BRO000000000000000BROOK62150000',
@@ -99,7 +122,7 @@ function App() {
99
122
  { brand: 'Puma', frames: framePuma },
100
123
  { brand: 'Reebok', frames: frameReebok },
101
124
  { brand: 'Under Armour', frames: frameUnderArmour },
102
- { brand: 'New Balance', frames: frameNewBalance },
125
+ { brand: 'Alpina', frames: frameAlpina },
103
126
  { brand: 'Brooks', frames: frameBrooks },
104
127
  ];
105
128
  function convertFrames(brand, frameArray) {
@@ -107,51 +130,30 @@ function App() {
107
130
  if (!foundFrames) {
108
131
  return [];
109
132
  }
133
+ const stripLeadingZeros = (s) => s.replace(/^0+/, '');
134
+ const stripOrZero = (s) => stripLeadingZeros(s) || '0';
110
135
  return foundFrames.frames.map((frame) => ({
111
136
  frame,
112
- name: frame.substring(18, 23),
113
- height: frame.substring(23, 25),
114
- width: frame.substring(25, 27),
115
- rest: frame.substring(27),
137
+ name: stripLeadingZeros(frame.substring(3, 23)),
138
+ sl: stripOrZero(frame.substring(23, 25)),
139
+ bw: stripOrZero(frame.substring(25, 27)),
140
+ rest: stripLeadingZeros(frame.substring(28, 33)),
116
141
  }));
117
142
  }
118
143
  const brandColumnHelper = createColumnHelper();
119
144
  const brandColumns = [
120
- brandColumnHelper.accessor((row) => row.description, {
145
+ brandColumnHelper.accessor((row) => row.description ?? '', {
121
146
  header: 'description',
122
- size: 100,
147
+ size: 300,
123
148
  cell: (info) => React.createElement("div", null, info.getValue()),
124
149
  }),
125
150
  ];
126
- const extraBrandColumns = [
151
+ const _extraBrandColumns = [
127
152
  {
128
153
  column: brandColumns[0],
129
154
  },
130
155
  ];
131
- const frameColumnHelper = createColumnHelper();
132
- const frameColumns = [
133
- frameColumnHelper.accessor((row) => row.height.toString(), {
134
- header: 'height',
135
- size: 120,
136
- cell: (info) => React.createElement("div", null, info.getValue()),
137
- }),
138
- frameColumnHelper.accessor((row) => row.width.toString(), {
139
- // Convert to string
140
- header: 'width',
141
- size: 20,
142
- cell: (info) => React.createElement("div", null, info.getValue()),
143
- }),
144
- ];
145
- const extraFrameColumns = [
146
- {
147
- column: frameColumns[0],
148
- },
149
- {
150
- column: frameColumns[1],
151
- },
152
- ];
153
156
  const onClickBrand = (cell) => {
154
- console.log(`cell: ${JSON.stringify(cell.row.original, null, 2)}`);
155
157
  const brand = brands.find((b) => b.name === cell.row.original.name);
156
158
  if (brand) {
157
159
  setBrand(brand.name);
@@ -162,10 +164,12 @@ function App() {
162
164
  };
163
165
  return (React.createElement(React.Fragment, null,
164
166
  React.createElement("h1", null, "Brand List"),
165
- React.createElement(BrandList, { brandList: brands, onClick: onClickBrand,
166
- // renderItem={renderItem}
167
- extraColumns: extraBrandColumns }),
168
- React.createElement("h2", null, "Frame List"),
169
- React.createElement(FrameList, { frameList: convertFrames(brand, frames), onClick: onClickFrame, extraColumns: extraFrameColumns, style: { border: '1px solid black', padding: '10px' } })));
167
+ React.createElement(BrandList, { brandList: brands, onClick: onClickBrand }),
168
+ React.createElement("h2", null,
169
+ "Frame List for ",
170
+ brand),
171
+ React.createElement(FrameList, { frameList: convertFrames(brand, frames), onClick: onClickFrame,
172
+ // extraColumns={extraFrameColumns}
173
+ style: { border: '1px solid black', padding: '10px' } })));
170
174
  }
171
175
  export default App;
@@ -8,6 +8,7 @@ export declare function BrandList(props: {
8
8
  onClick?: (cell: Cell<TBrandObj, unknown>, index: number) => void;
9
9
  renderItem?: (item: string) => React.ReactNode;
10
10
  extraColumns?: TColumn<TBrandObj>[];
11
+ backgroundColor?: string;
11
12
  style?: React.CSSProperties;
12
13
  }): JSX.Element;
13
14
  //# sourceMappingURL=BrandList.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"BrandList.d.ts","sourceRoot":"","sources":["../../src/components/BrandList.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACtC,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAC5B,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAGpC,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,CAcd"}
1
+ {"version":3,"file":"BrandList.d.ts","sourceRoot":"","sources":["../../src/components/BrandList.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACtC,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAC5B,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAGpC,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,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;CAC7B,GAAG,GAAG,CAAC,OAAO,CAed"}
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
2
  import { ItemList } from './ItemList';
3
3
  export function BrandList(props) {
4
- return (React.createElement(ItemList, { itemList: props.brandList, onClick: props.onClick, renderItem: props.renderItem, extraColumns: props.extraColumns, style: props.style, backgroundColor: "yellow", scrollbarWidth: 50, height: 300, placeholder: "Brands" }));
4
+ return (React.createElement(ItemList, { itemList: props.brandList, onClick: props.onClick, renderItem: props.renderItem, extraColumns: props.extraColumns, style: props.style, backgroundColor: props.backgroundColor, scrollbarWidth: 50, height: 300, placeholder: "Brands", defaultHeader: "Brand" }));
5
5
  }
@@ -1 +1 @@
1
- {"version":3,"file":"FrameList.d.ts","sourceRoot":"","sources":["../../src/components/FrameList.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACtC,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAC5B,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAGpC,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,CAcd"}
1
+ {"version":3,"file":"FrameList.d.ts","sourceRoot":"","sources":["../../src/components/FrameList.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAsB,MAAM,uBAAuB,CAAC;AACjE,OAAO,EAAE,OAAO,EAAS,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,GAAG,EAAY,MAAM,OAAO,CAAC;AACtC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAIL,SAAS,EACV,MAAM,SAAS,CAAC;AAGjB,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,CAuGd"}
@@ -1,5 +1,86 @@
1
+ import { createColumnHelper } from '@tanstack/react-table';
2
+ import { useState } from 'react';
1
3
  import React from 'react';
4
+ import { brueckenWeiteKey, scheibenFormKey, scheibenLaengeKey, } from './types';
2
5
  import { ItemList } from './ItemList';
3
6
  export function FrameList(props) {
4
- return (React.createElement(ItemList, { itemList: props.frameList, onClick: props.onClick, renderItem: props.renderItem, extraColumns: props.extraColumns, style: props.style }));
7
+ const [filterWidth, setFilterWidth] = useState('');
8
+ const [filterHeight, setFilterHeight] = useState('');
9
+ const [filterForm, setFilterForm] = useState('');
10
+ const filterMatches = (item, property, filter) => {
11
+ const frame = item;
12
+ const value = frame[property];
13
+ if (typeof value === 'string') {
14
+ return value.toLowerCase().includes(filter.toLowerCase());
15
+ }
16
+ if (typeof value === 'number') {
17
+ return String(value).includes(filter);
18
+ }
19
+ // Handle other types (boolean, etc.)
20
+ return String(value).toLowerCase().includes(filter.toLowerCase());
21
+ };
22
+ function filterWidthMatches(item, filter) {
23
+ return filterMatches(item, brueckenWeiteKey, filter);
24
+ }
25
+ function filterHeightMatches(item, filter) {
26
+ return filterMatches(item, scheibenLaengeKey, filter);
27
+ }
28
+ function filterFormMatches(item, filter) {
29
+ return filterMatches(item, scheibenFormKey, filter);
30
+ }
31
+ const frameColumnHelper = createColumnHelper();
32
+ const frameColumns = [
33
+ frameColumnHelper.accessor((row) => row[scheibenLaengeKey].toString(), {
34
+ header: scheibenLaengeKey,
35
+ size: 120,
36
+ cell: (info) => React.createElement("div", null, info.getValue()),
37
+ }),
38
+ frameColumnHelper.accessor((row) => row[brueckenWeiteKey].toString(), {
39
+ header: brueckenWeiteKey,
40
+ size: 120,
41
+ cell: (info) => React.createElement("div", null, info.getValue()),
42
+ }),
43
+ frameColumnHelper.accessor((row) => row[scheibenFormKey].toString(), {
44
+ header: scheibenFormKey,
45
+ size: 120,
46
+ cell: (info) => React.createElement("div", null, info.getValue()),
47
+ }),
48
+ ];
49
+ const extraFrameColumns = [
50
+ {
51
+ column: frameColumns[0],
52
+ filter: {
53
+ property: scheibenLaengeKey,
54
+ filter: filterHeight,
55
+ setFilter: setFilterHeight,
56
+ filterMatches: filterHeightMatches,
57
+ placeholder: 'Scheibenlänge',
58
+ },
59
+ },
60
+ {
61
+ column: frameColumns[1],
62
+ filter: {
63
+ property: brueckenWeiteKey,
64
+ filter: filterWidth,
65
+ setFilter: setFilterWidth,
66
+ filterMatches: filterWidthMatches,
67
+ placeholder: 'Brückenweite',
68
+ },
69
+ },
70
+ {
71
+ column: frameColumns[2],
72
+ filter: {
73
+ property: scheibenFormKey,
74
+ filter: filterForm,
75
+ setFilter: setFilterForm,
76
+ filterMatches: filterFormMatches,
77
+ placeholder: 'Scheibenform',
78
+ },
79
+ },
80
+ ];
81
+ return (React.createElement(ItemList, { itemList: props.frameList, onClick: props.onClick, renderItem: props.renderItem, extraColumns: props.extraColumns ? props.extraColumns : extraFrameColumns, style: props.style,
82
+ // backgroundColor="lightgreen"
83
+ // scrollbarWidth={100}
84
+ // height={400}
85
+ placeholder: "Modellnummer", defaultHeader: "Frame" }));
5
86
  }
@@ -1,6 +1,8 @@
1
1
  import { TItem, TItemFilter } from './itemTypes';
2
2
  import React from 'react';
3
3
  interface ItemFilterProps {
4
+ tableId: string;
5
+ id: string;
4
6
  itemFilter: TItemFilter<TItem>;
5
7
  }
6
8
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"ItemFilter.d.ts","sourceRoot":"","sources":["../../src/components/ItemFilter.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,UAAU,eAAe;IACvB,UAAU,EAAE,WAAW,CAAC,KAAK,CAAC,CAAC;CAChC;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,QAAA,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CAgCzC,CAAC;AAEF,eAAe,UAAU,CAAC"}
1
+ {"version":3,"file":"ItemFilter.d.ts","sourceRoot":"","sources":["../../src/components/ItemFilter.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,UAAU,eAAe;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,WAAW,CAAC,KAAK,CAAC,CAAC;CAChC;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,QAAA,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CAqCzC,CAAC;AAEF,eAAe,UAAU,CAAC"}
@@ -32,8 +32,8 @@ const ItemFilter = (props) => {
32
32
  props.itemFilter.setFilter('');
33
33
  }
34
34
  return (React.createElement("div", { style: { display: 'flex', alignItems: 'center' } },
35
- React.createElement("input", { type: "text", placeholder: props.itemFilter.placeholder ?? 'Items', value: props.itemFilter.filter || '', onChange: handleInputChange, style: { width: '80%' } }),
36
- props.itemFilter.filter !== '' ? (React.createElement(Button, { style: { minWidth: 'unset', padding: '1px' }, onClick: clearFilter },
35
+ React.createElement("input", { id: props.id, "data-testid": `input.filter.${props.id}`, type: "text", placeholder: props.itemFilter.placeholder ?? 'Items', value: props.itemFilter.filter || '', onChange: handleInputChange, style: { width: '80%' } }),
36
+ props.itemFilter.filter !== '' ? (React.createElement(Button, { "data-testid": `${props.tableId}.button.clearFilter.${props.id}`, style: { minWidth: 'unset', padding: '1px' }, onClick: clearFilter },
37
37
  React.createElement(CancelPresentationIcon, null))) : (React.createElement("div", null))));
38
38
  };
39
39
  export default ItemFilter;
@@ -2,7 +2,7 @@ import { Cell } from '@tanstack/react-table';
2
2
  import { TColumn, TItem } from './itemTypes';
3
3
  import { JSX } from 'react';
4
4
  import React from 'react';
5
- export interface ItemListProps<T extends TItem> {
5
+ export declare function ItemList<T extends TItem>(props: {
6
6
  itemList: T[];
7
7
  onClick?: (cell: Cell<T, unknown>, index: number) => void;
8
8
  renderItem?: (item: string) => React.ReactNode;
@@ -12,6 +12,6 @@ export interface ItemListProps<T extends TItem> {
12
12
  scrollbarWidth?: number;
13
13
  height?: number | string;
14
14
  placeholder?: string;
15
- }
16
- export declare function ItemList<T extends TItem>(props: ItemListProps<T>): JSX.Element;
15
+ defaultHeader?: string;
16
+ }): JSX.Element;
17
17
  //# sourceMappingURL=ItemList.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ItemList.d.ts","sourceRoot":"","sources":["../../src/components/ItemList.tsx"],"names":[],"mappings":"AASA,OAAO,EAIL,IAAI,EAKL,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAe,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAC1D,OAAO,EAAE,GAAG,EAA6C,MAAM,OAAO,CAAC;AACvE,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,WAAW,aAAa,CAAC,CAAC,SAAS,KAAK;IAC5C,QAAQ,EAAE,CAAC,EAAE,CAAC;IACd,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1D,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,KAAK,CAAC,SAAS,CAAC;IAC/C,YAAY,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;IAC5B,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,QAAQ,CAAC,CAAC,SAAS,KAAK,EACtC,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,GACtB,GAAG,CAAC,OAAO,CA4Qb"}
1
+ {"version":3,"file":"ItemList.d.ts","sourceRoot":"","sources":["../../src/components/ItemList.tsx"],"names":[],"mappings":"AAUA,OAAO,EAIL,IAAI,EAKL,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAe,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAC1D,OAAO,EAAE,GAAG,EAA6C,MAAM,OAAO,CAAC;AACvE,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,wBAAgB,QAAQ,CAAC,CAAC,SAAS,KAAK,EAAE,KAAK,EAAE;IAC/C,QAAQ,EAAE,CAAC,EAAE,CAAC;IACd,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1D,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,KAAK,CAAC,SAAS,CAAC;IAC/C,YAAY,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;IAC5B,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,GAAG,GAAG,CAAC,OAAO,CA+Yd"}
@@ -1,11 +1,11 @@
1
- import { TableContainer, Table, TableHead, TableRow, TableCell, TableBody, Button, } from '@mui/material';
1
+ import { TableContainer, Table, TableHead, TableRow, TableCell, TableBody, Button, Box, } from '@mui/material';
2
2
  import { useReactTable, getCoreRowModel, getFilteredRowModel, createColumnHelper, flexRender, } from '@tanstack/react-table';
3
3
  import ItemFilter from './ItemFilter';
4
4
  import { useMemo, useState, useCallback } from 'react';
5
5
  import React from 'react';
6
6
  export function ItemList(props) {
7
7
  'use no memo'; // For React Compiler compatibility with TanStack Table
8
- const { itemList, backgroundColor = 'lightgrey', scrollbarWidth = 50, height = 300, placeholder = 'Items', } = props;
8
+ const { itemList, backgroundColor = 'lightgrey', scrollbarWidth = 50, height = 300, placeholder = 'Items', defaultHeader = 'Name', } = props;
9
9
  const scrollbarStyles = {
10
10
  '&::-webkit-scrollbar': {
11
11
  width: `${scrollbarWidth}px`,
@@ -67,16 +67,15 @@ export function ItemList(props) {
67
67
  return filteredList;
68
68
  }, [itemFilter, itemList, extraCols]);
69
69
  /****************************************************************************/
70
- const defaultHeader = 'Name';
71
70
  const columnHelper = createColumnHelper();
72
71
  const defaultColumns = [
73
72
  columnHelper.accessor((row) => row.name, {
74
73
  header: defaultHeader,
75
74
  cell: (info) => (React.createElement("div", { style: { fontWeight: 'bold' } }, info.getValue())),
76
75
  footer: (info) => info.column.id,
77
- size: 150,
78
- minSize: 100,
79
- maxSize: 300,
76
+ size: 130,
77
+ minSize: 130,
78
+ maxSize: 130,
80
79
  }),
81
80
  ];
82
81
  const columns = [...defaultColumns];
@@ -93,19 +92,34 @@ export function ItemList(props) {
93
92
  console.log(`Clicked item index: ${index}`);
94
93
  }
95
94
  }, [props]);
95
+ const cellWidth = useCallback((extraCol) => {
96
+ const clearButtonWidth = extraCol?.filter ? 20 : 0;
97
+ const baseWidth = (extraCol?.column.size || 100) + clearButtonWidth;
98
+ return baseWidth;
99
+ }, []);
96
100
  function displayHeader(header) {
97
101
  let filter = React.createElement("div", null);
98
102
  if (header.id === defaultHeader) {
99
103
  if (itemFilter) {
100
- filter = (React.createElement("div", { style: { width: '100%' } },
101
- React.createElement(ItemFilter, { itemFilter: itemFilter })));
104
+ filter = (React.createElement("div", { style: {
105
+ width: '130px',
106
+ maxWidth: '130px',
107
+ overflow: 'hidden',
108
+ boxSizing: 'border-box',
109
+ } },
110
+ React.createElement(ItemFilter, { tableId: defaultHeader, id: defaultHeader, itemFilter: itemFilter })));
102
111
  }
103
112
  }
104
113
  else {
105
114
  extraCols.forEach((col) => {
106
115
  if (col && header.id === col.column.header) {
107
- filter = col.filter ? (React.createElement("div", { style: { width: '100%' } },
108
- React.createElement(ItemFilter, { itemFilter: col.filter }))) : (React.createElement("div", null));
116
+ filter = col.filter ? (React.createElement("div", { style: {
117
+ width: '120px',
118
+ maxWidth: '120px',
119
+ overflow: 'hidden',
120
+ boxSizing: 'border-box',
121
+ } },
122
+ React.createElement(ItemFilter, { tableId: header.id, id: col.column.header, itemFilter: col.filter }))) : (React.createElement("div", null));
109
123
  }
110
124
  });
111
125
  }
@@ -117,61 +131,145 @@ export function ItemList(props) {
117
131
  getCoreRowModel: getCoreRowModel(),
118
132
  getFilteredRowModel: getFilteredRowModel(),
119
133
  columnResizeMode: 'onChange',
120
- enableColumnResizing: true,
134
+ enableColumnResizing: false,
121
135
  defaultColumn: {
122
- size: 100,
123
- minSize: 50,
124
- maxSize: 500,
136
+ size: 120,
137
+ minSize: 120,
138
+ maxSize: 120,
125
139
  },
126
140
  });
127
141
  const paginatedRows = table.getRowModel().rows;
142
+ // Calculate total table width for consistent alignment
143
+ const totalTableWidth = useMemo(() => {
144
+ let width = 130; // Default header width
145
+ extraCols.forEach((col) => {
146
+ if (col && col.filter) {
147
+ width += 120; // Width for filtered extra columns
148
+ }
149
+ else if (col) {
150
+ width += 100; // Width for non-filtered extra columns
151
+ }
152
+ });
153
+ return width;
154
+ }, [extraCols]);
128
155
  const renderRows = React.useCallback((rows, bgColor = backgroundColor) => {
129
- function displayBody(cell) {
156
+ function renderItem(cell) {
157
+ const cll = cell.getValue();
158
+ return React.createElement("div", null, cll);
159
+ }
160
+ function displayBody(cell, index) {
130
161
  let cellContent = React.createElement("div", null);
131
162
  const cll = cell.getValue();
163
+ // Calculate width to match header cells exactly
164
+ let baseWidth;
132
165
  if (cell.column.columnDef.header === defaultHeader) {
133
- cellContent = (React.createElement(TableCell, { style: { backgroundColor: bgColor, padding: 2 }, key: cell.id },
166
+ baseWidth = 160;
167
+ }
168
+ else {
169
+ // Check if this extra column has a filter
170
+ const extraCol = extraCols.find((col) => col && cell.column.columnDef.header === col.column.header);
171
+ baseWidth = cellWidth(extraCol);
172
+ }
173
+ const minWidth = baseWidth;
174
+ const maxWidth = baseWidth;
175
+ if (cell.column.columnDef.header === defaultHeader) {
176
+ cellContent = (React.createElement(TableCell, { "data-testid": `${defaultHeader}.tb.${index}`, style: { backgroundColor: bgColor }, sx: {
177
+ borderRight: '1px solid #999',
178
+ paddingLeft: '16px',
179
+ paddingRight: 0,
180
+ paddingTop: 0,
181
+ paddingBottom: 0,
182
+ width: baseWidth,
183
+ minWidth: minWidth,
184
+ maxWidth: maxWidth,
185
+ boxSizing: 'border-box',
186
+ }, key: cell.id },
134
187
  React.createElement(Button, { onClick: onClick(cell, cell.row.index) }, props.renderItem
135
188
  ? props.renderItem(cll)
136
189
  : flexRender(cell.column.columnDef.cell, cell.getContext()))));
137
190
  }
138
191
  else {
139
- cellContent = (React.createElement(TableCell, { style: { backgroundColor: bgColor, padding: 2 }, key: cell.id }, props.renderItem ? props.renderItem(cll) : React.createElement("div", null, cll)));
192
+ cellContent = (React.createElement(TableCell, { "data-testid": `${defaultHeader}.tb.${index}`, style: { backgroundColor: bgColor }, sx: {
193
+ borderRight: '1px solid #999',
194
+ paddingLeft: '16px',
195
+ paddingRight: 0,
196
+ paddingTop: 0,
197
+ paddingBottom: 0,
198
+ width: baseWidth,
199
+ minWidth: minWidth,
200
+ maxWidth: maxWidth,
201
+ boxSizing: 'border-box',
202
+ }, key: cell.id }, props.renderItem ? props.renderItem(cll) : renderItem(cell)));
140
203
  }
141
204
  return cellContent;
142
205
  }
143
- return rows.map((row) => (React.createElement(TableRow, { key: row.id }, row.getVisibleCells().map((cell) => {
144
- return displayBody(cell);
206
+ return rows.map((row, index) => (React.createElement(TableRow, { "data-testid": `${defaultHeader}.tb.row.${index}`, key: row.id }, row.getVisibleCells().map((cell) => {
207
+ return displayBody(cell, index);
145
208
  }))));
146
- }, [backgroundColor, onClick, props]);
147
- return (React.createElement("div", { style: {
209
+ }, [backgroundColor, cellWidth, defaultHeader, extraCols, onClick, props]);
210
+ return (React.createElement("div", { "data-testid": `${defaultHeader}.table`, style: {
148
211
  height,
149
212
  overflow: 'hidden',
150
213
  backgroundColor,
151
- width: '100%',
214
+ width: 'fit-content',
152
215
  minWidth: 200,
153
216
  boxSizing: 'border-box',
217
+ display: 'flex',
218
+ flexDirection: 'column',
154
219
  } },
155
- React.createElement(TableContainer, { "data-testid": "item-list-TableContainer", style: {
156
- height,
220
+ React.createElement(TableContainer, { "data-testid": `${defaultHeader}.tableContainer`, style: {
157
221
  minWidth: 200,
158
- overflow: 'auto',
159
222
  backgroundColor,
160
- width: '100%',
223
+ width: 'fit-content',
161
224
  boxSizing: 'border-box',
225
+ overflow: 'visible',
162
226
  ...props.style,
163
- }, sx: scrollbarStyles },
227
+ } },
164
228
  React.createElement(Table, { stickyHeader: true, "aria-label": "sticky table", sx: {
165
229
  backgroundColor,
166
- width: '100%',
167
- minWidth: 200,
230
+ width: `${totalTableWidth}px`,
231
+ tableLayout: 'fixed',
232
+ borderCollapse: 'separate',
233
+ borderSpacing: 0,
234
+ } },
235
+ React.createElement(TableHead, { "data-testid": `${defaultHeader}.tableHeader`, sx: { backgroundColor } }, table.getHeaderGroups().map((headerGroup) => (React.createElement(TableRow, { key: headerGroup.id }, headerGroup.headers.map((header) => {
236
+ // Calculate width accounting for ItemFilter with CancelPresentationIcon
237
+ let baseWidth;
238
+ if (header.id === defaultHeader) {
239
+ baseWidth = 150;
240
+ }
241
+ else {
242
+ // Check if this extra column has a filter
243
+ const extraCol = extraCols.find((col) => col && header.id === col.column.header);
244
+ baseWidth = cellWidth(extraCol);
245
+ }
246
+ const minWidth = baseWidth;
247
+ const maxWidth = baseWidth;
248
+ return (React.createElement(TableCell, { "data-testid": `${defaultHeader}.th.cell.${header.id}`, key: header.id, sx: {
249
+ backgroundColor,
250
+ width: baseWidth,
251
+ minWidth: minWidth,
252
+ maxWidth: maxWidth,
253
+ borderRight: '1px solid #999',
254
+ paddingLeft: '16px',
255
+ paddingRight: 0,
256
+ paddingTop: 0,
257
+ paddingBottom: 0,
258
+ boxSizing: 'border-box',
259
+ } }, displayHeader(header)));
260
+ }))))))),
261
+ React.createElement(Box, { sx: {
262
+ flex: 1,
263
+ overflow: 'auto',
264
+ backgroundColor,
265
+ ...scrollbarStyles,
266
+ } },
267
+ React.createElement(Table, { sx: {
268
+ backgroundColor,
269
+ width: `${totalTableWidth}px`,
168
270
  tableLayout: 'fixed',
271
+ borderCollapse: 'separate',
272
+ borderSpacing: 0,
169
273
  } },
170
- React.createElement(TableHead, { sx: { backgroundColor } }, table.getHeaderGroups().map((headerGroup) => (React.createElement(TableRow, { key: headerGroup.id, "data-testid": headerGroup.id }, headerGroup.headers.map((header) => (React.createElement(TableCell, { key: header.id, sx: {
171
- backgroundColor,
172
- width: header.id === defaultHeader ? 150 : 'auto',
173
- minWidth: header.id === defaultHeader ? 100 : 50,
174
- maxWidth: header.id === defaultHeader ? 300 : 'none',
175
- } }, displayHeader(header)))))))),
176
274
  React.createElement(TableBody, { "data-testid": "table.list-of-items", sx: { backgroundColor } }, renderRows(paginatedRows, backgroundColor))))));
177
275
  }
@@ -1,13 +1,16 @@
1
1
  export type TBrandObj = {
2
2
  name: string;
3
3
  id: number;
4
- description: string;
4
+ description?: string;
5
5
  };
6
6
  export type TFrameObj = {
7
7
  frame: string;
8
8
  name: string;
9
- width: string;
10
- height: string;
9
+ bw: string;
10
+ sl: string;
11
11
  rest: string;
12
12
  };
13
+ export declare const brueckenWeiteKey = "bw";
14
+ export declare const scheibenLaengeKey = "sl";
15
+ export declare const scheibenFormKey = "rest";
13
16
  //# 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;AACF,MAAM,MAAM,SAAS,GAAG;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd,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,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AACF,MAAM,MAAM,SAAS,GAAG;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,eAAO,MAAM,gBAAgB,OAAO,CAAC;AACrC,eAAO,MAAM,iBAAiB,OAAO,CAAC;AACtC,eAAO,MAAM,eAAe,SAAS,CAAC"}
@@ -1 +1,3 @@
1
- export {};
1
+ export const brueckenWeiteKey = 'bw';
2
+ export const scheibenLaengeKey = 'sl';
3
+ export const scheibenFormKey = 'rest';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "frame.select",
3
- "version": "1.2.1",
3
+ "version": "1.2.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",
@@ -16,6 +16,9 @@
16
16
  "build-and-vite": "tsc -b && vite build",
17
17
  "lint": "eslint .",
18
18
  "test": "vitest --config vitest.config.ts",
19
+ "test:e2e": "playwright test",
20
+ "test:e2e:ui": "playwright test --ui",
21
+ "test:e2e:debug": "playwright test --debug",
19
22
  "preview": "vite preview"
20
23
  },
21
24
  "dependencies": {
@@ -30,22 +33,25 @@
30
33
  "react-dom": "^19.2.3"
31
34
  },
32
35
  "devDependencies": {
33
- "react": "^19.2.3",
34
- "react-dom": "^19.2.3",
35
36
  "@eslint/js": "^9.39.2",
37
+ "@playwright/test": "^1.57.0",
36
38
  "@testing-library/dom": "^10.4.1",
37
39
  "@testing-library/jest-dom": "^6.9.1",
38
40
  "@testing-library/react": "^16.3.1",
41
+ "@types/node": "^25.0.3",
39
42
  "@types/react": "^19.2.7",
40
43
  "@types/react-dom": "^19.2.3",
41
44
  "@vitejs/plugin-react": "^5.1.2",
42
45
  "eslint": "^9.39.2",
43
46
  "eslint-plugin-react-hooks": "^7.0.1",
44
47
  "eslint-plugin-react-refresh": "^0.4.26",
45
- "globals": "^16.5.0",
46
- "jsdom": "^27.3.0",
48
+ "globals": "^17.0.0",
49
+ "jsdom": "^27.4.0",
50
+ "playwright": "^1.57.0",
51
+ "react": "^19.2.3",
52
+ "react-dom": "^19.2.3",
47
53
  "typescript": "~5.9.3",
48
- "typescript-eslint": "^8.50.0",
54
+ "typescript-eslint": "^8.51.0",
49
55
  "vite": "^7.3.0",
50
56
  "vitest": "^4.0.16"
51
57
  }