ar-design 0.1.90 → 0.1.92

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,21 +6,28 @@ 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
13
  const _tableWrapper = useRef(null);
12
14
  const _table = useRef(null);
13
15
  const _tableContent = useRef(null);
14
16
  const _checkboxItems = useRef([]);
17
+ const _filterCheckboxItems = useRef([]);
18
+ // refs -> Search
15
19
  const _searchTextInputs = useRef([]);
16
20
  const _searchTimeOut = useRef(null);
21
+ // const _searchFilterFirstLoad = useRef<boolean>(false);
17
22
  // className
18
23
  const _tableClassName = ["ar-table", "scroll"];
19
24
  // states
20
25
  const [selectAll, setSelectAll] = useState(false);
21
26
  const [selectionItems, setSelectionItems] = useState([]);
27
+ // states -> Search
22
28
  const [searchedText, setSearchedText] = useState(undefined);
23
29
  const [_searchedParams, setSearchedParams] = useState(undefined);
30
+ // const [searchedFilters, setSearchedFilters] = useState<string | undefined>(undefined);
24
31
  // const [totalRecords, setTotalRecords] = useState<number>(0);
25
32
  const [currentPage, setCurrentPage] = useState(1);
26
33
  if (config && Object.keys(config.scroll || {}).length > 0) {
@@ -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)
@@ -119,13 +172,28 @@ const TableWithRef = forwardRef(({ children, title, description, data, columns,
119
172
  // Eğer değer bir sayı veya string ise, aranan metinle eşleşip eşleşmediğini kontrol ediyoruz.
120
173
  return Object.entries(searchedText).every(([key, value]) => {
121
174
  const _itemValue = item[key];
175
+ debugger;
122
176
  if (typeof _itemValue === "number" || typeof _itemValue === "string") {
177
+ if (Array.isArray(value)) {
178
+ if (value.length === 0)
179
+ return true;
180
+ else
181
+ return value.some((v) => _itemValue.toString().toLocaleLowerCase().includes(v.toLocaleLowerCase()));
182
+ }
123
183
  return _itemValue.toString().toLocaleLowerCase().includes(value.toLocaleLowerCase());
124
184
  }
125
185
  if (typeof _itemValue === "object") {
186
+ if (Array.isArray(value)) {
187
+ if (value.length === 0)
188
+ return true;
189
+ else {
190
+ return value.some((v) => Object.entries(_itemValue ?? {}).some(([_, objValue]) => String(objValue).toLocaleLowerCase().includes(v.toLocaleLowerCase())));
191
+ }
192
+ }
126
193
  return Object.entries(_itemValue ?? {}).some(([_, objValue]) => String(objValue).toLocaleLowerCase().includes(value.toLocaleLowerCase()));
127
194
  }
128
195
  if (Array.isArray(_itemValue)) {
196
+ console.log("Buradasın", _itemValue);
129
197
  }
130
198
  return false;
131
199
  });
@@ -170,6 +238,7 @@ const TableWithRef = forwardRef(({ children, title, description, data, columns,
170
238
  }
171
239
  setSelectAll(allChecked);
172
240
  }, [currentPage]);
241
+ console.log(searchedText);
173
242
  return (React.createElement("div", { ref: _tableWrapper, className: _tableClassName.map((c) => c).join(" ") },
174
243
  (title || description || actions || React.Children.count(children) > 0) && (React.createElement("div", { className: "header" },
175
244
  React.createElement("div", { className: "title" },
@@ -223,32 +292,36 @@ const TableWithRef = forwardRef(({ children, title, description, data, columns,
223
292
  if (c.config?.alignContent) {
224
293
  _className.push(`align-content-${c.config.alignContent}`);
225
294
  }
226
- if (!c.key)
227
- return (React.createElement("th", { key: `column-${cIndex}`, ...(_className.length > 0 && {
228
- className: `${_className.map((c) => c).join(" ")}`,
229
- }), ...(c.config?.sticky && {
230
- "data-sticky-position": c.config.sticky,
231
- }) }));
232
295
  return (React.createElement("th", { key: `column-${cIndex}`, ...(_className.length > 0 && {
233
296
  className: `${_className.map((c) => c).join(" ")}`,
234
297
  }), ...(c.config?.sticky && {
235
298
  "data-sticky-position": c.config.sticky,
236
299
  }) },
237
- 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) => {
238
- if (config.isServerSide) {
239
- if (_searchTimeOut.current)
240
- clearTimeout(_searchTimeOut.current);
241
- _searchTimeOut.current = setTimeout(() => {
242
- setSearchedParams((prev) => ({ ...prev, [event.target.name]: event.target.value }));
243
- setCurrentPage(1);
244
- pagination && pagination.onChange(1);
245
- }, 750);
246
- }
247
- else {
248
- setCurrentPage(1);
249
- setSearchedText((prev) => ({ ...prev, [event.target.name]: event.target.value }));
250
- }
251
- } })));
300
+ React.createElement("div", { className: "filter-field" },
301
+ 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 }),
302
+ c.filters && (React.createElement(Popover, { content: React.createElement(React.Fragment, null,
303
+ React.createElement("ul", null, c.filters
304
+ // .filter((x) =>
305
+ // x.text.toLocaleLowerCase().includes(searchedFilters?.toLocaleLowerCase() ?? "")
306
+ // )
307
+ .map((filter, index) => {
308
+ const name = typeof c.key !== "object" ? String(c.key) : String(c.key.field);
309
+ return (React.createElement("li", { key: index },
310
+ React.createElement(Checkbox, { ref: (element) => (_filterCheckboxItems.current[index] = element), label: filter.text, name: name, status: "success", value: filter.text, checked: config.isServerSide
311
+ ? _searchedParams?.[name]?.includes(filter.text)
312
+ : searchedText?.[name]?.includes(filter.text), onChange: handleChecboxFilter })));
313
+ }))) },
314
+ _filterCheckboxItems.current.filter((item) => item?.checked).length > 0 && (React.createElement("div", { style: {
315
+ position: "absolute",
316
+ top: "0.35rem",
317
+ right: "0.35rem",
318
+ width: "0.5rem",
319
+ height: "0.5rem",
320
+ backgroundColor: "var(--danger)",
321
+ borderRadius: "var(--border-radius-pill)",
322
+ zIndex: 1,
323
+ } })),
324
+ React.createElement(Button, { variant: "borderless", icon: { element: React.createElement(ARIcon, { icon: "Filter", stroke: "var(--primary)", size: 16 }) } }))))));
252
325
  })))),
253
326
  React.createElement("tbody", null, getData().length > 0 ? (getData().map((item, index) => (React.createElement("tr", { key: `row-${index}` },
254
327
  selections && (React.createElement("td", { key: `selection-${index}`, className: "sticky-left", "data-sticky-position": "left" },
@@ -292,20 +365,19 @@ const TableWithRef = forwardRef(({ children, title, description, data, columns,
292
365
  }))))) : (React.createElement("tr", null,
293
366
  React.createElement("td", { colSpan: columns.length + 1 }, "Herhangi bir kay\u0131t bulunamad\u0131!")))))),
294
367
  pagination && pagination.totalRecords > pagination.perPage && (React.createElement("div", { className: "footer" },
295
- React.createElement(React.Fragment, null,
368
+ React.createElement("span", null,
369
+ React.createElement("strong", null,
370
+ "Showing ",
371
+ getData().length),
372
+ " ",
296
373
  React.createElement("span", null,
297
- React.createElement("strong", null,
298
- "Showing ",
299
- getData().length),
300
- " ",
301
- React.createElement("span", null,
302
- "of ",
303
- pagination?.perPage ?? getData().length,
304
- " agreement")),
305
- React.createElement(Pagination, { totalRecords: pagination.totalRecords, currentPage: currentPage, perPage: pagination.perPage, onChange: (currentPage) => {
306
- config.isServerSide && pagination.onChange(currentPage);
307
- setCurrentPage(currentPage);
308
- } }))))));
374
+ "of ",
375
+ pagination?.perPage ?? getData().length,
376
+ " agreement")),
377
+ React.createElement(Pagination, { totalRecords: pagination.totalRecords, currentPage: currentPage, perPage: pagination.perPage, onChange: (currentPage) => {
378
+ config.isServerSide && pagination.onChange(currentPage);
379
+ setCurrentPage(currentPage);
380
+ } })))));
309
381
  });
310
382
  // Actions'ı ekliyoruz.
311
383
  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.90",
3
+ "version": "0.1.92",
4
4
  "main": "./dist/index.js",
5
5
  "module": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",