ar-design 0.1.89 → 0.1.91

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.
@@ -33,6 +33,9 @@
33
33
  column-gap: 0.5rem;
34
34
  margin-left: auto;
35
35
  }
36
+ .ar-table > .header > div:last-child {
37
+ margin-left: auto;
38
+ }
36
39
 
37
40
  .ar-table > .footer {
38
41
  display: flex;
@@ -43,15 +46,6 @@
43
46
  border-top: solid 1px var(--gray-200);
44
47
  }
45
48
 
46
- .ar-table > .header > div:first-child > .ar-input-wrapper,
47
- .ar-table > .header > div:first-child > .ar-input-wrapper > .ar-input,
48
- .ar-table > .header > div:first-child > .ar-input-wrapper > .ar-input > input {
49
- width: auto !important;
50
- }
51
- .ar-table > .header > div:last-child {
52
- margin-left: auto;
53
- }
54
-
55
49
  .ar-table > .content > table {
56
50
  border-collapse: collapse;
57
51
  width: 100%;
@@ -87,6 +81,14 @@
87
81
  transition: background 250ms, box-shadow 250ms ease-in-out;
88
82
  z-index: 2;
89
83
  }
84
+ .ar-table > .content > table > thead > tr > th > .filter-field {
85
+ display: flex;
86
+ flex-direction: row;
87
+ justify-content: space-between;
88
+ align-items: center;
89
+ gap: 0.5rem;
90
+ min-width: 100%;
91
+ }
90
92
  .ar-table > .content > table > thead > tr > th::after {
91
93
  position: absolute;
92
94
  top: 50%;
@@ -120,24 +122,6 @@
120
122
  text-align: right;
121
123
  }
122
124
 
123
- .ar-table > .content > table > thead > tr > th > .search-input {
124
- background-color: var(--gray-200);
125
- width: 100%;
126
- height: var(--input-height);
127
- padding: 0 0.5rem;
128
- border: solid 1px var(--gray-200);
129
- border-radius: var(--border-radius-sm);
130
- font-family: var(--system);
131
- font-size: 1rem;
132
- outline: none;
133
- box-sizing: border-box;
134
- transition: background 250ms, border 250ms, box-shadow 250ms ease-in-out;
135
- }
136
- .ar-table > .content > table > thead > tr > th > .search-input:focus {
137
- border: solid 1px var(--primary);
138
- box-shadow: 0 0 0 3.5px rgba(var(--primary-rgb), 0.25);
139
- }
140
-
141
125
  .ar-table > .content > table > tbody > tr {
142
126
  border-bottom: solid 1px var(--gray-200);
143
127
  }
@@ -6,22 +6,29 @@ import Checkbox from "../../form/checkbox";
6
6
  import Pagination from "../../navigation/pagination";
7
7
  import React, { forwardRef, useCallback, useEffect, useImperativeHandle, useRef, useState } from "react";
8
8
  import Actions from "./Actions";
9
+ import Input from "../../form/input";
10
+ import Popover from "../../feedback/popover";
9
11
  const TableWithRef = forwardRef(({ children, title, description, data, columns, actions, selections, searchedParams, pagination, config = { isSearchable: false }, }, ref) => {
10
12
  // refs
11
- let _dataLength = useRef(0);
12
13
  const _tableWrapper = useRef(null);
13
14
  const _table = useRef(null);
14
15
  const _tableContent = useRef(null);
15
16
  const _checkboxItems = useRef([]);
17
+ const _filterCheckboxItems = useRef([]);
18
+ // refs -> Search
16
19
  const _searchTextInputs = useRef([]);
17
20
  const _searchTimeOut = useRef(null);
21
+ // const _searchFilterFirstLoad = useRef<boolean>(false);
18
22
  // className
19
23
  const _tableClassName = ["ar-table", "scroll"];
20
24
  // states
21
25
  const [selectAll, setSelectAll] = useState(false);
22
26
  const [selectionItems, setSelectionItems] = useState([]);
27
+ // states -> Search
23
28
  const [searchedText, setSearchedText] = useState(undefined);
24
29
  const [_searchedParams, setSearchedParams] = useState(undefined);
30
+ // const [searchedFilters, setSearchedFilters] = useState<string | undefined>(undefined);
31
+ // const [totalRecords, setTotalRecords] = useState<number>(0);
25
32
  const [currentPage, setCurrentPage] = useState(1);
26
33
  if (config && Object.keys(config.scroll || {}).length > 0) {
27
34
  if (_tableContent.current && config.scroll) {
@@ -112,6 +119,52 @@ const TableWithRef = forwardRef(({ children, title, description, data, columns,
112
119
  updateStickyPositions(tbodyElements);
113
120
  });
114
121
  };
122
+ const handleSearch = (event) => {
123
+ if (config.isServerSide) {
124
+ if (_searchTimeOut.current)
125
+ clearTimeout(_searchTimeOut.current);
126
+ _searchTimeOut.current = setTimeout(() => {
127
+ setSearchedParams((prev) => ({ ...prev, [event.target.name]: event.target.value }));
128
+ setCurrentPage(1);
129
+ pagination && pagination.onChange(1);
130
+ }, 750);
131
+ }
132
+ else {
133
+ setCurrentPage(1);
134
+ setSearchedText((prev) => ({ ...prev, [event.target.name]: event.target.value }));
135
+ }
136
+ };
137
+ const handleChecboxFilter = (event) => {
138
+ if (config.isServerSide) {
139
+ if (_searchTimeOut.current)
140
+ clearTimeout(_searchTimeOut.current);
141
+ setSearchedParams((prev) => {
142
+ const updatedValues = new Set(prev?.[event.target.name] || []);
143
+ event.target.checked ? updatedValues.add(event.target.value) : updatedValues.delete(event.target.value);
144
+ return {
145
+ ...prev,
146
+ ...(Array.from(updatedValues).length > 0
147
+ ? { [event.target.name]: Array.from(updatedValues) }
148
+ : { [event.target.name]: [] }),
149
+ };
150
+ });
151
+ setCurrentPage(1);
152
+ pagination && pagination.onChange(1);
153
+ }
154
+ else {
155
+ setSearchedText((prev) => {
156
+ const updatedValues = new Set(prev?.[event.target.name] || []);
157
+ event.target.checked ? updatedValues.add(event.target.value) : updatedValues.delete(event.target.value);
158
+ return {
159
+ ...prev,
160
+ ...(Array.from(updatedValues).length > 0
161
+ ? { [event.target.name]: Array.from(updatedValues) }
162
+ : { [event.target.name]: [] }),
163
+ };
164
+ });
165
+ setCurrentPage(1);
166
+ }
167
+ };
115
168
  // Derinlemesine arama yapmak için özyinelemeli bir fonksiyon tanımlayalım.
116
169
  const deepSearch = (item, searchedText) => {
117
170
  if (!searchedText)
@@ -120,26 +173,39 @@ const TableWithRef = forwardRef(({ children, title, description, data, columns,
120
173
  return Object.entries(searchedText).every(([key, value]) => {
121
174
  const _itemValue = item[key];
122
175
  if (typeof _itemValue === "number" || typeof _itemValue === "string") {
176
+ if (Array.isArray(value)) {
177
+ if (value.length === 0)
178
+ return true;
179
+ else
180
+ return value.some((v) => _itemValue.toString().toLocaleLowerCase().includes(v.toLocaleLowerCase()));
181
+ }
123
182
  return _itemValue.toString().toLocaleLowerCase().includes(value.toLocaleLowerCase());
124
183
  }
125
184
  if (typeof _itemValue === "object") {
185
+ if (Array.isArray(value)) {
186
+ if (value.length === 0)
187
+ return true;
188
+ else {
189
+ return value.some((v) => Object.entries(_itemValue ?? {}).some(([_, objValue]) => String(objValue).toLocaleLowerCase().includes(v.toLocaleLowerCase())));
190
+ }
191
+ }
126
192
  return Object.entries(_itemValue ?? {}).some(([_, objValue]) => String(objValue).toLocaleLowerCase().includes(value.toLocaleLowerCase()));
127
193
  }
128
194
  if (Array.isArray(_itemValue)) {
195
+ console.log("Buradasın", _itemValue);
129
196
  }
130
197
  return false;
131
198
  });
132
199
  };
133
200
  const getData = useCallback(() => {
134
201
  let _data = [...data];
135
- _dataLength.current = data.length;
202
+ if (searchedText)
203
+ _data = _data.filter((item) => deepSearch(item, searchedText));
136
204
  if (pagination && !config.isServerSide) {
137
205
  const indexOfLastRow = currentPage * pagination.perPage;
138
206
  const indexOfFirstRow = indexOfLastRow - pagination.perPage;
139
- _data = data.slice(indexOfFirstRow, indexOfLastRow);
207
+ _data = _data.slice(indexOfFirstRow, indexOfLastRow);
140
208
  }
141
- if (searchedText)
142
- _data = _data.filter((item) => deepSearch(item, searchedText));
143
209
  return _data;
144
210
  }, [data, searchedText, currentPage]);
145
211
  // useEffects
@@ -171,6 +237,7 @@ const TableWithRef = forwardRef(({ children, title, description, data, columns,
171
237
  }
172
238
  setSelectAll(allChecked);
173
239
  }, [currentPage]);
240
+ console.log(searchedText);
174
241
  return (React.createElement("div", { ref: _tableWrapper, className: _tableClassName.map((c) => c).join(" ") },
175
242
  (title || description || actions || React.Children.count(children) > 0) && (React.createElement("div", { className: "header" },
176
243
  React.createElement("div", { className: "title" },
@@ -224,32 +291,36 @@ const TableWithRef = forwardRef(({ children, title, description, data, columns,
224
291
  if (c.config?.alignContent) {
225
292
  _className.push(`align-content-${c.config.alignContent}`);
226
293
  }
227
- if (!c.key)
228
- return (React.createElement("th", { key: `column-${cIndex}`, ...(_className.length > 0 && {
229
- className: `${_className.map((c) => c).join(" ")}`,
230
- }), ...(c.config?.sticky && {
231
- "data-sticky-position": c.config.sticky,
232
- }) }));
233
294
  return (React.createElement("th", { key: `column-${cIndex}`, ...(_className.length > 0 && {
234
295
  className: `${_className.map((c) => c).join(" ")}`,
235
296
  }), ...(c.config?.sticky && {
236
297
  "data-sticky-position": c.config.sticky,
237
298
  }) },
238
- React.createElement("input", { ref: (element) => (_searchTextInputs.current[cIndex] = element), name: typeof c.key !== "object" ? String(c.key) : String(c.key.field), className: "search-input", onChange: (event) => {
239
- if (config.isServerSide) {
240
- if (_searchTimeOut.current)
241
- clearTimeout(_searchTimeOut.current);
242
- _searchTimeOut.current = setTimeout(() => {
243
- setSearchedParams((prev) => ({ ...prev, [event.target.name]: event.target.value }));
244
- setCurrentPage(1);
245
- pagination && pagination.onChange(1);
246
- }, 750);
247
- }
248
- else {
249
- setCurrentPage(1);
250
- setSearchedText((prev) => ({ ...prev, [event.target.name]: event.target.value }));
251
- }
252
- } })));
299
+ React.createElement("div", { className: "filter-field" },
300
+ React.createElement(Input, { ref: (element) => (_searchTextInputs.current[cIndex] = element), variant: c.key && !c.filters ? "filled" : "outlined", status: "light", name: typeof c.key !== "object" ? String(c.key) : String(c.key.field), onChange: handleSearch, disabled: !c.key || !!c.filters }),
301
+ c.filters && (React.createElement(Popover, { content: React.createElement(React.Fragment, null,
302
+ React.createElement("ul", null, c.filters
303
+ // .filter((x) =>
304
+ // x.text.toLocaleLowerCase().includes(searchedFilters?.toLocaleLowerCase() ?? "")
305
+ // )
306
+ .map((filter, index) => {
307
+ const name = typeof c.key !== "object" ? String(c.key) : String(c.key.field);
308
+ return (React.createElement("li", { key: index },
309
+ React.createElement(Checkbox, { ref: (element) => (_filterCheckboxItems.current[index] = element), label: filter.text, name: name, status: "success", value: filter.text, checked: config.isServerSide
310
+ ? _searchedParams && _searchedParams[name].includes(filter.text)
311
+ : searchedText && searchedText[name].includes(filter.text), onChange: handleChecboxFilter })));
312
+ }))) },
313
+ _filterCheckboxItems.current.filter((item) => item?.checked).length > 0 && (React.createElement("div", { style: {
314
+ position: "absolute",
315
+ top: "0.35rem",
316
+ right: "0.35rem",
317
+ width: "0.5rem",
318
+ height: "0.5rem",
319
+ backgroundColor: "var(--danger)",
320
+ borderRadius: "var(--border-radius-pill)",
321
+ zIndex: 1,
322
+ } })),
323
+ React.createElement(Button, { variant: "borderless", icon: { element: React.createElement(ARIcon, { icon: "Filter", stroke: "var(--primary)", size: 16 }) } }))))));
253
324
  })))),
254
325
  React.createElement("tbody", null, getData().length > 0 ? (getData().map((item, index) => (React.createElement("tr", { key: `row-${index}` },
255
326
  selections && (React.createElement("td", { key: `selection-${index}`, className: "sticky-left", "data-sticky-position": "left" },
@@ -293,20 +364,19 @@ const TableWithRef = forwardRef(({ children, title, description, data, columns,
293
364
  }))))) : (React.createElement("tr", null,
294
365
  React.createElement("td", { colSpan: columns.length + 1 }, "Herhangi bir kay\u0131t bulunamad\u0131!")))))),
295
366
  pagination && pagination.totalRecords > pagination.perPage && (React.createElement("div", { className: "footer" },
296
- React.createElement(React.Fragment, null,
367
+ React.createElement("span", null,
368
+ React.createElement("strong", null,
369
+ "Showing ",
370
+ getData().length),
371
+ " ",
297
372
  React.createElement("span", null,
298
- React.createElement("strong", null,
299
- "Showing ",
300
- getData().length),
301
- " ",
302
- React.createElement("span", null,
303
- "of ",
304
- pagination?.perPage ?? getData().length,
305
- " agreement")),
306
- React.createElement(Pagination, { totalRecords: pagination.totalRecords, currentPage: currentPage, perPage: pagination.perPage, onChange: (currentPage) => {
307
- config.isServerSide && pagination.onChange(currentPage);
308
- setCurrentPage(currentPage);
309
- } }))))));
373
+ "of ",
374
+ pagination?.perPage ?? getData().length,
375
+ " agreement")),
376
+ React.createElement(Pagination, { totalRecords: pagination.totalRecords, currentPage: currentPage, perPage: pagination.perPage, onChange: (currentPage) => {
377
+ config.isServerSide && pagination.onChange(currentPage);
378
+ setCurrentPage(currentPage);
379
+ } })))));
310
380
  });
311
381
  // Actions'ı ekliyoruz.
312
382
  const Table = TableWithRef;
@@ -43,7 +43,7 @@ const Input = forwardRef(({ variant = "outlined", status = "light", size = "norm
43
43
  // useEffects
44
44
  useEffect(() => {
45
45
  if (attributes.value !== undefined)
46
- setValue(attributes.value);
46
+ setValue(attributes.value ?? "");
47
47
  }, [attributes.value]);
48
48
  return (React.createElement("div", { className: _wrapperClassName.map((c) => c).join(" ") },
49
49
  addon?.before && React.createElement("span", { className: _addonBeforeClassName.map((c) => c).join(" ") }, addon?.before),
@@ -52,7 +52,7 @@ const Input = forwardRef(({ variant = "outlined", status = "light", size = "norm
52
52
  attributes.placeholder && (React.createElement("label", { className: value ? "visible" : "hidden" },
53
53
  validation && "* ",
54
54
  attributes.placeholder)),
55
- React.createElement("input", { ref: ref, ...attributes, placeholder: `${validation ? "* " : ""}${attributes.placeholder}`, value: attributes.value !== undefined ? attributes.value : value, size: 20, className: _inputClassName.map((c) => c).join(" "), onChange: (event) => {
55
+ React.createElement("input", { ref: ref, ...attributes, placeholder: `${validation ? "* " : ""}${attributes.placeholder ?? ""}`, value: value ?? attributes.value, size: 20, className: _inputClassName.map((c) => c).join(" "), onChange: (event) => {
56
56
  // Disabled gelmesi durumunda işlem yapmasına izin verme...
57
57
  if (attributes.disabled)
58
58
  return;
@@ -74,6 +74,9 @@ class Icon {
74
74
  React.createElement("line", { x1: "4", y1: this._startIndex, x2: "20", y2: this._startIndex, stroke: this._stroke, strokeWidth: this._strokeWidth, strokeLinecap: "round", strokeLinejoin: "round" }),
75
75
  React.createElement("line", { x1: "8", y1: this._centerIndex, x2: "20", y2: this._centerIndex, stroke: this._stroke, strokeWidth: this._strokeWidth, strokeLinecap: "round", strokeLinejoin: "round" }),
76
76
  React.createElement("line", { x1: "4", y1: this._finishIndex, x2: "20", y2: this._finishIndex, stroke: this._stroke, strokeWidth: this._strokeWidth, strokeLinecap: "round", strokeLinejoin: "round" })));
77
+ case "Filter":
78
+ return (React.createElement(React.Fragment, null,
79
+ React.createElement("path", { d: "M5.4 2.1h13.2c1.1 0 2 .9 2 2v2.2c0 .8-.5 1.8-1 2.3l-4.3 3.8c-.6.5-1 1.5-1 2.3V19c0 .6-.4 1.4-.9 1.7l-1.4.9c-1.3.8-3.1-.1-3.1-1.7v-5.3c0-.7-.4-1.6-.8-2.1l-3.8-4c-.5-.5-.9-1.4-.9-2V4.2c0-1.2.9-2.1 2-2.1ZM10.93 2.1 6 10", stroke: this._stroke, strokeWidth: this._strokeWidth, strokeMiterlimit: "10", strokeLinecap: "round", strokeLinejoin: "round" })));
77
80
  default:
78
81
  return null;
79
82
  }
@@ -29,6 +29,7 @@ export type TableColumnType<T> = {
29
29
  field: keyof T;
30
30
  nestedKey: string;
31
31
  };
32
+ filters?: Option[];
32
33
  render?: (item: T) => React.ReactNode;
33
34
  config?: {
34
35
  width?: number;
@@ -65,7 +66,7 @@ export type Errors<TData> = Partial<{
65
66
  }>;
66
67
  export type AllowedTypes = "image/jpeg" | "image/png" | "image/gif" | "image/webp" | "image/svg+xml" | "image/bmp" | "image/tiff" | "application/pdf" | "application/msword" | "application/vnd.openxmlformats-officedocument.wordprocessingml.document" | "application/vnd.ms-excel" | "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" | "application/vnd.openxmlformats-officedocument.presentationml.presentation" | "application/zip" | "application/x-rar-compressed" | "application/x-7z-compressed" | "application/gzip" | "application/json" | "application/xml" | "text/plain" | "text/csv" | "text/html" | "video/mp4" | "video/quicktime" | "video/x-msvideo" | "video/x-matroska" | "video/webm" | "video/x-flv" | "audio/mpeg" | "audio/wav" | "audio/ogg" | "audio/aac" | "audio/flac" | "application/octet-stream";
67
68
  export type IconVariants = "linear" | "bulk";
68
- export type Icons = "Add" | "CloseSquare" | "Drive" | "Folder" | "Trash" | "Upload" | "Image" | "Import" | "Bold" | "Italic" | "Underline" | "Strikethrough" | "BulletList" | "NumberList" | "TextAlingLeft" | "TextAlingCenter" | "TextAlingRight";
69
+ export type Icons = "Add" | "CloseSquare" | "Drive" | "Folder" | "Trash" | "Upload" | "Image" | "Import" | "Bold" | "Italic" | "Underline" | "Strikethrough" | "BulletList" | "NumberList" | "TextAlingLeft" | "TextAlingCenter" | "TextAlingRight" | "Filter";
69
70
  export type PieChartDataType = {
70
71
  value: number;
71
72
  text: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ar-design",
3
- "version": "0.1.89",
3
+ "version": "0.1.91",
4
4
  "main": "./dist/index.js",
5
5
  "module": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",