ar-design 0.4.22 → 0.4.23

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.
@@ -234,13 +234,13 @@
234
234
  position: relative;
235
235
  padding: 0.5rem;
236
236
  cursor: pointer;
237
- transition: background-color 150ms ease-in-out;
237
+ user-select: none;
238
238
 
239
- &:hover {
239
+ &.active {
240
240
  background-color: var(--gray-100);
241
241
 
242
242
  > ul {
243
- display: block;
243
+ animation: dropdownOpen 250ms ease-in-out;
244
244
  }
245
245
  }
246
246
 
@@ -256,7 +256,6 @@
256
256
  }
257
257
 
258
258
  > ul {
259
- display: none;
260
259
  position: absolute;
261
260
  top: 100%;
262
261
  right: 0;
@@ -275,6 +274,17 @@
275
274
  }
276
275
  }
277
276
 
277
+ @keyframes dropdownOpen {
278
+ from {
279
+ opacity: 0;
280
+ transform: translateY(-8px);
281
+ }
282
+ to {
283
+ opacity: 1;
284
+ transform: translateY(0);
285
+ }
286
+ }
287
+
278
288
  /* --- [KÜÇÜK MOBİL - IPHONE SE VB.] --- */
279
289
  /* Çok dar ekranlar için özel düzeltmeler */
280
290
  @media (max-width: 375px) {
@@ -10,7 +10,6 @@
10
10
  flex-direction: row;
11
11
  }
12
12
  .ar-date-picker > label {
13
- background-color: var(--white);
14
13
  position: absolute;
15
14
  top: -0.5rem;
16
15
  left: 0.55rem;
@@ -0,0 +1,6 @@
1
+ interface IProps {
2
+ config?: {
3
+ margin: string | number;
4
+ };
5
+ }
6
+ export default IProps;
@@ -0,0 +1 @@
1
+ export {};
@@ -1,4 +1,5 @@
1
1
  import React from "react";
2
2
  import "../../../assets/css/components/data-display/divider/divider.css";
3
- declare const Divider: React.FC;
3
+ import IProps from "./IProps";
4
+ declare const Divider: React.FC<IProps>;
4
5
  export default Divider;
@@ -1,5 +1,5 @@
1
1
  import React from "react";
2
2
  import "../../../assets/css/components/data-display/divider/divider.css";
3
- const Divider = () => React.createElement("hr", { className: "ar-divider" });
3
+ const Divider = ({ config }) => React.createElement("hr", { className: "ar-divider", style: { margin: config?.margin } });
4
4
  Divider.displayName = "Divider";
5
5
  export default Divider;
@@ -11,7 +11,13 @@ interface IProps {
11
11
  to: Date | null;
12
12
  }>>>;
13
13
  };
14
+ openName: {
15
+ get: string | null;
16
+ };
17
+ };
18
+ methods: {
19
+ open: (name: string | null) => void;
14
20
  };
15
21
  }
16
- declare const DateFilters: ({ states }: IProps) => React.JSX.Element[];
17
- export default DateFilters;
22
+ declare const _default: React.MemoExoticComponent<({ states, methods }: IProps) => React.JSX.Element[]>;
23
+ export default _default;
@@ -0,0 +1,52 @@
1
+ import React, { memo } from "react";
2
+ import DatePicker from "../../../form/date-picker";
3
+ import { ARIcon } from "../../../icons";
4
+ import Grid from "../../grid-system";
5
+ import Button from "../../../form/button";
6
+ import Divider from "../../divider";
7
+ const { Row, Column, Box } = Grid;
8
+ const DateFilters = ({ states, methods }) => {
9
+ return Object.entries(states.dateFilters.get).map(([name, range], index) => {
10
+ const isEqualsName = states.openName.get === name;
11
+ const className = [];
12
+ if (isEqualsName)
13
+ className.push("active");
14
+ return (React.createElement(React.Fragment, null,
15
+ React.createElement("li", { key: index, className: className.map((c) => c).join(" "), onClick: () => methods.open(name) },
16
+ React.createElement("div", null,
17
+ React.createElement("span", null, name),
18
+ React.createElement(ARIcon, { icon: "ChevronDown" })),
19
+ isEqualsName && (React.createElement("ul", { className: className.map((c) => c).join(" "), onClick: (event) => event.stopPropagation() },
20
+ React.createElement(Row, null,
21
+ React.createElement(Column, null,
22
+ React.createElement(DatePicker, { value: range.from?.toISOString(), onChange: (value) => {
23
+ states.dateFilters.set((prev) => ({
24
+ ...prev,
25
+ [name]: {
26
+ ...prev[name],
27
+ from: new Date(value),
28
+ },
29
+ }));
30
+ }, placeholder: "From" }))),
31
+ React.createElement(Row, null,
32
+ React.createElement(Column, null,
33
+ React.createElement(DatePicker, { value: range.to?.toISOString(), onChange: (value) => {
34
+ states.dateFilters.set((prev) => ({
35
+ ...prev,
36
+ [name]: {
37
+ ...prev[name],
38
+ to: new Date(value),
39
+ },
40
+ }));
41
+ }, placeholder: "To" }))),
42
+ React.createElement(Divider, { config: { margin: "0.5rem 0" } }),
43
+ React.createElement(Box, { direction: "flex-end" },
44
+ React.createElement(Button, { color: "red", size: "small", onClick: () => {
45
+ states.dateFilters.set((prev) => ({
46
+ ...prev,
47
+ [name]: { from: null, to: null },
48
+ }));
49
+ } }, "Clear")))))));
50
+ });
51
+ };
52
+ export default memo(DateFilters);
@@ -13,7 +13,13 @@ interface IProps {
13
13
  get: Record<string, Set<string | null>>;
14
14
  set: Dispatch<SetStateAction<Record<string, Set<string | null>>>>;
15
15
  };
16
+ openName: {
17
+ get: string | null;
18
+ };
19
+ };
20
+ methods: {
21
+ open: (name: string | null) => void;
16
22
  };
17
23
  }
18
- declare const SelectFilters: ({ states }: IProps) => React.JSX.Element[];
24
+ declare const SelectFilters: ({ states, methods }: IProps) => React.JSX.Element[];
19
25
  export default SelectFilters;
@@ -0,0 +1,40 @@
1
+ import React from "react";
2
+ import { ARIcon } from "../../../icons";
3
+ import Checkbox from "../../../form/checkbox";
4
+ import Grid from "../../grid-system";
5
+ import Button from "../../../form/button";
6
+ import Divider from "../../divider";
7
+ const { Box } = Grid;
8
+ const SelectFilters = ({ states, methods }) => {
9
+ return Object.entries(states.selectFilters.get).map(([name, values], index) => {
10
+ const isEqualsName = states.openName.get === name;
11
+ const className = [];
12
+ if (isEqualsName)
13
+ className.push("active");
14
+ return (React.createElement("li", { key: index, className: className.map((c) => c).join(" "), onClick: () => methods.open(name) },
15
+ React.createElement("div", null,
16
+ React.createElement("span", null, name),
17
+ React.createElement(ARIcon, { icon: "ChevronDown" })),
18
+ isEqualsName && (React.createElement("ul", { className: className.map((c) => c).join(" "), onClick: (event) => event.stopPropagation() },
19
+ values.map((value, index) => (React.createElement("li", { key: index },
20
+ React.createElement(Checkbox, { label: String(value ?? "-"), checked: states.selectedFilters.get[name]?.has(value) ?? false, onChange: () => {
21
+ states.selectedFilters.set((prev) => {
22
+ const next = { ...prev };
23
+ const set = new Set(next[name] ?? []);
24
+ set.has(value) ? set.delete(value) : set.add(value);
25
+ next[name] = set;
26
+ return next;
27
+ });
28
+ } })))),
29
+ React.createElement(Divider, { config: { margin: "0.5rem 0" } }),
30
+ React.createElement(Box, { direction: "flex-end" },
31
+ React.createElement(Button, { color: "red", size: "small", onClick: () => {
32
+ states.selectedFilters.set((prev) => {
33
+ const next = { ...prev };
34
+ delete next[name];
35
+ return next;
36
+ });
37
+ } }, "Clear"))))));
38
+ });
39
+ };
40
+ export default SelectFilters;
@@ -0,0 +1,34 @@
1
+ import { Dispatch, SetStateAction } from "react";
2
+ import React from "react";
3
+ interface IProps {
4
+ states: {
5
+ search: {
6
+ get: string;
7
+ set: Dispatch<React.SetStateAction<string>>;
8
+ };
9
+ dateFilters: {
10
+ get: Record<string, {
11
+ from: Date | null;
12
+ to: Date | null;
13
+ }>;
14
+ set: Dispatch<SetStateAction<Record<string, {
15
+ from: Date | null;
16
+ to: Date | null;
17
+ }>>>;
18
+ };
19
+ selectFilters: {
20
+ get: {
21
+ [key: string]: (string | null)[];
22
+ };
23
+ set: Dispatch<SetStateAction<{
24
+ [key: string]: (string | null)[];
25
+ }>>;
26
+ };
27
+ selectedFilters: {
28
+ get: Record<string, Set<string | null>>;
29
+ set: Dispatch<SetStateAction<Record<string, Set<string | null>>>>;
30
+ };
31
+ };
32
+ }
33
+ declare const Filter: ({ states }: IProps) => React.JSX.Element;
34
+ export default Filter;
@@ -0,0 +1,36 @@
1
+ "use client";
2
+ import { useState } from "react";
3
+ import DateFilters from "./DateFilters";
4
+ import SelectFilters from "./SelectFilters";
5
+ import React from "react";
6
+ import Input from "../../../form/input";
7
+ const Filter = ({ states }) => {
8
+ // states
9
+ const [openName, setOpenName] = useState(null);
10
+ // methods
11
+ const handleOpen = (name) => setOpenName(openName === name ? null : name);
12
+ return (React.createElement("div", { className: "filters" },
13
+ React.createElement(Input, { variant: "borderless", placeholder: "Filter by keyword", onChange: (event) => states.search.set(event.target.value.toLocaleLowerCase()) }),
14
+ React.createElement("ul", null,
15
+ React.createElement(DateFilters, { states: {
16
+ dateFilters: {
17
+ get: states.dateFilters.get,
18
+ set: states.dateFilters.set,
19
+ },
20
+ openName: { get: openName },
21
+ }, methods: {
22
+ open: handleOpen,
23
+ } }),
24
+ React.createElement(SelectFilters, { states: {
25
+ selectFilters: {
26
+ get: states.selectFilters.get,
27
+ set: states.selectFilters.set,
28
+ },
29
+ selectedFilters: {
30
+ get: states.selectedFilters.get,
31
+ set: states.selectedFilters.set,
32
+ },
33
+ openName: { get: openName },
34
+ }, methods: { open: handleOpen } }))));
35
+ };
36
+ export default Filter;
@@ -3,9 +3,7 @@ import React, { useEffect, useRef, useState } from "react";
3
3
  import "../../../assets/css/components/data-display/kanban-board/styles.css";
4
4
  import DnD from "../dnd";
5
5
  import { ARIcon } from "../../icons";
6
- import Input from "../../form/input";
7
- import DateFilters from "./DateFilters";
8
- import SelectFilters from "./SelectFilters";
6
+ import Filter from "./filter";
9
7
  const KanbanBoard = function ({ trackBy, columns, onChange, config, }) {
10
8
  // refs
11
9
  const _kanbanWrapper = useRef(null);
@@ -155,10 +153,7 @@ const KanbanBoard = function ({ trackBy, columns, onChange, config, }) {
155
153
  });
156
154
  });
157
155
  });
158
- // checkbox filtre seçenekleri
159
- const nextSelectFilters = Object.fromEntries(Array.from(selectMap.entries()).map(([name, set]) => [name, Array.from(set)]));
160
- setSelectFilters(nextSelectFilters);
161
- // date filtreler (sadece isim + boş range)
156
+ setSelectFilters(Object.fromEntries(Array.from(selectMap.entries()).map(([name, set]) => [name, Array.from(set)])));
162
157
  setDateFilters((prev) => {
163
158
  const next = { ...prev };
164
159
  Array.from(dateMap.keys()).forEach((name) => {
@@ -216,25 +211,24 @@ const KanbanBoard = function ({ trackBy, columns, onChange, config, }) {
216
211
  setData(nextData);
217
212
  }, [columns, search, selectedFilters, dateFilters]);
218
213
  return (React.createElement(React.Fragment, null,
219
- React.createElement("div", { className: "filters" },
220
- React.createElement(Input, { variant: "borderless", placeholder: "Filter by keyword", onChange: (event) => setSearch(event.target.value.toLocaleLowerCase()) }),
221
- React.createElement("ul", null,
222
- React.createElement(DateFilters, { states: {
223
- dateFilters: {
224
- get: dateFilters,
225
- set: setDateFilters,
226
- },
227
- } }),
228
- React.createElement(SelectFilters, { states: {
229
- selectFilters: {
230
- get: selectFilters,
231
- set: setSelectFilters,
232
- },
233
- selectedFilters: {
234
- get: selectedFilters,
235
- set: setSelectedFilters,
236
- },
237
- } }))),
214
+ config?.filter && (React.createElement(Filter, { states: {
215
+ search: {
216
+ get: search,
217
+ set: setSearch,
218
+ },
219
+ dateFilters: {
220
+ get: dateFilters,
221
+ set: setDateFilters,
222
+ },
223
+ selectFilters: {
224
+ get: selectFilters,
225
+ set: setSelectFilters,
226
+ },
227
+ selectedFilters: {
228
+ get: selectedFilters,
229
+ set: setSelectedFilters,
230
+ },
231
+ } })),
238
232
  React.createElement("div", { ref: _kanbanWrapper, className: "ar-kanban-board", style: {
239
233
  height: `calc(100dvh - (${_kanbanWrapper.current?.getBoundingClientRect().top}px + ${config?.safeAreaOffset?.bottom ?? 0}px))`,
240
234
  }, onDragOver: handleBoardDragOver, onDragEnd: stopScrolling, onDrop: stopScrolling },
@@ -25,6 +25,7 @@ const DatePicker = ({ variant, color, onChange, config, validation, ...attribute
25
25
  // refs
26
26
  const _arCalendar = useRef(null);
27
27
  const _arClock = useRef(null);
28
+ const _placeholder = useRef(null);
28
29
  const _calendarHeader = useRef(null);
29
30
  const _calendarFooter = useRef(null);
30
31
  const _clockHeader = useRef(null);
@@ -247,45 +248,61 @@ const DatePicker = ({ variant, color, onChange, config, validation, ...attribute
247
248
  setYears(years);
248
249
  }, [selectedYear]);
249
250
  return (React.createElement("div", { className: "ar-date-picker" },
250
- attributes.placeholder && attributes.placeholder.length > 0 && (React.createElement("label", null,
251
+ attributes.placeholder && attributes.placeholder.length > 0 && (React.createElement("label", { ref: _placeholder },
251
252
  validation ? "* " : "",
252
253
  attributes.placeholder)),
253
- React.createElement(Input, { ref: _beginDate, variant: variant, color: color, ...attributes, value: DATE.ParseValue(String(attributes.value), config?.isClock), type: config?.isClock ? "datetime-local" : "date", onKeyDown: (event) => {
254
- if (event.code === "Space")
254
+ React.createElement("div", { className: "wrapper", ...(String(attributes.value).length > 0
255
+ ? {
256
+ style: {
257
+ clipPath: `polygon(
258
+ -15px 0,
259
+ 10px -5px,
260
+ 10px 5px,
261
+ calc(${_placeholder.current?.getBoundingClientRect().width}px + 7px) 5px,
262
+ calc(${_placeholder.current?.getBoundingClientRect().width}px + 7px) -5px,
263
+ 100% -70px,
264
+ calc(100% + 5px) calc(100% + 5px),
265
+ -5px calc(100% + 5px)
266
+ )`,
267
+ },
268
+ }
269
+ : {}) },
270
+ React.createElement(Input, { ref: _beginDate, variant: variant, color: color, ...attributes, value: DATE.ParseValue(String(attributes.value), config?.isClock), type: config?.isClock ? "datetime-local" : "date", onKeyDown: (event) => {
271
+ if (event.code === "Space")
272
+ event.preventDefault();
273
+ else if (event.code === "Enter")
274
+ handleOk();
275
+ }, onChange: (event) => {
276
+ // Disabled gelmesi durumunda işlem yapmasına izin verme...
277
+ if (attributes.disabled)
278
+ return;
279
+ (() => {
280
+ if (!calendarIsOpen)
281
+ setCalendarIsOpen(true);
282
+ const value = event.target.value;
283
+ const [date, time] = value.split("T");
284
+ const [year, month, day] = date.split("-").map(Number);
285
+ const hours = time ? time.split(".")[0].split(":").map(Number)[0] : 0;
286
+ const minutes = time ? time.split(".")[0].split(":").map(Number)[1] : 0;
287
+ _year.current = year;
288
+ _month.current = month - 1;
289
+ _day.current = day;
290
+ if (hours || minutes) {
291
+ _hours.current = hours;
292
+ _minutes.current = minutes;
293
+ }
294
+ // Yıl ve Ay'ı anlık yeniler.
295
+ setSelectedYear(_year.current);
296
+ setSelectedMonth(_month.current);
297
+ // Takvimi anlık yeniler.
298
+ setDateChanged((prev) => !prev);
299
+ setTimeChanged((prev) => !prev);
300
+ onChange(value);
301
+ })();
302
+ }, onClick: (event) => {
255
303
  event.preventDefault();
256
- else if (event.code === "Enter")
257
- handleOk();
258
- }, onChange: (event) => {
259
- // Disabled gelmesi durumunda işlem yapmasına izin verme...
260
- if (attributes.disabled)
261
- return;
262
- (() => {
263
- if (!calendarIsOpen)
264
- setCalendarIsOpen(true);
265
- const value = event.target.value;
266
- const [date, time] = value.split("T");
267
- const [year, month, day] = date.split("-").map(Number);
268
- const hours = time ? time.split(".")[0].split(":").map(Number)[0] : 0;
269
- const minutes = time ? time.split(".")[0].split(":").map(Number)[1] : 0;
270
- _year.current = year;
271
- _month.current = month - 1;
272
- _day.current = day;
273
- if (hours || minutes) {
274
- _hours.current = hours;
275
- _minutes.current = minutes;
276
- }
277
- // Yıl ve Ay'ı anlık yeniler.
278
- setSelectedYear(_year.current);
279
- setSelectedMonth(_month.current);
280
- // Takvimi anlık yeniler.
281
- setDateChanged((prev) => !prev);
282
- setTimeChanged((prev) => !prev);
283
- onChange(value);
284
- })();
285
- }, onClick: (event) => {
286
- event.preventDefault();
287
- setCalendarIsOpen(true);
288
- }, autoComplete: "off", validation: validation }),
304
+ setCalendarIsOpen(true);
305
+ }, autoComplete: "off", validation: validation })),
289
306
  calendarIsOpen &&
290
307
  ReactDOM.createPortal(React.createElement("div", { ref: _arCalendar, className: "ar-date-calendar" },
291
308
  React.createElement("div", { ref: _calendarHeader, className: "header" },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ar-design",
3
- "version": "0.4.22",
3
+ "version": "0.4.23",
4
4
  "main": "./dist/index.js",
5
5
  "module": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -1,35 +0,0 @@
1
- import React from "react";
2
- import DatePicker from "../../form/date-picker";
3
- import { ARIcon } from "../../icons";
4
- import Grid from "../grid-system";
5
- const { Row, Column } = Grid;
6
- const DateFilters = ({ states }) => {
7
- return Object.entries(states.dateFilters.get).map(([name, range]) => (React.createElement("li", { key: name, className: "filter-box" },
8
- React.createElement("div", null,
9
- React.createElement("span", null, name),
10
- React.createElement(ARIcon, { icon: "ChevronDown" })),
11
- React.createElement("ul", null,
12
- React.createElement(Row, null,
13
- React.createElement(Column, null,
14
- React.createElement(DatePicker, { value: range.from?.toISOString(), onChange: (value) => {
15
- states.dateFilters.set((prev) => ({
16
- ...prev,
17
- [name]: {
18
- ...prev[name],
19
- from: new Date(value),
20
- },
21
- }));
22
- } }))),
23
- React.createElement(Row, null,
24
- React.createElement(Column, null,
25
- React.createElement(DatePicker, { value: range.to?.toISOString(), onChange: (value) => {
26
- states.dateFilters.set((prev) => ({
27
- ...prev,
28
- [name]: {
29
- ...prev[name],
30
- to: new Date(value),
31
- },
32
- }));
33
- } })))))));
34
- };
35
- export default DateFilters;
@@ -1,20 +0,0 @@
1
- import React from "react";
2
- import { ARIcon } from "../../icons";
3
- import Checkbox from "../../form/checkbox";
4
- const SelectFilters = ({ states }) => {
5
- return Object.entries(states.selectFilters.get).map(([name, values]) => (React.createElement("li", null,
6
- React.createElement("div", null,
7
- React.createElement("span", null, name),
8
- React.createElement(ARIcon, { icon: "ChevronDown" })),
9
- React.createElement("ul", null, values.map((val) => (React.createElement("li", null,
10
- React.createElement(Checkbox, { label: String(val ?? "-"), checked: states.selectedFilters.get[name]?.has(val) ?? false, onChange: () => {
11
- states.selectedFilters.set((prev) => {
12
- const next = { ...prev };
13
- const set = new Set(next[name] ?? []);
14
- set.has(val) ? set.delete(val) : set.add(val);
15
- next[name] = set;
16
- return next;
17
- });
18
- } }))))))));
19
- };
20
- export default SelectFilters;